1- import React from 'react' ;
1+ import React , {
2+ forwardRef ,
3+ MutableRefObject ,
4+ useEffect ,
5+ useImperativeHandle ,
6+ useRef ,
7+ useState ,
8+ } from 'react' ;
29import styled from 'styled-components' ;
3- import { Tween , SplitWords , SplitLetters , Controls } from 'react-gsap' ;
4- import { gsap } from 'gsap' ;
5- import { ScrollTrigger } from 'gsap/ScrollTrigger' ;
6- gsap . registerPlugin ( ScrollTrigger ) ;
10+ import {
11+ Tween ,
12+ Timeline ,
13+ SplitWords ,
14+ SplitLetters ,
15+ Controls ,
16+ ScrollTrigger ,
17+ PlayState ,
18+ SplitChars ,
19+ } from 'react-gsap' ;
720
821const Container = styled . div `
922 width: 100%;
@@ -26,26 +39,151 @@ const FadeIn = ({ children }: { children: React.ReactNode }) => (
2639 < Tween from = { { opacity : 0 } } > { children } </ Tween >
2740) ;
2841
29- const TweenComponent = ( ) => (
30- < TweenStyled >
31- < Container className = "trigger" >
32- < Tween
33- to = { {
34- x : '500px' ,
35- scrollTrigger : {
36- trigger : '.trigger' ,
37- start : 'top center' ,
38- end : 'bottom center' ,
39- scrub : 0.5 ,
40- markers : true ,
41- pin : true ,
42- } ,
43- } }
42+ const TargetWithNames = forwardRef ( ( props , ref : any ) => {
43+ const div1 = useRef ( null ) ;
44+ const div2 = useRef < MutableRefObject < any > [ ] > ( [ ] ) ;
45+ const div3 = useRef ( null ) ;
46+ const trigger = useRef ( null ) ;
47+ useImperativeHandle ( ref , ( ) => ( {
48+ div1,
49+ div2,
50+ div3,
51+ trigger,
52+ } ) ) ;
53+ return (
54+ < div ref = { trigger } >
55+ < div ref = { div1 } > first</ div >
56+ < SplitChars
57+ ref = { ( charRef : MutableRefObject < any > ) => div2 . current . push ( charRef ) }
58+ wrapper = { < span style = { { display : 'inline-block' } } /> }
4459 >
45- < Square className = "square" > This element gets tweened</ Square >
46- </ Tween >
47- </ Container >
48- </ TweenStyled >
49- ) ;
60+ second
61+ </ SplitChars >
62+ < div ref = { div3 } > third</ div >
63+ </ div >
64+ ) ;
65+ } ) ;
66+
67+ const TweenComponent = ( ) => {
68+ const triggerRef = useRef ( null ) ;
69+ const [ trigger , setTrigger ] = useState ( triggerRef . current ) ;
70+
71+ useEffect ( ( ) => {
72+ setTrigger ( triggerRef . current ) ;
73+ } , [ ] ) ;
74+
75+ return (
76+ < >
77+ < TweenStyled >
78+ < ScrollTrigger trigger = ".trigger" >
79+ < Tween
80+ to = { {
81+ x : '500px' ,
82+ } }
83+ >
84+ < Square className = "square" > This element gets tweened</ Square >
85+ </ Tween >
86+ </ ScrollTrigger >
87+
88+ < ScrollTrigger trigger = { trigger } >
89+ < Tween
90+ to = { {
91+ x : '500px' ,
92+ } }
93+ >
94+ < Square className = "square" > This element gets tweened by ref</ Square >
95+ </ Tween >
96+ </ ScrollTrigger >
97+
98+ < ScrollTrigger
99+ start = "top center"
100+ end = "400px center"
101+ scrub = { 0.5 }
102+ markers = { true }
103+ pin = { true }
104+ once = { false }
105+ >
106+ < Tween
107+ to = { {
108+ x : '600px' ,
109+ } }
110+ >
111+ < Square className = "trigger" ref = { triggerRef } >
112+ This element is the trigger
113+ </ Square >
114+ </ Tween >
115+ </ ScrollTrigger >
116+
117+ < ScrollTrigger >
118+ < Tween
119+ to = { {
120+ x : '500px' ,
121+ } }
122+ >
123+ < Square className = "square" > This element gets tweened</ Square >
124+ </ Tween >
125+ < Tween
126+ to = { {
127+ x : '500px' ,
128+ } }
129+ >
130+ < Square className = "square" > This element gets tweened</ Square >
131+ </ Tween >
132+ </ ScrollTrigger >
133+
134+ < ScrollTrigger
135+ trigger = "trigger"
136+ start = "top center"
137+ end = "400px center"
138+ scrub = { 0.5 }
139+ markers = { true }
140+ pin = { true }
141+ >
142+ < Timeline target = { < TargetWithNames /> } >
143+ < Tween
144+ to = { {
145+ x : '500px' ,
146+ } }
147+ target = "div1"
148+ />
149+ < Tween
150+ to = { {
151+ x : '200px' ,
152+ } }
153+ stagger = { 0.2 }
154+ target = "div2"
155+ />
156+ < Tween
157+ to = { {
158+ x : '500px' ,
159+ } }
160+ target = "div3"
161+ />
162+ </ Timeline >
163+ </ ScrollTrigger >
164+
165+ < ScrollTrigger />
166+
167+ { /*<Container className="trigger">*/ }
168+ { /* <Tween*/ }
169+ { /* to={{*/ }
170+ { /* x: '500px',*/ }
171+ { /* scrollTrigger: {*/ }
172+ { /* trigger: '.trigger',*/ }
173+ { /* start: 'top center',*/ }
174+ { /* end: 'bottom center',*/ }
175+ { /* scrub: 0.5,*/ }
176+ { /* markers: true,*/ }
177+ { /* pin: true,*/ }
178+ { /* },*/ }
179+ { /* }}*/ }
180+ { /* >*/ }
181+ { /* <Square className="square">This element gets tweened</Square>*/ }
182+ { /* </Tween>*/ }
183+ { /*</Container>*/ }
184+ </ TweenStyled >
185+ </ >
186+ ) ;
187+ } ;
50188
51189export default TweenComponent ;
0 commit comments