coherent-gameface-interaction-manager
Version:
Library for the most common UI interactions
7 lines (6 loc) • 7.91 kB
JavaScript
(function(a,c){typeof exports=="object"&&typeof module<"u"?module.exports=c():typeof define=="function"&&define.amd?define(c):(a=typeof globalThis<"u"?globalThis:a||self,a.gamepad=c())})(this,(function(){"use strict";const a={FACE_BUTTON_DOWN:0,FACE_BUTTON_RIGHT:1,FACE_BUTTON_LEFT:2,FACE_BUTTON_TOP:3,LEFT_SHOULDER:4,RIGHT_SHOULDER:5,LEFT_SHOULDER_BOTTOM:6,RIGHT_SHOULDER_BOTTOM:7,SELECT:8,START:9,LEFT_ANALOGUE_STICK:10,RIGHT_ANALOGUE_STICK:11,PAD_UP:12,PAD_DOWN:13,PAD_LEFT:14,PAD_RIGHT:15,CENTER_BUTTON:16,aliases:{"face-button-down":"FACE_BUTTON_DOWN","face-button-left":"FACE_BUTTON_LEFT","face-button-right":"FACE_BUTTON_RIGHT","face-button-top":"FACE_BUTTON_TOP","left-shoulder":"LEFT_SHOULDER","right-shoulder":"RIGHT_SHOULDER","left-shoulder-bottom":"LEFT_SHOULDER_BOTTOM","right-shoulder-bottom":"RIGHT_SHOULDER_BOTTOM",select:"SELECT",start:"START","left-analogue-stick":"LEFT_ANALOGUE_STICK","right-analogue-stick":"RIGHT_ANALOGUE_STICK","pad-up":"PAD_UP","pad-down":"PAD_DOWN","pad-left":"PAD_LEFT","pad-right":"PAD_RIGHT","center-button":"CENTER_BUTTON","playstation.x":"FACE_BUTTON_DOWN","playstation.square":"FACE_BUTTON_LEFT","playstation.circle":"FACE_BUTTON_RIGHT","playstation.triangle":"FACE_BUTTON_TOP","playstation.l1":"LEFT_SHOULDER","playstation.r1":"RIGHT_SHOULDER","playstation.l2":"LEFT_SHOULDER_BOTTOM","playstation.r2":"RIGHT_SHOULDER_BOTTOM","playstation.share":"SELECT","playstation.options":"START","playstation.l3":"LEFT_ANALOGUE_STICK","playstation.r3":"RIGHT_ANALOGUE_STICK","playstation.d-pad-up":"PAD_UP","playstation.d-pad-down":"PAD_DOWN","playstation.d-pad-left":"PAD_LEFT","playstation.d-pad-right":"PAD_RIGHT","playstation.center":"CENTER_BUTTON","xbox.a":"FACE_BUTTON_DOWN","xbox.x":"FACE_BUTTON_LEFT","xbox.b":"FACE_BUTTON_RIGHT","xbox.y":"FACE_BUTTON_TOP","xbox.lb":"LEFT_SHOULDER","xbox.rb":"RIGHT_SHOULDER","xbox.lt":"LEFT_SHOULDER_BOTTOM","xbox.rt":"RIGHT_SHOULDER_BOTTOM","xbox.view":"SELECT","xbox.menu":"START","xbox.left-thumbstick":"LEFT_ANALOGUE_STICK","xbox.right-thumbstick":"RIGHT_ANALOGUE_STICK","xbox.d-pad-up":"PAD_UP","xbox.d-pad-down":"PAD_DOWN","xbox.d-pad-left":"PAD_LEFT","xbox.d-pad-right":"PAD_RIGHT","xbox.center":"CENTER_BUTTON"},axisAliases:["right.joystick","left.joystick","left.joystick.down","left.joystick.up","left.joystick.left","left.joystick.right","right.joystick.down","right.joystick.up","right.joystick.left","right.joystick.right"]};class c{constructor(){this.actions=[],this.keyboardFunctions=[],this.gamepadFunctions=[]}init(){window._IM||(window._IM=new c)}getKeys(t){return _IM.keyboardFunctions.filter(e=>e.keys.every(i=>t.includes(i)))}getKeysIndex(t){return _IM.keyboardFunctions.findIndex(e=>e.keys.every(i=>t.includes(i)))}getGamepadAction({actions:t,type:e}){return _IM.gamepadFunctions.find(i=>i.actions.every(n=>t.includes(n))&&i.type===e&&i.actions.length===t.length)}getGamepadActions(t,e=!0){return _IM.gamepadFunctions.filter(i=>i.actions.every(n=>t.includes(n))&&(e?i.actions.length===t.length:!0))}getGamepadActionIndex(t){return _IM.gamepadFunctions.findIndex(e=>e.actions.every(i=>t.includes(i)))}getAction(t){return _IM.actions.find(e=>e.name===t)}getActionIndex(t){return _IM.actions.findIndex(e=>e.name===t)}hasDuplicateCallback(t,e){return t.callbacks.some(i=>i===e)}addCallbackToEntry(t,e,i){if(this.hasDuplicateCallback(t,e)){const n=typeof e=="string"?"action":"function",s=typeof e=="string"?e:"(anonymous function)";return console.error(`Duplicate callback detected!
${i.identifier}
Type: '${i.type}'
Callback: ${s}
This ${n} is already registered for this combination and type. To update it, first remove with the .off() method.`)}return t.callbacks.push(e)}removeKeyboardFunction(t){const e=_IM.keyboardFunctions.indexOf(t);e!==-1&&_IM.keyboardFunctions.splice(e,1)}removeGamepadFunction(t){const e=_IM.gamepadFunctions.indexOf(t);e!==-1&&_IM.gamepadFunctions.splice(e,1)}}const o=new c;class u{register(t,e){if(o.getAction(t))return console.error(`The following action "${t}" is already registered!`);_IM.actions.push({name:t,callback:e})}remove(t){const e=o.getActionIndex(t);if(e===-1)return console.error(`${t} is not a registered action!`);_IM.actions.splice(e,1)}execute(t,e){const i=o.getAction(t);if(!i)return console.error(`${t} is not a registered action!`);i.callback(e)}}const d=new u,r=.9,T=["press","hold"];class _{constructor(){this._gamepadEnabled=!1,this._pollingInterval=200,this._pressedAction=null,this._pressedButtons=[],this.sanitizeAction=this.sanitizeAction.bind(this)}set enabled(t){this._gamepadEnabled=t,this._gamepadEnabled?this.startPolling():this.stopPolling()}set pollingInterval(t){this._pollingInterval=t,this._gamepadEnabled&&(this.pollingIntervalRef&&this.stopPolling(),this.startPolling())}on(t){const e=t.actions.map(this.sanitizeAction),i=a.axisAliases.some(l=>e.includes(l)),n=t.type&&T.includes(t.type)?t.type:"hold";if(n==="press"&&i)return console.error("You can't use an axis action with a 'press' type!");if(e.length>1&&i)return console.error("You can't use an axis action in a combination with a button action");const s=o.getGamepadAction({actions:e,type:n});if(s)return o.addCallbackToEntry(s,t.callback,{identifier:`Actions: [${e.join(", ")}]`,type:n});_IM.gamepadFunctions.push({actions:e,type:n,callbacks:[t.callback]})}off(t,e){const i=o.getGamepadActions(t.map(this.sanitizeAction));if(i.length===0)return console.error("You are trying to remove a non-existent action!");if(e){const n=i.filter(s=>s.callbacks.includes(e));if(n.length===0)return console.error("You are trying to remove a non-existent callback from this action!");n.forEach(s=>{const l=s.callbacks.indexOf(e);s.callbacks.splice(l,1),s.callbacks.length===0&&o.removeGamepadFunction(s)})}else i.forEach(n=>o.removeGamepadFunction(n))}startPolling(){this.pollingIntervalRef=setInterval(()=>{const t=navigator.getGamepads();t.length!==0&&t.forEach(e=>{e&&(this.handleButtons(e.buttons),this.handleJoysticks(e.axes))})},this._pollingInterval)}stopPolling(){this.pollingIntervalRef&&clearInterval(this.pollingIntervalRef)}handleButtons(t){const e=t.reduce((n,s,l)=>(s.pressed&&(n.buttonIndexes.push(l),n.buttons.push(s)),n),{buttonIndexes:[],buttons:[]}),i=o.getGamepadActions(e.buttonIndexes,!1);this._pressedAction&&(i.includes(this._pressedAction)||this.executeCallbacks(this._pressedAction,this._pressedButtons),this._pressedAction=null,this._pressedButtons=[]),i.forEach(n=>{if(n.type==="press"){this._pressedAction=n,this._pressedButtons=e.buttons;return}this.executeCallbacks(n,e.buttons)})}handleJoysticks(t){this.getJoystickActions().forEach(i=>{switch(i.actions[0]){case"left.joystick":return this.executeCallbacks(i,[t[0],t[1]]);case"right.joystick":return this.executeCallbacks(i,[t[2],t[3]]);case"left.joystick.down":if(t[1]>r)return this.executeCallbacks(i,[t[0],t[1]]);break;case"left.joystick.up":if(t[1]<-r)return this.executeCallbacks(i,[t[0],t[1]]);break;case"left.joystick.left":if(t[0]<-r)return this.executeCallbacks(i,[t[0],t[1]]);break;case"left.joystick.right":if(t[0]>r)return this.executeCallbacks(i,[t[0],t[1]]);break;case"right.joystick.down":if(t[3]>r)return this.executeCallbacks(i,[t[2],t[3]]);break;case"right.joystick.up":if(t[3]<-r)return this.executeCallbacks(i,[t[2],t[3]]);break;case"right.joystick.left":if(t[2]<-r)return this.executeCallbacks(i,[t[2],t[3]]);break;case"right.joystick.right":if(t[2]>r)return this.executeCallbacks(i,[t[2],t[3]]);break}})}sanitizeAction(t){if(typeof t=="number")return t;const e=t.toLowerCase();if(a.axisAliases.includes(e))return e;const i=a.aliases[e];if(i)return a[i];throw new Error(`You have entered a non-supported button alias: ${t}`)}getJoystickActions(){return _IM.gamepadFunctions.filter(t=>a.axisAliases.includes(t.actions[0]))}executeCallbacks(t,e){t.callbacks.forEach(i=>{if(typeof i=="string")return d.execute(i,e);i(e)})}}const h=new _;return o.init(),h}));
//# sourceMappingURL=gamepad.min.js.map