Pixi.js Multi-Touch Events on Mobile Devices
Modern mobile web applications rely heavily on responsive touch interactions, and Pixi.js provides a robust system to manage them. This article explores how Pixi.js handles multi-touch events on mobile devices, covering its internal EventSystem, pointer event abstraction, and practical implementation strategies for tracking multiple simultaneous touches.
The Foundation: Unified Pointer Events
Pixi.js simplifies input handling by using the W3C Pointer Events API. Instead of forcing developers to write separate codebases for mouse, touch, and pen inputs, Pixi.js abstracts these into unified “pointer” events.
On mobile devices, when multiple fingers touch the screen, the browser fires standard touch events. Pixi.js intercepts these events and maps each individual touch point to a corresponding Pixi pointer event. The primary events used for multi-touch interaction include:
pointerdown: Triggered when a finger contacts the screen.pointermove: Triggered when a finger slides across the screen.pointerup: Triggered when a finger is lifted from the screen.pointerupoutside: Triggered when a finger is lifted outside the boundary of the targeted display object.
Enabling Interactivity in Pixi.js
To make a display object (like a Sprite or
Container) responsive to touch, you must explicitly enable
its interactivity. In modern versions of Pixi.js (v7 and v8), this is
achieved using the eventMode property.
const sprite = new PIXI.Sprite(texture);
sprite.eventMode = 'static'; // Makes the object interactiveBy setting eventMode to 'static' (or
'dynamic' for moving objects), Pixi.js includes the object
in its hit-testing passes.
Tracking Multiple Touches with Pointer IDs
The key to handling multi-touch in Pixi.js is the
pointerId property. Every active touch on a mobile screen
is assigned a unique identifier by the browser, which Pixi.js exposes
via the event object.
To track multiple fingers independently, you must store the
coordinates of each touch mapped to its respective
pointerId.
Practical Implementation
Here is how to track and respond to multi-touch events on a single interactive object:
const activeTouches = new Map();
sprite.on('pointerdown', (event) => {
// Store the initial touch position using the unique pointerId
activeTouches.set(event.pointerId, {
x: event.global.x,
y: event.global.y
});
});
sprite.on('pointermove', (event) => {
// Check if this moving pointer is one we are tracking
if (activeTouches.has(event.pointerId)) {
const touch = activeTouches.get(event.pointerId);
// Update to the new position
touch.x = event.global.x;
touch.y = event.global.y;
// Handle custom multi-touch logic here (e.g., pinch-to-zoom, rotation)
handleMultiTouchLogic();
}
});
const endTouch = (event) => {
// Remove the touch pointer when the finger is lifted
activeTouches.delete(event.pointerId);
};
sprite.on('pointerup', endTouch);
sprite.on('pointerupoutside', endTouch);Implementing Complex Gestures (Pinch and Zoom)
When multiple touches are registered inside
activeTouches, you can calculate the distance and angle
between the touch points to implement complex mobile gestures:
- Pinch-to-Zoom: Calculate the distance between two
active pointer coordinates on
pointerdown. Onpointermove, recalculate the distance. The ratio between the new distance and the starting distance determines the scale factor. - Rotation: Calculate the angle between two pointers
using
Math.atan2. Track the change in angle duringpointermoveto rotate display objects.
Mobile Best Practices
For optimal multi-touch performance in Pixi.js on mobile browsers, consider these optimizations:
- Disable Default Browser Gestures: To prevent the
mobile browser from zooming or scrolling the page while users interact
with your canvas, apply the CSS property
touch-action: none;to the HTML5 canvas element. - Use
globalCoordinates: Always retrieve coordinates usingevent.globalfor screen-relative calculations, or useevent.getLocalPosition(parent)to convert touch points relative to a specific display object’s coordinate space. - Clean Up Memory: Always clean up event listeners and clear active touch maps when destroying display objects to prevent memory leaks on mobile devices.