coherent-gameface-interaction-manager
Version:
Library for the most common UI interactions
7 lines (6 loc) • 5.51 kB
JavaScript
(function(o,s){typeof exports=="object"&&typeof module<"u"?module.exports=s():typeof define=="function"&&define.amd?define(s):(o=typeof globalThis<"u"?globalThis:o||self,o.keyboard=s())})(this,(function(){"use strict";class o{constructor(){this.actions=[],this.keyboardFunctions=[],this.gamepadFunctions=[]}init(){window._IM||(window._IM=new o)}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(i=>e.includes(i))&&n.type===t&&n.actions.length===e.length)}getGamepadActions(e,t=!0){return _IM.gamepadFunctions.filter(n=>n.actions.every(i=>e.includes(i))&&(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 i=typeof t=="string"?"action":"function",r=typeof t=="string"?t:"(anonymous function)";return console.error(`Duplicate callback detected!
${n.identifier}
Type: '${n.type}'
Callback: ${r}
This ${i} 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)}}const s=new o,c={ALT:18,ARROW_DOWN:40,ARROW_LEFT:37,ARROW_RIGHT:39,ARROW_UP:38,BACKSPACE:8,CAPS_LOCK:20,CTRL:17,DELETE:46,END:35,ENTER:13,ESC:27,F1:112,F2:113,F3:114,F4:115,F5:116,F6:117,F7:118,F8:119,F9:120,F10:121,F11:122,F12:123,HOME:36,INSERT:45,NUM_LOCK:144,NUMPAD_ENTER:13,NUMPAD_DASH:109,NUMPAD_STAR:106,NUMPAD_DOT:110,NUMPAD_FORWARD_SLASH:111,NUMPAD_PLUS:107,NUMPAD_0:96,NUMPAD_1:97,NUMPAD_2:98,NUMPAD_3:99,NUMPAD_4:100,NUMPAD_5:101,NUMPAD_6:102,NUMPAD_7:103,NUMPAD_8:104,NUMPAD_9:105,PAGE_DOWN:34,PAGE_UP:33,PAUSE:19,PRINT_SCRN:44,SCROLL_LOCK:145,SHIFT:16,SPACEBAR:32,TAB:9,A:65,B:66,C:67,D:68,E:69,F:70,G:71,H:72,I:73,J:74,K:75,L:76,M:77,N:78,O:79,P:80,Q:81,R:82,S:83,T:84,U:85,V:86,W:87,X:88,Y:89,Z:90,1:49,2:50,3:51,4:52,5:53,6:54,7:55,8:56,9:57,0:48,QUOTE:222,DASH:189,COMMA:188,DOT:190,FORWARD_SLASH:191,SEMI_COLON:186,SQUARE_BRACKET_LEFT:219,SQUARE_BRACKET_RIGHT:221,BACKWARD_SLASH:220,BACKTICK:192,EQUAL:187,SYSTEM:91},l=Object.keys(c);class y{register(e,t){if(s.getAction(e))return console.error(`The following action "${e}" is already registered!`);_IM.actions.push({name:e,callback:t})}remove(e){const t=s.getActionIndex(e);if(t===-1)return console.error(`${e} is not a registered action!`);_IM.actions.splice(t,1)}execute(e,t){const n=s.getAction(e);if(!n)return console.error(`${e} is not a registered action!`);n.callback(t)}}const u=new y;class f{constructor(){this.eventListenerAttached=!1,this.keysPressed=new Set,this.onKeyDown=this.onKeyDown.bind(this),this.onKeyUp=this.onKeyUp.bind(this),window.KEYS||(window.KEYS=c)}on(e){const t=this.normalizeKeys(e.keys),n=t.filter(r=>!c[r]);if(n.length>0)return console.error(`The following keys [${n.join(", ")}] you have entered are incorrect! `);this.eventListenerAttached||(document.addEventListener("keydown",this.onKeyDown),document.addEventListener("keyup",this.onKeyUp),this.eventListenerAttached=!0),(e.type?Array.isArray(e.type)?e.type:[e.type]:["press"]).forEach(r=>{const d=s.getKeys(t).find(g=>g.type===r);if(d)return s.addCallbackToEntry(d,e.callback,{identifier:`Keys: [${t.join(", ")}]`,type:r});if(r==="lift"&&t.length>1)return console.error("You can only have a single key trigger an action on lift");_IM.keyboardFunctions.push({keys:t,type:r,callbacks:[e.callback]})})}off(e,t){e=this.normalizeKeys(e);const n=s.getKeys(e);if(n.length===0)return console.error("You are trying to remove a non-existent key combination!");if(t){const i=n.filter(r=>r.callbacks.includes(t));if(i.length===0)return console.error("You are trying to remove a non-existent callback from this key combination!");i.forEach(r=>{const a=r.callbacks.indexOf(t);r.callbacks.splice(a,1),r.callbacks.length===0&&s.removeKeyboardFunction(r)})}else n.forEach(i=>{s.removeKeyboardFunction(i)});_IM.keyboardFunctions.length===0&&(document.removeEventListener("keydown",this.onKeyDown),document.removeEventListener("keyup",this.onKeyUp),this.eventListenerAttached=!1)}onKeyDown(e){const t=this.keyCodeToString(e.keyCode);if(!t)return;this.keysPressed.add(t);const n=s.getKeys([...this.keysPressed]);n.length!==0&&n.forEach(i=>{i.type==="press"&&e.repeat||i.type!=="press"&&i.type!=="hold"||i.type==="hold"&&!e.repeat||this.executeCallbacks(e,i)})}onKeyUp(e){const t=this.keyCodeToString(e.keyCode);if(!t)return;this.keysPressed.delete(t);const n=s.getKeys([t]);n.length!==0&&n.forEach(i=>{i.type==="lift"&&i.keys.indexOf(t)!==-1&&this.executeCallbacks(e,i)})}keyCodeToString(e){return l.find(t=>c[t]===e)}normalizeKeys(e){const t=e.map(n=>{if(typeof n=="number"){const i=this.keyCodeToString(n);if(!i)throw new Error(`Invalid KeyCode: ${n}`);return i}return n.toUpperCase()});return[...new Set(t)]}executeCallbacks(e,t){t.callbacks.forEach(n=>{if(typeof n=="string")return u.execute(n,e);n(e)})}}const h=new f;return s.init(),h}));
//# sourceMappingURL=keyboard.min.js.map