@twick/visualizer 0.14.0 → 0.14.3

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 (68) hide show
  1. package/.eslintrc.json +20 -20
  2. package/README.md +113 -13
  3. package/package.json +14 -14
  4. package/package.json.bak +34 -0
  5. package/src/animations/blur.tsx +96 -60
  6. package/src/animations/breathe.tsx +95 -60
  7. package/src/animations/fade.tsx +173 -60
  8. package/src/animations/index.ts +12 -0
  9. package/src/animations/photo-rise.tsx +103 -66
  10. package/src/animations/photo-zoom.tsx +109 -73
  11. package/src/animations/rise.tsx +157 -118
  12. package/src/animations/succession.tsx +112 -77
  13. package/src/components/frame-effects.tsx +188 -188
  14. package/src/components/track.tsx +237 -232
  15. package/src/controllers/animation.controller.ts +38 -38
  16. package/src/controllers/element.controller.ts +42 -42
  17. package/src/controllers/frame-effect.controller.tsx +29 -29
  18. package/src/controllers/text-effect.controller.ts +32 -32
  19. package/src/elements/audio.element.tsx +79 -17
  20. package/src/elements/caption.element.tsx +169 -87
  21. package/src/elements/circle.element.tsx +88 -20
  22. package/src/elements/icon.element.tsx +88 -20
  23. package/src/elements/image.element.tsx +134 -55
  24. package/src/elements/index.ts +14 -0
  25. package/src/elements/rect.element.tsx +92 -22
  26. package/src/elements/scene.element.tsx +97 -29
  27. package/src/elements/text.element.tsx +101 -27
  28. package/src/elements/video.element.tsx +274 -56
  29. package/src/frame-effects/circle.frame.tsx +168 -103
  30. package/src/frame-effects/index.ts +7 -0
  31. package/src/frame-effects/rect.frame.tsx +198 -103
  32. package/src/global.css +11 -11
  33. package/src/helpers/caption.utils.ts +29 -29
  34. package/src/helpers/constants.ts +162 -158
  35. package/src/helpers/element.utils.ts +331 -239
  36. package/src/helpers/event.utils.ts +21 -0
  37. package/src/helpers/filters.ts +127 -127
  38. package/src/helpers/log.utils.ts +55 -29
  39. package/src/helpers/timing.utils.ts +109 -109
  40. package/src/helpers/types.ts +361 -241
  41. package/src/helpers/utils.ts +36 -19
  42. package/src/index.ts +196 -6
  43. package/src/live.tsx +16 -16
  44. package/src/project.ts +6 -6
  45. package/src/sample.ts +247 -247
  46. package/src/text-effects/elastic.tsx +70 -39
  47. package/src/text-effects/erase.tsx +91 -58
  48. package/src/text-effects/index.ts +9 -0
  49. package/src/text-effects/stream-word.tsx +94 -60
  50. package/src/text-effects/typewriter.tsx +93 -59
  51. package/src/visualizer-grouped.ts +83 -0
  52. package/src/visualizer.tsx +182 -78
  53. package/tsconfig.json +11 -11
  54. package/typedoc.json +19 -14
  55. package/vite.config.ts +15 -15
  56. package/.turbo/turbo-build.log +0 -19
  57. package/.turbo/turbo-docs.log +0 -7
  58. package/LICENSE +0 -197
  59. package/dist/mp4.wasm +0 -0
  60. package/dist/project.css +0 -1
  61. package/dist/project.js +0 -145
  62. package/docs/.nojekyll +0 -1
  63. package/docs/README.md +0 -13
  64. package/docs/interfaces/Animation.md +0 -47
  65. package/docs/interfaces/Element.md +0 -47
  66. package/docs/interfaces/FrameEffectPlugin.md +0 -47
  67. package/docs/interfaces/TextEffect.md +0 -47
  68. package/docs/modules.md +0 -535
package/src/sample.ts CHANGED
@@ -1,248 +1,248 @@
1
- export const sample = {
2
- "input": {
3
- "properties": {
4
- "width": 720,
5
- "height": 1280,
6
- "video_format": "mp4",
7
- "video_codec": "libx264",
8
- "audio_codec": "aac",
9
- "video_bitrate": "2500k",
10
- "audio_bitrate": "128k",
11
- "fps": 30
12
- },
13
- "backgroundMusic": "",
14
- "backgroundMusicLevel": 1,
15
- "bucket_name": "kifferai-assets",
16
- "context": {
17
- "scriptInput": {
18
- "scriptStyle": "PRODUCT_DEMONSTRATION"
19
- },
20
- "requestId": "f5d5db7a-8911-4b28-9c3c-71d91c83ddda",
21
- "campaignId": "campaign",
22
- "productUrl": "",
23
- "pageId": "page",
24
- "userId": "b1436dea-50e1-7049-cf34-6e49702da72a",
25
- "productName": "product",
26
- "orgId": "a251d9971a55"
27
- },
28
- "basePath": "carlyn",
29
- "tracks": [
30
- {
31
- "id": "t-scene",
32
- "type": "scene",
33
- "elements": [
34
- {
35
- "id": "e-244f8d5a3bbc",
36
- "type": "video",
37
- "s": 0,
38
- "e": 4.74,
39
- "objectFit": "cover",
40
- "props": {
41
- "time": 8.428,
42
- "src": "https://static-assets.kifferai.com/developmen/a251d9971a55/c436f351-ee9c-49c2-a26f-e7a7733c77ff/video_1746786031627-96448ec8-6430-4d4b-bb89-ebdbfeade7fa-normalized-1747225095191.mp4",
43
- "play": true,
44
- "decoder": "web",
45
- "volume": 1,
46
- "playbackRate": 2.4
47
- },
48
- "animation": {
49
- "name": "photo-zoom",
50
- "interval": 1,
51
- "mode": "out",
52
- "animate": "both",
53
- "direction": "top"
54
- },
55
- "frame": {
56
- "size": [
57
- 720,
58
- 1280
59
- ],
60
- "layout": false,
61
- "clip": "true"
62
- }
63
- },
64
- {
65
- "id": "e-ef2f208db319",
66
- "type": "video",
67
- "s": 4.74,
68
- "e": 6.774,
69
- "objectFit": "cover",
70
- "props": {
71
- "time": 0,
72
- "src": "https://static-assets.kifferai.com/developmen/a251d9971a55/63e0e7c3-5939-41a2-95c7-4e47e8be1ebf/video_1746786032120-6e4ab84c-d0dd-401e-b5e8-13d49fd8fe67-normalized-1747225095053.mp4",
73
- "play": true,
74
- "decoder": "web",
75
- "volume": 1,
76
- "playbackRate": 2
77
- },
78
- "frame": {
79
- "size": [
80
- 720,
81
- 1280
82
- ],
83
- "layout": false,
84
- "clip": "true"
85
- }
86
- },
87
- {
88
- "id": "e-477f620c0ec7",
89
- "type": "video",
90
- "s": 6.774,
91
- "e": 9.395,
92
- "objectFit": "cover",
93
- "props": {
94
- "time": 18.222499999999997,
95
- "src": "https://static-assets.kifferai.com/developmen/a251d9971a55/e66b4682-096d-46c5-b1b2-1e2e6a46fe8d/video_1746790653457-7e9e9a1d-9410-4bb3-bec1-7474fa88286c-normalized-1747225095442.mp4",
96
- "play": true,
97
- "decoder": "web",
98
- "volume": 1,
99
- "playbackRate": 2
100
- },
101
- "frame": {
102
- "size": [
103
- 2292.281711648068,
104
- 1286.2247382025269
105
- ],
106
- "layout": false,
107
- "clip": "true",
108
- "rotation": 0,
109
- "x": 269.48206359326264,
110
- "y": 6.293648227413769
111
- }
112
- }
113
- ],
114
- "name": "scene"
115
- },
116
- {
117
- "id": "t-83fa5f365f7f",
118
- "type": "audio",
119
- "name": "audio",
120
- "elements": [
121
- {
122
- "id": "e-50848c2d8271",
123
- "type": "audio",
124
- "s": 0,
125
- "e": 10,
126
- "props": {
127
- "time": 0,
128
- "src": "https://static-assets.kifferai.com/developmen/a251d9971a55/brand-music/Unstoppable-Reprise-909549aa-6807-482b-ab92-bce7e6834fe7.mp3",
129
- "play": true
130
- },
131
- "frame": {
132
- "size": [
133
- 720,
134
- 1280
135
- ],
136
- "layout": false,
137
- "clip": "true"
138
- }
139
- }
140
- ]
141
- },
142
- {
143
- "id": "t-795891203a03",
144
- "type": "element",
145
- "name": "element",
146
- "elements": [
147
- {
148
- "id": "e-6c32ca5f728e",
149
- "type": "text",
150
- "s": 0.009,
151
- "e": 4.691000000000001,
152
- "t": "GOD WILL BREAK YOU",
153
- "textEffect": {
154
- "name": "elastic",
155
- "duration": 1,
156
- },
157
- "props": {
158
- "fill": "#ffd700",
159
- "font": {
160
- "size": 48,
161
- "family": "Poppins"
162
- },
163
- "fontSize": 54,
164
- "fontFamily": "Impact",
165
- "stroke": "#000000",
166
- "lineWidth": 0.25,
167
- "fontWeight": "bold",
168
- "fontStyle": "Italic",
169
- "rotation": 0,
170
- "x": -11.306514773940933,
171
- "y": 103.95475034024639
172
- }
173
- },
174
- {
175
- "id": "e-39e2112fa735",
176
- "type": "text",
177
- "s": 4.824,
178
- "e": 6.709,
179
- "t": "BREAK YOU AGAIN",
180
- "props": {
181
- "fill": "#FFFFFF",
182
- "font": {
183
- "size": 48,
184
- "family": "Poppins"
185
- },
186
- "fontSize": 54,
187
- "fontFamily": "Impact",
188
- "stroke": "#000000",
189
- "lineWidth": 0.25,
190
- "fontWeight": "bold",
191
- "fontStyle": "normal",
192
- "rotation": 0,
193
- "x": 2.261302954788164,
194
- "y": 128.8134949868271
195
- }
196
- },
197
- {
198
- "id": "e-384f59e94253",
199
- "type": "text",
200
- "s": 4.904,
201
- "e": 6.7059999999999995,
202
- "t": "AND THEN",
203
- "props": {
204
- "fill": "#fffd70",
205
- "font": {
206
- "size": 48,
207
- "family": "Poppins"
208
- },
209
- "fontSize": 54,
210
- "fontFamily": "Impact",
211
- "stroke": "#000000",
212
- "lineWidth": 0.25,
213
- "fontWeight": "bold",
214
- "fontStyle": "Italic",
215
- "rotation": 0,
216
- "x": 0,
217
- "y": 201.12984304960742
218
- }
219
- },
220
- {
221
- "id": "e-180cab9f1871",
222
- "type": "text",
223
- "s": 6.891,
224
- "e": 9.343,
225
- "t": "BREAK YOU ONCE AGAIN",
226
- "props": {
227
- "fill": "#ffd700",
228
- "font": {
229
- "size": 48,
230
- "family": "Poppins"
231
- },
232
- "fontSize": 54,
233
- "fontFamily": "Impact",
234
- "stroke": "#000000",
235
- "lineWidth": 0.25,
236
- "fontWeight": "bold",
237
- "fontStyle": "Italic",
238
- "rotation": 0,
239
- "x": 4.522605909576328,
240
- "y": 81.35589157062759
241
- }
242
- }
243
- ]
244
- }
245
- ],
246
- "version": 1
247
- }
1
+ export const sample = {
2
+ "input": {
3
+ "properties": {
4
+ "width": 720,
5
+ "height": 1280,
6
+ "video_format": "mp4",
7
+ "video_codec": "libx264",
8
+ "audio_codec": "aac",
9
+ "video_bitrate": "2500k",
10
+ "audio_bitrate": "128k",
11
+ "fps": 30
12
+ },
13
+ "backgroundMusic": "",
14
+ "backgroundMusicLevel": 1,
15
+ "bucket_name": "kifferai-assets",
16
+ "context": {
17
+ "scriptInput": {
18
+ "scriptStyle": "PRODUCT_DEMONSTRATION"
19
+ },
20
+ "requestId": "f5d5db7a-8911-4b28-9c3c-71d91c83ddda",
21
+ "campaignId": "campaign",
22
+ "productUrl": "",
23
+ "pageId": "page",
24
+ "userId": "b1436dea-50e1-7049-cf34-6e49702da72a",
25
+ "productName": "product",
26
+ "orgId": "a251d9971a55"
27
+ },
28
+ "basePath": "carlyn",
29
+ "tracks": [
30
+ {
31
+ "id": "t-scene",
32
+ "type": "scene",
33
+ "elements": [
34
+ {
35
+ "id": "e-244f8d5a3bbc",
36
+ "type": "video",
37
+ "s": 0,
38
+ "e": 4.74,
39
+ "objectFit": "cover",
40
+ "props": {
41
+ "time": 8.428,
42
+ "src": "https://static-assets.kifferai.com/developmen/a251d9971a55/c436f351-ee9c-49c2-a26f-e7a7733c77ff/video_1746786031627-96448ec8-6430-4d4b-bb89-ebdbfeade7fa-normalized-1747225095191.mp4",
43
+ "play": true,
44
+ "decoder": "web",
45
+ "volume": 1,
46
+ "playbackRate": 2.4
47
+ },
48
+ "animation": {
49
+ "name": "photo-zoom",
50
+ "interval": 1,
51
+ "mode": "out",
52
+ "animate": "both",
53
+ "direction": "top"
54
+ },
55
+ "frame": {
56
+ "size": [
57
+ 720,
58
+ 1280
59
+ ],
60
+ "layout": false,
61
+ "clip": "true"
62
+ }
63
+ },
64
+ {
65
+ "id": "e-ef2f208db319",
66
+ "type": "video",
67
+ "s": 4.74,
68
+ "e": 6.774,
69
+ "objectFit": "cover",
70
+ "props": {
71
+ "time": 0,
72
+ "src": "https://static-assets.kifferai.com/developmen/a251d9971a55/63e0e7c3-5939-41a2-95c7-4e47e8be1ebf/video_1746786032120-6e4ab84c-d0dd-401e-b5e8-13d49fd8fe67-normalized-1747225095053.mp4",
73
+ "play": true,
74
+ "decoder": "web",
75
+ "volume": 1,
76
+ "playbackRate": 2
77
+ },
78
+ "frame": {
79
+ "size": [
80
+ 720,
81
+ 1280
82
+ ],
83
+ "layout": false,
84
+ "clip": "true"
85
+ }
86
+ },
87
+ {
88
+ "id": "e-477f620c0ec7",
89
+ "type": "video",
90
+ "s": 6.774,
91
+ "e": 9.395,
92
+ "objectFit": "cover",
93
+ "props": {
94
+ "time": 18.222499999999997,
95
+ "src": "https://static-assets.kifferai.com/developmen/a251d9971a55/e66b4682-096d-46c5-b1b2-1e2e6a46fe8d/video_1746790653457-7e9e9a1d-9410-4bb3-bec1-7474fa88286c-normalized-1747225095442.mp4",
96
+ "play": true,
97
+ "decoder": "web",
98
+ "volume": 1,
99
+ "playbackRate": 2
100
+ },
101
+ "frame": {
102
+ "size": [
103
+ 2292.281711648068,
104
+ 1286.2247382025269
105
+ ],
106
+ "layout": false,
107
+ "clip": "true",
108
+ "rotation": 0,
109
+ "x": 269.48206359326264,
110
+ "y": 6.293648227413769
111
+ }
112
+ }
113
+ ],
114
+ "name": "scene"
115
+ },
116
+ {
117
+ "id": "t-83fa5f365f7f",
118
+ "type": "audio",
119
+ "name": "audio",
120
+ "elements": [
121
+ {
122
+ "id": "e-50848c2d8271",
123
+ "type": "audio",
124
+ "s": 0,
125
+ "e": 10,
126
+ "props": {
127
+ "time": 0,
128
+ "src": "https://static-assets.kifferai.com/developmen/a251d9971a55/brand-music/Unstoppable-Reprise-909549aa-6807-482b-ab92-bce7e6834fe7.mp3",
129
+ "play": true
130
+ },
131
+ "frame": {
132
+ "size": [
133
+ 720,
134
+ 1280
135
+ ],
136
+ "layout": false,
137
+ "clip": "true"
138
+ }
139
+ }
140
+ ]
141
+ },
142
+ {
143
+ "id": "t-795891203a03",
144
+ "type": "element",
145
+ "name": "element",
146
+ "elements": [
147
+ {
148
+ "id": "e-6c32ca5f728e",
149
+ "type": "text",
150
+ "s": 0.009,
151
+ "e": 4.691000000000001,
152
+ "t": "GOD WILL BREAK YOU",
153
+ "textEffect": {
154
+ "name": "elastic",
155
+ "duration": 1,
156
+ },
157
+ "props": {
158
+ "fill": "#ffd700",
159
+ "font": {
160
+ "size": 48,
161
+ "family": "Poppins"
162
+ },
163
+ "fontSize": 54,
164
+ "fontFamily": "Impact",
165
+ "stroke": "#000000",
166
+ "lineWidth": 0.25,
167
+ "fontWeight": "bold",
168
+ "fontStyle": "Italic",
169
+ "rotation": 0,
170
+ "x": -11.306514773940933,
171
+ "y": 103.95475034024639
172
+ }
173
+ },
174
+ {
175
+ "id": "e-39e2112fa735",
176
+ "type": "text",
177
+ "s": 4.824,
178
+ "e": 6.709,
179
+ "t": "BREAK YOU AGAIN",
180
+ "props": {
181
+ "fill": "#FFFFFF",
182
+ "font": {
183
+ "size": 48,
184
+ "family": "Poppins"
185
+ },
186
+ "fontSize": 54,
187
+ "fontFamily": "Impact",
188
+ "stroke": "#000000",
189
+ "lineWidth": 0.25,
190
+ "fontWeight": "bold",
191
+ "fontStyle": "normal",
192
+ "rotation": 0,
193
+ "x": 2.261302954788164,
194
+ "y": 128.8134949868271
195
+ }
196
+ },
197
+ {
198
+ "id": "e-384f59e94253",
199
+ "type": "text",
200
+ "s": 4.904,
201
+ "e": 6.7059999999999995,
202
+ "t": "AND THEN",
203
+ "props": {
204
+ "fill": "#fffd70",
205
+ "font": {
206
+ "size": 48,
207
+ "family": "Poppins"
208
+ },
209
+ "fontSize": 54,
210
+ "fontFamily": "Impact",
211
+ "stroke": "#000000",
212
+ "lineWidth": 0.25,
213
+ "fontWeight": "bold",
214
+ "fontStyle": "Italic",
215
+ "rotation": 0,
216
+ "x": 0,
217
+ "y": 201.12984304960742
218
+ }
219
+ },
220
+ {
221
+ "id": "e-180cab9f1871",
222
+ "type": "text",
223
+ "s": 6.891,
224
+ "e": 9.343,
225
+ "t": "BREAK YOU ONCE AGAIN",
226
+ "props": {
227
+ "fill": "#ffd700",
228
+ "font": {
229
+ "size": 48,
230
+ "family": "Poppins"
231
+ },
232
+ "fontSize": 54,
233
+ "fontFamily": "Impact",
234
+ "stroke": "#000000",
235
+ "lineWidth": 0.25,
236
+ "fontWeight": "bold",
237
+ "fontStyle": "Italic",
238
+ "rotation": 0,
239
+ "x": 4.522605909576328,
240
+ "y": 81.35589157062759
241
+ }
242
+ }
243
+ ]
244
+ }
245
+ ],
246
+ "version": 1
247
+ }
248
248
  }
@@ -1,39 +1,70 @@
1
- import { easeOutElastic, waitFor } from "@twick/core";
2
- import { TextEffectParams } from "../helpers/types";
3
-
4
- /**
5
- * ElasticEffect applies a scaling animation to text elements
6
- * with an elastic easing curve for a "pop" or "bounce" effect.
7
- *
8
- * Behavior:
9
- * - Optionally waits for a delay.
10
- * - Starts at zero scale (invisible).
11
- * - Scales up to full size with an elastic bounce.
12
- *
13
- * @param elementRef - Reference to the text element to animate.
14
- * @param duration - Duration of the scaling animation.
15
- * @param delay - Optional delay before the animation starts.
16
- */
17
- export const ElasticEffect = {
18
- name: "elastic",
19
-
20
- /**
21
- * Generator function controlling the elastic text scaling effect.
22
- */
23
- *run({
24
- elementRef,
25
- duration,
26
- delay,
27
- }: TextEffectParams) {
28
- // If a delay is specified, wait before starting the animation
29
- if (delay) {
30
- yield* waitFor(delay);
31
- }
32
-
33
- // Instantly set scale to 0 (invisible)
34
- elementRef().scale(0);
35
-
36
- // Animate scaling up to full size using elastic easing
37
- yield* elementRef().scale(1, duration, easeOutElastic);
38
- },
39
- };
1
+ import { easeOutElastic, waitFor } from "@twick/core";
2
+ import { TextEffectParams } from "../helpers/types";
3
+
4
+ /**
5
+ * @group ElasticEffect
6
+ * ElasticEffect applies a scaling animation to text elements with an elastic easing
7
+ * curve for a "pop" or "bounce" effect. Creates playful, attention-grabbing text
8
+ * animations that bounce into view with natural physics.
9
+ *
10
+ * Behavior:
11
+ * - Optionally waits for a delay
12
+ * - Starts at zero scale (invisible)
13
+ * - Scales up to full size with an elastic bounce
14
+ *
15
+ * @param elementRef - Reference to the text element to animate
16
+ * @param duration - Duration of the scaling animation in seconds
17
+ * @param delay - Optional delay before the animation starts in seconds
18
+ *
19
+ * @example
20
+ * ```js
21
+ * // Basic elastic bounce
22
+ * textEffect: {
23
+ * name: "elastic",
24
+ * duration: 1.5,
25
+ * delay: 0.5
26
+ * }
27
+ *
28
+ * // Quick elastic pop
29
+ * textEffect: {
30
+ * name: "elastic",
31
+ * duration: 0.8
32
+ * }
33
+ * ```
34
+ */
35
+ export const ElasticEffect = {
36
+ name: "elastic",
37
+
38
+ /**
39
+ * Generator function controlling the elastic text scaling effect.
40
+ * Handles elastic bounce animations for text elements with natural physics.
41
+ *
42
+ * @param params - Text effect parameters including element reference and timing
43
+ * @returns Generator that controls the elastic animation timeline
44
+ *
45
+ * @example
46
+ * ```js
47
+ * yield* ElasticEffect.run({
48
+ * elementRef: textElement,
49
+ * duration: 1.5,
50
+ * delay: 0.5
51
+ * });
52
+ * ```
53
+ */
54
+ *run({
55
+ elementRef,
56
+ duration,
57
+ delay,
58
+ }: TextEffectParams) {
59
+ // If a delay is specified, wait before starting the animation
60
+ if (delay) {
61
+ yield* waitFor(delay);
62
+ }
63
+
64
+ // Instantly set scale to 0 (invisible)
65
+ elementRef().scale(0);
66
+
67
+ // Animate scaling up to full size using elastic easing
68
+ yield* elementRef().scale(1, duration, easeOutElastic);
69
+ },
70
+ };