@twick/visualizer 0.0.1 → 0.14.2
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/.eslintrc.json +20 -20
- package/README.md +12 -12
- package/package.json +34 -31
- package/package.json.bak +34 -0
- package/src/animations/blur.tsx +60 -0
- package/src/animations/breathe.tsx +60 -0
- package/src/animations/fade.tsx +60 -0
- package/src/animations/photo-rise.tsx +66 -0
- package/src/animations/photo-zoom.tsx +73 -0
- package/src/animations/rise.tsx +118 -0
- package/src/animations/succession.tsx +77 -0
- package/src/components/frame-effects.tsx +188 -190
- package/src/components/track.tsx +237 -0
- package/src/controllers/animation.controller.ts +39 -0
- package/src/controllers/element.controller.ts +43 -0
- package/src/controllers/frame-effect.controller.tsx +30 -0
- package/src/controllers/text-effect.controller.ts +33 -0
- package/src/elements/audio.element.tsx +17 -0
- package/src/elements/caption.element.tsx +87 -0
- package/src/elements/circle.element.tsx +20 -0
- package/src/elements/icon.element.tsx +20 -0
- package/src/elements/image.element.tsx +53 -0
- package/src/elements/rect.element.tsx +22 -0
- package/src/elements/scene.element.tsx +29 -0
- package/src/elements/text.element.tsx +28 -0
- package/src/elements/video.element.tsx +55 -0
- package/src/frame-effects/circle.frame.tsx +103 -0
- package/src/frame-effects/rect.frame.tsx +103 -0
- package/src/global.css +11 -11
- package/src/helpers/caption.utils.ts +30 -40
- package/src/helpers/constants.ts +162 -158
- package/src/helpers/element.utils.ts +239 -85
- package/src/helpers/event.utils.ts +6 -0
- package/src/helpers/filters.ts +127 -127
- package/src/helpers/log.utils.ts +29 -32
- package/src/helpers/timing.utils.ts +110 -129
- package/src/helpers/types.ts +242 -146
- package/src/helpers/utils.ts +20 -0
- package/src/index.ts +6 -4
- package/src/live.tsx +16 -16
- package/src/project.ts +6 -6
- package/src/sample.ts +247 -449
- package/src/text-effects/elastic.tsx +39 -0
- package/src/text-effects/erase.tsx +58 -0
- package/src/text-effects/stream-word.tsx +60 -0
- package/src/text-effects/typewriter.tsx +59 -0
- package/src/visualizer.tsx +98 -78
- package/tsconfig.json +11 -10
- package/typedoc.json +14 -14
- package/vite.config.ts +15 -15
- package/src/components/animation.tsx +0 -7
- package/src/components/element.tsx +0 -344
- package/src/components/timeline.tsx +0 -225
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { all, delay, Vector2, waitFor } from "@twick/core";
|
|
2
|
+
import { AnimationParams } from "../helpers/types";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* SuccessionAnimation combines scaling and opacity transitions
|
|
6
|
+
* to create an appearing and disappearing zoom effect.
|
|
7
|
+
*
|
|
8
|
+
* Available animation modes:
|
|
9
|
+
* - "enter": Starts scaled down and transparent, then scales up while fading in.
|
|
10
|
+
* - "exit": Waits, then scales down while fading out.
|
|
11
|
+
* - "both": Scales up and fades in, waits, then scales down and fades out.
|
|
12
|
+
*
|
|
13
|
+
* @param elementRef - Reference to the main element to animate.
|
|
14
|
+
* @param containerRef - Optional reference to a container element.
|
|
15
|
+
* @param interval - Duration of scaling and opacity transitions.
|
|
16
|
+
* @param duration - Total duration of the animation.
|
|
17
|
+
* @param animate - Animation phase ("enter" | "exit" | "both").
|
|
18
|
+
*/
|
|
19
|
+
export const SuccessionAnimation = {
|
|
20
|
+
name: "succession",
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Generator function controlling the succession animation.
|
|
24
|
+
*/
|
|
25
|
+
*run({
|
|
26
|
+
elementRef,
|
|
27
|
+
containerRef,
|
|
28
|
+
interval,
|
|
29
|
+
duration,
|
|
30
|
+
animate,
|
|
31
|
+
}: AnimationParams) {
|
|
32
|
+
// Use containerRef if provided, otherwise fallback to elementRef
|
|
33
|
+
const ref = containerRef ?? elementRef;
|
|
34
|
+
|
|
35
|
+
// Capture the element's original scale
|
|
36
|
+
const scale = ref().scale();
|
|
37
|
+
|
|
38
|
+
let animationInterval = Math.min(interval, duration);
|
|
39
|
+
if (animate === "enter") {
|
|
40
|
+
// Start fully transparent and scaled down to 50%
|
|
41
|
+
ref().opacity(0);
|
|
42
|
+
ref().scale(new Vector2(scale.x / 2, scale.y / 2));
|
|
43
|
+
// Animate scaling up to original size and fading in
|
|
44
|
+
yield* all(
|
|
45
|
+
ref().scale(scale, animationInterval),
|
|
46
|
+
ref().opacity(1, animationInterval / 2)
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
} else if (animate === "exit") {
|
|
50
|
+
// Wait until exit animation should start
|
|
51
|
+
yield* waitFor(duration - animationInterval);
|
|
52
|
+
// Animate scaling down to 50% and fading out (opacity starts after half the interval)
|
|
53
|
+
yield* all(
|
|
54
|
+
ref().scale(new Vector2(scale.x / 2, scale.y / 2), animationInterval),
|
|
55
|
+
delay(animationInterval / 2, ref().opacity(0, animationInterval / 2))
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
} else if (animate === "both") {
|
|
59
|
+
animationInterval = Math.min(interval, duration/2);
|
|
60
|
+
// Start fully transparent and scaled down to 50%
|
|
61
|
+
ref().opacity(0);
|
|
62
|
+
ref().scale(new Vector2(scale.x / 2, scale.y / 2));
|
|
63
|
+
// Animate scaling up and fading in
|
|
64
|
+
yield* all(
|
|
65
|
+
ref().scale(scale, animationInterval),
|
|
66
|
+
ref().opacity(1, animationInterval / 2)
|
|
67
|
+
);
|
|
68
|
+
// Wait for the remaining duration
|
|
69
|
+
yield* waitFor(duration - animationInterval);
|
|
70
|
+
// Animate scaling down and fading out
|
|
71
|
+
yield* all(
|
|
72
|
+
ref().scale(new Vector2(scale.x / 2, scale.y / 2), animationInterval),
|
|
73
|
+
delay(animationInterval / 2, ref().opacity(0, animationInterval / 2))
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
};
|
|
@@ -1,190 +1,188 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Frame effects component that handles the application of various visual effects
|
|
3
|
-
* to frames and elements in the scene.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { all, Reference, waitFor } from "@
|
|
7
|
-
import { getTimingFunction } from "../helpers/timing.utils";
|
|
8
|
-
import { fitElement } from "../helpers/element.utils";
|
|
9
|
-
import { DEFAULT_POSITION, DEFAULT_TIMING_FUNCTION, FRAME_SHAPE } from "../helpers/constants";
|
|
10
|
-
import { FrameEffect } from "../helpers/types";
|
|
11
|
-
import { View2D } from "@
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
*
|
|
17
|
-
* @param {
|
|
18
|
-
* @
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
props.
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
props.
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
props.
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
)
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
props.
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
props.
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
sequence.push(containerRef().
|
|
174
|
-
sequence.push(containerRef().
|
|
175
|
-
sequence.push(containerRef().
|
|
176
|
-
sequence.push(
|
|
177
|
-
sequence.push(
|
|
178
|
-
sequence.push(elementRef().
|
|
179
|
-
sequence.push(
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
yield* all(...sequence);
|
|
190
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Frame effects component that handles the application of various visual effects
|
|
3
|
+
* to frames and elements in the scene.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { all, Reference, waitFor } from "@twick/core";
|
|
7
|
+
import { getTimingFunction } from "../helpers/timing.utils";
|
|
8
|
+
import { fitElement } from "../helpers/element.utils";
|
|
9
|
+
import { DEFAULT_POSITION, DEFAULT_TIMING_FUNCTION, FRAME_SHAPE } from "../helpers/constants";
|
|
10
|
+
import { FrameEffect } from "../helpers/types";
|
|
11
|
+
import { View2D } from "@twick/2d";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Applies frame effects to a view or element
|
|
15
|
+
* @param {Object} params - Parameters for applying frame effects
|
|
16
|
+
* @param {View2D} params.view - The 2D view to apply effects to
|
|
17
|
+
* @param {FrameEffect[]} params.effects - Array of effects to apply
|
|
18
|
+
* @returns {void}
|
|
19
|
+
*/
|
|
20
|
+
export function applyFrameEffects({ view, effects }: { view: View2D; effects: FrameEffect[] }) {
|
|
21
|
+
// ... existing code ...
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function* addFrameEffect({
|
|
25
|
+
containerRef,
|
|
26
|
+
elementRef,
|
|
27
|
+
frameElement,
|
|
28
|
+
}: {
|
|
29
|
+
containerRef: Reference<any>;
|
|
30
|
+
elementRef: Reference<any>;
|
|
31
|
+
frameElement: any;
|
|
32
|
+
}) {
|
|
33
|
+
let frameEffects = [];
|
|
34
|
+
const initProps = {
|
|
35
|
+
frame: {
|
|
36
|
+
size: containerRef().size(),
|
|
37
|
+
pos: containerRef().position(),
|
|
38
|
+
radius: containerRef().radius(),
|
|
39
|
+
scale: containerRef().scale(),
|
|
40
|
+
rotation: containerRef().rotation(),
|
|
41
|
+
},
|
|
42
|
+
element: {
|
|
43
|
+
size: containerRef().size(),
|
|
44
|
+
pos: elementRef().position(),
|
|
45
|
+
scale: elementRef().scale(),
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
for (let i = 0; i < frameElement?.frameEffects?.length; i++) {
|
|
50
|
+
const frameEffect = frameElement.frameEffects[i];
|
|
51
|
+
const restore =
|
|
52
|
+
i === frameElement.frameEffects.length - 1 ||
|
|
53
|
+
frameElement.frameEffects[i + 1].s !== frameEffect.e;
|
|
54
|
+
frameEffects.push(
|
|
55
|
+
getFrameEffect({
|
|
56
|
+
containerRef,
|
|
57
|
+
elementRef,
|
|
58
|
+
frameEffect,
|
|
59
|
+
element: frameElement,
|
|
60
|
+
restore,
|
|
61
|
+
initProps,
|
|
62
|
+
})
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
yield* all(...frameEffects);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function* getFrameEffect({
|
|
69
|
+
containerRef,
|
|
70
|
+
elementRef,
|
|
71
|
+
frameEffect,
|
|
72
|
+
element,
|
|
73
|
+
initProps,
|
|
74
|
+
restore = true,
|
|
75
|
+
}: {
|
|
76
|
+
containerRef: Reference<any>;
|
|
77
|
+
elementRef: Reference<any>;
|
|
78
|
+
frameEffect: FrameEffect;
|
|
79
|
+
element: any;
|
|
80
|
+
initProps: any;
|
|
81
|
+
restore?: boolean;
|
|
82
|
+
}) {
|
|
83
|
+
yield* waitFor(frameEffect.s);
|
|
84
|
+
const props = frameEffect.props;
|
|
85
|
+
const sequence = [];
|
|
86
|
+
|
|
87
|
+
if (restore) {
|
|
88
|
+
sequence.push(
|
|
89
|
+
restoreState({
|
|
90
|
+
containerRef,
|
|
91
|
+
elementRef,
|
|
92
|
+
frameEffect,
|
|
93
|
+
element,
|
|
94
|
+
initProps,
|
|
95
|
+
})
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
sequence.push(
|
|
100
|
+
containerRef().size(
|
|
101
|
+
props.frameSize,
|
|
102
|
+
props.transitionDuration,
|
|
103
|
+
getTimingFunction(props.transitionEasing ?? DEFAULT_TIMING_FUNCTION)
|
|
104
|
+
)
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
sequence.push(
|
|
108
|
+
containerRef().position(
|
|
109
|
+
props.framePosition ?? { x: 0, y: 0 },
|
|
110
|
+
props.transitionDuration,
|
|
111
|
+
getTimingFunction(props.transitionEasing ?? DEFAULT_TIMING_FUNCTION)
|
|
112
|
+
)
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
sequence.push(
|
|
116
|
+
elementRef().position(
|
|
117
|
+
props.elementPosition ?? DEFAULT_POSITION,
|
|
118
|
+
props.transitionDuration,
|
|
119
|
+
getTimingFunction(props.transitionEasing ?? DEFAULT_TIMING_FUNCTION)
|
|
120
|
+
)
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
switch (props.frameShape) {
|
|
124
|
+
case FRAME_SHAPE.CIRCLE:
|
|
125
|
+
sequence.push(
|
|
126
|
+
containerRef().radius(
|
|
127
|
+
props.frameSize[0] / 2,
|
|
128
|
+
props.transitionDuration,
|
|
129
|
+
getTimingFunction(props.transitionEasing ?? DEFAULT_TIMING_FUNCTION)
|
|
130
|
+
)
|
|
131
|
+
);
|
|
132
|
+
break;
|
|
133
|
+
default:
|
|
134
|
+
sequence.push(
|
|
135
|
+
containerRef().radius(
|
|
136
|
+
props.radius ?? 0,
|
|
137
|
+
props.transitionDuration,
|
|
138
|
+
getTimingFunction(props.transitionEasing ?? DEFAULT_TIMING_FUNCTION)
|
|
139
|
+
)
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (props.objectFit) {
|
|
144
|
+
sequence.push(
|
|
145
|
+
fitElement({
|
|
146
|
+
elementRef,
|
|
147
|
+
containerSize: { x: props.frameSize[0], y: props.frameSize[1] },
|
|
148
|
+
elementSize: initProps.element.size,
|
|
149
|
+
objectFit: props.objectFit,
|
|
150
|
+
})
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
yield* all(...sequence);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function* restoreState({
|
|
157
|
+
containerRef,
|
|
158
|
+
elementRef,
|
|
159
|
+
frameEffect,
|
|
160
|
+
element,
|
|
161
|
+
initProps,
|
|
162
|
+
}: {
|
|
163
|
+
containerRef: Reference<any>;
|
|
164
|
+
elementRef: Reference<any>;
|
|
165
|
+
frameEffect: any;
|
|
166
|
+
element: any;
|
|
167
|
+
initProps: any;
|
|
168
|
+
}) {
|
|
169
|
+
yield* waitFor(frameEffect.e - frameEffect.s);
|
|
170
|
+
let sequence = [];
|
|
171
|
+
sequence.push(containerRef().size(initProps.frame.size));
|
|
172
|
+
sequence.push(containerRef().position(initProps.frame.pos));
|
|
173
|
+
sequence.push(containerRef().scale(initProps.frame.scale));
|
|
174
|
+
sequence.push(containerRef().rotation(initProps.frame.rotation));
|
|
175
|
+
sequence.push(containerRef().radius(initProps.frame.radius));
|
|
176
|
+
sequence.push(elementRef().size(initProps.element.size));
|
|
177
|
+
sequence.push(elementRef().position(initProps.element.pos));
|
|
178
|
+
sequence.push(elementRef().scale(initProps.element.scale));
|
|
179
|
+
sequence.push(
|
|
180
|
+
fitElement({
|
|
181
|
+
elementRef,
|
|
182
|
+
containerSize: initProps.frame.size,
|
|
183
|
+
elementSize: initProps.element.size,
|
|
184
|
+
objectFit: element.objectFit ?? "none",
|
|
185
|
+
})
|
|
186
|
+
);
|
|
187
|
+
yield* all(...sequence);
|
|
188
|
+
}
|