visualfries 0.1.0
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/LICENSE +21 -0
- package/README.md +213 -0
- package/dist/DIContainer.d.ts +4 -0
- package/dist/DIContainer.js +145 -0
- package/dist/SceneBuilder.svelte.d.ts +8574 -0
- package/dist/SceneBuilder.svelte.js +409 -0
- package/dist/adapters/subtitleHelpers.d.ts +2 -0
- package/dist/adapters/subtitleHelpers.js +187 -0
- package/dist/animations/AnimationContext.d.ts +17 -0
- package/dist/animations/AnimationContext.js +72 -0
- package/dist/animations/AnimationPresetsRegister.d.ts +362 -0
- package/dist/animations/AnimationPresetsRegister.js +20 -0
- package/dist/animations/AnimationSetup.d.ts +8 -0
- package/dist/animations/AnimationSetup.js +30 -0
- package/dist/animations/SplitTextCache.d.ts +28 -0
- package/dist/animations/SplitTextCache.js +68 -0
- package/dist/animations/animationBuilder.d.ts +31 -0
- package/dist/animations/animationBuilder.js +255 -0
- package/dist/animations/animationPreset.d.ts +7 -0
- package/dist/animations/animationPreset.js +31 -0
- package/dist/animations/builders/AnimationPresetFactory.d.ts +43 -0
- package/dist/animations/builders/AnimationPresetFactory.js +139 -0
- package/dist/animations/builders/LineHighlighterAnimationBuilder.d.ts +16 -0
- package/dist/animations/builders/LineHighlighterAnimationBuilder.js +183 -0
- package/dist/animations/builders/WordHighlighterAnimationBuilder.d.ts +15 -0
- package/dist/animations/builders/WordHighlighterAnimationBuilder.js +180 -0
- package/dist/animations/engines/AnimationEngineAdaptor.d.ts +107 -0
- package/dist/animations/engines/AnimationEngineAdaptor.js +1 -0
- package/dist/animations/engines/GSAPEngineAdaptor.d.ts +21 -0
- package/dist/animations/engines/GSAPEngineAdaptor.js +145 -0
- package/dist/animations/presets/index.d.ts +2 -0
- package/dist/animations/presets/index.js +3 -0
- package/dist/animations/presets/lines.d.ts +52 -0
- package/dist/animations/presets/lines.js +547 -0
- package/dist/animations/presets/words.d.ts +31 -0
- package/dist/animations/presets/words.js +268 -0
- package/dist/animations/transformers/AnimationReferenceTransformer.d.ts +9 -0
- package/dist/animations/transformers/AnimationReferenceTransformer.js +114 -0
- package/dist/builders/PixiComponentBuilder.d.ts +63 -0
- package/dist/builders/PixiComponentBuilder.js +112 -0
- package/dist/builders/_ComponentState.svelte.d.ts +795 -0
- package/dist/builders/_ComponentState.svelte.js +203 -0
- package/dist/builders/html/HtmlBuilder.d.ts +66 -0
- package/dist/builders/html/HtmlBuilder.js +171 -0
- package/dist/builders/html/HtmlBuilderFactory.d.ts +27 -0
- package/dist/builders/html/HtmlBuilderFactory.js +30 -0
- package/dist/builders/html/StyleBuilder.d.ts +13 -0
- package/dist/builders/html/StyleBuilder.js +133 -0
- package/dist/builders/html/StyleProcessor.d.ts +9 -0
- package/dist/builders/html/StyleProcessor.js +1 -0
- package/dist/builders/html/TextComponentHtmlBuilder.d.ts +16 -0
- package/dist/builders/html/TextComponentHtmlBuilder.js +93 -0
- package/dist/builders/html/TextShadowBuilder.d.ts +60 -0
- package/dist/builders/html/TextShadowBuilder.js +227 -0
- package/dist/builders/html/processors/AppearanceStyleProcessor.d.ts +5 -0
- package/dist/builders/html/processors/AppearanceStyleProcessor.js +57 -0
- package/dist/builders/html/processors/TextAppearanceStyleProcessor.d.ts +5 -0
- package/dist/builders/html/processors/TextAppearanceStyleProcessor.js +37 -0
- package/dist/builders/html/processors/TextEffectsStyleProcessor.d.ts +6 -0
- package/dist/builders/html/processors/TextEffectsStyleProcessor.js +68 -0
- package/dist/commands/Command.d.ts +6 -0
- package/dist/commands/Command.js +1 -0
- package/dist/commands/CommandRunner.d.ts +28 -0
- package/dist/commands/CommandRunner.js +81 -0
- package/dist/commands/CommandTypes.d.ts +11 -0
- package/dist/commands/CommandTypes.js +13 -0
- package/dist/commands/PauseCommand.d.ts +4 -0
- package/dist/commands/PauseCommand.js +5 -0
- package/dist/commands/PlayCommand.d.ts +4 -0
- package/dist/commands/PlayCommand.js +6 -0
- package/dist/commands/RenderCommand.d.ts +15 -0
- package/dist/commands/RenderCommand.js +18 -0
- package/dist/commands/RenderFrameCommand.d.ts +17 -0
- package/dist/commands/RenderFrameCommand.js +93 -0
- package/dist/commands/ReplaceSourceOnTimeCommand.d.ts +4 -0
- package/dist/commands/ReplaceSourceOnTimeCommand.js +22 -0
- package/dist/commands/SeekCommand.d.ts +15 -0
- package/dist/commands/SeekCommand.js +39 -0
- package/dist/commands/UpdateComponentCommand.d.ts +4 -0
- package/dist/commands/UpdateComponentCommand.js +17 -0
- package/dist/components/AnimatedGIF.d.ts +201 -0
- package/dist/components/AnimatedGIF.js +391 -0
- package/dist/components/Component.svelte.d.ts +33 -0
- package/dist/components/Component.svelte.js +152 -0
- package/dist/components/ComponentContext.svelte.d.ts +33 -0
- package/dist/components/ComponentContext.svelte.js +105 -0
- package/dist/components/hooks/AnimationHook.d.ts +25 -0
- package/dist/components/hooks/AnimationHook.js +180 -0
- package/dist/components/hooks/CanvasShapeHook.d.ts +12 -0
- package/dist/components/hooks/CanvasShapeHook.js +229 -0
- package/dist/components/hooks/HtmlAnimationHook.d.ts +8 -0
- package/dist/components/hooks/HtmlAnimationHook.js +70 -0
- package/dist/components/hooks/HtmlTextHook.d.ts +16 -0
- package/dist/components/hooks/HtmlTextHook.js +102 -0
- package/dist/components/hooks/HtmlToCanvasHook.d.ts +16 -0
- package/dist/components/hooks/HtmlToCanvasHook.js +148 -0
- package/dist/components/hooks/ImageHook.d.ts +10 -0
- package/dist/components/hooks/ImageHook.js +45 -0
- package/dist/components/hooks/MediaHook.d.ts +15 -0
- package/dist/components/hooks/MediaHook.js +252 -0
- package/dist/components/hooks/MediaSeekingHook.d.ts +12 -0
- package/dist/components/hooks/MediaSeekingHook.js +204 -0
- package/dist/components/hooks/PixiDisplayObjectHook.d.ts +15 -0
- package/dist/components/hooks/PixiDisplayObjectHook.js +77 -0
- package/dist/components/hooks/PixiGifHook.d.ts +15 -0
- package/dist/components/hooks/PixiGifHook.js +97 -0
- package/dist/components/hooks/PixiProgressShapeHook.d.ts +12 -0
- package/dist/components/hooks/PixiProgressShapeHook.js +128 -0
- package/dist/components/hooks/PixiSplitScreenDisplayObjectHook.d.ts +21 -0
- package/dist/components/hooks/PixiSplitScreenDisplayObjectHook.js +210 -0
- package/dist/components/hooks/PixiTextureHook.d.ts +7 -0
- package/dist/components/hooks/PixiTextureHook.js +29 -0
- package/dist/components/hooks/PixiVideoTextureHook.d.ts +10 -0
- package/dist/components/hooks/PixiVideoTextureHook.js +35 -0
- package/dist/components/hooks/SubtitlesHook.d.ts +88 -0
- package/dist/components/hooks/SubtitlesHook.js +199 -0
- package/dist/components/hooks/VerifyGifHook.d.ts +7 -0
- package/dist/components/hooks/VerifyGifHook.js +27 -0
- package/dist/components/hooks/VerifyImageHook.d.ts +7 -0
- package/dist/components/hooks/VerifyImageHook.js +27 -0
- package/dist/components/hooks/VerifyMediaHook.d.ts +7 -0
- package/dist/components/hooks/VerifyMediaHook.js +21 -0
- package/dist/components/hooks/shapes/progress/CustomProgressRenderer.d.ts +8 -0
- package/dist/components/hooks/shapes/progress/CustomProgressRenderer.js +53 -0
- package/dist/components/hooks/shapes/progress/DoubleProgressRenderer.d.ts +8 -0
- package/dist/components/hooks/shapes/progress/DoubleProgressRenderer.js +69 -0
- package/dist/components/hooks/shapes/progress/LinearProgressRenderer.d.ts +8 -0
- package/dist/components/hooks/shapes/progress/LinearProgressRenderer.js +60 -0
- package/dist/components/hooks/shapes/progress/PerimeterProgressRenderer.d.ts +9 -0
- package/dist/components/hooks/shapes/progress/PerimeterProgressRenderer.js +213 -0
- package/dist/components/hooks/shapes/progress/ProgressRenderer.d.ts +17 -0
- package/dist/components/hooks/shapes/progress/ProgressRenderer.js +75 -0
- package/dist/components/hooks/shapes/progress/RadialProgressRenderer.d.ts +8 -0
- package/dist/components/hooks/shapes/progress/RadialProgressRenderer.js +50 -0
- package/dist/components/hooks/shapes/progress/index.d.ts +6 -0
- package/dist/components/hooks/shapes/progress/index.js +6 -0
- package/dist/composers/componentComposer.d.ts +55 -0
- package/dist/composers/componentComposer.js +118 -0
- package/dist/composers/layerComposer.d.ts +46 -0
- package/dist/composers/layerComposer.js +79 -0
- package/dist/composers/sceneComposer.d.ts +48 -0
- package/dist/composers/sceneComposer.js +92 -0
- package/dist/constants.d.ts +12 -0
- package/dist/constants.js +14 -0
- package/dist/directors/ComponentDirector.d.ts +20 -0
- package/dist/directors/ComponentDirector.js +86 -0
- package/dist/factories/SceneBuilderFactory.d.ts +15 -0
- package/dist/factories/SceneBuilderFactory.js +51 -0
- package/dist/fonts/GoogleFontsProvider.d.ts +12 -0
- package/dist/fonts/GoogleFontsProvider.js +125 -0
- package/dist/fonts/fontLoader.d.ts +15 -0
- package/dist/fonts/fontLoader.js +41 -0
- package/dist/fonts/types.d.ts +1 -0
- package/dist/fonts/types.js +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +14 -0
- package/dist/layers/Layer.svelte.d.ts +8492 -0
- package/dist/layers/Layer.svelte.js +125 -0
- package/dist/managers/AppManager.svelte.d.ts +23 -0
- package/dist/managers/AppManager.svelte.js +89 -0
- package/dist/managers/ComponentsManager.svelte.d.ts +49 -0
- package/dist/managers/ComponentsManager.svelte.js +247 -0
- package/dist/managers/DomManager.d.ts +18 -0
- package/dist/managers/DomManager.js +73 -0
- package/dist/managers/EventManager.d.ts +7 -0
- package/dist/managers/EventManager.js +22 -0
- package/dist/managers/LayersManager.svelte.d.ts +8499 -0
- package/dist/managers/LayersManager.svelte.js +176 -0
- package/dist/managers/MediaManager.d.ts +32 -0
- package/dist/managers/MediaManager.js +243 -0
- package/dist/managers/RenderManager.d.ts +23 -0
- package/dist/managers/RenderManager.js +59 -0
- package/dist/managers/StateManager.svelte.d.ts +8746 -0
- package/dist/managers/StateManager.svelte.js +272 -0
- package/dist/managers/SubtitlesManager.svelte.d.ts +261 -0
- package/dist/managers/SubtitlesManager.svelte.js +1385 -0
- package/dist/managers/TimeManager.svelte.d.ts +6 -0
- package/dist/managers/TimeManager.svelte.js +18 -0
- package/dist/managers/TimelineManager.svelte.d.ts +25 -0
- package/dist/managers/TimelineManager.svelte.js +152 -0
- package/dist/registers.d.ts +12 -0
- package/dist/registers.js +29 -0
- package/dist/schemas/runtime/index.d.ts +3 -0
- package/dist/schemas/runtime/index.js +4 -0
- package/dist/schemas/runtime/types.d.ts +323 -0
- package/dist/schemas/runtime/types.js +12 -0
- package/dist/schemas/scene/animations.d.ts +89738 -0
- package/dist/schemas/scene/animations.js +211 -0
- package/dist/schemas/scene/components.js +515 -0
- package/dist/schemas/scene/core.js +160 -0
- package/dist/schemas/scene/index.d.ts +22 -0
- package/dist/schemas/scene/index.js +10 -0
- package/dist/schemas/scene/properties.d.ts +914 -0
- package/dist/schemas/scene/properties.js +398 -0
- package/dist/schemas/scene/subtitles.d.ts +1141 -0
- package/dist/schemas/scene/subtitles.js +111 -0
- package/dist/schemas/scene/utils.d.ts +1 -0
- package/dist/schemas/scene/utils.js +5 -0
- package/dist/seeds/SeedFactory.d.ts +59 -0
- package/dist/seeds/SeedFactory.js +99 -0
- package/dist/seeds/index.d.ts +8 -0
- package/dist/seeds/index.js +8 -0
- package/dist/transformers/ColorTransformer.d.ts +5 -0
- package/dist/transformers/ColorTransformer.js +67 -0
- package/dist/transformers/PixiColorTransformer.d.ts +22 -0
- package/dist/transformers/PixiColorTransformer.js +104 -0
- package/dist/utils/canvas.d.ts +6 -0
- package/dist/utils/canvas.js +18 -0
- package/dist/utils/document.d.ts +2 -0
- package/dist/utils/document.js +36 -0
- package/dist/utils/emoji.d.ts +10 -0
- package/dist/utils/emoji.js +51 -0
- package/dist/utils/html.d.ts +4 -0
- package/dist/utils/html.js +45 -0
- package/dist/utils/svgGenerator.d.ts +20 -0
- package/dist/utils/svgGenerator.js +103 -0
- package/dist/utils/utils.d.ts +5 -0
- package/dist/utils/utils.js +125 -0
- package/package.json +96 -0
|
@@ -0,0 +1,515 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { isValidColor } from './utils.js';
|
|
3
|
+
import { EffectBaseShape, EffectShape as BaseEffectShape, BlurEffectShape, ShadowShape as StructuredShadowShape, OutlineShape as StructuredOutlineShape, ColorTypeShape, GradientDefinitionShape } from './properties.js';
|
|
4
|
+
import { AnimationPresetShape, AnimationReferenceShape } from './animations.js';
|
|
5
|
+
// Utility functions
|
|
6
|
+
const toFixed3 = (val) => parseFloat(val.toFixed(3));
|
|
7
|
+
const toFixed3Optional = (val) => {
|
|
8
|
+
if (val === undefined || val === null)
|
|
9
|
+
return val;
|
|
10
|
+
return parseFloat(val.toFixed(3));
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Structured Font Size as per schema-llm.md
|
|
14
|
+
*/
|
|
15
|
+
export const StructuredFontSizeShape = z.union([
|
|
16
|
+
z
|
|
17
|
+
.number()
|
|
18
|
+
.positive()
|
|
19
|
+
.transform((val) => ({ value: val, unit: 'px' })),
|
|
20
|
+
z.object({
|
|
21
|
+
value: z.number().positive(),
|
|
22
|
+
unit: z.enum(['px', 'em', 'rem', '%']).default('px')
|
|
23
|
+
})
|
|
24
|
+
]);
|
|
25
|
+
export const StructuredEmSizeShape = z.union([
|
|
26
|
+
z.number().transform((val) => ({ value: val, unit: 'em' })),
|
|
27
|
+
z.object({
|
|
28
|
+
value: z.number(),
|
|
29
|
+
unit: z.enum(['px', 'em', 'rem', '%']).default('em')
|
|
30
|
+
})
|
|
31
|
+
]);
|
|
32
|
+
const FontWeightShape = z.enum([
|
|
33
|
+
'normal',
|
|
34
|
+
'bold',
|
|
35
|
+
'bolder',
|
|
36
|
+
'lighter',
|
|
37
|
+
'100',
|
|
38
|
+
'200',
|
|
39
|
+
'300',
|
|
40
|
+
'400',
|
|
41
|
+
'500',
|
|
42
|
+
'600',
|
|
43
|
+
'700',
|
|
44
|
+
'800',
|
|
45
|
+
'900'
|
|
46
|
+
]);
|
|
47
|
+
export const FontSourceShape = z.object({
|
|
48
|
+
id: z.string().optional(),
|
|
49
|
+
source: z.enum(['google', 'custom']),
|
|
50
|
+
family: z.string().optional(),
|
|
51
|
+
category: z.string().optional().nullable(),
|
|
52
|
+
subsets: z.array(z.string()).optional().nullable(),
|
|
53
|
+
variants: z.array(z.string()).optional().nullable(),
|
|
54
|
+
fileUrl: z.string().optional().nullable()
|
|
55
|
+
});
|
|
56
|
+
/**
|
|
57
|
+
* Basic appearance structure for text components matching schema-llm.md
|
|
58
|
+
*/
|
|
59
|
+
export const TextAppearanceShape = z.object({
|
|
60
|
+
fontFamily: z.string().max(255),
|
|
61
|
+
fontSize: StructuredFontSizeShape,
|
|
62
|
+
fontWeight: FontWeightShape.nullable().optional(),
|
|
63
|
+
fontSource: FontSourceShape.nullable().optional(),
|
|
64
|
+
lineHeight: StructuredEmSizeShape.nullable().optional(),
|
|
65
|
+
letterSpacing: StructuredEmSizeShape.nullable().optional(),
|
|
66
|
+
color: ColorTypeShape,
|
|
67
|
+
textAlign: z.enum(['left', 'center', 'right', 'justify']),
|
|
68
|
+
textTransform: z.enum(['none', 'uppercase', 'lowercase', 'capitalize']).optional(),
|
|
69
|
+
shadow: StructuredShadowShape.nullable().optional(),
|
|
70
|
+
outline: StructuredOutlineShape.nullable().optional(),
|
|
71
|
+
activeLine: z
|
|
72
|
+
.object({
|
|
73
|
+
enabled: z.boolean(),
|
|
74
|
+
color: ColorTypeShape.nullable().optional(),
|
|
75
|
+
backgroundColor: ColorTypeShape.nullable().optional(),
|
|
76
|
+
fontWeight: FontWeightShape.optional(),
|
|
77
|
+
scale: z.number().positive().optional(),
|
|
78
|
+
backgroundPaddingX: z.number().min(0).optional(),
|
|
79
|
+
backgroundPaddingY: z.number().min(0).optional(),
|
|
80
|
+
backgroundBorderRadius: z.number().min(0).optional()
|
|
81
|
+
})
|
|
82
|
+
.nullable()
|
|
83
|
+
.optional(),
|
|
84
|
+
activeWord: z
|
|
85
|
+
.object({
|
|
86
|
+
enabled: z.boolean(),
|
|
87
|
+
color: ColorTypeShape.nullable().optional(),
|
|
88
|
+
backgroundColor: ColorTypeShape.nullable().optional(),
|
|
89
|
+
fontWeight: FontWeightShape.optional(),
|
|
90
|
+
scale: z.number().positive().optional(),
|
|
91
|
+
backgroundPaddingX: z.number().min(0).optional(),
|
|
92
|
+
backgroundPaddingY: z.number().min(0).optional(),
|
|
93
|
+
backgroundBorderRadius: z.number().min(0).optional()
|
|
94
|
+
})
|
|
95
|
+
.nullable()
|
|
96
|
+
.optional(),
|
|
97
|
+
highlightColors: z.array(ColorTypeShape).nullable().optional()
|
|
98
|
+
});
|
|
99
|
+
const BgShape = z.object({
|
|
100
|
+
enabled: z.boolean().default(false),
|
|
101
|
+
color: ColorTypeShape,
|
|
102
|
+
target: z.enum(['wrapper', 'element']).default('wrapper').optional(),
|
|
103
|
+
radius: z.number().min(0).default(0).optional()
|
|
104
|
+
});
|
|
105
|
+
export const BackgroundShape = z.union([BgShape, ColorTypeShape]).transform((value) => {
|
|
106
|
+
if (typeof value === 'object' && value !== null && 'enabled' in value) {
|
|
107
|
+
return value;
|
|
108
|
+
}
|
|
109
|
+
return {
|
|
110
|
+
enabled: true,
|
|
111
|
+
color: value,
|
|
112
|
+
target: 'wrapper',
|
|
113
|
+
radius: 0
|
|
114
|
+
};
|
|
115
|
+
});
|
|
116
|
+
/**
|
|
117
|
+
* General appearance schema for all components
|
|
118
|
+
*/
|
|
119
|
+
export const AppearanceShape = z.object({
|
|
120
|
+
x: z.number(),
|
|
121
|
+
y: z.number(),
|
|
122
|
+
width: z.number().positive(),
|
|
123
|
+
height: z.number().positive(),
|
|
124
|
+
offsetX: z.number().optional(), // 0 = left, 132 = 132px from left
|
|
125
|
+
offsetY: z.number().optional(), // 0 = top, 132 = 132px from top
|
|
126
|
+
opacity: z.number().min(0).max(1).default(1).optional(),
|
|
127
|
+
rotation: z.number().default(0).optional(),
|
|
128
|
+
scaleX: z.number().default(1).optional(),
|
|
129
|
+
scaleY: z.number().default(1).optional(),
|
|
130
|
+
background: BackgroundShape.nullable().default(null).optional(), // ColorTypeShape
|
|
131
|
+
// Text-specific appearance properties
|
|
132
|
+
text: TextAppearanceShape.optional(),
|
|
133
|
+
// Optional alignment properties
|
|
134
|
+
verticalAlign: z.enum(['top', 'center', 'bottom']).optional(),
|
|
135
|
+
horizontalAlign: z.enum(['left', 'center', 'right']).optional(),
|
|
136
|
+
// not optimal but to prevent linter errors. This is for subtitles only
|
|
137
|
+
backgroundAlwaysVisible: z.boolean().default(false).optional()
|
|
138
|
+
});
|
|
139
|
+
/**
|
|
140
|
+
* Timeline structure for components
|
|
141
|
+
*/
|
|
142
|
+
export const ComponentTimelineShape = z.object({
|
|
143
|
+
startAt: z.number().min(0).transform(toFixed3),
|
|
144
|
+
endAt: z.number().min(0).transform(toFixed3)
|
|
145
|
+
});
|
|
146
|
+
/**
|
|
147
|
+
* Animation structure
|
|
148
|
+
*/
|
|
149
|
+
export const AnimationShape = z.object({
|
|
150
|
+
id: z.string(),
|
|
151
|
+
name: z.string(),
|
|
152
|
+
startAt: z.number().min(0).optional(),
|
|
153
|
+
animation: AnimationReferenceShape,
|
|
154
|
+
enabled: z.boolean().default(true).optional()
|
|
155
|
+
});
|
|
156
|
+
/**
|
|
157
|
+
* Source metadata for media components
|
|
158
|
+
*/
|
|
159
|
+
export const SourceMetadataShape = z.object({
|
|
160
|
+
width: z.number().positive().optional(),
|
|
161
|
+
height: z.number().positive().optional(),
|
|
162
|
+
duration: z.number().min(0).optional(),
|
|
163
|
+
format: z.string().optional(),
|
|
164
|
+
codec: z.string().optional(),
|
|
165
|
+
bitrate: z.number().positive().optional(),
|
|
166
|
+
fps: z.number().positive().optional(),
|
|
167
|
+
hasAudio: z.boolean().optional()
|
|
168
|
+
});
|
|
169
|
+
/**
|
|
170
|
+
* Component source definition
|
|
171
|
+
*/
|
|
172
|
+
export const ComponentSourceShape = z.object({
|
|
173
|
+
url: z.string().url().optional(), // might have assetId. However should be required for video and other components
|
|
174
|
+
streamUrl: z.string().url().optional(),
|
|
175
|
+
assetId: z.string().optional(),
|
|
176
|
+
languageCode: z.string().optional(),
|
|
177
|
+
startAt: z.number().min(0).optional().transform(toFixed3Optional),
|
|
178
|
+
endAt: z.number().min(0).optional().transform(toFixed3Optional),
|
|
179
|
+
metadata: SourceMetadataShape.optional(),
|
|
180
|
+
transcriptFormat: z.string().optional()
|
|
181
|
+
});
|
|
182
|
+
/**
|
|
183
|
+
* Timing anchor for components that need synchronization (like subtitles)
|
|
184
|
+
*/
|
|
185
|
+
export const TimingAnchorShape = z.object({
|
|
186
|
+
mode: z.enum(['ASSET_USAGE', 'COMPONENT']),
|
|
187
|
+
assetId: z.string().optional(),
|
|
188
|
+
layerId: z.string().optional(),
|
|
189
|
+
componentId: z.string().optional(),
|
|
190
|
+
offset: z.number().default(0)
|
|
191
|
+
});
|
|
192
|
+
/**
|
|
193
|
+
* Layout split effect schema
|
|
194
|
+
*/
|
|
195
|
+
export const LayoutSplitEffectShape = EffectBaseShape.extend({
|
|
196
|
+
type: z.literal('layoutSplit'),
|
|
197
|
+
pieces: z.number().int().positive().optional(),
|
|
198
|
+
sceneWidth: z.number().positive().optional(),
|
|
199
|
+
sceneHeight: z.number().positive().optional(),
|
|
200
|
+
chunks: z.array(z.record(z.any())).optional()
|
|
201
|
+
});
|
|
202
|
+
/**
|
|
203
|
+
* Rotation randomizer effect schema
|
|
204
|
+
*/
|
|
205
|
+
export const RotationRandomizerEffectShape = EffectBaseShape.extend({
|
|
206
|
+
type: z.literal('rotationRandomizer'),
|
|
207
|
+
maxRotation: z.number().default(2),
|
|
208
|
+
animate: z.boolean().default(true),
|
|
209
|
+
seed: z.number().int().optional()
|
|
210
|
+
});
|
|
211
|
+
export const FillBackgroundBlurEffectShape = z.object({
|
|
212
|
+
type: z.literal('fillBackgroundBlur'),
|
|
213
|
+
enabled: z.boolean().default(true),
|
|
214
|
+
// Using the hardcoded value from PixiSplitScreenDisplayObjectHook.ts as default
|
|
215
|
+
blurAmount: z.number().min(0).default(50)
|
|
216
|
+
// Note: intensity and blendMode might not be applicable here, keeping it simple.
|
|
217
|
+
});
|
|
218
|
+
/**
|
|
219
|
+
* Text Shadow effect schema
|
|
220
|
+
*/
|
|
221
|
+
export const TextShadowEffectShape = EffectBaseShape.extend({
|
|
222
|
+
type: z.literal('textShadow'),
|
|
223
|
+
// Use the imported StructuredShadowShape for parameters
|
|
224
|
+
...StructuredShadowShape.shape
|
|
225
|
+
});
|
|
226
|
+
/**
|
|
227
|
+
* Text Outline effect schema
|
|
228
|
+
*/
|
|
229
|
+
export const TextOutlineEffectShape = EffectBaseShape.extend({
|
|
230
|
+
type: z.literal('textOutline'),
|
|
231
|
+
// Use the imported StructuredOutlineShape for parameters
|
|
232
|
+
...StructuredOutlineShape.shape
|
|
233
|
+
});
|
|
234
|
+
/**
|
|
235
|
+
* Union of all effect types for components
|
|
236
|
+
*/
|
|
237
|
+
export const ComponentEffectShape = z.union([
|
|
238
|
+
BaseEffectShape,
|
|
239
|
+
LayoutSplitEffectShape,
|
|
240
|
+
RotationRandomizerEffectShape,
|
|
241
|
+
BlurEffectShape,
|
|
242
|
+
FillBackgroundBlurEffectShape,
|
|
243
|
+
TextShadowEffectShape,
|
|
244
|
+
TextOutlineEffectShape
|
|
245
|
+
]);
|
|
246
|
+
const ComponentEffectsShape = z.object({
|
|
247
|
+
enabled: z.boolean().optional().default(true), // Globally enable/disable all effects?
|
|
248
|
+
map: z
|
|
249
|
+
.union([
|
|
250
|
+
z.record(z.string().min(1), // Key: Effect name/ID (e.g., "mainBlur", "rotator")
|
|
251
|
+
ComponentEffectShape // Value: An object conforming to one of the effect shapes
|
|
252
|
+
),
|
|
253
|
+
z.array(z.any()) // Support array format for backward compatibility
|
|
254
|
+
])
|
|
255
|
+
.transform((val) => {
|
|
256
|
+
// If it's an array, convert to empty object
|
|
257
|
+
if (Array.isArray(val)) {
|
|
258
|
+
return {};
|
|
259
|
+
}
|
|
260
|
+
// If it's already an object, return as is
|
|
261
|
+
return val;
|
|
262
|
+
})
|
|
263
|
+
.default({}) // Default to an empty object if no effects
|
|
264
|
+
});
|
|
265
|
+
const ComponentAnimationsShape = z.object({
|
|
266
|
+
enabled: z.boolean().optional().default(true), // Globally enable/disable all animations?
|
|
267
|
+
list: z.array(AnimationShape).default([]),
|
|
268
|
+
subtitlesSeed: z.number().int().optional()
|
|
269
|
+
});
|
|
270
|
+
/**
|
|
271
|
+
* Base component schema that all component types will extend
|
|
272
|
+
*/
|
|
273
|
+
export const ComponentBaseShape = z.object({
|
|
274
|
+
id: z.string(),
|
|
275
|
+
name: z.string().optional(),
|
|
276
|
+
type: z.enum([
|
|
277
|
+
'IMAGE',
|
|
278
|
+
'GIF',
|
|
279
|
+
'VIDEO',
|
|
280
|
+
'TEXT',
|
|
281
|
+
'SHAPE',
|
|
282
|
+
'AUDIO',
|
|
283
|
+
'COLOR',
|
|
284
|
+
'GRADIENT',
|
|
285
|
+
'SUBTITLES'
|
|
286
|
+
]),
|
|
287
|
+
timeline: ComponentTimelineShape,
|
|
288
|
+
appearance: AppearanceShape,
|
|
289
|
+
animations: ComponentAnimationsShape.default({}),
|
|
290
|
+
effects: ComponentEffectsShape.default({}),
|
|
291
|
+
visible: z.boolean().default(true),
|
|
292
|
+
order: z.number().default(0),
|
|
293
|
+
checksum: z.string().optional()
|
|
294
|
+
});
|
|
295
|
+
/**
|
|
296
|
+
* Text component schema
|
|
297
|
+
*/
|
|
298
|
+
export const TextComponentShape = ComponentBaseShape.extend({
|
|
299
|
+
type: z.literal('TEXT'),
|
|
300
|
+
text: z.string(),
|
|
301
|
+
isAIEmoji: z.boolean().default(false).optional(),
|
|
302
|
+
appearance: AppearanceShape.extend({
|
|
303
|
+
text: TextAppearanceShape,
|
|
304
|
+
verticalAlign: z.enum(['top', 'center', 'bottom']).optional(),
|
|
305
|
+
horizontalAlign: z.enum(['left', 'center', 'right']).optional()
|
|
306
|
+
})
|
|
307
|
+
}).strict();
|
|
308
|
+
/**
|
|
309
|
+
* Image component schema
|
|
310
|
+
*/
|
|
311
|
+
export const ImageComponentShape = ComponentBaseShape.extend({
|
|
312
|
+
type: z.literal('IMAGE'),
|
|
313
|
+
source: ComponentSourceShape,
|
|
314
|
+
crop: z
|
|
315
|
+
.object({
|
|
316
|
+
xPercent: z.number().min(0).max(1).default(0),
|
|
317
|
+
yPercent: z.number().min(0).max(1).default(0),
|
|
318
|
+
widthPercent: z.number().min(0).max(1).default(1),
|
|
319
|
+
heightPercent: z.number().min(0).max(1).default(1)
|
|
320
|
+
})
|
|
321
|
+
.optional()
|
|
322
|
+
}).strict();
|
|
323
|
+
/**
|
|
324
|
+
* GIF component schema
|
|
325
|
+
*/
|
|
326
|
+
export const GifComponentShape = ComponentBaseShape.extend({
|
|
327
|
+
type: z.literal('GIF'),
|
|
328
|
+
source: ComponentSourceShape,
|
|
329
|
+
playback: z
|
|
330
|
+
.object({
|
|
331
|
+
loop: z.boolean().default(true),
|
|
332
|
+
speed: z.number().positive().default(1)
|
|
333
|
+
})
|
|
334
|
+
.optional()
|
|
335
|
+
}).strict();
|
|
336
|
+
/**
|
|
337
|
+
* Video component schema
|
|
338
|
+
*/
|
|
339
|
+
export const VideoComponentShape = ComponentBaseShape.extend({
|
|
340
|
+
type: z.literal('VIDEO'),
|
|
341
|
+
source: ComponentSourceShape,
|
|
342
|
+
volume: z.number().min(0).max(1).default(1),
|
|
343
|
+
muted: z.boolean().default(false),
|
|
344
|
+
playback: z
|
|
345
|
+
.object({
|
|
346
|
+
autoplay: z.boolean().default(true),
|
|
347
|
+
loop: z.boolean().default(false),
|
|
348
|
+
playbackRate: z.number().positive().default(1),
|
|
349
|
+
startAt: z.number().min(0).default(0),
|
|
350
|
+
endAt: z.number().optional()
|
|
351
|
+
})
|
|
352
|
+
.optional(),
|
|
353
|
+
crop: z
|
|
354
|
+
.object({
|
|
355
|
+
x: z.number().default(0),
|
|
356
|
+
y: z.number().default(0),
|
|
357
|
+
width: z.number().min(0).max(1).default(1),
|
|
358
|
+
height: z.number().min(0).max(1).default(1)
|
|
359
|
+
})
|
|
360
|
+
.optional()
|
|
361
|
+
}).strict();
|
|
362
|
+
/**
|
|
363
|
+
* Progress configuration schemas for different progress types
|
|
364
|
+
*/
|
|
365
|
+
export const LinearProgressConfigShape = z.object({
|
|
366
|
+
type: z.literal('linear'),
|
|
367
|
+
direction: z.enum(['horizontal', 'vertical']).default('horizontal'),
|
|
368
|
+
reverse: z.boolean().default(false).optional(),
|
|
369
|
+
anchor: z.enum(['start', 'center', 'end']).default('start').optional()
|
|
370
|
+
});
|
|
371
|
+
export const PerimeterProgressConfigShape = z.object({
|
|
372
|
+
type: z.literal('perimeter'),
|
|
373
|
+
startCorner: z.enum(['top-left', 'top-right', 'bottom-right', 'bottom-left']).default('top-left'),
|
|
374
|
+
clockwise: z.boolean().default(true).optional(),
|
|
375
|
+
strokeWidth: z.number().positive().default(4).optional()
|
|
376
|
+
});
|
|
377
|
+
export const RadialProgressConfigShape = z.object({
|
|
378
|
+
type: z.literal('radial'),
|
|
379
|
+
startAngle: z.number().default(-90).optional(), // -90 = top (12 o'clock), 0 = right (3 o'clock)
|
|
380
|
+
clockwise: z.boolean().default(true).optional(),
|
|
381
|
+
innerRadius: z.number().min(0).max(1).default(0).optional(), // 0 = filled circle, >0 = ring/donut
|
|
382
|
+
strokeWidth: z.number().positive().optional(), // For ring style
|
|
383
|
+
capStyle: z.enum(['butt', 'round', 'square']).default('round').optional()
|
|
384
|
+
});
|
|
385
|
+
export const DoubleProgressConfigShape = z.object({
|
|
386
|
+
type: z.literal('double'),
|
|
387
|
+
paths: z
|
|
388
|
+
.array(z.object({
|
|
389
|
+
direction: z.enum(['horizontal', 'vertical']),
|
|
390
|
+
position: z.enum(['top', 'bottom', 'left', 'right']),
|
|
391
|
+
reverse: z.boolean().default(false).optional(),
|
|
392
|
+
offset: z.number().default(0).optional() // Offset from edge in pixels
|
|
393
|
+
}))
|
|
394
|
+
.min(2)
|
|
395
|
+
.max(4) // At least 2 paths, max 4 for performance
|
|
396
|
+
});
|
|
397
|
+
export const CustomProgressConfigShape = z.object({
|
|
398
|
+
type: z.literal('custom'),
|
|
399
|
+
pathData: z.string(), // SVG path data for custom progress shapes
|
|
400
|
+
strokeWidth: z.number().positive().default(4).optional(),
|
|
401
|
+
capStyle: z.enum(['butt', 'round', 'square']).default('round').optional()
|
|
402
|
+
});
|
|
403
|
+
/**
|
|
404
|
+
* Union of all progress configuration types
|
|
405
|
+
*/
|
|
406
|
+
export const ProgressConfigShape = z.discriminatedUnion('type', [
|
|
407
|
+
LinearProgressConfigShape,
|
|
408
|
+
PerimeterProgressConfigShape,
|
|
409
|
+
RadialProgressConfigShape,
|
|
410
|
+
DoubleProgressConfigShape,
|
|
411
|
+
CustomProgressConfigShape
|
|
412
|
+
]);
|
|
413
|
+
/**
|
|
414
|
+
* Shape component schema for basic geometric shapes
|
|
415
|
+
*/
|
|
416
|
+
export const ShapeComponentShape = ComponentBaseShape.extend({
|
|
417
|
+
type: z.literal('SHAPE'),
|
|
418
|
+
shape: z.union([
|
|
419
|
+
// Progress shape with specialized configuration
|
|
420
|
+
z.object({
|
|
421
|
+
type: z.literal('progress'),
|
|
422
|
+
progressConfig: ProgressConfigShape.optional().default({
|
|
423
|
+
type: 'linear',
|
|
424
|
+
direction: 'horizontal',
|
|
425
|
+
reverse: false,
|
|
426
|
+
anchor: 'start'
|
|
427
|
+
})
|
|
428
|
+
}),
|
|
429
|
+
// Other shape types
|
|
430
|
+
z.object({
|
|
431
|
+
type: z.enum(['rectangle', 'triangle', 'circle', 'ellipse', 'polygon', 'star', 'path']),
|
|
432
|
+
// Specific properties for each shape type
|
|
433
|
+
points: z.array(z.object({ x: z.number(), y: z.number() })).optional(), // For polygon
|
|
434
|
+
pathData: z.string().optional(), // For path
|
|
435
|
+
cornerRadius: z.number().min(0).optional() // For rectangle
|
|
436
|
+
})
|
|
437
|
+
]),
|
|
438
|
+
appearance: AppearanceShape.extend({
|
|
439
|
+
color: ColorTypeShape.optional() // fill color
|
|
440
|
+
})
|
|
441
|
+
}).strict();
|
|
442
|
+
/**
|
|
443
|
+
* Audio component schema
|
|
444
|
+
*/
|
|
445
|
+
export const AudioComponentShape = ComponentBaseShape.extend({
|
|
446
|
+
type: z.literal('AUDIO'),
|
|
447
|
+
source: ComponentSourceShape,
|
|
448
|
+
volume: z.number().min(0).max(1).default(1),
|
|
449
|
+
muted: z.boolean().default(false)
|
|
450
|
+
}).strict();
|
|
451
|
+
/**
|
|
452
|
+
* Color component schema
|
|
453
|
+
*/
|
|
454
|
+
export const ColorComponentShape = ComponentBaseShape.extend({
|
|
455
|
+
type: z.literal('COLOR'),
|
|
456
|
+
appearance: AppearanceShape.extend({
|
|
457
|
+
background: z
|
|
458
|
+
.string()
|
|
459
|
+
.refine(isValidColor, { message: 'Invalid color format for ColorComponent background' })
|
|
460
|
+
})
|
|
461
|
+
}).strict();
|
|
462
|
+
/**
|
|
463
|
+
* Gradient component schema
|
|
464
|
+
*/
|
|
465
|
+
export const GradientComponentShape = ComponentBaseShape.extend({
|
|
466
|
+
type: z.literal('GRADIENT'),
|
|
467
|
+
appearance: AppearanceShape.extend({
|
|
468
|
+
background: GradientDefinitionShape // Requires a gradient type in background
|
|
469
|
+
})
|
|
470
|
+
}).strict();
|
|
471
|
+
/**
|
|
472
|
+
* Subtitles component schema
|
|
473
|
+
*/
|
|
474
|
+
export const AIEmojiShape = z.object({
|
|
475
|
+
text: z.string(),
|
|
476
|
+
emoji: z.string(),
|
|
477
|
+
startAt: z.number(),
|
|
478
|
+
endAt: z.number(),
|
|
479
|
+
componentId: z.string().optional()
|
|
480
|
+
});
|
|
481
|
+
export const SubtitleComponentShape = ComponentBaseShape.extend({
|
|
482
|
+
type: z.literal('SUBTITLES'),
|
|
483
|
+
source: ComponentSourceShape.extend({
|
|
484
|
+
url: z.string().url().optional()
|
|
485
|
+
// Subtitles might need specific source fields, e.g., format
|
|
486
|
+
}).optional(),
|
|
487
|
+
timingAnchor: TimingAnchorShape,
|
|
488
|
+
text: z.string().optional(), // Optional: if text is directly embedded
|
|
489
|
+
appearance: AppearanceShape.extend({
|
|
490
|
+
text: TextAppearanceShape,
|
|
491
|
+
verticalAlign: z.enum(['top', 'center', 'bottom']).optional(),
|
|
492
|
+
horizontalAlign: z.enum(['left', 'center', 'right']).optional(),
|
|
493
|
+
hasAIEmojis: z.boolean().default(false).optional(),
|
|
494
|
+
aiEmojisPlacement: z.enum(['top', 'bottom']).default('top').optional(),
|
|
495
|
+
aiEmojisPlacementOffset: z.number().default(30).optional(),
|
|
496
|
+
aiEmojis: z.array(AIEmojiShape).optional(),
|
|
497
|
+
highlighterColor1: ColorTypeShape.optional(),
|
|
498
|
+
highlighterColor2: ColorTypeShape.optional(),
|
|
499
|
+
highlighterColor3: ColorTypeShape.optional()
|
|
500
|
+
})
|
|
501
|
+
}).strict();
|
|
502
|
+
/**
|
|
503
|
+
* Union of all component types for polymorphic handling
|
|
504
|
+
*/
|
|
505
|
+
export const ComponentShape = z.discriminatedUnion('type', [
|
|
506
|
+
TextComponentShape,
|
|
507
|
+
ImageComponentShape,
|
|
508
|
+
GifComponentShape,
|
|
509
|
+
VideoComponentShape,
|
|
510
|
+
ShapeComponentShape,
|
|
511
|
+
AudioComponentShape,
|
|
512
|
+
ColorComponentShape,
|
|
513
|
+
GradientComponentShape,
|
|
514
|
+
SubtitleComponentShape
|
|
515
|
+
]);
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { isValidColor } from './utils.js';
|
|
3
|
+
import { ComponentShape } from './components.js';
|
|
4
|
+
import { SubtitleCollectionShape, SubtitleWithCompactWordsShape } from './subtitles.js';
|
|
5
|
+
// Utility functions
|
|
6
|
+
const toFixed3 = (val) => parseFloat(val.toFixed(3));
|
|
7
|
+
/**
|
|
8
|
+
* Basic asset metadata
|
|
9
|
+
*/
|
|
10
|
+
export const SceneAssetMetadataShape = z.object({
|
|
11
|
+
width: z.number().positive().optional(),
|
|
12
|
+
height: z.number().positive().optional(),
|
|
13
|
+
duration: z.number().min(0).optional(),
|
|
14
|
+
format: z.string().optional(),
|
|
15
|
+
codec: z.string().optional(),
|
|
16
|
+
bitrate: z.number().positive().optional(),
|
|
17
|
+
fps: z.number().positive().optional(),
|
|
18
|
+
hasAudio: z.boolean().optional()
|
|
19
|
+
});
|
|
20
|
+
export const AssetSubtitleShape = z.object({
|
|
21
|
+
// id: z.string(),
|
|
22
|
+
url: z.string().url().optional(),
|
|
23
|
+
language_code: z.string().optional(),
|
|
24
|
+
subtitles: z.array(SubtitleWithCompactWordsShape).optional()
|
|
25
|
+
});
|
|
26
|
+
/**
|
|
27
|
+
* Asset schema for centralized asset registry
|
|
28
|
+
*/
|
|
29
|
+
export const SceneAssetShape = z.object({
|
|
30
|
+
id: z.string(),
|
|
31
|
+
type: z.enum(['VIDEO', 'IMAGE', 'AUDIO', 'FONT', 'GIF']),
|
|
32
|
+
url: z.string(),
|
|
33
|
+
path: z.string().optional(),
|
|
34
|
+
language_code: z.string().optional(),
|
|
35
|
+
metadata: SceneAssetMetadataShape.optional(),
|
|
36
|
+
subtitles: z.array(AssetSubtitleShape).optional()
|
|
37
|
+
});
|
|
38
|
+
export const SceneSubtitlesSettingsShape = z.object({
|
|
39
|
+
punctuation: z.boolean().default(true),
|
|
40
|
+
mergeGap: z.number().min(0).default(0.2).optional(),
|
|
41
|
+
data: z.record(z.string(), SubtitleCollectionShape).optional()
|
|
42
|
+
});
|
|
43
|
+
/**
|
|
44
|
+
* Core scene settings schema defining dimensions, background, and other scene-level properties
|
|
45
|
+
*/
|
|
46
|
+
export const SceneSettingsShape = z.object({
|
|
47
|
+
/** Scene dimensions in pixels */
|
|
48
|
+
width: z.number().positive(),
|
|
49
|
+
height: z.number().positive(),
|
|
50
|
+
language_code: z.string().optional(),
|
|
51
|
+
/** Scene duration in seconds */
|
|
52
|
+
duration: z.number().positive().transform(toFixed3),
|
|
53
|
+
startAt: z.number().min(0).transform(toFixed3).optional(),
|
|
54
|
+
endAt: z.number().min(0).transform(toFixed3).optional(),
|
|
55
|
+
trimZones: z
|
|
56
|
+
.array(z.object({
|
|
57
|
+
start: z.number().min(0).transform(toFixed3),
|
|
58
|
+
end: z.number().positive().transform(toFixed3)
|
|
59
|
+
}))
|
|
60
|
+
.optional(),
|
|
61
|
+
/** Frame rate for rendering */
|
|
62
|
+
fps: z.number().int().positive().default(30),
|
|
63
|
+
/** Background configuration */
|
|
64
|
+
backgroundColor: z
|
|
65
|
+
.union([
|
|
66
|
+
z.string().refine(isValidColor, { message: 'Invalid color format' }),
|
|
67
|
+
z.object({
|
|
68
|
+
type: z.enum(['linear', 'radial']),
|
|
69
|
+
colors: z.array(z.string().refine(isValidColor)).min(2),
|
|
70
|
+
stops: z.array(z.number().min(0).max(1)).optional(),
|
|
71
|
+
angle: z.number().min(0).max(360).default(180).optional(),
|
|
72
|
+
position: z.string().optional(),
|
|
73
|
+
shape: z.enum(['ellipse', 'circle']).optional()
|
|
74
|
+
})
|
|
75
|
+
])
|
|
76
|
+
.default('#FFFFFF'),
|
|
77
|
+
/** Audio configuration */
|
|
78
|
+
audio: z
|
|
79
|
+
.object({
|
|
80
|
+
src: z.string().url().optional(),
|
|
81
|
+
volume: z.number().min(0).max(1).default(1),
|
|
82
|
+
muted: z.boolean().default(false)
|
|
83
|
+
})
|
|
84
|
+
.optional(),
|
|
85
|
+
subtitles: SceneSubtitlesSettingsShape.optional()
|
|
86
|
+
});
|
|
87
|
+
/**
|
|
88
|
+
* Schema for a scene layer in v2.0
|
|
89
|
+
* Layers organize related components and control their stacking order
|
|
90
|
+
*/
|
|
91
|
+
export const SceneLayerShape = z.object({
|
|
92
|
+
/** Unique identifier for the layer */
|
|
93
|
+
id: z.string(),
|
|
94
|
+
/** Optional name for the layer */
|
|
95
|
+
name: z.string().optional(),
|
|
96
|
+
/** Layer stacking order (higher values appear on top) */
|
|
97
|
+
order: z.number().default(0),
|
|
98
|
+
/** Whether the layer is visible */
|
|
99
|
+
visible: z.boolean().default(true),
|
|
100
|
+
/** Whether audio in this layer is muted */
|
|
101
|
+
muted: z.boolean().default(false),
|
|
102
|
+
/** Components contained in this layer */
|
|
103
|
+
components: z
|
|
104
|
+
.array(
|
|
105
|
+
// Will be extended with component schemas in components.ts
|
|
106
|
+
ComponentShape)
|
|
107
|
+
.default([])
|
|
108
|
+
});
|
|
109
|
+
/**
|
|
110
|
+
* Audio track schema for global audio playback
|
|
111
|
+
*/
|
|
112
|
+
export const AudioTrackShape = z.object({
|
|
113
|
+
id: z.string(),
|
|
114
|
+
name: z.string().optional(),
|
|
115
|
+
url: z.string(),
|
|
116
|
+
volume: z.number().min(0).max(1).default(1),
|
|
117
|
+
startAt: z.number().min(0).transform(toFixed3),
|
|
118
|
+
endAt: z
|
|
119
|
+
.number()
|
|
120
|
+
.min(0)
|
|
121
|
+
.optional()
|
|
122
|
+
.transform((val) => (val === undefined ? undefined : toFixed3(val))),
|
|
123
|
+
muted: z.boolean().default(false)
|
|
124
|
+
});
|
|
125
|
+
/**
|
|
126
|
+
* Schema for transitions between components
|
|
127
|
+
*/
|
|
128
|
+
export const SceneTransitionShape = z.object({
|
|
129
|
+
id: z.string(),
|
|
130
|
+
name: z.string().optional(),
|
|
131
|
+
fromComponentId: z.string(),
|
|
132
|
+
toComponentId: z.string(),
|
|
133
|
+
type: z.string(),
|
|
134
|
+
presetId: z.string().optional(),
|
|
135
|
+
duration: z.number().min(0).transform(toFixed3),
|
|
136
|
+
parameters: z.record(z.unknown()).optional()
|
|
137
|
+
});
|
|
138
|
+
/**
|
|
139
|
+
* Schema for the main scene structure in v2.0
|
|
140
|
+
*/
|
|
141
|
+
export const SceneShape = z.object({
|
|
142
|
+
/** Unique identifier for the scene */
|
|
143
|
+
id: z.string(),
|
|
144
|
+
/** Schema version */
|
|
145
|
+
version: z.coerce.string().optional(),
|
|
146
|
+
/** Optional name for the scene */
|
|
147
|
+
name: z.string().optional(),
|
|
148
|
+
/** Scene settings */
|
|
149
|
+
settings: SceneSettingsShape.strict(),
|
|
150
|
+
/** Assets registry */
|
|
151
|
+
assets: z.array(SceneAssetShape).default([]),
|
|
152
|
+
/** Layers in the scene */
|
|
153
|
+
layers: z.array(SceneLayerShape.strict()).default([]),
|
|
154
|
+
/** Scene transitions */
|
|
155
|
+
transitions: z.array(SceneTransitionShape).default([]),
|
|
156
|
+
/** Audio tracks */
|
|
157
|
+
audioTracks: z.array(AudioTrackShape).default([]),
|
|
158
|
+
/** Optional checksum */
|
|
159
|
+
checksum: z.string().optional()
|
|
160
|
+
});
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export * from './core.js';
|
|
2
|
+
export * from './components.js';
|
|
3
|
+
export * from './properties.js';
|
|
4
|
+
export * from './animations.js';
|
|
5
|
+
export type * from './components.js';
|
|
6
|
+
export type * from './properties.js';
|
|
7
|
+
export type { CompactWordMetadata, CompactWordTuple, SubtitleWord, SubtitleWithCompactWords, SubtitleWithLegacyWords, Subtitle, SubtitleCollection } from './subtitles.js';
|
|
8
|
+
export * from './subtitles.js';
|
|
9
|
+
export type FontType = {
|
|
10
|
+
alias: string;
|
|
11
|
+
url?: string;
|
|
12
|
+
data?: {
|
|
13
|
+
family: string;
|
|
14
|
+
};
|
|
15
|
+
source: 'google' | 'custom';
|
|
16
|
+
src?: string;
|
|
17
|
+
};
|
|
18
|
+
export type BackgroundColors = {
|
|
19
|
+
colors: string[];
|
|
20
|
+
angle: number;
|
|
21
|
+
type: string;
|
|
22
|
+
};
|