Skip to content

Commit

Permalink
Merge pull request #2125 from tf/backdrop-reduced-motion
Browse files Browse the repository at this point in the history
Honor user's reduced motion preference for backdrop animations
  • Loading branch information
tf authored Jul 12, 2024
2 parents 25b40ca + 85ccce8 commit 8c1d959
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,33 @@ describe('backdrop animation effects', () => {
expect(animateMock).not.toHaveBeenCalled();
});

it('neither calls animate nor sets up view timeline when reduced motion is preferred', () => {
window.matchMedia.mockPrefersReducedMotion();

renderEntry({
seed: {
imageFiles: [{permaId: 100}],
sections: [
{
permaId: 1,
configuration: {
backdrop: {image: 100},
backdropEffects: [
{
name: 'scrollParallax',
value: 40
}
]
}
}
]
}
});

expect(viewTimelines.length).toEqual(0);
expect(animateMock).not.toHaveBeenCalled();
});

it('supports auto zoom', () => {
const {getSectionByPermaId} = renderEntry({
seed: {
Expand Down Expand Up @@ -245,4 +272,32 @@ describe('backdrop animation effects', () => {

expect(animateMock).not.toHaveBeenCalled();
});

it('does not autozoom if reduced motion is preferred', () => {
window.matchMedia.mockPrefersReducedMotion();

const {getSectionByPermaId} = renderEntry({
seed: {
imageFiles: [{permaId: 100}],
sections: [
{
permaId: 1,
configuration: {
backdrop: {image: 100},
backdropEffects: [
{
name: 'autoZoom',
value: 50
}
]
}
}
]
}
});

getSectionByPermaId(1).simulateScrollingIntoView();

expect(animateMock).not.toHaveBeenCalled();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,4 @@ describe('Backdrop Effects getFilter', () => {

expect(result).toEqual('grayscale(20%)');
});

it('sets up scroll animation ', () => {

});
});
14 changes: 13 additions & 1 deletion entry_types/scrolled/package/spec/support/matchMediaStub.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
let mockOrientation;
let mockPrefersReducedMotion;

Object.defineProperty(window, 'matchMedia', {
writable: true,
Expand All @@ -17,6 +18,13 @@ Object.defineProperty(window, 'matchMedia', {
matches: mockOrientation !== 'portrait'
};
}
else if (query === '(prefers-reduced-motion)') {
return {
addEventListener: jest.fn(),
removeEventListener: jest.fn(),
matches: mockPrefersReducedMotion
};
}
else {
return {
addEventListener: jest.fn(),
Expand All @@ -27,6 +35,10 @@ Object.defineProperty(window, 'matchMedia', {
})
});

beforeEach(() => mockOrientation = 'landscape');
beforeEach(() => {
mockOrientation = 'landscape';
mockPrefersReducedMotion = false;
});

window.matchMedia.mockPortrait = () => mockOrientation = 'portrait';
window.matchMedia.mockPrefersReducedMotion = () => mockPrefersReducedMotion = true;
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import React, {useContext, useEffect, useState, useRef} from 'react';

import {prefersReducedMotion} from './prefersReducedMotion';

const SectionViewTimelineContext = React.createContext();

export function SectionViewTimelineProvider({backdrop, children}) {
Expand All @@ -9,7 +11,7 @@ export function SectionViewTimelineProvider({backdrop, children}) {
const isNeeded = backdrop?.effects?.some(effect => effect.name === 'scrollParallax');

useEffect(() => {
if (!isNeeded || !window.ViewTimeline) {
if (!isNeeded || !window.ViewTimeline || prefersReducedMotion()) {
return;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function prefersReducedMotion() {
return window.matchMedia('(prefers-reduced-motion)').matches;
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import styles from '../../Backdrop.module.css';
import {useSectionViewTimeline} from '../../SectionViewTimelineProvider';
import {useSectionLifecycle} from '../../useSectionLifecycle';
import {useIsStaticPreview} from '../../useScrollPositionLifecycle';
import {prefersReducedMotion} from '../../prefersReducedMotion';

export function Effects({file, children}) {
const ref = useRef();
Expand Down Expand Up @@ -45,7 +46,7 @@ export function Effects({file, children}) {
const y = file?.motifArea ? 50 - (file.motifArea.top + file.motifArea.height / 2) : 0;

useIsomorphicLayoutEffect(() => {
if (autoZoomValue && isVisible) {
if (autoZoomValue && isVisible && !prefersReducedMotion()) {
const animation = ref.current.animate(
{
transform: [
Expand Down

0 comments on commit 8c1d959

Please sign in to comment.