@omnimedia/omnitool 1.1.0-81 → 1.1.0-83
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 +59 -6
- package/package.json +1 -1
- package/s/timeline/index.ts +3 -2
- package/s/timeline/parts/animations/make.ts +34 -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 +68 -0
- package/s/timeline/renderers/parts/handy.ts +2 -2
- package/s/timeline/sugar/helpers.ts +32 -18
- package/s/timeline/sugar/o.ts +25 -17
- package/s/timeline/utils/anim.ts +3 -3
- 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 +3 -2
- package/x/timeline/index.js +3 -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 +23 -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 +50 -0
- package/x/timeline/parts/animations/types.js +2 -0
- package/x/timeline/parts/animations/types.js.map +1 -0
- package/x/timeline/renderers/parts/handy.js +2 -2
- package/x/timeline/renderers/parts/handy.js.map +1 -1
- 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 +3 -3
- package/x/timeline/utils/anim.js +1 -1
- 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,29 @@ const timeline = omni.timeline(o => {
|
|
|
170
170
|
})
|
|
171
171
|
```
|
|
172
172
|
|
|
173
|
+
Built-in spatial animations:
|
|
174
|
+
|
|
175
|
+
```ts
|
|
176
|
+
const slideIn = o.animatedSpatial(o.anim.presets.slideIn())
|
|
177
|
+
const slideOut = o.animatedSpatial(o.anim.presets.slideOut({duration: 500}))
|
|
178
|
+
const spinIn = o.animatedSpatial(o.anim.presets.spinIn())
|
|
179
|
+
const spinOut = o.animatedSpatial(o.anim.presets.spinOut())
|
|
180
|
+
const zoomIn = o.animatedSpatial(o.anim.presets.zoomIn())
|
|
181
|
+
const zoomOut = o.animatedSpatial(o.anim.presets.zoomOut())
|
|
182
|
+
const bounceIn = o.animatedSpatial(o.anim.presets.bounceIn())
|
|
183
|
+
const bounceOut = o.animatedSpatial(o.anim.presets.bounceOut())
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
Built-in scalar animations:
|
|
187
|
+
|
|
188
|
+
```ts
|
|
189
|
+
const fadeInPreset = o.anim.presets.fadeIn()
|
|
190
|
+
const fadeIn = o.animate.opacity.make(fadeInPreset.terp, fadeInPreset.track)
|
|
191
|
+
|
|
192
|
+
const fadeOutPreset = o.anim.presets.fadeOut({duration: 500})
|
|
193
|
+
const fadeOut = o.animate.opacity.make(fadeOutPreset.terp, fadeOutPreset.track)
|
|
194
|
+
```
|
|
195
|
+
|
|
173
196
|
Animation application:
|
|
174
197
|
|
|
175
198
|
```ts
|
|
@@ -215,19 +238,49 @@ const timeline = omni.timeline(o => {
|
|
|
215
238
|
})
|
|
216
239
|
```
|
|
217
240
|
|
|
218
|
-
Animation
|
|
241
|
+
Animation metadata:
|
|
219
242
|
|
|
220
243
|
```ts
|
|
221
|
-
import {
|
|
244
|
+
import {animatableProperties, animationPresets} from "@omnimedia/omnitool"
|
|
222
245
|
|
|
223
|
-
Object.entries(
|
|
246
|
+
Object.entries(animatableProperties).forEach(([property, meta]) => {
|
|
224
247
|
console.log(property, meta.type, meta.defaultTerp, meta.channels)
|
|
225
248
|
// transform transform linear [...]
|
|
226
249
|
// opacity scalar linear [...]
|
|
227
250
|
})
|
|
251
|
+
|
|
252
|
+
Object.entries(animationPresets).forEach(([preset, meta]) => {
|
|
253
|
+
console.log(preset, meta.type, meta.label, meta.defaults)
|
|
254
|
+
// slideIn motion Slide in {...}
|
|
255
|
+
// slideOut motion Slide out {...}
|
|
256
|
+
// spinIn motion Spin in {...}
|
|
257
|
+
// spinOut motion Spin out {...}
|
|
258
|
+
// zoomIn motion Zoom in {...}
|
|
259
|
+
// zoomOut motion Zoom out {...}
|
|
260
|
+
// bounceIn motion Bounce in {...}
|
|
261
|
+
// bounceOut motion Bounce out {...}
|
|
262
|
+
// fadeIn scalar Fade in {...}
|
|
263
|
+
// fadeOut scalar Fade out {...}
|
|
264
|
+
})
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
Animatable properties describe what can be keyframed, such as `transform` and `opacity`.
|
|
268
|
+
Animation presets describe built-in recipes, such as `slideIn` and `fadeIn`, that create animation data.
|
|
269
|
+
Use `animationPresets` to list available recipes, and `o.anim.presets` to create animation data from them.
|
|
270
|
+
|
|
271
|
+
Utils:
|
|
272
|
+
|
|
273
|
+
```ts
|
|
274
|
+
import {resolveScalarAnimation, resolveTransformAnimation} from "@omnimedia/omnitool"
|
|
275
|
+
|
|
276
|
+
const transform = resolveTransformAnimation(localTime, spatial.anim)
|
|
277
|
+
const opacity = resolveScalarAnimation(localTime, opacityAnimation)
|
|
228
278
|
```
|
|
229
279
|
|
|
230
|
-
|
|
280
|
+
`resolveTransformAnimation` resolves an animated transform at the given local time.
|
|
281
|
+
`resolveScalarAnimation` resolves an animated scalar value at the given local time.
|
|
282
|
+
`localTime` is time relative to the item being resolved.
|
|
283
|
+
`clamp` is the default and currently only extrapolation mode, holding the first or last keyframe value outside the authored range.
|
|
231
284
|
|
|
232
285
|
Worker URL notes:
|
|
233
286
|
- `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"
|
|
@@ -19,3 +19,4 @@ export * from "./sugar/omni.js"
|
|
|
19
19
|
|
|
20
20
|
export * from "./utils/checksum.js"
|
|
21
21
|
export * from "./utils/datafile.js"
|
|
22
|
+
export * from "./utils/anim.js"
|
|
@@ -0,0 +1,34 @@
|
|
|
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
|
+
transform(options?.terp ?? preset.defaults.terp, [
|
|
15
|
+
[0, transformFrom({
|
|
16
|
+
...preset.transform.from,
|
|
17
|
+
...(options?.from === undefined ? {} : {position: options.from}),
|
|
18
|
+
})],
|
|
19
|
+
[options?.duration ?? preset.defaults.duration, transformFrom({
|
|
20
|
+
...preset.transform.to,
|
|
21
|
+
...(options?.to === undefined ? {} : {position: options.to}),
|
|
22
|
+
})],
|
|
23
|
+
])
|
|
24
|
+
: (options?: ScalarAnimationOptions): Anim<Keyframes> =>
|
|
25
|
+
scalar(options?.terp ?? preset.defaults.terp, [
|
|
26
|
+
[0, options?.from ?? preset.defaults.from],
|
|
27
|
+
[options?.duration ?? preset.defaults.duration, options?.to ?? preset.defaults.to],
|
|
28
|
+
])
|
|
29
|
+
|
|
30
|
+
return [name, action]
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
return Object.fromEntries(entries) as AnimationPresetActions
|
|
34
|
+
}
|
|
@@ -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,68 @@
|
|
|
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<MotionAnimationOptions>
|
|
28
|
+
transform: {
|
|
29
|
+
from: TransformOptions
|
|
30
|
+
to: TransformOptions
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export type ScalarAnimationPresetDefinition = {
|
|
35
|
+
type: "scalar"
|
|
36
|
+
label: string
|
|
37
|
+
defaults: Required<ScalarAnimationOptions>
|
|
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
|
+
from?: Value
|
|
63
|
+
to?: Value
|
|
64
|
+
terp?: Interpolation
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export type MotionAnimationOptions = AnimationPresetOptions<Vec2>
|
|
68
|
+
export type ScalarAnimationOptions = AnimationPresetOptions<number>
|
|
@@ -3,7 +3,7 @@ import {ms, Ms} from '../../../units/ms.js'
|
|
|
3
3
|
import {Id, TimelineFile} from '../../parts/basics.js'
|
|
4
4
|
import { SampleContext } from './samplers/visual/parts/types.js'
|
|
5
5
|
import {I6, Mat6, mul6, transformToMat6} from '../../utils/matrix.js'
|
|
6
|
-
import {resolveScalarAnimation,
|
|
6
|
+
import {resolveScalarAnimation, resolveTransform} from '../../utils/anim.js'
|
|
7
7
|
import {ContainerItem, Item, Kind, PlayableItem, SpatialItem} from '../../parts/item.js'
|
|
8
8
|
|
|
9
9
|
function isPlayableItem(item: Item.Any): item is PlayableItem {
|
|
@@ -101,7 +101,7 @@ function applySpatialIfAny(
|
|
|
101
101
|
if ("spatialId" in item && item.spatialId) {
|
|
102
102
|
const spatial = items.get(item.spatialId) as SpatialItem | undefined
|
|
103
103
|
if (spatial?.enabled) {
|
|
104
|
-
const local = transformToMat6(
|
|
104
|
+
const local = transformToMat6(resolveTransform(spatial, time))
|
|
105
105
|
return mul6(local, parentMatrix)
|
|
106
106
|
}
|
|
107
107
|
}
|
|
@@ -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),
|
|
@@ -62,7 +62,7 @@ export const resolveScalarAnimation =(
|
|
|
62
62
|
anim: ScalarAnimation,
|
|
63
63
|
): number => resolveScalar(time, anim.track, anim.terp)
|
|
64
64
|
|
|
65
|
-
export const
|
|
65
|
+
export const resolveTransform =(
|
|
66
66
|
spatial: Item.Spatial | Item.AnimatedSpatial,
|
|
67
67
|
time: number,
|
|
68
68
|
): Transform =>
|