@octanejs/spring 0.0.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.
Files changed (48) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +53 -0
  3. package/UPSTREAM.md +103 -0
  4. package/package.json +73 -0
  5. package/src/animated/Animated.ts +24 -0
  6. package/src/animated/AnimatedArray.ts +26 -0
  7. package/src/animated/index.ts +3 -0
  8. package/src/browser.ts +246 -0
  9. package/src/components.tsrx +60 -0
  10. package/src/components.tsrx.d.ts +33 -0
  11. package/src/context.ts +13 -0
  12. package/src/core/AnimationConfig.ts +60 -0
  13. package/src/core/AnimationResult.ts +19 -0
  14. package/src/core/Controller.ts +200 -0
  15. package/src/core/FrameValue.ts +16 -0
  16. package/src/core/Interpolation.ts +46 -0
  17. package/src/core/SpringRef.ts +26 -0
  18. package/src/core/SpringValue.ts +384 -0
  19. package/src/core/index.ts +9 -0
  20. package/src/core/runAsync.ts +17 -0
  21. package/src/core/scheduleProps.ts +34 -0
  22. package/src/core/valueInterpolation.ts +54 -0
  23. package/src/engine.ts +9 -0
  24. package/src/hooks.ts +610 -0
  25. package/src/index.ts +26 -0
  26. package/src/parallax.ts +8 -0
  27. package/src/parallax.tsrx +321 -0
  28. package/src/parallax.tsrx.d.ts +60 -0
  29. package/src/shared/FrameLoop.ts +75 -0
  30. package/src/shared/createInterpolator.ts +85 -0
  31. package/src/shared/globals.ts +7 -0
  32. package/src/shared/index.ts +4 -0
  33. package/src/shared/stringInterpolation.ts +56 -0
  34. package/src/spring-component.ts +36 -0
  35. package/src/types/animated.ts +10 -0
  36. package/src/types/common.ts +29 -0
  37. package/src/types/fluid.ts +9 -0
  38. package/src/types/index.ts +9 -0
  39. package/src/types/interpolate.ts +50 -0
  40. package/src/types/interpolation.ts +18 -0
  41. package/src/types/objects.ts +17 -0
  42. package/src/types/props.ts +275 -0
  43. package/src/types/utils.ts +57 -0
  44. package/src/upstream-compat.ts +164 -0
  45. package/src/web/AnimatedStyle.ts +51 -0
  46. package/src/web/animated.ts +118 -0
  47. package/src/web/applyAnimatedValues.ts +92 -0
  48. package/src/web/index.ts +3 -0
@@ -0,0 +1,9 @@
1
+ // React-free public type surface aligned with @react-spring/types + core types at v10.1.2.
2
+ export * from './interpolation';
3
+ export * from './animated';
4
+ export * from './utils';
5
+ export * from './fluid';
6
+ export * from './common';
7
+ export * from './objects';
8
+ export * from './props';
9
+ export type { Interpolator, Interpolated } from './interpolate';
@@ -0,0 +1,50 @@
1
+ import type { Interpolation } from '../core/Interpolation';
2
+ import type { FrameValue } from '../core/FrameValue';
3
+ import type { Animatable } from './animated';
4
+ import type { FluidValue } from './fluid';
5
+ import type { Arrify, Constrain, OneOrMore } from './utils';
6
+ import type { ExtrapolateType, InterpolatorConfig, InterpolatorFn } from './interpolation';
7
+
8
+ /** Extract the raw value types that are being interpolated */
9
+ export type Interpolated<T extends ReadonlyArray<any>> = {
10
+ [P in keyof T]: T[P] extends infer Element
11
+ ? Element extends FluidValue<infer U>
12
+ ? U
13
+ : Element extends FrameValue<infer U>
14
+ ? U
15
+ : Element
16
+ : never;
17
+ };
18
+
19
+ /**
20
+ * This interpolates one or more fluid/frame values.
21
+ */
22
+ export interface Interpolator {
23
+ <Input extends ReadonlyArray<any>, Output>(
24
+ parents: Input,
25
+ interpolator: (...args: Interpolated<Input>) => Output,
26
+ ): Interpolation<Output>;
27
+
28
+ <Input, Output>(
29
+ parent: FluidValue<Input> | FrameValue<Input> | Input,
30
+ interpolator: InterpolatorFn<Input, Output>,
31
+ ): Interpolation<Output>;
32
+
33
+ <Out>(
34
+ parents: OneOrMore<FluidValue<any> | FrameValue<any>>,
35
+ config: InterpolatorConfig<Out>,
36
+ ): Interpolation<Animatable<Out>>;
37
+
38
+ <Out>(
39
+ parents:
40
+ | OneOrMore<FluidValue<number> | FrameValue<number>>
41
+ | FluidValue<number[]>
42
+ | FrameValue<number[]>,
43
+ range: readonly number[],
44
+ output: readonly Constrain<Out, Animatable>[],
45
+ extrapolate?: ExtrapolateType,
46
+ ): Interpolation<Animatable<Out>>;
47
+ }
48
+
49
+ // Re-export Arrify for InterpolatorFn consumers
50
+ export type { Arrify };
@@ -0,0 +1,18 @@
1
+ // Ported from @react-spring/types v10.1.2 (packages/types/src/interpolation.ts).
2
+ import type { Animatable } from './animated';
3
+ import type { Arrify, Constrain } from './utils';
4
+
5
+ export type ExtrapolateType = 'identity' | 'clamp' | 'extend';
6
+ export type EasingFunction = (value: number) => number;
7
+
8
+ export type InterpolatorFn<Input = any, Output = any> = (...inputs: Arrify<Input>) => Output;
9
+
10
+ export interface InterpolatorConfig<Output = Animatable> {
11
+ range?: readonly number[];
12
+ output: readonly Constrain<Output, Animatable>[];
13
+ easing?: EasingFunction;
14
+ extrapolate?: ExtrapolateType;
15
+ extrapolateLeft?: ExtrapolateType;
16
+ extrapolateRight?: ExtrapolateType;
17
+ map?: (value: number) => number;
18
+ }
@@ -0,0 +1,17 @@
1
+ import type { Any, Lookup } from './utils';
2
+ import type { FluidValue } from './fluid';
3
+ import type { SpringValue } from '../core/SpringValue';
4
+
5
+ /**
6
+ * The set of `SpringValue` objects returned by a `useSpring` call (or similar).
7
+ */
8
+ export type SpringValues<T extends Lookup = any> = [T] extends [Any]
9
+ ? Lookup<SpringValue<unknown> | undefined>
10
+ : { [P in keyof T]: SpringWrap<T[P]> };
11
+
12
+ type SpringWrap<T> = [Exclude<T, FluidValue>, Extract<T, readonly any[]>] extends [
13
+ object | void,
14
+ never,
15
+ ]
16
+ ? never
17
+ : SpringValue<Exclude<T, FluidValue | void>> | Extract<T, void>;
@@ -0,0 +1,275 @@
1
+ import type { SpringConfig } from '../core/SpringValue';
2
+ import type { SpringRef } from '../core/SpringRef';
3
+ import type { SpringValue } from '../core/SpringValue';
4
+ import type { Controller } from '../core/Controller';
5
+ import type { AnimationResult } from '../core/AnimationResult';
6
+ import type { FluidProps, FluidValue } from './fluid';
7
+ import type { IsPlainObject, RawValues, StringKeys } from './common';
8
+ import type {
9
+ Any,
10
+ Constrain,
11
+ Falsy,
12
+ Lookup,
13
+ Merge,
14
+ ObjectFromUnion,
15
+ ObjectType,
16
+ OneOrMore,
17
+ Remap,
18
+ UnknownProps,
19
+ } from './utils';
20
+
21
+ /** The phases of a `useTransition` item */
22
+ export type TransitionKey = 'initial' | 'enter' | 'update' | 'leave';
23
+
24
+ /**
25
+ * Extract a union of animated values from a set of `useTransition` props.
26
+ */
27
+ export type TransitionValues<Props extends object> = unknown &
28
+ ForwardProps<
29
+ ObjectFromUnion<
30
+ Constrain<
31
+ ObjectType<
32
+ Props[TransitionKey & keyof Props] extends infer T
33
+ ? T extends ReadonlyArray<infer Element>
34
+ ? Element
35
+ : T extends (...args: any[]) => infer Return
36
+ ? Return extends ReadonlyArray<infer ReturnElement>
37
+ ? ReturnElement
38
+ : Return
39
+ : T
40
+ : never
41
+ >,
42
+ {}
43
+ >
44
+ >
45
+ >;
46
+
47
+ /**
48
+ * Move all non-reserved props into the `to` prop.
49
+ */
50
+ export type InferTo<T extends object> = Merge<
51
+ { to: ForwardProps<T> },
52
+ Pick<T, keyof T & keyof ReservedProps>
53
+ >;
54
+
55
+ export type SpringUpdate<T = any> = ToProps<T> & SpringProps<T>;
56
+
57
+ export type SpringsUpdate<State extends Lookup = UnknownProps> =
58
+ | OneOrMore<ControllerUpdate<State>>
59
+ | ((index: number, ctrl: Controller<State>) => ControllerUpdate<State> | null);
60
+
61
+ export interface SpringProps<T = any> extends AnimationProps<T> {
62
+ from?: GoalValue<T>;
63
+ loop?: LoopProp<SpringUpdate>;
64
+ onProps?: EventProp<OnProps<T>>;
65
+ onStart?: EventProp<OnStart<SpringValue<T>, SpringValue<T>>>;
66
+ onChange?: EventProp<OnChange<SpringValue<T>, SpringValue<T>>>;
67
+ onPause?: EventProp<OnPause<SpringValue<T>, SpringValue<T>>>;
68
+ onResume?: EventProp<OnResume<SpringValue<T>, SpringValue<T>>>;
69
+ onRest?: EventProp<OnRest<SpringValue<T>, SpringValue<T>>>;
70
+ }
71
+
72
+ export type ToProps<T = any> =
73
+ | { to?: GoalProp<T> | SpringToFn<T> | SpringChain<T> }
74
+ | ([T] extends [IsPlainObject<T>] ? InlineToProps<T> : never);
75
+
76
+ export type GoalProp<T> = [T] extends [IsPlainObject<T>] ? GoalValues<T> | Falsy : GoalValue<T>;
77
+
78
+ export type GoalValues<T> =
79
+ FluidProps<T> extends infer Props ? { [P in keyof Props]?: Props[P] | null } : never;
80
+
81
+ export type GoalValue<T> = T | FluidValue<T> | UnknownProps | null | undefined;
82
+
83
+ export type InlineToProps<T = any> = Remap<GoalValues<T> & { to?: undefined }>;
84
+
85
+ export interface SpringChain<T = any> extends Array<
86
+ [T] extends [IsPlainObject<T>] ? ControllerUpdate<T> : SpringTo<T> | SpringUpdate<T>
87
+ > {}
88
+
89
+ export type SpringTo<T = any> =
90
+ | ([T] extends [IsPlainObject<T>] ? never : T | FluidValue<T>)
91
+ | SpringChain<T>
92
+ | SpringToFn<T>
93
+ | Falsy;
94
+
95
+ export type ControllerUpdate<State extends Lookup = Lookup, Item = undefined> = unknown &
96
+ ToProps<State> &
97
+ ControllerProps<State, Item>;
98
+
99
+ export interface ControllerProps<
100
+ State extends Lookup = Lookup,
101
+ Item = undefined,
102
+ > extends AnimationProps<State> {
103
+ ref?: SpringRef<State>;
104
+ from?: GoalValues<State> | Falsy;
105
+ loop?: LoopProp<ControllerUpdate>;
106
+ onStart?:
107
+ | OnStart<SpringValue<State>, Controller<State>, Item>
108
+ | {
109
+ [P in keyof State]?: OnStart<SpringValue<State[P]>, Controller<State>, Item>;
110
+ };
111
+ onRest?:
112
+ | OnRest<SpringValue<State>, Controller<State>, Item>
113
+ | {
114
+ [P in keyof State]?: OnRest<SpringValue<State[P]>, Controller<State>, Item>;
115
+ };
116
+ onChange?:
117
+ | OnChange<SpringValue<State>, Controller<State>, Item>
118
+ | {
119
+ [P in keyof State]?: OnChange<SpringValue<State[P]>, Controller<State>, Item>;
120
+ };
121
+ onPause?:
122
+ | OnPause<SpringValue<State>, Controller<State>, Item>
123
+ | {
124
+ [P in keyof State]?: OnPause<SpringValue<State[P]>, Controller<State>, Item>;
125
+ };
126
+ onResume?:
127
+ | OnResume<SpringValue<State>, Controller<State>, Item>
128
+ | {
129
+ [P in keyof State]?: OnResume<SpringValue<State[P]>, Controller<State>, Item>;
130
+ };
131
+ onProps?: OnProps<State> | { [P in keyof State]?: OnProps<State[P]> };
132
+ onResolve?: OnResolve<SpringValue<State>, Controller<State>, Item>;
133
+ }
134
+
135
+ export type LoopProp<T extends object> = boolean | T | (() => boolean | T);
136
+
137
+ export type MatchProp<T> = boolean | OneOrMore<StringKeys<T>> | ((key: StringKeys<T>) => boolean);
138
+
139
+ export type EventProp<T> = T | Lookup<T | undefined>;
140
+
141
+ export interface AnimationProps<T = any> {
142
+ config?: SpringConfig | ((key: StringKeys<T>) => SpringConfig);
143
+ delay?: number | ((key: StringKeys<T>) => number);
144
+ immediate?: MatchProp<T>;
145
+ cancel?: MatchProp<T>;
146
+ pause?: MatchProp<T>;
147
+ reset?: MatchProp<T>;
148
+ reverse?: boolean;
149
+ default?: boolean | SpringProps<T>;
150
+ }
151
+
152
+ export type ForwardProps<T extends object> = RawValues<Omit<Constrain<T, {}>, keyof ReservedProps>>;
153
+
154
+ export interface ReservedProps extends ReservedEventProps {
155
+ config?: any;
156
+ from?: any;
157
+ to?: any;
158
+ ref?: any;
159
+ loop?: any;
160
+ pause?: any;
161
+ reset?: any;
162
+ cancel?: any;
163
+ reverse?: any;
164
+ immediate?: any;
165
+ default?: any;
166
+ delay?: any;
167
+ items?: any;
168
+ trail?: any;
169
+ sort?: any;
170
+ expires?: any;
171
+ initial?: any;
172
+ enter?: any;
173
+ update?: any;
174
+ leave?: any;
175
+ children?: any;
176
+ keys?: any;
177
+ callId?: any;
178
+ parentId?: any;
179
+ }
180
+
181
+ export interface ReservedEventProps {
182
+ onProps?: any;
183
+ onStart?: any;
184
+ onChange?: any;
185
+ onPause?: any;
186
+ onResume?: any;
187
+ onRest?: any;
188
+ onResolve?: any;
189
+ onDestroyed?: any;
190
+ }
191
+
192
+ export type PickAnimated<Props extends object, Fwd = true> = unknown &
193
+ ([Props] extends [Any]
194
+ ? Lookup
195
+ : [object] extends [Props]
196
+ ? Lookup
197
+ : ObjectFromUnion<
198
+ Props extends { from: infer From }
199
+ ? | (From extends () => any ? ReturnType<From> : ObjectType<From>)
200
+ | (TransitionKey & keyof Props extends never
201
+ ? ToValues<Omit<Props, 'from'>, Fwd>
202
+ : TransitionValues<Omit<Props, 'from'>>)
203
+ : TransitionKey & keyof Props extends never
204
+ ? ToValues<Props, Fwd>
205
+ : TransitionValues<Props>
206
+ >);
207
+
208
+ export type ToValues<Props extends object, AndForward = true> = unknown &
209
+ (AndForward extends true ? ForwardProps<Props> : unknown) &
210
+ (Props extends { to?: any }
211
+ ? Exclude<Props['to'], Function | ReadonlyArray<any>> extends infer To
212
+ ? ForwardProps<[To] extends [object] ? To : Partial<Extract<To, object>>>
213
+ : never
214
+ : unknown);
215
+
216
+ export interface SpringToFn<T = any> {
217
+ (start: any, stop: any): Promise<any> | void;
218
+ }
219
+
220
+ type EventHandler<TResult = any, TSource = unknown, Item = undefined> = (
221
+ result: AnimationResult<TResult extends { get(): infer U } ? U : any>,
222
+ ctrl: TSource,
223
+ item?: Item,
224
+ ) => void;
225
+
226
+ export type OnStart<TResult = any, TSource = unknown, Item = undefined> = EventHandler<
227
+ TResult,
228
+ TSource,
229
+ Item
230
+ >;
231
+ export type OnChange<TResult = any, TSource = unknown, Item = undefined> = EventHandler<
232
+ TResult,
233
+ TSource,
234
+ Item
235
+ >;
236
+ export type OnPause<TResult = any, TSource = unknown, Item = undefined> = EventHandler<
237
+ TResult,
238
+ TSource,
239
+ Item
240
+ >;
241
+ export type OnResume<TResult = any, TSource = unknown, Item = undefined> = EventHandler<
242
+ TResult,
243
+ TSource,
244
+ Item
245
+ >;
246
+ export type OnRest<TResult = any, TSource = unknown, Item = undefined> = EventHandler<
247
+ TResult,
248
+ TSource,
249
+ Item
250
+ >;
251
+ export type OnResolve<TResult = any, TSource = unknown, Item = undefined> = EventHandler<
252
+ TResult,
253
+ TSource,
254
+ Item
255
+ >;
256
+
257
+ export type OnProps<T = unknown> = (
258
+ props: Readonly<SpringProps<T>>,
259
+ spring: SpringValue<T>,
260
+ ) => void;
261
+
262
+ /**
263
+ * Update the props of a `Controller` object or `useSpring` call.
264
+ */
265
+ export type SpringUpdateFn<T = any> =
266
+ T extends IsPlainObject<T>
267
+ ? {
268
+ (to: SpringTo<T>, props?: ControllerProps<T>): Promise<AnimationResult<T>>;
269
+ (props: InlineToProps<T> & ControllerProps<T>): Promise<AnimationResult<T>>;
270
+ (props: { to?: GoalValues<T> | Falsy } & ControllerProps<T>): Promise<AnimationResult<T>>;
271
+ }
272
+ : {
273
+ (to: SpringTo<T>, props?: SpringProps<T>): Promise<AnimationResult<T>>;
274
+ (props: { to?: GoalValue<T> } & SpringProps<T>): Promise<AnimationResult<T>>;
275
+ };
@@ -0,0 +1,57 @@
1
+ // React-free subset of @react-spring/types v10.1.2 utils (no React element types).
2
+
3
+ /** Override the property types of `A` with `B` and merge any new properties */
4
+ export type Merge<A, B> = Remap<
5
+ { [P in keyof A]: P extends keyof B ? B[P] : A[P] } & Omit<B, keyof A>
6
+ >;
7
+
8
+ /** Better type errors for overloads with generic types */
9
+ export type Constrain<T, U> = [T] extends [Any] ? U : [T] extends [U] ? T : U;
10
+
11
+ /** Try to simplify `&` out of an object type */
12
+ export type Remap<T> = {} & {
13
+ [P in keyof T]: T[P];
14
+ };
15
+
16
+ export type OneOrMore<T> = T | readonly T[];
17
+
18
+ export type Falsy = false | null | undefined;
19
+
20
+ export type NoInfer<T> = [T][T extends any ? 0 : never];
21
+
22
+ export interface Lookup<T = any> {
23
+ [key: string]: T;
24
+ }
25
+
26
+ export type LoosePick<T, K> = {} & Pick<T, K & keyof T>;
27
+
28
+ /** Intersected with other object types to allow for unknown properties */
29
+ export interface UnknownProps extends Lookup<unknown> {}
30
+
31
+ /** Use `[T] extends [Any]` to know if a type parameter is `any` */
32
+ export class Any {
33
+ // @ts-expect-error – dont worry about this.
34
+ private _: never;
35
+ }
36
+
37
+ /** Ensure the given type is an object type */
38
+ export type ObjectType<T> = T extends object ? T : {};
39
+
40
+ /** Intersect a union of objects but merge property types with _unions_ */
41
+ export type ObjectFromUnion<T extends object> = Remap<{
42
+ [P in keyof Intersect<T>]: T extends infer U ? (P extends keyof U ? U[P] : never) : never;
43
+ }>;
44
+
45
+ /** Convert a union to an intersection */
46
+ type Intersect<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void
47
+ ? I
48
+ : never;
49
+
50
+ /** Ensure each type of `T` is an array */
51
+ export type Arrify<T> = [T, T] extends [infer T, infer DT]
52
+ ? DT extends ReadonlyArray<any>
53
+ ? Array<DT[number]> extends DT
54
+ ? ReadonlyArray<T extends ReadonlyArray<infer U> ? U : T>
55
+ : DT
56
+ : ReadonlyArray<T extends ReadonlyArray<infer U> ? U : T>
57
+ : never;
@@ -0,0 +1,164 @@
1
+ // Behavioral ports of public helpers exported by @react-spring/web@10.1.2.
2
+ import { raf } from '@react-spring/rafz';
3
+ export { Globals } from './shared/globals';
4
+
5
+ export class Any {}
6
+
7
+ export class BailSignal extends Error {
8
+ result: unknown;
9
+
10
+ constructor() {
11
+ super(
12
+ 'An async animation has been interrupted. You see this error because you forgot to use `await` or `.catch(...)` on its returned promise.',
13
+ );
14
+ }
15
+ }
16
+
17
+ export const update = raf.advance;
18
+
19
+ export interface InterpolatorConfig<T = number> {
20
+ range?: readonly number[];
21
+ output: readonly T[];
22
+ extrapolate?: 'identity' | 'clamp' | 'extend';
23
+ extrapolateLeft?: 'identity' | 'clamp' | 'extend';
24
+ extrapolateRight?: 'identity' | 'clamp' | 'extend';
25
+ easing?: (value: number) => number;
26
+ map?: (value: number) => number;
27
+ }
28
+
29
+ // Public `createInterpolator` is re-exported from `./shared/createInterpolator`
30
+ // via the package root so string/color ranges blend instead of snapping.
31
+
32
+ const bounceOut = (x: number) => {
33
+ const n = 7.5625;
34
+ const d = 2.75;
35
+ if (x < 1 / d) return n * x * x;
36
+ if (x < 2 / d) return n * (x -= 1.5 / d) * x + 0.75;
37
+ if (x < 2.5 / d) return n * (x -= 2.25 / d) * x + 0.9375;
38
+ return n * (x -= 2.625 / d) * x + 0.984375;
39
+ };
40
+
41
+ export const easings = {
42
+ linear: (x: number) => x,
43
+ easeInQuad: (x: number) => x * x,
44
+ easeOutQuad: (x: number) => 1 - (1 - x) * (1 - x),
45
+ easeInOutQuad: (x: number) => (x < 0.5 ? 2 * x * x : 1 - Math.pow(-2 * x + 2, 2) / 2),
46
+ easeInCubic: (x: number) => x * x * x,
47
+ easeOutCubic: (x: number) => 1 - Math.pow(1 - x, 3),
48
+ easeInOutCubic: (x: number) => (x < 0.5 ? 4 * x * x * x : 1 - Math.pow(-2 * x + 2, 3) / 2),
49
+ easeInQuart: (x: number) => x ** 4,
50
+ easeOutQuart: (x: number) => 1 - (1 - x) ** 4,
51
+ easeInOutQuart: (x: number) => (x < 0.5 ? 8 * x ** 4 : 1 - (-2 * x + 2) ** 4 / 2),
52
+ easeInQuint: (x: number) => x ** 5,
53
+ easeOutQuint: (x: number) => 1 - (1 - x) ** 5,
54
+ easeInOutQuint: (x: number) => (x < 0.5 ? 16 * x ** 5 : 1 - (-2 * x + 2) ** 5 / 2),
55
+ easeInSine: (x: number) => 1 - Math.cos((x * Math.PI) / 2),
56
+ easeOutSine: (x: number) => Math.sin((x * Math.PI) / 2),
57
+ easeInOutSine: (x: number) => -(Math.cos(Math.PI * x) - 1) / 2,
58
+ easeInExpo: (x: number) => (x === 0 ? 0 : 2 ** (10 * x - 10)),
59
+ easeOutExpo: (x: number) => (x === 1 ? 1 : 1 - 2 ** (-10 * x)),
60
+ easeInOutExpo: (x: number) =>
61
+ x === 0 ? 0 : x === 1 ? 1 : x < 0.5 ? 2 ** (20 * x - 10) / 2 : (2 - 2 ** (-20 * x + 10)) / 2,
62
+ easeInCirc: (x: number) => 1 - Math.sqrt(1 - x ** 2),
63
+ easeOutCirc: (x: number) => Math.sqrt(1 - (x - 1) ** 2),
64
+ easeInOutCirc: (x: number) =>
65
+ x < 0.5 ? (1 - Math.sqrt(1 - (2 * x) ** 2)) / 2 : (Math.sqrt(1 - (-2 * x + 2) ** 2) + 1) / 2,
66
+ easeInBack: (x: number) => 2.70158 * x ** 3 - 1.70158 * x ** 2,
67
+ easeOutBack: (x: number) => 1 + 2.70158 * (x - 1) ** 3 + 1.70158 * (x - 1) ** 2,
68
+ easeInOutBack: (x: number) => {
69
+ const c = 1.70158 * 1.525;
70
+ return x < 0.5
71
+ ? ((2 * x) ** 2 * ((c + 1) * 2 * x - c)) / 2
72
+ : ((2 * x - 2) ** 2 * ((c + 1) * (2 * x - 2) + c) + 2) / 2;
73
+ },
74
+ easeInElastic: (x: number) =>
75
+ x === 0
76
+ ? 0
77
+ : x === 1
78
+ ? 1
79
+ : -(2 ** (10 * x - 10)) * Math.sin((10 * x - 10.75) * ((2 * Math.PI) / 3)),
80
+ easeOutElastic: (x: number) =>
81
+ x === 0
82
+ ? 0
83
+ : x === 1
84
+ ? 1
85
+ : 2 ** (-10 * x) * Math.sin((10 * x - 0.75) * ((2 * Math.PI) / 3)) + 1,
86
+ easeInOutElastic: (x: number) => {
87
+ const c = (2 * Math.PI) / 4.5;
88
+ return x === 0
89
+ ? 0
90
+ : x === 1
91
+ ? 1
92
+ : x < 0.5
93
+ ? -(2 ** (20 * x - 10) * Math.sin((20 * x - 11.125) * c)) / 2
94
+ : (2 ** (-20 * x + 10) * Math.sin((20 * x - 11.125) * c)) / 2 + 1;
95
+ },
96
+ easeInBounce: (x: number) => 1 - bounceOut(1 - x),
97
+ easeOutBounce: bounceOut,
98
+ easeInOutBounce: (x: number) =>
99
+ x < 0.5 ? (1 - bounceOut(1 - 2 * x)) / 2 : (1 + bounceOut(2 * x - 1)) / 2,
100
+ steps:
101
+ (count: number, direction: 'start' | 'end' = 'end') =>
102
+ (progress: number) => {
103
+ progress = direction === 'end' ? Math.min(progress, 0.999) : Math.max(progress, 0.001);
104
+ return Math.max(
105
+ 0,
106
+ Math.min(
107
+ 1,
108
+ (direction === 'end' ? Math.floor(progress * count) : Math.ceil(progress * count)) /
109
+ count,
110
+ ),
111
+ );
112
+ },
113
+ } as const;
114
+
115
+ const RESERVED = new Set([
116
+ 'config',
117
+ 'from',
118
+ 'to',
119
+ 'ref',
120
+ 'loop',
121
+ 'reset',
122
+ 'pause',
123
+ 'cancel',
124
+ 'reverse',
125
+ 'immediate',
126
+ 'default',
127
+ 'delay',
128
+ 'onProps',
129
+ 'onStart',
130
+ 'onChange',
131
+ 'onPause',
132
+ 'onResume',
133
+ 'onRest',
134
+ 'onResolve',
135
+ 'items',
136
+ 'trail',
137
+ 'sort',
138
+ 'expires',
139
+ 'initial',
140
+ 'enter',
141
+ 'update',
142
+ 'leave',
143
+ 'children',
144
+ 'onDestroyed',
145
+ 'keys',
146
+ 'callId',
147
+ 'parentId',
148
+ ]);
149
+
150
+ export function hasReservedProps(props: object): boolean {
151
+ for (const key of Object.keys(props)) {
152
+ if (RESERVED.has(key)) return true;
153
+ }
154
+ return false;
155
+ }
156
+
157
+ export function inferTo<T extends object>(props: T): T & { to?: object } {
158
+ const to: Record<string, unknown> = {};
159
+ const rest: Record<string, unknown> = {};
160
+ for (const [key, value] of Object.entries(props)) {
161
+ (RESERVED.has(key) ? rest : to)[key] = value;
162
+ }
163
+ return (Object.keys(to).length === 0 ? { ...props } : { ...rest, to }) as T & { to?: object };
164
+ }
@@ -0,0 +1,51 @@
1
+ import { FrameValue } from '../core/FrameValue';
2
+
3
+ const transforms =
4
+ /^(matrix3d|matrix|translate3d|translate[XYZ]?|scale3d|scale[XYZ]?|rotate3d|rotate[XYZ]?|skew[XY]?)$/;
5
+
6
+ function read(value: any): any {
7
+ if (value instanceof FrameValue) return value.get();
8
+ if (Array.isArray(value)) return value.map(read);
9
+ return value;
10
+ }
11
+
12
+ function unit(value: any, suffix: string): any {
13
+ return typeof value === 'number' && value !== 0 ? `${value}${suffix}` : value;
14
+ }
15
+
16
+ function identity(values: any[], expected: number): boolean {
17
+ return values.every(
18
+ (value) => (typeof value === 'number' ? value : Number.parseFloat(value)) === expected,
19
+ );
20
+ }
21
+
22
+ export function resolveAnimatedStyle(input: Record<string, any>): Record<string, any> {
23
+ const { x, y, z, ...source } = input;
24
+ const style: Record<string, any> = {};
25
+ const output: string[] = [];
26
+ let allIdentity = true;
27
+ if (x !== undefined || y !== undefined || z !== undefined) {
28
+ const values = [read(x ?? 0), read(y ?? 0), read(z ?? 0)];
29
+ output.push(`translate3d(${values.map((value) => unit(value, 'px')).join(',')})`);
30
+ allIdentity = identity(values, 0);
31
+ }
32
+ for (const key in source) {
33
+ const value = source[key];
34
+ if (key === 'transform') {
35
+ const resolved = read(value) || '';
36
+ if (resolved) output.push(resolved);
37
+ allIdentity = allIdentity && resolved === '';
38
+ } else if (transforms.test(key)) {
39
+ const values = (Array.isArray(value) ? value : [value]).map(read);
40
+ const suffix = key.startsWith('translate')
41
+ ? 'px'
42
+ : key.startsWith('rotate') || key.startsWith('skew')
43
+ ? 'deg'
44
+ : '';
45
+ output.push(`${key}(${values.map((item) => unit(item, suffix)).join(',')})`);
46
+ allIdentity = allIdentity && identity(values, key.startsWith('scale') ? 1 : 0);
47
+ } else style[key] = read(value);
48
+ }
49
+ if (output.length) style.transform = allIdentity ? 'none' : ` ${output.join(' ')}`;
50
+ return style;
51
+ }