diff --git a/packages/react-native-reanimated/src/layoutReanimation/web/componentUtils.ts b/packages/react-native-reanimated/src/layoutReanimation/web/componentUtils.ts index e5a1ea303e0..d8085301a3e 100644 --- a/packages/react-native-reanimated/src/layoutReanimation/web/componentUtils.ts +++ b/packages/react-native-reanimated/src/layoutReanimation/web/componentUtils.ts @@ -175,6 +175,9 @@ export function handleLayoutTransition( case 'FadingTransition': animationType = TransitionType.FADING; break; + case 'JumpingTransition': + animationType = TransitionType.JUMPING; + break; default: animationType = TransitionType.LINEAR; break; diff --git a/packages/react-native-reanimated/src/layoutReanimation/web/config.ts b/packages/react-native-reanimated/src/layoutReanimation/web/config.ts index 60307910897..47bf53cea33 100644 --- a/packages/react-native-reanimated/src/layoutReanimation/web/config.ts +++ b/packages/react-native-reanimated/src/layoutReanimation/web/config.ts @@ -65,6 +65,7 @@ export enum TransitionType { LINEAR, SEQUENCED, FADING, + JUMPING, } export const AnimationsData: Record = { diff --git a/packages/react-native-reanimated/src/layoutReanimation/web/createAnimation.ts b/packages/react-native-reanimated/src/layoutReanimation/web/createAnimation.ts index ff147f5c129..0354d118d6c 100644 --- a/packages/react-native-reanimated/src/layoutReanimation/web/createAnimation.ts +++ b/packages/react-native-reanimated/src/layoutReanimation/web/createAnimation.ts @@ -10,6 +10,7 @@ import type { TransformsStyle } from 'react-native'; import { LinearTransition } from './transition/Linear.web'; import { SequencedTransition } from './transition/Sequenced.web'; import { FadingTransition } from './transition/Fading.web'; +import { JumpingTransition } from './transition/Jumping.web'; import { insertWebAnimation } from './domUtils'; // Translate values are passed as numbers. However, if `translate` property receives number, it will not automatically @@ -81,6 +82,13 @@ export function TransitionGenerator( transitionData ); break; + + case TransitionType.JUMPING: + transitionObject = JumpingTransition( + transitionKeyframeName, + transitionData + ); + break; } const transitionKeyframe = diff --git a/packages/react-native-reanimated/src/layoutReanimation/web/transition/Jumping.web.ts b/packages/react-native-reanimated/src/layoutReanimation/web/transition/Jumping.web.ts new file mode 100644 index 00000000000..b8c17f234c0 --- /dev/null +++ b/packages/react-native-reanimated/src/layoutReanimation/web/transition/Jumping.web.ts @@ -0,0 +1,44 @@ +'use strict'; +import type { TransitionData } from '../animationParser'; +import { Easing } from '../../../Easing'; + +export function JumpingTransition( + name: string, + transitionData: TransitionData +) { + const { translateX, translateY, scaleX, scaleY } = transitionData; + + const d = Math.max(Math.abs(translateX), Math.abs(translateY)) / 2; + const peakTranslateY = translateY <= 0 ? translateY - d : -translateY + d; + + const jumpingTransition = { + name, + style: { + 0: { + transform: [ + { + translateX: `${translateX}px`, + translateY: `${translateY}px`, + scale: `${scaleX},${scaleY}`, + }, + ], + easing: Easing.exp, + }, + 50: { + transform: [ + { + translateX: `${translateX / 2}px`, + translateY: `${peakTranslateY}px`, + scale: `${scaleX},${scaleY}`, + }, + ], + }, + 100: { + transform: [{ translateX: '0px', translateY: '0px', scale: '1,1' }], + }, + }, + duration: 300, + }; + + return jumpingTransition; +}