Use Nintendo Switch Joy-Cons as input devices (Bluetooth).
- Run callback(s) when buttons are pressed/released/changed
- Toggle player LEDs
npm install --save switch-joy-con
const { listConnectedJoyCons } = require("switch-joy-con");
// First, list all the Joy-Cons connected to the computer.
const devices = listConnectedJoyCons();
console.log(devices);
// [
// {
// vendorId: 1406,
// productId: 8198,
// path: 'IOService:/IOResources/IOBluetoothHCIController/AppleBroadcomBluetoothHostController/IOBluetoothDevice/IOBluetoothL2CAPChannel/IOBluetoothHIDDriver',
// serialNumber: '94-58-cb-a6-1b-86',
// manufacturer: 'Unknown',
// product: 'Joy-Con (L)',
// release: 1,
// interface: -1,
// usagePage: 1,
// usage: 5,
// open: [Function: open]
// },
// {
// vendorId: 1406,
// productId: 8199,
// path: 'IOService:/IOResources/IOBluetoothHCIController/AppleBroadcomBluetoothHostController/IOBluetoothDevice/IOBluetoothL2CAPChannel/IOBluetoothHIDDriver',
// serialNumber: '94-58-cb-a5-cb-9d',
// manufacturer: 'Unknown',
// product: 'Joy-Con (R)',
// release: 1,
// interface: -1,
// usagePage: 1,
// usage: 5,
// open: [Function: open]
// }
// ]
// Decide which to use, and then call `open` on it.
const left = devices[0].open();
// NOTE: for third-party Joy-Cons, you may have to pass a side string:
// const left = devices[0].open("left");
// The `buttons` property always contains up-to-date buttons state:
console.log(left.buttons);
// {
// dpadUp: false,
// dpadDown: false,
// dpadLeft: false,
// dpadRight: false,
// minus: false,
// screenshot: false,
// sl: false,
// sr: false,
// l: false,
// zl: false,
// analogStickPress: false,
// analogStick: left.Directions.NEUTRAL
// }
// A "change" event will be emitted whenever the button state changes
left.on("change", () => {
console.log(left.buttons);
});
// Whenever a button is pressed or released, a `down:${buttonName}` or `up:${buttonName}` event is emitted.
left.on("down:minus", () => {
console.log("minus pressed down");
});
left.on("up:minus", () => {
console.log("minus depressed");
});
// a `change:${buttonName}` event is also emitted:
left.on("change:minus", (pressed) => {
console.log(`minus is now: ${pressed ? "pressed" : "unpressed"}`);
});
// The `analogStick` "button" is a number. Use the `Directions` property on the
// instance to understand its value:
left.on("change:analogStick", (value) => {
switch (value) {
case left.Directions.UP: {
console.log("up");
break;
}
case left.Directions.UP_RIGHT: {
console.log("up-right");
break;
}
case left.Directions.RIGHT: {
console.log("right");
break;
}
case left.Directions.DOWN_RIGHT: {
console.log("down-right");
break;
}
case left.Directions.DOWN: {
console.log("down");
break;
}
case left.Directions.DOWN_LEFT: {
console.log("down-left");
break;
}
case left.Directions.LEFT: {
console.log("left");
break;
}
case left.Directions.UP_LEFT: {
console.log("up-left");
break;
}
case left.Directions.UP_RIGHT: {
console.log("up-right");
break;
}
case left.Directions.NEUTRAL: {
console.log("neutral");
break;
}
}
});
// When you're done with the device, call `close` on it:
left.close();
// Usage with a right-side Joy-Con is the same, but it has different button names:
const right = devices[1].open();
console.log(right.buttons);
// {
// a: false,
// x: false,
// b: false,
// y: false,
// plus: false,
// home: false,
// sl: false,
// sr: false,
// r: false,
// zr: false,
// analogStickPress: false,
// analogStick: right.Directions.NEUTRAL
// }
// If you need to tell whether a Joy-Con is a left or right Joy-Con, use the `side` property:
console.log(left.side); // "left"
console.log(right.side); // "right"
The "switch-joy-con"
module has one named export, listConnectedJoyCons
.
Returns an array of objects, each describing a connected Joy-Con.
The objects have the following properties:
interface JoyConDescription {
vendorId: number;
productId: number;
path: string;
serialNumber: string;
manufacturer: string;
product: string;
release: number;
interface: number;
usagePage: number;
usage: number;
open: () => JoyCon;
}
The most important thing here is the open
method, which returns a JoyCon
instance.
You can obtain a JoyCon
instance by calling open
on a JoyConDescription
, as returned by listConnectedJoyCons()
.
Each JoyCon
adheres to the following interface:
interface JoyCon extends EventEmitter {
// Whether the Joy-Con attaches to the left or right side of a Switch.
// The buttons will differ depending on this.
side: "left" | "right";
// An object containing the current button state.
buttons: // If `side` is "left", `buttons` will have the following properties:
| {
// If a button is pressed, its value will be `true`. Otherwise, it will be `false`.
dpadUp: boolean;
dpadDown: boolean;
dpadLeft: boolean;
dpadRight: boolean;
minus: boolean;
screenshot: boolean;
sl: boolean;
sr: boolean;
l: boolean;
zl: boolean;
analogStickPress: boolean;
// Use the `Directions` property on the JoyCon to understand this number.
analogStick: number;
}
// Otherwise (if `side` is "right"), `buttons` will have these properties:
| {
// If a button is pressed, its value will be `true`. Otherwise, it will be `false`.
a: boolean;
x: boolean;
b: boolean;
y: boolean;
plus: boolean;
home: boolean;
sl: boolean;
sr: boolean;
r: boolean;
zr: boolean;
analogStickPress: boolean;
// Use the `Directions` property on the JoyCon to understand this number.
analogStick: number;
};
// The analog stick direction constants for this Joy-Con. Note that these differ
// between left/right Joy-Cons, so always rely on this property.
Directions: {
LEFT: number;
UP_LEFT: number;
UP: number;
UP_RIGHT: number;
RIGHT: number;
DOWN_RIGHT: number;
DOWN: number;
DOWN_LEFT: number;
NEUTRAL: number;
};
// Call this method when you are done using the Joy-Con.
// It won't be disconnected from Bluetooth, but the handle
// will be released so it can be used by another application.
close();
// LED values that can be provided to the `setPlayerLEDs` method.
LED_VALUES: {
// Indicates that the LED in this slot should be lit up solid.
ONE: number;
TWO: number;
THREE: number;
FOUR: number;
// Indicates that the LED in this slot should be flashing on and off.
ONE_FLASH: number;
TWO_FLASH: number;
THREE_FLASH: number;
FOUR_FLASH: number;
};
// Set which player LEDs are lit. Use value(s) from the `LED_VALUES` property.
// To turn on more than one LED, add them together; eg:
// setPlayerLEDs(LED_VALUES.ONE + LED_VALUES.TWO)
setPlayerLEDs(value: number);
}
JoyCon
s are also EventEmitter
s, and they emit the following events:
change
- Button state has changed. Inspect thebuttons
property on the device for more info.change:${buttonName}
- A specific button changed state. The event listener will be called with one argument, containing the new button value.down:${buttonName}
- A specific button is now being held down.up:${buttonName}
- A specific button is no longer being held down.
List of button names:
a
x
b
y
plus
home
l
r
zl
zr
dpadUp
dpadDown
dpadLeft
dpadRight
minus
screenshot
sl
sr
analogStickPress
analogStick
MIT