visualfries 0.1.902 → 0.1.1095
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/dist/SceneBuilder.svelte.js +19 -0
- package/dist/animations/builders/WordHighlighterAnimationBuilder.js +5 -0
- package/dist/builders/_ComponentState.svelte.js +4 -2
- package/dist/commands/SeekCommand.js +20 -0
- package/dist/components/ComponentContext.svelte.js +16 -1
- package/dist/components/ComponentContextHelpers.d.ts +115 -0
- package/dist/components/ComponentContextHelpers.js +196 -0
- package/dist/components/SafeHookRunner.d.ts +52 -0
- package/dist/components/SafeHookRunner.js +67 -0
- package/dist/components/hooks/HtmlToCanvasHook.js +24 -1
- package/dist/components/hooks/MediaHook.js +1 -1
- package/dist/components/hooks/PixiDisplayObjectHook.js +19 -3
- package/dist/components/hooks/PixiSplitScreenDisplayObjectHook.js +28 -10
- package/dist/components/hooks/PixiVideoTextureHook.js +41 -13
- package/dist/directors/ComponentDirector.js +1 -1
- package/dist/examples/01_basic_text.json +89 -0
- package/dist/examples/02_animated_text.json +110 -0
- package/dist/examples/03_video_background.json +94 -0
- package/dist/examples/04_real_subtitles.json +116 -0
- package/dist/examples/animated-shapes.json +148 -0
- package/dist/examples/gradient-background.json +105 -0
- package/dist/examples/karaoke-subtitles.json +97 -0
- package/dist/managers/SubtitlesManager.svelte.js +3 -1
- package/dist/schemas/runtime/types.d.ts +7 -0
- package/dist/utils/utils.js +22 -4
- package/package.json +1 -1
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "animated-shapes-example",
|
|
3
|
+
"version": "2.0",
|
|
4
|
+
"name": "Animated Shapes",
|
|
5
|
+
"settings": {
|
|
6
|
+
"width": 1080,
|
|
7
|
+
"height": 1920,
|
|
8
|
+
"duration": 3,
|
|
9
|
+
"fps": 30,
|
|
10
|
+
"backgroundColor": "#0a0a0a"
|
|
11
|
+
},
|
|
12
|
+
"assets": [],
|
|
13
|
+
"layers": [
|
|
14
|
+
{
|
|
15
|
+
"id": "layer-main",
|
|
16
|
+
"name": "Main Layer",
|
|
17
|
+
"order": 0,
|
|
18
|
+
"visible": true,
|
|
19
|
+
"muted": false,
|
|
20
|
+
"components": [
|
|
21
|
+
{
|
|
22
|
+
"id": "bg",
|
|
23
|
+
"name": "Background",
|
|
24
|
+
"type": "SHAPE",
|
|
25
|
+
"timeline": { "startAt": 0, "endAt": 3 },
|
|
26
|
+
"visible": true,
|
|
27
|
+
"order": 0,
|
|
28
|
+
"shape": { "type": "rectangle" },
|
|
29
|
+
"appearance": {
|
|
30
|
+
"x": 0,
|
|
31
|
+
"y": 0,
|
|
32
|
+
"width": 1080,
|
|
33
|
+
"height": 1920,
|
|
34
|
+
"opacity": 1,
|
|
35
|
+
"rotation": 0,
|
|
36
|
+
"scaleX": 1,
|
|
37
|
+
"scaleY": 1,
|
|
38
|
+
"color": "#0a0a0a"
|
|
39
|
+
},
|
|
40
|
+
"animations": { "enabled": true, "list": [] },
|
|
41
|
+
"effects": { "enabled": true, "map": {} }
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"id": "circle-1",
|
|
45
|
+
"name": "Circle",
|
|
46
|
+
"type": "SHAPE",
|
|
47
|
+
"timeline": { "startAt": 0, "endAt": 3 },
|
|
48
|
+
"visible": true,
|
|
49
|
+
"order": 1,
|
|
50
|
+
"shape": { "type": "circle" },
|
|
51
|
+
"appearance": {
|
|
52
|
+
"x": 290,
|
|
53
|
+
"y": 710,
|
|
54
|
+
"width": 500,
|
|
55
|
+
"height": 500,
|
|
56
|
+
"opacity": 1,
|
|
57
|
+
"rotation": 0,
|
|
58
|
+
"scaleX": 1,
|
|
59
|
+
"scaleY": 1,
|
|
60
|
+
"background": {
|
|
61
|
+
"colors": ["#f472b6", "#a855f7"],
|
|
62
|
+
"angle": 45
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
"animations": {
|
|
66
|
+
"enabled": true,
|
|
67
|
+
"list": [
|
|
68
|
+
{
|
|
69
|
+
"id": "circle-scale",
|
|
70
|
+
"name": "Pulse",
|
|
71
|
+
"animation": {
|
|
72
|
+
"id": "pulse",
|
|
73
|
+
"timeline": [
|
|
74
|
+
{
|
|
75
|
+
"tweens": [
|
|
76
|
+
{
|
|
77
|
+
"method": "from",
|
|
78
|
+
"vars": { "duration": 0.5, "scale": 0 }
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"method": "to",
|
|
82
|
+
"vars": { "duration": 0.5, "scale": 1.1 }
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
"method": "to",
|
|
86
|
+
"vars": { "duration": 0.3, "scale": 1 }
|
|
87
|
+
}
|
|
88
|
+
]
|
|
89
|
+
}
|
|
90
|
+
]
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
]
|
|
94
|
+
},
|
|
95
|
+
"effects": { "enabled": true, "map": {} }
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
"id": "star-1",
|
|
99
|
+
"name": "Star",
|
|
100
|
+
"type": "SHAPE",
|
|
101
|
+
"timeline": { "startAt": 0.5, "endAt": 3 },
|
|
102
|
+
"visible": true,
|
|
103
|
+
"order": 2,
|
|
104
|
+
"shape": { "type": "star" },
|
|
105
|
+
"appearance": {
|
|
106
|
+
"x": 640,
|
|
107
|
+
"y": 300,
|
|
108
|
+
"width": 300,
|
|
109
|
+
"height": 300,
|
|
110
|
+
"opacity": 1,
|
|
111
|
+
"rotation": 0,
|
|
112
|
+
"scaleX": 1,
|
|
113
|
+
"scaleY": 1,
|
|
114
|
+
"background": {
|
|
115
|
+
"colors": ["#fbbf24", "#f59e0b"],
|
|
116
|
+
"angle": 90
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
"animations": {
|
|
120
|
+
"enabled": true,
|
|
121
|
+
"list": [
|
|
122
|
+
{
|
|
123
|
+
"id": "star-spin",
|
|
124
|
+
"name": "Spin",
|
|
125
|
+
"animation": {
|
|
126
|
+
"id": "spin",
|
|
127
|
+
"timeline": [
|
|
128
|
+
{
|
|
129
|
+
"tweens": [
|
|
130
|
+
{
|
|
131
|
+
"method": "from",
|
|
132
|
+
"vars": { "duration": 0.6, "rotation": 180, "scale": 0 }
|
|
133
|
+
}
|
|
134
|
+
]
|
|
135
|
+
}
|
|
136
|
+
]
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
]
|
|
140
|
+
},
|
|
141
|
+
"effects": { "enabled": true, "map": {} }
|
|
142
|
+
}
|
|
143
|
+
]
|
|
144
|
+
}
|
|
145
|
+
],
|
|
146
|
+
"transitions": [],
|
|
147
|
+
"audioTracks": []
|
|
148
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "gradient-background-example",
|
|
3
|
+
"version": "2.0",
|
|
4
|
+
"name": "Gradient Background",
|
|
5
|
+
"settings": {
|
|
6
|
+
"width": 1080,
|
|
7
|
+
"height": 1920,
|
|
8
|
+
"duration": 5,
|
|
9
|
+
"fps": 30,
|
|
10
|
+
"backgroundColor": "#000000"
|
|
11
|
+
},
|
|
12
|
+
"assets": [],
|
|
13
|
+
"layers": [
|
|
14
|
+
{
|
|
15
|
+
"id": "layer-main",
|
|
16
|
+
"name": "Main Layer",
|
|
17
|
+
"order": 0,
|
|
18
|
+
"visible": true,
|
|
19
|
+
"muted": false,
|
|
20
|
+
"components": [
|
|
21
|
+
{
|
|
22
|
+
"id": "bg-gradient",
|
|
23
|
+
"name": "Background Gradient",
|
|
24
|
+
"type": "SHAPE",
|
|
25
|
+
"timeline": { "startAt": 0, "endAt": 5 },
|
|
26
|
+
"visible": true,
|
|
27
|
+
"order": 0,
|
|
28
|
+
"shape": { "type": "rectangle" },
|
|
29
|
+
"appearance": {
|
|
30
|
+
"x": 0,
|
|
31
|
+
"y": 0,
|
|
32
|
+
"width": 1080,
|
|
33
|
+
"height": 1920,
|
|
34
|
+
"opacity": 1,
|
|
35
|
+
"rotation": 0,
|
|
36
|
+
"scaleX": 1,
|
|
37
|
+
"scaleY": 1,
|
|
38
|
+
"background": {
|
|
39
|
+
"colors": ["#667eea", "#764ba2"],
|
|
40
|
+
"angle": 135
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
"animations": { "enabled": true, "list": [] },
|
|
44
|
+
"effects": { "enabled": true, "map": {} }
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"id": "title-text",
|
|
48
|
+
"name": "Title",
|
|
49
|
+
"type": "TEXT",
|
|
50
|
+
"text": "Hello World",
|
|
51
|
+
"timeline": { "startAt": 0, "endAt": 5 },
|
|
52
|
+
"visible": true,
|
|
53
|
+
"order": 1,
|
|
54
|
+
"appearance": {
|
|
55
|
+
"x": 0,
|
|
56
|
+
"y": 800,
|
|
57
|
+
"width": 1080,
|
|
58
|
+
"height": 300,
|
|
59
|
+
"opacity": 1,
|
|
60
|
+
"rotation": 0,
|
|
61
|
+
"scaleX": 1,
|
|
62
|
+
"scaleY": 1,
|
|
63
|
+
"horizontalAlign": "center",
|
|
64
|
+
"verticalAlign": "center",
|
|
65
|
+
"text": {
|
|
66
|
+
"fontFamily": "Inter",
|
|
67
|
+
"fontSize": 120,
|
|
68
|
+
"fontWeight": "900",
|
|
69
|
+
"lineHeight": { "value": 1.1, "unit": "em" },
|
|
70
|
+
"letterSpacing": { "value": -0.02, "unit": "em" },
|
|
71
|
+
"color": "#ffffff",
|
|
72
|
+
"textAlign": "center",
|
|
73
|
+
"textTransform": "uppercase"
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
"animations": {
|
|
77
|
+
"enabled": true,
|
|
78
|
+
"list": [
|
|
79
|
+
{
|
|
80
|
+
"id": "title-scale",
|
|
81
|
+
"name": "Scale In",
|
|
82
|
+
"animation": {
|
|
83
|
+
"id": "scale-in",
|
|
84
|
+
"timeline": [
|
|
85
|
+
{
|
|
86
|
+
"tweens": [
|
|
87
|
+
{
|
|
88
|
+
"method": "from",
|
|
89
|
+
"vars": { "duration": 0.6, "scale": 0.5, "opacity": 0 }
|
|
90
|
+
}
|
|
91
|
+
]
|
|
92
|
+
}
|
|
93
|
+
]
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
]
|
|
97
|
+
},
|
|
98
|
+
"effects": { "enabled": true, "map": {} }
|
|
99
|
+
}
|
|
100
|
+
]
|
|
101
|
+
}
|
|
102
|
+
],
|
|
103
|
+
"transitions": [],
|
|
104
|
+
"audioTracks": []
|
|
105
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "karaoke-subtitles-example",
|
|
3
|
+
"version": "2.0",
|
|
4
|
+
"name": "Karaoke Subtitles",
|
|
5
|
+
"settings": {
|
|
6
|
+
"width": 1080,
|
|
7
|
+
"height": 1920,
|
|
8
|
+
"duration": 4,
|
|
9
|
+
"fps": 30,
|
|
10
|
+
"backgroundColor": "#1a1a2e"
|
|
11
|
+
},
|
|
12
|
+
"assets": [],
|
|
13
|
+
"layers": [
|
|
14
|
+
{
|
|
15
|
+
"id": "layer-main",
|
|
16
|
+
"name": "Main Layer",
|
|
17
|
+
"order": 0,
|
|
18
|
+
"visible": true,
|
|
19
|
+
"muted": false,
|
|
20
|
+
"components": [
|
|
21
|
+
{
|
|
22
|
+
"id": "bg",
|
|
23
|
+
"name": "Background",
|
|
24
|
+
"type": "SHAPE",
|
|
25
|
+
"timeline": { "startAt": 0, "endAt": 4 },
|
|
26
|
+
"visible": true,
|
|
27
|
+
"order": 0,
|
|
28
|
+
"shape": { "type": "rectangle" },
|
|
29
|
+
"appearance": {
|
|
30
|
+
"x": 0,
|
|
31
|
+
"y": 0,
|
|
32
|
+
"width": 1080,
|
|
33
|
+
"height": 1920,
|
|
34
|
+
"opacity": 1,
|
|
35
|
+
"rotation": 0,
|
|
36
|
+
"scaleX": 1,
|
|
37
|
+
"scaleY": 1,
|
|
38
|
+
"background": {
|
|
39
|
+
"colors": ["#0f0f23", "#1a1a3e"],
|
|
40
|
+
"angle": 180
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
"animations": { "enabled": true, "list": [] },
|
|
44
|
+
"effects": { "enabled": true, "map": {} }
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"id": "subtitle-karaoke",
|
|
48
|
+
"name": "Karaoke Text",
|
|
49
|
+
"type": "TEXT",
|
|
50
|
+
"text": "Create stunning videos",
|
|
51
|
+
"timeline": { "startAt": 0, "endAt": 4 },
|
|
52
|
+
"visible": true,
|
|
53
|
+
"order": 1,
|
|
54
|
+
"appearance": {
|
|
55
|
+
"x": 0,
|
|
56
|
+
"y": 850,
|
|
57
|
+
"width": 1080,
|
|
58
|
+
"height": 200,
|
|
59
|
+
"opacity": 1,
|
|
60
|
+
"rotation": 0,
|
|
61
|
+
"scaleX": 1,
|
|
62
|
+
"scaleY": 1,
|
|
63
|
+
"horizontalAlign": "center",
|
|
64
|
+
"verticalAlign": "center",
|
|
65
|
+
"text": {
|
|
66
|
+
"fontFamily": "Montserrat",
|
|
67
|
+
"fontSize": 90,
|
|
68
|
+
"fontWeight": "900",
|
|
69
|
+
"lineHeight": { "value": 1.2, "unit": "em" },
|
|
70
|
+
"color": "rgba(255,255,255,0.4)",
|
|
71
|
+
"textAlign": "center",
|
|
72
|
+
"textTransform": "uppercase",
|
|
73
|
+
"activeWord": {
|
|
74
|
+
"enabled": true,
|
|
75
|
+
"color": "#ffd700",
|
|
76
|
+
"scale": 1.3
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
"animations": {
|
|
81
|
+
"enabled": true,
|
|
82
|
+
"list": [
|
|
83
|
+
{
|
|
84
|
+
"id": "words-anim",
|
|
85
|
+
"name": "Words Highlight",
|
|
86
|
+
"animation": "cf-words-highlight"
|
|
87
|
+
}
|
|
88
|
+
]
|
|
89
|
+
},
|
|
90
|
+
"effects": { "enabled": true, "map": {} }
|
|
91
|
+
}
|
|
92
|
+
]
|
|
93
|
+
}
|
|
94
|
+
],
|
|
95
|
+
"transitions": [],
|
|
96
|
+
"audioTracks": []
|
|
97
|
+
}
|
|
@@ -208,7 +208,9 @@ function buildSubtitlesManager(timeManager, eventManager, sceneData, subtitles)
|
|
|
208
208
|
for (const [lang, langIndex] of Object.entries(assetIndex)) {
|
|
209
209
|
for (const [subtitleId, subtitle] of Object.entries(langIndex)) {
|
|
210
210
|
const text = subtitle.text;
|
|
211
|
-
|
|
211
|
+
// Use Array.from to properly handle multi-codepoint characters (emojis, etc.)
|
|
212
|
+
// This prevents splitting emojis into unpaired surrogates that cause encodeURIComponent to fail
|
|
213
|
+
const characters = Array.from(text);
|
|
212
214
|
if (characters && characters.length > 0) {
|
|
213
215
|
for (const char of characters) {
|
|
214
216
|
if (!charactersList.includes(char)) {
|
|
@@ -37,6 +37,13 @@ export interface LayerEvents {
|
|
|
37
37
|
export interface ComponentEvents {
|
|
38
38
|
componentschange: void;
|
|
39
39
|
componentchange: ComponentData;
|
|
40
|
+
hookerror: {
|
|
41
|
+
hookName: string;
|
|
42
|
+
hookType: string;
|
|
43
|
+
error: Error;
|
|
44
|
+
componentId: string;
|
|
45
|
+
timestamp: number;
|
|
46
|
+
};
|
|
40
47
|
}
|
|
41
48
|
export interface SubtitlesEvents {
|
|
42
49
|
subtitleschange: void;
|
package/dist/utils/utils.js
CHANGED
|
@@ -19,6 +19,19 @@ export function changeIdDeep(obj) {
|
|
|
19
19
|
}
|
|
20
20
|
return obj;
|
|
21
21
|
}
|
|
22
|
+
/**
|
|
23
|
+
* Checks if a character is an emoji.
|
|
24
|
+
* Preserves all legitimate Unicode letters and numbers (Chinese, Japanese, Korean, Arabic, etc.).
|
|
25
|
+
*/
|
|
26
|
+
function isEmoji(char) {
|
|
27
|
+
// If it's a legitimate Unicode letter or number, it's NOT an emoji
|
|
28
|
+
// This includes Chinese, Japanese, Korean, Arabic, and all other writing systems
|
|
29
|
+
if (/\p{L}|\p{N}/u.test(char)) {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
// Use Unicode emoji property - automatically maintained by the Unicode standard
|
|
33
|
+
return /\p{Emoji}/u.test(char);
|
|
34
|
+
}
|
|
22
35
|
export const buildCharactersListFromComponentsAndSubtitles = function (layers, subtitlesCharactersList) {
|
|
23
36
|
const characters = ' ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.-,;:!$?\'"';
|
|
24
37
|
const charactestList = characters.split('');
|
|
@@ -28,11 +41,16 @@ export const buildCharactersListFromComponentsAndSubtitles = function (layers, s
|
|
|
28
41
|
const c = component;
|
|
29
42
|
const text = c.text;
|
|
30
43
|
if (text) {
|
|
31
|
-
|
|
44
|
+
// Use Array.from to properly handle multi-codepoint characters (emojis, etc.)
|
|
45
|
+
// This prevents splitting emojis into unpaired surrogates
|
|
46
|
+
const textList = Array.from(text);
|
|
32
47
|
const missingChars = textList.filter((char) => {
|
|
33
48
|
// Check if the character is not whitespace, not in the characters list,
|
|
34
|
-
//
|
|
35
|
-
return !/\s/.test(char) &&
|
|
49
|
+
// is a Unicode letter or number, and is NOT an emoji
|
|
50
|
+
return (!/\s/.test(char) &&
|
|
51
|
+
!characters.includes(char) &&
|
|
52
|
+
/\p{L}|\p{N}/u.test(char) &&
|
|
53
|
+
!isEmoji(char));
|
|
36
54
|
});
|
|
37
55
|
// Add both uppercase and lowercase variants of missing chars
|
|
38
56
|
const variantChars = missingChars.flatMap((char) => [
|
|
@@ -44,7 +62,7 @@ export const buildCharactersListFromComponentsAndSubtitles = function (layers, s
|
|
|
44
62
|
}
|
|
45
63
|
if (subtitlesCharactersList.length > 0) {
|
|
46
64
|
for (const char of subtitlesCharactersList) {
|
|
47
|
-
if (!characters.includes(char)) {
|
|
65
|
+
if (!characters.includes(char) && !isEmoji(char)) {
|
|
48
66
|
// Add both uppercase and lowercase variants of missing chars
|
|
49
67
|
charactestList.push(char.toLowerCase(), char.toUpperCase());
|
|
50
68
|
}
|