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.
Files changed (219) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +213 -0
  3. package/dist/DIContainer.d.ts +4 -0
  4. package/dist/DIContainer.js +145 -0
  5. package/dist/SceneBuilder.svelte.d.ts +8574 -0
  6. package/dist/SceneBuilder.svelte.js +409 -0
  7. package/dist/adapters/subtitleHelpers.d.ts +2 -0
  8. package/dist/adapters/subtitleHelpers.js +187 -0
  9. package/dist/animations/AnimationContext.d.ts +17 -0
  10. package/dist/animations/AnimationContext.js +72 -0
  11. package/dist/animations/AnimationPresetsRegister.d.ts +362 -0
  12. package/dist/animations/AnimationPresetsRegister.js +20 -0
  13. package/dist/animations/AnimationSetup.d.ts +8 -0
  14. package/dist/animations/AnimationSetup.js +30 -0
  15. package/dist/animations/SplitTextCache.d.ts +28 -0
  16. package/dist/animations/SplitTextCache.js +68 -0
  17. package/dist/animations/animationBuilder.d.ts +31 -0
  18. package/dist/animations/animationBuilder.js +255 -0
  19. package/dist/animations/animationPreset.d.ts +7 -0
  20. package/dist/animations/animationPreset.js +31 -0
  21. package/dist/animations/builders/AnimationPresetFactory.d.ts +43 -0
  22. package/dist/animations/builders/AnimationPresetFactory.js +139 -0
  23. package/dist/animations/builders/LineHighlighterAnimationBuilder.d.ts +16 -0
  24. package/dist/animations/builders/LineHighlighterAnimationBuilder.js +183 -0
  25. package/dist/animations/builders/WordHighlighterAnimationBuilder.d.ts +15 -0
  26. package/dist/animations/builders/WordHighlighterAnimationBuilder.js +180 -0
  27. package/dist/animations/engines/AnimationEngineAdaptor.d.ts +107 -0
  28. package/dist/animations/engines/AnimationEngineAdaptor.js +1 -0
  29. package/dist/animations/engines/GSAPEngineAdaptor.d.ts +21 -0
  30. package/dist/animations/engines/GSAPEngineAdaptor.js +145 -0
  31. package/dist/animations/presets/index.d.ts +2 -0
  32. package/dist/animations/presets/index.js +3 -0
  33. package/dist/animations/presets/lines.d.ts +52 -0
  34. package/dist/animations/presets/lines.js +547 -0
  35. package/dist/animations/presets/words.d.ts +31 -0
  36. package/dist/animations/presets/words.js +268 -0
  37. package/dist/animations/transformers/AnimationReferenceTransformer.d.ts +9 -0
  38. package/dist/animations/transformers/AnimationReferenceTransformer.js +114 -0
  39. package/dist/builders/PixiComponentBuilder.d.ts +63 -0
  40. package/dist/builders/PixiComponentBuilder.js +112 -0
  41. package/dist/builders/_ComponentState.svelte.d.ts +795 -0
  42. package/dist/builders/_ComponentState.svelte.js +203 -0
  43. package/dist/builders/html/HtmlBuilder.d.ts +66 -0
  44. package/dist/builders/html/HtmlBuilder.js +171 -0
  45. package/dist/builders/html/HtmlBuilderFactory.d.ts +27 -0
  46. package/dist/builders/html/HtmlBuilderFactory.js +30 -0
  47. package/dist/builders/html/StyleBuilder.d.ts +13 -0
  48. package/dist/builders/html/StyleBuilder.js +133 -0
  49. package/dist/builders/html/StyleProcessor.d.ts +9 -0
  50. package/dist/builders/html/StyleProcessor.js +1 -0
  51. package/dist/builders/html/TextComponentHtmlBuilder.d.ts +16 -0
  52. package/dist/builders/html/TextComponentHtmlBuilder.js +93 -0
  53. package/dist/builders/html/TextShadowBuilder.d.ts +60 -0
  54. package/dist/builders/html/TextShadowBuilder.js +227 -0
  55. package/dist/builders/html/processors/AppearanceStyleProcessor.d.ts +5 -0
  56. package/dist/builders/html/processors/AppearanceStyleProcessor.js +57 -0
  57. package/dist/builders/html/processors/TextAppearanceStyleProcessor.d.ts +5 -0
  58. package/dist/builders/html/processors/TextAppearanceStyleProcessor.js +37 -0
  59. package/dist/builders/html/processors/TextEffectsStyleProcessor.d.ts +6 -0
  60. package/dist/builders/html/processors/TextEffectsStyleProcessor.js +68 -0
  61. package/dist/commands/Command.d.ts +6 -0
  62. package/dist/commands/Command.js +1 -0
  63. package/dist/commands/CommandRunner.d.ts +28 -0
  64. package/dist/commands/CommandRunner.js +81 -0
  65. package/dist/commands/CommandTypes.d.ts +11 -0
  66. package/dist/commands/CommandTypes.js +13 -0
  67. package/dist/commands/PauseCommand.d.ts +4 -0
  68. package/dist/commands/PauseCommand.js +5 -0
  69. package/dist/commands/PlayCommand.d.ts +4 -0
  70. package/dist/commands/PlayCommand.js +6 -0
  71. package/dist/commands/RenderCommand.d.ts +15 -0
  72. package/dist/commands/RenderCommand.js +18 -0
  73. package/dist/commands/RenderFrameCommand.d.ts +17 -0
  74. package/dist/commands/RenderFrameCommand.js +93 -0
  75. package/dist/commands/ReplaceSourceOnTimeCommand.d.ts +4 -0
  76. package/dist/commands/ReplaceSourceOnTimeCommand.js +22 -0
  77. package/dist/commands/SeekCommand.d.ts +15 -0
  78. package/dist/commands/SeekCommand.js +39 -0
  79. package/dist/commands/UpdateComponentCommand.d.ts +4 -0
  80. package/dist/commands/UpdateComponentCommand.js +17 -0
  81. package/dist/components/AnimatedGIF.d.ts +201 -0
  82. package/dist/components/AnimatedGIF.js +391 -0
  83. package/dist/components/Component.svelte.d.ts +33 -0
  84. package/dist/components/Component.svelte.js +152 -0
  85. package/dist/components/ComponentContext.svelte.d.ts +33 -0
  86. package/dist/components/ComponentContext.svelte.js +105 -0
  87. package/dist/components/hooks/AnimationHook.d.ts +25 -0
  88. package/dist/components/hooks/AnimationHook.js +180 -0
  89. package/dist/components/hooks/CanvasShapeHook.d.ts +12 -0
  90. package/dist/components/hooks/CanvasShapeHook.js +229 -0
  91. package/dist/components/hooks/HtmlAnimationHook.d.ts +8 -0
  92. package/dist/components/hooks/HtmlAnimationHook.js +70 -0
  93. package/dist/components/hooks/HtmlTextHook.d.ts +16 -0
  94. package/dist/components/hooks/HtmlTextHook.js +102 -0
  95. package/dist/components/hooks/HtmlToCanvasHook.d.ts +16 -0
  96. package/dist/components/hooks/HtmlToCanvasHook.js +148 -0
  97. package/dist/components/hooks/ImageHook.d.ts +10 -0
  98. package/dist/components/hooks/ImageHook.js +45 -0
  99. package/dist/components/hooks/MediaHook.d.ts +15 -0
  100. package/dist/components/hooks/MediaHook.js +252 -0
  101. package/dist/components/hooks/MediaSeekingHook.d.ts +12 -0
  102. package/dist/components/hooks/MediaSeekingHook.js +204 -0
  103. package/dist/components/hooks/PixiDisplayObjectHook.d.ts +15 -0
  104. package/dist/components/hooks/PixiDisplayObjectHook.js +77 -0
  105. package/dist/components/hooks/PixiGifHook.d.ts +15 -0
  106. package/dist/components/hooks/PixiGifHook.js +97 -0
  107. package/dist/components/hooks/PixiProgressShapeHook.d.ts +12 -0
  108. package/dist/components/hooks/PixiProgressShapeHook.js +128 -0
  109. package/dist/components/hooks/PixiSplitScreenDisplayObjectHook.d.ts +21 -0
  110. package/dist/components/hooks/PixiSplitScreenDisplayObjectHook.js +210 -0
  111. package/dist/components/hooks/PixiTextureHook.d.ts +7 -0
  112. package/dist/components/hooks/PixiTextureHook.js +29 -0
  113. package/dist/components/hooks/PixiVideoTextureHook.d.ts +10 -0
  114. package/dist/components/hooks/PixiVideoTextureHook.js +35 -0
  115. package/dist/components/hooks/SubtitlesHook.d.ts +88 -0
  116. package/dist/components/hooks/SubtitlesHook.js +199 -0
  117. package/dist/components/hooks/VerifyGifHook.d.ts +7 -0
  118. package/dist/components/hooks/VerifyGifHook.js +27 -0
  119. package/dist/components/hooks/VerifyImageHook.d.ts +7 -0
  120. package/dist/components/hooks/VerifyImageHook.js +27 -0
  121. package/dist/components/hooks/VerifyMediaHook.d.ts +7 -0
  122. package/dist/components/hooks/VerifyMediaHook.js +21 -0
  123. package/dist/components/hooks/shapes/progress/CustomProgressRenderer.d.ts +8 -0
  124. package/dist/components/hooks/shapes/progress/CustomProgressRenderer.js +53 -0
  125. package/dist/components/hooks/shapes/progress/DoubleProgressRenderer.d.ts +8 -0
  126. package/dist/components/hooks/shapes/progress/DoubleProgressRenderer.js +69 -0
  127. package/dist/components/hooks/shapes/progress/LinearProgressRenderer.d.ts +8 -0
  128. package/dist/components/hooks/shapes/progress/LinearProgressRenderer.js +60 -0
  129. package/dist/components/hooks/shapes/progress/PerimeterProgressRenderer.d.ts +9 -0
  130. package/dist/components/hooks/shapes/progress/PerimeterProgressRenderer.js +213 -0
  131. package/dist/components/hooks/shapes/progress/ProgressRenderer.d.ts +17 -0
  132. package/dist/components/hooks/shapes/progress/ProgressRenderer.js +75 -0
  133. package/dist/components/hooks/shapes/progress/RadialProgressRenderer.d.ts +8 -0
  134. package/dist/components/hooks/shapes/progress/RadialProgressRenderer.js +50 -0
  135. package/dist/components/hooks/shapes/progress/index.d.ts +6 -0
  136. package/dist/components/hooks/shapes/progress/index.js +6 -0
  137. package/dist/composers/componentComposer.d.ts +55 -0
  138. package/dist/composers/componentComposer.js +118 -0
  139. package/dist/composers/layerComposer.d.ts +46 -0
  140. package/dist/composers/layerComposer.js +79 -0
  141. package/dist/composers/sceneComposer.d.ts +48 -0
  142. package/dist/composers/sceneComposer.js +92 -0
  143. package/dist/constants.d.ts +12 -0
  144. package/dist/constants.js +14 -0
  145. package/dist/directors/ComponentDirector.d.ts +20 -0
  146. package/dist/directors/ComponentDirector.js +86 -0
  147. package/dist/factories/SceneBuilderFactory.d.ts +15 -0
  148. package/dist/factories/SceneBuilderFactory.js +51 -0
  149. package/dist/fonts/GoogleFontsProvider.d.ts +12 -0
  150. package/dist/fonts/GoogleFontsProvider.js +125 -0
  151. package/dist/fonts/fontLoader.d.ts +15 -0
  152. package/dist/fonts/fontLoader.js +41 -0
  153. package/dist/fonts/types.d.ts +1 -0
  154. package/dist/fonts/types.js +1 -0
  155. package/dist/index.d.ts +11 -0
  156. package/dist/index.js +14 -0
  157. package/dist/layers/Layer.svelte.d.ts +8492 -0
  158. package/dist/layers/Layer.svelte.js +125 -0
  159. package/dist/managers/AppManager.svelte.d.ts +23 -0
  160. package/dist/managers/AppManager.svelte.js +89 -0
  161. package/dist/managers/ComponentsManager.svelte.d.ts +49 -0
  162. package/dist/managers/ComponentsManager.svelte.js +247 -0
  163. package/dist/managers/DomManager.d.ts +18 -0
  164. package/dist/managers/DomManager.js +73 -0
  165. package/dist/managers/EventManager.d.ts +7 -0
  166. package/dist/managers/EventManager.js +22 -0
  167. package/dist/managers/LayersManager.svelte.d.ts +8499 -0
  168. package/dist/managers/LayersManager.svelte.js +176 -0
  169. package/dist/managers/MediaManager.d.ts +32 -0
  170. package/dist/managers/MediaManager.js +243 -0
  171. package/dist/managers/RenderManager.d.ts +23 -0
  172. package/dist/managers/RenderManager.js +59 -0
  173. package/dist/managers/StateManager.svelte.d.ts +8746 -0
  174. package/dist/managers/StateManager.svelte.js +272 -0
  175. package/dist/managers/SubtitlesManager.svelte.d.ts +261 -0
  176. package/dist/managers/SubtitlesManager.svelte.js +1385 -0
  177. package/dist/managers/TimeManager.svelte.d.ts +6 -0
  178. package/dist/managers/TimeManager.svelte.js +18 -0
  179. package/dist/managers/TimelineManager.svelte.d.ts +25 -0
  180. package/dist/managers/TimelineManager.svelte.js +152 -0
  181. package/dist/registers.d.ts +12 -0
  182. package/dist/registers.js +29 -0
  183. package/dist/schemas/runtime/index.d.ts +3 -0
  184. package/dist/schemas/runtime/index.js +4 -0
  185. package/dist/schemas/runtime/types.d.ts +323 -0
  186. package/dist/schemas/runtime/types.js +12 -0
  187. package/dist/schemas/scene/animations.d.ts +89738 -0
  188. package/dist/schemas/scene/animations.js +211 -0
  189. package/dist/schemas/scene/components.js +515 -0
  190. package/dist/schemas/scene/core.js +160 -0
  191. package/dist/schemas/scene/index.d.ts +22 -0
  192. package/dist/schemas/scene/index.js +10 -0
  193. package/dist/schemas/scene/properties.d.ts +914 -0
  194. package/dist/schemas/scene/properties.js +398 -0
  195. package/dist/schemas/scene/subtitles.d.ts +1141 -0
  196. package/dist/schemas/scene/subtitles.js +111 -0
  197. package/dist/schemas/scene/utils.d.ts +1 -0
  198. package/dist/schemas/scene/utils.js +5 -0
  199. package/dist/seeds/SeedFactory.d.ts +59 -0
  200. package/dist/seeds/SeedFactory.js +99 -0
  201. package/dist/seeds/index.d.ts +8 -0
  202. package/dist/seeds/index.js +8 -0
  203. package/dist/transformers/ColorTransformer.d.ts +5 -0
  204. package/dist/transformers/ColorTransformer.js +67 -0
  205. package/dist/transformers/PixiColorTransformer.d.ts +22 -0
  206. package/dist/transformers/PixiColorTransformer.js +104 -0
  207. package/dist/utils/canvas.d.ts +6 -0
  208. package/dist/utils/canvas.js +18 -0
  209. package/dist/utils/document.d.ts +2 -0
  210. package/dist/utils/document.js +36 -0
  211. package/dist/utils/emoji.d.ts +10 -0
  212. package/dist/utils/emoji.js +51 -0
  213. package/dist/utils/html.d.ts +4 -0
  214. package/dist/utils/html.js +45 -0
  215. package/dist/utils/svgGenerator.d.ts +20 -0
  216. package/dist/utils/svgGenerator.js +103 -0
  217. package/dist/utils/utils.d.ts +5 -0
  218. package/dist/utils/utils.js +125 -0
  219. package/package.json +96 -0
@@ -0,0 +1,105 @@
1
+ import { StateManager } from '../managers/StateManager.svelte.js';
2
+ import { EventManager } from '../managers/EventManager.js';
3
+ export class ComponentContext {
4
+ #data;
5
+ // context data replacement, useful for modifiing context of subtitles
6
+ #contextData;
7
+ disabled = false;
8
+ resources = new Map();
9
+ state;
10
+ eventManager;
11
+ constructor(cradle) {
12
+ this.state = cradle.stateManager;
13
+ this.eventManager = cradle.eventManager;
14
+ }
15
+ setComponentProps(props) {
16
+ this.#data = props;
17
+ this.#contextData = undefined;
18
+ }
19
+ get duration() {
20
+ // TODO maybe we will need to get duration from the contextData
21
+ return this.#data.duration;
22
+ }
23
+ get contextData() {
24
+ return this.#contextData ? this.#contextData : this.#data.getData();
25
+ }
26
+ get data() {
27
+ return this.#data.getData();
28
+ }
29
+ get id() {
30
+ return this.data.id;
31
+ }
32
+ get type() {
33
+ return this.data.type;
34
+ }
35
+ get isActive() {
36
+ const currentTime = this.sceneState.currentTime;
37
+ const startAt = this.data.timeline.startAt;
38
+ const endAt = this.data.timeline.endAt;
39
+ // Add small tolerance to handle floating point precision issues
40
+ const tolerance = 1e-10;
41
+ return currentTime >= startAt - tolerance && currentTime <= endAt + tolerance;
42
+ }
43
+ get progress() {
44
+ const currentTime = this.sceneState.currentTime;
45
+ const startAt = this.data.timeline.startAt;
46
+ const endAt = this.data.timeline.endAt;
47
+ const duration = endAt - startAt;
48
+ if (duration === 0)
49
+ return 0;
50
+ // Calculate progress as percentage (0-1)
51
+ const progress = Math.max(0, Math.min(1, (currentTime - startAt) / duration));
52
+ return progress;
53
+ }
54
+ get currentComponentTime() {
55
+ const startAt = this.state.transformTime(this.data.timeline.startAt);
56
+ let startAtModifier = 0;
57
+ if (this.data.type === 'VIDEO') {
58
+ startAtModifier = this.data.source.startAt ?? 0;
59
+ }
60
+ // Calculate relative time from start of component
61
+ const relativeTime = this.sceneState.currentTime - startAt;
62
+ // Add starting_time modifier
63
+ return this.state.transformTime(startAtModifier, true) + relativeTime;
64
+ }
65
+ get componentTimelineTime() {
66
+ const startAt = this.data.timeline.startAt;
67
+ const endAt = this.data.timeline.endAt;
68
+ const duration = endAt - startAt;
69
+ const relativeTime = this.sceneState.currentTime - startAt;
70
+ if (relativeTime < 0 || relativeTime > duration) {
71
+ return undefined;
72
+ }
73
+ return this.state.transformTime(relativeTime);
74
+ }
75
+ get currentTime() {
76
+ return this.state.currentTime;
77
+ }
78
+ get sceneState() {
79
+ return this.state;
80
+ }
81
+ updateContextData(data) {
82
+ this.#contextData = data;
83
+ }
84
+ resetContextData() {
85
+ this.#contextData = undefined;
86
+ }
87
+ getResource(type) {
88
+ return this.resources.get(type);
89
+ }
90
+ setResource(type, resource) {
91
+ this.resources.set(type, resource);
92
+ }
93
+ removeResource(type) {
94
+ this.resources.delete(type);
95
+ }
96
+ async runHooks(hooks, type) {
97
+ // Sort handlers by priority (low to high, meaning 1 has higher priority then 100)
98
+ const sortedHooks = [...hooks].sort((a, b) => (a.priority ?? 0) - (b.priority ?? 0));
99
+ for (let i = 0; i < sortedHooks.length; i += 1) {
100
+ const handler = sortedHooks[i];
101
+ await handler.handle(type, this);
102
+ }
103
+ }
104
+ destroy() { }
105
+ }
@@ -0,0 +1,25 @@
1
+ import type { IComponentContext, IComponentHook, HookType } from '../..';
2
+ import { TimelineManager } from '../../managers/TimelineManager.svelte.js';
3
+ import type { ComponentAnimationTransformer } from '../../animations/transformers/AnimationReferenceTransformer.js';
4
+ import { SplitTextCache } from '../../animations/SplitTextCache.js';
5
+ /**
6
+ * Animation hook for managing component animations
7
+ * This hook can be applied to any component type and handles animation lifecycle
8
+ */
9
+ export declare class AnimationHook implements IComponentHook {
10
+ #private;
11
+ private timeline;
12
+ private splitTextCache;
13
+ types: HookType[];
14
+ priority: number;
15
+ animTransformer: ComponentAnimationTransformer;
16
+ constructor(cradle: {
17
+ timelineManager: TimelineManager;
18
+ componentAnimationTransformer: ComponentAnimationTransformer;
19
+ splitTextCache: SplitTextCache;
20
+ });
21
+ /**
22
+ * Hook handle method
23
+ */
24
+ handle(type: HookType, context: IComponentContext): Promise<void>;
25
+ }
@@ -0,0 +1,180 @@
1
+ import { AnimationPresetShape } from '../..';
2
+ import { TimelineManager } from '../../managers/TimelineManager.svelte.js';
3
+ import { AnimationContext } from '../../animations/AnimationContext.js';
4
+ import { GsapEngineAdaptor } from '../../animations/engines/GSAPEngineAdaptor.js';
5
+ import { AnimationBuilder } from '../../animations/animationBuilder.js';
6
+ import { AnimationPreset } from '../../animations/animationPreset.js';
7
+ import { gsap } from 'gsap';
8
+ import { SplitTextCache } from '../../animations/SplitTextCache.js';
9
+ import { WordHighlighterAnimationBuilder } from '../../animations/builders/WordHighlighterAnimationBuilder.js';
10
+ import { LineHighlighterAnimationBuilder } from '../../animations/builders/LineHighlighterAnimationBuilder.js';
11
+ /**
12
+ * Animation hook for managing component animations
13
+ * This hook can be applied to any component type and handles animation lifecycle
14
+ */
15
+ export class AnimationHook {
16
+ #handlers = {
17
+ setup: this.#handleSetup.bind(this),
18
+ destroy: this.#handleDestroy.bind(this),
19
+ update: this.#handleUpdate.bind(this),
20
+ refresh: this.#handleRefresh.bind(this),
21
+ 'refresh:animation': this.#handleRefresh.bind(this)
22
+ };
23
+ #context;
24
+ #currentId = undefined;
25
+ #componentTimeline = undefined;
26
+ #animationsBuilt = false;
27
+ timeline;
28
+ splitTextCache;
29
+ types = Object.keys(this.#handlers);
30
+ priority = 1;
31
+ animTransformer;
32
+ constructor(cradle) {
33
+ this.timeline = cradle.timelineManager;
34
+ this.animTransformer = cradle.componentAnimationTransformer;
35
+ this.splitTextCache = cradle.splitTextCache;
36
+ }
37
+ #getComponentAnimations() {
38
+ const target = this.#context.resources.get('animationTarget');
39
+ const animationData = this.#context.resources.get('animationData') ??
40
+ {};
41
+ const animations = [...(this.#context.contextData.animations.list ?? [])];
42
+ const customAnimations = WordHighlighterAnimationBuilder.build(this.#context.contextData, target, animationData, this.splitTextCache);
43
+ const lineAnimations = LineHighlighterAnimationBuilder.build(this.#context.contextData, target, animationData, this.splitTextCache);
44
+ animations.push(...customAnimations);
45
+ animations.push(...lineAnimations);
46
+ return animations;
47
+ }
48
+ /**
49
+ * Handle hook setup
50
+ */
51
+ async #handleSetup() {
52
+ if (this.#componentTimeline !== undefined) {
53
+ return;
54
+ }
55
+ // Get component animations
56
+ if (!this.#context.data.animations.enabled) {
57
+ return;
58
+ }
59
+ const target = this.#context.resources.get('animationTarget');
60
+ if (!target) {
61
+ // console.warn("Animation target not specified. Skipping animations")
62
+ return;
63
+ }
64
+ const animations = this.#getComponentAnimations();
65
+ if (!animations?.length) {
66
+ return;
67
+ }
68
+ // if (this.#animationsBuilt) {
69
+ // return;
70
+ // }
71
+ this.#currentId = this.#context.contextData.id;
72
+ const animationTimes = animations.map((anim) => {
73
+ return {
74
+ id: anim.id,
75
+ startAt: anim.startAt ?? 0
76
+ };
77
+ });
78
+ // first we need to transform / normalize strings or simplified animations into animations
79
+ const anims = animations
80
+ .map((anim) => {
81
+ const animation = this.animTransformer.handle(anim.animation);
82
+ if (animation) {
83
+ animation.id = anim.id;
84
+ return animation;
85
+ }
86
+ })
87
+ .filter((anim) => anim !== null);
88
+ // build timeline and add it to the main timeline
89
+ const animationData = this.#context.resources.get('animationData') ??
90
+ {};
91
+ const animationsTimeline = gsap.timeline();
92
+ let hasAnimations = false;
93
+ for (const anim of anims) {
94
+ try {
95
+ if (!anim) {
96
+ continue;
97
+ }
98
+ const parsedPreset = AnimationPresetShape.safeParse(anim);
99
+ if (!parsedPreset.success) {
100
+ continue;
101
+ }
102
+ const animationPreset = new AnimationPreset(anim);
103
+ const animationContext = new AnimationContext(target, animationPreset, this.splitTextCache, {
104
+ ...animationData
105
+ });
106
+ animationContext.setAnimationTargetDuration(this.#context.duration);
107
+ // 3. Instantiate Engine Adaptor
108
+ const gsapAdaptor = new GsapEngineAdaptor();
109
+ // 4. Build the Animation
110
+ const builder = new AnimationBuilder(animationContext, gsapAdaptor);
111
+ const animation = builder.build();
112
+ if (animation) {
113
+ // pass in animation start time so it starts at the correct time, relative to the component
114
+ const animationTime = animationTimes.find((at) => at.id === anim.id)?.startAt;
115
+ animationsTimeline.add(animation, animationTime ?? 0);
116
+ hasAnimations = true;
117
+ }
118
+ this.#animationsBuilt = true;
119
+ }
120
+ catch (error) {
121
+ console.error('Error building animation', error, anim);
122
+ }
123
+ }
124
+ if (hasAnimations) {
125
+ this.#componentTimeline = animationsTimeline;
126
+ this.timeline.addLabel(this.#context.contextData.id, this.#context.contextData.timeline.startAt);
127
+ this.timeline.add(this.#componentTimeline, this.#context.contextData.id);
128
+ }
129
+ }
130
+ /**
131
+ * Handle animation refresh
132
+ */
133
+ async #handleRefresh() {
134
+ await this.#handleDestroy();
135
+ await this.#handleSetup();
136
+ }
137
+ /**
138
+ * Handle component updates
139
+ */
140
+ async #handleUpdate() {
141
+ // Check if component ID has changed
142
+ if (this.#context.isActive && this.#currentId !== this.#context.contextData.id) {
143
+ await this.#handleRefresh();
144
+ }
145
+ // Setup if component becomes active and animations aren't set up
146
+ if (this.#context.isActive) {
147
+ // && !this.#controls
148
+ await this.#handleSetup();
149
+ }
150
+ }
151
+ /**
152
+ * Handle hook destruction
153
+ */
154
+ async #handleDestroy() {
155
+ // this.#controls
156
+ this.#currentId = undefined;
157
+ this.#componentTimeline?.revert();
158
+ this.#componentTimeline?.kill();
159
+ this.#componentTimeline = undefined;
160
+ if (this.#context.resources.get('animationTarget') instanceof HTMLElement) {
161
+ // clear cache for the animation target so it works on rewind / fast forward as underlying instances were destroyed by revert
162
+ this.splitTextCache.clearCache(this.#context.resources.get('animationTarget'));
163
+ }
164
+ }
165
+ /**
166
+ * Hook handle method
167
+ */
168
+ async handle(type, context) {
169
+ this.#context = context;
170
+ // Skip if component is disabled
171
+ if (this.#context.disabled) {
172
+ return;
173
+ }
174
+ // Call the appropriate handler
175
+ const handler = this.#handlers[type];
176
+ if (handler) {
177
+ await handler();
178
+ }
179
+ }
180
+ }
@@ -0,0 +1,12 @@
1
+ import type { IComponentContext, IComponentHook, HookType } from '../..';
2
+ import { StateManager } from '../../managers/StateManager.svelte.js';
3
+ export declare class CanvasShapeHook implements IComponentHook {
4
+ #private;
5
+ types: HookType[];
6
+ priority: number;
7
+ private state;
8
+ constructor(cradle: {
9
+ stateManager: StateManager;
10
+ });
11
+ handle(type: HookType, context: IComponentContext): Promise<void>;
12
+ }
@@ -0,0 +1,229 @@
1
+ import { computeXYAngle } from '../../utils/canvas.js';
2
+ import { StateManager } from '../../managers/StateManager.svelte.js';
3
+ export class CanvasShapeHook {
4
+ types = ['setup', 'update', 'destroy'];
5
+ priority = 1;
6
+ #context;
7
+ #resource;
8
+ #width;
9
+ #height;
10
+ state;
11
+ constructor(cradle) {
12
+ this.state = cradle.stateManager;
13
+ }
14
+ #shapeRenderers = new Map([
15
+ ['rectangle', this.#renderRectangle.bind(this)],
16
+ ['circle', this.#renderCircle.bind(this)],
17
+ ['triangle', this.#renderTriangle.bind(this)],
18
+ ['star', this.#renderStar.bind(this)],
19
+ ['ellipse', this.#renderEllipse.bind(this)],
20
+ ['polygon', this.#renderPolygon.bind(this)],
21
+ ['path', this.#renderPath.bind(this)]
22
+ ]);
23
+ #renderShape(ctx) {
24
+ if (this.#context.data.type !== 'SHAPE')
25
+ return;
26
+ const shapeData = this.#context.data;
27
+ const renderer = this.#shapeRenderers.get(shapeData.shape.type);
28
+ if (renderer) {
29
+ renderer(ctx);
30
+ }
31
+ }
32
+ #renderRectangle(ctx) {
33
+ this.#applyFill(ctx);
34
+ ctx.fillRect(0, 0, this.#width, this.#height);
35
+ }
36
+ #renderEllipse(ctx) {
37
+ this.#applyFill(ctx);
38
+ const centerX = this.#width / 2;
39
+ const centerY = this.#height / 2;
40
+ const radiusX = this.#width / 2;
41
+ const radiusY = this.#height / 2;
42
+ ctx.beginPath();
43
+ ctx.ellipse(centerX, centerY, radiusX, radiusY, 0, 0, Math.PI * 2);
44
+ ctx.fill();
45
+ }
46
+ #renderPolygon(ctx) {
47
+ if (this.#context.data.type !== 'SHAPE')
48
+ return;
49
+ const shapeData = this.#context.data;
50
+ // Handle new schema structure
51
+ const points = 'points' in shapeData.shape ? shapeData.shape.points : [];
52
+ if (!points || points.length < 3)
53
+ return;
54
+ this.#applyFill(ctx);
55
+ ctx.beginPath();
56
+ ctx.moveTo(points[0].x, points[0].y);
57
+ for (let i = 1; i < points.length; i++) {
58
+ ctx.lineTo(points[i].x, points[i].y);
59
+ }
60
+ ctx.closePath();
61
+ ctx.fill();
62
+ }
63
+ #renderPath(ctx) {
64
+ if (this.#context.data.type !== 'SHAPE')
65
+ return;
66
+ const shapeData = this.#context.data;
67
+ // Handle new schema structure
68
+ const pathData = 'pathData' in shapeData.shape ? shapeData.shape.pathData : '';
69
+ if (!pathData)
70
+ return;
71
+ this.#applyFill(ctx);
72
+ const path = new Path2D(pathData);
73
+ ctx.fill(path);
74
+ }
75
+ #renderCircle(ctx) {
76
+ this.#applyFill(ctx);
77
+ const centerX = this.#width / 2;
78
+ const centerY = this.#height / 2;
79
+ const radius = Math.min(this.#width, this.#height) / 2;
80
+ ctx.beginPath();
81
+ ctx.arc(centerX, centerY, radius, 0, Math.PI * 2);
82
+ ctx.fill();
83
+ }
84
+ #renderTriangle(ctx) {
85
+ this.#applyFill(ctx);
86
+ ctx.beginPath();
87
+ ctx.moveTo(this.#width / 2, 0);
88
+ ctx.lineTo(this.#width, this.#height);
89
+ ctx.lineTo(0, this.#height);
90
+ ctx.closePath();
91
+ ctx.fill();
92
+ }
93
+ #renderStar(ctx) {
94
+ this.#applyFill(ctx);
95
+ const centerX = this.#width / 2;
96
+ const centerY = this.#height / 2;
97
+ const outerRadius = Math.min(this.#width, this.#height) / 2;
98
+ const innerRadius = outerRadius * 0.4;
99
+ const spikes = 5;
100
+ ctx.beginPath();
101
+ ctx.moveTo(centerX, centerY - outerRadius);
102
+ for (let i = 0; i < spikes * 2; i++) {
103
+ const radius = i % 2 === 0 ? outerRadius : innerRadius;
104
+ const angle = (Math.PI * i) / spikes - Math.PI / 2;
105
+ const x = centerX + Math.cos(angle) * radius;
106
+ const y = centerY + Math.sin(angle) * radius;
107
+ ctx.lineTo(x, y);
108
+ }
109
+ ctx.closePath();
110
+ ctx.fill();
111
+ }
112
+ #applyFill(ctx) {
113
+ if (this.#context.data.type !== 'SHAPE')
114
+ return;
115
+ const shapeData = this.#context.data;
116
+ const appearance = shapeData.appearance;
117
+ const background = appearance.background;
118
+ // If background is a gradient object
119
+ if (background &&
120
+ typeof background === 'object' &&
121
+ 'colors' in background &&
122
+ Array.isArray(background.colors) &&
123
+ background.colors.length > 1) {
124
+ const { colors, angle } = background;
125
+ const { x1, y1, x2, y2 } = computeXYAngle(angle, this.#width, this.#height);
126
+ const gradient = ctx.createLinearGradient(x1, y1, x2, y2);
127
+ gradient.addColorStop(0, colors[0]);
128
+ gradient.addColorStop(1, colors[1]);
129
+ ctx.fillStyle = gradient;
130
+ return;
131
+ }
132
+ const fill = appearance.fill;
133
+ const color = appearance.color;
134
+ if (fill) {
135
+ ctx.fillStyle = fill;
136
+ }
137
+ else if (color) {
138
+ ctx.fillStyle = color;
139
+ }
140
+ else {
141
+ ctx.fillStyle = '#000000'; // Default to black if no fill specified
142
+ }
143
+ }
144
+ async #handleSetup() {
145
+ if (this.#resource) {
146
+ return;
147
+ }
148
+ if (this.#context.data.type !== 'SHAPE')
149
+ return;
150
+ const shapeData = this.#context.data;
151
+ const { width, height } = shapeData.appearance;
152
+ this.#width = width;
153
+ this.#height = height;
154
+ const resource = document.createElement('canvas');
155
+ resource.width = width;
156
+ resource.height = height;
157
+ const ctx = resource.getContext('2d');
158
+ ctx?.clearRect(0, 0, width, height);
159
+ // this logic will differ by the type of element type given
160
+ if (ctx) {
161
+ this.#renderShape(ctx);
162
+ }
163
+ this.#resource = resource;
164
+ this.#context.setResource('pixiResource', resource);
165
+ }
166
+ async #handleDestroy() {
167
+ // remove event listeners from video
168
+ this.#resource.remove();
169
+ }
170
+ async #handleUpdate() {
171
+ if (!this.#resource) {
172
+ // Recreate the canvas if it doesn't exist
173
+ await this.#handleSetup();
174
+ }
175
+ if (this.#context.data.type !== 'SHAPE')
176
+ return;
177
+ const shapeData = this.#context.data;
178
+ // Skip progress shapes - they're handled by PixiProgressShapeHook
179
+ if (shapeData.shape.type === 'progress')
180
+ return;
181
+ const ctx = this.#resource.getContext('2d');
182
+ if (ctx) {
183
+ // Only static shapes need texture updates (for dynamic content like animations)
184
+ // Clear and re-render if needed
185
+ ctx.clearRect(0, 0, this.#width, this.#height);
186
+ this.#renderShape(ctx);
187
+ // Force PIXI texture update
188
+ const pixiTexture = this.#context.getResource('pixiTexture');
189
+ if (pixiTexture) {
190
+ pixiTexture.update();
191
+ // Mark dirty when shape is re-rendered
192
+ this.state.markDirty();
193
+ }
194
+ }
195
+ }
196
+ async handle(type, context) {
197
+ this.#context = context;
198
+ if (this.#context.data.type !== 'SHAPE')
199
+ return;
200
+ const shapeData = this.#context.data;
201
+ // Skip progress shapes - they're handled by PixiProgressShapeHook
202
+ if (shapeData.shape.type === 'progress')
203
+ return;
204
+ const supportedTypes = [
205
+ 'rectangle',
206
+ 'triangle',
207
+ 'circle',
208
+ 'star',
209
+ 'ellipse',
210
+ 'polygon',
211
+ 'path'
212
+ ];
213
+ if (!supportedTypes.includes(shapeData.shape.type)) {
214
+ console.error('CanvasShapeHook: Unsupported shape type: ' +
215
+ shapeData.shape.type +
216
+ '. Supported types are ' +
217
+ supportedTypes.join(', ') +
218
+ '. Progress shapes are handled by PixiProgressShapeHook.');
219
+ return;
220
+ }
221
+ if (type === 'setup') {
222
+ return await this.#handleSetup();
223
+ }
224
+ else if (type === 'destroy') {
225
+ return await this.#handleDestroy();
226
+ }
227
+ await this.#handleUpdate();
228
+ }
229
+ }
@@ -0,0 +1,8 @@
1
+ import type { IComponentContext, IComponentHook, HookType } from '../..';
2
+ export declare class HtmlAnimationHook implements IComponentHook {
3
+ #private;
4
+ types: HookType[];
5
+ priority: number;
6
+ private buildTimeline;
7
+ handle(type: HookType, context: IComponentContext): Promise<void>;
8
+ }
@@ -0,0 +1,70 @@
1
+ export class HtmlAnimationHook {
2
+ #handlers = {
3
+ // setup: this.#handleSetup.bind(this),
4
+ destroy: this.#handleDestroy.bind(this),
5
+ refresh: this.#handleRefresh.bind(this),
6
+ update: this.#handleUpdate.bind(this),
7
+ 'refresh:animation': this.#handleRefresh.bind(this)
8
+ };
9
+ #context;
10
+ #htmlEl = undefined;
11
+ #tl = false;
12
+ #currentId = undefined;
13
+ types = Object.keys(this.#handlers);
14
+ priority = 1;
15
+ buildTimeline() {
16
+ if (this.#tl) {
17
+ return;
18
+ }
19
+ if (!this.#htmlEl) {
20
+ throw new Error('html element not found for animation hook of component: ' + this.#context.contextData.id);
21
+ }
22
+ }
23
+ async #handleSetup() {
24
+ if (this.#htmlEl) {
25
+ return;
26
+ }
27
+ const el = this.#context.getResource('htmlEl');
28
+ if (!el) {
29
+ throw new Error('HtmlAnimationHandler: Html el resource not found: ' + this.#context.contextData.id);
30
+ }
31
+ this.#htmlEl = el;
32
+ // this is a gsap animation that might utilize gsap text splitter and other complex animations and apply them to htmlEl
33
+ this.buildTimeline();
34
+ this.#currentId = this.#context.contextData.id;
35
+ }
36
+ async #handleRefresh() {
37
+ await this.#handleDestroy();
38
+ await this.#handleSetup();
39
+ }
40
+ // update on context id change, for example, subtitle changed so id changed as well
41
+ async #handleUpdate() {
42
+ if (this.#context.isActive && this.#currentId !== this.#context.contextData.id) {
43
+ await this.#handleRefresh();
44
+ }
45
+ if (this.#context.isActive && !this.#htmlEl) {
46
+ await this.#handleSetup();
47
+ }
48
+ }
49
+ async #handleDestroy() {
50
+ // remove event listeners from video
51
+ if (this.#tl) {
52
+ this.#tl = false;
53
+ // this.timeline.getTimeline().remove(this.#tl);
54
+ // this.#tl.kill();
55
+ // this.#tl = undefined;
56
+ }
57
+ this.#htmlEl = undefined;
58
+ }
59
+ // we need to set context here and not inject it is bound to component and we can update any of the components at any time
60
+ async handle(type, context) {
61
+ this.#context = context;
62
+ if (this.#context.disabled) {
63
+ return;
64
+ }
65
+ const handler = this.#handlers[type];
66
+ if (handler) {
67
+ await handler();
68
+ }
69
+ }
70
+ }
@@ -0,0 +1,16 @@
1
+ import type { IComponentContext, IComponentHook, HookType } from '../..';
2
+ import type { DomManager } from '../../managers/DomManager.js';
3
+ import type { ComponentsManager } from '../../managers/ComponentsManager.svelte.js';
4
+ export declare class HtmlTextHook implements IComponentHook {
5
+ #private;
6
+ types: HookType[];
7
+ priority: number;
8
+ private domManager;
9
+ private componentsManager;
10
+ constructor(cradle: {
11
+ domManager: DomManager;
12
+ componentsManager: ComponentsManager;
13
+ });
14
+ private buildHtmlElements;
15
+ handle(type: HookType, context: IComponentContext): Promise<void>;
16
+ }