1- ! function ( e , t ) { "function" == typeof define && define . amd ?define ( function ( ) { return e . vs = t ( ) } ) :"object" == typeof module && module . exports ?module . exports = e . vs = t ( ) :e . vs = t ( ) } ( this , function ( ) { function e ( e , t , r ) { var s = { } ; for ( i in t ) s [ i ] = n . map ( e , 0 , 1 , t [ i ] , r [ i ] ) ; return s . offset = e , s } function t ( e ) { return e . nodeName ?e :e [ 0 ] . nodeName ?e [ 0 ] :document . querySelector ( e ) } var n = { normalize :function ( e , t , n ) { return ( e - t ) / ( n - t ) } , interpolate :function ( e , t , n ) { return t + ( n - t ) * e } , map :function ( e , t , n , r , s ) { return e < t && ( e = t ) , e > n && ( e = n ) , this . interpolate ( this . normalize ( e , t , n ) , r , s ) } } ; return function ( r , s , a ) { function o ( t ) { u = t , p = u + h , pWhenStart < u + h * c . start . is && pWhenEnd > u + h * c . end . is && ! m ?( c . start . hasOwnProperty ( "call" ) && ! m && ( u > pTop ?c . start . call ( ! 1 ) :c . start . call ( ! 0 ) ) , m = ! 0 ) :( pWhenStart > u + h * c . start . is || pWhenEnd <= u + h * c . end . is ) && m ?( m = ! 1 , pWhenEnd > u + h * c . end . is ?( c . hasOwnProperty ( "scroll" ) && ( c . start . hasOwnProperty ( "vals" ) && c . end . hasOwnProperty ( "vals" ) ?c . scroll ( c . start . vals ) :c . scroll ( { offset :0 } ) ) , c . end . hasOwnProperty ( "call" ) && c . end . call ( ! 1 ) ) :( m = ! 1 , c . hasOwnProperty ( "scroll" ) && ( c . start . hasOwnProperty ( "vals" ) && c . end . hasOwnProperty ( "vals" ) ?c . scroll ( c . end . vals ) :c . scroll ( { offset :1 } ) ) , c . end . hasOwnProperty ( "call" ) && c . end . call ( ! 0 ) ) ) :y && ( y = ! 1 , c . scroll ( { offset :1 } ) ) , m && ( track1 = Math . floor ( u + h * c . start . is - pWhenStart ) , track2 = Math . floor ( pWhenEnd - ( u + h * c . end . is ) ) , trackPerc = n . map ( track1 , 0 , track1 + track2 , 0 , 1 ) , c . hasOwnProperty ( "scroll" ) && ( c . start . hasOwnProperty ( "vals" ) && c . end . hasOwnProperty ( "vals" ) ?c . scroll ( e ( trackPerc , c . start . vals , c . end . vals ) ) :c . scroll ( { offset :trackPerc } ) ) ) } function i ( e ) { f = window . scrollY , w || ( window . requestAnimationFrame ( function ( ) { l ( ) , o ( f ) , w = ! 1 } ) , w = ! 0 ) } function l ( ) { h = window . innerHeight , u = f , p = Math . abs ( u ) + h , pTop = v . offsetTop , pHeight = v . clientHeight , pWhenStart = pTop + pHeight * c . start . when , pWhenEnd = pTop + pHeight * c . end . when } var c = { condition :1 , start :{ } , end :{ } , override :! 1 } ; if ( c . scroll = function ( e ) { c . override || s . seek ( s . totalDuration ( ) * e . offset ) } , void 0 !== a && "object" == typeof a ) for ( var d in c ) a . hasOwnProperty ( d ) && ( "scroll" === d ?( c . userScroll = a [ d ] , c [ d ] = function ( e ) { c . userScroll ( e ) , c . override || s . seek ( s . totalDuration ( ) * e . offset ) } ) :c [ d ] = a [ d ] ) ; switch ( c . condition ) { case 1 :c . start . when = 0 , c . start . is = 1 , c . end . when = 1 , c . end . is = 0 ; break ; case 2 :c . start . when = 1 , c . start . is = 1 , c . end . when = 0 , c . end . is = 0 ; break ; case 3 :c . start . when = 0 , c . start . is = 0 , c . end . when = 1 , c . end . is = 1 ; break ; case 4 :c . start . when = 0 , c . start . is = 0 , c . end . when = 1 , c . end . is = 0 ; break ; case 5 :c . start . when = 0 , c . start . is = 1 , c . end . when = 1 , c . end . is = 1 ; break ; case 6 :c . start . when = Number ( a . start . when . split ( "%" ) [ 0 ] ) / 100 , c . start . is = Number ( a . start . is . split ( "%" ) [ 0 ] ) / 100 , c . end . when = Number ( a . end . when . split ( "%" ) [ 0 ] ) / 100 , c . end . is = Number ( a . end . is . split ( "%" ) [ 0 ] ) / 100 } var h , p , f = window . scrollY , w = ! 1 , u = ( window , 0 ) , v = t ( r ) , m = ! 1 , y = ! 0 ; return window . addEventListener ( "scroll" , i ) , window . addEventListener ( "resize" , function ( ) { l ( ) , o ( f ) } , { passive :! 0 } ) , l ( ) , o ( f ) , ! 1 } } ) ;
1+ ( function ( root , factory ) {
2+ if ( typeof define === "function" && define . amd ) {
3+ // Now we're wrapping the factory and assigning the return
4+ // value to the root (window) and returning it as well to
5+ // the AMD loader.
6+ define ( function ( ) {
7+ return ( root . vs = factory ( ) ) ;
8+ } ) ;
9+ } else if ( typeof module === "object" && module . exports ) {
10+ // I've not encountered a need for this yet, since I haven't
11+ // run into a scenario where plain modules depend on CommonJS
12+ // *and* I happen to be loading in a CJS browser environment
13+ // but I'm including it for the sake of being thorough
14+ module . exports = ( root . vs = factory ( ) ) ;
15+ } else {
16+ root . vs = factory ( ) ;
17+ }
18+ } ( this , function ( ) {
19+ //Mathutils never fails me!
20+ var Mathutils = {
21+ normalize : function ( $value , $min , $max ) {
22+ return ( $value - $min ) / ( $max - $min ) ;
23+ } ,
24+ interpolate : function ( $normValue , $min , $max ) {
25+ return $min + ( $max - $min ) * $normValue ;
26+ } ,
27+ map : function ( $value , $min1 , $max1 , $min2 , $max2 ) {
28+ if ( $value < $min1 ) {
29+ $value = $min1 ;
30+ }
31+ if ( $value > $max1 ) {
32+ $value = $max1 ;
33+ }
34+ return this . interpolate ( this . normalize ( $value , $min1 , $max1 ) , $min2 , $max2 ) ;
35+ }
36+ } ;
37+ // pure functions
38+ function equalize ( perc , from , to ) {
39+ var tmpVals = { } ;
40+ for ( i in from ) {
41+ tmpVals [ i ] = Mathutils . map ( perc , 0 , 1 , from [ i ] , to [ i ] ) ;
42+ }
43+ tmpVals . offset = perc ;
44+ return tmpVals ;
45+ }
46+
47+
48+ function $$ ( el ) {
49+ return el . nodeName ? el : el [ 0 ] . nodeName ? el [ 0 ] : document . querySelector ( el ) ;
50+ }
51+
52+ /*
53+ I want to change this to this format
54+ vs(squareAnimation, {
55+ trigger: ".section-two",
56+ start: "top top",
57+ end: "bottom bottom"
58+ });
59+ */
60+
61+ //Animate GSAP Timelines as you scroll.
62+ var vs = function ( timeline , options ) {
63+
64+
65+ // base options
66+ var defaults = {
67+ trigger : undefined ,
68+ start : "top bottom" ,
69+ end : "bottom top" ,
70+ override : false
71+ }
72+
73+ var presets = {
74+ "top" : 0 ,
75+ "middle" : .5 ,
76+ "bottom" : 1
77+ }
78+
79+ defaults . scroll = function ( options ) {
80+ if ( ! defaults . override ) {
81+ timeline . seek ( timeline . totalDuration ( ) * options . offset ) ;
82+ }
83+ }
84+
85+
86+ //it might be a config object
87+ // override with options
88+ if ( options !== undefined && typeof ( options ) == "object" ) {
89+ for ( var key in defaults ) {
90+ if ( options . hasOwnProperty ( key ) ) {
91+ if ( key === "scroll" ) {
92+ defaults . userScroll = options [ key ] ;
93+ defaults [ key ] = function ( options ) {
94+ defaults . userScroll ( options ) ;
95+ if ( ! defaults . override ) {
96+ timeline . seek ( timeline . totalDuration ( ) * options . offset ) ;
97+ }
98+ }
99+ } else {
100+ defaults [ key ] = options [ key ] ;
101+ }
102+ }
103+ }
104+ }
105+
106+
107+
108+ //start
109+ var startSplit = defaults . start . split ( " " ) ;
110+ defaults . start = { } ;
111+ //lets do the first one
112+ //is the start.when a percentage?
113+ if ( startSplit [ 0 ] . indexOf ( "%" ) > - 1 ) {
114+ defaults . start . when = Number ( startSplit [ 0 ] . split ( "%" ) [ 0 ] ) / 100 ;
115+ } else {
116+ //check for word: top, middle, bottom
117+ defaults . start . when = presets [ startSplit [ 0 ] ] ;
118+ }
119+
120+ if ( startSplit [ 1 ] . indexOf ( "%" ) > - 1 ) {
121+ defaults . start . is = Number ( startSplit [ 1 ] . split ( "%" ) [ 0 ] ) / 100 ;
122+ } else {
123+ defaults . start . is = presets [ startSplit [ 1 ] ] ;
124+ }
125+
126+
127+
128+ var stopSplit = defaults . end . split ( " " ) ;
129+ //lets do the second one
130+ defaults . end = { } ;
131+ if ( stopSplit [ 0 ] . indexOf ( "%" ) > - 1 ) {
132+ defaults . end . when = Number ( stopSplit [ 0 ] . split ( "%" ) [ 0 ] ) / 100 ;
133+ } else {
134+ //check for word: top, middle, bottom
135+ defaults . end . when = presets [ stopSplit [ 0 ] ] ;
136+ }
137+
138+ if ( stopSplit [ 1 ] . indexOf ( "%" ) > - 1 ) {
139+ defaults . end . is = Number ( stopSplit [ 1 ] . split ( "%" ) [ 0 ] ) / 100 ;
140+ } else {
141+ defaults . end . is = presets [ stopSplit [ 1 ] ] ;
142+ }
143+
144+ // MONITOR THESE
145+ var last_known_scroll_position = window . scrollY ,
146+ ticking = false ,
147+ $win = window ,
148+ wHeight ,
149+ wBottom ,
150+ wTop = 0 ,
151+ i ,
152+ tmpVals ,
153+ $tmpPiggy = $$ ( defaults . trigger ) ,
154+ active = false ,
155+ firstLoad = true ;
156+
157+ function doSomething ( scroll_pos ) {
158+ wTop = scroll_pos ;
159+ wBottom = wTop + wHeight ;
160+
161+
162+ //check if we're inside the window start and end.
163+ if ( pWhenStart <= wTop + ( wHeight * defaults . start . is ) &&
164+ pWhenEnd > wTop + ( wHeight * defaults . end . is ) &&
165+ ! active ) {
166+
167+ //call once if we haven't activated yet, and call() exists
168+ if ( defaults . start . hasOwnProperty ( "call" ) && ! active ) {
169+
170+ //check if it's coming on from the bottom
171+ //console.log(pTop, pHeight, pWhenStart, pWhenEnd, wTop);
172+ if ( wTop > pTop ) {
173+ defaults . start . call ( false ) ;
174+ } else {
175+ defaults . start . call ( true ) ;
176+ }
177+
178+ }
179+ active = true ;
180+
181+
182+ } else if ( ( pWhenStart > wTop + ( wHeight * defaults . start . is ) ||
183+ pWhenEnd <= wTop + ( wHeight * defaults . end . is ) ) &&
184+ active ) {
185+
186+ //nice - deactivate
187+ active = false ;
188+
189+
190+ //when deactivating, check if its off the bottom, or off the top, and force a scroll call
191+
192+ if ( ( pWhenEnd > wTop + ( wHeight * defaults . end . is ) ) ) {
193+ //off bottom
194+
195+ //if we have values to check, equalize the values proportionally to trackPerc
196+ if ( defaults . hasOwnProperty ( "scroll" ) ) {
197+ if ( defaults . start . hasOwnProperty ( "vals" ) && defaults . end . hasOwnProperty ( "vals" ) ) {
198+ defaults . scroll ( defaults . start . vals ) ;
199+ } else {
200+ defaults . scroll ( {
201+ offset : 0
202+ } ) ;
203+ }
204+ }
205+
206+ if ( defaults . end . hasOwnProperty ( "call" ) ) {
207+ defaults . end . call ( false ) ;
208+ }
209+
210+ } else {
211+ active = false ;
212+ if ( defaults . hasOwnProperty ( "scroll" ) ) {
213+ if ( defaults . start . hasOwnProperty ( "vals" ) && defaults . end . hasOwnProperty ( "vals" ) ) {
214+ defaults . scroll ( defaults . end . vals ) ;
215+ } else {
216+ defaults . scroll ( {
217+ offset : 1
218+ } ) ;
219+ }
220+ }
221+
222+ if ( defaults . end . hasOwnProperty ( "call" ) ) {
223+ defaults . end . call ( true ) ;
224+ }
225+
226+ }
227+ } else if ( firstLoad ) {
228+ firstLoad = false ;
229+ //todo check if it's above or below
230+
231+ //for now, I' just gonna put it on it's end
232+ defaults . scroll ( {
233+ offset : 1
234+ } ) ;
235+ }
236+
237+ //If a scroll is active I'd like to know how far through it is.
238+ if ( active ) {
239+ track1 = Math . floor ( wTop + ( wHeight * defaults . start . is ) - pWhenStart ) ;
240+ track2 = Math . floor ( pWhenEnd - ( wTop + ( wHeight * defaults . end . is ) ) ) ;
241+ trackPerc = Mathutils . map ( track1 , 0 , track1 + track2 , 0 , 1 ) ;
242+
243+
244+
245+ //if we have values to check, equalize the values proportionally to trackPerc
246+ if ( defaults . hasOwnProperty ( "scroll" ) ) {
247+ if ( defaults . start . hasOwnProperty ( "vals" ) && defaults . end . hasOwnProperty ( "vals" ) ) {
248+ defaults . scroll ( equalize ( trackPerc , defaults . start . vals , defaults . end . vals ) ) ;
249+ } else {
250+ defaults . scroll ( {
251+ offset : trackPerc
252+ } ) ;
253+ }
254+ }
255+ }
256+ }
257+
258+ function scrollHandler ( e ) {
259+ last_known_scroll_position = window . scrollY ;
260+
261+ if ( ! ticking ) {
262+
263+ window . requestAnimationFrame ( function ( ) {
264+ recalculate ( ) ;
265+ doSomething ( last_known_scroll_position ) ;
266+ ticking = false ;
267+ } ) ;
268+
269+ ticking = true ;
270+
271+ }
272+ }
273+
274+ window . addEventListener ( 'scroll' , scrollHandler ) ;
275+
276+
277+ function recalculate ( ) {
278+ wHeight = window . innerHeight ;
279+ wTop = last_known_scroll_position ;
280+ wBottom = Math . abs ( wTop ) + wHeight ;
281+
282+ pTop = $tmpPiggy . offsetTop ;
283+ pHeight = $tmpPiggy . clientHeight ;
284+ pWhenStart = pTop + ( pHeight * defaults . start . when ) ;
285+ pWhenEnd = pTop + ( pHeight * defaults . end . when ) ;
286+ }
287+
288+
289+
290+
291+ //set winHeight on resize
292+ window . addEventListener ( 'resize' , function ( ) {
293+ recalculate ( ) ;
294+ doSomething ( last_known_scroll_position ) ;
295+ } , {
296+ passive : true
297+ } ) ;
298+
299+ recalculate ( ) ;
300+ doSomething ( last_known_scroll_position ) ;
301+
302+ return false ;
303+ }
304+
305+ return vs ;
306+ } ) ) ;
0 commit comments