From a71d081155bd3e7cd26383b8c1e7fa334a32daa0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Bert?= <63123542+m-bert@users.noreply.github.com> Date: Mon, 22 Jul 2024 12:48:23 +0200 Subject: [PATCH] [Web LA] Fix `easing` (#6304) ## Summary After #6163 was merged, each `worklet` function follows new naming convention. Since `easings` are `worklets`, their `name` property has also been changed. In web layout animations we were applying `easing` based on its name, therefore changing it resulted in only default `linear` easing being available on web. This PR adds new `Symbol` into easing functions so that we can once again get their name and apply correct easing to animations. ## Test plan Tested on _**BasicLayoutAnimation**_ example with `Easing.exp` --- .../react-native-reanimated/src/Easing.ts | 11 ++++++++++ .../layoutReanimation/web/componentUtils.ts | 22 ++++++++++++++----- .../src/layoutReanimation/web/config.ts | 7 +++++- 3 files changed, 34 insertions(+), 6 deletions(-) diff --git a/packages/react-native-reanimated/src/Easing.ts b/packages/react-native-reanimated/src/Easing.ts index 224cbd382f3..c24b8e3812b 100644 --- a/packages/react-native-reanimated/src/Easing.ts +++ b/packages/react-native-reanimated/src/Easing.ts @@ -313,4 +313,15 @@ const EasingObject = { inOut, }; +export const EasingNameSymbol = Symbol('easingName'); + +for (const [easingName, easing] of Object.entries(EasingObject)) { + Object.defineProperty(easing, EasingNameSymbol, { + value: easingName, + configurable: false, + enumerable: false, + writable: false, + }); +} + export const Easing = EasingObject; diff --git a/packages/react-native-reanimated/src/layoutReanimation/web/componentUtils.ts b/packages/react-native-reanimated/src/layoutReanimation/web/componentUtils.ts index 32f60d3258b..9a52b26c44c 100644 --- a/packages/react-native-reanimated/src/layoutReanimation/web/componentUtils.ts +++ b/packages/react-native-reanimated/src/layoutReanimation/web/componentUtils.ts @@ -21,14 +21,26 @@ import type { ReanimatedSnapshot, ScrollOffsets } from './componentStyle'; import { setElementPosition, snapshots } from './componentStyle'; import { Keyframe } from '../animationBuilder'; import { ReducedMotionManager } from '../../ReducedMotion'; +import { EasingNameSymbol } from '../../Easing'; function getEasingFromConfig(config: CustomConfig): string { - const easingName = - config.easingV && config.easingV.name in WebEasings - ? (config.easingV.name as WebEasingsNames) - : 'linear'; + if (!config.easingV) { + return `cubic-bezier(${WebEasings.linear.toString()})`; + } + + const easingName = config.easingV[EasingNameSymbol]; + + if (!(easingName in WebEasings)) { + console.warn( + `[Reanimated] Selected easing is not currently supported on web.` + ); + + return `cubic-bezier(${WebEasings.linear.toString()})`; + } - return `cubic-bezier(${WebEasings[easingName].toString()})`; + return `cubic-bezier(${WebEasings[ + easingName as WebEasingsNames + ].toString()})`; } function getRandomDelay(maxDelay = 1000) { diff --git a/packages/react-native-reanimated/src/layoutReanimation/web/config.ts b/packages/react-native-reanimated/src/layoutReanimation/web/config.ts index 9baa39e9ae3..068fac48c63 100644 --- a/packages/react-native-reanimated/src/layoutReanimation/web/config.ts +++ b/packages/react-native-reanimated/src/layoutReanimation/web/config.ts @@ -57,8 +57,13 @@ export interface AnimationConfig { reversed: boolean; } +interface EasingType { + (): number; + [EasingNameSymbol: symbol]: string; +} + export interface CustomConfig { - easingV?: () => number; + easingV?: EasingType; durationV?: number; delayV?: number; randomizeDelay?: boolean;