-
-
Notifications
You must be signed in to change notification settings - Fork 961
/
index.ts
112 lines (99 loc) · 3.81 KB
/
index.ts
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
import {interpolate} from '../interpolate.js';
import {validateFrame} from '../validate-frame.js';
import {validateFps} from '../validation/validate-fps.js';
import {validateSpringDuration} from '../validation/validation-spring-duration.js';
import {measureSpring} from './measure-spring.js';
import type {SpringConfig} from './spring-utils';
import {springCalculation} from './spring-utils.js';
/**
* @description Calculates a position based on physical parameters, start and end value, and time.
* @see [Documentation](https://www.remotion.dev/docs/spring)
* @param {number} frame The current time value. Most of the time you want to pass in the return value of useCurrentFrame.
* @param {number} fps The framerate at which the animation runs. Pass in the value obtained by `useVideoConfig()`.
* @param {?boolean} reverse Whether the animation plays in reverse or not. Default `false`.
* @param {?Object} config optional object that allows you to customize the physical properties of the animation.
* @param {number} [config.mass=1] The weight of the spring. If you reduce the mass, the animation becomes faster!
* @param {number} [config.damping=10] How hard the animation decelerates.
* @param {number} [config.stiffness=100] Affects bounciness of the animation.
* @param {boolean} [config.overshootClamping=false] Whether to prevent the animation going beyond the target value.
* @param {?number} [config.from] The initial value of the animation. Default `0`
* @param {?number} [config.to] The end value of the animation. Default `1`
* @param {?number} [config.durationInFrames] Stretch the duration of an animation to a set value.. Default `undefined`
* @param {?number} [config.durationThreshold] How close to the end the animation is considered to be done. Default `0.005`
* @param {?number} [config.delay] Delay the animation for this amount of frames. Default `0`
*/
export function spring({
frame: passedFrame,
fps,
config = {},
from = 0,
to = 1,
durationInFrames: passedDurationInFrames,
durationRestThreshold,
delay = 0,
reverse = false,
}: {
frame: number;
fps: number;
config?: Partial<SpringConfig>;
from?: number;
to?: number;
durationInFrames?: number;
durationRestThreshold?: number;
delay?: number;
reverse?: boolean;
}): number {
validateSpringDuration(passedDurationInFrames);
validateFrame({
frame: passedFrame,
durationInFrames: Infinity,
allowFloats: true,
});
validateFps(fps, 'to spring()', false);
const needsToCalculateNaturalDuration =
reverse || typeof passedDurationInFrames !== 'undefined';
const naturalDuration = needsToCalculateNaturalDuration
? measureSpring({
fps,
config,
threshold: durationRestThreshold,
})
: undefined;
const naturalDurationGetter = needsToCalculateNaturalDuration
? {
get: () => naturalDuration as number,
}
: {
get: () => {
throw new Error(
'did not calculate natural duration, this is an error with Remotion. Please report',
);
},
};
const reverseProcessed = reverse
? (passedDurationInFrames ?? naturalDurationGetter.get()) - passedFrame
: passedFrame;
const delayProcessed = reverseProcessed + (reverse ? delay : -delay);
const durationProcessed =
passedDurationInFrames === undefined
? delayProcessed
: delayProcessed / (passedDurationInFrames / naturalDurationGetter.get());
if (passedDurationInFrames && delayProcessed > passedDurationInFrames) {
return to;
}
const spr = springCalculation({
fps,
frame: durationProcessed,
config,
});
const inner = config.overshootClamping
? to >= from
? Math.min(spr.current, to)
: Math.max(spr.current, to)
: spr.current;
const interpolated =
from === 0 && to === 1 ? inner : interpolate(inner, [0, 1], [from, to]);
return interpolated;
}
export {measureSpring} from './measure-spring.js';
export type {SpringConfig} from './spring-utils';