Activez le lecteur d'écran et la navigation au clavier via le système AccessibilitySystem de PixiJS. Le système crée une couche DOM fantôme invisible positionnée sur les conteneurs accessibles afin que la technologie d'assistance puisse les découvrir et les activer.
Quick Start
const button = new Sprite(await Assets.load("button.png"));
button.accessible = true;
button.accessibleTitle = "Play game";
button.accessibleHint = "Starts a new game session";
button.eventMode = "static";
button.tabIndex = 0;
app.stage.addChild(button);
app.renderer.accessibility.setAccessibilityEnabled(true);
button.on("pointertap", () => startGame());
Skills connexes : pixijs-events (gestionnaires pointer/tap), pixijs-scene-dom-container (éléments HTML sur canvas), pixijs-application (options d'initialisation).
Points clés :
- Par défaut, le système s'active uniquement après que l'utilisateur appuie sur Tab. Définissez
enabledByDefault: truelors de l'initialisation de l'Application pour une activation immédiate. - Sur mobile, le système crée un hook tactile masqué ; le focus du lecteur d'écran active l'accessibilité pour toute la session.
- L'AccessibilitySystem nécessite le thread principal ; il n'est pas disponible dans un Web Worker.
Core Patterns
Propriétés accessible des conteneurs
import { Container, Sprite } from "pixi.js";
const container = new Container();
container.accessible = true;
container.accessibleTitle = "Navigation menu";
container.accessibleHint = "Contains links to other pages";
container.eventMode = "static"; // required for custom tabIndex to apply
container.tabIndex = 0;
container.accessibleType = "div"; // defaults to 'button'
const sprite = new Sprite();
sprite.accessible = true;
sprite.accessibleTitle = "Close dialog";
sprite.accessibleText = "X"; // text content of the shadow div
sprite.eventMode = "static";
sprite.tabIndex = 1;
Propriétés disponibles sur tout Container :
accessible(boolean) - active la div overlay accessibleaccessibleTitle(string) - définit l'attributtitlesur la div fantômeaccessibleHint(string) - définit l'attributaria-labelaccessibleText(string) - définit le contenu texte interne de la div fantômeaccessibleType(string) - balise HTML pour l'élément fantôme, par défaut'button'tabIndex(number) - ordre de tabulation pour la navigation au clavier (appliqué uniquement quandinteractiveest true /eventModeest'static'ou'dynamic')accessibleChildren(boolean, par défauttrue) - quandfalse, empêche les conteneurs enfants d'être accessiblesaccessiblePointerEvents(string) - valeur CSSpointer-eventssur la div fantôme
Ordre de tabulation personnalisé
Attribuez à chaque conteneur accessible un tabIndex pour contrôler l'ordre dans lequel la technologie d'assistance les parcourt. Les nombres plus élevés viennent plus tard ; les nombres égaux reviennent à l'ordre du graphe de scène.
menuButton.accessible = true;
menuButton.eventMode = "static";
menuButton.tabIndex = 1;
playButton.accessible = true;
playButton.eventMode = "static";
playButton.tabIndex = 2;
settingsButton.accessible = true;
settingsButton.eventMode = "static";
settingsButton.tabIndex = 3;
tabIndex est transmis à la div fantôme uniquement quand le conteneur est interactive (eventMode est 'static' ou 'dynamic'). Sans cela, le système limite le tabIndex de la div à 0, et l'ordre que vous définissez est ignoré.
Contrôle programmatique
import { Application } from "pixi.js";
const app = new Application();
await app.init({ width: 800, height: 600 });
// Enable accessibility at runtime
app.renderer.accessibility.setAccessibilityEnabled(true);
// Check current state
console.log(app.renderer.accessibility.isActive);
console.log(app.renderer.accessibility.isMobileAccessibility);
// Full init options:
await app.init({
accessibilityOptions: {
enabledByDefault: true, // activate immediately (default: false)
debug: true, // makes overlay divs visible (default: false)
activateOnTab: true, // Tab key activates system (default: true)
deactivateOnMouseMove: false, // stay active when mouse moves (default: true)
},
});
Le système peut aussi être configuré via des options statiques par défaut avant de créer l'Application :
import { AccessibilitySystem, Application } from "pixi.js";
AccessibilitySystem.defaultOptions.enabledByDefault = true;
AccessibilitySystem.defaultOptions.deactivateOnMouseMove = false;
const app = new Application();
await app.init();
Traiter les interactions accessibles
import { Sprite } from "pixi.js";
const button = new Sprite();
button.eventMode = "static";
button.accessible = true;
button.accessibleTitle = "Submit form";
button.tabIndex = 0;
// Screen readers trigger click/tap events through the shadow DOM element
button.on("pointertap", () => {
submitForm();
});
Quand l'accessibilité est active et qu'un utilisateur active une div fantôme (via la touche Entrée/Espace ou une action du lecteur d'écran), le système distribue les événements fédérés click, pointertap, et tap au conteneur correspondant. Le focus sur la div fantôme distribue mouseover, et la perte de focus distribue mouseout. À la fois eventMode et accessible doivent être définis pour un support clavier + pointeur complet.
Common Mistakes
[MEDIUM] Attendre que l'accessibilité soit active sans appui sur la touche Tab
L'AccessibilitySystem ne crée sa couche DOM que lorsque l'utilisateur appuie sur Tab (ou, sur mobile, met le focus sur le hook tactile). Si votre application a besoin d'accessibilité immédiatement :
const app = new Application();
await app.init({
accessibilityOptions: {
enabledByDefault: true,
},
});
Ou au runtime :
app.renderer.accessibility.setAccessibilityEnabled(true);
Sans l'un de ces éléments, les outils de test d'accessibilité automatisés ne trouveront pas les éléments overlay.
[MEDIUM] Définir accessible sans accessibleTitle
Incorrect :
const sprite = new Sprite();
sprite.accessible = true;
// no title or hint set
Correct :
const sprite = new Sprite();
sprite.accessible = true;
sprite.accessibleTitle = "Play button";
sprite.accessibleHint = "Click to start the game";
Un conteneur avec accessible = true mais sans accessibleTitle ou accessibleHint obtient un titre de secours "container {tabIndex}". Les lecteurs d'écran annonceront ce label générique sans contexte utile. Fournissez toujours au moins accessibleTitle.
[MEDIUM] L'accessibilité se désactive quand on bouge la souris
Par défaut, deactivateOnMouseMove est true. Tout mouvement de souris après l'activation par Tab désactivera l'overlay. C'est intentionnel (suppose que les utilisateurs au clavier seul n'utilisent pas une souris), mais cela rend les tests à la souris frustrateurs.
await app.init({
accessibilityOptions: {
deactivateOnMouseMove: false,
},
});
[MEDIUM] Ne pas importer l'extension accessibility dans les builds personnalisés
Quand vous utilisez skipExtensionImports: true pour un build personnalisé, l'extension accessibility n'est pas automatiquement enregistrée. Vous devez l'importer explicitement :
import "pixi.js/accessibility";
import { Application } from "pixi.js";
const app = new Application();
await app.init({ skipExtensionImports: true });
Sans cet import, app.renderer.accessibility sera undefined et aucune couche shadow DOM ne sera créée.