@omnimedia/omnitool 1.1.0-82 → 1.1.0-84
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/README.md +64 -9
- package/package.json +1 -1
- package/s/timeline/index.ts +2 -2
- package/s/timeline/parts/animations/make.ts +38 -0
- package/s/timeline/parts/animations/presets.ts +138 -0
- package/s/timeline/parts/{animations.ts → animations/properties.ts} +2 -24
- package/s/timeline/parts/animations/registry.ts +13 -0
- package/s/timeline/parts/animations/types.ts +69 -0
- package/s/timeline/sugar/helpers.ts +32 -18
- package/s/timeline/sugar/o.ts +25 -17
- package/s/timeline/utils/anim.ts +2 -2
- package/x/demo/demo.bundle.min.js +100 -100
- package/x/demo/demo.bundle.min.js.map +4 -4
- package/x/index.html +2 -2
- package/x/tests.bundle.min.js +102 -102
- package/x/tests.bundle.min.js.map +4 -4
- package/x/tests.html +1 -1
- package/x/timeline/index.d.ts +2 -2
- package/x/timeline/index.js +2 -2
- package/x/timeline/index.js.map +1 -1
- package/x/timeline/parts/animations/make.d.ts +3 -0
- package/x/timeline/parts/animations/make.js +29 -0
- package/x/timeline/parts/animations/make.js.map +1 -0
- package/x/timeline/parts/animations/presets.d.ts +170 -0
- package/x/timeline/parts/animations/presets.js +135 -0
- package/x/timeline/parts/animations/presets.js.map +1 -0
- package/x/timeline/parts/{animations.d.ts → animations/properties.d.ts} +1 -20
- package/x/timeline/parts/{animations.js → animations/properties.js} +2 -2
- package/x/timeline/parts/animations/properties.js.map +1 -0
- package/x/timeline/parts/animations/registry.d.ts +218 -0
- package/x/timeline/parts/animations/registry.js +11 -0
- package/x/timeline/parts/animations/registry.js.map +1 -0
- package/x/timeline/parts/animations/types.d.ts +51 -0
- package/x/timeline/parts/animations/types.js +2 -0
- package/x/timeline/parts/animations/types.js.map +1 -0
- package/x/timeline/sugar/helpers.d.ts +2 -1
- package/x/timeline/sugar/helpers.js +23 -16
- package/x/timeline/sugar/helpers.js.map +1 -1
- package/x/timeline/sugar/o.d.ts +1 -0
- package/x/timeline/sugar/o.js +18 -16
- package/x/timeline/sugar/o.js.map +1 -1
- package/x/timeline/utils/anim.d.ts +2 -2
- package/x/timeline/utils/anim.js.map +1 -1
- package/x/timeline/parts/animations.js.map +0 -1
package/README.md
CHANGED
|
@@ -150,7 +150,7 @@ Animated spatial transforms:
|
|
|
150
150
|
|
|
151
151
|
```ts
|
|
152
152
|
const timeline = omni.timeline(o => {
|
|
153
|
-
const
|
|
153
|
+
const customMotion = o.animatedSpatial(
|
|
154
154
|
o.anim.transform("linear", [
|
|
155
155
|
[0, o.transform({position: [-400, 0]})],
|
|
156
156
|
[1000, o.transform({position: [0, 0]})],
|
|
@@ -161,7 +161,7 @@ const timeline = omni.timeline(o => {
|
|
|
161
161
|
duration: 2000,
|
|
162
162
|
styles: {fill: "white", fontSize: 36}
|
|
163
163
|
})
|
|
164
|
-
o.set(title.id, {spatialId:
|
|
164
|
+
o.set(title.id, {spatialId: customMotion.id})
|
|
165
165
|
|
|
166
166
|
return o.stack(
|
|
167
167
|
o.video(clip, {duration: 4000}),
|
|
@@ -170,6 +170,33 @@ const timeline = omni.timeline(o => {
|
|
|
170
170
|
})
|
|
171
171
|
```
|
|
172
172
|
|
|
173
|
+
Built-in spatial animations:
|
|
174
|
+
|
|
175
|
+
```ts
|
|
176
|
+
const animOut = {
|
|
177
|
+
duration: 500,
|
|
178
|
+
offset: item.duration - 500,
|
|
179
|
+
}
|
|
180
|
+
const slideIn = o.animatedSpatial(o.anim.presets.slideIn())
|
|
181
|
+
const slideOut = o.animatedSpatial(o.anim.presets.slideOut(animOut))
|
|
182
|
+
const spinIn = o.animatedSpatial(o.anim.presets.spinIn())
|
|
183
|
+
const spinOut = o.animatedSpatial(o.anim.presets.spinOut(animOut))
|
|
184
|
+
const zoomIn = o.animatedSpatial(o.anim.presets.zoomIn())
|
|
185
|
+
const zoomOut = o.animatedSpatial(o.anim.presets.zoomOut(animOut))
|
|
186
|
+
const bounceIn = o.animatedSpatial(o.anim.presets.bounceIn())
|
|
187
|
+
const bounceOut = o.animatedSpatial(o.anim.presets.bounceOut(animOut))
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
Built-in scalar animations:
|
|
191
|
+
|
|
192
|
+
```ts
|
|
193
|
+
const fadeInPreset = o.anim.presets.fadeIn()
|
|
194
|
+
const fadeIn = o.animate.opacity.make(fadeInPreset.terp, fadeInPreset.track)
|
|
195
|
+
|
|
196
|
+
const fadeOutPreset = o.anim.presets.fadeOut({duration: 500})
|
|
197
|
+
const fadeOut = o.animate.opacity.make(fadeOutPreset.terp, fadeOutPreset.track)
|
|
198
|
+
```
|
|
199
|
+
|
|
173
200
|
Animation application:
|
|
174
201
|
|
|
175
202
|
```ts
|
|
@@ -215,29 +242,57 @@ const timeline = omni.timeline(o => {
|
|
|
215
242
|
})
|
|
216
243
|
```
|
|
217
244
|
|
|
218
|
-
Animation
|
|
245
|
+
Animation metadata:
|
|
219
246
|
|
|
220
247
|
```ts
|
|
221
|
-
import {
|
|
248
|
+
import {animatableProperties, animationPresets} from "@omnimedia/omnitool"
|
|
222
249
|
|
|
223
|
-
Object.entries(
|
|
250
|
+
Object.entries(animatableProperties).forEach(([property, meta]) => {
|
|
224
251
|
console.log(property, meta.type, meta.defaultTerp, meta.channels)
|
|
225
252
|
// transform transform linear [...]
|
|
226
253
|
// opacity scalar linear [...]
|
|
227
254
|
})
|
|
255
|
+
|
|
256
|
+
Object.entries(animationPresets).forEach(([preset, meta]) => {
|
|
257
|
+
console.log(preset, meta.type, meta.label, meta.defaults)
|
|
258
|
+
// slideIn motion Slide in {...}
|
|
259
|
+
// slideOut motion Slide out {...}
|
|
260
|
+
// spinIn motion Spin in {...}
|
|
261
|
+
// spinOut motion Spin out {...}
|
|
262
|
+
// zoomIn motion Zoom in {...}
|
|
263
|
+
// zoomOut motion Zoom out {...}
|
|
264
|
+
// bounceIn motion Bounce in {...}
|
|
265
|
+
// bounceOut motion Bounce out {...}
|
|
266
|
+
// fadeIn scalar Fade in {...}
|
|
267
|
+
// fadeOut scalar Fade out {...}
|
|
268
|
+
})
|
|
228
269
|
```
|
|
229
270
|
|
|
230
|
-
|
|
271
|
+
Animatable properties describe what can be keyframed, such as `transform` and `opacity`.
|
|
272
|
+
Animation presets describe built-in recipes, such as `slideIn` and `fadeIn`, that create animation data.
|
|
273
|
+
Use `animationPresets` to list available recipes, and `o.anim.presets` to create animation data from them.
|
|
274
|
+
|
|
275
|
+
Preset options:
|
|
276
|
+
- `duration` sets the animation duration, defaulting to `700`.
|
|
277
|
+
- `offset` shifts generated keyframes in item-local time.
|
|
278
|
+
Useful for out animations: `item.duration - 500` starts `slideOut` 500ms before the item ends.
|
|
279
|
+
- `from` sets the start value, like opacity `0` or position `[-400, 0]`.
|
|
280
|
+
- `to` sets the end value, like opacity `1` or position `[0, 0]`.
|
|
281
|
+
- `terp` sets interpolation, defaulting to the preset's `terp`.
|
|
231
282
|
|
|
232
283
|
Utils:
|
|
233
284
|
|
|
234
285
|
```ts
|
|
235
|
-
import {
|
|
286
|
+
import {resolveScalarAnimation, resolveTransformAnimation} from "@omnimedia/omnitool"
|
|
236
287
|
|
|
237
|
-
const transform =
|
|
288
|
+
const transform = resolveTransformAnimation(localTime, spatial.anim)
|
|
289
|
+
const opacity = resolveScalarAnimation(localTime, opacityAnimation)
|
|
238
290
|
```
|
|
239
291
|
|
|
240
|
-
`
|
|
292
|
+
`resolveTransformAnimation` resolves an animated transform at the given local time.
|
|
293
|
+
`resolveScalarAnimation` resolves an animated scalar value at the given local time.
|
|
294
|
+
`localTime` is time relative to the item being resolved.
|
|
295
|
+
`clamp` is the default and currently only extrapolation mode, holding the first or last keyframe value outside the authored range.
|
|
241
296
|
|
|
242
297
|
Worker URL notes:
|
|
243
298
|
- `Driver.setup()` defaults to `/node_modules/@omnimedia/omnitool/x/driver/driver.worker.bundle.min.js`.
|
package/package.json
CHANGED
package/s/timeline/index.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
|
|
2
|
+
export * from "./types.js"
|
|
2
3
|
export * from "./parts/basics.js"
|
|
3
|
-
export * from "./parts/animations.js"
|
|
4
4
|
export * from "./parts/filters.js"
|
|
5
5
|
export * from "./parts/item.js"
|
|
6
6
|
export * from "./parts/media.js"
|
|
7
7
|
export * from "./parts/resource-pool.js"
|
|
8
8
|
export * from "./parts/resource.js"
|
|
9
9
|
export * from "./parts/filmstrip.js"
|
|
10
|
-
export * from "./
|
|
10
|
+
export * from "./parts/animations/registry.js"
|
|
11
11
|
|
|
12
12
|
export * from "./parts/waveform/waveform.js"
|
|
13
13
|
export * from "./parts/waveform/parts/types.js"
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
|
|
2
|
+
import {animationPresets} from "./presets.js"
|
|
3
|
+
import {AnimationPresetActions, MotionAnimationOptions, ScalarAnimationOptions} from "./types.js"
|
|
4
|
+
import {Anim, Interpolation, Keyframes, TrackTransform, Transform, TransformOptions} from "../../types.js"
|
|
5
|
+
|
|
6
|
+
export function makeAnimationPresets(
|
|
7
|
+
scalar: (terp: Interpolation, track: Keyframes) => Anim<Keyframes>,
|
|
8
|
+
transform: (terp: Interpolation, source: Keyframes<Transform>) => Anim<TrackTransform>,
|
|
9
|
+
transformFrom: (options: TransformOptions) => Transform,
|
|
10
|
+
): AnimationPresetActions {
|
|
11
|
+
const entries = Object.entries(animationPresets).map(([name, preset]) => {
|
|
12
|
+
const action = preset.type === "motion"
|
|
13
|
+
? (options?: MotionAnimationOptions): Anim<TrackTransform> => {
|
|
14
|
+
const offset = options?.offset ?? 0
|
|
15
|
+
return transform(options?.terp ?? preset.defaults.terp, [
|
|
16
|
+
[offset, transformFrom({
|
|
17
|
+
...preset.transform.from,
|
|
18
|
+
...(options?.from === undefined ? {} : {position: options.from}),
|
|
19
|
+
})],
|
|
20
|
+
[offset + (options?.duration ?? preset.defaults.duration), transformFrom({
|
|
21
|
+
...preset.transform.to,
|
|
22
|
+
...(options?.to === undefined ? {} : {position: options.to}),
|
|
23
|
+
})],
|
|
24
|
+
])
|
|
25
|
+
}
|
|
26
|
+
: (options?: ScalarAnimationOptions): Anim<Keyframes> => {
|
|
27
|
+
const offset = options?.offset ?? 0
|
|
28
|
+
return scalar(options?.terp ?? preset.defaults.terp, [
|
|
29
|
+
[offset, options?.from ?? preset.defaults.from],
|
|
30
|
+
[offset + (options?.duration ?? preset.defaults.duration), options?.to ?? preset.defaults.to],
|
|
31
|
+
])
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return [name, action]
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
return Object.fromEntries(entries) as AnimationPresetActions
|
|
38
|
+
}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
|
|
2
|
+
import type {AnimationPresetDefinition} from "./types.js"
|
|
3
|
+
|
|
4
|
+
export const animationPresets = {
|
|
5
|
+
slideIn: {
|
|
6
|
+
type: "motion",
|
|
7
|
+
label: "Slide in",
|
|
8
|
+
defaults: {
|
|
9
|
+
duration: 700,
|
|
10
|
+
from: [-400, 0],
|
|
11
|
+
to: [0, 0],
|
|
12
|
+
terp: "easeOut",
|
|
13
|
+
},
|
|
14
|
+
transform: {
|
|
15
|
+
from: {position: [-400, 0]},
|
|
16
|
+
to: {position: [0, 0]},
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
slideOut: {
|
|
20
|
+
type: "motion",
|
|
21
|
+
label: "Slide out",
|
|
22
|
+
defaults: {
|
|
23
|
+
duration: 700,
|
|
24
|
+
from: [0, 0],
|
|
25
|
+
to: [400, 0],
|
|
26
|
+
terp: "easeIn",
|
|
27
|
+
},
|
|
28
|
+
transform: {
|
|
29
|
+
from: {position: [0, 0]},
|
|
30
|
+
to: {position: [400, 0]},
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
spinIn: {
|
|
34
|
+
type: "motion",
|
|
35
|
+
label: "Spin in",
|
|
36
|
+
defaults: {
|
|
37
|
+
duration: 700,
|
|
38
|
+
from: [0, 0],
|
|
39
|
+
to: [0, 0],
|
|
40
|
+
terp: "easeOut",
|
|
41
|
+
},
|
|
42
|
+
transform: {
|
|
43
|
+
from: {scale: [0, 0], rotation: -Math.PI},
|
|
44
|
+
to: {scale: [1, 1], rotation: 0},
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
spinOut: {
|
|
48
|
+
type: "motion",
|
|
49
|
+
label: "Spin out",
|
|
50
|
+
defaults: {
|
|
51
|
+
duration: 700,
|
|
52
|
+
from: [0, 0],
|
|
53
|
+
to: [0, 0],
|
|
54
|
+
terp: "easeIn",
|
|
55
|
+
},
|
|
56
|
+
transform: {
|
|
57
|
+
from: {scale: [1, 1], rotation: 0},
|
|
58
|
+
to: {scale: [0, 0], rotation: Math.PI},
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
zoomIn: {
|
|
62
|
+
type: "motion",
|
|
63
|
+
label: "Zoom in",
|
|
64
|
+
defaults: {
|
|
65
|
+
duration: 700,
|
|
66
|
+
from: [0, 0],
|
|
67
|
+
to: [0, 0],
|
|
68
|
+
terp: "easeOut",
|
|
69
|
+
},
|
|
70
|
+
transform: {
|
|
71
|
+
from: {scale: [0, 0]},
|
|
72
|
+
to: {scale: [1, 1]},
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
zoomOut: {
|
|
76
|
+
type: "motion",
|
|
77
|
+
label: "Zoom out",
|
|
78
|
+
defaults: {
|
|
79
|
+
duration: 700,
|
|
80
|
+
from: [0, 0],
|
|
81
|
+
to: [0, 0],
|
|
82
|
+
terp: "easeIn",
|
|
83
|
+
},
|
|
84
|
+
transform: {
|
|
85
|
+
from: {scale: [1, 1]},
|
|
86
|
+
to: {scale: [0, 0]},
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
bounceIn: {
|
|
90
|
+
type: "motion",
|
|
91
|
+
label: "Bounce in",
|
|
92
|
+
defaults: {
|
|
93
|
+
duration: 700,
|
|
94
|
+
from: [0, 0],
|
|
95
|
+
to: [0, 0],
|
|
96
|
+
terp: "bounce",
|
|
97
|
+
},
|
|
98
|
+
transform: {
|
|
99
|
+
from: {scale: [0, 0]},
|
|
100
|
+
to: {scale: [1, 1]},
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
bounceOut: {
|
|
104
|
+
type: "motion",
|
|
105
|
+
label: "Bounce out",
|
|
106
|
+
defaults: {
|
|
107
|
+
duration: 700,
|
|
108
|
+
from: [0, 0],
|
|
109
|
+
to: [0, 0],
|
|
110
|
+
terp: "bounce",
|
|
111
|
+
},
|
|
112
|
+
transform: {
|
|
113
|
+
from: {scale: [1, 1]},
|
|
114
|
+
to: {scale: [0, 0]},
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
fadeIn: {
|
|
118
|
+
type: "scalar",
|
|
119
|
+
label: "Fade in",
|
|
120
|
+
defaults: {
|
|
121
|
+
duration: 700,
|
|
122
|
+
from: 0,
|
|
123
|
+
to: 1,
|
|
124
|
+
terp: "easeIn",
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
fadeOut: {
|
|
128
|
+
type: "scalar",
|
|
129
|
+
label: "Fade out",
|
|
130
|
+
defaults: {
|
|
131
|
+
duration: 700,
|
|
132
|
+
from: 1,
|
|
133
|
+
to: 0,
|
|
134
|
+
terp: "easeOut",
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
} as const satisfies Record<string, AnimationPresetDefinition>
|
|
138
|
+
|
|
@@ -1,23 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
import type {
|
|
3
|
-
|
|
4
|
-
export type AnimationType = "scalar" | "transform"
|
|
5
|
-
export type AnimationChannelType = "number"
|
|
6
|
-
export type AnimationUnit = "pixel" | "scale" | "radian" | "ratio"
|
|
7
|
-
|
|
8
|
-
export type AnimationChannel = {
|
|
9
|
-
path?: string
|
|
10
|
-
type: AnimationChannelType
|
|
11
|
-
default: number
|
|
12
|
-
unit?: AnimationUnit
|
|
13
|
-
range?: readonly [min: number, max: number]
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export type AnimationDefinition = {
|
|
17
|
-
type: AnimationType
|
|
18
|
-
defaultTerp: Interpolation
|
|
19
|
-
channels: readonly AnimationChannel[]
|
|
20
|
-
}
|
|
2
|
+
import type {AnimationDefinition} from "./types.js"
|
|
21
3
|
|
|
22
4
|
export const spatialAnimations = {
|
|
23
5
|
transform: {
|
|
@@ -45,12 +27,8 @@ export const visualAnimations = {
|
|
|
45
27
|
|
|
46
28
|
// const audioAnimations = {}
|
|
47
29
|
|
|
48
|
-
export const
|
|
30
|
+
export const animatableProperties = {
|
|
49
31
|
...spatialAnimations,
|
|
50
32
|
...visualAnimations,
|
|
51
33
|
} as const
|
|
52
34
|
|
|
53
|
-
export type SpatialAnimationProperty = keyof typeof spatialAnimations
|
|
54
|
-
export type VisualAnimationProperty = keyof typeof visualAnimations
|
|
55
|
-
export type AnimationProperty = keyof typeof animations
|
|
56
|
-
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
|
|
2
|
+
import {animationPresets} from "./presets.js"
|
|
3
|
+
import {animatableProperties} from "./properties.js"
|
|
4
|
+
|
|
5
|
+
export const animationRegistry = {
|
|
6
|
+
presets: animationPresets,
|
|
7
|
+
properties: animatableProperties,
|
|
8
|
+
} as const
|
|
9
|
+
|
|
10
|
+
export * from "./make.js"
|
|
11
|
+
export * from "./presets.js"
|
|
12
|
+
export * from "./properties.js"
|
|
13
|
+
export * from "./types.js"
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
|
|
2
|
+
import {animationPresets} from "./presets.js"
|
|
3
|
+
import {spatialAnimations, visualAnimations, animatableProperties} from "./properties.js"
|
|
4
|
+
import {Anim, Interpolation, Keyframes, TrackTransform, TransformOptions, Vec2} from "../../types.js"
|
|
5
|
+
|
|
6
|
+
export type AnimationType = "scalar" | "transform"
|
|
7
|
+
export type AnimationChannelType = "number"
|
|
8
|
+
export type AnimationUnit = "pixel" | "scale" | "radian" | "ratio"
|
|
9
|
+
|
|
10
|
+
export type AnimationChannel = {
|
|
11
|
+
path?: string
|
|
12
|
+
type: AnimationChannelType
|
|
13
|
+
default: number
|
|
14
|
+
unit?: AnimationUnit
|
|
15
|
+
range?: readonly [min: number, max: number]
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export type AnimationDefinition = {
|
|
19
|
+
type: AnimationType
|
|
20
|
+
defaultTerp: Interpolation
|
|
21
|
+
channels: readonly AnimationChannel[]
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export type MotionAnimationPresetDefinition = {
|
|
25
|
+
type: "motion"
|
|
26
|
+
label: string
|
|
27
|
+
defaults: Required<Omit<MotionAnimationOptions, "offset">>
|
|
28
|
+
transform: {
|
|
29
|
+
from: TransformOptions
|
|
30
|
+
to: TransformOptions
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export type ScalarAnimationPresetDefinition = {
|
|
35
|
+
type: "scalar"
|
|
36
|
+
label: string
|
|
37
|
+
defaults: Required<Omit<ScalarAnimationOptions, "offset">>
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export type AnimationPresetDefinition =
|
|
41
|
+
| MotionAnimationPresetDefinition
|
|
42
|
+
| ScalarAnimationPresetDefinition
|
|
43
|
+
|
|
44
|
+
export type SpatialAnimationProperty = keyof typeof spatialAnimations
|
|
45
|
+
export type VisualAnimationProperty = keyof typeof visualAnimations
|
|
46
|
+
export type AnimationProperty = keyof typeof animatableProperties
|
|
47
|
+
export type AnimationPreset = keyof typeof animationPresets
|
|
48
|
+
|
|
49
|
+
type AnimationPresetAction<TPreset extends AnimationPresetDefinition> =
|
|
50
|
+
TPreset extends MotionAnimationPresetDefinition
|
|
51
|
+
? (options?: MotionAnimationOptions) => Anim<TrackTransform>
|
|
52
|
+
: TPreset extends ScalarAnimationPresetDefinition
|
|
53
|
+
? (options?: ScalarAnimationOptions) => Anim<Keyframes>
|
|
54
|
+
: never
|
|
55
|
+
|
|
56
|
+
export type AnimationPresetActions = {
|
|
57
|
+
[TName in AnimationPreset]: AnimationPresetAction<(typeof animationPresets)[TName]>
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export type AnimationPresetOptions<Value> = {
|
|
61
|
+
duration?: number
|
|
62
|
+
offset?: number
|
|
63
|
+
from?: Value
|
|
64
|
+
to?: Value
|
|
65
|
+
terp?: Interpolation
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export type MotionAnimationOptions = AnimationPresetOptions<Vec2>
|
|
69
|
+
export type ScalarAnimationOptions = AnimationPresetOptions<number>
|
|
@@ -5,10 +5,34 @@ import {O} from "./o.js"
|
|
|
5
5
|
import {Media} from "../parts/media.js"
|
|
6
6
|
import {TimelineFile} from "../parts/basics.js"
|
|
7
7
|
import {FilterAction} from "../parts/filters.js"
|
|
8
|
-
import {visualAnimations} from "../parts/animations.js"
|
|
9
8
|
import {filters, FilterParams, FilterType} from "../parts/filters.js"
|
|
10
9
|
import {Crop, FilterableItem, Item, VisualAnimatableItem} from "../parts/item.js"
|
|
11
|
-
import {
|
|
10
|
+
import {makeAnimationPresets, visualAnimations} from "../parts/animations/registry.js"
|
|
11
|
+
import {Anim, AnimateAction, Interpolation, Keyframes, TrackTransform, Transform, TransformOptions, Vec2, VisualAnimations} from "../types.js"
|
|
12
|
+
|
|
13
|
+
const transformFrom = (options: TransformOptions): Transform => [
|
|
14
|
+
options.position ?? [0, 0],
|
|
15
|
+
options.scale ?? [1, 1],
|
|
16
|
+
options.rotation ?? 0,
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
const transformAnimation = (terp: Interpolation, source: Keyframes<Transform>): Anim<TrackTransform> => {
|
|
20
|
+
const track: TrackTransform = {
|
|
21
|
+
position: {x: [], y: []},
|
|
22
|
+
scale: {x: [], y: []},
|
|
23
|
+
rotation: [],
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
for (const [time, [position, scale, rotation]] of source) {
|
|
27
|
+
track.position.x.push([time, position[0]])
|
|
28
|
+
track.position.y.push([time, position[1]])
|
|
29
|
+
track.scale.x.push([time, scale[0]])
|
|
30
|
+
track.scale.y.push([time, scale[1]])
|
|
31
|
+
track.rotation.push([time, rotation])
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return {terp, track}
|
|
35
|
+
}
|
|
12
36
|
|
|
13
37
|
export type Build<T extends Item.Any = Item.Any> = (o: O) => T
|
|
14
38
|
type BuildVisualAnimateActions = {
|
|
@@ -99,23 +123,13 @@ export const anim = {
|
|
|
99
123
|
return {terp, track}
|
|
100
124
|
},
|
|
101
125
|
|
|
102
|
-
transform
|
|
103
|
-
const track: TrackTransform = {
|
|
104
|
-
position: {x: [], y: []},
|
|
105
|
-
scale: {x: [], y: []},
|
|
106
|
-
rotation: [],
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
for (const [time, [position, scale, rotation]] of source) {
|
|
110
|
-
track.position.x.push([time, position[0]])
|
|
111
|
-
track.position.y.push([time, position[1]])
|
|
112
|
-
track.scale.x.push([time, scale[0]])
|
|
113
|
-
track.scale.y.push([time, scale[1]])
|
|
114
|
-
track.rotation.push([time, rotation])
|
|
115
|
-
}
|
|
126
|
+
transform: transformAnimation,
|
|
116
127
|
|
|
117
|
-
|
|
118
|
-
|
|
128
|
+
presets: makeAnimationPresets(
|
|
129
|
+
(terp, track) => ({terp, track}),
|
|
130
|
+
transformAnimation,
|
|
131
|
+
transformFrom,
|
|
132
|
+
),
|
|
119
133
|
}
|
|
120
134
|
|
|
121
135
|
interface BuildFilterAction<TFilter extends FilterType> {
|
package/s/timeline/sugar/o.ts
CHANGED
|
@@ -5,7 +5,7 @@ import {Media} from "../parts/media.js"
|
|
|
5
5
|
import {Id, TimelineFile} from "../parts/basics.js"
|
|
6
6
|
import {FilterAction, FilterActions} from "../parts/filters.js"
|
|
7
7
|
import {filters, FilterParams, FilterType} from "../parts/filters.js"
|
|
8
|
-
import {visualAnimations} from "../parts/animations.js"
|
|
8
|
+
import {makeAnimationPresets, visualAnimations} from "../parts/animations/registry.js"
|
|
9
9
|
import {Crop, Effect, FilterableItem, Item, Kind, VisualAnimatableItem} from "../parts/item.js"
|
|
10
10
|
import {Anim, AnimateAction, Interpolation, Keyframes, TrackTransform, Transform, TransformOptions, Vec2, VisualAnimations} from "../types.js"
|
|
11
11
|
|
|
@@ -87,6 +87,24 @@ export class O {
|
|
|
87
87
|
return item
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
+
#transformAnimation = (terp: Interpolation, source: Keyframes<Transform>): Anim<TrackTransform> => {
|
|
91
|
+
const track: TrackTransform = {
|
|
92
|
+
position: {x: [], y: []},
|
|
93
|
+
scale: {x: [], y: []},
|
|
94
|
+
rotation: [],
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
for (const [time, [position, scale, rotation]] of source) {
|
|
98
|
+
track.position.x.push([time, position[0]])
|
|
99
|
+
track.position.y.push([time, position[1]])
|
|
100
|
+
track.scale.x.push([time, scale[0]])
|
|
101
|
+
track.scale.y.push([time, scale[1]])
|
|
102
|
+
track.rotation.push([time, rotation])
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return {terp, track}
|
|
106
|
+
}
|
|
107
|
+
|
|
90
108
|
anim = {
|
|
91
109
|
scalar: (terp: Interpolation, track: Keyframes): Anim<Keyframes> => ({terp, track}),
|
|
92
110
|
|
|
@@ -101,23 +119,13 @@ export class O {
|
|
|
101
119
|
return {terp, track}
|
|
102
120
|
},
|
|
103
121
|
|
|
104
|
-
transform:
|
|
105
|
-
const track: TrackTransform = {
|
|
106
|
-
position: {x: [], y: []},
|
|
107
|
-
scale: {x: [], y: []},
|
|
108
|
-
rotation: [],
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
for (const [time, [position, scale, rotation]] of source) {
|
|
112
|
-
track.position.x.push([time, position[0]])
|
|
113
|
-
track.position.y.push([time, position[1]])
|
|
114
|
-
track.scale.x.push([time, scale[0]])
|
|
115
|
-
track.scale.y.push([time, scale[1]])
|
|
116
|
-
track.rotation.push([time, rotation])
|
|
117
|
-
}
|
|
122
|
+
transform: this.#transformAnimation,
|
|
118
123
|
|
|
119
|
-
|
|
120
|
-
|
|
124
|
+
presets: makeAnimationPresets(
|
|
125
|
+
(terp, track) => ({terp, track}),
|
|
126
|
+
this.#transformAnimation,
|
|
127
|
+
options => this.transform(options),
|
|
128
|
+
),
|
|
121
129
|
}
|
|
122
130
|
|
|
123
131
|
#makeFilter = <TFilter extends FilterType>(type: TFilter) => {
|
package/s/timeline/utils/anim.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
|
|
2
2
|
import {resolveTerp} from "./terps.js"
|
|
3
3
|
import {Item, Kind} from "../parts/item.js"
|
|
4
|
-
import {Anim, Keyframes, ScalarAnimation,
|
|
4
|
+
import {Anim, Keyframes, ScalarAnimation, Transform, TransformAnimation} from "../types.js"
|
|
5
5
|
|
|
6
6
|
const resolveScalar =(
|
|
7
7
|
time: number,
|
|
@@ -44,7 +44,7 @@ const resolveScalar =(
|
|
|
44
44
|
|
|
45
45
|
export const resolveTransformAnimation =(
|
|
46
46
|
time: number,
|
|
47
|
-
anim:
|
|
47
|
+
anim: TransformAnimation,
|
|
48
48
|
): Transform => ([
|
|
49
49
|
[
|
|
50
50
|
resolveScalar(time, anim.track.position.x, anim.terp),
|