spacemouse-monorepo
    Preparing search index...

    spacemouse-monorepo

    SpaceMouse and SpaceNavigator connection library

    Node CI npm npm

    A Node.js module to interact with the 3Dconnexion devices, such as the SpaceMouse and SpaceNavigator.

    This repository is not affiliated with 3Dconnexion in any way.

    License: MIT

    If you are using a browser that supports WebHID, you can try out the library right away, in the browser: Demo.

    Some of the devices supported by this library are:

    • SpaceNavigator
    • SpaceMouse Wireless
    • SpaceMouse Compact
    • SpaceMouse Module
    • SpaceMouse Pro
    • SpaceMouse Pro Wireless
    • SpacePilot PRO
    • SpaceMouse Enterprise
    • CadMouse
    • CadMouse Wireless
    • CadMouse Pro Wireless
    • CadMouse Compact
    • CadMouse Pro
    • CadMouse Compact Wireless

    See the full list in products.ts.

    $ npm install --save spacemouse-node
    or
    $ yarn add spacemouse-node
    $ npm install --save spacemouse-webhid
    or
    $ yarn add spacemouse-webhid

    On linux, the udev subsystem blocks access for non-root users to the SpaceMouse without some special configuration. Save the following to /etc/udev/rules.d/50-spacemouse.rules and reload the rules with sudo udevadm control --reload-rules

    SUBSYSTEM=="input", GROUP="input", MODE="0666"
    SUBSYSTEM=="usb", ATTRS{idVendor}=="0x46d", MODE:="666", GROUP="plugdev"
    KERNEL=="hidraw*", ATTRS{idVendor}=="0x46d", MODE="0666", GROUP="plugdev"
    SUBSYSTEM=="usb", ATTRS{idVendor}=="0x256f", MODE:="666", GROUP="plugdev"
    KERNEL=="hidraw*", ATTRS{idVendor}=="0x256f", MODE="0666", GROUP="plugdev"

    Note: If you need more than 4 devices simultaneously, you might also have to set your env-var UV_THREADPOOL_SIZE:

    var { env } = require('process')
    env.UV_THREADPOOL_SIZE = 8 // Allow up to 8 devices

    This is the recommended way to use this library, to automatically be connected or reconnected to the device.

    Note: The watcher uses the node-usb library, which might be unsupported on some platforms. If it is not supported, it can use polling as fallback.

    const { SpaceMouseWatcher } = require('spacemouse-node') // or spacemouse-webhid in browser

    /*
    This example connects to any connected SpaceMouse devices and logs
    whenever the mouse is moved or a button is pressed.
    */

    // Set up the watcher for SpaceMouse:
    const watcher = new SpaceMouseWatcher({
    // usePolling: false // To be used if node-usb is not supported
    // pollingInterval= 1000
    })
    watcher.on('error', (e) => {
    console.log('Error in SpaceMouseWatcher', e)
    })
    watcher.on('connected', (spaceMouse) => {
    console.log(`SpaceMouse device of type ${spaceMouse.info.name} connected`)

    spaceMouse.on('disconnected', () => {
    console.log(`SpaceMouse device of type ${spaceMouse.info.name} was disconnected`)
    // Clean up stuff
    spaceMouse.removeAllListeners()
    })
    spaceMouse.on('error', (...errs) => {
    console.log('SpaceMouse error:', ...errs)
    })
    // Listen to Rotation changes:
    spaceMouse.on('rotate', (rotate) => {
    console.log(`Rotate ${JSON.stringify(rotate)}`)
    })
    // Listen to Translation changes:
    spaceMouse.on('translate', (translate) => {
    console.log(`Translate ${JSON.stringify(translate)}`)
    })
    // Listen to pressed buttons:
    spaceMouse.on('down', (keyIndex) => {
    console.log('Button pressed ', keyIndex)
    })
    // Listen to released buttons:
    spaceMouse.on('up', (keyIndex) => {
    console.log('Button released', keyIndex)
    })
    })

    // To stop watching, call
    // watcher.stop().catch(console.error)
    const { setupSpaceMouse } = require('spacemouse-node') // or spacemouse-webhid in browser

    /*
    This example shows how to use setupSpaceMouse()
    directly, instead of going via SpaceMouseWatcher()
    */

    // Connect to an SpaceMouse-device:
    setupSpaceMouse()
    .then((spaceMouse) => {
    console.log(`Connected to ${spaceMouse.info.name}`)
    spaceMouse.on('disconnected', () => {
    console.log(`Disconnected!`)
    spaceMouse.removeAllListeners()
    })
    spaceMouse.on('error', (...args) => {
    console.log('SpaceMouse error:', ...args)
    })
    // Listen to Rotation changes:
    spaceMouse.on('rotate', (rotate) => {
    console.log(`Rotate ${JSON.stringify(rotate)}`)
    })
    // ...
    })
    .catch(console.log) // Handle error

    or

    const { listAllConnectedDevices, setupSpaceMouse } = require('spacemouse-node')

    // List and connect to all SpaceMouse-devices:
    listAllConnectedDevices().forEach((connectedDevice) => {
    setupSpaceMouse(connectedDevice)
    .then((spaceMouse) => {
    console.log(`Connected to ${spaceMouse.info.name}`)
    spaceMouse.on('disconnected', () => {
    console.log(`Disconnected!`)
    spaceMouse.removeAllListeners()
    })
    spaceMouse.on('error', (...args) => {
    console.log('SpaceMouse error:', ...args)
    })

    // Listen to Rotation changes:
    spaceMouse.on('rotate', (rotate) => {
    console.log(`Rotate ${JSON.stringify(rotate)}`)
    })
    // ...
    })
    .catch(console.log) // Handle error

    See the example implementation at packages/webhid-demo.

    If you are using a Chromium v89+ based browser, you can try out the webhid demo.

    The SpaceMouseWatcher has a few different options that can be set upon initialization:

    const { SpaceMouseWatcher } = require('spacemouse-node')
    const watcher = new SpaceMouseWatcher({
    // usePolling: false
    // pollingInterval: 1000
    })
    watcher.on('error', (e) => {
    console.log('Error in SpaceMouseWatcher', e)
    })
    watcher.on('connected', (spaceMouse) => {
    // SpaceMouse connected...
    })

    When this is set, the SpaceMouseWatcher will not use the node-usb library for detecting connected devices, but instead resort to polling at an interval (pollingInterval). This is compatible with more systems and OS:es, but might result in higher system usage, slower detection of new devices.

    // Example:
    spaceMouse.on('rotate', (rotation) => {
    console.log(rotation)
    })
    Event Description
    "error" Triggered on error.
    Emitted with (error).
    "disconnected" Triggered when device is disconnected.
    "rotate" Triggered when the mouse is rotated.
    Emitted with (rotation: {pitch: number, roll: number, yaw: number})
    "translate" Triggered when the mouse is moved.
    Emitted with (translation: {x: number, y: number, z: number})
    "down", "up" Triggered when a button is pressed / released.
    Emitted with (buttonIndex: number)

    See the SpaceMouse-class for more functionality.

    For developers

    This is a mono-repo, using Lerna and Yarn.

    This repo is using Yarn. If you don't want to use it, replace yarn xyz with npm run xyz below.

    To install Yarn, just run npm install -g yarn.

    • Clone the repo and cd into it.
    • Install all dependencies: yarn.
    • Do an initial build: yarn build

    If you'd like to run and test your local changes, yarn link is a useful tool to symlink your local spaceMouse dependency into your test repo.

    # To set up the SpaceMouse-repo for linking:
    cd your/spaceMouse/repo
    yarn lerna exec yarn link # This runs "yarn link" in all of the mono-repo packages
    yarn build

    # Every time after you've made any changes to the SpaceMouse-repo you need to rebuild
    cd your/spaceMouse/repo
    yarn build

    # Set up your local test repo to used the linked SpaceMouse libraries:
    cd your/test/repo
    yarn add spacemouse-node
    yarn link spacemouse-node
    yarn link @spacemouse-lib/core

    # To unlink the spacemouse-lib from your local test repo:
    cd your/test/repo
    yarn unlink spacemouse-node
    yarn unlink @spacemouse-lib/core
    yarn --force # So that it reinstalls the ordinary dependencies

    If you have any questions or want to report a bug, please open an issue at Github.

    If you want to contribute a bug fix or improvement, we'd happily accept Pull Requests. (If you're planning something big, please open an issue to announce it first, and spark discussions.

    Please follow the same coding style as the rest of the repository as you type. :)

    Before committing your code to git, be sure to run these commands:

    yarn # To ensure the right dependencies are installed and yarn.lock is updated
    yarn build # To ensure that there are no syntax or build errors
    yarn lint # To ensure that the formatting follows the right rules
    yarn test # To ensure that your code passes the unit tests.

    If you're adding a new functionality, adding unit tests for it is much appreciated.

    • Update the branch (preferably the master branch)
    • yarn release:bump-prerelease and push the changes (including the tag)
    • Trigger a run of CI: publish-prerelease
    • Update the the master branch
    • yarn release:bump-release and push the changes (including the tag)
    • Trigger a run of CI: publish-release to publish to NPM.
    • Trigger a run of CI: publish-demo to update the docs.

    By contributing, you agree that your contributions will be licensed under the MIT License.