Limit animation when reduced motion is preferred

This commit is contained in:
Sam Becker 2023-11-10 22:39:14 -06:00
parent 5f99e46cbe
commit e1e2552f5d
2 changed files with 29 additions and 0 deletions

View File

@ -3,6 +3,7 @@
import { ReactNode, useRef } from 'react';
import { Variant, motion } from 'framer-motion';
import { useAppState } from '@/state';
import usePrefersReducedMotion from '@/utility/usePrefersReducedMotion';
export type AnimationType = 'none' | 'scale' | 'left' | 'right' | 'bottom';
@ -41,11 +42,14 @@ function AnimateItems({
nextPhotoAnimation,
clearNextPhotoAnimation,
} = useAppState();
const prefersReducedMotion = usePrefersReducedMotion();
const hasLoadedInitial = useRef(hasLoaded);
const nextPhotoAnimationInitial = useRef(nextPhotoAnimation);
const shouldAnimate = type !== 'none' &&
!prefersReducedMotion &&
!(animateOnFirstLoadOnly && hasLoadedInitial.current);
const shouldStagger =
!(staggerOnFirstLoadOnly && hasLoadedInitial.current);

View File

@ -0,0 +1,25 @@
import { useEffect, useState } from 'react';
const MEDIA_QUERY_SELECTOR = '(prefers-reduced-motion: reduce)';
const MEDIA_QUERY_EVENT = 'change';
const usePrefersReducedMotion = () => {
const [prefersReducedMotion, setPrefersReducedMotion] = useState(
window.matchMedia(MEDIA_QUERY_SELECTOR).matches
);
useEffect(() => {
const mediaQuery = window.matchMedia(MEDIA_QUERY_SELECTOR);
const listener = () => {
setPrefersReducedMotion(mediaQuery.matches);
};
mediaQuery.addEventListener(MEDIA_QUERY_EVENT, listener);
return () => mediaQuery.removeEventListener(MEDIA_QUERY_EVENT, listener);
}, []);
return prefersReducedMotion;
};
export default usePrefersReducedMotion;