@r2digisolutions/components 0.2.0 → 0.3.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 (63) hide show
  1. package/dist/components/atoms/Playhead/Playhead.svelte +44 -5
  2. package/dist/components/atoms/Playhead/Playhead.svelte.d.ts +8 -0
  3. package/dist/components/atoms/TimeRuler/TimeRuler.svelte +75 -16
  4. package/dist/components/atoms/TimeRuler/TimeRuler.svelte.d.ts +7 -0
  5. package/dist/components/atoms/TimelineGrid/TimelineGrid.stories.js +8 -0
  6. package/dist/components/atoms/TimelineGrid/TimelineGrid.svelte +39 -0
  7. package/dist/components/atoms/TimelineGrid/TimelineGrid.svelte.d.ts +11 -0
  8. package/dist/components/atoms/TimelineGrid/TimelineGridStory.svelte +7 -0
  9. package/dist/components/atoms/TimelineGrid/TimelineGridStory.svelte.d.ts +18 -0
  10. package/dist/components/molecules/ColorPicker/ColorPicker.svelte +45 -4
  11. package/dist/components/molecules/ColorPicker/ColorPicker.svelte.d.ts +2 -0
  12. package/dist/components/molecules/ContextMenu/ContextMenu.svelte +38 -11
  13. package/dist/components/molecules/MediaAssetBrowser/MediaAssetBrowser.svelte +17 -2
  14. package/dist/components/molecules/MediaAssetBrowser/MediaAssetBrowser.svelte.d.ts +5 -0
  15. package/dist/components/molecules/MediaTimeline/MediaTimeline.svelte +362 -52
  16. package/dist/components/molecules/MediaTimeline/MediaTimeline.svelte.d.ts +22 -2
  17. package/dist/components/molecules/PdfViewer/PdfViewer.svelte.d.ts +1 -1
  18. package/dist/components/molecules/ProgramMonitor/ProgramMonitor.svelte +751 -29
  19. package/dist/components/molecules/ProgramMonitor/ProgramMonitor.svelte.d.ts +14 -1
  20. package/dist/components/molecules/SplitPane/SplitPane.svelte +2 -2
  21. package/dist/components/molecules/TimelineClip/TimelineClip.svelte +95 -18
  22. package/dist/components/molecules/TimelineClip/TimelineClip.svelte.d.ts +3 -0
  23. package/dist/components/molecules/TimelineTrack/TimelineTrack.svelte +82 -12
  24. package/dist/components/molecules/TimelineTrack/TimelineTrack.svelte.d.ts +13 -2
  25. package/dist/components/molecules/TransportControls/TransportControls.svelte +84 -2
  26. package/dist/components/molecules/TransportControls/TransportControls.svelte.d.ts +13 -1
  27. package/dist/components/molecules/TransportControls/TransportControlsStory.svelte +33 -11
  28. package/dist/components/molecules/VideoAnimationsPanel/VideoAnimationsPanel.stories.js +8 -0
  29. package/dist/components/molecules/VideoAnimationsPanel/VideoAnimationsPanel.svelte +213 -0
  30. package/dist/components/molecules/VideoAnimationsPanel/VideoAnimationsPanel.svelte.d.ts +22 -0
  31. package/dist/components/molecules/VideoAnimationsPanel/VideoAnimationsPanelStory.svelte +7 -0
  32. package/dist/components/molecules/VideoAnimationsPanel/VideoAnimationsPanelStory.svelte.d.ts +18 -0
  33. package/dist/components/molecules/VideoComponentsPanel/VideoComponentsPanel.stories.js +8 -0
  34. package/dist/components/molecules/VideoComponentsPanel/VideoComponentsPanel.svelte +524 -0
  35. package/dist/components/molecules/VideoComponentsPanel/VideoComponentsPanel.svelte.d.ts +32 -0
  36. package/dist/components/molecules/VideoComponentsPanel/VideoComponentsPanelStory.svelte +7 -0
  37. package/dist/components/molecules/VideoComponentsPanel/VideoComponentsPanelStory.svelte.d.ts +18 -0
  38. package/dist/components/molecules/VideoTrackHeader/VideoTrackHeader.svelte +85 -32
  39. package/dist/components/molecules/VideoTrackHeader/VideoTrackHeader.svelte.d.ts +6 -0
  40. package/dist/components/molecules/VideoTransitionsPanel/VideoTransitionsPanel.stories.js +8 -0
  41. package/dist/components/molecules/VideoTransitionsPanel/VideoTransitionsPanel.svelte +113 -0
  42. package/dist/components/molecules/VideoTransitionsPanel/VideoTransitionsPanel.svelte.d.ts +18 -0
  43. package/dist/components/molecules/VideoTransitionsPanel/VideoTransitionsPanelStory.svelte +7 -0
  44. package/dist/components/molecules/VideoTransitionsPanel/VideoTransitionsPanelStory.svelte.d.ts +18 -0
  45. package/dist/components/organisms/AudioEditor/AudioEditor.svelte +52 -1
  46. package/dist/components/organisms/EditorShell/EditorShell.svelte +102 -92
  47. package/dist/components/organisms/FileUploader/FileUploader.stories.d.ts +10 -0
  48. package/dist/components/organisms/FileUploader/FileUploader.stories.js +21 -0
  49. package/dist/components/organisms/FileUploader/FileUploader.svelte +61 -21
  50. package/dist/components/organisms/FileUploader/FileUploader.svelte.d.ts +9 -0
  51. package/dist/components/organisms/FileUploader/FileUploaderStory.svelte +7 -1
  52. package/dist/components/organisms/FileUploader/FileUploaderStory.svelte.d.ts +3 -0
  53. package/dist/components/organisms/VideoEditor/VideoEditor.svelte +1457 -78
  54. package/dist/components/organisms/VideoEditor/VideoEditor.svelte.d.ts +2 -1
  55. package/dist/components/organisms/VideoEditor/VideoEditorStory.svelte +3 -2
  56. package/dist/index.d.ts +11 -3
  57. package/dist/index.js +6 -2
  58. package/dist/utils/mediaTime.d.ts +14 -4
  59. package/dist/utils/mediaTime.js +27 -8
  60. package/dist/utils/mediaTracks.d.ts +154 -0
  61. package/dist/utils/mediaTracks.js +697 -1
  62. package/dist/utils/videoSequence.js +35 -4
  63. package/package.json +1 -1
@@ -1,4 +1,5 @@
1
1
  import { type VideoSequence } from '../../../utils/videoSequence.js';
2
+ import type { Component } from 'svelte';
2
3
  interface VideoEditorProps {
3
4
  value?: VideoSequence;
4
5
  class?: string;
@@ -8,6 +9,6 @@ interface VideoEditorProps {
8
9
  document: VideoSequence;
9
10
  }) => void;
10
11
  }
11
- declare const VideoEditor: import("svelte").Component<VideoEditorProps, {}, "value">;
12
+ declare const VideoEditor: Component<VideoEditorProps, {}, "value">;
12
13
  type VideoEditor = ReturnType<typeof VideoEditor>;
13
14
  export default VideoEditor;
@@ -5,6 +5,7 @@
5
5
  let value = $state(createDemoVideoSequence());
6
6
  </script>
7
7
 
8
- <div class="h-[780px] w-full overflow-hidden rounded-xl border border-border">
9
- <VideoEditor bind:value />
8
+ <!-- Edge-to-edge in Storybook same pattern as CanvasEditor -->
9
+ <div class="fixed inset-0 overflow-hidden bg-surface">
10
+ <VideoEditor bind:value class="h-full" />
10
11
  </div>
package/dist/index.d.ts CHANGED
@@ -95,6 +95,7 @@ export type { VersionTagTone, VersionTagSize } from './components/atoms/VersionT
95
95
  export { default as WaveBars } from './components/atoms/WaveBars/WaveBars.svelte';
96
96
  export { default as Playhead } from './components/atoms/Playhead/Playhead.svelte';
97
97
  export { default as TimeRuler } from './components/atoms/TimeRuler/TimeRuler.svelte';
98
+ export { default as TimelineGrid } from './components/atoms/TimelineGrid/TimelineGrid.svelte';
98
99
  export { default as TrimHandle } from './components/atoms/TrimHandle/TrimHandle.svelte';
99
100
  export type { TrimHandleSide } from './components/atoms/TrimHandle/TrimHandle.svelte';
100
101
  export { default as MediaKindIcon } from './components/atoms/MediaKindIcon/MediaKindIcon.svelte';
@@ -606,6 +607,12 @@ export { default as MediaStage } from './components/molecules/MediaStage/MediaSt
606
607
  export { default as CanvasInspector } from './components/molecules/CanvasInspector/CanvasInspector.svelte';
607
608
  export { default as CanvasElementsPanel } from './components/molecules/CanvasElementsPanel/CanvasElementsPanel.svelte';
608
609
  export { CANVAS_ELEMENT_MIME, type CanvasElementDef } from './components/molecules/CanvasElementsPanel/CanvasElementsPanel.svelte';
610
+ export { default as VideoComponentsPanel } from './components/molecules/VideoComponentsPanel/VideoComponentsPanel.svelte';
611
+ export type { VideoComponentDef } from './components/molecules/VideoComponentsPanel/VideoComponentsPanel.svelte';
612
+ export { default as VideoAnimationsPanel } from './components/molecules/VideoAnimationsPanel/VideoAnimationsPanel.svelte';
613
+ export type { VideoAnimationDef } from './components/molecules/VideoAnimationsPanel/VideoAnimationsPanel.svelte';
614
+ export { default as VideoTransitionsPanel } from './components/molecules/VideoTransitionsPanel/VideoTransitionsPanel.svelte';
615
+ export type { VideoTransitionDef } from './components/molecules/VideoTransitionsPanel/VideoTransitionsPanel.svelte';
609
616
  export { default as ProgramMonitor } from './components/molecules/ProgramMonitor/ProgramMonitor.svelte';
610
617
  export { default as VideoTrackHeader } from './components/molecules/VideoTrackHeader/VideoTrackHeader.svelte';
611
618
  export { default as WaveformRegion } from './components/molecules/WaveformRegion/WaveformRegion.svelte';
@@ -827,9 +834,10 @@ export { tokenizeQuery, validateQuery, parseSimpleClauses, fieldIdsFromDefs, DEF
827
834
  export type { QueryToken, QueryTokenKind, QueryExample } from './utils/queryBar.js';
828
835
  export { queryStringToGroup, groupToQueryString, groupToFilterItems, removeRuleFromGroup, setFlatRules } from './utils/queryBridge.js';
829
836
  export { emptyBlogDocument, createBlock, createComponentBlock, serializeBlogDocument, parseBlogDocument, registerBlogComponent, unregisterBlogComponent, getBlogComponent, listBlogComponents, clearBlogComponentRegistry, NATIVE_BLOCK_TYPES, defaultDataForType, blogWidthClass, blogAlignClass, blogAspectPadding } from './utils/blogDocument.js';
830
- export { msToPx, pxToMs, pxPerMsFromZoom, snapMs, clampMs, formatTimecode, ticksForDuration } from './utils/mediaTime.js';
831
- export { uid, createMediaClip, createMediaTrack, createMediaAsset, clipDurationMs, moveClip, trimClipStart, trimClipEnd, isClipActiveAt, findClipAt, updateClipInTracks, removeClipFromTracks, kindFromFile } from './utils/mediaTracks.js';
832
- export type { MediaAsset, MediaAssetKind, MediaClip, MediaTrack, MediaTrackKind } from './utils/mediaTracks.js';
837
+ export { msToPx, pxToMs, pxPerMsFromZoom, snapMs, clampMs, formatTimecode, ticksForDuration, snapStepForZoom } from './utils/mediaTime.js';
838
+ export type { TimeTick, TimeTickLevel } from './utils/mediaTime.js';
839
+ export type { MediaAsset, MediaAssetKind, MediaClip, MediaClipAlign, MediaClipRect, MediaClipResettableField, MediaClipRectAxis, MediaTransitionPlayback, MediaTrack, MediaTrackKind } from './utils/mediaTracks.js';
840
+ export { uid, createMediaClip, createMediaTrack, createMediaAsset, clipDurationMs, moveClip, trimClipStart, trimClipEnd, isClipActiveAt, findClipAt, updateClipInTracks, removeClipFromTracks, removeClipsFromTracks, splitClipAt, splitClipsAt, duplicateClipInTracks, mergeClipsInTracks, canMergeMediaClips, moveClipsByDelta, findClipById, nextTrackName, reorderTracks, moveTrack, removeTrack, removeTracks, defaultOverlayRect, defaultMediaClipRect, resolveClipRect, alignClipRect, alignMediaRect, clipHasSpatialRect, isMediaClipFieldModified, resetMediaClipField, findTransitionAt, transitionLayerStyle, transitionDipOverlay, resolvePreviewOpacity, resolveClipOpacity, MEDIA_CLIP_DEFAULTS, kindFromFile, probeMediaSrc } from './utils/mediaTracks.js';
833
841
  export { emptyCanvasDocument, createCanvasLayer, createCanvasGuide, createPathFromDocPoints, rebakePathLayer, pathPointsToDoc, reorderCanvasLayers, updateCanvasLayer, updateCanvasLayers, alignLayerRect, snapLayerRect, snapRectToGuides, migrateCanvasDocument, defaultSlotFromRect, rectFromSlot, ensureLayerSlot, canvasLayerFieldDefault, isCanvasFieldModified, resetCanvasField, CANVAS_PRESETS, presetIdForSize } from './utils/canvasDocument.js';
834
842
  export type { CanvasDocument, CanvasLayer, CanvasLayerKind, CanvasLayerRect, CanvasPoint, CanvasObjectFit, CanvasTextAlign, CanvasResettableField, CanvasAlign, CanvasFontStyle, CanvasTextDecoration, CanvasGuide, CanvasGuideOrientation, CanvasAnchors, CanvasSlot, CanvasExposedProp, CanvasWidgetDefinition } from './utils/canvasDocument.js';
835
843
  export { isContainerKind, canHaveChildren, getChildren, getDescendantIds, getSubtreeIds, getAncestors, isEffectivelyVisible, paintTransformForLayer, isDescendant, canReparent, ANCHOR_PRESETS, resolveSlotRect, slotFromLocalRect, computeAbsoluteRects, absoluteRectFor, reparentLayer, wrapSelection, groupLayers, ungroupLayers, deleteSubtree, duplicateSubtree, reorderSiblings, clipPathForLayer, scrollBoxOverflow, scrollBarMetrics, applyScrollBoxOffsets } from './utils/canvasHierarchy.js';
package/dist/index.js CHANGED
@@ -82,6 +82,7 @@ export { default as VersionTag } from './components/atoms/VersionTag/VersionTag.
82
82
  export { default as WaveBars } from './components/atoms/WaveBars/WaveBars.svelte';
83
83
  export { default as Playhead } from './components/atoms/Playhead/Playhead.svelte';
84
84
  export { default as TimeRuler } from './components/atoms/TimeRuler/TimeRuler.svelte';
85
+ export { default as TimelineGrid } from './components/atoms/TimelineGrid/TimelineGrid.svelte';
85
86
  export { default as TrimHandle } from './components/atoms/TrimHandle/TrimHandle.svelte';
86
87
  export { default as MediaKindIcon } from './components/atoms/MediaKindIcon/MediaKindIcon.svelte';
87
88
  export { default as PanKnob } from './components/atoms/PanKnob/PanKnob.svelte';
@@ -419,6 +420,9 @@ export { default as MediaStage } from './components/molecules/MediaStage/MediaSt
419
420
  export { default as CanvasInspector } from './components/molecules/CanvasInspector/CanvasInspector.svelte';
420
421
  export { default as CanvasElementsPanel } from './components/molecules/CanvasElementsPanel/CanvasElementsPanel.svelte';
421
422
  export { CANVAS_ELEMENT_MIME } from './components/molecules/CanvasElementsPanel/CanvasElementsPanel.svelte';
423
+ export { default as VideoComponentsPanel } from './components/molecules/VideoComponentsPanel/VideoComponentsPanel.svelte';
424
+ export { default as VideoAnimationsPanel } from './components/molecules/VideoAnimationsPanel/VideoAnimationsPanel.svelte';
425
+ export { default as VideoTransitionsPanel } from './components/molecules/VideoTransitionsPanel/VideoTransitionsPanel.svelte';
422
426
  export { default as ProgramMonitor } from './components/molecules/ProgramMonitor/ProgramMonitor.svelte';
423
427
  export { default as VideoTrackHeader } from './components/molecules/VideoTrackHeader/VideoTrackHeader.svelte';
424
428
  export { default as WaveformRegion } from './components/molecules/WaveformRegion/WaveformRegion.svelte';
@@ -563,8 +567,8 @@ export { parseFilterSchema, emptyFilterValues, clearFilterValues, countActiveFil
563
567
  export { tokenizeQuery, validateQuery, parseSimpleClauses, fieldIdsFromDefs, DEFAULT_QUERY_EXAMPLES, operatorSuggestionsForField } from './utils/queryBar.js';
564
568
  export { queryStringToGroup, groupToQueryString, groupToFilterItems, removeRuleFromGroup, setFlatRules } from './utils/queryBridge.js';
565
569
  export { emptyBlogDocument, createBlock, createComponentBlock, serializeBlogDocument, parseBlogDocument, registerBlogComponent, unregisterBlogComponent, getBlogComponent, listBlogComponents, clearBlogComponentRegistry, NATIVE_BLOCK_TYPES, defaultDataForType, blogWidthClass, blogAlignClass, blogAspectPadding } from './utils/blogDocument.js';
566
- export { msToPx, pxToMs, pxPerMsFromZoom, snapMs, clampMs, formatTimecode, ticksForDuration } from './utils/mediaTime.js';
567
- export { uid, createMediaClip, createMediaTrack, createMediaAsset, clipDurationMs, moveClip, trimClipStart, trimClipEnd, isClipActiveAt, findClipAt, updateClipInTracks, removeClipFromTracks, kindFromFile } from './utils/mediaTracks.js';
570
+ export { msToPx, pxToMs, pxPerMsFromZoom, snapMs, clampMs, formatTimecode, ticksForDuration, snapStepForZoom } from './utils/mediaTime.js';
571
+ export { uid, createMediaClip, createMediaTrack, createMediaAsset, clipDurationMs, moveClip, trimClipStart, trimClipEnd, isClipActiveAt, findClipAt, updateClipInTracks, removeClipFromTracks, removeClipsFromTracks, splitClipAt, splitClipsAt, duplicateClipInTracks, mergeClipsInTracks, canMergeMediaClips, moveClipsByDelta, findClipById, nextTrackName, reorderTracks, moveTrack, removeTrack, removeTracks, defaultOverlayRect, defaultMediaClipRect, resolveClipRect, alignClipRect, alignMediaRect, clipHasSpatialRect, isMediaClipFieldModified, resetMediaClipField, findTransitionAt, transitionLayerStyle, transitionDipOverlay, resolvePreviewOpacity, resolveClipOpacity, MEDIA_CLIP_DEFAULTS, kindFromFile, probeMediaSrc } from './utils/mediaTracks.js';
568
572
  export { emptyCanvasDocument, createCanvasLayer, createCanvasGuide, createPathFromDocPoints, rebakePathLayer, pathPointsToDoc, reorderCanvasLayers, updateCanvasLayer, updateCanvasLayers, alignLayerRect, snapLayerRect, snapRectToGuides, migrateCanvasDocument, defaultSlotFromRect, rectFromSlot, ensureLayerSlot, canvasLayerFieldDefault, isCanvasFieldModified, resetCanvasField, CANVAS_PRESETS, presetIdForSize } from './utils/canvasDocument.js';
569
573
  export { isContainerKind, canHaveChildren, getChildren, getDescendantIds, getSubtreeIds, getAncestors, isEffectivelyVisible, paintTransformForLayer, isDescendant, canReparent, ANCHOR_PRESETS, resolveSlotRect, slotFromLocalRect, computeAbsoluteRects, absoluteRectFor, reparentLayer, wrapSelection, groupLayers, ungroupLayers, deleteSubtree, duplicateSubtree, reorderSiblings, clipPathForLayer, scrollBoxOverflow, scrollBarMetrics, applyScrollBoxOffsets } from './utils/canvasHierarchy.js';
570
574
  export { createWidgetDefinition, createWidgetFromSelection, placeWidgetInstance, resolveWidgetInstance, flattenLayersWithWidgets, breakWidgetInstance, updateWidgetDefinition, deleteWidgetDefinition, renameWidgetDefinition, duplicateWidgetDefinition, syncInstanceSizesToDefinition, setExposedProp, isPropExposed, getExposedProp, getExposedFieldDefault, resolveExposedPropValue, groupExposedPropsByLayer, setInstanceOverride, getNamedSlotsFromDefinition, listFillableSlotsForInstance } from './utils/canvasWidget.js';
@@ -1,4 +1,11 @@
1
1
  /** Milliseconds ↔ pixels and timecode helpers for media timelines. */
2
+ export type TimeTickLevel = 'major' | 'mid' | 'minor';
3
+ export interface TimeTick {
4
+ ms: number;
5
+ level: TimeTickLevel;
6
+ /** @deprecated Prefer `level === 'major'` */
7
+ major: boolean;
8
+ }
2
9
  export declare function msToPx(ms: number, pxPerMs: number): number;
3
10
  export declare function pxToMs(px: number, pxPerMs: number): number;
4
11
  /** px per ms from a zoom level (1 = 0.05 px/ms ≈ 50px/s). */
@@ -10,7 +17,10 @@ export declare function formatTimecode(ms: number, opts?: {
10
17
  showMs?: boolean;
11
18
  fps?: number;
12
19
  }): string;
13
- export declare function ticksForDuration(durationMs: number, pxPerMs: number, minTickPx?: number): {
14
- ms: number;
15
- major: boolean;
16
- }[];
20
+ /**
21
+ * Major / mid / minor ticks for a duration (same hierarchy idea as MediaStage rulers).
22
+ * mid = major/2, minor = major/10.
23
+ */
24
+ export declare function ticksForDuration(durationMs: number, pxPerMs: number, minTickPx?: number): TimeTick[];
25
+ /** Suggested snap interval from current zoom (mid tick step). */
26
+ export declare function snapStepForZoom(pxPerMs: number, minTickPx?: number): number;
@@ -40,18 +40,37 @@ export function formatTimecode(ms, opts) {
40
40
  }
41
41
  return `${hh}${mm}:${ss}`;
42
42
  }
43
- export function ticksForDuration(durationMs, pxPerMs, minTickPx = 60) {
43
+ /** Nice major step so major labels sit ~minTickPx apart on screen. */
44
+ function majorStepForPxPerMs(pxPerMs, minTickPx = 64) {
44
45
  const candidates = [100, 250, 500, 1000, 2000, 5000, 10_000, 30_000, 60_000, 120_000, 300_000];
45
- let step = candidates[candidates.length - 1];
46
46
  for (const c of candidates) {
47
- if (msToPx(c, pxPerMs) >= minTickPx) {
48
- step = c;
49
- break;
50
- }
47
+ if (msToPx(c, pxPerMs) >= minTickPx)
48
+ return c;
51
49
  }
50
+ return candidates[candidates.length - 1];
51
+ }
52
+ /**
53
+ * Major / mid / minor ticks for a duration (same hierarchy idea as MediaStage rulers).
54
+ * mid = major/2, minor = major/10.
55
+ */
56
+ export function ticksForDuration(durationMs, pxPerMs, minTickPx = 64) {
57
+ const major = majorStepForPxPerMs(pxPerMs, minTickPx);
58
+ const mid = major / 2;
59
+ const minor = major / 10;
52
60
  const ticks = [];
53
- for (let t = 0; t <= durationMs + 0.5; t += step) {
54
- ticks.push({ ms: t, major: t % (step * 2) === 0 || t === 0 });
61
+ const eps = minor / 4;
62
+ for (let t = 0; t <= durationMs + eps; t += minor) {
63
+ const ms = Math.round(t * 1000) / 1000;
64
+ if (ms > durationMs)
65
+ break;
66
+ const nearMajor = Math.abs(ms % major) < eps || Math.abs((ms % major) - major) < eps;
67
+ const nearMid = Math.abs(ms % mid) < eps || Math.abs((ms % mid) - mid) < eps;
68
+ const level = nearMajor ? 'major' : nearMid ? 'mid' : 'minor';
69
+ ticks.push({ ms, level, major: level === 'major' });
55
70
  }
56
71
  return ticks;
57
72
  }
73
+ /** Suggested snap interval from current zoom (mid tick step). */
74
+ export function snapStepForZoom(pxPerMs, minTickPx = 64) {
75
+ return majorStepForPxPerMs(pxPerMs, minTickPx) / 2;
76
+ }
@@ -1,5 +1,13 @@
1
1
  /** Shared track/clip types and helpers for Video / Audio editors. */
2
2
  export type MediaAssetKind = 'image' | 'video' | 'audio' | 'text';
3
+ /** Spatial rect on the program frame (document px). */
4
+ export interface MediaClipRect {
5
+ x: number;
6
+ y: number;
7
+ w: number;
8
+ h: number;
9
+ }
10
+ export type MediaClipAlign = 'left' | 'center-h' | 'right' | 'top' | 'center-v' | 'bottom' | 'center' | 'full';
3
11
  export interface MediaAsset {
4
12
  id: string;
5
13
  kind: MediaAssetKind;
@@ -26,6 +34,32 @@ export interface MediaClip {
26
34
  /** Source trim out (absolute in source) */
27
35
  trimOutMs?: number;
28
36
  color?: string;
37
+ /** Overlay / title text */
38
+ text?: string;
39
+ /** Timeline clip block opacity (0–1). Does not affect program preview. */
40
+ opacity?: number;
41
+ /** Program monitor / render opacity (0–1). */
42
+ previewOpacity?: number;
43
+ volume?: number;
44
+ fontSize?: number;
45
+ fontWeight?: number | string;
46
+ fontFamily?: string;
47
+ textAlign?: 'left' | 'center' | 'right';
48
+ textColor?: string;
49
+ /** Position on program monitor (document px). Overlays / positioned media. */
50
+ rect?: MediaClipRect;
51
+ animationIn?: {
52
+ type: string;
53
+ durationMs: number;
54
+ };
55
+ animationOut?: {
56
+ type: string;
57
+ durationMs: number;
58
+ };
59
+ transitionOut?: {
60
+ type: string;
61
+ durationMs: number;
62
+ };
29
63
  }
30
64
  export type MediaTrackKind = 'video' | 'audio' | 'image';
31
65
  export interface MediaTrack {
@@ -43,6 +77,24 @@ export declare function uid(prefix?: string): string;
43
77
  export declare function createMediaClip(partial: Omit<MediaClip, 'id'> & {
44
78
  id?: string;
45
79
  }): MediaClip;
80
+ /** Default overlay rect for text / plates on a program frame. */
81
+ export declare function defaultOverlayRect(frame: {
82
+ width: number;
83
+ height: number;
84
+ }, preset?: 'center' | 'lower-third' | 'top' | 'watermark' | 'full' | 'badge' | 'ticker' | 'side'): MediaClipRect;
85
+ export declare function clipHasSpatialRect(clip: MediaClip): boolean;
86
+ export declare function resolveClipRect(clip: MediaClip, frame: {
87
+ width: number;
88
+ height: number;
89
+ }): MediaClipRect;
90
+ export declare function alignClipRect(clip: MediaClip, frame: {
91
+ width: number;
92
+ height: number;
93
+ }, align: MediaClipAlign): MediaClip;
94
+ export declare function alignMediaRect(rect: MediaClipRect, bounds: {
95
+ width: number;
96
+ height: number;
97
+ }, align: MediaClipAlign): MediaClipRect;
46
98
  export declare function createMediaTrack(partial: Omit<MediaTrack, 'id' | 'clips'> & {
47
99
  id?: string;
48
100
  clips?: MediaClip[];
@@ -52,10 +104,112 @@ export declare function moveClip(clip: MediaClip, newStartMs: number, durationMs
52
104
  export declare function trimClipStart(clip: MediaClip, newStartMs: number, minDur?: number): MediaClip;
53
105
  export declare function trimClipEnd(clip: MediaClip, newEndMs: number, minDur?: number): MediaClip;
54
106
  export declare function isClipActiveAt(clip: MediaClip, timeMs: number): boolean;
107
+ /** Active CapCut-style transition: straddles the cut of a clip with `transitionOut`. */
108
+ export interface MediaTransitionPlayback {
109
+ from: MediaClip;
110
+ to: MediaClip | null;
111
+ trackId: string;
112
+ type: string;
113
+ /** 0 at transition start → 1 at end of transition */
114
+ progress: number;
115
+ durationMs: number;
116
+ windowStartMs: number;
117
+ windowEndMs: number;
118
+ }
119
+ export declare function findTransitionAt(tracks: MediaTrack[], timeMs: number): MediaTransitionPlayback | null;
120
+ /** Geometry for overflow-based wipes (reliable vs clip-path). */
121
+ export interface TransitionWipeBox {
122
+ box: {
123
+ left: string;
124
+ top: string;
125
+ width: string;
126
+ height: string;
127
+ };
128
+ content: {
129
+ left: string;
130
+ top: string;
131
+ width: string;
132
+ height: string;
133
+ };
134
+ }
135
+ export interface TransitionLayerStyle {
136
+ opacity: number;
137
+ transform: string;
138
+ clipPath?: string;
139
+ filter?: string;
140
+ transformOrigin?: string;
141
+ /** CSS mask-image (and -webkit-mask-image) */
142
+ maskImage?: string;
143
+ /** Prefer this for hard directional wipes */
144
+ wipe?: TransitionWipeBox;
145
+ }
146
+ /** CSS bits for outgoing / incoming layers during a transition. */
147
+ export declare function transitionLayerStyle(role: 'from' | 'to', type: string, progress: number): TransitionLayerStyle;
148
+ export declare function transitionDipOverlay(type: string, progress: number): {
149
+ color: string;
150
+ opacity: number;
151
+ } | null;
55
152
  export declare function findClipAt(tracks: MediaTrack[], timeMs: number, kind?: MediaTrackKind): MediaClip | null;
153
+ export declare function findClipById(tracks: MediaTrack[], clipId: string): MediaClip | null;
56
154
  export declare function updateClipInTracks(tracks: MediaTrack[], clipId: string, updater: (c: MediaClip) => MediaClip): MediaTrack[];
57
155
  export declare function removeClipFromTracks(tracks: MediaTrack[], clipId: string): MediaTrack[];
156
+ export declare function removeClipsFromTracks(tracks: MediaTrack[], clipIds: string[]): MediaTrack[];
157
+ /** Split a clip at timeMs; returns updated tracks (no-op if playhead not inside clip). */
158
+ export declare function splitClipAt(tracks: MediaTrack[], clipId: string, timeMs: number, minDur?: number): MediaTrack[];
159
+ /** Split every selected clip that contains timeMs. */
160
+ export declare function splitClipsAt(tracks: MediaTrack[], clipIds: string[], timeMs: number, minDur?: number): MediaTrack[];
161
+ export declare function duplicateClipInTracks(tracks: MediaTrack[], clipId: string): MediaTrack[];
162
+ /**
163
+ * Merge 2+ clips of the same kind into one spanning earliest start → latest end.
164
+ * Clips may live on different tracks; the result is placed on the earliest clip's track.
165
+ * Returns null if merge is not possible.
166
+ */
167
+ export declare function canMergeMediaClips(tracks: MediaTrack[], clipIds: string[]): boolean;
168
+ export declare function mergeClipsInTracks(tracks: MediaTrack[], clipIds: string[]): MediaTrack[] | null;
169
+ /** Shift one or more clips in time by the same delta (clamped so none go before 0). */
170
+ export declare function moveClipsByDelta(tracks: MediaTrack[], clipIds: string[], deltaMs: number): MediaTrack[];
171
+ export declare function nextTrackName(tracks: MediaTrack[], kind: MediaTrackKind): string;
172
+ /** Reorder tracks by id list (ids not listed keep relative order at the end). */
173
+ export declare function reorderTracks(tracks: MediaTrack[], orderedIds: string[]): MediaTrack[];
174
+ /** Move a track from one index to another. */
175
+ export declare function moveTrack(tracks: MediaTrack[], fromIndex: number, toIndex: number): MediaTrack[];
176
+ export declare function removeTrack(tracks: MediaTrack[], trackId: string): MediaTrack[];
177
+ export declare function removeTracks(tracks: MediaTrack[], trackIds: string[]): MediaTrack[];
178
+ /** Defaults for inspector reset (Unreal-style). */
179
+ export declare const MEDIA_CLIP_DEFAULTS: {
180
+ opacity: number;
181
+ previewOpacity: number;
182
+ volume: number;
183
+ fontSize: number;
184
+ fontWeight: number | string;
185
+ textAlign: "center";
186
+ textColor: string;
187
+ color: string;
188
+ trimInMs: number;
189
+ trimOutMs: number | undefined;
190
+ };
191
+ export type MediaClipRectAxis = 'x' | 'y' | 'w' | 'h';
192
+ export type MediaClipResettableField = keyof typeof MEDIA_CLIP_DEFAULTS | 'rect' | `rect.${MediaClipRectAxis}`;
193
+ /** Default rect used by inspector reset (must stay in sync with `resetMediaClipField`). */
194
+ export declare function defaultMediaClipRect(clip: MediaClip, frame: {
195
+ width: number;
196
+ height: number;
197
+ }): MediaClipRect;
198
+ export declare function isMediaClipFieldModified(clip: MediaClip, field: MediaClipResettableField, frame?: {
199
+ width: number;
200
+ height: number;
201
+ }): boolean;
202
+ export declare function resetMediaClipField(clip: MediaClip, field: MediaClipResettableField, frame?: {
203
+ width: number;
204
+ height: number;
205
+ }): MediaClip;
206
+ /** Effective program-monitor opacity (ignores timeline clip opacity). */
207
+ export declare function resolvePreviewOpacity(clip: MediaClip): number;
208
+ /** Effective timeline block opacity. */
209
+ export declare function resolveClipOpacity(clip: MediaClip): number;
58
210
  export declare function createMediaAsset(partial: Omit<MediaAsset, 'id'> & {
59
211
  id?: string;
60
212
  }): MediaAsset;
61
213
  export declare function kindFromFile(file: File): MediaAssetKind;
214
+ /** Probe width/height/duration from a local media URL. */
215
+ export declare function probeMediaSrc(src: string, kind: MediaAssetKind): Promise<Pick<MediaAsset, 'width' | 'height' | 'durationMs'>>;