@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,55 @@
1
+ import { ElementParams } from "../helpers/types";
2
+ import { all, createRef, waitFor } from "@twick/core";
3
+ import { Rect, Video } from "@twick/2d";
4
+ import { addAnimation, addFrameEffect, fitElement } from "../helpers/element.utils";
5
+ import { applyColorFilter } from "../helpers/filters";
6
+
7
+ export const VideoElement = {
8
+ name: "video",
9
+ *create({ containerRef, element, view }: ElementParams) {
10
+ yield* waitFor(element?.s);
11
+ const frameContainerRef = createRef<any>();
12
+ const frameElementRef = createRef<any>();
13
+
14
+ yield containerRef().add(
15
+ <Rect ref={frameContainerRef} key={element.id} {...element.frame}>
16
+ <Video
17
+ ref={frameElementRef}
18
+ key={`child-${element.id}`}
19
+ play={true}
20
+ {...element.props}
21
+ />
22
+ </Rect>
23
+ );
24
+ if (frameContainerRef()) {
25
+ yield fitElement({
26
+ elementRef: frameElementRef,
27
+ containerSize: frameContainerRef().size(),
28
+ elementSize: frameElementRef().size(),
29
+ objectFit: element.objectFit,
30
+ });
31
+
32
+ if (element?.props?.mediaFilter) {
33
+ applyColorFilter(frameElementRef, element.props.mediaFilter);
34
+ }
35
+
36
+ yield* all(
37
+ addAnimation({
38
+ elementRef: frameElementRef,
39
+ containerRef: frameContainerRef,
40
+ element: element,
41
+ view,
42
+ }),
43
+ addFrameEffect({
44
+ containerRef: frameContainerRef,
45
+ elementRef: frameElementRef,
46
+ element,
47
+ }),
48
+ waitFor(Math.max(0, element.e - element.s))
49
+ );
50
+ yield frameElementRef().play(false);
51
+ yield frameElementRef().remove();
52
+ yield frameContainerRef().remove();
53
+ }
54
+ },
55
+ };
@@ -0,0 +1,103 @@
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, waitFor } from "@twick/core";
7
+ import { getTimingFunction } from "../helpers/timing.utils";
8
+ import { fitElement } from "../helpers/element.utils";
9
+ import {
10
+ DEFAULT_POSITION,
11
+ DEFAULT_TIMING_FUNCTION,
12
+ } from "../helpers/constants";
13
+ import { FrameEffectParams } from "../helpers/types";
14
+
15
+ /**
16
+ * CircleFrameEffect animates a frame transitioning into a circular shape,
17
+ * resizing, repositioning, and optionally fitting its content.
18
+ *
19
+ * Behavior:
20
+ * - Waits for the specified start time.
21
+ * - Resizes and repositions the frame container smoothly.
22
+ * - Animates the corner radius to create a perfect circle.
23
+ * - Repositions the content element if needed.
24
+ * - Optionally fits the element inside the container based on object-fit.
25
+ *
26
+ * @param containerRef - Reference to the frame container element.
27
+ * @param elementRef - Reference to the content element inside the frame.
28
+ * @param initFrameState - Initial size and position state of the element.
29
+ * @param frameEffect - Frame transformation configuration and timing.
30
+ */
31
+ export const CircleFrameEffect = {
32
+ name: "circle",
33
+
34
+ /**
35
+ * Generator function controlling the circle frame animation.
36
+ */
37
+ *run({
38
+ containerRef,
39
+ elementRef,
40
+ initFrameState,
41
+ frameEffect,
42
+ }: FrameEffectParams) {
43
+ // Wait for the specified start time before starting animation
44
+ yield* waitFor(frameEffect.s);
45
+
46
+ const props = frameEffect.props;
47
+ const sequence = [];
48
+
49
+ // Animate resizing the container to target size
50
+ sequence.push(
51
+ containerRef().size(
52
+ { x: props.frameSize[0], y: props.frameSize[1] },
53
+ props.transitionDuration,
54
+ getTimingFunction(props.transitionEasing ?? DEFAULT_TIMING_FUNCTION)
55
+ )
56
+ );
57
+
58
+ // Animate repositioning the container
59
+ sequence.push(
60
+ containerRef().position(
61
+ props.framePosition ?? { x: 0, y: 0 },
62
+ props.transitionDuration,
63
+ getTimingFunction(props.transitionEasing ?? DEFAULT_TIMING_FUNCTION)
64
+ )
65
+ );
66
+
67
+ // Animate repositioning the element inside the container
68
+ sequence.push(
69
+ elementRef().position(
70
+ props.elementPosition ?? DEFAULT_POSITION,
71
+ props.transitionDuration,
72
+ getTimingFunction(props.transitionEasing ?? DEFAULT_TIMING_FUNCTION)
73
+ )
74
+ );
75
+
76
+ // Animate rounding corners to create a circle (radius = half the width)
77
+ sequence.push(
78
+ containerRef().radius(
79
+ props.frameSize[0] / 2,
80
+ props.transitionDuration,
81
+ getTimingFunction(props.transitionEasing ?? DEFAULT_TIMING_FUNCTION)
82
+ )
83
+ );
84
+
85
+ // Optionally fit the element inside the resized container
86
+ if (props.objectFit) {
87
+ sequence.push(
88
+ fitElement({
89
+ elementRef,
90
+ containerSize: {
91
+ x: props.frameSize[0],
92
+ y: props.frameSize[1],
93
+ },
94
+ elementSize: initFrameState.element.size,
95
+ objectFit: props.objectFit,
96
+ })
97
+ );
98
+ }
99
+
100
+ // Run all animations in parallel
101
+ yield* all(...sequence);
102
+ },
103
+ };
@@ -0,0 +1,103 @@
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, waitFor } from "@twick/core";
7
+ import { getTimingFunction } from "../helpers/timing.utils";
8
+ import { fitElement } from "../helpers/element.utils";
9
+ import {
10
+ DEFAULT_POSITION,
11
+ DEFAULT_TIMING_FUNCTION,
12
+ } from "../helpers/constants";
13
+ import { FrameEffectParams } from "../helpers/types";
14
+
15
+ /**
16
+ * RectFrameEffect applies frame transformations such as resizing,
17
+ * repositioning, rounding corners, and optionally fitting the element
18
+ * within the frame according to an object-fit mode.
19
+ *
20
+ * Behavior:
21
+ * - Waits for the specified start time.
22
+ * - Resizes and repositions the container and element smoothly.
23
+ * - Adjusts corner radius if provided.
24
+ * - Optionally fits the element inside the container.
25
+ *
26
+ * @param containerRef - Reference to the frame container element.
27
+ * @param elementRef - Reference to the content element inside the frame.
28
+ * @param initFrameState - Initial size and position state of the element.
29
+ * @param frameEffect - Frame transformation configuration and timing.
30
+ */
31
+ export const RectFrameEffect = {
32
+ name: "rect",
33
+
34
+ /**
35
+ * Generator function controlling the frame resizing and positioning animation.
36
+ */
37
+ *run({
38
+ containerRef,
39
+ elementRef,
40
+ initFrameState,
41
+ frameEffect,
42
+ }: FrameEffectParams) {
43
+ // Wait until the effect start time
44
+ yield* waitFor(frameEffect.s);
45
+
46
+ const props = frameEffect.props;
47
+ const sequence = [];
48
+
49
+ // Animate resizing the container
50
+ sequence.push(
51
+ containerRef().size(
52
+ props.frameSize,
53
+ props.transitionDuration,
54
+ getTimingFunction(props.transitionEasing ?? DEFAULT_TIMING_FUNCTION)
55
+ )
56
+ );
57
+
58
+ // Animate repositioning the container
59
+ sequence.push(
60
+ containerRef().position(
61
+ props.framePosition ?? { x: 0, y: 0 },
62
+ props.transitionDuration,
63
+ getTimingFunction(props.transitionEasing ?? DEFAULT_TIMING_FUNCTION)
64
+ )
65
+ );
66
+
67
+ // Animate repositioning the element inside the container
68
+ sequence.push(
69
+ elementRef().position(
70
+ props.elementPosition ?? DEFAULT_POSITION,
71
+ props.transitionDuration,
72
+ getTimingFunction(props.transitionEasing ?? DEFAULT_TIMING_FUNCTION)
73
+ )
74
+ );
75
+
76
+ // Animate corner radius if specified
77
+ sequence.push(
78
+ containerRef().radius(
79
+ props.radius ?? 0,
80
+ props.transitionDuration,
81
+ getTimingFunction(props.transitionEasing ?? DEFAULT_TIMING_FUNCTION)
82
+ )
83
+ );
84
+
85
+ // Optionally fit the element within the container based on object-fit
86
+ if (props.objectFit) {
87
+ sequence.push(
88
+ fitElement({
89
+ elementRef,
90
+ containerSize: {
91
+ x: props.frameSize[0],
92
+ y: props.frameSize[1],
93
+ },
94
+ elementSize: initFrameState.element.size,
95
+ objectFit: props.objectFit,
96
+ })
97
+ );
98
+ }
99
+
100
+ // Run all animations in parallel
101
+ yield* all(...sequence);
102
+ },
103
+ };
package/src/global.css CHANGED
@@ -1,12 +1,12 @@
1
- @import url('https://fonts.googleapis.com/css2?family=Rubik:ital,wght@0,300..900;1,300..900&display=swap');
2
- @import url('https://fonts.googleapis.com/css2?family=Mulish:ital,wght@0,200..1000;1,200..1000&display=swap');
3
- @import url('https://fonts.googleapis.com/css2?family=Luckiest+Guy&family=Mulish:ital,wght@0,200..1000;1,200..1000&family=Playfair+Display:ital,wght@0,400..900;1,400..900&display=swap');
4
- @import url('https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap');
5
- @import url('https://fonts.googleapis.com/css2?family=Bangers&family=Birthstone&family=Corinthia:wght@400;700&family=Imperial+Script&family=Kumar+One+Outline&family=Londrina+Outline&family=Marck+Script&family=Montserrat:ital,wght@0,100..900;1,100..900&family=Pattaya&family=Playfair+Display:ital,wght@0,400..900;1,400..900&family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap');
6
- @import url('https://fonts.cdnfonts.com/css/peralta');
7
- @import url('https://fonts.cdnfonts.com/css/impact');
8
- @import url('https://fonts.cdnfonts.com/css/lumanosimo');
9
- @import url('https://fonts.cdnfonts.com/css/kapakana');
10
- @import url('https://fonts.cdnfonts.com/css/handyrush');
11
- @import url('https://fonts.cdnfonts.com/css/dasher');
1
+ @import url('https://fonts.googleapis.com/css2?family=Rubik:ital,wght@0,300..900;1,300..900&display=swap');
2
+ @import url('https://fonts.googleapis.com/css2?family=Mulish:ital,wght@0,200..1000;1,200..1000&display=swap');
3
+ @import url('https://fonts.googleapis.com/css2?family=Luckiest+Guy&family=Mulish:ital,wght@0,200..1000;1,200..1000&family=Playfair+Display:ital,wght@0,400..900;1,400..900&display=swap');
4
+ @import url('https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap');
5
+ @import url('https://fonts.googleapis.com/css2?family=Bangers&family=Birthstone&family=Corinthia:wght@400;700&family=Imperial+Script&family=Kumar+One+Outline&family=Londrina+Outline&family=Marck+Script&family=Montserrat:ital,wght@0,100..900;1,100..900&family=Pattaya&family=Playfair+Display:ital,wght@0,400..900;1,400..900&family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap');
6
+ @import url('https://fonts.cdnfonts.com/css/peralta');
7
+ @import url('https://fonts.cdnfonts.com/css/impact');
8
+ @import url('https://fonts.cdnfonts.com/css/lumanosimo');
9
+ @import url('https://fonts.cdnfonts.com/css/kapakana');
10
+ @import url('https://fonts.cdnfonts.com/css/handyrush');
11
+ @import url('https://fonts.cdnfonts.com/css/dasher');
12
12
  @import url('https://fonts.cdnfonts.com/css/brittany-signature');
@@ -1,40 +1,30 @@
1
- /**
2
- * Caption utilities for the visualizer package.
3
- * Provides functions for handling caption text formatting and timing.
4
- */
5
-
6
- /**
7
- * Splits a phrase into words with timing information
8
- * @param {string} phrase - The phrase to split
9
- * @param {number} startTime - Start time of the phrase
10
- * @param {number} duration - Duration of the phrase
11
- * @returns {Array} Array of words with timing information
12
- */
13
- export function splitPhraseTiming({ t, s, e }: { t: string, s: number, e: number }) {
14
- const words = t.split(" ");
15
- const totalDuration = e - s;
16
- const totalLength = words.join("").length; // Total character length without spaces
17
-
18
- let currentTime = s;
19
- return words.map((word) => {
20
- const wordDuration = (word.length / totalLength) * totalDuration;
21
- const wordStart = currentTime;
22
- const wordEnd = wordStart + wordDuration;
23
- currentTime = wordEnd;
24
- return {
25
- t: word,
26
- s: parseFloat(wordStart.toFixed(2)),
27
- e: parseFloat(wordEnd.toFixed(2)),
28
- };
29
- });
30
- }
31
-
32
- /**
33
- * Formats caption text with specified style
34
- * @param {string} text - The text to format
35
- * @param {Object} style - The style to apply
36
- * @returns {string} Formatted text
37
- */
38
- export function formatCaptionText(text: string, style: any) {
39
- // ... existing code ...
40
- }
1
+ /**
2
+ * Caption utilities for the visualizer package.
3
+ * Provides functions for handling caption text formatting and timing.
4
+ */
5
+
6
+ /**
7
+ * Splits a phrase into words with timing information
8
+ * @param {string} t - The phrase to split
9
+ * @param {number} s - Start time of the phrase
10
+ * @param {number} e - End time of the phrase
11
+ * @returns {Array} Array of words with timing information
12
+ */
13
+ export function splitPhraseTiming({ t, s, e }: { t: string, s: number, e: number }) {
14
+ const words = t.split(" ");
15
+ const totalDuration = e - s;
16
+ const totalLength = words.join("").length; // Total character length without spaces
17
+
18
+ let currentTime = s;
19
+ return words.map((word) => {
20
+ const wordDuration = (word.length / totalLength) * totalDuration;
21
+ const wordStart = currentTime;
22
+ const wordEnd = wordStart + wordDuration;
23
+ currentTime = wordEnd;
24
+ return {
25
+ t: word,
26
+ s: parseFloat(wordStart.toFixed(2)),
27
+ e: parseFloat(wordEnd.toFixed(2)),
28
+ };
29
+ });
30
+ }
@@ -1,159 +1,163 @@
1
- import { CaptionStyle } from "./types";
2
-
3
- /**
4
- * Constants used throughout the visualizer package.
5
- * Contains default values, configuration options, and type definitions.
6
- */
7
-
8
- /**
9
- * Default background color for scenes
10
- */
11
- export const DEFAULT_BACKGROUND_COLOR = "#000000";
12
-
13
- /**
14
- * Default position for elements
15
- */
16
- export const DEFAULT_POSITION = {
17
- x: 0,
18
- y: 0
19
- };
20
-
21
- /**
22
- * Default timing function for animations
23
- */
24
- export const DEFAULT_TIMING_FUNCTION = "easeInOut";
25
-
26
- /**
27
- * Available frame shapes for elements
28
- */
29
- export const FRAME_SHAPE = {
30
- RECTANGLE: "rectangle",
31
- CIRCLE: "circle",
32
- LINE: "line"
33
- } as const;
34
-
35
- /**
36
- * Timeline types for different media elements
37
- */
38
- export const TIMELINE_TYPES = {
39
- VIDEO: "video",
40
- AUDIO: "audio",
41
- CAPTION: "caption",
42
- SCENE: "scene",
43
- ELEMENT: "element"
44
- } as const;
45
-
46
- export const CAPTION_STYLE: Record<string, CaptionStyle> = {
47
- highlight_bg: {
48
- rect: {
49
- alignItems: "center",
50
- gap: 2,
51
- },
52
- word: {
53
- lineWidth: 0.35,
54
- stroke: "#000000",
55
- fontWeight: 700,
56
- shadowOffset: [-3, 3],
57
- shadowColor: "#000000",
58
- fill: "#ffffff",
59
- fontFamily: "Bangers",
60
- bgColor: "#000000",
61
- bgOffsetWidth: 30,
62
- bgOffsetHeight: 8,
63
- fontSize: 54,
64
- },
65
- },
66
- word_by_word: {
67
- rect: {
68
- alignItems: "center",
69
- justifyContent: "center",
70
- gap: 12,
71
- },
72
- word: {
73
- lineWidth: 0.35,
74
- stroke: "#000000",
75
- fontWeight: 700,
76
- strokeFirst: true,
77
- shadowOffset: [-2, 2],
78
- shadowColor: "#000000",
79
- shadowBlur: 5,
80
- fontFamily: "Bangers",
81
- fill: "#FFFFFF",
82
- bgOffsetWidth: 20,
83
- bgOffsetHeight: 10,
84
- fontSize: 54,
85
- },
86
- },
87
- word_by_word_with_bg: {
88
- rect: {
89
- alignItems: "center",
90
- gap: 12,
91
- padding: [10, 20],
92
- radius: 10,
93
- },
94
- word: {
95
- lineWidth: 0.35,
96
- stroke: "#000000",
97
- fontWeight: 700,
98
- strokeFirst: true,
99
- shadowOffset: [-2, 2],
100
- shadowColor: "#000000",
101
- shadowBlur: 5,
102
- fontFamily: "Bangers",
103
- fill: "#FFFFFF",
104
- bgOffsetWidth: 20,
105
- bgOffsetHeight: 10,
106
- fontSize: 54,
107
- },
108
- },
109
- };
110
-
111
- export const DEFAULT_CAPTION_COLORS = {
112
- text: "#000000",
113
- background: "#FFFFFF",
114
- };
115
-
116
- export const DEFAULT_CAPTION_FONT = {
117
- family: "Poppins",
118
- size: 48,
119
- weight: 400,
120
- };
121
-
122
- export const TRANSPARENT_COLOR = "#FFFFFF00";
123
-
124
- export const ELEMENT_TYPES = {
125
- VIDEO: "video",
126
- IMAGE: "image",
127
- AUDIO: "audio",
128
- TEXT: "text",
129
- CAPTION: "caption",
130
- RECT: "rect",
131
- CIRCLE: "circle",
132
- ICON: "icon",
133
- };
134
-
135
- export const OBJECT_FIT = {
136
- CONTAIN: "contain",
137
- COVER: "cover",
138
- FILL: "fill",
139
- NONE: "none",
140
- }
141
-
142
- export const COLOR_FILTERS = {
143
- SATURATED: "saturated",
144
- BRIGHT: "bright",
145
- VIBRANT: "vibrant",
146
- RETRO: "retro",
147
- BLACK_WHITE: "blackWhite",
148
- SEPIA: "sepia",
149
- COOL: "cool",
150
- WARM: "warm",
151
- CINEMATIC: "cinematic",
152
- SOFT_GLOW: "softGlow",
153
- MOODY: "moody",
154
- DREAMY: "dreamy",
155
- INVERTED: "inverted",
156
- VINTAGE: "vintage",
157
- DRAMATIC: "dramatic",
158
- FADED: "faded",
1
+ import { CaptionStyle } from "./types";
2
+
3
+ /**
4
+ * Constants used throughout the visualizer package.
5
+ * Contains default values, configuration options, and type definitions.
6
+ */
7
+
8
+ /**
9
+ * Default background color for scenes
10
+ */
11
+ export const DEFAULT_BACKGROUND_COLOR = "#000000";
12
+
13
+ /**
14
+ * Default position for elements
15
+ */
16
+ export const DEFAULT_POSITION = {
17
+ x: 0,
18
+ y: 0
19
+ };
20
+
21
+ /**
22
+ * Default timing function for animations
23
+ */
24
+ export const DEFAULT_TIMING_FUNCTION = "easeInOut";
25
+
26
+ /**
27
+ * Available frame shapes for elements
28
+ */
29
+ export const FRAME_SHAPE = {
30
+ RECTANGLE: "rectangle",
31
+ CIRCLE: "circle",
32
+ LINE: "line"
33
+ } as const;
34
+
35
+ /**
36
+ * Timeline types for different media elements
37
+ */
38
+ export const TRACK_TYPES = {
39
+ VIDEO: "video",
40
+ AUDIO: "audio",
41
+ CAPTION: "caption",
42
+ SCENE: "scene",
43
+ ELEMENT: "element"
44
+ } as const;
45
+
46
+ export const CAPTION_STYLE: Record<string, CaptionStyle> = {
47
+ highlight_bg: {
48
+ rect: {
49
+ alignItems: "center",
50
+ gap: 2,
51
+ },
52
+ word: {
53
+ lineWidth: 0.35,
54
+ stroke: "#000000",
55
+ fontWeight: 700,
56
+ shadowOffset: [-3, 3],
57
+ shadowColor: "#000000",
58
+ fill: "#ffffff",
59
+ fontFamily: "Bangers",
60
+ bgColor: "#000000",
61
+ bgOffsetWidth: 30,
62
+ bgOffsetHeight: 8,
63
+ fontSize: 54,
64
+ },
65
+ },
66
+ word_by_word: {
67
+ rect: {
68
+ alignItems: "center",
69
+ justifyContent: "center",
70
+ gap: 12,
71
+ },
72
+ word: {
73
+ lineWidth: 0.35,
74
+ stroke: "#000000",
75
+ fontWeight: 700,
76
+ strokeFirst: true,
77
+ shadowOffset: [-2, 2],
78
+ shadowColor: "#000000",
79
+ shadowBlur: 5,
80
+ fontFamily: "Bangers",
81
+ fill: "#FFFFFF",
82
+ bgOffsetWidth: 20,
83
+ bgOffsetHeight: 10,
84
+ fontSize: 54,
85
+ },
86
+ },
87
+ word_by_word_with_bg: {
88
+ rect: {
89
+ alignItems: "center",
90
+ gap: 12,
91
+ padding: [10, 20],
92
+ radius: 10,
93
+ },
94
+ word: {
95
+ lineWidth: 0.35,
96
+ stroke: "#000000",
97
+ fontWeight: 700,
98
+ strokeFirst: true,
99
+ shadowOffset: [-2, 2],
100
+ shadowColor: "#000000",
101
+ shadowBlur: 5,
102
+ fontFamily: "Bangers",
103
+ fill: "#FFFFFF",
104
+ bgOffsetWidth: 20,
105
+ bgOffsetHeight: 10,
106
+ fontSize: 54,
107
+ },
108
+ },
109
+ };
110
+
111
+ export const DEFAULT_CAPTION_COLORS = {
112
+ text: "#000000",
113
+ background: "#FFFFFF",
114
+ };
115
+
116
+ export const DEFAULT_CAPTION_FONT = {
117
+ family: "Poppins",
118
+ size: 48,
119
+ weight: 400,
120
+ };
121
+
122
+ export const TRANSPARENT_COLOR = "#FFFFFF00";
123
+
124
+ export const ELEMENT_TYPES = {
125
+ VIDEO: "video",
126
+ IMAGE: "image",
127
+ AUDIO: "audio",
128
+ TEXT: "text",
129
+ CAPTION: "caption",
130
+ RECT: "rect",
131
+ CIRCLE: "circle",
132
+ ICON: "icon",
133
+ };
134
+
135
+ export const OBJECT_FIT = {
136
+ CONTAIN: "contain",
137
+ COVER: "cover",
138
+ FILL: "fill",
139
+ NONE: "none",
140
+ }
141
+
142
+ export const COLOR_FILTERS = {
143
+ SATURATED: "saturated",
144
+ BRIGHT: "bright",
145
+ VIBRANT: "vibrant",
146
+ RETRO: "retro",
147
+ BLACK_WHITE: "blackWhite",
148
+ SEPIA: "sepia",
149
+ COOL: "cool",
150
+ WARM: "warm",
151
+ CINEMATIC: "cinematic",
152
+ SOFT_GLOW: "softGlow",
153
+ MOODY: "moody",
154
+ DREAMY: "dreamy",
155
+ INVERTED: "inverted",
156
+ VINTAGE: "vintage",
157
+ DRAMATIC: "dramatic",
158
+ FADED: "faded",
159
+ }
160
+
161
+ export const EVENT_TYPES = {
162
+ PLAYER_UPDATE: "twick:playerUpdate",
159
163
  }