UNPKG

coherent-gameface-interaction-manager

Version:
7 lines (6 loc) 7.53 kB
(function(v,h){typeof exports=="object"&&typeof module<"u"?module.exports=h():typeof define=="function"&&define.amd?define(h):(v=typeof globalThis<"u"?globalThis:v||self,v.touchGestures=h())})(this,(function(){"use strict";function v(s,e){if(e<0&&s>-200&&s<200)return"top";if(e>0&&s>-200&&s<200)return"bottom";if(s<0&&e>-200&&e<200)return"left";if(s>0&&e>-200&&e<200)return"right";if(s<=-200&&e<=-200)return"top-left";if(s>=200&&e<=-200)return"top-right";if(s<=-200&&e>=200)return"bottom-left";if(s>=200&&e>=200)return"bottom-right"}function h(s){return s instanceof HTMLElement?s:document.querySelector(s)}function S(s){return s*180/Math.PI}function T(s,e,t,n){const r=s-t,c=e-n;return Math.hypot(r,c)}function F(s,e,t,n){return{x:(s+t)/2,y:(e+n)/2}}const f=2;class M{constructor(){this.activeTouches=new Map}hold(e){if(!e)return console.error("Options not provided for hold!");let t;const n=h(e.element);if(!n)return console.error("Element not found!");const r=({touches:i})=>{this.activeTouches.set(i[0].identifier,i[0]),t=setTimeout(()=>{e.callback&&e.callback()},e.time||1e3)},c=({touches:i})=>{this.activeTouches.delete(i[0].identifier),clearTimeout(t)};return n.addEventListener("touchstart",r),n.addEventListener("touchend",c),{remove(){n.removeEventListener("touchstart",r),n.removeEventListener("touchend",c)}}}tap(e){if(!e)return console.error("Options not provided for tap!");let t,n,r=!0,c=e.tapsNumber||1;const i=h(e.element);if(!i)return console.error("Element not found!");const d=({touches:o})=>{this.activeTouches.set(o[0].identifier,o[0]),clearTimeout(n),r=!0,t=setTimeout(()=>{r=!1},e.tapTime||200)},u=({touches:o})=>{this.activeTouches.delete(o[0].identifier),clearTimeout(t),r&&(c--,n=setTimeout(()=>{c=e.tapsNumber||1,clearTimeout(n)},e.betweenTapsTime||500),!(c!==0||!e.callback)&&(e.callback(),r=!0,clearTimeout(t),c=e.tapsNumber||1))};return i.addEventListener("touchstart",d),i.addEventListener("touchend",u),{remove(){i.removeEventListener("touchstart",d),i.removeEventListener("touchend",u)}}}drag(e){if(!e)return console.error("Options not provided for drag!");const t=h(e.element);if(!t)return console.error("Element not found!");const n=({touches:i,target:d,currentTarget:u})=>{this.activeTouches.set(i[0].identifier,i[0]),document.addEventListener("touchmove",r),document.addEventListener("touchend",c),e.onDragStart&&e.onDragStart({x:i[0].clientX,y:i[0].clientY,target:d,currentTarget:u})},r=({touches:i})=>{this.activeTouches.has(i[0].identifier)&&e.onDrag&&e.onDrag({x:i[0].clientX,y:i[0].clientY})},c=({touches:i})=>{this.activeTouches.delete(i[0].identifier),document.removeEventListener("touchmove",r),document.removeEventListener("touchend",c),e.onDragEnd&&e.onDragEnd({x:i[0].clientX,y:i[0].clientY})};return t.addEventListener("touchstart",n),{remove(){t.removeEventListener("touchstart",n)}}}swipe(e){if(!e)return console.error("Options not provided for swipe!");let t,n,r,c=!0;const i=100;e.touchNumber||=1;const d=h(e.element);if(!d)return console.error("Element not found!");const u=({touches:a})=>{this.activeTouches.set(a[0].identifier,a[0]),this.activeTouches.size>e.touchNumber&&(document.removeEventListener("touchmove",o),document.removeEventListener("touchend",l)),this.activeTouches.size===e.touchNumber&&(t=setTimeout(()=>{c=!1,clearTimeout(t),t=null},1e3),document.addEventListener("touchmove",o),document.addEventListener("touchend",l))},o=({touches:a})=>{if(!this.activeTouches.has(a[0].identifier))return;const E=this.activeTouches.get(a[0].identifier);if(!E)return;const{clientX:_,clientY:g}=E,L=a[0].clientX-_,b=a[0].clientY-g;n=v(L,b),r=T(_,g,a[0].clientX,a[0].clientY)},l=({touches:a})=>{this.activeTouches.delete(a[0].identifier),this.activeTouches.size===0&&(document.removeEventListener("touchmove",o),document.removeEventListener("touchend",l),m()&&e.callback(n),clearTimeout(t),c=!0,t=null)},m=()=>c&&n&&r&&r>i;return d.addEventListener("touchstart",u),{remove(){d.removeEventListener("touchstart",u)}}}pinch(e){if(!e)return console.error("Options not provided for pinch!");let t;const n=40,r=h(e.element);if(!r)return console.error("Element not found!");const c=({touches:u})=>{if(this.activeTouches.set(u[0].identifier,u[0]),this.activeTouches.size<f)return;const o=this.activeTouches.get(0),l=this.activeTouches.get(1);!o||!l||(document.addEventListener("touchmove",i),document.addEventListener("touchend",d),t=T(o.clientX,o.clientY,l.clientX,l.clientY))},i=({touches:u})=>{if(this.activeTouches.size!==f)return;this.activeTouches.set(u[0].identifier,u[0]);const o=this.activeTouches.get(0),l=this.activeTouches.get(1);if(!o||!l)return;const m=T(o.clientX,o.clientY,l.clientX,l.clientY),a=Math.sign(m-t)*n;t=m;const E=F(o.clientX,o.clientY,l.clientX,l.clientY);e.callback&&e.callback({pinchDelta:a,midpoint:E})},d=({touches:u})=>{this.activeTouches.delete(u[0].identifier),this.activeTouches.size===0&&(document.removeEventListener("touchmove",i),document.removeEventListener("touchend",d))};return r.addEventListener("touchstart",c),{remove(){r.removeEventListener("touchstart",c)}}}rotate(e){if(!e)return console.error("Options not provided for rotate!");let t=0,n=0;const r=h(e.element);if(!r)return console.error("Element not found!");const c=({touches:o})=>{this.activeTouches.size<f||(this.activeTouches.set(o[0].identifier,o[0]),t=u()-n,e.callback&&e.callback(t))},i=({touches:o})=>{this.activeTouches.set(o[0].identifier,o[0]),this.activeTouches.size===f&&(n=u()-t,document.addEventListener("touchmove",c),document.addEventListener("touchend",d))},d=({touches:o})=>{this.activeTouches.delete(o[0].identifier),document.removeEventListener("touchmove",c),document.removeEventListener("touchend",d)};r.addEventListener("touchstart",i);const u=()=>{const m=this.activeTouches.get(0).clientY-this.activeTouches.get(1).clientY,a=this.activeTouches.get(0).clientX-this.activeTouches.get(1).clientX;return(S(Math.atan2(m,a))+360+90)%360};return{remove(){r.removeEventListener("touchstart",i)}}}}const p=new M;class I{constructor(){this.actions=[],this.keyboardFunctions=[],this.gamepadFunctions=[]}init(){window._IM||(window._IM=new I)}getKeys(e){return _IM.keyboardFunctions.filter(t=>t.keys.every(n=>e.includes(n)))}getKeysIndex(e){return _IM.keyboardFunctions.findIndex(t=>t.keys.every(n=>e.includes(n)))}getGamepadAction({actions:e,type:t}){return _IM.gamepadFunctions.find(n=>n.actions.every(r=>e.includes(r))&&n.type===t&&n.actions.length===e.length)}getGamepadActions(e,t=!0){return _IM.gamepadFunctions.filter(n=>n.actions.every(r=>e.includes(r))&&(t?n.actions.length===e.length:!0))}getGamepadActionIndex(e){return _IM.gamepadFunctions.findIndex(t=>t.actions.every(n=>e.includes(n)))}getAction(e){return _IM.actions.find(t=>t.name===e)}getActionIndex(e){return _IM.actions.findIndex(t=>t.name===e)}hasDuplicateCallback(e,t){return e.callbacks.some(n=>n===t)}addCallbackToEntry(e,t,n){if(this.hasDuplicateCallback(e,t)){const r=typeof t=="string"?"action":"function",c=typeof t=="string"?t:"(anonymous function)";return console.error(`Duplicate callback detected! ${n.identifier} Type: '${n.type}' Callback: ${c} This ${r} is already registered for this combination and type. To update it, first remove with the .off() method.`)}return e.callbacks.push(t)}removeKeyboardFunction(e){const t=_IM.keyboardFunctions.indexOf(e);t!==-1&&_IM.keyboardFunctions.splice(t,1)}removeGamepadFunction(e){const t=_IM.gamepadFunctions.indexOf(e);t!==-1&&_IM.gamepadFunctions.splice(t,1)}}return new I().init(),p})); //# sourceMappingURL=touch-gestures.min.js.map