UNPKG

the-finger

Version:

JavaScript library to detect touch gestures: tap, double tap, press, long press, drag, flick, rotate, pinch, spread, pan, two-finger.

2 lines (1 loc) 11.7 kB
(function(c,f){typeof exports=="object"&&typeof module<"u"?module.exports=f():typeof define=="function"&&define.amd?define(f):(c=typeof globalThis<"u"?globalThis:c||self,c.TheFinger=f())})(this,function(){"use strict";var gt=Object.defineProperty;var nt=c=>{throw TypeError(c)};var pt=(c,f,x)=>f in c?gt(c,f,{enumerable:!0,configurable:!0,writable:!0,value:x}):c[f]=x;var ht=(c,f,x)=>pt(c,typeof f!="symbol"?f+"":f,x),tt=(c,f,x)=>f.has(c)||nt("Cannot "+x);var t=(c,f,x)=>(tt(c,f,"read from private field"),x?x.call(c):f.get(c)),g=(c,f,x)=>f.has(c)?nt("Cannot add the same private member more than once"):f instanceof WeakSet?f.add(c):f.set(c,x),l=(c,f,x,S)=>(tt(c,f,"write to private field"),S?S.call(c,x):f.set(c,x),x),u=(c,f,x)=>(tt(c,f,"access private method"),x);var et=(c,f,x,S)=>({set _(k){l(c,f,k,x)},get _(){return t(c,f,S)}});var S,k,T,_,R,z,d,U,N,E,X,j,G,B,K,M,C,m,I,q,w,b,y,P,D,F,O,H,o,rt,lt,ot,at,ct,ut,Z,W,$,st,ft,V,J,dt,it,Q;const c={PRESS_TIME:350,DOUBLE_TAP_INTERVAL:250,FLICK_THRESHOLD:.75,DOUBLE_TAP_DRAG_THRESHOLD:5},f=new WeakMap;class x{constructor(e,s={}){g(this,o);g(this,S);g(this,k);g(this,T);g(this,_,null);g(this,R,!1);g(this,z);g(this,d,{});g(this,U);g(this,N);g(this,E);g(this,X);g(this,j);g(this,G);g(this,B);g(this,K);g(this,M,null);g(this,C,null);g(this,m,0);g(this,I,!1);g(this,q);g(this,w,{});g(this,b,{});g(this,y,new Map);g(this,P,[]);g(this,D);g(this,F,!1);g(this,O,null);ht(this,"gestures",{press:{start:()=>(l(this,_,"press"),{type:"press",data:{x:t(this,E),y:t(this,X)}}),move:()=>{},end:()=>{}},tap:{start:()=>{},move:()=>{clearTimeout(t(this,z))},end:(e,s)=>!t(this,R)&&s-t(this,U)<c.PRESS_TIME?(clearTimeout(t(this,z)),s<t(this,N)+c.DOUBLE_TAP_INTERVAL+c.PRESS_TIME?(l(this,N,null),{type:"double-tap",data:{x:t(this,E),y:t(this,X)}}):(l(this,N,s),{type:"tap",data:{x:t(this,E),y:t(this,X)}})):null},"two-finger-tap":{start:()=>{},move:()=>{},end:(e,s)=>{if(t(this,P).length===2&&!t(this,R)&&s-t(this,U)<c.PRESS_TIME){const i=[...t(this,y).values()].map(n=>({x:n.x[0],y:n.y[0]}));if(i.length===2){const n=(i[0].x+i[1].x)/2,h=(i[0].y+i[1].y)/2;return{type:"two-finger-tap",data:{x:n,y:h,touches:i}}}}return null}},"long-press":{start:(e,s)=>{e.length===1&&l(this,z,setTimeout(()=>{l(this,_,"long-press"),l(this,d,{x:t(this,E),y:t(this,X)}),u(this,o,Q).call(this,"long-press",[t(this,d)])},c.PRESS_TIME))},move:()=>{clearTimeout(t(this,z))},end:()=>{clearTimeout(t(this,z))}},drag:{start:()=>{},move:e=>{if(e.length!==1)return null;const s=e[0],i=s.clientX-t(this,T).left,n=s.clientY-t(this,T).top,{prevX:h,prevY:r}=u(this,o,it).call(this,e,t(this,E),t(this,X));return l(this,d,{x:i,y:n,startX:t(this,E),startY:t(this,X),step:u(this,o,Z).call(this),speed:u(this,o,W).call(this),angle:u(this,o,V).call(this,h,r,i,n)}),t(this,D)||(l(this,D,u(this,o,J).call(this,t(this,E),t(this,X),i,n)),t(this,d).initial_direction=t(this,D)),{type:"drag",data:t(this,d)}},end:()=>{var n,h;if(!t(this,R)||t(this,y).size===0||t(this,_)!=="drag")return null;const e=t(this,y).values().next().value;if(!((n=e==null?void 0:e.x)!=null&&n.length)||!((h=e==null?void 0:e.y)!=null&&h.length))return null;const s=e.x,i=e.y;return l(this,j,s[s.length-1]),l(this,G,i[i.length-1]),t(this,d).endX=t(this,j),t(this,d).endY=t(this,G),t(this,d).speed=u(this,o,W).call(this),t(this,d).initial_direction=t(this,D),s.length>1&&i.length>1&&(t(this,d).final_direction=u(this,o,J).call(this,s[s.length-2],i[i.length-2],t(this,d).endX,t(this,d).endY)),t(this,d).flick=t(this,d).speed>=c.FLICK_THRESHOLD,{type:"drag",data:t(this,d)}}},pan:{start:e=>{if(e.length<2)return null;const{x:s,y:i}=u(this,o,st).call(this,e);l(this,E,s),l(this,X,i)},move:e=>{if(e.length<2)return null;const{x:s,y:i,touchesArr:n}=u(this,o,st).call(this,e),{prevX:h,prevY:r}=u(this,o,it).call(this,e,t(this,E),t(this,X));return l(this,d,{touches:n,x:s,y:i,startX:t(this,E),startY:t(this,X),step:u(this,o,Z).call(this),speed:u(this,o,W).call(this),angle:u(this,o,V).call(this,h,r,s,i)}),t(this,D)||(l(this,D,u(this,o,J).call(this,t(this,E),t(this,X),s,i)),t(this,d).initial_direction=t(this,D)),{type:"pan",data:t(this,d)}},end:()=>{if(t(this,P).length<2||!t(this,R)||t(this,y).size===0)return null;const e=[...t(this,y).values()].map(L=>({x:L.x[L.x.length-1],y:L.y[L.y.length-1]})),s=e.length,i=e.reduce((L,A)=>L+A.x,0)/s,n=e.reduce((L,A)=>L+A.y,0)/s;let h=t(this,d).x||t(this,E),r=t(this,d).y||t(this,X),a=0,p=0,Y=0;for(const[L,A]of t(this,y).entries())A.x.length>=5&&A.y.length>=5&&(a+=A.x[A.x.length-5],p+=A.y[A.y.length-5],Y++);Y>0&&(h=a/Y,r=p/Y);const v=u(this,o,W).call(this);return l(this,d,{touches:e,x:i,y:n,startX:t(this,E),startY:t(this,X),step:u(this,o,Z).call(this),speed:v,angle:u(this,o,V).call(this,h,r,i,n),endX:i,endY:n,initial_direction:t(this,D),final_direction:u(this,o,J).call(this,t(this,E),t(this,X),i,n),flick:v>=c.FLICK_THRESHOLD}),{type:"pan",data:t(this,d)}}},rotate:{start:e=>{if(e.length!==2)return;const[s,i]=e,n=s.clientX,h=s.clientY,r=i.clientX,a=i.clientY;l(this,B,u(this,o,V).call(this,n,h,r,a)),l(this,K,t(this,B)>180?360*t(this,m)+t(this,B)-360:360*t(this,m)+t(this,B))},move:e=>{if(e.length!==2)return null;const[s,i]=e,n=s.clientX,h=s.clientY,r=i.clientX,a=i.clientY,p=u(this,o,V).call(this,n,h,r,a);u(this,o,dt).call(this,p);const Y={touches:[{x:n,y:h},{x:r,y:a}],rotation:t(this,C)-t(this,K),angleAbsolute:p,angleRelative:t(this,C)};return l(this,d,Y),{type:"rotate",data:Y}},end:()=>{}},"pinch-spread":{start:e=>{if(e.length!==2)return;const[s,i]=e,n=s.clientX,h=s.clientY,r=i.clientX,a=i.clientY;l(this,q,u(this,o,$).call(this,n,h,r,a))},move:e=>{if(e.length!==2||!t(this,w)["pinch-spread"])return null;const[s,i]=e,n=s.clientX,h=s.clientY,r=i.clientX,a=i.clientY,p=u(this,o,$).call(this,n,h,r,a),Y=u(this,o,ft).call(this,t(this,q),p),v={touches:[{x:n,y:h},{x:r,y:a}],distance:p,scale:Y};return l(this,d,v),{type:"pinch-spread",data:v}},end:()=>t(this,_)!=="pinch-spread"||!t(this,R)||t(this,y).size===0?null:(t(this,d).end=!0,{type:"pinch-spread",data:t(this,d)})},"double-tap-and-drag":{start:(e,s)=>{if(e.length===1)if(t(this,N)&&s<t(this,N)+c.DOUBLE_TAP_INTERVAL+c.PRESS_TIME){l(this,F,!0);const i=e[0];l(this,O,{x:i.clientX-t(this,T).left,y:i.clientY-t(this,T).top})}else l(this,F,!1)},move:(e,s)=>{if(!t(this,F)||e.length!==1)return null;const i=e[0],n=i.clientX-t(this,T).left,h=i.clientY-t(this,T).top,r=n-t(this,O).x,a=h-t(this,O).y,p=Math.sqrt(r*r+a*a);return p>c.DOUBLE_TAP_DRAG_THRESHOLD?(l(this,_,"double-tap-and-drag"),l(this,d,{x:n,y:h,startX:t(this,O).x,startY:t(this,O).y,dx:r,dy:a,dist:p}),{type:"double-tap-and-drag",data:t(this,d)}):null},end:()=>{l(this,F,!1),l(this,O,null)}}});g(this,H,e=>{var h,r;(h=t(this,k))!=null&&h.preventDefault&&e.preventDefault();const{touches:s,type:i,timeStamp:n}=e;switch(i){case"touchstart":u(this,o,rt).call(this,s,n);break;case"touchmove":u(this,o,lt).call(this,s,n);break;case"touchend":u(this,o,ot).call(this,s,n);break}u(this,o,at).call(this,e),(r=t(this,k))!=null&&r.visualize&&visualize(s)});l(this,S,e),l(this,k,s),e&&this.on(e)}on(e){l(this,S,e),e.addEventListener("touchstart",t(this,H)),e.addEventListener("touchmove",t(this,H)),e.addEventListener("touchend",t(this,H)),f.set(e,{})}off(e){e=e||t(this,S),e.removeEventListener("touchstart",t(this,H)),e.removeEventListener("touchmove",t(this,H)),e.removeEventListener("touchend",t(this,H)),f.delete(e)}track(e,s,i){t(this,w)[e]=s,i&&(i.preventDefault===!0&&(t(this,b)[e]=!0),i.preventDefault==="horizontal"&&(t(this,b)[e]="horizontal"),i.preventDefault==="vertical"&&(t(this,b)[e]="vertical"))}untrack(e){delete t(this,w)[e]}}return S=new WeakMap,k=new WeakMap,T=new WeakMap,_=new WeakMap,R=new WeakMap,z=new WeakMap,d=new WeakMap,U=new WeakMap,N=new WeakMap,E=new WeakMap,X=new WeakMap,j=new WeakMap,G=new WeakMap,B=new WeakMap,K=new WeakMap,M=new WeakMap,C=new WeakMap,m=new WeakMap,I=new WeakMap,q=new WeakMap,w=new WeakMap,b=new WeakMap,y=new WeakMap,P=new WeakMap,D=new WeakMap,F=new WeakMap,O=new WeakMap,H=new WeakMap,o=new WeakSet,rt=function(e,s){l(this,U,s),l(this,M,null),l(this,C,null),l(this,m,0),l(this,I,!1),l(this,_,null),u(this,o,ct).call(this,e,s);const i=Object.values(this.gestures);for(let n=0;n<i.length;n++){const h=i[n];if(h.start){const r=h.start(e,s);r&&(l(this,_,r.type),u(this,o,Q).call(this,r.type,[r.data,t(this,y)]))}}},lt=function(e,s){l(this,R,!0),u(this,o,ut).call(this,e,s);const i=Object.values(this.gestures);for(let n=0;n<i.length;n++){const h=i[n];if(h.move){const r=h.move(e,s);r&&(l(this,_,r.type),u(this,o,Q).call(this,r.type,[r.data,t(this,y)]))}}},ot=function(e,s){const i=Object.values(this.gestures);for(let n=0;n<i.length;n++){const h=i[n];if(h.end){const r=h.end(e,s);r&&(l(this,_,r.type),u(this,o,Q).call(this,r.type,[r.data,t(this,y)]))}}e.length===0&&(l(this,y,new Map),l(this,P,[])),l(this,R,!1),l(this,D,null)},at=function(e){if(t(this,b)[t(this,_)]===!0){e.preventDefault();return}const s=t(this,d).angle;s==null||Number.isNaN(s)||(t(this,b)[t(this,_)]==="horizontal"?(s>45&&s<135||s>225&&s<315)&&e.preventDefault():t(this,b)[t(this,_)]==="vertical"&&(s>315||s<45||s>135&&s<225)&&e.preventDefault())},ct=function(e,s){l(this,T,t(this,S).getBoundingClientRect());for(const i of e){const n=i.identifier;if(!t(this,y).has(n)){const h=i.clientX-t(this,T).left,r=i.clientY-t(this,T).top;l(this,E,h),l(this,X,r),t(this,y).set(n,{x:[h],y:[r],t:[s]}),t(this,P).push(n)}}},ut=function(e,s){if(t(this,y).size!==0)for(const i of e){const n=t(this,y).get(i.identifier);n&&(n.x.push(i.clientX-t(this,T).left),n.y.push(i.clientY-t(this,T).top),n.t.push(s))}},Z=function(){let e=0;const s=t(this,P).length;for(let i=0;i<s;i++){const n=t(this,P)[i],h=t(this,y).get(n);if(h&&h.x.length>1){const r=h.x;e=Math.abs(r[r.length-1]-r[r.length-2]);break}}return e},W=function(){var Y,v,L;const e=t(this,P)[0],s=t(this,y).get(e);if(!((Y=s==null?void 0:s.x)!=null&&Y.length)||!((v=s==null?void 0:s.y)!=null&&v.length)||!((L=s==null?void 0:s.t)!=null&&L.length))return 0;const i=Math.min(5,s.x.length),n=s.x.slice(-i),h=s.y.slice(-i),r=s.t.slice(-i),a=r[r.length-1]-r[0];return a===0?0:u(this,o,$).call(this,n[0],h[0],n[n.length-1],h[h.length-1])/a},$=function(e,s,i,n){return Math.hypot(i-e,n-s)},st=function(e){const s=e.length;let i=0,n=0;for(let a=0;a<s;a++)i+=e[a].clientX-t(this,T).left,n+=e[a].clientY-t(this,T).top;const h=i/s,r=n/s;return{x:h,y:r,touchesArr:Array.from(e).map(a=>({x:a.clientX-t(this,T).left,y:a.clientY-t(this,T).top}))}},ft=function(e,s){return s/e},V=function(e,s,i,n){const h=i-e,r=n-s;let p=Math.atan2(r,h)*180/Math.PI+90;return p<0&&(p+=360),p>360&&(p-=360),p},J=function(e,s,i,n){const h=u(this,o,V).call(this,e,s,i,n);if(h>=315||h<45)return"top";if(h>=45&&h<135)return"right";if(h>=135&&h<225)return"bottom";if(h>=225&&h<315)return"left"},dt=function(e){if(t(this,M)===null){l(this,M,e);return}e-t(this,M)<=-180?t(this,I)?(l(this,m,0),l(this,I,!1)):et(this,m)._++:e-t(this,M)>=180&&(t(this,m)===0&&!t(this,I)?l(this,I,!0):et(this,m)._--),l(this,C,t(this,I)||t(this,m)<0?360*t(this,m)+e-360:360*t(this,m)+e),l(this,M,e)},it=function(e,s,i){let n=s,h=i;if(e.length>1){let r=0,a=0,p=0;for(const Y of e){const v=t(this,y).get(Y.identifier);v&&v.x.length>=5&&v.y.length>=5&&(r+=v.x[v.x.length-5],a+=v.y[v.y.length-5],p++)}if(p>0)return n=r/p,h=a/p,{prevX:n,prevY:h};r=0,a=0,p=0;for(const Y of e){const v=t(this,y).get(Y.identifier);v&&v.x.length>0&&v.y.length>0&&(r+=v.x[0],a+=v.y[0],p++)}p>0&&(n=r/p,h=a/p)}else if(e.length===1){const r=e[0].identifier,a=t(this,y).get(r);a&&a.x.length>1&&a.y.length>1&&(a.x.length>=5?(n=a.x[a.x.length-5],h=a.y[a.y.length-5]):(n=a.x[0],h=a.y[0]))}return{prevX:n,prevY:h}},Q=function(e,s){t(this,y).size>0&&t(this,w)[e]&&t(this,w)[e].apply(this,s)},x});