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,409 @@
|
|
|
1
|
+
import * as PIXI from 'pixi.js-legacy';
|
|
2
|
+
import { gsap } from 'gsap';
|
|
3
|
+
import { ComponentShape } from './';
|
|
4
|
+
import { buildCharactersListFromComponentsAndSubtitles, changeIdDeep } from './utils/utils.js';
|
|
5
|
+
import { loadFonts } from './utils/document.js';
|
|
6
|
+
import { CommandType } from './commands/CommandTypes.js';
|
|
7
|
+
import { CommandRunner } from './commands/CommandRunner.js';
|
|
8
|
+
import { StateManager } from './managers/StateManager.svelte.js';
|
|
9
|
+
import { TimelineManager } from './managers/TimelineManager.svelte.js';
|
|
10
|
+
import { EventManager } from './managers/EventManager.js';
|
|
11
|
+
import { DomManager } from './managers/DomManager.js';
|
|
12
|
+
import { AppManager } from './managers/AppManager.svelte.js';
|
|
13
|
+
import { ComponentsManager } from './managers/ComponentsManager.svelte.js';
|
|
14
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
15
|
+
import { MediaManager } from './managers/MediaManager.js';
|
|
16
|
+
import { LayersManager } from './managers/LayersManager.svelte.js';
|
|
17
|
+
import { SubtitlesManager } from './managers/SubtitlesManager.svelte.js';
|
|
18
|
+
import { removeContainer } from './DIContainer.js';
|
|
19
|
+
export class SceneBuilder {
|
|
20
|
+
initialized = false;
|
|
21
|
+
renderTicker;
|
|
22
|
+
timelineManager;
|
|
23
|
+
eventManager;
|
|
24
|
+
domManager;
|
|
25
|
+
appManager;
|
|
26
|
+
layersManager;
|
|
27
|
+
componentsManager;
|
|
28
|
+
stateManager;
|
|
29
|
+
commandRunner;
|
|
30
|
+
mediaManager;
|
|
31
|
+
subtitlesManager;
|
|
32
|
+
fonts;
|
|
33
|
+
// Replace constructor with cradle pattern
|
|
34
|
+
constructor(cradle) {
|
|
35
|
+
this.timelineManager = cradle.timelineManager;
|
|
36
|
+
this.eventManager = cradle.eventManager;
|
|
37
|
+
this.domManager = cradle.domManager;
|
|
38
|
+
this.appManager = cradle.appManager;
|
|
39
|
+
this.layersManager = cradle.layersManager;
|
|
40
|
+
this.componentsManager = cradle.componentsManager;
|
|
41
|
+
this.stateManager = cradle.stateManager;
|
|
42
|
+
this.commandRunner = cradle.commandRunner;
|
|
43
|
+
this.mediaManager = cradle.mediaManager;
|
|
44
|
+
this.subtitlesManager = cradle.subtitlesManager;
|
|
45
|
+
this.fonts = cradle.fonts;
|
|
46
|
+
// TODO - check scene is v2
|
|
47
|
+
// SceneShape.parse(this.sceneData);
|
|
48
|
+
}
|
|
49
|
+
get sceneData() {
|
|
50
|
+
return this.stateManager.data;
|
|
51
|
+
}
|
|
52
|
+
get environment() {
|
|
53
|
+
return this.stateManager.environment;
|
|
54
|
+
}
|
|
55
|
+
get state() {
|
|
56
|
+
return this.stateManager.state;
|
|
57
|
+
}
|
|
58
|
+
get isPlaying() {
|
|
59
|
+
return this.stateManager.isPlaying;
|
|
60
|
+
}
|
|
61
|
+
get isLoading() {
|
|
62
|
+
return this.stateManager.state === 'loading';
|
|
63
|
+
}
|
|
64
|
+
get currentTime() {
|
|
65
|
+
return this.stateManager.currentTime;
|
|
66
|
+
}
|
|
67
|
+
get currentFrame() {
|
|
68
|
+
return Math.round(this.stateManager.currentTime * this.fps);
|
|
69
|
+
}
|
|
70
|
+
get duration() {
|
|
71
|
+
return this.stateManager.duration;
|
|
72
|
+
}
|
|
73
|
+
get progress() {
|
|
74
|
+
// value between 0 - 1, 1 is compo
|
|
75
|
+
return this.duration ? this.currentTime / this.duration : 0;
|
|
76
|
+
}
|
|
77
|
+
get app() {
|
|
78
|
+
return this.appManager.app;
|
|
79
|
+
}
|
|
80
|
+
get timeline() {
|
|
81
|
+
return this.timelineManager.timeline;
|
|
82
|
+
}
|
|
83
|
+
get fps() {
|
|
84
|
+
return this.sceneData.settings.fps ?? 30;
|
|
85
|
+
}
|
|
86
|
+
// we should remove this later and inject domManager where needed instead
|
|
87
|
+
get htmlContainer() {
|
|
88
|
+
return this.domManager.htmlContainer;
|
|
89
|
+
}
|
|
90
|
+
get canvasContainer() {
|
|
91
|
+
return this.domManager.canvas;
|
|
92
|
+
}
|
|
93
|
+
get components() {
|
|
94
|
+
return this.componentsManager;
|
|
95
|
+
}
|
|
96
|
+
get layers() {
|
|
97
|
+
return this.layersManager;
|
|
98
|
+
}
|
|
99
|
+
get subtitles() {
|
|
100
|
+
return this.subtitlesManager;
|
|
101
|
+
}
|
|
102
|
+
get disabledTimeZones() {
|
|
103
|
+
return this.stateManager.disabledTimeZones;
|
|
104
|
+
}
|
|
105
|
+
addExcludedTimestamp(start, end) {
|
|
106
|
+
this.stateManager.data.settings.trimZones = this.stateManager.data.settings?.trimZones || [];
|
|
107
|
+
this.stateManager.data.settings.trimZones.push({
|
|
108
|
+
start: this.stateManager.transformTime(start),
|
|
109
|
+
end: this.stateManager.transformTime(end)
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
removeExcludedTimestampsBetween(start, end) {
|
|
113
|
+
const transformedStart = this.stateManager.transformTime(start);
|
|
114
|
+
const transformedEnd = this.stateManager.transformTime(end);
|
|
115
|
+
if (transformedEnd === this.stateManager.startTime) {
|
|
116
|
+
this.setStartAt(undefined);
|
|
117
|
+
}
|
|
118
|
+
if (transformedStart === this.stateManager.endTime) {
|
|
119
|
+
this.setEndAt(undefined);
|
|
120
|
+
}
|
|
121
|
+
if (!this.stateManager.data.settings.trimZones) {
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
this.stateManager.data.settings.trimZones = this.stateManager.data.settings.trimZones.filter(({ start, end }) => {
|
|
125
|
+
// Keep zones that are completely outside the removal range
|
|
126
|
+
return end < transformedStart || start > transformedEnd;
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
syncChanges() {
|
|
130
|
+
this.stateManager.updateLayers();
|
|
131
|
+
}
|
|
132
|
+
setStartAt(start) {
|
|
133
|
+
this.stateManager.setStartAt(start ? this.stateManager.transformTime(start) : undefined);
|
|
134
|
+
}
|
|
135
|
+
setEndAt(end) {
|
|
136
|
+
this.stateManager.setEndAt(end ? this.stateManager.transformTime(end) : undefined);
|
|
137
|
+
}
|
|
138
|
+
updateSubtitlesSettings(settings) {
|
|
139
|
+
const currentSubtitlesSettincs = this.stateManager.data.settings.subtitles
|
|
140
|
+
? this.stateManager.data.settings.subtitles
|
|
141
|
+
: {
|
|
142
|
+
punctuation: true
|
|
143
|
+
};
|
|
144
|
+
const newSettings = { ...currentSubtitlesSettincs, ...settings };
|
|
145
|
+
this.stateManager.updateSceneSubtitlesSettings(newSettings);
|
|
146
|
+
this.subtitlesManager.updateSettings(newSettings);
|
|
147
|
+
}
|
|
148
|
+
dispatchEvent(event, props) {
|
|
149
|
+
this.eventManager.emit(event, props);
|
|
150
|
+
}
|
|
151
|
+
addEventListener(event, callback, options) {
|
|
152
|
+
this.eventManager.addEventListener(event, ((e) => callback(e)), options);
|
|
153
|
+
}
|
|
154
|
+
removeEventListener(event, callback, options) {
|
|
155
|
+
this.eventManager.removeEventListener(event, ((e) => callback(e)), options);
|
|
156
|
+
}
|
|
157
|
+
async run(commandType, props) {
|
|
158
|
+
return await this.commandRunner.run(commandType, props);
|
|
159
|
+
}
|
|
160
|
+
runSync(commandType, props) {
|
|
161
|
+
return this.commandRunner.runSync(commandType, props);
|
|
162
|
+
}
|
|
163
|
+
scale(scale) {
|
|
164
|
+
const clampedScale = Math.max(0.01, Math.min(scale, 2));
|
|
165
|
+
this.appManager.scale(clampedScale);
|
|
166
|
+
this.domManager.scale(clampedScale);
|
|
167
|
+
}
|
|
168
|
+
async loadFonts(fonts) {
|
|
169
|
+
return await loadFonts(fonts);
|
|
170
|
+
}
|
|
171
|
+
async initialize() {
|
|
172
|
+
if (this.initialized) {
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
this.initialized = true;
|
|
176
|
+
gsap.ticker.fps(this.fps);
|
|
177
|
+
this.renderTicker = () => {
|
|
178
|
+
this.render();
|
|
179
|
+
};
|
|
180
|
+
if (this.fonts.length > 0) {
|
|
181
|
+
await this.loadFonts(this.fonts);
|
|
182
|
+
}
|
|
183
|
+
this.layersManager.setAppManager(this.appManager);
|
|
184
|
+
await this.appManager.initialize();
|
|
185
|
+
if (this.stateManager.scale !== 1) {
|
|
186
|
+
this.scale(this.stateManager.scale);
|
|
187
|
+
}
|
|
188
|
+
await this.buildSceneTree();
|
|
189
|
+
this.seek(0);
|
|
190
|
+
this.render();
|
|
191
|
+
this.eventManager.isReady = true;
|
|
192
|
+
this.domManager.removeLoader();
|
|
193
|
+
}
|
|
194
|
+
async buildSceneTree() {
|
|
195
|
+
// Sort layers by order
|
|
196
|
+
const sortedLayers = [...this.sceneData.layers].sort((a, b) => a.order - b.order);
|
|
197
|
+
for (const layerData of sortedLayers) {
|
|
198
|
+
await this.layersManager.create(layerData);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
async addLayer(layerInput) {
|
|
202
|
+
const layers = this.layersManager.getAll().sort((a, b) => b.order - a.order);
|
|
203
|
+
const lastLayerOrder = layers.length ? layers[0].order : 0;
|
|
204
|
+
const sceneLayer = {
|
|
205
|
+
id: layerInput.id ?? uuidv4(),
|
|
206
|
+
name: layerInput.name ?? 'Layer ' + (layers.length + 1),
|
|
207
|
+
order: layerInput.order ?? lastLayerOrder + 1, // TODO - should probably go into the first layer
|
|
208
|
+
components: layerInput.components ?? [],
|
|
209
|
+
visible: layerInput.visible ?? true,
|
|
210
|
+
muted: layerInput.muted ?? false
|
|
211
|
+
};
|
|
212
|
+
const layer = await this.layersManager.create(sceneLayer);
|
|
213
|
+
this.eventManager.emit('layerschange');
|
|
214
|
+
this.eventManager.emit('componentschange');
|
|
215
|
+
return layer ? layer : undefined;
|
|
216
|
+
}
|
|
217
|
+
async addNewLayerWithComponents(components) {
|
|
218
|
+
const layers = this.layersManager.getAll().sort((a, b) => b.order - a.order);
|
|
219
|
+
const lastLayerOrder = layers.length ? layers[0].order : 0;
|
|
220
|
+
const layer = await this.layersManager.create({
|
|
221
|
+
id: uuidv4(),
|
|
222
|
+
name: 'Layer ' + (this.layersManager.getAll().length + 1),
|
|
223
|
+
order: lastLayerOrder + 1,
|
|
224
|
+
components: components,
|
|
225
|
+
visible: true,
|
|
226
|
+
muted: false
|
|
227
|
+
});
|
|
228
|
+
this.eventManager.emit('layerschange');
|
|
229
|
+
this.eventManager.emit('componentschange');
|
|
230
|
+
return layer ? layer : undefined;
|
|
231
|
+
}
|
|
232
|
+
async addComponent(componentInput) {
|
|
233
|
+
// 1. Parse the input using the Zod schema
|
|
234
|
+
const result = ComponentShape.safeParse(componentInput);
|
|
235
|
+
// 2. Handle validation failure
|
|
236
|
+
if (!result.success) {
|
|
237
|
+
console.error('Invalid component input:', result.error.format());
|
|
238
|
+
// Potentially emit an error event or throw
|
|
239
|
+
return undefined;
|
|
240
|
+
}
|
|
241
|
+
// 3. Work with the validated and normalized data (result.data is type ComponentData)
|
|
242
|
+
const validatedComponentData = result.data;
|
|
243
|
+
// Pass the validated data
|
|
244
|
+
const layer = await this.addNewLayerWithComponents([componentInput]);
|
|
245
|
+
if (!layer) {
|
|
246
|
+
// Handle layer creation failure if necessary
|
|
247
|
+
return undefined;
|
|
248
|
+
}
|
|
249
|
+
// Return the validated data object
|
|
250
|
+
return validatedComponentData;
|
|
251
|
+
}
|
|
252
|
+
async splitComponent(component) {
|
|
253
|
+
// Find the layer containing this component
|
|
254
|
+
const compStart = component.props.timeline.startAt;
|
|
255
|
+
const compEnd = component.props.timeline.endAt;
|
|
256
|
+
const currentTime = this.currentTime;
|
|
257
|
+
const isInTime = currentTime > compStart && currentTime < compEnd;
|
|
258
|
+
if (!isInTime) {
|
|
259
|
+
return false;
|
|
260
|
+
}
|
|
261
|
+
const layer = this.layers
|
|
262
|
+
.getAll()
|
|
263
|
+
.find((layer) => layer.components.some((comp) => comp.id === component.id));
|
|
264
|
+
if (!layer) {
|
|
265
|
+
return false;
|
|
266
|
+
}
|
|
267
|
+
// Create clone of component data with adjusted times
|
|
268
|
+
const originalEndAt = component.props.timeline.endAt;
|
|
269
|
+
const newData = changeIdDeep(component.props.getData());
|
|
270
|
+
const cloneData = {
|
|
271
|
+
...newData,
|
|
272
|
+
id: uuidv4(), // Generate new ID for clone
|
|
273
|
+
timeline: {
|
|
274
|
+
...newData.timeline,
|
|
275
|
+
endAt: originalEndAt
|
|
276
|
+
},
|
|
277
|
+
checksum: 'new-' + uuidv4()
|
|
278
|
+
};
|
|
279
|
+
// Update original component's end time
|
|
280
|
+
component.props.setEnd(this.currentTime);
|
|
281
|
+
// Add the cloned component to the same layer
|
|
282
|
+
const newComponent = await this.componentsManager.create(cloneData);
|
|
283
|
+
newComponent?.props.setStart(this.currentTime);
|
|
284
|
+
if (newComponent) {
|
|
285
|
+
layer.addComponent(newComponent);
|
|
286
|
+
}
|
|
287
|
+
this.dispatchEvent('componentschange');
|
|
288
|
+
return true;
|
|
289
|
+
}
|
|
290
|
+
async seek(time) {
|
|
291
|
+
await this.run(CommandType.SEEK, { time });
|
|
292
|
+
}
|
|
293
|
+
async replaceSourceOnTime(time, componentId, base64data) {
|
|
294
|
+
await this.run(CommandType.REPLACE_SOURCE_ON_TIME, {
|
|
295
|
+
time,
|
|
296
|
+
componentId,
|
|
297
|
+
base64data
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
async seekAndRenderFrame(time, target, format = 'png', quality = 1) {
|
|
301
|
+
await this.seek(time);
|
|
302
|
+
// Ensure scene is rendered after seek so media hooks apply their updates
|
|
303
|
+
this.render();
|
|
304
|
+
const frame = await this.renderFrame(target, format, quality);
|
|
305
|
+
return frame;
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Check if seeking to a specific time would result in visual changes
|
|
309
|
+
* without actually extracting frame data.
|
|
310
|
+
*
|
|
311
|
+
* This is useful for determining if consecutive frames are identical,
|
|
312
|
+
* allowing you to skip rendering and return cached frame data.
|
|
313
|
+
*
|
|
314
|
+
* @param time Time in seconds to check
|
|
315
|
+
* @returns Promise<boolean> True if scene has visual changes at this time
|
|
316
|
+
*
|
|
317
|
+
* @example
|
|
318
|
+
* // Check if frame needs re-rendering
|
|
319
|
+
* const time = frame / sceneBuilder.fps;
|
|
320
|
+
* const isDirty = await sceneBuilder.isSceneDirty(time);
|
|
321
|
+
*
|
|
322
|
+
* if (!isDirty && isConsecutiveFrame) {
|
|
323
|
+
* // Return cached frame - scene hasn't changed
|
|
324
|
+
* return cachedFrameData;
|
|
325
|
+
* } else {
|
|
326
|
+
* // Render new frame - scene has changes
|
|
327
|
+
* return await sceneBuilder.seekAndRenderFrame(time);
|
|
328
|
+
* }
|
|
329
|
+
*/
|
|
330
|
+
async isSceneDirty(time) {
|
|
331
|
+
// Seek to the specified time to trigger component/hook updates
|
|
332
|
+
await this.seek(time);
|
|
333
|
+
// Get current dirty state BEFORE calling render()
|
|
334
|
+
// This prevents render() from clearing the dirty flag
|
|
335
|
+
const wasDirty = this.stateManager.isDirty;
|
|
336
|
+
// Render to update all display objects and let hooks detect changes
|
|
337
|
+
// This triggers all hook updates but doesn't extract frame data
|
|
338
|
+
this.render();
|
|
339
|
+
// Return the dirty state we captured before render()
|
|
340
|
+
// Don't clear the dirty flag - let actual frame extraction handle that
|
|
341
|
+
return wasDirty;
|
|
342
|
+
}
|
|
343
|
+
async renderFrame(target, format = 'png', quality = 1) {
|
|
344
|
+
const frame = (await this.run(CommandType.RENDER_FRAME, { target, format, quality }));
|
|
345
|
+
if (!frame) {
|
|
346
|
+
throw new Error('Rendering frame failed');
|
|
347
|
+
}
|
|
348
|
+
return frame;
|
|
349
|
+
}
|
|
350
|
+
log(message) {
|
|
351
|
+
$effect.root(function () {
|
|
352
|
+
$inspect(message);
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
play(changeState = true) {
|
|
356
|
+
if (this.state === 'loading' || this.state === 'playing') {
|
|
357
|
+
return;
|
|
358
|
+
}
|
|
359
|
+
if (changeState) {
|
|
360
|
+
this.stateManager.changeState('playing');
|
|
361
|
+
}
|
|
362
|
+
this.timelineManager.play();
|
|
363
|
+
gsap.ticker.add(this.renderTicker);
|
|
364
|
+
}
|
|
365
|
+
pause(changeState = true) {
|
|
366
|
+
if (changeState) {
|
|
367
|
+
this.stateManager.changeState('paused');
|
|
368
|
+
}
|
|
369
|
+
this.timelineManager.pause();
|
|
370
|
+
this.render();
|
|
371
|
+
gsap.ticker.remove(this.renderTicker);
|
|
372
|
+
}
|
|
373
|
+
setPlaybackRate(rate) {
|
|
374
|
+
this.timeline.timeScale(rate);
|
|
375
|
+
}
|
|
376
|
+
addLoadingComponent(componentId) {
|
|
377
|
+
this.stateManager.addLoadingComponent(componentId);
|
|
378
|
+
}
|
|
379
|
+
removeLoadingComponent(componentId) {
|
|
380
|
+
this.stateManager.removeLoadingComponent(componentId);
|
|
381
|
+
}
|
|
382
|
+
buildCharactersList() {
|
|
383
|
+
// TODO - refactor
|
|
384
|
+
this.stateManager.setCharactersList(buildCharactersListFromComponentsAndSubtitles(this.sceneData.layers, this.subtitles.data));
|
|
385
|
+
}
|
|
386
|
+
render() {
|
|
387
|
+
const rendered = this.runSync(CommandType.RENDER);
|
|
388
|
+
if (rendered === false) {
|
|
389
|
+
this.stateManager.setRenderAfterLoadingFinished(true);
|
|
390
|
+
}
|
|
391
|
+
if (this.stateManager.state === 'ended') {
|
|
392
|
+
gsap.ticker.remove(this.renderTicker);
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
destroy() {
|
|
396
|
+
// Stop the timeline and remove the render ticker
|
|
397
|
+
gsap.ticker.remove(this.renderTicker);
|
|
398
|
+
// Clear the components map
|
|
399
|
+
this.initialized = false;
|
|
400
|
+
this.appManager.destroy();
|
|
401
|
+
this.domManager.destroy();
|
|
402
|
+
this.stateManager.destroy();
|
|
403
|
+
this.mediaManager.destroy();
|
|
404
|
+
this.timelineManager.destroy();
|
|
405
|
+
this.componentsManager.destroy();
|
|
406
|
+
// Remove the container from the DI container cache
|
|
407
|
+
removeContainer(this.sceneData.id);
|
|
408
|
+
}
|
|
409
|
+
}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import { SubtitleWithCompactWordsShape, ColorTypeShape } from '..';
|
|
2
|
+
// ============================================================================
|
|
3
|
+
// TYPE GUARDS
|
|
4
|
+
// ============================================================================
|
|
5
|
+
/**
|
|
6
|
+
* Type guard to check if a word is a CompactWordTuple
|
|
7
|
+
*/
|
|
8
|
+
function isCompactWordTuple(word) {
|
|
9
|
+
return Array.isArray(word);
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Type guard to check if a word is a SubtitleWord
|
|
13
|
+
*/
|
|
14
|
+
function isSubtitleWord(word) {
|
|
15
|
+
return !Array.isArray(word);
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Safely access CompactWordTuple elements with bounds checking
|
|
19
|
+
*/
|
|
20
|
+
function safeGetTupleElement(tuple, index) {
|
|
21
|
+
return index < tuple.length ? tuple[index] : undefined;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Safely get text from CompactWordTuple with type checking
|
|
25
|
+
*/
|
|
26
|
+
function safeGetWordText(word) {
|
|
27
|
+
const text = safeGetTupleElement(word, 0);
|
|
28
|
+
return text || '';
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Safely get start time from CompactWordTuple with type checking
|
|
32
|
+
*/
|
|
33
|
+
function safeGetWordStart(word) {
|
|
34
|
+
const start = safeGetTupleElement(word, 1);
|
|
35
|
+
return start || 0;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Safely get end time from CompactWordTuple with type checking
|
|
39
|
+
*/
|
|
40
|
+
function safeGetWordEnd(word) {
|
|
41
|
+
const end = safeGetTupleElement(word, 2);
|
|
42
|
+
return end || 0;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Safely get metadata from CompactWordTuple with type checking
|
|
46
|
+
*/
|
|
47
|
+
function safeGetWordMeta(word) {
|
|
48
|
+
return safeGetTupleElement(word, 3);
|
|
49
|
+
}
|
|
50
|
+
// ============================================================================
|
|
51
|
+
// WORD PROPERTY ACCESS
|
|
52
|
+
// ============================================================================
|
|
53
|
+
function wordText(word) {
|
|
54
|
+
return isCompactWordTuple(word) ? safeGetWordText(word) : word.text;
|
|
55
|
+
}
|
|
56
|
+
function wordStart(word) {
|
|
57
|
+
return isCompactWordTuple(word) ? safeGetWordStart(word) : word.start_at;
|
|
58
|
+
}
|
|
59
|
+
function wordEnd(word) {
|
|
60
|
+
return isCompactWordTuple(word) ? safeGetWordEnd(word) : word.end_at;
|
|
61
|
+
}
|
|
62
|
+
function wordMeta(word) {
|
|
63
|
+
return safeGetWordMeta(word);
|
|
64
|
+
}
|
|
65
|
+
// ============================================================================
|
|
66
|
+
// METADATA HELPERS
|
|
67
|
+
// ============================================================================
|
|
68
|
+
function hasEmoji(word) {
|
|
69
|
+
return wordMeta(word)?.e ? true : false;
|
|
70
|
+
}
|
|
71
|
+
function getSpeakerIndex(word) {
|
|
72
|
+
return wordMeta(word)?.s;
|
|
73
|
+
}
|
|
74
|
+
function getColor(word) {
|
|
75
|
+
const color = wordMeta(word)?.c;
|
|
76
|
+
if (color) {
|
|
77
|
+
const c = ColorTypeShape.safeParse(color);
|
|
78
|
+
if (c.success) {
|
|
79
|
+
return c.data;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return undefined;
|
|
83
|
+
}
|
|
84
|
+
// ============================================================================
|
|
85
|
+
// FORMAT CONVERSION - WORD LEVEL
|
|
86
|
+
// ============================================================================
|
|
87
|
+
function compactToLegacy(wordTuple, parentSubtitleId, position) {
|
|
88
|
+
const [text, start_at, end_at] = wordTuple;
|
|
89
|
+
return {
|
|
90
|
+
id: `${parentSubtitleId}-word-${position}`,
|
|
91
|
+
start_at,
|
|
92
|
+
end_at,
|
|
93
|
+
text,
|
|
94
|
+
position
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
function legacyToCompact(word, includeMetadata = false) {
|
|
98
|
+
const tuple = [word.text, word.start_at, word.end_at];
|
|
99
|
+
if (includeMetadata) {
|
|
100
|
+
const metadata = {};
|
|
101
|
+
tuple.push(metadata);
|
|
102
|
+
}
|
|
103
|
+
return tuple;
|
|
104
|
+
}
|
|
105
|
+
// ============================================================================
|
|
106
|
+
// FORMAT CONVERSION - SUBTITLE LEVEL
|
|
107
|
+
// ============================================================================
|
|
108
|
+
/**
|
|
109
|
+
* Convert subtitle with legacy words to compact format
|
|
110
|
+
*/
|
|
111
|
+
function subtitleToCompact(subtitle) {
|
|
112
|
+
const compactWords = subtitle.words?.map((word) => legacyToCompact(word));
|
|
113
|
+
return {
|
|
114
|
+
...subtitle,
|
|
115
|
+
words: compactWords
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Convert subtitle with compact words to legacy format
|
|
120
|
+
*/
|
|
121
|
+
function subtitleToLegacy(subtitle) {
|
|
122
|
+
const legacyWords = subtitle.words?.map((wordTuple, index) => compactToLegacy(wordTuple, subtitle.id, index));
|
|
123
|
+
return {
|
|
124
|
+
...subtitle,
|
|
125
|
+
words: legacyWords,
|
|
126
|
+
// Convert ColorType properties to string if needed
|
|
127
|
+
color: typeof subtitle.color === 'string' ? subtitle.color : undefined,
|
|
128
|
+
background: typeof subtitle.background === 'string' ? subtitle.background : undefined
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
// ============================================================================
|
|
132
|
+
// COLLECTION UTILITIES
|
|
133
|
+
// ============================================================================
|
|
134
|
+
export function normalizeSubtitle(subtitle) {
|
|
135
|
+
// Start with the original subtitle as the candidate we'll validate
|
|
136
|
+
let candidate = subtitle;
|
|
137
|
+
// If words exist and are in legacy format, convert to compact
|
|
138
|
+
if (subtitle.words && subtitle.words.length > 0) {
|
|
139
|
+
const firstWord = subtitle.words[0];
|
|
140
|
+
if (Array.isArray(firstWord)) {
|
|
141
|
+
candidate = subtitle;
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
candidate = subtitleToCompact(subtitle);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
const resp = SubtitleWithCompactWordsShape.safeParse(candidate);
|
|
148
|
+
if (resp.success) {
|
|
149
|
+
return resp.data;
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
console.error('Failed to normalize subtitle', candidate, resp.error);
|
|
153
|
+
}
|
|
154
|
+
return null;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Normalize subtitle collection to use compact format internally
|
|
158
|
+
*/
|
|
159
|
+
function normalizeCollection(collection) {
|
|
160
|
+
const normalized = {};
|
|
161
|
+
for (const [key, subtitles] of Object.entries(collection)) {
|
|
162
|
+
normalized[key] = subtitles
|
|
163
|
+
.map((subtitle) => {
|
|
164
|
+
return normalizeSubtitle(subtitle); //subtitle as SubtitleWithCompactWords;
|
|
165
|
+
})
|
|
166
|
+
.filter(Boolean);
|
|
167
|
+
}
|
|
168
|
+
return normalized;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Calculate file size savings from using compact format
|
|
172
|
+
*/
|
|
173
|
+
function calculateSavings(collection) {
|
|
174
|
+
const legacyJson = JSON.stringify(collection);
|
|
175
|
+
const compactCollection = normalizeCollection(collection);
|
|
176
|
+
const compactJson = JSON.stringify(compactCollection);
|
|
177
|
+
const legacySize = legacyJson.length;
|
|
178
|
+
const compactSize = compactJson.length;
|
|
179
|
+
const savingsBytes = legacySize - compactSize;
|
|
180
|
+
const savingsPercent = (savingsBytes / legacySize) * 100;
|
|
181
|
+
return {
|
|
182
|
+
legacySize,
|
|
183
|
+
compactSize,
|
|
184
|
+
savingsBytes,
|
|
185
|
+
savingsPercent: Math.round(savingsPercent * 100) / 100
|
|
186
|
+
};
|
|
187
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { AnimationPreset } from './animationPreset.js';
|
|
2
|
+
import { SplitTextCache } from './SplitTextCache.js';
|
|
3
|
+
export declare class AnimationContext {
|
|
4
|
+
rootElement: any;
|
|
5
|
+
preset: AnimationPreset;
|
|
6
|
+
splitTextCache: SplitTextCache;
|
|
7
|
+
data: Record<string, any>;
|
|
8
|
+
private animationTargetDuration;
|
|
9
|
+
constructor(rootElement: any, preset: AnimationPreset, splitTextCache: SplitTextCache, data?: Record<string, any>);
|
|
10
|
+
get endAnchor(): number;
|
|
11
|
+
setAnimationTargetDuration(duration: number): void;
|
|
12
|
+
getData(key: string): any;
|
|
13
|
+
getElement(targetQuery: string): any;
|
|
14
|
+
getDuration(): number;
|
|
15
|
+
getAnimationTargetDuration(): number;
|
|
16
|
+
getAllData(): Record<string, any>;
|
|
17
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { SplitTextCache } from './SplitTextCache.js';
|
|
2
|
+
export class AnimationContext {
|
|
3
|
+
rootElement;
|
|
4
|
+
preset;
|
|
5
|
+
splitTextCache;
|
|
6
|
+
data;
|
|
7
|
+
animationTargetDuration;
|
|
8
|
+
constructor(rootElement, preset, splitTextCache, data = {}) {
|
|
9
|
+
this.rootElement = rootElement;
|
|
10
|
+
this.preset = preset;
|
|
11
|
+
this.splitTextCache = splitTextCache;
|
|
12
|
+
this.data = data;
|
|
13
|
+
let textShadow = '';
|
|
14
|
+
if (this.rootElement instanceof HTMLElement) {
|
|
15
|
+
textShadow = this.rootElement.style.textShadow ?? '';
|
|
16
|
+
}
|
|
17
|
+
this.data.textShadow = textShadow;
|
|
18
|
+
this.animationTargetDuration = 0;
|
|
19
|
+
this.preset.preset.data = {
|
|
20
|
+
...this.preset.preset.data,
|
|
21
|
+
...this.data
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
get endAnchor() {
|
|
25
|
+
return this.animationTargetDuration - this.getDuration();
|
|
26
|
+
}
|
|
27
|
+
setAnimationTargetDuration(duration) {
|
|
28
|
+
this.animationTargetDuration = duration;
|
|
29
|
+
}
|
|
30
|
+
getData(key) {
|
|
31
|
+
return this.data[key];
|
|
32
|
+
}
|
|
33
|
+
getElement(targetQuery) {
|
|
34
|
+
if (!(this.rootElement instanceof HTMLElement)) {
|
|
35
|
+
console.warn(`Root element is not an HTMLElement. Cannot target ${targetQuery}`);
|
|
36
|
+
return this.rootElement;
|
|
37
|
+
}
|
|
38
|
+
const splitTargets = ['words', 'lines', 'chars'];
|
|
39
|
+
if (splitTargets.includes(targetQuery)) {
|
|
40
|
+
// Get the splitText instance from the global singleton cache
|
|
41
|
+
return this.splitTextCache.getSplitText(this.rootElement, targetQuery);
|
|
42
|
+
}
|
|
43
|
+
if (targetQuery.startsWith('#') || targetQuery.startsWith('.')) {
|
|
44
|
+
const element = this.rootElement.querySelector(targetQuery);
|
|
45
|
+
if (!element) {
|
|
46
|
+
console.warn(`Element not found for query: ${targetQuery}`);
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
return element;
|
|
50
|
+
}
|
|
51
|
+
if (targetQuery === 'child') {
|
|
52
|
+
if (this.rootElement.children.length === 0) {
|
|
53
|
+
console.warn('No children found for "child" query');
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
return this.rootElement.children[0];
|
|
57
|
+
}
|
|
58
|
+
if (targetQuery === 'children') {
|
|
59
|
+
return this.rootElement.children;
|
|
60
|
+
}
|
|
61
|
+
return this.rootElement;
|
|
62
|
+
}
|
|
63
|
+
getDuration() {
|
|
64
|
+
return this.preset.duration;
|
|
65
|
+
}
|
|
66
|
+
getAnimationTargetDuration() {
|
|
67
|
+
return this.animationTargetDuration;
|
|
68
|
+
}
|
|
69
|
+
getAllData() {
|
|
70
|
+
return this.data;
|
|
71
|
+
}
|
|
72
|
+
}
|