tocada
Version:
Touch events with ease! (Inspired by the wonderful Tocca.js library). Written in Typescript with love
4 lines (2 loc) • 3.89 kB
JavaScript
function F(C,L){if(C<L)return L-C;else return C-L}function G(C,L){const b=C.clientX-L.clientX,j=C.clientY-L.clientY;return Math.hypot(b,j)}function w(C,L={}){return new H(C,L)}class H{element;endPressure=0;startingElement=null;startPressure=0;startTime=0;startX=0;startY=0;touchedElements=[];activeTouches=0;gestureStartDistance=0;isMultiTouch=!1;latestGestureDistance=0;touchCount=0;thresholds;eventPrefix="";constructor(C,L={}){if(this.element=typeof C==="string"?document.querySelector(C):C,!this.element){console.error("Element not found");return}const{thresholds:b={},eventPrefix:j=""}=L;this.thresholds={swipeThreshold:b.swipeThreshold||50},this.eventPrefix=j,this.element.addEventListener("touchstart",this.handleTouchStart,!1),this.element.addEventListener("touchmove",this.handleTouchMove,!1),this.element.addEventListener("touchend",this.handleTouchEnd,!1)}destroy=()=>{this.element?.removeEventListener("touchstart",this.handleTouchStart),this.element?.removeEventListener("touchmove",this.handleTouchMove),this.element?.removeEventListener("touchend",this.handleTouchEnd)};handleTouchStart=(C)=>{if(this.activeTouches+=C.changedTouches.length,this.touchCount=C.touches.length,this.activeTouches>1)this.isMultiTouch=!0,this.gestureStartDistance=G(C.touches[0],C.touches[1]),this.handleGestureStart(C);else this.isMultiTouch=!1,this.handleSwipeStart(C)};handleTouchMove=(C)=>{C.preventDefault();const L=C.touches[0].clientX,b=C.touches[0].clientY,j=document.elementFromPoint(L,b);if(j)this.touchedElements.push(j);if(this.isMultiTouch)this.handleGestureMove(C)};handleTouchEnd=(C)=>{if(this.activeTouches>=2)this.handleGestureEnd(C),this.touchCount=0;else if(this.activeTouches===1)this.handleSwipeEnd(C),this.touchCount=0;this.activeTouches-=C.changedTouches.length};handleSwipeStart=(C)=>{const L=C.touches[0];this.startX=L.clientX,this.startY=L.clientY,this.startTime=Date.now(),this.startPressure=L.force||0,this.startingElement=document.elementsFromPoint(this.startX,this.startY)[0],this.touchedElements.push(this.startingElement)};handleSwipeEnd=(C)=>{if(!this.isMultiTouch&&this.touchCount===1){const L=C.changedTouches[0],b=Date.now(),j=b-this.startTime,k=F(this.startX,L.clientX),z=F(this.startY,L.clientY),I=Math.abs(k),J=Math.abs(z),A=Math.hypot(I,J);if(A>this.thresholds.swipeThreshold){const M=k/j,Q=z/j,R=A/j;this.endPressure=L.force||0;const U=(this.startPressure+this.endPressure)/2,V=document.elementFromPoint(L.clientX,L.clientY),K={velocityX:M,velocityY:Q,velocity:R,avgPressure:U,startPressure:this.startPressure,endPressure:this.endPressure,startTime:this.startTime,endTime:b,distanceX:I,distanceY:J,distance:A,startingElement:this.startingElement,endingElement:V,touchedElements:this.touchedElements,startingCoords:{x:this.startX,y:this.startY},endingCoords:{x:L.clientX,y:L.clientY}};this.dispatchSwipeEvent("swipe",K);const W=this.startX<L.clientX?"swiperight":"swipeleft",Z=this.startY<L.clientY?"swipedown":"swipeup",_=k>z?W:Z;this.dispatchSwipeEvent(_,K),this.reset()}}};handleGestureStart=(C)=>{this.isMultiTouch=!0};handleGestureMove=(C)=>{this.latestGestureDistance=G(C.touches[0],C.touches[1])};handleGestureEnd=(C)=>{if(this.dispatchGestureEvent("gesture"),this.latestGestureDistance<this.gestureStartDistance)this.dispatchGestureEvent("pinch");else this.dispatchGestureEvent("spread");this.reset()};dispatchSwipeEvent=(C,L)=>{const b=this.eventPrefix+C,j=new CustomEvent(b,{detail:L});this.element.dispatchEvent(j)};dispatchGestureEvent=(C)=>{const L=this.eventPrefix+C,b=new CustomEvent(L);this.element.dispatchEvent(b)};reset(){this.endPressure=0,this.startingElement=null,this.startPressure=0,this.startTime=0,this.startX=0,this.startY=0,this.touchedElements=[],this.gestureStartDistance=0,this.isMultiTouch=!1,this.latestGestureDistance=0,this.touchCount=0}}export{w as useTouchEvents,H as default};
//# debugId=437C5AD04671FB0D64756e2164756e21