-
-
Notifications
You must be signed in to change notification settings - Fork 961
/
flip.tsx
96 lines (87 loc) · 2.83 KB
/
flip.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
import React, {useMemo} from 'react';
import {AbsoluteFill, interpolate} from 'remotion';
import type {
TransitionPresentation,
TransitionPresentationComponentProps,
} from '../types.js';
export type FlipDirection =
| 'from-left'
| 'from-right'
| 'from-top'
| 'from-bottom';
export type FlipProps = {
direction?: FlipDirection;
perspective?: number;
outerEnterStyle?: React.CSSProperties;
outerExitStyle?: React.CSSProperties;
innerEnterStyle?: React.CSSProperties;
innerExitStyle?: React.CSSProperties;
};
const Flip: React.FC<TransitionPresentationComponentProps<FlipProps>> = ({
children,
presentationDirection,
presentationProgress,
passedProps: {
direction = 'from-left',
perspective = 1000,
innerEnterStyle,
innerExitStyle,
outerEnterStyle,
outerExitStyle,
},
}) => {
const style: React.CSSProperties = useMemo(() => {
const startRotationEntering =
direction === 'from-right' || direction === 'from-top' ? 180 : -180;
const endRotationEntering =
direction === 'from-right' || direction === 'from-top' ? -180 : 180;
const rotation =
presentationDirection === 'entering'
? interpolate(presentationProgress, [0, 1], [startRotationEntering, 0])
: interpolate(presentationProgress, [0, 1], [0, endRotationEntering]);
const rotateProperty =
direction === 'from-top' || direction === 'from-bottom'
? 'rotateX'
: 'rotateY';
return {
width: '100%',
height: '100%',
transform: `${rotateProperty}(${rotation}deg)`,
backfaceVisibility: 'hidden',
WebkitBackfaceVisibility: 'hidden',
...(presentationDirection === 'entering'
? innerEnterStyle
: innerExitStyle),
};
}, [
direction,
innerEnterStyle,
innerExitStyle,
presentationDirection,
presentationProgress,
]);
const outer: React.CSSProperties = useMemo(() => {
return {
perspective,
// Make children also their backface hidden
transformStyle: 'preserve-3d',
...(presentationDirection === 'entering'
? outerEnterStyle
: outerExitStyle),
};
}, [outerEnterStyle, outerExitStyle, perspective, presentationDirection]);
return (
<AbsoluteFill style={outer}>
<AbsoluteFill style={style}>{children}</AbsoluteFill>
</AbsoluteFill>
);
};
/**
* @description A presentation where the exiting slide flips by 180 degrees, revealing the next slide on the back side. This function configures a 3D flip effect for transitions between components in presentations.
* @see [Documentation](https://remotion.dev/docs/transitions/presentations/flip)
* @param {FlipProps} [props] Optional properties to configure the flip effect, including direction, perspective, and styles.
* @returns {TransitionPresentation<FlipProps>} An object with the Flip component and configuration properties.
*/
export const flip = (props?: FlipProps): TransitionPresentation<FlipProps> => {
return {component: Flip, props: props ?? {}};
};