mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-08-28 05:27:24 +00:00
fix(web): respect prefers-reduced-motion in AnimatedBackground
Ensure the animated canvas renders a single static frame and never starts requestAnimationFrame when prefers-reduced-motion: reduce is enabled. Adds runtime listener to stop animations if the user toggles the setting. Mousemove listener is only attached when animating.
This commit is contained in:
parent
5e218febdb
commit
cd07bac576
1 changed files with 49 additions and 6 deletions
|
|
@ -225,8 +225,9 @@ export function AnimatedBackground() {
|
|||
connectParticles()
|
||||
}
|
||||
|
||||
// Animation loop.
|
||||
let animationId: number
|
||||
// Animation loop and reduced-motion handling.
|
||||
let animationId: number | undefined
|
||||
let isAnimating = false
|
||||
|
||||
// Target position for smooth following.
|
||||
let targetX = canvas.width * 0.2
|
||||
|
|
@ -265,14 +266,56 @@ export function AnimatedBackground() {
|
|||
drawGrid()
|
||||
}
|
||||
|
||||
animate()
|
||||
const startAnimation = () => {
|
||||
if (isAnimating) return
|
||||
isAnimating = true
|
||||
window.addEventListener("mousemove", handleMouseMove)
|
||||
animate()
|
||||
}
|
||||
|
||||
window.addEventListener("mousemove", handleMouseMove)
|
||||
const stopAnimation = () => {
|
||||
if (!isAnimating) return
|
||||
isAnimating = false
|
||||
window.removeEventListener("mousemove", handleMouseMove)
|
||||
if (animationId !== undefined) cancelAnimationFrame(animationId)
|
||||
}
|
||||
|
||||
// Respect user preference for reduced motion
|
||||
const mediaQuery =
|
||||
typeof window !== "undefined" && "matchMedia" in window
|
||||
? window.matchMedia("(prefers-reduced-motion: reduce)")
|
||||
: null
|
||||
|
||||
const onMotionPreferenceChange = (e: MediaQueryListEvent) => {
|
||||
if (e.matches) {
|
||||
// User prefers reduced motion now
|
||||
stopAnimation()
|
||||
// Render a single static frame
|
||||
drawGrid()
|
||||
} else {
|
||||
// User allows motion
|
||||
startAnimation()
|
||||
}
|
||||
}
|
||||
|
||||
if (mediaQuery) {
|
||||
if (mediaQuery.matches) {
|
||||
// Reduced motion: render one static frame
|
||||
drawGrid()
|
||||
} else {
|
||||
startAnimation()
|
||||
}
|
||||
mediaQuery.addEventListener("change", onMotionPreferenceChange)
|
||||
} else {
|
||||
// Fallback if matchMedia is unavailable
|
||||
startAnimation()
|
||||
}
|
||||
|
||||
return () => {
|
||||
window.removeEventListener("resize", resizeCanvas)
|
||||
window.removeEventListener("mousemove", handleMouseMove)
|
||||
cancelAnimationFrame(animationId)
|
||||
// Ensure animation and listeners are stopped
|
||||
stopAnimation()
|
||||
if (mediaQuery) mediaQuery.removeEventListener("change", onMotionPreferenceChange)
|
||||
}
|
||||
}, [])
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue