@ng-native/components 0.0.1 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +78 -1
- package/dist/activity-indicator.d.ts +41 -0
- package/dist/activity-indicator.js +66 -0
- package/dist/activity-indicator.js.map +1 -0
- package/dist/animated-style.d.ts +31 -0
- package/dist/animated-style.js +102 -0
- package/dist/animated-style.js.map +1 -0
- package/dist/animated.d.ts +125 -0
- package/dist/animated.js +538 -0
- package/dist/animated.js.map +1 -0
- package/dist/animation.d.ts +40 -0
- package/dist/animation.js +20 -0
- package/dist/animation.js.map +1 -0
- package/dist/animations-web.d.ts +8 -0
- package/dist/animations-web.js +31 -0
- package/dist/animations-web.js.map +1 -0
- package/dist/animations.d.ts +7 -0
- package/dist/animations.js +58 -0
- package/dist/animations.js.map +1 -0
- package/dist/controlled-model.d.ts +33 -0
- package/dist/controlled-model.js +47 -0
- package/dist/controlled-model.js.map +1 -0
- package/dist/easing.d.ts +21 -0
- package/dist/easing.js +50 -0
- package/dist/easing.js.map +1 -0
- package/dist/events.d.ts +169 -0
- package/dist/events.js +2 -0
- package/dist/events.js.map +1 -0
- package/dist/gesture-backend.d.ts +26 -0
- package/dist/gesture-backend.js +14 -0
- package/dist/gesture-backend.js.map +1 -0
- package/dist/gesture-dispatch.d.ts +67 -0
- package/dist/gesture-dispatch.js +106 -0
- package/dist/gesture-dispatch.js.map +1 -0
- package/dist/gestures.d.ts +23 -0
- package/dist/gestures.js +164 -0
- package/dist/gestures.js.map +1 -0
- package/dist/height-index.d.ts +31 -0
- package/dist/height-index.js +80 -0
- package/dist/height-index.js.map +1 -0
- package/dist/image-background.d.ts +32 -0
- package/dist/image-background.js +80 -0
- package/dist/image-background.js.map +1 -0
- package/dist/image.d.ts +79 -0
- package/dist/image.js +155 -0
- package/dist/image.js.map +1 -0
- package/dist/index.d.ts +38 -0
- package/dist/index.js +39 -0
- package/dist/index.js.map +1 -0
- package/dist/input-accessory-view.d.ts +16 -0
- package/dist/input-accessory-view.js +29 -0
- package/dist/input-accessory-view.js.map +1 -0
- package/dist/keyboard-avoiding-view.d.ts +79 -0
- package/dist/keyboard-avoiding-view.js +172 -0
- package/dist/keyboard-avoiding-view.js.map +1 -0
- package/dist/keyboard-dock.d.ts +126 -0
- package/dist/keyboard-dock.js +327 -0
- package/dist/keyboard-dock.js.map +1 -0
- package/dist/keyboard-taps.d.ts +12 -0
- package/dist/keyboard-taps.js +51 -0
- package/dist/keyboard-taps.js.map +1 -0
- package/dist/modal.d.ts +56 -0
- package/dist/modal.js +102 -0
- package/dist/modal.js.map +1 -0
- package/dist/native-gesture.d.ts +21 -0
- package/dist/native-gesture.js +56 -0
- package/dist/native-gesture.js.map +1 -0
- package/dist/native-ref.d.ts +7 -0
- package/dist/native-ref.js +13 -0
- package/dist/native-ref.js.map +1 -0
- package/dist/pressable.d.ts +220 -0
- package/dist/pressable.js +484 -0
- package/dist/pressable.js.map +1 -0
- package/dist/reanimated.d.ts +19 -0
- package/dist/reanimated.js +111 -0
- package/dist/reanimated.js.map +1 -0
- package/dist/refresh-control.d.ts +50 -0
- package/dist/refresh-control.js +103 -0
- package/dist/refresh-control.js.map +1 -0
- package/dist/safe-area-provider.d.ts +11 -0
- package/dist/safe-area-provider.js +70 -0
- package/dist/safe-area-provider.js.map +1 -0
- package/dist/safe-area-view.d.ts +22 -0
- package/dist/safe-area-view.js +77 -0
- package/dist/safe-area-view.js.map +1 -0
- package/dist/safe-area.d.ts +12 -0
- package/dist/safe-area.js +27 -0
- package/dist/safe-area.js.map +1 -0
- package/dist/scroll-view-props.d.ts +89 -0
- package/dist/scroll-view-props.js +153 -0
- package/dist/scroll-view-props.js.map +1 -0
- package/dist/scroll-view.d.ts +95 -0
- package/dist/scroll-view.js +181 -0
- package/dist/scroll-view.js.map +1 -0
- package/dist/section-list.d.ts +146 -0
- package/dist/section-list.js +300 -0
- package/dist/section-list.js.map +1 -0
- package/dist/sticky-headers.d.ts +41 -0
- package/dist/sticky-headers.js +118 -0
- package/dist/sticky-headers.js.map +1 -0
- package/dist/swipe-refresh-layout.d.ts +51 -0
- package/dist/swipe-refresh-layout.js +162 -0
- package/dist/swipe-refresh-layout.js.map +1 -0
- package/dist/switch.d.ts +54 -0
- package/dist/switch.js +110 -0
- package/dist/switch.js.map +1 -0
- package/dist/template-slot.d.ts +18 -0
- package/dist/template-slot.js +30 -0
- package/dist/template-slot.js.map +1 -0
- package/dist/text-input.d.ts +168 -0
- package/dist/text-input.js +312 -0
- package/dist/text-input.js.map +1 -0
- package/dist/text.d.ts +70 -0
- package/dist/text.js +111 -0
- package/dist/text.js.map +1 -0
- package/dist/touchable-opacity.d.ts +36 -0
- package/dist/touchable-opacity.js +76 -0
- package/dist/touchable-opacity.js.map +1 -0
- package/dist/transforms.d.ts +2 -0
- package/dist/transforms.js +17 -0
- package/dist/transforms.js.map +1 -0
- package/dist/view-base.d.ts +332 -0
- package/dist/view-base.js +534 -0
- package/dist/view-base.js.map +1 -0
- package/dist/view.d.ts +12 -0
- package/dist/view.js +18 -0
- package/dist/view.js.map +1 -0
- package/dist/virtual-list.d.ts +530 -0
- package/dist/virtual-list.js +1150 -0
- package/dist/virtual-list.js.map +1 -0
- package/dist/worklet-scroll.d.ts +13 -0
- package/dist/worklet-scroll.js +49 -0
- package/dist/worklet-scroll.js.map +1 -0
- package/dist/worklet-style.d.ts +13 -0
- package/dist/worklet-style.js +47 -0
- package/dist/worklet-style.js.map +1 -0
- package/dist/worklets.d.ts +89 -0
- package/dist/worklets.js +42 -0
- package/dist/worklets.js.map +1 -0
- package/dist/written-props.d.ts +6 -0
- package/dist/written-props.js +180 -0
- package/dist/written-props.js.map +1 -0
- package/package.json +88 -3
package/dist/animated.js
ADDED
|
@@ -0,0 +1,538 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React Native's `Animated`, for a browser: values, interpolation, timing, spring and the
|
|
3
|
+
* composites that sequence them, stepped by `requestAnimationFrame`.
|
|
4
|
+
*
|
|
5
|
+
* A browser build cannot load React Native's own graph. It is Flow source a web bundler will not
|
|
6
|
+
* parse, and it pulls in the rest of React Native behind it. So `animations-web.ts` hands out this
|
|
7
|
+
* instead, under the same names, and an app's `new Animated.Value(0)` and `Animated.timing(...)`
|
|
8
|
+
* run here in a browser and in React Native on a device, from one import.
|
|
9
|
+
*
|
|
10
|
+
* The arithmetic is React Native's, formula for formula - `TimingAnimation`, `SpringAnimation`,
|
|
11
|
+
* `SpringConfig` and `AnimatedInterpolation` in `Libraries/Animated` - so a curve lands in the
|
|
12
|
+
* same place at the same moment on both. What is left out is what a browser has no use for or
|
|
13
|
+
* nothing here needs yet: the native driver (every value here is JavaScript-driven, and
|
|
14
|
+
* `useNativeDriver` is accepted and ignored), decay, loops, `ValueXY`, events and the arithmetic
|
|
15
|
+
* nodes. Anything else a device build calls on `Animated` is simply not here, and fails loudly.
|
|
16
|
+
*
|
|
17
|
+
* Time is the frame's own timestamp rather than `Date.now()`, which is the clock a browser paints
|
|
18
|
+
* on. The one visible difference that makes: an animation's first frame is its start, at the value
|
|
19
|
+
* it starts from, where React Native's first frame is already one frame in.
|
|
20
|
+
*/
|
|
21
|
+
import { interpolate as mix, tween } from '@ng-native/fabric';
|
|
22
|
+
import { Easing } from "./easing.js";
|
|
23
|
+
/** Anything a style can hold where a plain value would go. */
|
|
24
|
+
export class AnimatedNode {
|
|
25
|
+
interpolate(config) {
|
|
26
|
+
return new AnimatedInterpolation(this, config);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
export class AnimatedValue extends AnimatedNode {
|
|
30
|
+
value;
|
|
31
|
+
offset = 0;
|
|
32
|
+
startingValue;
|
|
33
|
+
animation = null;
|
|
34
|
+
listeners = new Map();
|
|
35
|
+
nextListener = 0;
|
|
36
|
+
/** The `[animatedStyle]` handles reading this value, told once per change. */
|
|
37
|
+
__observers = new Set();
|
|
38
|
+
constructor(value = 0) {
|
|
39
|
+
super();
|
|
40
|
+
this.value = this.startingValue = value;
|
|
41
|
+
}
|
|
42
|
+
__getValue() {
|
|
43
|
+
return this.value + this.offset;
|
|
44
|
+
}
|
|
45
|
+
__roots() {
|
|
46
|
+
return [this];
|
|
47
|
+
}
|
|
48
|
+
setValue(value) {
|
|
49
|
+
this.stopAnimation();
|
|
50
|
+
this.update(value);
|
|
51
|
+
}
|
|
52
|
+
setOffset(offset) {
|
|
53
|
+
this.offset = offset;
|
|
54
|
+
}
|
|
55
|
+
flattenOffset() {
|
|
56
|
+
this.value += this.offset;
|
|
57
|
+
this.offset = 0;
|
|
58
|
+
}
|
|
59
|
+
extractOffset() {
|
|
60
|
+
this.offset += this.value;
|
|
61
|
+
this.value = 0;
|
|
62
|
+
}
|
|
63
|
+
addListener(callback) {
|
|
64
|
+
const id = String(this.nextListener++);
|
|
65
|
+
this.listeners.set(id, callback);
|
|
66
|
+
return id;
|
|
67
|
+
}
|
|
68
|
+
removeListener(id) {
|
|
69
|
+
this.listeners.delete(id);
|
|
70
|
+
}
|
|
71
|
+
removeAllListeners() {
|
|
72
|
+
this.listeners.clear();
|
|
73
|
+
}
|
|
74
|
+
stopAnimation(callback) {
|
|
75
|
+
const animation = this.animation;
|
|
76
|
+
this.animation = null;
|
|
77
|
+
animation?.stop();
|
|
78
|
+
callback?.(this.__getValue());
|
|
79
|
+
}
|
|
80
|
+
resetAnimation(callback) {
|
|
81
|
+
this.stopAnimation(callback);
|
|
82
|
+
this.value = this.startingValue;
|
|
83
|
+
}
|
|
84
|
+
/** Run one animation on this value, stopping whatever was running on it. */
|
|
85
|
+
__animate(animation, callback) {
|
|
86
|
+
const previous = this.animation;
|
|
87
|
+
this.animation = null;
|
|
88
|
+
previous?.stop();
|
|
89
|
+
this.animation = animation;
|
|
90
|
+
animation.start(this.value, (value) => this.update(value), (result) => {
|
|
91
|
+
if (this.animation === animation)
|
|
92
|
+
this.animation = null;
|
|
93
|
+
callback?.(result);
|
|
94
|
+
}, previous);
|
|
95
|
+
}
|
|
96
|
+
update(value) {
|
|
97
|
+
this.value = value;
|
|
98
|
+
for (const observer of this.__observers)
|
|
99
|
+
observer();
|
|
100
|
+
for (const listener of this.listeners.values())
|
|
101
|
+
listener({ value: this.__getValue() });
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
export class AnimatedInterpolation extends AnimatedNode {
|
|
105
|
+
parent;
|
|
106
|
+
config;
|
|
107
|
+
constructor(parent, config) {
|
|
108
|
+
super();
|
|
109
|
+
this.parent = parent;
|
|
110
|
+
this.config = config;
|
|
111
|
+
}
|
|
112
|
+
__getValue() {
|
|
113
|
+
return interpolateRange(this.parent.__getValue(), this.config);
|
|
114
|
+
}
|
|
115
|
+
__roots() {
|
|
116
|
+
return this.parent.__roots();
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
/** React Native's segment lookup: the last range whose end is at or past the input. */
|
|
120
|
+
function findRange(input, inputRange) {
|
|
121
|
+
let i;
|
|
122
|
+
for (i = 1; i < inputRange.length - 1; ++i)
|
|
123
|
+
if (inputRange[i] >= input)
|
|
124
|
+
break;
|
|
125
|
+
return i - 1;
|
|
126
|
+
}
|
|
127
|
+
function interpolateRange(input, config) {
|
|
128
|
+
const range = findRange(input, config.inputRange);
|
|
129
|
+
const segment = {
|
|
130
|
+
inMin: config.inputRange[range],
|
|
131
|
+
inMax: config.inputRange[range + 1],
|
|
132
|
+
easing: config.easing ?? Easing.linear,
|
|
133
|
+
left: config.extrapolateLeft ?? config.extrapolate ?? 'extend',
|
|
134
|
+
right: config.extrapolateRight ?? config.extrapolate ?? 'extend',
|
|
135
|
+
};
|
|
136
|
+
const outMin = config.outputRange[range];
|
|
137
|
+
const outMax = config.outputRange[range + 1];
|
|
138
|
+
if (typeof outMin === 'number' && typeof outMax === 'number') {
|
|
139
|
+
return interpolateNumber(input, segment, outMin, outMax);
|
|
140
|
+
}
|
|
141
|
+
// A string range - an angle, a percentage, a colour - is the same curve from 0 to 1, laid over
|
|
142
|
+
// the two strings by the engine's own tween, which is what CSS transitions interpolate with.
|
|
143
|
+
if (extrapolated(input, segment) === null)
|
|
144
|
+
return input;
|
|
145
|
+
const t = interpolateNumber(input, segment, 0, 1);
|
|
146
|
+
return tween(outMin, outMax, t) ?? mix(outMin, outMax, t);
|
|
147
|
+
}
|
|
148
|
+
/** The input, with either end's rule applied past that end. Null where `identity` hands it back. */
|
|
149
|
+
function extrapolated(input, { inMin, inMax, left, right }) {
|
|
150
|
+
if (input < inMin)
|
|
151
|
+
return left === 'identity' ? null : left === 'clamp' ? inMin : input;
|
|
152
|
+
if (input > inMax)
|
|
153
|
+
return right === 'identity' ? null : right === 'clamp' ? inMax : input;
|
|
154
|
+
return input;
|
|
155
|
+
}
|
|
156
|
+
const normalise = (value, min, max) => min === -Infinity ? -value : max === Infinity ? value - min : (value - min) / (max - min);
|
|
157
|
+
const project = (value, min, max) => min === -Infinity ? -value : max === Infinity ? value + min : value * (max - min) + min;
|
|
158
|
+
/** `AnimatedInterpolation`'s `interpolate`, step for step. */
|
|
159
|
+
function interpolateNumber(input, segment, outMin, outMax) {
|
|
160
|
+
const result = extrapolated(input, segment);
|
|
161
|
+
if (result === null)
|
|
162
|
+
return input;
|
|
163
|
+
if (outMin === outMax)
|
|
164
|
+
return outMin;
|
|
165
|
+
if (segment.inMin === segment.inMax)
|
|
166
|
+
return input <= segment.inMin ? outMin : outMax;
|
|
167
|
+
return project(segment.easing(normalise(result, segment.inMin, segment.inMax)), outMin, outMax);
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* One animation on one value: React Native's `Animation`, reduced to what it does here. It asks
|
|
171
|
+
* for frames until it ends, and ends once, whether it finished or was stopped.
|
|
172
|
+
*/
|
|
173
|
+
class Driver {
|
|
174
|
+
update = () => { };
|
|
175
|
+
onEnd = () => { };
|
|
176
|
+
active = true;
|
|
177
|
+
frameId = null;
|
|
178
|
+
start(from, update, onEnd, previous) {
|
|
179
|
+
this.update = update;
|
|
180
|
+
this.onEnd = onEnd;
|
|
181
|
+
this.begin(from, previous);
|
|
182
|
+
}
|
|
183
|
+
stop() {
|
|
184
|
+
this.end(false);
|
|
185
|
+
}
|
|
186
|
+
request(step) {
|
|
187
|
+
if (!this.active)
|
|
188
|
+
return;
|
|
189
|
+
this.frameId = requestAnimationFrame((time) => {
|
|
190
|
+
this.frameId = null;
|
|
191
|
+
step(time);
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
/** Whether a listener stopped this from inside the last update. */
|
|
195
|
+
get stopped() {
|
|
196
|
+
return !this.active;
|
|
197
|
+
}
|
|
198
|
+
end(finished) {
|
|
199
|
+
if (!this.active)
|
|
200
|
+
return;
|
|
201
|
+
this.active = false;
|
|
202
|
+
if (this.frameId !== null)
|
|
203
|
+
cancelAnimationFrame(this.frameId);
|
|
204
|
+
this.frameId = null;
|
|
205
|
+
this.onEnd({ finished });
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
/** React Native's default timing curve. Made once, because a bezier is solved per call anyway. */
|
|
209
|
+
const easeInOut = Easing.inOut(Easing.ease);
|
|
210
|
+
class Timing extends Driver {
|
|
211
|
+
to;
|
|
212
|
+
duration;
|
|
213
|
+
easing;
|
|
214
|
+
delay;
|
|
215
|
+
from = 0;
|
|
216
|
+
startTime = 0;
|
|
217
|
+
constructor(config) {
|
|
218
|
+
super();
|
|
219
|
+
this.to = config.toValue;
|
|
220
|
+
this.duration = config.duration ?? 500;
|
|
221
|
+
this.easing = config.easing ?? easeInOut;
|
|
222
|
+
this.delay = config.delay ?? 0;
|
|
223
|
+
}
|
|
224
|
+
begin(from) {
|
|
225
|
+
this.from = from;
|
|
226
|
+
if (this.duration === 0 && this.delay === 0) {
|
|
227
|
+
this.update(this.to);
|
|
228
|
+
this.end(true);
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
this.request((time) => {
|
|
232
|
+
this.startTime = time + this.delay;
|
|
233
|
+
this.step(time);
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
step(time) {
|
|
237
|
+
const elapsed = time - this.startTime;
|
|
238
|
+
if (elapsed < 0)
|
|
239
|
+
return this.request((t) => this.step(t));
|
|
240
|
+
if (elapsed >= this.duration) {
|
|
241
|
+
this.update(this.duration === 0 ? this.to : this.from + this.easing(1) * (this.to - this.from));
|
|
242
|
+
this.end(true);
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
this.update(this.from + this.easing(elapsed / this.duration) * (this.to - this.from));
|
|
246
|
+
this.request((t) => this.step(t));
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
const stiffnessFromOrigami = (value) => (value - 30) * 3.62 + 194;
|
|
250
|
+
const dampingFromOrigami = (value) => (value - 8) * 3 + 25;
|
|
251
|
+
/** `SpringConfig.fromBouncinessAndSpeed`, as React Native converts Origami's two knobs. */
|
|
252
|
+
function fromBouncinessAndSpeed(bounciness, speed) {
|
|
253
|
+
const normalize = (value, start, end) => (value - start) / (end - start);
|
|
254
|
+
const projectNormal = (n, start, end) => start + n * (end - start);
|
|
255
|
+
const linear = (t, start, end) => t * end + (1 - t) * start;
|
|
256
|
+
const quadraticOut = (t, start, end) => linear(2 * t - t * t, start, end);
|
|
257
|
+
const noBounce = (tension) => {
|
|
258
|
+
if (tension <= 18)
|
|
259
|
+
return 0.0007 * tension ** 3 - 0.031 * tension ** 2 + 0.64 * tension + 1.28;
|
|
260
|
+
if (tension <= 44)
|
|
261
|
+
return 0.000044 * tension ** 3 - 0.006 * tension ** 2 + 0.36 * tension + 2;
|
|
262
|
+
return 0.00000045 * tension ** 3 - 0.000332 * tension ** 2 + 0.1078 * tension + 5.84;
|
|
263
|
+
};
|
|
264
|
+
const b = projectNormal(normalize(bounciness / 1.7, 0, 20), 0, 0.8);
|
|
265
|
+
const s = normalize(speed / 1.7, 0, 20);
|
|
266
|
+
const tension = projectNormal(s, 0.5, 200);
|
|
267
|
+
const friction = quadraticOut(b, noBounce(tension), 0.01);
|
|
268
|
+
return { stiffness: stiffnessFromOrigami(tension), damping: dampingFromOrigami(friction) };
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* The three ways React Native lets a spring be described, reduced to the one it solves. Which one
|
|
272
|
+
* applies is decided the way `SpringAnimation` decides it: stiffness, damping or mass named at all
|
|
273
|
+
* wins, then bounciness or speed, then tension and friction, which are the defaults.
|
|
274
|
+
*/
|
|
275
|
+
function physics(config) {
|
|
276
|
+
const { stiffness, damping, mass, bounciness, speed } = config;
|
|
277
|
+
if (stiffness !== undefined || damping !== undefined || mass !== undefined) {
|
|
278
|
+
return { stiffness: stiffness ?? 100, damping: damping ?? 10, mass: mass ?? 1 };
|
|
279
|
+
}
|
|
280
|
+
if (bounciness !== undefined || speed !== undefined) {
|
|
281
|
+
return { ...fromBouncinessAndSpeed(bounciness ?? 8, speed ?? 12), mass: 1 };
|
|
282
|
+
}
|
|
283
|
+
return fromTensionAndFriction(config);
|
|
284
|
+
}
|
|
285
|
+
const fromTensionAndFriction = ({ tension = 40, friction = 7 }) => ({
|
|
286
|
+
stiffness: stiffnessFromOrigami(tension),
|
|
287
|
+
damping: dampingFromOrigami(friction),
|
|
288
|
+
mass: 1,
|
|
289
|
+
});
|
|
290
|
+
/** A frame that arrives after a stall advances at most this far, so a spring never jumps. */
|
|
291
|
+
const MAX_STEP_MS = 64;
|
|
292
|
+
class Spring extends Driver {
|
|
293
|
+
to;
|
|
294
|
+
overshootClamping;
|
|
295
|
+
restDisplacement;
|
|
296
|
+
restSpeed;
|
|
297
|
+
delay;
|
|
298
|
+
stiffness;
|
|
299
|
+
damping;
|
|
300
|
+
mass;
|
|
301
|
+
initialVelocity;
|
|
302
|
+
startPosition = 0;
|
|
303
|
+
lastPosition = 0;
|
|
304
|
+
lastVelocity;
|
|
305
|
+
lastTime = null;
|
|
306
|
+
frameTime = 0;
|
|
307
|
+
constructor(config) {
|
|
308
|
+
super();
|
|
309
|
+
this.to = config.toValue;
|
|
310
|
+
this.overshootClamping = config.overshootClamping ?? false;
|
|
311
|
+
this.restDisplacement = config.restDisplacementThreshold ?? 0.001;
|
|
312
|
+
this.restSpeed = config.restSpeedThreshold ?? 0.001;
|
|
313
|
+
this.initialVelocity = this.lastVelocity = config.velocity ?? 0;
|
|
314
|
+
this.delay = config.delay ?? 0;
|
|
315
|
+
({ stiffness: this.stiffness, damping: this.damping, mass: this.mass } = physics(config));
|
|
316
|
+
}
|
|
317
|
+
begin(from, previous) {
|
|
318
|
+
this.startPosition = this.lastPosition = from;
|
|
319
|
+
// A spring replacing a spring carries on from where the last one was going, and how fast.
|
|
320
|
+
if (previous instanceof Spring) {
|
|
321
|
+
this.lastPosition = previous.lastPosition;
|
|
322
|
+
this.lastVelocity = this.initialVelocity = previous.lastVelocity;
|
|
323
|
+
this.lastTime = previous.lastTime;
|
|
324
|
+
}
|
|
325
|
+
this.request((time) => {
|
|
326
|
+
const start = time + this.delay;
|
|
327
|
+
const wait = (t) => {
|
|
328
|
+
if (t < start)
|
|
329
|
+
return this.request(wait);
|
|
330
|
+
this.lastTime ??= t;
|
|
331
|
+
this.step(t);
|
|
332
|
+
};
|
|
333
|
+
wait(time);
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
/** `SpringAnimation.onUpdate`: the damped harmonic oscillator's closed form, at `time`. */
|
|
337
|
+
step(time) {
|
|
338
|
+
const last = this.lastTime;
|
|
339
|
+
const now = Math.min(time, last + MAX_STEP_MS);
|
|
340
|
+
this.frameTime += (now - last) / 1000;
|
|
341
|
+
const c = this.damping;
|
|
342
|
+
const m = this.mass;
|
|
343
|
+
const k = this.stiffness;
|
|
344
|
+
const v0 = -this.initialVelocity;
|
|
345
|
+
const zeta = c / (2 * Math.sqrt(k * m));
|
|
346
|
+
const omega0 = Math.sqrt(k / m);
|
|
347
|
+
const omega1 = omega0 * Math.sqrt(1 - zeta * zeta);
|
|
348
|
+
const x0 = this.to - this.startPosition;
|
|
349
|
+
const t = this.frameTime;
|
|
350
|
+
let position;
|
|
351
|
+
let velocity;
|
|
352
|
+
if (zeta < 1) {
|
|
353
|
+
const envelope = Math.exp(-zeta * omega0 * t);
|
|
354
|
+
position =
|
|
355
|
+
this.to -
|
|
356
|
+
envelope *
|
|
357
|
+
(((v0 + zeta * omega0 * x0) / omega1) * Math.sin(omega1 * t) + x0 * Math.cos(omega1 * t));
|
|
358
|
+
velocity =
|
|
359
|
+
zeta *
|
|
360
|
+
omega0 *
|
|
361
|
+
envelope *
|
|
362
|
+
((Math.sin(omega1 * t) * (v0 + zeta * omega0 * x0)) / omega1 +
|
|
363
|
+
x0 * Math.cos(omega1 * t)) -
|
|
364
|
+
envelope *
|
|
365
|
+
(Math.cos(omega1 * t) * (v0 + zeta * omega0 * x0) - omega1 * x0 * Math.sin(omega1 * t));
|
|
366
|
+
}
|
|
367
|
+
else {
|
|
368
|
+
const envelope = Math.exp(-omega0 * t);
|
|
369
|
+
position = this.to - envelope * (x0 + (v0 + omega0 * x0) * t);
|
|
370
|
+
velocity = envelope * (v0 * (t * omega0 - 1) + t * x0 * (omega0 * omega0));
|
|
371
|
+
}
|
|
372
|
+
this.lastTime = now;
|
|
373
|
+
this.lastPosition = position;
|
|
374
|
+
this.lastVelocity = velocity;
|
|
375
|
+
this.update(position);
|
|
376
|
+
if (this.stopped)
|
|
377
|
+
return;
|
|
378
|
+
// With no stiffness there is no spring pulling towards the target, so React Native asks only
|
|
379
|
+
// that the value has stopped, and leaves it where it stopped rather than snapping it there.
|
|
380
|
+
const sprung = this.stiffness !== 0;
|
|
381
|
+
const overshooting = sprung &&
|
|
382
|
+
this.overshootClamping &&
|
|
383
|
+
(this.startPosition < this.to ? position > this.to : position < this.to);
|
|
384
|
+
const resting = Math.abs(velocity) <= this.restSpeed &&
|
|
385
|
+
(!sprung || Math.abs(this.to - position) <= this.restDisplacement);
|
|
386
|
+
if (overshooting || resting) {
|
|
387
|
+
if (sprung) {
|
|
388
|
+
this.lastPosition = this.to;
|
|
389
|
+
this.lastVelocity = 0;
|
|
390
|
+
this.update(this.to);
|
|
391
|
+
}
|
|
392
|
+
this.end(true);
|
|
393
|
+
return;
|
|
394
|
+
}
|
|
395
|
+
this.request((next) => this.step(next));
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
function single(value, make) {
|
|
399
|
+
return {
|
|
400
|
+
start: (callback) => value.__animate(make(), callback),
|
|
401
|
+
stop: () => value.stopAnimation(),
|
|
402
|
+
reset: () => value.resetAnimation(),
|
|
403
|
+
};
|
|
404
|
+
}
|
|
405
|
+
function timing(value, config) {
|
|
406
|
+
return single(value, () => new Timing(config));
|
|
407
|
+
}
|
|
408
|
+
function spring(value, config) {
|
|
409
|
+
return single(value, () => new Spring(config));
|
|
410
|
+
}
|
|
411
|
+
function sequence(animations) {
|
|
412
|
+
let current = 0;
|
|
413
|
+
return {
|
|
414
|
+
start(callback) {
|
|
415
|
+
const onComplete = (result) => {
|
|
416
|
+
if (!result.finished)
|
|
417
|
+
return callback?.(result);
|
|
418
|
+
current++;
|
|
419
|
+
if (current === animations.length) {
|
|
420
|
+
current = 0;
|
|
421
|
+
return callback?.(result);
|
|
422
|
+
}
|
|
423
|
+
animations[current].start(onComplete);
|
|
424
|
+
};
|
|
425
|
+
if (animations.length === 0)
|
|
426
|
+
callback?.({ finished: true });
|
|
427
|
+
else
|
|
428
|
+
animations[current].start(onComplete);
|
|
429
|
+
},
|
|
430
|
+
stop() {
|
|
431
|
+
if (current < animations.length)
|
|
432
|
+
animations[current].stop();
|
|
433
|
+
},
|
|
434
|
+
reset() {
|
|
435
|
+
animations.forEach((animation, i) => i <= current && animation.reset());
|
|
436
|
+
current = 0;
|
|
437
|
+
},
|
|
438
|
+
};
|
|
439
|
+
}
|
|
440
|
+
function parallel(animations, config = {}) {
|
|
441
|
+
const stopTogether = config.stopTogether ?? true;
|
|
442
|
+
const ended = animations.map(() => false);
|
|
443
|
+
let done = 0;
|
|
444
|
+
const result = {
|
|
445
|
+
start(callback) {
|
|
446
|
+
if (done === animations.length) {
|
|
447
|
+
callback?.({ finished: true });
|
|
448
|
+
return;
|
|
449
|
+
}
|
|
450
|
+
animations.forEach((animation, i) => {
|
|
451
|
+
animation.start((end) => {
|
|
452
|
+
ended[i] = true;
|
|
453
|
+
done++;
|
|
454
|
+
if (done === animations.length) {
|
|
455
|
+
done = 0;
|
|
456
|
+
callback?.(end);
|
|
457
|
+
return;
|
|
458
|
+
}
|
|
459
|
+
if (!end.finished && stopTogether)
|
|
460
|
+
result.stop();
|
|
461
|
+
});
|
|
462
|
+
});
|
|
463
|
+
},
|
|
464
|
+
stop() {
|
|
465
|
+
animations.forEach((animation, i) => {
|
|
466
|
+
if (!ended[i])
|
|
467
|
+
animation.stop();
|
|
468
|
+
ended[i] = true;
|
|
469
|
+
});
|
|
470
|
+
},
|
|
471
|
+
reset() {
|
|
472
|
+
animations.forEach((animation, i) => {
|
|
473
|
+
animation.reset();
|
|
474
|
+
ended[i] = false;
|
|
475
|
+
done = 0;
|
|
476
|
+
});
|
|
477
|
+
},
|
|
478
|
+
};
|
|
479
|
+
return result;
|
|
480
|
+
}
|
|
481
|
+
function delay(time) {
|
|
482
|
+
return timing(new AnimatedValue(0), { toValue: 0, delay: time, duration: 0 });
|
|
483
|
+
}
|
|
484
|
+
export const Animated = {
|
|
485
|
+
Value: AnimatedValue,
|
|
486
|
+
Node: AnimatedNode,
|
|
487
|
+
Interpolation: AnimatedInterpolation,
|
|
488
|
+
timing,
|
|
489
|
+
spring,
|
|
490
|
+
sequence,
|
|
491
|
+
parallel,
|
|
492
|
+
delay,
|
|
493
|
+
};
|
|
494
|
+
/** A style's animated values swapped for what they hold now, however deep they sit. */
|
|
495
|
+
function resolve(value) {
|
|
496
|
+
if (value instanceof AnimatedNode)
|
|
497
|
+
return value.__getValue();
|
|
498
|
+
if (Array.isArray(value))
|
|
499
|
+
return value.map(resolve);
|
|
500
|
+
if (isPlainObject(value)) {
|
|
501
|
+
const out = {};
|
|
502
|
+
for (const key in value)
|
|
503
|
+
out[key] = resolve(value[key]);
|
|
504
|
+
return out;
|
|
505
|
+
}
|
|
506
|
+
return value;
|
|
507
|
+
}
|
|
508
|
+
function collect(value, into) {
|
|
509
|
+
if (value instanceof AnimatedNode)
|
|
510
|
+
for (const root of value.__roots())
|
|
511
|
+
into.add(root);
|
|
512
|
+
else if (Array.isArray(value))
|
|
513
|
+
for (const item of value)
|
|
514
|
+
collect(item, into);
|
|
515
|
+
else if (isPlainObject(value))
|
|
516
|
+
for (const key in value)
|
|
517
|
+
collect(value[key], into);
|
|
518
|
+
}
|
|
519
|
+
function isPlainObject(value) {
|
|
520
|
+
return (typeof value === 'object' && value !== null && Object.getPrototypeOf(value) === Object.prototype);
|
|
521
|
+
}
|
|
522
|
+
/**
|
|
523
|
+
* `[animatedStyle]`'s graph, for a browser. Every value here is driven in JavaScript, so each
|
|
524
|
+
* change is a frame the directive writes, and there is never a native view to hand a tag to.
|
|
525
|
+
*/
|
|
526
|
+
export const animationBackend = {
|
|
527
|
+
props(style, onFrame) {
|
|
528
|
+
const roots = new Set();
|
|
529
|
+
collect(style, roots);
|
|
530
|
+
return {
|
|
531
|
+
attach: () => roots.forEach((root) => root.__observers.add(onFrame)),
|
|
532
|
+
detach: () => roots.forEach((root) => root.__observers.delete(onFrame)),
|
|
533
|
+
read: () => resolve(style),
|
|
534
|
+
connect: () => { },
|
|
535
|
+
};
|
|
536
|
+
},
|
|
537
|
+
};
|
|
538
|
+
//# sourceMappingURL=animated.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"animated.js","sourceRoot":"","sources":["../src/animated.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * React Native's `Animated`, for a browser: values, interpolation, timing, spring and the\n * composites that sequence them, stepped by `requestAnimationFrame`.\n *\n * A browser build cannot load React Native's own graph. It is Flow source a web bundler will not\n * parse, and it pulls in the rest of React Native behind it. So `animations-web.ts` hands out this\n * instead, under the same names, and an app's `new Animated.Value(0)` and `Animated.timing(...)`\n * run here in a browser and in React Native on a device, from one import.\n *\n * The arithmetic is React Native's, formula for formula - `TimingAnimation`, `SpringAnimation`,\n * `SpringConfig` and `AnimatedInterpolation` in `Libraries/Animated` - so a curve lands in the\n * same place at the same moment on both. What is left out is what a browser has no use for or\n * nothing here needs yet: the native driver (every value here is JavaScript-driven, and\n * `useNativeDriver` is accepted and ignored), decay, loops, `ValueXY`, events and the arithmetic\n * nodes. Anything else a device build calls on `Animated` is simply not here, and fails loudly.\n *\n * Time is the frame's own timestamp rather than `Date.now()`, which is the clock a browser paints\n * on. The one visible difference that makes: an animation's first frame is its start, at the value\n * it starts from, where React Native's first frame is already one frame in.\n */\nimport { interpolate as mix, tween } from '@ng-native/fabric';\nimport type { AnimatedPropsHandle, AnimationBackend } from './animation.ts';\nimport { Easing, type EasingFunction } from './easing.ts';\n\nexport interface EndResult {\n finished: boolean;\n}\nexport type EndCallback = (result: EndResult) => void;\n\n/** What `Animated.timing` and the rest hand back, as React Native's do. */\nexport interface CompositeAnimation {\n start(callback?: EndCallback): void;\n stop(): void;\n reset(): void;\n}\n\ntype Extrapolate = 'extend' | 'clamp' | 'identity';\n\nexport interface InterpolationConfig {\n inputRange: readonly number[];\n outputRange: readonly (number | string)[];\n easing?: EasingFunction;\n extrapolate?: Extrapolate;\n extrapolateLeft?: Extrapolate;\n extrapolateRight?: Extrapolate;\n}\n\n/** Anything a style can hold where a plain value would go. */\nexport abstract class AnimatedNode {\n abstract __getValue(): unknown;\n /** The values this one is computed from: the things that actually change. */\n abstract __roots(): Iterable<AnimatedValue>;\n\n interpolate(config: InterpolationConfig): AnimatedInterpolation {\n return new AnimatedInterpolation(this, config);\n }\n}\n\nexport class AnimatedValue extends AnimatedNode {\n private value: number;\n private offset = 0;\n private readonly startingValue: number;\n private animation: Driver | null = null;\n private readonly listeners = new Map<string, (state: { value: number }) => void>();\n private nextListener = 0;\n /** The `[animatedStyle]` handles reading this value, told once per change. */\n readonly __observers = new Set<() => void>();\n\n constructor(value = 0) {\n super();\n this.value = this.startingValue = value;\n }\n\n __getValue(): number {\n return this.value + this.offset;\n }\n\n __roots(): Iterable<AnimatedValue> {\n return [this];\n }\n\n setValue(value: number): void {\n this.stopAnimation();\n this.update(value);\n }\n\n setOffset(offset: number): void {\n this.offset = offset;\n }\n\n flattenOffset(): void {\n this.value += this.offset;\n this.offset = 0;\n }\n\n extractOffset(): void {\n this.offset += this.value;\n this.value = 0;\n }\n\n addListener(callback: (state: { value: number }) => void): string {\n const id = String(this.nextListener++);\n this.listeners.set(id, callback);\n return id;\n }\n\n removeListener(id: string): void {\n this.listeners.delete(id);\n }\n\n removeAllListeners(): void {\n this.listeners.clear();\n }\n\n stopAnimation(callback?: (value: number) => void): void {\n const animation = this.animation;\n this.animation = null;\n animation?.stop();\n callback?.(this.__getValue());\n }\n\n resetAnimation(callback?: (value: number) => void): void {\n this.stopAnimation(callback);\n this.value = this.startingValue;\n }\n\n /** Run one animation on this value, stopping whatever was running on it. */\n __animate(animation: Driver, callback?: EndCallback): void {\n const previous = this.animation;\n this.animation = null;\n previous?.stop();\n this.animation = animation;\n animation.start(\n this.value,\n (value) => this.update(value),\n (result) => {\n if (this.animation === animation) this.animation = null;\n callback?.(result);\n },\n previous,\n );\n }\n\n private update(value: number): void {\n this.value = value;\n for (const observer of this.__observers) observer();\n for (const listener of this.listeners.values()) listener({ value: this.__getValue() });\n }\n}\n\nexport class AnimatedInterpolation extends AnimatedNode {\n private readonly parent: AnimatedNode;\n private readonly config: InterpolationConfig;\n\n constructor(parent: AnimatedNode, config: InterpolationConfig) {\n super();\n this.parent = parent;\n this.config = config;\n }\n\n __getValue(): unknown {\n return interpolateRange(this.parent.__getValue() as number, this.config);\n }\n\n __roots(): Iterable<AnimatedValue> {\n return this.parent.__roots();\n }\n}\n\n/** React Native's segment lookup: the last range whose end is at or past the input. */\nfunction findRange(input: number, inputRange: readonly number[]): number {\n let i;\n for (i = 1; i < inputRange.length - 1; ++i) if (inputRange[i]! >= input) break;\n return i - 1;\n}\n\n/** One segment of an interpolation's ranges, and what to do past either end of it. */\ninterface Segment {\n readonly inMin: number;\n readonly inMax: number;\n readonly easing: EasingFunction;\n readonly left: Extrapolate;\n readonly right: Extrapolate;\n}\n\nfunction interpolateRange(input: number, config: InterpolationConfig): unknown {\n const range = findRange(input, config.inputRange);\n const segment: Segment = {\n inMin: config.inputRange[range]!,\n inMax: config.inputRange[range + 1]!,\n easing: config.easing ?? Easing.linear,\n left: config.extrapolateLeft ?? config.extrapolate ?? 'extend',\n right: config.extrapolateRight ?? config.extrapolate ?? 'extend',\n };\n const outMin = config.outputRange[range]!;\n const outMax = config.outputRange[range + 1]!;\n if (typeof outMin === 'number' && typeof outMax === 'number') {\n return interpolateNumber(input, segment, outMin, outMax);\n }\n // A string range - an angle, a percentage, a colour - is the same curve from 0 to 1, laid over\n // the two strings by the engine's own tween, which is what CSS transitions interpolate with.\n if (extrapolated(input, segment) === null) return input;\n const t = interpolateNumber(input, segment, 0, 1);\n return tween(outMin, outMax, t) ?? mix(outMin, outMax, t);\n}\n\n/** The input, with either end's rule applied past that end. Null where `identity` hands it back. */\nfunction extrapolated(input: number, { inMin, inMax, left, right }: Segment): number | null {\n if (input < inMin) return left === 'identity' ? null : left === 'clamp' ? inMin : input;\n if (input > inMax) return right === 'identity' ? null : right === 'clamp' ? inMax : input;\n return input;\n}\n\nconst normalise = (value: number, min: number, max: number): number =>\n min === -Infinity ? -value : max === Infinity ? value - min : (value - min) / (max - min);\n\nconst project = (value: number, min: number, max: number): number =>\n min === -Infinity ? -value : max === Infinity ? value + min : value * (max - min) + min;\n\n/** `AnimatedInterpolation`'s `interpolate`, step for step. */\nfunction interpolateNumber(\n input: number,\n segment: Segment,\n outMin: number,\n outMax: number,\n): number {\n const result = extrapolated(input, segment);\n if (result === null) return input;\n if (outMin === outMax) return outMin;\n if (segment.inMin === segment.inMax) return input <= segment.inMin ? outMin : outMax;\n return project(segment.easing(normalise(result, segment.inMin, segment.inMax)), outMin, outMax);\n}\n\n/**\n * One animation on one value: React Native's `Animation`, reduced to what it does here. It asks\n * for frames until it ends, and ends once, whether it finished or was stopped.\n */\nabstract class Driver {\n protected update: (value: number) => void = () => {};\n private onEnd: EndCallback = () => {};\n private active = true;\n private frameId: number | null = null;\n\n start(\n from: number,\n update: (value: number) => void,\n onEnd: EndCallback,\n previous: Driver | null,\n ): void {\n this.update = update;\n this.onEnd = onEnd;\n this.begin(from, previous);\n }\n\n stop(): void {\n this.end(false);\n }\n\n protected abstract begin(from: number, previous: Driver | null): void;\n\n protected request(step: (time: number) => void): void {\n if (!this.active) return;\n this.frameId = requestAnimationFrame((time) => {\n this.frameId = null;\n step(time);\n });\n }\n\n /** Whether a listener stopped this from inside the last update. */\n protected get stopped(): boolean {\n return !this.active;\n }\n\n protected end(finished: boolean): void {\n if (!this.active) return;\n this.active = false;\n if (this.frameId !== null) cancelAnimationFrame(this.frameId);\n this.frameId = null;\n this.onEnd({ finished });\n }\n}\n\nexport interface TimingConfig {\n toValue: number;\n duration?: number;\n easing?: EasingFunction;\n delay?: number;\n useNativeDriver?: boolean;\n}\n\n/** React Native's default timing curve. Made once, because a bezier is solved per call anyway. */\nconst easeInOut = Easing.inOut(Easing.ease);\n\nclass Timing extends Driver {\n private readonly to: number;\n private readonly duration: number;\n private readonly easing: EasingFunction;\n private readonly delay: number;\n private from = 0;\n private startTime = 0;\n\n constructor(config: TimingConfig) {\n super();\n this.to = config.toValue;\n this.duration = config.duration ?? 500;\n this.easing = config.easing ?? easeInOut;\n this.delay = config.delay ?? 0;\n }\n\n protected begin(from: number): void {\n this.from = from;\n if (this.duration === 0 && this.delay === 0) {\n this.update(this.to);\n this.end(true);\n return;\n }\n this.request((time) => {\n this.startTime = time + this.delay;\n this.step(time);\n });\n }\n\n private step(time: number): void {\n const elapsed = time - this.startTime;\n if (elapsed < 0) return this.request((t) => this.step(t));\n if (elapsed >= this.duration) {\n this.update(\n this.duration === 0 ? this.to : this.from + this.easing(1) * (this.to - this.from),\n );\n this.end(true);\n return;\n }\n this.update(this.from + this.easing(elapsed / this.duration) * (this.to - this.from));\n this.request((t) => this.step(t));\n }\n}\n\nexport interface SpringConfig {\n toValue: number;\n overshootClamping?: boolean;\n restDisplacementThreshold?: number;\n restSpeedThreshold?: number;\n velocity?: number;\n delay?: number;\n bounciness?: number;\n speed?: number;\n tension?: number;\n friction?: number;\n stiffness?: number;\n damping?: number;\n mass?: number;\n useNativeDriver?: boolean;\n}\n\nconst stiffnessFromOrigami = (value: number): number => (value - 30) * 3.62 + 194;\nconst dampingFromOrigami = (value: number): number => (value - 8) * 3 + 25;\n\n/** `SpringConfig.fromBouncinessAndSpeed`, as React Native converts Origami's two knobs. */\nfunction fromBouncinessAndSpeed(\n bounciness: number,\n speed: number,\n): { stiffness: number; damping: number } {\n const normalize = (value: number, start: number, end: number) => (value - start) / (end - start);\n const projectNormal = (n: number, start: number, end: number) => start + n * (end - start);\n const linear = (t: number, start: number, end: number) => t * end + (1 - t) * start;\n const quadraticOut = (t: number, start: number, end: number) => linear(2 * t - t * t, start, end);\n const noBounce = (tension: number): number => {\n if (tension <= 18) return 0.0007 * tension ** 3 - 0.031 * tension ** 2 + 0.64 * tension + 1.28;\n if (tension <= 44) return 0.000044 * tension ** 3 - 0.006 * tension ** 2 + 0.36 * tension + 2;\n return 0.00000045 * tension ** 3 - 0.000332 * tension ** 2 + 0.1078 * tension + 5.84;\n };\n\n const b = projectNormal(normalize(bounciness / 1.7, 0, 20), 0, 0.8);\n const s = normalize(speed / 1.7, 0, 20);\n const tension = projectNormal(s, 0.5, 200);\n const friction = quadraticOut(b, noBounce(tension), 0.01);\n return { stiffness: stiffnessFromOrigami(tension), damping: dampingFromOrigami(friction) };\n}\n\ninterface Physics {\n stiffness: number;\n damping: number;\n mass: number;\n}\n\n/**\n * The three ways React Native lets a spring be described, reduced to the one it solves. Which one\n * applies is decided the way `SpringAnimation` decides it: stiffness, damping or mass named at all\n * wins, then bounciness or speed, then tension and friction, which are the defaults.\n */\nfunction physics(config: SpringConfig): Physics {\n const { stiffness, damping, mass, bounciness, speed } = config;\n if (stiffness !== undefined || damping !== undefined || mass !== undefined) {\n return { stiffness: stiffness ?? 100, damping: damping ?? 10, mass: mass ?? 1 };\n }\n if (bounciness !== undefined || speed !== undefined) {\n return { ...fromBouncinessAndSpeed(bounciness ?? 8, speed ?? 12), mass: 1 };\n }\n return fromTensionAndFriction(config);\n}\n\nconst fromTensionAndFriction = ({ tension = 40, friction = 7 }: SpringConfig): Physics => ({\n stiffness: stiffnessFromOrigami(tension),\n damping: dampingFromOrigami(friction),\n mass: 1,\n});\n\n/** A frame that arrives after a stall advances at most this far, so a spring never jumps. */\nconst MAX_STEP_MS = 64;\n\nclass Spring extends Driver {\n private readonly to: number;\n private readonly overshootClamping: boolean;\n private readonly restDisplacement: number;\n private readonly restSpeed: number;\n private readonly delay: number;\n private readonly stiffness: number;\n private readonly damping: number;\n private readonly mass: number;\n private initialVelocity: number;\n private startPosition = 0;\n lastPosition = 0;\n lastVelocity: number;\n lastTime: number | null = null;\n private frameTime = 0;\n\n constructor(config: SpringConfig) {\n super();\n this.to = config.toValue;\n this.overshootClamping = config.overshootClamping ?? false;\n this.restDisplacement = config.restDisplacementThreshold ?? 0.001;\n this.restSpeed = config.restSpeedThreshold ?? 0.001;\n this.initialVelocity = this.lastVelocity = config.velocity ?? 0;\n this.delay = config.delay ?? 0;\n ({ stiffness: this.stiffness, damping: this.damping, mass: this.mass } = physics(config));\n }\n\n protected begin(from: number, previous: Driver | null): void {\n this.startPosition = this.lastPosition = from;\n // A spring replacing a spring carries on from where the last one was going, and how fast.\n if (previous instanceof Spring) {\n this.lastPosition = previous.lastPosition;\n this.lastVelocity = this.initialVelocity = previous.lastVelocity;\n this.lastTime = previous.lastTime;\n }\n this.request((time) => {\n const start = time + this.delay;\n const wait = (t: number): void => {\n if (t < start) return this.request(wait);\n this.lastTime ??= t;\n this.step(t);\n };\n wait(time);\n });\n }\n\n /** `SpringAnimation.onUpdate`: the damped harmonic oscillator's closed form, at `time`. */\n private step(time: number): void {\n const last = this.lastTime!;\n const now = Math.min(time, last + MAX_STEP_MS);\n this.frameTime += (now - last) / 1000;\n\n const c = this.damping;\n const m = this.mass;\n const k = this.stiffness;\n const v0 = -this.initialVelocity;\n const zeta = c / (2 * Math.sqrt(k * m));\n const omega0 = Math.sqrt(k / m);\n const omega1 = omega0 * Math.sqrt(1 - zeta * zeta);\n const x0 = this.to - this.startPosition;\n const t = this.frameTime;\n\n let position: number;\n let velocity: number;\n if (zeta < 1) {\n const envelope = Math.exp(-zeta * omega0 * t);\n position =\n this.to -\n envelope *\n (((v0 + zeta * omega0 * x0) / omega1) * Math.sin(omega1 * t) + x0 * Math.cos(omega1 * t));\n velocity =\n zeta *\n omega0 *\n envelope *\n ((Math.sin(omega1 * t) * (v0 + zeta * omega0 * x0)) / omega1 +\n x0 * Math.cos(omega1 * t)) -\n envelope *\n (Math.cos(omega1 * t) * (v0 + zeta * omega0 * x0) - omega1 * x0 * Math.sin(omega1 * t));\n } else {\n const envelope = Math.exp(-omega0 * t);\n position = this.to - envelope * (x0 + (v0 + omega0 * x0) * t);\n velocity = envelope * (v0 * (t * omega0 - 1) + t * x0 * (omega0 * omega0));\n }\n\n this.lastTime = now;\n this.lastPosition = position;\n this.lastVelocity = velocity;\n this.update(position);\n if (this.stopped) return;\n\n // With no stiffness there is no spring pulling towards the target, so React Native asks only\n // that the value has stopped, and leaves it where it stopped rather than snapping it there.\n const sprung = this.stiffness !== 0;\n const overshooting =\n sprung &&\n this.overshootClamping &&\n (this.startPosition < this.to ? position > this.to : position < this.to);\n const resting =\n Math.abs(velocity) <= this.restSpeed &&\n (!sprung || Math.abs(this.to - position) <= this.restDisplacement);\n if (overshooting || resting) {\n if (sprung) {\n this.lastPosition = this.to;\n this.lastVelocity = 0;\n this.update(this.to);\n }\n this.end(true);\n return;\n }\n this.request((next) => this.step(next));\n }\n}\n\nfunction single(value: AnimatedValue, make: () => Driver): CompositeAnimation {\n return {\n start: (callback) => value.__animate(make(), callback),\n stop: () => value.stopAnimation(),\n reset: () => value.resetAnimation(),\n };\n}\n\nfunction timing(value: AnimatedValue, config: TimingConfig): CompositeAnimation {\n return single(value, () => new Timing(config));\n}\n\nfunction spring(value: AnimatedValue, config: SpringConfig): CompositeAnimation {\n return single(value, () => new Spring(config));\n}\n\nfunction sequence(animations: readonly CompositeAnimation[]): CompositeAnimation {\n let current = 0;\n return {\n start(callback) {\n const onComplete = (result: EndResult): void => {\n if (!result.finished) return callback?.(result);\n current++;\n if (current === animations.length) {\n current = 0;\n return callback?.(result);\n }\n animations[current]!.start(onComplete);\n };\n if (animations.length === 0) callback?.({ finished: true });\n else animations[current]!.start(onComplete);\n },\n stop() {\n if (current < animations.length) animations[current]!.stop();\n },\n reset() {\n animations.forEach((animation, i) => i <= current && animation.reset());\n current = 0;\n },\n };\n}\n\nfunction parallel(\n animations: readonly CompositeAnimation[],\n config: { stopTogether?: boolean } = {},\n): CompositeAnimation {\n const stopTogether = config.stopTogether ?? true;\n const ended = animations.map(() => false);\n let done = 0;\n const result: CompositeAnimation = {\n start(callback) {\n if (done === animations.length) {\n callback?.({ finished: true });\n return;\n }\n animations.forEach((animation, i) => {\n animation.start((end) => {\n ended[i] = true;\n done++;\n if (done === animations.length) {\n done = 0;\n callback?.(end);\n return;\n }\n if (!end.finished && stopTogether) result.stop();\n });\n });\n },\n stop() {\n animations.forEach((animation, i) => {\n if (!ended[i]) animation.stop();\n ended[i] = true;\n });\n },\n reset() {\n animations.forEach((animation, i) => {\n animation.reset();\n ended[i] = false;\n done = 0;\n });\n },\n };\n return result;\n}\n\nfunction delay(time: number): CompositeAnimation {\n return timing(new AnimatedValue(0), { toValue: 0, delay: time, duration: 0 });\n}\n\nexport const Animated = {\n Value: AnimatedValue,\n Node: AnimatedNode,\n Interpolation: AnimatedInterpolation,\n timing,\n spring,\n sequence,\n parallel,\n delay,\n};\n\n/** A style's animated values swapped for what they hold now, however deep they sit. */\nfunction resolve(value: unknown): unknown {\n if (value instanceof AnimatedNode) return value.__getValue();\n if (Array.isArray(value)) return value.map(resolve);\n if (isPlainObject(value)) {\n const out: Record<string, unknown> = {};\n for (const key in value) out[key] = resolve(value[key]);\n return out;\n }\n return value;\n}\n\nfunction collect(value: unknown, into: Set<AnimatedValue>): void {\n if (value instanceof AnimatedNode) for (const root of value.__roots()) into.add(root);\n else if (Array.isArray(value)) for (const item of value) collect(item, into);\n else if (isPlainObject(value)) for (const key in value) collect(value[key], into);\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return (\n typeof value === 'object' && value !== null && Object.getPrototypeOf(value) === Object.prototype\n );\n}\n\n/**\n * `[animatedStyle]`'s graph, for a browser. Every value here is driven in JavaScript, so each\n * change is a frame the directive writes, and there is never a native view to hand a tag to.\n */\nexport const animationBackend: AnimationBackend = {\n props(style, onFrame): AnimatedPropsHandle {\n const roots = new Set<AnimatedValue>();\n collect(style, roots);\n return {\n attach: () => roots.forEach((root) => root.__observers.add(onFrame)),\n detach: () => roots.forEach((root) => root.__observers.delete(onFrame)),\n read: () => resolve(style) as Record<string, unknown>,\n connect: () => {},\n };\n },\n};\n"]}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Platform capability: React Native's animation graph.
|
|
3
|
+
*
|
|
4
|
+
* React Native's `Animated` is worth reusing rather than reimplementing. Of the 45 files in
|
|
5
|
+
* `Libraries/Animated`, only 11 touch React, and all of them are the `components/*` wrappers,
|
|
6
|
+
* `createAnimatedComponent` and the hooks. The graph itself - values, interpolations, styles,
|
|
7
|
+
* timing, spring, decay, easing - and the native driver bridge are React-free.
|
|
8
|
+
*
|
|
9
|
+
* It is injected rather than imported for the same reason keyboard metrics are: the components
|
|
10
|
+
* package stays runnable under Node, where React Native's Flow-typed source cannot even be
|
|
11
|
+
* parsed, and a test can drive an animation without a device.
|
|
12
|
+
*
|
|
13
|
+
* Apps do not wire this at all: `AnimatedStyle` in `../animations.ts` carries it as its own
|
|
14
|
+
* provider, so importing the directive is the whole setup. The token is what makes that possible
|
|
15
|
+
* without the components package importing React Native, and what lets a test drive an animation
|
|
16
|
+
* with no device.
|
|
17
|
+
*/
|
|
18
|
+
import { InjectionToken } from '@angular/core';
|
|
19
|
+
/** One element's animated props, for as long as that element is alive. */
|
|
20
|
+
export interface AnimatedPropsHandle {
|
|
21
|
+
/** Start observing the values. Until this runs, nothing reports a frame. */
|
|
22
|
+
attach(): void;
|
|
23
|
+
/** Stop observing, and release the native side if it was driving. */
|
|
24
|
+
detach(): void;
|
|
25
|
+
/** The current values, flattened the way a style object is. */
|
|
26
|
+
read(): Record<string, unknown>;
|
|
27
|
+
/**
|
|
28
|
+
* Tell the graph which view the native driver should write to, by react tag. Safe to call
|
|
29
|
+
* before any animation starts: React Native connects then, or later when one goes native.
|
|
30
|
+
*/
|
|
31
|
+
connect(tag: number): void;
|
|
32
|
+
}
|
|
33
|
+
export interface AnimationBackend {
|
|
34
|
+
/**
|
|
35
|
+
* Wrap a style that may contain animated values. `onFrame` fires on every frame the graph
|
|
36
|
+
* advances in JavaScript, and never while the native driver owns the animation.
|
|
37
|
+
*/
|
|
38
|
+
props(style: Record<string, unknown>, onFrame: () => void): AnimatedPropsHandle;
|
|
39
|
+
}
|
|
40
|
+
export declare const ANIMATION: InjectionToken<AnimationBackend>;
|