PixiJS Rendering Pipeline and @pixi-accessibility/core Plugin: Pointer Event vs Assistive‑Tech Gesture Handling
0 reputation · 27 Jan 2024, 15:27 UTC
0 reputation · 27 Jan 2024, 15:27 UTC
The goal is to define a consistent interaction model when using PixiJS together with the @pixi-accessibility/core plugin so that pointer events (click/touch) and assistive‑tech gestures are handled uniformly across keyboard navigation, screen‑reader announcements, and touch input.
Currently the plugin provides ARIA roles, labels, tabindex and a focus proxy for Sprites, but it does not automatically intercept raw PixiJS pointer events. Developers must decide whether to forward those events through the plugin’s accessibility layer or let PixiJS process them directly, which leads to inconsistent behavior where a Sprite may receive focus via keyboard yet ignore touch, or vice‑versa.
This unresolved decision leaves developers without a default behavior, requiring them to weigh performance overhead, synchronization complexity, and the risk of mismatched assistive‑tech feedback.
Should the plugin automatically intercept pointer events to forward them to the accessibility layer? Should a configuration flag enable developers to choose between raw PixiJS handling and accessibility‑mediated handling? What are the performance implications of each approach on low‑end devices?
35275 reputation · 27 Jan 2024, 23:27 UTC
Do not make the plugin automatically intercept every pointer event. Keep raw PixiJS handling as the default and expose a configuration flag (e.g. accessibility.interceptPointer) that lets developers opt‑in to forward pointer events to the accessibility layer when they need consistent announcements for touch and mouse.
tabindex, and a focus proxy but does not intercept pointer events.Because PixiJS is a performance‑oriented rendering engine, the designers of @pixi-accessibility chose to keep the core lightweight. Automatic interception would force every sprite to route events through the accessibility context, which could degrade frame rates on devices with limited CPU or GPU resources.
1. Default behaviour: Let PixiJS handle pointer events directly.
2. Optional interception: Enable accessibility.interceptPointer to forward pointerdown, pointerup, and pointertap to the accessibility context. When enabled, the plugin should stop propagation in the PixiJS handler to avoid duplicate events.
3. Screen‑reader safety: Ensure that the accessibility layer only announces once per interaction. Use aria-pressed or similar attributes to signal state changes.
npm install @pixi/accessibility-coreapp.renderer.plugins.accessibility.interceptPointer = true;app.renderer.plugins.accessibility.onPointer = (event) => {
if (!app.renderer.plugins.accessibility.interceptPointer) return;
// Forward to accessibility context
app.renderer.plugins.accessibility.handlePointer(event);
};app.renderer.plugins.accessibility.registerSprite(sprite) to attach ARIA metadata.role="button".How many interactive sprites do you expect to render simultaneously in your application? This number will help decide whether to keep the default raw handling or enable the interception flag for all sprites.
Use comments to ask for clarification. Post a solution as an answer.
6,530 reputation · 28 Jan 2024, 02:03 UTC
By default the two layers are separate. PixiJS InteractionManager does canvas-level hit testing and dispatches pointer events to DisplayObjects. @pixi-accessibility/core does not register as a pointer interceptor; it builds a parallel DOM accessibility tree with ARIA roles, labels and tabindex proxies for Sprites.
Focus and activation are driven by DOM focus events and assistive-tech virtual cursor, not by PixiJS pointer events. Consistent keyboard, screen reader and touch behavior therefore requires explicit mapping between a pointer hit test result and the corresponding accessibility proxy, e.g., syncing DOM focus on pointer down and synthesizing activation on pointer up.
Behavior is version-sensitive and should be verified by inspecting plugin initialization for InteractionManager listeners versus DOM proxy creation only.