Try two browser controls
Move and aim separately with nippleJS 1.0.4. Read the input, release to zero and test keyboard alternatives before connecting a game.
Browser-library example, tested in Chromium · 8 October 2026. Keyboard alternatives are supplied by this Forge example. Your game still needs movement, aiming and target-device tests.
Check the full resource, compatibility and licenceDrag. Read. Release.
Move
Drag the stick, or focus this box and use the arrow keys. Release to return to zero.
Aim
Drag the stick, or focus this box and use W, A, S and D. Release to return to zero.
Both inputs active: No
The interactive example needs JavaScript. The steps and original-source links below still work.
- STEP 1
Use one known version
Start in a separate browser test page. This example uses the integrity-checked npm release
nipplejs@1.0.4, served locally with its upstream MIT notice. In your existing package setup, install that exact version and import its module:npm install --save-exact nipplejs@1.0.4 import nipplejs from 'nipplejs';Check: Your lockfile records 1.0.4. This is JavaScript DOM input, not a native Godot, Unity, Unreal or GameMaker plugin.
- STEP 2
Give each control its own zone
Use separate positioned containers for move and aim. Keep page scrolling available outside those zones; the control zones use
touch-action: none. Start with one manager, then add the other.const move = nipplejs.create({ zone: document.querySelector('#move-zone'), mode: 'static', size: 88, position: { left: '50%', top: '50%' } });Check: Drag right in Move; its x value increases. Drag up in Aim; its y value increases. Neither control should clear the other while both are held.
- STEP 3
Read input; implement movement separately
move.on('move', event => { const { x, y } = event.data.vector; // Feed your movement system; test its units and timing. }); move.on('end', () => { // Clear held movement input. });Version 1.x reads
event.data; older two-argument callback examples differ. Keyboard input here uses the same displayed vector but does not come from nippleJS.Check: Release one stick while holding the other. Only the released vector returns to zero. A vector alone does not implement a character, camera, collision or aim.
- STEP 4
Test cancellation and alternatives
Reset both controls, switch tabs and test pointer cancellation before keeping the change. Focus Move with Tab and use the arrow keys; focus Aim and use W/A/S/D. Release keys or leave the control to clear keyboard input. Recheck scrolling outside the zones and your real target devices.
Check: No stale held input remains after reset or backgrounding. A missing library reports an error, and the guide remains readable without JavaScript.
Review the actual example files
Forge example controller source · Exact upstream module · Retained MIT notice