@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.
Files changed (53) hide show
  1. package/.eslintrc.json +20 -20
  2. package/README.md +12 -12
  3. package/package.json +34 -31
  4. package/package.json.bak +34 -0
  5. package/src/animations/blur.tsx +60 -0
  6. package/src/animations/breathe.tsx +60 -0
  7. package/src/animations/fade.tsx +60 -0
  8. package/src/animations/photo-rise.tsx +66 -0
  9. package/src/animations/photo-zoom.tsx +73 -0
  10. package/src/animations/rise.tsx +118 -0
  11. package/src/animations/succession.tsx +77 -0
  12. package/src/components/frame-effects.tsx +188 -190
  13. package/src/components/track.tsx +237 -0
  14. package/src/controllers/animation.controller.ts +39 -0
  15. package/src/controllers/element.controller.ts +43 -0
  16. package/src/controllers/frame-effect.controller.tsx +30 -0
  17. package/src/controllers/text-effect.controller.ts +33 -0
  18. package/src/elements/audio.element.tsx +17 -0
  19. package/src/elements/caption.element.tsx +87 -0
  20. package/src/elements/circle.element.tsx +20 -0
  21. package/src/elements/icon.element.tsx +20 -0
  22. package/src/elements/image.element.tsx +53 -0
  23. package/src/elements/rect.element.tsx +22 -0
  24. package/src/elements/scene.element.tsx +29 -0
  25. package/src/elements/text.element.tsx +28 -0
  26. package/src/elements/video.element.tsx +55 -0
  27. package/src/frame-effects/circle.frame.tsx +103 -0
  28. package/src/frame-effects/rect.frame.tsx +103 -0
  29. package/src/global.css +11 -11
  30. package/src/helpers/caption.utils.ts +30 -40
  31. package/src/helpers/constants.ts +162 -158
  32. package/src/helpers/element.utils.ts +239 -85
  33. package/src/helpers/event.utils.ts +6 -0
  34. package/src/helpers/filters.ts +127 -127
  35. package/src/helpers/log.utils.ts +29 -32
  36. package/src/helpers/timing.utils.ts +110 -129
  37. package/src/helpers/types.ts +242 -146
  38. package/src/helpers/utils.ts +20 -0
  39. package/src/index.ts +6 -4
  40. package/src/live.tsx +16 -16
  41. package/src/project.ts +6 -6
  42. package/src/sample.ts +247 -449
  43. package/src/text-effects/elastic.tsx +39 -0
  44. package/src/text-effects/erase.tsx +58 -0
  45. package/src/text-effects/stream-word.tsx +60 -0
  46. package/src/text-effects/typewriter.tsx +59 -0
  47. package/src/visualizer.tsx +98 -78
  48. package/tsconfig.json +11 -10
  49. package/typedoc.json +14 -14
  50. package/vite.config.ts +15 -15
  51. package/src/components/animation.tsx +0 -7
  52. package/src/components/element.tsx +0 -344
  53. 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 "@revideo/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 "@revideo/2d";
12
- import { createSignal } from "@revideo/core";
13
- import { logger } from "../helpers/log.utils";
14
-
15
- /**
16
- * Applies frame effects to a view or element
17
- * @param {Object} params - Parameters for applying frame effects
18
- * @param {View2D} params.view - The 2D view to apply effects to
19
- * @param {FrameEffect[]} params.effects - Array of effects to apply
20
- * @returns {void}
21
- */
22
- export function applyFrameEffects({ view, effects }: { view: View2D; effects: FrameEffect[] }) {
23
- // ... existing code ...
24
- }
25
-
26
- export function* addFrameEffect({
27
- containerRef,
28
- elementRef,
29
- frameElement,
30
- }: {
31
- containerRef: Reference<any>;
32
- elementRef: Reference<any>;
33
- frameElement: any;
34
- }) {
35
- let frameEffects = [];
36
- const initProps = {
37
- frame: {
38
- size: containerRef().size(),
39
- pos: containerRef().position(),
40
- radius: containerRef().radius(),
41
- scale: containerRef().scale(),
42
- rotation: containerRef().rotation(),
43
- },
44
- element: {
45
- size: containerRef().size(),
46
- pos: elementRef().position(),
47
- scale: elementRef().scale(),
48
- },
49
- };
50
-
51
- for (let i = 0; i < frameElement?.frameEffects?.length; i++) {
52
- const frameEffect = frameElement.frameEffects[i];
53
- const restore =
54
- i === frameElement.frameEffects.length - 1 ||
55
- frameElement.frameEffects[i + 1].s !== frameEffect.e;
56
- frameEffects.push(
57
- getFrameEffect({
58
- containerRef,
59
- elementRef,
60
- frameEffect,
61
- element: frameElement,
62
- restore,
63
- initProps,
64
- })
65
- );
66
- }
67
- yield* all(...frameEffects);
68
- }
69
-
70
- function* getFrameEffect({
71
- containerRef,
72
- elementRef,
73
- frameEffect,
74
- element,
75
- initProps,
76
- restore = true,
77
- }: {
78
- containerRef: Reference<any>;
79
- elementRef: Reference<any>;
80
- frameEffect: FrameEffect;
81
- element: any;
82
- initProps: any;
83
- restore?: boolean;
84
- }) {
85
- yield* waitFor(frameEffect.s);
86
- const props = frameEffect.props;
87
- const sequence = [];
88
-
89
- if (restore) {
90
- sequence.push(
91
- restoreState({
92
- containerRef,
93
- elementRef,
94
- frameEffect,
95
- element,
96
- initProps,
97
- })
98
- );
99
- }
100
-
101
- sequence.push(
102
- containerRef().size(
103
- props.frameSize,
104
- props.transitionDuration,
105
- getTimingFunction(props.transitionEasing ?? DEFAULT_TIMING_FUNCTION)
106
- )
107
- );
108
-
109
- sequence.push(
110
- containerRef().position(
111
- props.framePosition ?? { x: 0, y: 0 },
112
- props.transitionDuration,
113
- getTimingFunction(props.transitionEasing ?? DEFAULT_TIMING_FUNCTION)
114
- )
115
- );
116
-
117
- sequence.push(
118
- elementRef().position(
119
- props.elementPosition ?? DEFAULT_POSITION,
120
- props.transitionDuration,
121
- getTimingFunction(props.transitionEasing ?? DEFAULT_TIMING_FUNCTION)
122
- )
123
- );
124
-
125
- switch (props.frameShape) {
126
- case FRAME_SHAPE.CIRCLE:
127
- sequence.push(
128
- containerRef().radius(
129
- props.frameSize[0] / 2,
130
- props.transitionDuration,
131
- getTimingFunction(props.transitionEasing ?? DEFAULT_TIMING_FUNCTION)
132
- )
133
- );
134
- break;
135
- default:
136
- sequence.push(
137
- containerRef().radius(
138
- props.radius ?? 0,
139
- props.transitionDuration,
140
- getTimingFunction(props.transitionEasing ?? DEFAULT_TIMING_FUNCTION)
141
- )
142
- );
143
- }
144
-
145
- if (props.objectFit) {
146
- sequence.push(
147
- fitElement({
148
- elementRef,
149
- containerSize: { x: props.frameSize[0], y: props.frameSize[1] },
150
- elementSize: initProps.element.size,
151
- objectFit: props.objectFit,
152
- })
153
- );
154
- }
155
- yield* all(...sequence);
156
- }
157
-
158
- function* restoreState({
159
- containerRef,
160
- elementRef,
161
- frameEffect,
162
- element,
163
- initProps,
164
- }: {
165
- containerRef: Reference<any>;
166
- elementRef: Reference<any>;
167
- frameEffect: any;
168
- element: any;
169
- initProps: any;
170
- }) {
171
- yield* waitFor(frameEffect.e - frameEffect.s);
172
- let sequence = [];
173
- sequence.push(containerRef().size(initProps.frame.size));
174
- sequence.push(containerRef().position(initProps.frame.pos));
175
- sequence.push(containerRef().scale(initProps.frame.scale));
176
- sequence.push(containerRef().rotation(initProps.frame.rotation));
177
- sequence.push(containerRef().radius(initProps.frame.radius));
178
- sequence.push(elementRef().size(initProps.element.size));
179
- sequence.push(elementRef().position(initProps.element.pos));
180
- sequence.push(elementRef().scale(initProps.element.scale));
181
- sequence.push(
182
- fitElement({
183
- elementRef,
184
- containerSize: initProps.frame.size,
185
- elementSize: initProps.element.size,
186
- objectFit: element.objectFit ?? "none",
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
+ }