UNPKG

5 kBPlain TextView Raw
1'use strict';
2import { withDelay } from '../../animation';
3import type {
4 EntryExitAnimationFunction,
5 AnimationFunction,
6 LayoutAnimationFunction,
7} from './commonTypes';
8
9import { ReduceMotion } from '../../commonTypes';
10import { getReduceMotionFromConfig } from '../../animation/util';
11
12export class BaseAnimationBuilder {
13 durationV?: number;
14 delayV?: number;
15 reduceMotionV: ReduceMotion = ReduceMotion.System;
16 randomizeDelay = false;
17 callbackV?: (finished: boolean) => void;
18
19 static createInstance: <T extends typeof BaseAnimationBuilder>(
20 this: T
21 ) => InstanceType<T>;
22
23 build = (): EntryExitAnimationFunction | LayoutAnimationFunction => {
24 throw new Error('[Reanimated] Unimplemented method in child class.');
25 };
26
27 /**
28 * Lets you adjust the animation duration. Can be chained alongside other [layout animation modifiers](https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/glossary#layout-animation-modifier).
29 *
30 * @param durationMs - Length of the animation (in milliseconds).
31 */
32 static duration<T extends typeof BaseAnimationBuilder>(
33 this: T,
34 durationMs: number
35 ): InstanceType<T> {
36 const instance = this.createInstance();
37 return instance.duration(durationMs);
38 }
39
40 duration(durationMs: number): this {
41 this.durationV = durationMs;
42 return this;
43 }
44
45 /**
46 * Lets you adjust the delay before the animation starts (in milliseconds). Can be chained alongside other [layout animation modifiers](https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/glossary#layout-animation-modifier).
47 *
48 * @param delayMs - Delay before the animation starts (in milliseconds).
49 */
50 static delay<T extends typeof BaseAnimationBuilder>(
51 this: T,
52 delayMs: number
53 ): InstanceType<T> {
54 const instance = this.createInstance();
55 return instance.delay(delayMs);
56 }
57
58 delay(delayMs: number): this {
59 this.delayV = delayMs;
60 return this;
61 }
62
63 /**
64 * The callback that will fire after the animation ends. Can be chained alongside other [layout animation modifiers](https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/glossary#layout-animation-modifier).
65 *
66 * @param callback - Callback that will fire after the animation ends.
67 */
68 static withCallback<T extends typeof BaseAnimationBuilder>(
69 this: T,
70 callback: (finished: boolean) => void
71 ): InstanceType<T> {
72 const instance = this.createInstance();
73 return instance.withCallback(callback);
74 }
75
76 withCallback(callback: (finished: boolean) => void): this {
77 this.callbackV = callback;
78 return this;
79 }
80
81 /**
82 * Lets you adjust the behavior when the device's reduced motion accessibility setting is turned on. Can be chained alongside other [layout animation modifiers](https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/glossary#layout-animation-modifier).
83 *
84 * @param reduceMotion - Determines how the animation responds to the device's reduced motion accessibility setting. Default to `ReduceMotion.System` - {@link ReduceMotion}.
85 */
86 static reduceMotion<T extends typeof BaseAnimationBuilder>(
87 this: T,
88 reduceMotion: ReduceMotion
89 ): InstanceType<T> {
90 const instance = this.createInstance();
91 return instance.reduceMotion(reduceMotion);
92 }
93
94 reduceMotion(reduceMotionV: ReduceMotion): this {
95 this.reduceMotionV = reduceMotionV;
96 return this;
97 }
98
99 // 300ms is the default animation duration. If any animation has different default has to override this method.
100 static getDuration(): number {
101 return 300;
102 }
103
104 getDuration(): number {
105 return this.durationV ?? 300;
106 }
107
108 /**
109 * @deprecated Use `.delay()` with `Math.random()` instead
110 */
111 static randomDelay<T extends typeof BaseAnimationBuilder>(
112 this: T
113 ): InstanceType<T> {
114 const instance = this.createInstance();
115 return instance.randomDelay();
116 }
117
118 randomDelay(): this {
119 this.randomizeDelay = true;
120 return this;
121 }
122
123 // when randomizeDelay is set to true, randomize delay between 0 and provided value (or 1000ms if delay is not provided)
124 getDelay(): number {
125 return this.randomizeDelay
126 ? Math.random() * (this.delayV ?? 1000)
127 : this.delayV ?? 0;
128 }
129
130 getReduceMotion(): ReduceMotion {
131 return this.reduceMotionV;
132 }
133
134 getDelayFunction(): AnimationFunction {
135 const isDelayProvided = this.randomizeDelay || this.delayV;
136 const reduceMotion = this.getReduceMotion();
137 return isDelayProvided
138 ? (delay, animation) => {
139 'worklet';
140 return withDelay(delay, animation, reduceMotion);
141 }
142 : (_, animation) => {
143 'worklet';
144 animation.reduceMotion = getReduceMotionFromConfig(reduceMotion);
145 return animation;
146 };
147 }
148
149 static build<T extends typeof BaseAnimationBuilder>(
150 this: T
151 ): EntryExitAnimationFunction | LayoutAnimationFunction {
152 const instance = this.createInstance();
153 return instance.build();
154 }
155}