@gamepad/plugin-joycon
Version:
Joy-Con plugin for Gamepad
78 lines (76 loc) • 3.06 kB
JavaScript
function joycon(_opts = {}) {
const buttonMap = ['A', 'X', 'B', 'Y', 'SL', 'SR', '-', '-', 'Minus', 'Plus', 'LStick', 'RStick', 'Home', 'Screenshot', 'Bumper', 'Trigger'];
const getAxisValue = (value) => {
if (!Array.isArray(value)) {
value = Math.round(value / (2 / 7) + 3.5);
switch (value) {
case 8: return { x: 0, y: 0 };
case 7: return { x: 1, y: -1 };
case 6: return { x: 0, y: -1 };
case 5: return { x: -1, y: -1 };
case 4: return { x: -1, y: 0 };
case 3: return { x: -1, y: 1 };
case 2: return { x: 0, y: 1 };
case 1: return { x: 1, y: 1 };
case 0: return { x: 1, y: 0 };
}
}
const [{ value: XL }, { value: XR }, { value: YT }, { value: YB }] = value;
const x = (XR * -1) || (XL) || 0;
const y = (YT * -1) || (YB) || 0;
return { x, y };
};
const sides = new Map();
const getSide = (id) => {
let side = sides.get(id);
if (!side) {
side = id[id.indexOf('Joy-Con') + 9].toUpperCase();
if (['L', 'R'].includes(side)) {
sides.set(id, side);
}
else {
sides.set(id, null);
}
}
return side;
};
const getButton = (code, side) => {
switch (code) {
case 'Trigger': return `Z${side}`;
case 'Bumper': return side;
case 'A': return (side === 'L') ? 'ArrowLeft' : code;
case 'X': return (side === 'L') ? 'ArrowDown' : code;
case 'B': return (side === 'L') ? 'ArrowUp' : code;
case 'Y': return (side === 'L') ? 'ArrowRight' : code;
default: return code;
}
};
return {
name: 'joycon',
enabled: (gamepad) => (gamepad.id.indexOf('Joy-Con') > -1),
transform: (context) => {
const mapping = (context.buttons.length === 20) ? 'firefox' : 'chrome';
const side = getSide(context.id);
let buttons;
let axes;
if (mapping === 'chrome') {
buttons = context.buttons.map((value, index) => {
const code = buttonMap[index];
const button = getButton(code, side);
return { button, code, value };
});
axes = [Object.assign({}, getAxisValue(context.axes[9]), { axis: `${side}Stick` })];
}
else if (mapping === 'firefox') {
buttons = context.buttons.slice(0, 16).map((value, index) => {
const code = buttonMap[index];
const button = getButton(code, side);
return { button, code, value };
});
axes = [Object.assign({}, getAxisValue(context.buttons.slice(-4)), { axis: `${side}Stick` })];
}
return { buttons, axes };
}
};
}
export default joycon;