Haptics
Overview
Haptic feedback (a short vibration on a tap, a hit, or a win) makes your app feel more responsive and satisfying, and we encourage you to use it. Support differs by device, so design haptics as an enhancement: your app must work the same with or without them.
Use the SDK
Call JestSDK.haptics.vibrate() instead of navigator.vibrate(). It takes the same arguments and works fully on Android. It works partially on iPhone: only in response to a player's tap, and only as one short tick. On devices without haptics it does nothing, so you don't need to check for support first:
canvas.addEventListener("pointerdown", () => {
JestSDK.haptics.vibrate(20);
// ...the rest of your handler runs on every device
});
Don't call navigator.vibrate() directly. It doesn't exist on iOS, so calling it throws TypeError: navigator.vibrate is not a function and stops the rest of your handler: a tap that should have scored a point or opened a menu silently does nothing.
Browser support
| Platform | Support | What JestSDK.haptics.vibrate() does |
|---|---|---|
| Android (Chrome and most Chromium browsers) | Full | Vibrates for the duration or pattern you pass |
| iOS 18+ (Safari, and every other iOS browser) | Partial | Plays one light tick when the player lifts their finger from a tap on your game canvas |
| iOS 17 and earlier | None | Nothing |
| Firefox | None | Nothing. Firefox has removed the Vibration API. |
| Desktop browsers | None | Nothing. There is no hardware to vibrate. |
All iOS browsers use Safari's WebKit engine, so Chrome on iOS behaves the same as Safari.
JestSDK.haptics.getCapability() tells you which of these applies, if you need to adjust your design to it.
Android
Pass a duration in milliseconds, or an array of alternating vibrate and pause durations:
JestSDK.haptics.vibrate(20); // a short tick
JestSDK.haptics.vibrate([30, 50, 30]); // buzz, pause, buzz
The browser ignores vibration until the player has interacted with your app (a tap or a key press), and while the page is hidden.
iPhone
iPhone has no Vibration API, so the SDK plays the system's switch tick instead. This works only in response to a real tap:
- Call it during the tap. Call
vibrate()while the finger is down, or synchronously in atouchend,pointeruporclickhandler. Calls from timers, or for game events like a collision, do nothing. - One fixed tick. The pattern is ignored: there is one strength and no duration.
- Canvas taps only. Drags, multi-finger gestures and taps on HTML elements outside your game canvas don't tick.
- The first tap doesn't tick. The first call sets up an invisible layer over your canvas, which later taps go through.
The layer passes touches on to your canvas as copies, which a few engines don't expect. See the iPhone section of the SDK reference for what to check, and how to skip haptics on iPhone if your game doesn't work with the layer.
Use haptics well
- Keep vibrations short (10-50 ms). Long or constant buzzing is unpleasant and drains the battery.
- Tie haptics to meaningful moments, like a confirmed action, a hit, or a reward, not every frame or animation.
- Give players a setting to turn haptics off.
- Test on a real Android phone and iPhone in Jest, not just a desktop browser. If nothing vibrates, check that the phone isn't in silent, Do Not Disturb or battery-saving mode, and that system haptics are on.