@r2digisolutions/components 0.2.0 → 0.3.1

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 (65) hide show
  1. package/README.md +10 -0
  2. package/dist/components/atoms/Playhead/Playhead.svelte +44 -5
  3. package/dist/components/atoms/Playhead/Playhead.svelte.d.ts +8 -0
  4. package/dist/components/atoms/TimeRuler/TimeRuler.svelte +75 -16
  5. package/dist/components/atoms/TimeRuler/TimeRuler.svelte.d.ts +7 -0
  6. package/dist/components/atoms/TimelineGrid/TimelineGrid.stories.js +8 -0
  7. package/dist/components/atoms/TimelineGrid/TimelineGrid.svelte +39 -0
  8. package/dist/components/atoms/TimelineGrid/TimelineGrid.svelte.d.ts +11 -0
  9. package/dist/components/atoms/TimelineGrid/TimelineGridStory.svelte +7 -0
  10. package/dist/components/atoms/TimelineGrid/TimelineGridStory.svelte.d.ts +18 -0
  11. package/dist/components/molecules/ColorPicker/ColorPicker.svelte +45 -4
  12. package/dist/components/molecules/ColorPicker/ColorPicker.svelte.d.ts +2 -0
  13. package/dist/components/molecules/ContextMenu/ContextMenu.svelte +38 -11
  14. package/dist/components/molecules/MediaAssetBrowser/MediaAssetBrowser.svelte +17 -2
  15. package/dist/components/molecules/MediaAssetBrowser/MediaAssetBrowser.svelte.d.ts +5 -0
  16. package/dist/components/molecules/MediaTimeline/MediaTimeline.svelte +362 -52
  17. package/dist/components/molecules/MediaTimeline/MediaTimeline.svelte.d.ts +22 -2
  18. package/dist/components/molecules/PdfViewer/PdfViewer.svelte.d.ts +1 -1
  19. package/dist/components/molecules/ProgramMonitor/ProgramMonitor.svelte +751 -29
  20. package/dist/components/molecules/ProgramMonitor/ProgramMonitor.svelte.d.ts +14 -1
  21. package/dist/components/molecules/SplitPane/SplitPane.svelte +2 -2
  22. package/dist/components/molecules/TimelineClip/TimelineClip.svelte +95 -18
  23. package/dist/components/molecules/TimelineClip/TimelineClip.svelte.d.ts +3 -0
  24. package/dist/components/molecules/TimelineTrack/TimelineTrack.svelte +82 -12
  25. package/dist/components/molecules/TimelineTrack/TimelineTrack.svelte.d.ts +13 -2
  26. package/dist/components/molecules/TransportControls/TransportControls.svelte +84 -2
  27. package/dist/components/molecules/TransportControls/TransportControls.svelte.d.ts +13 -1
  28. package/dist/components/molecules/TransportControls/TransportControlsStory.svelte +33 -11
  29. package/dist/components/molecules/VideoAnimationsPanel/VideoAnimationsPanel.stories.js +8 -0
  30. package/dist/components/molecules/VideoAnimationsPanel/VideoAnimationsPanel.svelte +213 -0
  31. package/dist/components/molecules/VideoAnimationsPanel/VideoAnimationsPanel.svelte.d.ts +22 -0
  32. package/dist/components/molecules/VideoAnimationsPanel/VideoAnimationsPanelStory.svelte +7 -0
  33. package/dist/components/molecules/VideoAnimationsPanel/VideoAnimationsPanelStory.svelte.d.ts +18 -0
  34. package/dist/components/molecules/VideoComponentsPanel/VideoComponentsPanel.stories.js +8 -0
  35. package/dist/components/molecules/VideoComponentsPanel/VideoComponentsPanel.svelte +524 -0
  36. package/dist/components/molecules/VideoComponentsPanel/VideoComponentsPanel.svelte.d.ts +32 -0
  37. package/dist/components/molecules/VideoComponentsPanel/VideoComponentsPanelStory.svelte +7 -0
  38. package/dist/components/molecules/VideoComponentsPanel/VideoComponentsPanelStory.svelte.d.ts +18 -0
  39. package/dist/components/molecules/VideoTrackHeader/VideoTrackHeader.svelte +85 -32
  40. package/dist/components/molecules/VideoTrackHeader/VideoTrackHeader.svelte.d.ts +6 -0
  41. package/dist/components/molecules/VideoTransitionsPanel/VideoTransitionsPanel.stories.js +8 -0
  42. package/dist/components/molecules/VideoTransitionsPanel/VideoTransitionsPanel.svelte +113 -0
  43. package/dist/components/molecules/VideoTransitionsPanel/VideoTransitionsPanel.svelte.d.ts +18 -0
  44. package/dist/components/molecules/VideoTransitionsPanel/VideoTransitionsPanelStory.svelte +7 -0
  45. package/dist/components/molecules/VideoTransitionsPanel/VideoTransitionsPanelStory.svelte.d.ts +18 -0
  46. package/dist/components/organisms/AudioEditor/AudioEditor.svelte +52 -1
  47. package/dist/components/organisms/EditorShell/EditorShell.svelte +102 -92
  48. package/dist/components/organisms/FileUploader/FileUploader.stories.d.ts +10 -0
  49. package/dist/components/organisms/FileUploader/FileUploader.stories.js +21 -0
  50. package/dist/components/organisms/FileUploader/FileUploader.svelte +61 -21
  51. package/dist/components/organisms/FileUploader/FileUploader.svelte.d.ts +9 -0
  52. package/dist/components/organisms/FileUploader/FileUploaderStory.svelte +7 -1
  53. package/dist/components/organisms/FileUploader/FileUploaderStory.svelte.d.ts +3 -0
  54. package/dist/components/organisms/VideoEditor/VideoEditor.svelte +1457 -78
  55. package/dist/components/organisms/VideoEditor/VideoEditor.svelte.d.ts +2 -1
  56. package/dist/components/organisms/VideoEditor/VideoEditorStory.svelte +3 -2
  57. package/dist/index.d.ts +11 -3
  58. package/dist/index.js +6 -2
  59. package/dist/styles.css +237 -0
  60. package/dist/utils/mediaTime.d.ts +14 -4
  61. package/dist/utils/mediaTime.js +27 -8
  62. package/dist/utils/mediaTracks.d.ts +154 -0
  63. package/dist/utils/mediaTracks.js +697 -1
  64. package/dist/utils/videoSequence.js +35 -4
  65. package/package.json +4 -2
@@ -0,0 +1,213 @@
1
+ <script lang="ts" module>
2
+ export interface VideoAnimationDef {
3
+ id: string;
4
+ label: string;
5
+ group: string;
6
+ /** CapCut-style: In / Out / Combo (sets both) */
7
+ slot: 'in' | 'out' | 'combo';
8
+ type: string;
9
+ /** Used when slot is combo */
10
+ outType?: string;
11
+ durationMs: number;
12
+ glyph?: string;
13
+ }
14
+
15
+ export const VIDEO_ANIMATION_MIME = 'application/x-r2-video-animation';
16
+ </script>
17
+
18
+ <script lang="ts">
19
+ interface VideoAnimationsPanelProps {
20
+ class?: string;
21
+ disabled?: boolean;
22
+ hint?: string;
23
+ onapply?: (def: VideoAnimationDef) => void;
24
+ }
25
+
26
+ let {
27
+ class: className = '',
28
+ disabled = false,
29
+ hint = 'Select a clip, or drag onto one',
30
+ onapply
31
+ }: VideoAnimationsPanelProps = $props();
32
+
33
+ const animations: VideoAnimationDef[] = [
34
+ /* —— In —— */
35
+ { id: 'fade-in', label: 'Fade in', group: 'In', slot: 'in', type: 'fade', durationMs: 500, glyph: '↗' },
36
+ { id: 'slide-up-in', label: 'Slide up', group: 'In', slot: 'in', type: 'slide-up', durationMs: 500, glyph: '↑' },
37
+ { id: 'slide-down-in', label: 'Slide down', group: 'In', slot: 'in', type: 'slide-down', durationMs: 500, glyph: '↓' },
38
+ { id: 'slide-left-in', label: 'Slide left', group: 'In', slot: 'in', type: 'slide-left', durationMs: 500, glyph: '←' },
39
+ { id: 'slide-right-in', label: 'Slide right', group: 'In', slot: 'in', type: 'slide-right', durationMs: 500, glyph: '→' },
40
+ { id: 'scale-in', label: 'Zoom in', group: 'In', slot: 'in', type: 'scale', durationMs: 400, glyph: '⊕' },
41
+ { id: 'grow-in', label: 'Grow', group: 'In', slot: 'in', type: 'grow', durationMs: 450, glyph: '▣' },
42
+ { id: 'shrink-in', label: 'Shrink in', group: 'In', slot: 'in', type: 'shrink', durationMs: 450, glyph: '▢' },
43
+ { id: 'pop-in', label: 'Pop', group: 'In', slot: 'in', type: 'pop', durationMs: 450, glyph: '✦' },
44
+ { id: 'rotate-in', label: 'Rotate in', group: 'In', slot: 'in', type: 'rotate', durationMs: 550, glyph: '↻' },
45
+ { id: 'spin-in', label: 'Spin', group: 'In', slot: 'in', type: 'spin', durationMs: 600, glyph: '⟳' },
46
+ { id: 'bounce-in', label: 'Bounce', group: 'In', slot: 'in', type: 'bounce', durationMs: 600, glyph: '↕' },
47
+ { id: 'drop-in', label: 'Drop', group: 'In', slot: 'in', type: 'drop', durationMs: 550, glyph: '⬇' },
48
+ { id: 'swing-in', label: 'Swing', group: 'In', slot: 'in', type: 'swing', durationMs: 600, glyph: '∿' },
49
+ { id: 'flip-x-in', label: 'Flip H', group: 'In', slot: 'in', type: 'flip-x', durationMs: 550, glyph: '↔' },
50
+ { id: 'flip-y-in', label: 'Flip V', group: 'In', slot: 'in', type: 'flip-y', durationMs: 550, glyph: '↕' },
51
+ { id: 'skew-in', label: 'Skew', group: 'In', slot: 'in', type: 'skew', durationMs: 500, glyph: '▱' },
52
+ { id: 'expand-h-in', label: 'Expand H', group: 'In', slot: 'in', type: 'expand-h', durationMs: 500, glyph: '⟷' },
53
+ { id: 'expand-v-in', label: 'Expand V', group: 'In', slot: 'in', type: 'expand-v', durationMs: 500, glyph: '↕︎' },
54
+ { id: 'blur-in', label: 'Blur in', group: 'In', slot: 'in', type: 'blur', durationMs: 550, glyph: '◈' },
55
+ { id: 'glow-in', label: 'Glow', group: 'In', slot: 'in', type: 'glow', durationMs: 500, glyph: '✧' },
56
+ /* —— Out —— */
57
+ { id: 'fade-out', label: 'Fade out', group: 'Out', slot: 'out', type: 'fade', durationMs: 500, glyph: '↘' },
58
+ { id: 'slide-up-out', label: 'Slide up', group: 'Out', slot: 'out', type: 'slide-up', durationMs: 500, glyph: '↑' },
59
+ { id: 'slide-down-out', label: 'Slide down', group: 'Out', slot: 'out', type: 'slide-down', durationMs: 500, glyph: '↓' },
60
+ { id: 'slide-left-out', label: 'Slide left', group: 'Out', slot: 'out', type: 'slide-left', durationMs: 500, glyph: '←' },
61
+ { id: 'slide-right-out', label: 'Slide right', group: 'Out', slot: 'out', type: 'slide-right', durationMs: 500, glyph: '→' },
62
+ { id: 'scale-out', label: 'Zoom out', group: 'Out', slot: 'out', type: 'scale', durationMs: 400, glyph: '⊖' },
63
+ { id: 'grow-out', label: 'Grow out', group: 'Out', slot: 'out', type: 'grow', durationMs: 450, glyph: '▣' },
64
+ { id: 'shrink-out', label: 'Shrink', group: 'Out', slot: 'out', type: 'shrink', durationMs: 450, glyph: '▢' },
65
+ { id: 'pop-out', label: 'Pop out', group: 'Out', slot: 'out', type: 'pop', durationMs: 450, glyph: '✧' },
66
+ { id: 'rotate-out', label: 'Rotate out', group: 'Out', slot: 'out', type: 'rotate', durationMs: 550, glyph: '↺' },
67
+ { id: 'spin-out', label: 'Spin out', group: 'Out', slot: 'out', type: 'spin', durationMs: 600, glyph: '⟲' },
68
+ { id: 'bounce-out', label: 'Bounce', group: 'Out', slot: 'out', type: 'bounce', durationMs: 600, glyph: '↕' },
69
+ { id: 'drop-out', label: 'Drop', group: 'Out', slot: 'out', type: 'drop', durationMs: 550, glyph: '⬇' },
70
+ { id: 'swing-out', label: 'Swing', group: 'Out', slot: 'out', type: 'swing', durationMs: 600, glyph: '∿' },
71
+ { id: 'flip-x-out', label: 'Flip H', group: 'Out', slot: 'out', type: 'flip-x', durationMs: 550, glyph: '↔' },
72
+ { id: 'flip-y-out', label: 'Flip V', group: 'Out', slot: 'out', type: 'flip-y', durationMs: 550, glyph: '↕' },
73
+ { id: 'skew-out', label: 'Skew', group: 'Out', slot: 'out', type: 'skew', durationMs: 500, glyph: '▱' },
74
+ { id: 'expand-h-out', label: 'Collapse H', group: 'Out', slot: 'out', type: 'expand-h', durationMs: 500, glyph: '⟷' },
75
+ { id: 'expand-v-out', label: 'Collapse V', group: 'Out', slot: 'out', type: 'expand-v', durationMs: 500, glyph: '↕︎' },
76
+ { id: 'blur-out', label: 'Blur out', group: 'Out', slot: 'out', type: 'blur', durationMs: 550, glyph: '◈' },
77
+ { id: 'glow-out', label: 'Glow out', group: 'Out', slot: 'out', type: 'glow', durationMs: 500, glyph: '✧' },
78
+ /* —— Combo —— */
79
+ {
80
+ id: 'fade-io',
81
+ label: 'Fade I/O',
82
+ group: 'Combo',
83
+ slot: 'combo',
84
+ type: 'fade',
85
+ outType: 'fade',
86
+ durationMs: 500,
87
+ glyph: '↕'
88
+ },
89
+ {
90
+ id: 'slide-io',
91
+ label: 'Slide I/O',
92
+ group: 'Combo',
93
+ slot: 'combo',
94
+ type: 'slide-up',
95
+ outType: 'slide-down',
96
+ durationMs: 500,
97
+ glyph: '⇅'
98
+ },
99
+ {
100
+ id: 'zoom-io',
101
+ label: 'Zoom I/O',
102
+ group: 'Combo',
103
+ slot: 'combo',
104
+ type: 'scale',
105
+ outType: 'scale',
106
+ durationMs: 400,
107
+ glyph: '⊙'
108
+ },
109
+ {
110
+ id: 'pop-io',
111
+ label: 'Pop I/O',
112
+ group: 'Combo',
113
+ slot: 'combo',
114
+ type: 'pop',
115
+ outType: 'pop',
116
+ durationMs: 450,
117
+ glyph: '✦'
118
+ },
119
+ {
120
+ id: 'spin-io',
121
+ label: 'Spin I/O',
122
+ group: 'Combo',
123
+ slot: 'combo',
124
+ type: 'spin',
125
+ outType: 'spin',
126
+ durationMs: 550,
127
+ glyph: '↻'
128
+ },
129
+ {
130
+ id: 'flip-io',
131
+ label: 'Flip I/O',
132
+ group: 'Combo',
133
+ slot: 'combo',
134
+ type: 'flip-x',
135
+ outType: 'flip-y',
136
+ durationMs: 550,
137
+ glyph: '⧉'
138
+ },
139
+ {
140
+ id: 'blur-io',
141
+ label: 'Blur I/O',
142
+ group: 'Combo',
143
+ slot: 'combo',
144
+ type: 'blur',
145
+ outType: 'blur',
146
+ durationMs: 550,
147
+ glyph: '◈'
148
+ },
149
+ {
150
+ id: 'drop-io',
151
+ label: 'Drop I/O',
152
+ group: 'Combo',
153
+ slot: 'combo',
154
+ type: 'drop',
155
+ outType: 'drop',
156
+ durationMs: 550,
157
+ glyph: '⬇'
158
+ }
159
+ ];
160
+
161
+ const groups = $derived(
162
+ [...new Set(animations.map((a) => a.group))].map((group) => ({
163
+ group,
164
+ items: animations.filter((a) => a.group === group)
165
+ }))
166
+ );
167
+
168
+ function onDragStart(e: DragEvent, item: VideoAnimationDef) {
169
+ if (disabled) {
170
+ e.preventDefault();
171
+ return;
172
+ }
173
+ e.dataTransfer?.setData(VIDEO_ANIMATION_MIME, JSON.stringify(item));
174
+ e.dataTransfer?.setData('text/plain', item.label);
175
+ if (e.dataTransfer) e.dataTransfer.effectAllowed = 'copy';
176
+ }
177
+ </script>
178
+
179
+ <div class={['flex flex-col gap-4 p-2', className]}>
180
+ {#if disabled}
181
+ <p class="px-1 py-4 text-center text-xs text-muted">{hint}</p>
182
+ {:else}
183
+ <p class="px-1 text-[10px] leading-relaxed text-muted">
184
+ CapCut-style: pick <strong class="font-medium text-secondary">In</strong> and/or
185
+ <strong class="font-medium text-secondary"> Out</strong> (one each). Drag onto a clip or click
186
+ with a clip selected.
187
+ </p>
188
+ {/if}
189
+ {#each groups as { group, items } (group)}
190
+ <section class="flex flex-col gap-2">
191
+ <h3 class="px-1 text-[10px] font-semibold uppercase tracking-wide text-muted">{group}</h3>
192
+ <div class="grid grid-cols-3 gap-1.5">
193
+ {#each items as item (item.id)}
194
+ <button
195
+ type="button"
196
+ disabled={disabled}
197
+ draggable={!disabled}
198
+ ondragstart={(e) => onDragStart(e, item)}
199
+ class="flex cursor-grab flex-col items-center gap-1.5 rounded-lg border border-border bg-surface-elevated px-1.5 py-2 text-center transition-colors enabled:hover:border-brand-500/50 enabled:hover:bg-surface-overlay active:cursor-grabbing disabled:cursor-not-allowed disabled:opacity-50"
200
+ onclick={() => onapply?.(item)}
201
+ >
202
+ <span
203
+ class="flex h-9 w-full items-center justify-center rounded-md bg-surface text-sm font-semibold text-secondary"
204
+ >
205
+ {item.glyph ?? item.label.slice(0, 2)}
206
+ </span>
207
+ <span class="text-[10px] font-medium text-secondary">{item.label}</span>
208
+ </button>
209
+ {/each}
210
+ </div>
211
+ </section>
212
+ {/each}
213
+ </div>
@@ -0,0 +1,22 @@
1
+ export interface VideoAnimationDef {
2
+ id: string;
3
+ label: string;
4
+ group: string;
5
+ /** CapCut-style: In / Out / Combo (sets both) */
6
+ slot: 'in' | 'out' | 'combo';
7
+ type: string;
8
+ /** Used when slot is combo */
9
+ outType?: string;
10
+ durationMs: number;
11
+ glyph?: string;
12
+ }
13
+ export declare const VIDEO_ANIMATION_MIME = "application/x-r2-video-animation";
14
+ interface VideoAnimationsPanelProps {
15
+ class?: string;
16
+ disabled?: boolean;
17
+ hint?: string;
18
+ onapply?: (def: VideoAnimationDef) => void;
19
+ }
20
+ declare const VideoAnimationsPanel: import("svelte").Component<VideoAnimationsPanelProps, {}, "">;
21
+ type VideoAnimationsPanel = ReturnType<typeof VideoAnimationsPanel>;
22
+ export default VideoAnimationsPanel;
@@ -0,0 +1,7 @@
1
+ <script lang="ts">
2
+ import VideoAnimationsPanel from './VideoAnimationsPanel.svelte';
3
+ </script>
4
+
5
+ <div class="h-96 w-72 rounded-lg border border-border bg-surface">
6
+ <VideoAnimationsPanel onapply={(d) => console.log('anim', d)} />
7
+ </div>
@@ -0,0 +1,18 @@
1
+ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
2
+ new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
3
+ $$bindings?: Bindings;
4
+ } & Exports;
5
+ (internal: unknown, props: {
6
+ $$events?: Events;
7
+ $$slots?: Slots;
8
+ }): Exports & {
9
+ $set?: any;
10
+ $on?: any;
11
+ };
12
+ z_$$bindings?: Bindings;
13
+ }
14
+ declare const VideoAnimationsPanelStory: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
15
+ [evt: string]: CustomEvent<any>;
16
+ }, {}, {}, string>;
17
+ type VideoAnimationsPanelStory = InstanceType<typeof VideoAnimationsPanelStory>;
18
+ export default VideoAnimationsPanelStory;
@@ -0,0 +1,8 @@
1
+ import VideoComponentsPanelStory from './VideoComponentsPanelStory.svelte';
2
+ const meta = {
3
+ title: 'Molecules/VideoComponentsPanel',
4
+ component: VideoComponentsPanelStory,
5
+ tags: ['autodocs']
6
+ };
7
+ export default meta;
8
+ export const Default = {};