Skip to content

Commit

Permalink
docs: update docz
Browse files Browse the repository at this point in the history
  • Loading branch information
Jan Fischer committed Apr 6, 2021
1 parent 8a9b8c0 commit b2d2666
Show file tree
Hide file tree
Showing 8 changed files with 279 additions and 30 deletions.
10 changes: 9 additions & 1 deletion packages/docz/doczrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,15 @@ export default {
'Introduction',
{
name: 'Components',
menu: ['Tween', 'Timeline', 'Reveal', 'SplitChars', 'SplitWords', 'Controls'],
menu: [
'Tween',
'Timeline',
'ScrollTrigger',
'Reveal',
'SplitChars',
'SplitWords',
'Controls',
],
},
{ name: 'Plugins', menu: ['GSAP Plugins', 'CountPlugin', 'SvgDrawPlugin'] },
'Instructions',
Expand Down
4 changes: 2 additions & 2 deletions packages/docz/src/components/Controls.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@ Just wrap it around a Tween or Timeline component and you'll get control buttons

With the optional `playState` prop you can set an initial play state.

You can use the `PlayState` enum/object or just the strings "play", "reverse", "stop" or "pause".
You can use the `PlayState` enum/object or just the strings "play", "restart", "reverse", "restartReverse", "stop", "stopEnd", "pause" or "resume".

import { Controls, PlayState, Tween } from 'react-gsap';

### Usage with Tween

<Playground>
<Controls playState={PlayState.reverse}>
<Controls playState={PlayState.restartReverse}>
<Tween to={{ x: '200px', rotation: 180 }} duration={2} ease="back.out(1.7)">
<div style={{ width: '100px', height: '100px', background: '#ccc' }} />
</Tween>
Expand Down
2 changes: 1 addition & 1 deletion packages/docz/src/components/Reveal.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ If no trigger is passed, the first element from any child Tween or Timeline that

## forwardRef trigger

You also can create a forwardRef component as trigger if you need a more complex wrapper or trigger.
You can also create a forwardRef component as trigger if you need a more complex wrapper or trigger.

```javascript
export const AnimationTrigger = React.forwardRef<HTMLDivElement>(({ children }, ref) => (
Expand Down
193 changes: 193 additions & 0 deletions packages/docz/src/components/ScrollTrigger.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
---
name: ScrollTrigger
menu: Components
---

import { Fragment } from 'react';
import { Playground, Props } from 'docz'
import { Controls, PlayState, ScrollTrigger } from './../../../react-gsap/src/'
import { Tween } from './Tween'
import { Timeline, TargetWithNames } from './Timeline'

# ScrollTrigger

The ScrollTrigger component is a small helper for the ScrollTrigger plugin.

Read the official documentation: https://greensock.com/docs/v3/Plugins/ScrollTrigger

It's available since version 3.2.0.
Before you also could use the ScrollTrigger plugin by importing/registering and using it in a Tween or Timeline by yourself:

import { Tween } from 'react-gsap';

import { ScrollTrigger } from 'gsap/dist/ScrollTrigger';
gsap.registerPlugin(ScrollTrigger);

<Tween
to={{
x: '300px',
scrollTrigger: {
trigger: '.square',
start: '-200px center',
end: '200px center',
scrub: 0.5,
markers: true,
},
}}
>
<div className="square" style={{ width: '100px', height: '100px', background: '#ccc' }} />
</Tween>

## Basic usage

With the ScrollTrigger component, it looks like the following. If you don't add a trigger prop, it will use the ref from the Tween target.

<Playground>
<ScrollTrigger
start="-200px center"
end="200px center"
scrub={0.5}
markers
>
<Tween
to={{
x: '300px',
}}
>
<div style={{ width: '100px', height: '100px', background: '#ccc' }} />
</Tween>
<Tween
to={{
x: '300px',
}}
>
<div style={{ width: '100px', height: '100px', background: '#999' }} />
</Tween>
</ScrollTrigger>
</Playground>

## Use "trigger" prop

Currently it's not possible to change the props on the fly. **So this will not work for the `trigger` prop**:

const triggerRef = useRef(null);
const [trigger, setTrigger] = useState(triggerRef.current);

useEffect(() => {
setTrigger(triggerRef.current);
}, []);

return (
<>
<ScrollTrigger trigger={trigger}>
<Tween
to={{
x: '500px',
}}
>
<div>This element gets not tweened by ref</div>
</Tween>
</ScrollTrigger>

<Square ref={triggerRef}>
This element is the trigger
</Square>
</>
);

If you want to target a ref directly instead of using a CSS selector you can use a Timeline with a forwardRef target:

// This is the target component which "exports" 4 refs
const TargetWithNames = forwardRef((props, ref: any) => {
const div1 = useRef(null);
const div2 = useRef<MutableRefObject<any>[]>([]);
const div3 = useRef(null);
const trigger = useRef(null);

useImperativeHandle(ref, () => ({
div1,
div2,
div3,
trigger,
}));

return (
<div ref={trigger} style={{ textAlign: 'center' }}>
<h3 ref={div1}>THIS</h3>
<SplitChars
ref={(charRef: MutableRefObject<any>) => div2.current.push(charRef)}
wrapper={<h3 style={{ display: 'inline-block' }} />}
>
TEST
</SplitChars>
<h3 ref={div3}>IS A</h3>
</div>
);
});

You can then use the key of the exported refs in the `trigger` or `target` props.
If it doesn't find a ref with this key it will use the `trigger` string as CSS selector.

<Playground>
<ScrollTrigger
trigger="trigger"
start="top center"
end="400px center"
scrub={0.5}
markers={true}
pin={true}
>
<Timeline target={<TargetWithNames />}>
<Tween
from={{
x: '-100vw',
}}
target="div1"
/>
<Tween
from={{
x: '-100vw',
}}
target="div3"
/>
<Tween
from={{
x: '-100vw',
}}
stagger={0.5}
target="div2"
/>
</Timeline>
</ScrollTrigger>
</Playground>

## Standalone

If you don't pass children to the component a GSAP ScrollTrigger instance will be created and can be used standalone.

You can get the instance by calling `getGSAP()` on the ref.

<Playground>
{() => {
const scrollTrigger = React.useRef(null);
return (
<Fragment>
<div id="id" style={{width: '100px', height: '100px', background: '#ccc'}}/>
<div id="otherID" style={{width: '100px', height: '100px', background: '#999'}}/>
<ScrollTrigger
ref={scrollTrigger}
trigger="#id"
start="top top"
endTrigger="#otherID"
end="bottom 50%+=100px"
markers
onToggle={self => console.log("toggled, isActive:", self.isActive)}
onUpdate={self => {
console.log("progress:", self.progress.toFixed(3), "direction:", self.direction, "velocity", self.getVelocity());
}}
/>
<button onClick={() => scrollTrigger.current.getGSAP().disable()}>Disable ScrollTrigger</button>
</Fragment>
)
}}
</Playground>
4 changes: 4 additions & 0 deletions packages/docz/src/components/Timeline.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,10 @@ More info: [https://greensock.com/docs/v3/GSAP/Timeline/addLabel()](https://gree
| Field | As string |
| :-- | :-- |
| play | "play" |
| restart | "restart" |
| reverse | "reverse" |
| restartReverse | "restartReverse" |
| stop | "stop" |
| stopEnd | "stopEnd" |
| pause | "pause" |
| resume | "resume" |
4 changes: 3 additions & 1 deletion packages/docz/src/components/Timeline.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,15 @@ const TargetWithNames = forwardRef((props, ref: any) => {
const div1 = useRef(null);
const div2 = useRef<MutableRefObject<any>[]>([]);
const div3 = useRef(null);
const trigger = useRef(null);
useImperativeHandle(ref, () => ({
div1,
div2,
div3,
trigger,
}));
return (
<div style={{ textAlign: 'center' }}>
<div ref={trigger} style={{ textAlign: 'center' }}>
<h3 ref={div1}>THIS</h3>
<SplitChars
ref={(charRef: MutableRefObject<any>) => div2.current.push(charRef)}
Expand Down
29 changes: 4 additions & 25 deletions packages/docz/src/components/Tween.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -88,31 +88,6 @@ More info: https://greensock.com/docs/v3/Staggers
</Controls>
</Playground>

## Use playState and totalProgress props

With the playState and progress/totalProgress props you can control the Tween.
So you don't need low-level access to play/reverse/pause/stop or seek to a position.

<Playground>
{() => {
const [playing, setPlaying] = React.useState(false)
const [progress, setProgress] = React.useState(0)
return (
<Fragment>
<Tween to={{ x: '200px' }} duration={2} playState={playing ? PlayState.play : PlayState.pause} totalProgress={progress}>
<div style={{ width: '100px', height: '100px', background: '#ccc' }} />
</Tween>
<button onClick={() => setPlaying(!playing)}>
{playing ? 'Pause' : 'Play'}
</button>
<div>
<input type="range" max="1" step="0.001" value={progress} onChange={(event) => setProgress(event.target.value)} />
</div>
</Fragment>
)
}}
</Playground>

## Props

The question mark means it's an optional prop.
Expand Down Expand Up @@ -159,6 +134,10 @@ More info: https://greensock.com/docs/v3/Staggers
| Field | As string |
| :-- | :-- |
| play | "play" |
| restart | "restart" |
| reverse | "reverse" |
| restartReverse | "restartReverse" |
| stop | "stop" |
| stopEnd | "stopEnd" |
| pause | "pause" |
| resume | "resume" |
63 changes: 63 additions & 0 deletions packages/docz/src/instructions/PlayState.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
---
name: Use "playState" prop
menu: Instructions
---

import { Fragment } from 'react';
import { Playground } from 'docz'
import { PlayState, Tween } from './../../../react-gsap/src/'

# Use playState and totalProgress props

With the playState and progress/totalProgress props you can control a Tween or a Timeline.
So you don't need low-level access to play/reverse/pause/stop or seek to a position.

From version 3.2.0 on the `playState` prop also works for the initial state and the following states were added:
`restartReverse`, `stopEnd`, `resume`.

The following gsap functions are called internally, if the `playState` prop change:

if (playState === PlayState.play) {
gsap.play();
} else if (playState === PlayState.restart) {
gsap.restart(true);
} else if (playState === PlayState.reverse) {
gsap.reverse();
} else if (playState === PlayState.restartReverse) {
gsap.reverse(0);
} else if (playState === PlayState.stop) {
gsap.pause(0);
} else if (playState === PlayState.stopEnd) {
gsap.reverse(0);
gsap.pause();
} else if (playState === PlayState.pause) {
gsap.pause();
} else if (playState === PlayState.resume) {
gsap.resume();
}

<Playground>
{() => {
const [playState, setPlayState] = React.useState(PlayState.pause);
const [totalProgress, setTotalProgress] = React.useState(0)
return (
<Fragment>
<Tween to={{ x: '300px' }} duration={2} playState={playState} totalProgress={totalProgress}>
<div style={{ width: '100px', height: '100px', background: '#ccc' }} />
</Tween>
<button onClick={() => setPlayState(PlayState.play)}>play</button>
<button onClick={() => setPlayState(PlayState.restart)}>restart</button>
<button onClick={() => setPlayState(PlayState.reverse)}>reverse</button>
<button onClick={() => setPlayState(PlayState.restartReverse)}>restartReverse</button>
<button onClick={() => setPlayState(PlayState.stop)}>stop</button>
<button onClick={() => setPlayState(PlayState.stopEnd)}>stopEnd</button>
<button onClick={() => setPlayState(PlayState.pause)}>pause</button>
<button onClick={() => setPlayState(PlayState.resume)}>resume</button>
<div>
<input type="range" max="1" step="0.001" value={totalProgress} onChange={(event) => setTotalProgress(event.target.value)} />
</div>
</Fragment>
)
}}
</Playground>

0 comments on commit b2d2666

Please sign in to comment.