1- import { on } from './events' ;
1+ import { on , once } from './events' ;
22import { debounceFrame } from './delays' ;
33
4- export function observeVisibility ( items , once ) {
5- if ( ! items || ! items . length ) return { off : ( ) => { } } ;
6-
7- const observer = new IntersectionObserver ( ( entries ) => {
8- console . log ( 'IntersectionObserver 2' , entries ) ;
9- entries . forEach ( entry => {
10- if ( entry . isIntersecting ) {
11- console . log ( 'is Intersecting' , entry ) ;
12- entry . target . classList . add ( 'is-in-view' ) ;
13- if ( once ) {
14- observer . unobserve ( entry . target ) ;
15- }
16- } else {
17- console . log ( 'not Intersecting' , entry ) ;
18- entry . target . classList . remove ( 'is-in-view' ) ;
19- }
20- } ) ;
21- } , {
22- threshold : 0.5
4+ /* global Promise */
5+ export function observeVisibility ( items , doOnce ) {
6+ if ( ! items || ! items . length ) return { off : ( ) => { } } ;
7+
8+ const observer = new IntersectionObserver ( ( entries ) => {
9+ //console.log('IntersectionObserver 2', entries);
10+ entries . forEach ( entry => {
11+ if ( entry . isIntersecting ) {
12+ //console.log('is Intersecting', entry);
13+ entry . target . classList . add ( 'is-in-view' ) ;
14+ if ( doOnce ) {
15+ observer . unobserve ( entry . target ) ;
16+ }
17+ } else {
18+ //console.log('not Intersecting', entry);
19+ entry . target . classList . remove ( 'is-in-view' ) ;
20+ }
2321 } ) ;
22+ } , { threshold : 0.5 } ) ;
2423
25- if ( items && items . length ) {
26- for ( let i = 0 ; i < items . length ; i ++ ) {
27- observer . observe ( items [ i ] ) ;
28- }
24+ if ( items && items . length ) {
25+ for ( let i = 0 ; i < items . length ; i ++ ) {
26+ observer . observe ( items [ i ] ) ;
2927 }
28+ }
3029
31- return {
32- off : ( ) => {
33- observer . disconnect ( ) ;
34- }
35- } ;
30+ return {
31+ off : ( ) => {
32+ observer . disconnect ( ) ;
33+ }
34+ } ;
3635}
3736
3837let vpW = window . innerWidth ;
3938let vpH = window . innerHeight ;
4039function elementIsVisible ( el ) {
41- // FIXME: performance issue, cache this somewhere
42- const rect = el . getBoundingClientRect ( ) ;
43- if ( rect . top <= - rect . height || rect . top >= vpH ) {
44- return false ;
45- }
40+ // FIXME: performance issue, cache this somewhere
41+ const rect = el . getBoundingClientRect ( ) ;
42+ if ( rect . top <= - rect . height || rect . top >= vpH ) {
43+ return false ;
44+ }
4645
47- if ( rect . left <= - rect . width || rect . left >= vpW ) {
48- return false ;
49- }
46+ if ( rect . left <= - rect . width || rect . left >= vpW ) {
47+ return false ;
48+ }
5049
51- return true ;
50+ return true ;
5251}
5352
54- function detectVisibility ( items , once ) {
55- items . forEach ( el => {
56- if ( once && el . classList . contains ( 'is-in-view' ) ) {
57- return ;
58- }
59-
60- if ( elementIsVisible ( el ) ) {
61- el . classList . add ( 'is-in-view' ) ;
62- } else {
63- el . classList . remove ( 'is-in-view' ) ;
64- }
53+ const isInView = el => el . classList . contains ( 'is-in-view' ) ;
54+
55+ function detectVisibility ( items , doOnce ) {
56+ return Promise . all ( items . map ( el => {
57+ return new Promise ( ( resolve ) => {
58+ if ( doOnce && isInView ( el ) ) {
59+ //console.log('This probably should not happen');
60+ resolve ( ) ;
61+ return ;
62+ }
63+
64+ if ( el . classList . contains ( 'is-animating' ) ) {
65+ resolve ( ) ;
66+ return ;
67+ }
68+
69+ if ( ! elementIsVisible ( el ) ) {
70+ el . classList . remove ( 'is-in-view' ) ;
71+ resolve ( ) ;
72+ } else if ( ! isInView ( el ) ) {
73+ once ( el , 'animationend' , ( ) => {
74+ el . classList . remove ( 'is-animating' ) ;
75+ resolve ( ) ;
76+ } ) ;
77+ el . classList . add ( 'is-animating' , 'is-in-view' ) ;
78+ } else {
79+ resolve ( ) ;
80+ }
6581 } ) ;
82+ } ) ) ;
6683}
6784
6885const listenerQueue = { } ;
6986function detectAnimationVisibility ( ) {
70- //console.log('detectAnimationVisibility');
87+ //console.log('detectAnimationVisibility');
7188
72- Object . keys ( listenerQueue ) . map ( key => listenerQueue [ key ] ) . forEach ( _ => {
73- detectVisibility ( _ . items , _ . once ) ;
74- } ) ;
89+ Object . keys ( listenerQueue ) . forEach ( key => {
90+ const _ = listenerQueue [ key ] ;
91+
92+ const p = detectVisibility ( _ . items , _ . once )
93+
94+ if ( _ . once ) {
95+ p . then ( ( ) => {
96+ _ . items = _ . items . filter ( el => ! isInView ( el ) ) ;
97+
98+ if ( ! _ . items . length && listenerQueue [ key ] ) {
99+ //console.log(key, 'has none left');
100+ delete listenerQueue [ key ] ;
101+ }
102+ } ) ;
103+ }
104+ } ) ;
75105}
76106
77107const debouncedDetectAnimationVisibility = debounceFrame ( ( ) => {
78- detectAnimationVisibility ( ) ;
108+ detectAnimationVisibility ( ) ;
79109} ) ;
80110
81111let activeVisibility ;
82112function listenOnChanges ( ) {
83- if ( ! activeVisibility ) {
84- let events = [
85- on ( window , 'resize' , ( ) => {
86- //console.log('resize');
87- vpW = window . innerWidth ;
88- vpH = window . innerHeight ;
89- debouncedDetectAnimationVisibility ( ) ;
90- } ) ,
91- on ( window , 'scroll' , ( ) => {
92- //console.log('scroll');
93- debouncedDetectAnimationVisibility ( ) ;
94- } )
95- ] ;
96-
113+ if ( ! activeVisibility ) {
114+ const events = [
115+ on ( window , 'resize' , ( ) => {
116+ //console.log('resize');
117+ vpW = window . innerWidth ;
118+ vpH = window . innerHeight ;
119+ debouncedDetectAnimationVisibility ( ) ;
120+ } ) ,
121+ on ( window , 'scroll' , ( ) => {
122+ //console.log('scroll');
97123 debouncedDetectAnimationVisibility ( ) ;
124+ } )
125+ ] ;
98126
99- activeVisibility = {
100- off : ( ) => {
101- events . forEach ( _ => _ . off ( ) ) ;
102- }
103- } ;
104- }
127+ debouncedDetectAnimationVisibility ( ) ;
105128
106- return activeVisibility ;
129+ activeVisibility = {
130+ off : ( ) => {
131+ events . forEach ( _ => _ . off ( ) ) ;
132+ }
133+ } ;
134+ }
135+
136+ return activeVisibility ;
107137}
108138
109- export function monitorVisibility ( selector , once ) {
110- if ( ! listenerQueue . hasOwnProperty ( selector ) ) {
111- const els = document . querySelectorAll ( selector ) ;
112- if ( els && els . length ) {
113- listenerQueue [ selector ] = {
114- items : els ,
115- once : once || false
116- } ;
117- listenOnChanges ( ) ;
118- }
139+ export function monitorVisibility ( selector , doOnce ) {
140+ if ( ! listenerQueue . hasOwnProperty ( selector ) ) {
141+ const els = Array . prototype . slice . call ( document . querySelectorAll ( selector ) ) ;
142+ if ( els && els . length ) {
143+ listenerQueue [ selector ] = {
144+ items : els ,
145+ once : doOnce || false
146+ } ;
147+ listenOnChanges ( ) ;
119148 }
149+ }
120150
121- return {
122- off : function ( ) {
123- activeVisibility && activeVisibility . off ( ) ;
124- }
125- } ;
126- }
151+ return {
152+ off : function ( ) {
153+ activeVisibility && activeVisibility . off ( ) ;
154+ }
155+ } ;
156+ }
0 commit comments