UNPKG

@pronotron/io

Version:

Reliable viewport tracking without missed targets, unlike the default IntersectionObserver API.

1 lines 3.08 kB
"use strict";var t=require("@pronotron/utils"),s=class{constructor(s=20,i=!0){this.t=new Map,this.i=new Map,this.h=0,this.o=0,this.u=0,this.l=0,this.p=0,this.v=0,this._=0,this.N=i,this.m=new t.NativeControlTable(11,i?Uint16Array:Float32Array,s),this.A=new t.IDPool(s)}addNode(t){if(this.t.has(t.ref))return console.warn("Node is already in the list.",t.ref),!1;{const s=this.A.get();this.t.set(t.ref,s),this.i.set(s,t);const i=this.F(t.dispatch.onFastForward);return this.m.add(s,{0:s,1:0,2:0,3:0,4:0,5:t.dispatch.onInViewport?1:0,6:t.dispatch[this.k.I]?1:0,7:t.dispatch[this.k.B]?1:0,8:t.dispatch[this.k.L]?1:0,9:t.dispatch[this.k.M]?1:0,10:i}),this.A.consume(s),this.P(s,t),s}}removeNode(t){const s=this.t.get(t);void 0!==s?this.T([s]):console.warn("IONode is not found in the list.",t)}setLastScroll(t){this.h=t}updatePositions(t){this._=t,this.S(),this.i.forEach((t,s)=>this.P(s,t))}updateViewportLayout(t,s){s<=t&&console.warn("Tracking area must be bigger than 0 units"),this.o=t,this.u=s,this.v=s-t}U(t,s){return s<this.l?1:t>this.p?3:2}T(t){for(const s of t){const t=this.i.get(s);this.t.delete(t.ref),this.i.delete(s),this.m.remove(s),this.A.release(s),t.onRemoveNode&&t.onRemoveNode()}}P(t,s){const{start:i,end:e}=s.getBounds(),h=s.offset||0,n=this.N?Math.round(i-h):i-h,o=this.N?Math.round(e+h):e+h;this.m.modifyByID(t,{1:n,2:o})}F(t){switch(t){case"skip_both":default:return 0;case"execute_both":return 1;case"execute_last":return 2}}O(){this.l=this.o+this.h,this.p=this.u+this.h}S(){if(this.N&&this._>65535&&this.m.table.constructor!==Uint32Array){const t=Uint32Array.from(this.m.table);this.m.table=t}}},i=class extends s{constructor(){super(...arguments),this.R={2:{1:(t,s)=>{this.V(t,s,7,this.k.B)},3:(t,s)=>{this.V(t,s,9,this.k.M)}},1:{2:(t,s)=>{this.V(t,s,6,this.k.I)},3:(t,s)=>{this.q(t,s,6,this.k.I,9,this.k.M)}},3:{2:(t,s)=>{this.V(t,s,8,this.k.L)},1:(t,s)=>{this.q(t,s,8,this.k.L,7,this.k.B)}}}}handleScroll(t){this.direction=t>this.h?this.j.C:this.j.D,this.h=t,this.O(),this.G()}G(){const{table:t,stride:s,usedSlots:i}=this.m;for(let e=0;e<i;e++){const i=e*s,h=t[i+0],n=t[i+1],o=t[i+2],r=t[i+4],a=this.U(n,o);if(r!==a&&(0!==r&&this.R[r][a](i,h),this.m.modifyByPosition(e,{4:a,3:2===a?1:0})),t[i+5]&&t[i+3]){const t=this.H(n,o,this.h,this.v);this.J(h,t)}}}V(t,s,i,e){const h=this.m.table;h[t+i]&&(h[t+i]=this.K(s,e))}q(t,s,i,e,h,n){const o=this.m.table[t+10];if(0!==o)switch(o){case 2:this.V(t,s,h,n);break;case 1:this.V(t,s,i,e),this.V(t,s,h,n)}}H(t,s,i,e){return 2*(s-i)/(e+(s-t))-1}J(t,s){this.i.get(t).dispatch.onInViewport(s)}K(t,s){const i=this.i.get(t).dispatch[s];return"limit"in i?(i.dispatch(),i.limit-=1,i.limit<1?0:1):(i(),1)}};exports.PronotronIOHorizontalObserver=class extends i{constructor(){super(...arguments),this.direction="right",this.j={C:"left",D:"right"},this.k={I:"onLeftEnter",B:"onLeftExit",L:"onRightEnter",M:"onRightExit"}}},exports.PronotronIOVerticalObserver=class extends i{constructor(){super(...arguments),this.direction="down",this.j={C:"down",D:"up"},this.k={I:"onTopEnter",B:"onTopExit",L:"onBottomEnter",M:"onBottomExit"}}};