Three.jsのアニメーションに停止ボタンを実装してみた
はじめに
こんにちは、もりみちです。
本記事では、Three.jsを使った3Dアニメーションにアクセシブルな停止機能を実装し、WCAG達成基準2.2.2(一時停止、停止、非表示)を満たす方法を紹介します。
デモ
こちらがデモサイトになります。
なぜ停止ボタンが必要なのか
Three.jsを含む動きがあるアニメーションはユーザーの注意を引きつけ、視覚的なフィードバックを提供するなど、多くのメリットがあります。しかし持続する動きによって一部のユーザーが、集中力の阻害、読字困難などの問題を引き起こす可能性があります。
また、WCAG 2.2.2「一時停止、停止、非表示」は、動きのあるコンテンツに対して、ユーザーが一時停止、停止、非表示にする機能を提供することを要求しています。
そのため、自動的に開始され継続するアニメーションはユーザー自身が制御できる選択肢を提供することが、アクセシビリティの観点から非常に重要です。
解説
それではデモで実装したコードを一部抜粋し解説します。
HTML
<button type="button" class="button" aria-label="アニメーションを停止" data-button>
<svg width="24" height="24" viewBox="0 0 24 24" aria-hidden="true" class="icon stop">
<path fill="currentColor" d="M14 19V5h4v14zm-8 0V5h4v14z"></path>
</svg>
<svg width="24" height="24" viewBox="0 0 24 24" aria-hidden="true" class="icon play">
<path fill="currentColor" d="M8 5.14v14l11-7z"></path>
</svg>
</button>
ボタンがアイコンのみで構成されている場合、スクリーンリーダーのユーザーにその役割を伝えるためにaria-labelを使用します。今回はサイト訪問時にアニメーションが既に再生されていることを想定し、初期ラベルを「アニメーションを停止」に設定しました。
CSS
.icon.play {
display: none;
}
.button.stop .icon.play {
display: block;
}
.button.stop .icon.stop {
display: none;
}
JavaScript
// DOM要素の取得
const canvas = document.querySelector('[data-canvas]');
const button = document.querySelector('[data-button]');
// ...Three.jsの基本設定(シーン、カメラ、レンダラーなど)
// サンプルのボックスメッシュの作成
const box = new THREE.BoxGeometry(window.innerHeight * 0.5, window.innerHeight * 0.5, window.innerHeight * 0.5);
const material = new THREE.MeshBasicMaterial({ color: 'blue' });
const boxMesh = new THREE.Mesh(box, material);
scene.add(boxMesh);
let isPlaying = true;
let animationId = null;
const tick = () => {
if (isPlaying) {
boxMesh.rotation.y += 0.01;
boxMesh.rotation.x += 0.01;
boxMesh.rotation.z += 0.01;
}
renderer.render(scene, camera);
animationId = requestAnimationFrame(tick);
};
const handleButtonClick = () => {
isPlaying = !isPlaying;
if (!isPlaying) {
if (animationId) {
cancelAnimationFrame(animationId);
animationId = null;
}
} else {
tick();
}
button.setAttribute("aria-label", isPlaying ? "アニメーションを停止" : "アニメーションを再開");
button.classList.toggle("stop", !isPlaying);
};
button.addEventListener('click', handleButtonClick);
tick();
isPlayingはアニメーションの再生状態を管理するフラグです。
ボタンをクリックすると、アニメーションの再生/停止を切り替え、状態に応じてアイコンとaria-labelを更新します。これにより、スクリーンリーダーのユーザーにも、ボタンの現在の役割(「停止」か「再開」か)が正確に伝わります。
まとめ
今回はThree.jsを使用した3Dアニメーションに対して再生・停止ボタンを実装し、WCAG 2.2.2を達成する方法について解説しました。アニメーションの停止機能は、特定のユーザーのためだけでなく、すべてのユーザーにとっての使いやすさを向上させる重要な要素です。
ほんの少しの実装で、より多くのユーザーが快適にコンテンツを利用できるようになります。
この記事が、皆さんの実装の参考になれば幸いです。
参考
Discussion