UNPKG

9.59 kBPlain TextView Raw
1'use strict';
2import { withTiming, withSpring } from '../../animation';
3import type {
4 AnimationFunction,
5 BaseBuilderAnimationConfig,
6 LayoutAnimationAndConfig,
7} from './commonTypes';
8import type { EasingFunction } from '../../Easing';
9import { BaseAnimationBuilder } from './BaseAnimationBuilder';
10import type { StyleProps } from '../../commonTypes';
11import { assertEasingIsWorklet } from '../../animation/util';
12
13export class ComplexAnimationBuilder extends BaseAnimationBuilder {
14 easingV?: EasingFunction;
15 rotateV?: string;
16 type?: AnimationFunction;
17 dampingV?: number;
18 dampingRatioV?: number;
19 massV?: number;
20 stiffnessV?: number;
21 overshootClampingV?: number;
22 restDisplacementThresholdV?: number;
23 restSpeedThresholdV?: number;
24 initialValues?: StyleProps;
25
26 static createInstance: <T extends typeof BaseAnimationBuilder>(
27 this: T
28 ) => InstanceType<T>;
29
30 /**
31 * Lets you change the easing curve of the animation. Can be chained alongside other [layout animation modifiers](https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/glossary#layout-animation-modifier).
32 *
33 * @param easingFunction - An easing function which defines the animation curve.
34 */
35 static easing<T extends typeof ComplexAnimationBuilder>(
36 this: T,
37 easingFunction: EasingFunction
38 ) {
39 const instance = this.createInstance();
40 return instance.easing(easingFunction);
41 }
42
43 easing(easingFunction: EasingFunction): this {
44 if (__DEV__) {
45 assertEasingIsWorklet(easingFunction);
46 }
47 this.easingV = easingFunction;
48 return this;
49 }
50
51 /**
52 * Lets you rotate the element. Can be chained alongside other [layout animation modifiers](https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/glossary#layout-animation-modifier).
53 *
54 * @param degree - The rotation degree.
55 */
56 static rotate<T extends typeof ComplexAnimationBuilder>(
57 this: T,
58 degree: string
59 ) {
60 const instance = this.createInstance();
61 return instance.rotate(degree);
62 }
63
64 rotate(degree: string): this {
65 this.rotateV = degree;
66 return this;
67 }
68
69 /**
70 * Enables the spring-based animation configuration. Can be chained alongside other [layout animation modifiers](https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/glossary#layout-animation-modifier).
71 *
72 * @param duration - An optional duration of the spring animation (in milliseconds).
73 */
74 static springify<T extends typeof ComplexAnimationBuilder>(
75 this: T,
76 duration?: number
77 ): ComplexAnimationBuilder {
78 const instance = this.createInstance();
79 return instance.springify(duration);
80 }
81
82 springify(duration?: number): this {
83 this.durationV = duration;
84 this.type = withSpring as AnimationFunction;
85 return this;
86 }
87
88 /**
89 * Lets you adjust the spring animation damping ratio. Can be chained alongside other [layout animation modifiers](https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/glossary#layout-animation-modifier).
90 *
91 * @param dampingRatio - How damped the spring is.
92 */
93 static dampingRatio<T extends typeof ComplexAnimationBuilder>(
94 this: T,
95 dampingRatio: number
96 ) {
97 const instance = this.createInstance();
98 return instance.dampingRatio(dampingRatio);
99 }
100
101 dampingRatio(value: number): this {
102 this.dampingRatioV = value;
103 return this;
104 }
105
106 /**
107 * Lets you adjust the spring animation damping. Can be chained alongside other [layout animation modifiers](https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/glossary#layout-animation-modifier).
108 *
109 * @param value - Decides how quickly a spring stops moving. Higher damping means the spring will come to rest faster.
110 */
111 static damping<T extends typeof ComplexAnimationBuilder>(
112 this: T,
113 damping: number
114 ) {
115 const instance = this.createInstance();
116 return instance.damping(damping);
117 }
118
119 damping(damping: number): this {
120 this.dampingV = damping;
121 return this;
122 }
123
124 /**
125 * Lets you adjust the spring animation mass. Can be chained alongside other [layout animation modifiers](https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/glossary#layout-animation-modifier).
126 *
127 * @param mass - The weight of the spring. Reducing this value makes the animation faster.
128 */
129 static mass<T extends typeof ComplexAnimationBuilder>(this: T, mass: number) {
130 const instance = this.createInstance();
131 return instance.mass(mass);
132 }
133
134 mass(mass: number): this {
135 this.massV = mass;
136 return this;
137 }
138
139 /**
140 * Lets you adjust the stiffness of the spring animation. Can be chained alongside other [layout animation modifiers](https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/glossary#layout-animation-modifier).
141 *
142 * @param stiffness - How bouncy the spring is.
143 */
144 static stiffness<T extends typeof ComplexAnimationBuilder>(
145 this: T,
146 stiffness: number
147 ) {
148 const instance = this.createInstance();
149 return instance.stiffness(stiffness);
150 }
151
152 stiffness(stiffness: number): this {
153 this.stiffnessV = stiffness;
154 return this;
155 }
156
157 /**
158 * Lets you adjust overshoot clamping of the spring. Can be chained alongside other [layout animation modifiers](https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/glossary#layout-animation-modifier).
159 *
160 * @param overshootClamping - Whether a spring can bounce over the final position.
161 */
162 static overshootClamping<T extends typeof ComplexAnimationBuilder>(
163 this: T,
164 overshootClamping: number
165 ) {
166 const instance = this.createInstance();
167 return instance.overshootClamping(overshootClamping);
168 }
169
170 overshootClamping(overshootClamping: number): this {
171 this.overshootClampingV = overshootClamping;
172 return this;
173 }
174
175 /**
176 * Lets you adjust the rest displacement threshold of the spring animation. Can be chained alongside other [layout animation modifiers](https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/glossary#layout-animation-modifier).
177 *
178 * @param restDisplacementThreshold - The displacement below which the spring will snap to the designated position without further oscillations.
179 */
180 static restDisplacementThreshold<T extends typeof ComplexAnimationBuilder>(
181 this: T,
182 restDisplacementThreshold: number
183 ) {
184 const instance = this.createInstance();
185 return instance.restDisplacementThreshold(restDisplacementThreshold);
186 }
187
188 restDisplacementThreshold(restDisplacementThreshold: number) {
189 this.restDisplacementThresholdV = restDisplacementThreshold;
190 return this;
191 }
192
193 /**
194 * Lets you adjust the rest speed threshold of the spring animation. Can be chained alongside other [layout animation modifiers](https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/glossary#layout-animation-modifier).
195 *
196 * @param restSpeedThreshold - The speed in pixels per second from which the spring will snap to the designated position without further oscillations.
197 */
198 static restSpeedThreshold<T extends typeof ComplexAnimationBuilder>(
199 this: T,
200 restSpeedThreshold: number
201 ) {
202 const instance = this.createInstance();
203 return instance.restSpeedThreshold(restSpeedThreshold);
204 }
205
206 restSpeedThreshold(restSpeedThreshold: number): this {
207 this.restSpeedThresholdV = restSpeedThreshold;
208 return this;
209 }
210
211 /**
212 * Lets you override the initial config of the animation
213 *
214 * @param values - An object containing the styles to override.
215 */
216 static withInitialValues<T extends typeof ComplexAnimationBuilder>(
217 this: T,
218 values: StyleProps
219 ) {
220 const instance = this.createInstance();
221 return instance.withInitialValues(values);
222 }
223
224 withInitialValues(values: StyleProps): this {
225 this.initialValues = values;
226 return this;
227 }
228
229 getAnimationAndConfig(): LayoutAnimationAndConfig {
230 const duration = this.durationV;
231 const easing = this.easingV;
232 const rotate = this.rotateV;
233 const type = this.type ? this.type : (withTiming as AnimationFunction);
234 const damping = this.dampingV;
235 const dampingRatio = this.dampingRatioV;
236 const mass = this.massV;
237 const stiffness = this.stiffnessV;
238 const overshootClamping = this.overshootClampingV;
239 const restDisplacementThreshold = this.restDisplacementThresholdV;
240 const restSpeedThreshold = this.restSpeedThresholdV;
241
242 const animation = type;
243
244 const config: BaseBuilderAnimationConfig = {};
245
246 function maybeSetConfigValue<Key extends keyof BaseBuilderAnimationConfig>(
247 value: BaseBuilderAnimationConfig[Key],
248 variableName: Key
249 ) {
250 if (value) {
251 config[variableName] = value;
252 }
253 }
254
255 if (type === withTiming) {
256 maybeSetConfigValue(easing, 'easing');
257 }
258
259 (
260 [
261 { variableName: 'damping', value: damping },
262 { variableName: 'dampingRatio', value: dampingRatio },
263 { variableName: 'mass', value: mass },
264 { variableName: 'stiffness', value: stiffness },
265 { variableName: 'overshootClamping', value: overshootClamping },
266 {
267 variableName: 'restDisplacementThreshold',
268 value: restDisplacementThreshold,
269 },
270 { variableName: 'restSpeedThreshold', value: restSpeedThreshold },
271 { variableName: 'duration', value: duration },
272 { variableName: 'rotate', value: rotate },
273 ] as const
274 ).forEach(({ value, variableName }) =>
275 maybeSetConfigValue(value, variableName)
276 );
277
278 return [animation, config];
279 }
280}