# @chundev/gtranz

> Page transition context with GSAP timeline.

Latest version **1.1.3** (published 2023-04-24) · MIT license · 0 weekly downloads

## Install

```sh
npm install @chundev/gtranz
pnpm add @chundev/gtranz
yarn add @chundev/gtranz
bun add @chundev/gtranz
```

## Health

**Score 25/100 (F)** — status: abandoned.

Positive: has types; esm support; no vulnerabilities.

Warnings: low downloads.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 1.1.3 |
| Published | 2023-04-24 |
| First published | 2023-04-20 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Dependencies | 0 |
| Unpacked size | 7.5 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 1 |
| Author | latteouka |
| Maintainers | oukalatte |
| Keywords | react, typescript, nextjs, transition |

## Links

- npm: https://www.npmjs.com/package/@chundev/gtranz
- Repository: https://github.com/latteouka/gtranz
- Homepage: https://github.com/latteouka/gtranz#readme
- Issues: https://github.com/latteouka/gtranz/issues
- npm.io page: https://npm.io/package/@chundev/gtranz

## Alternatives

- [mobx-react](https://npm.io/package/mobx-react.md) — 2.8M weekly downloads
- [rc-tree](https://npm.io/package/rc-tree.md) — 2.6M weekly downloads
- [@react-oauth/google](https://npm.io/package/@react-oauth/google.md) — 1.3M weekly downloads
- [@wagmi/connectors](https://npm.io/package/@wagmi/connectors.md) — 877.0K weekly downloads
- [vee-validate](https://npm.io/package/vee-validate.md) — 836.4K weekly downloads

## Recent versions

- 1.1.3 (latest) — 2023-04-24
- 1.1.2 — 2023-04-23
- 1.1.1 — 2023-04-21
- 1.1.0 — 2023-04-21
- 1.0.29 — 2023-04-21
- 1.0.28 — 2023-04-21
- 1.0.27 — 2023-04-21
- 1.0.26 — 2023-04-21
- 1.0.25 — 2023-04-21
- 1.0.24 — 2023-04-21
- 1.0.21 — 2023-04-21
- 1.0.20 — 2023-04-20
- 1.0.19 — 2023-04-20
- 1.0.18 — 2023-04-20
- 1.0.17 — 2023-04-20
- … 16 more at https://npm.io/package/@chundev/gtranz/versions

## README

## Gtranz


[DEMO](https://transition.chundev.com/)

This is a simple timeline context lets you setup intro/outro animations with
GSAP in Next.js.

Original idea is from [johnpolacek/TweenPages](https://tweenpages.vercel.app/docs)

You can read how it works in his doc.

If you can read Chinese, check [this](https://doc.chundev.com/blogs/transition-next)
and learn what I've edited.

## Usage

```bash
npm install @chundev/gtranz

yarn add @chundev/gtranz
```

- Wrap your content in `_app.tsx`

```tsx
import Gtranz from "@chundev/gtranz";

export default function App({ Component, pageProps }: AppProps) {
  return (
    <main className={font.className}>
       <Head>
          <title>Next.js Transition</title>
       </Head>
       <Gtranz>
       <Component {...pageProps} />
       </Gtranz>
    </main>
  );
}
```

- then setup your outro with timeline

```ts
import { timeline, useIsomorphicLayoutEffect } from "@chundev/gtranz";

const timeline = useTimeline();

// intro
// will play when enter the page
useIsomorphicLayoutEffect(() => {
  const ctx = gsap.context(() => {
    gsap.fromTo(
      ".title",
      { x: -100, opacity: 0 },
      {
        x: 0,
        opacity: 1,
      }
    );
  });

  return () => {
    ctx.revert();
  };
}, []);

// outro
useIsomorphicLayoutEffect(() => {
  timeline.add(
    gsap.to(".title", {
      opacity: 0,
    }),
    0
  );

  return () => {
    timeline?.clear();
  };
}, []);
```

## Dealing with overwrite

EDIT: **ALTHOUGH IT CAN BE DONE THIS WAY, IT IS PROBABLY NOT A BEST SOLUTION.**  
Check out the [discussion](https://greensock.com/forums/topic/29470-gsap-page-transitions-in-nextjs/).  
You can still do transitions with default overwrite:false setting.

If you are trying to setup animations like I did in the demo.  
You might also realize that sometimes you have to overwrite gsap
tweens for some instant animations(for the same element).  
In the demo, I tween the positions of the images which are also set in the outro.
And that messes up everything.  
What you can to do is let gsap overwrite by default.

```ts
// put this somewhere high and do it once
// this effects globally
gsap.defaults({ overwrite: true });
```

And then you arrange all the setup cycle by yourself.

You might:

1. use a state to determine the setup order of intro/outro.
(if you overwrite some element's tweens that are also used in outro)

```ts
const timeline = useTimeline();
const [introPlayed, setIntroPlayed] = useState(false);
// intro
useIsomorphicLayoutEffect(() => {
  const ctx = gsap.context(() => {
    gsap.fromTo(
      ".title",
      { x: -100, opacity: 0 },
      {
        x: 0,
        opacity: 1,
        onComplete: () => {
          setIntroPlayed(true);
        },
      }
    );
  });

  return () => {
    ctx.revert();
  };
}, []);

// out
useIsomorphicLayoutEffect(() => {
  if (!introPlayed) return;
  timeline.add(
    gsap.to(".title", {
      opacity: 0,
    }),
    0
  );

  return () => {
    timeline?.clear();
  };
}, [introPlayed]);
```

2. use custom event to re-setup outro whenever you want.

```ts
const timeline = useTimeline();
const [introPlayed, setIntroPlayed] = useState(false);

// intro
useIsomorphicLayoutEffect(() => {
  // bind event
  document.addEventListener("setupAnimation", setupOutro);

  const ctx = gsap.context(() => {
    gsap.fromTo(
      ".title",
      { x: -100, opacity: 0 },
      {
        x: 0,
        opacity: 1,
        onComplete: () => {
          // dispatch when intro end
          dispatchSetupOutroEvent("setupAnimation");
        },
      }
    );
  });

  return () => {
    document.removeEventListener("setupAnimation", setupOutro);
    ctx.revert();
  };
}, []);

// outro setup
function setupOutro() {
  timeline.add(
    gsap.to(".title", {
      opacity: 0,
    }),
    0
  );
}
```

```ts
// dispatch when other animation(at anywhere) is over
gsap.fromTo(
  ".title",
  { x: -100, opacity: 0 },
  {
    x: 0,
    opacity: 1,
    onComplete: () => {
      dispatchSetupOutroEvent("setupAnimation");
    },
  }
);
```

custom event function looks like:

```ts
function dispatchSetupOutroEvent(eventName: string, data: any) {
  const e = new CustomEvent(eventName, { detail: data });
  document.dispatchEvent(e);
}

dispatchSetupOutroEvent("setupAnimation");
```

I don't really know if it's good practice or not.  
But I did solve my problem and make nice transition by doing so.

---
_Source: https://npm.io/package/@chundev/gtranz · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
