@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.
- package/README.md +10 -0
- package/dist/components/atoms/Playhead/Playhead.svelte +44 -5
- package/dist/components/atoms/Playhead/Playhead.svelte.d.ts +8 -0
- package/dist/components/atoms/TimeRuler/TimeRuler.svelte +75 -16
- package/dist/components/atoms/TimeRuler/TimeRuler.svelte.d.ts +7 -0
- package/dist/components/atoms/TimelineGrid/TimelineGrid.stories.js +8 -0
- package/dist/components/atoms/TimelineGrid/TimelineGrid.svelte +39 -0
- package/dist/components/atoms/TimelineGrid/TimelineGrid.svelte.d.ts +11 -0
- package/dist/components/atoms/TimelineGrid/TimelineGridStory.svelte +7 -0
- package/dist/components/atoms/TimelineGrid/TimelineGridStory.svelte.d.ts +18 -0
- package/dist/components/molecules/ColorPicker/ColorPicker.svelte +45 -4
- package/dist/components/molecules/ColorPicker/ColorPicker.svelte.d.ts +2 -0
- package/dist/components/molecules/ContextMenu/ContextMenu.svelte +38 -11
- package/dist/components/molecules/MediaAssetBrowser/MediaAssetBrowser.svelte +17 -2
- package/dist/components/molecules/MediaAssetBrowser/MediaAssetBrowser.svelte.d.ts +5 -0
- package/dist/components/molecules/MediaTimeline/MediaTimeline.svelte +362 -52
- package/dist/components/molecules/MediaTimeline/MediaTimeline.svelte.d.ts +22 -2
- package/dist/components/molecules/PdfViewer/PdfViewer.svelte.d.ts +1 -1
- package/dist/components/molecules/ProgramMonitor/ProgramMonitor.svelte +751 -29
- package/dist/components/molecules/ProgramMonitor/ProgramMonitor.svelte.d.ts +14 -1
- package/dist/components/molecules/SplitPane/SplitPane.svelte +2 -2
- package/dist/components/molecules/TimelineClip/TimelineClip.svelte +95 -18
- package/dist/components/molecules/TimelineClip/TimelineClip.svelte.d.ts +3 -0
- package/dist/components/molecules/TimelineTrack/TimelineTrack.svelte +82 -12
- package/dist/components/molecules/TimelineTrack/TimelineTrack.svelte.d.ts +13 -2
- package/dist/components/molecules/TransportControls/TransportControls.svelte +84 -2
- package/dist/components/molecules/TransportControls/TransportControls.svelte.d.ts +13 -1
- package/dist/components/molecules/TransportControls/TransportControlsStory.svelte +33 -11
- package/dist/components/molecules/VideoAnimationsPanel/VideoAnimationsPanel.stories.js +8 -0
- package/dist/components/molecules/VideoAnimationsPanel/VideoAnimationsPanel.svelte +213 -0
- package/dist/components/molecules/VideoAnimationsPanel/VideoAnimationsPanel.svelte.d.ts +22 -0
- package/dist/components/molecules/VideoAnimationsPanel/VideoAnimationsPanelStory.svelte +7 -0
- package/dist/components/molecules/VideoAnimationsPanel/VideoAnimationsPanelStory.svelte.d.ts +18 -0
- package/dist/components/molecules/VideoComponentsPanel/VideoComponentsPanel.stories.js +8 -0
- package/dist/components/molecules/VideoComponentsPanel/VideoComponentsPanel.svelte +524 -0
- package/dist/components/molecules/VideoComponentsPanel/VideoComponentsPanel.svelte.d.ts +32 -0
- package/dist/components/molecules/VideoComponentsPanel/VideoComponentsPanelStory.svelte +7 -0
- package/dist/components/molecules/VideoComponentsPanel/VideoComponentsPanelStory.svelte.d.ts +18 -0
- package/dist/components/molecules/VideoTrackHeader/VideoTrackHeader.svelte +85 -32
- package/dist/components/molecules/VideoTrackHeader/VideoTrackHeader.svelte.d.ts +6 -0
- package/dist/components/molecules/VideoTransitionsPanel/VideoTransitionsPanel.stories.js +8 -0
- package/dist/components/molecules/VideoTransitionsPanel/VideoTransitionsPanel.svelte +113 -0
- package/dist/components/molecules/VideoTransitionsPanel/VideoTransitionsPanel.svelte.d.ts +18 -0
- package/dist/components/molecules/VideoTransitionsPanel/VideoTransitionsPanelStory.svelte +7 -0
- package/dist/components/molecules/VideoTransitionsPanel/VideoTransitionsPanelStory.svelte.d.ts +18 -0
- package/dist/components/organisms/AudioEditor/AudioEditor.svelte +52 -1
- package/dist/components/organisms/EditorShell/EditorShell.svelte +102 -92
- package/dist/components/organisms/FileUploader/FileUploader.stories.d.ts +10 -0
- package/dist/components/organisms/FileUploader/FileUploader.stories.js +21 -0
- package/dist/components/organisms/FileUploader/FileUploader.svelte +61 -21
- package/dist/components/organisms/FileUploader/FileUploader.svelte.d.ts +9 -0
- package/dist/components/organisms/FileUploader/FileUploaderStory.svelte +7 -1
- package/dist/components/organisms/FileUploader/FileUploaderStory.svelte.d.ts +3 -0
- package/dist/components/organisms/VideoEditor/VideoEditor.svelte +1457 -78
- package/dist/components/organisms/VideoEditor/VideoEditor.svelte.d.ts +2 -1
- package/dist/components/organisms/VideoEditor/VideoEditorStory.svelte +3 -2
- package/dist/index.d.ts +11 -3
- package/dist/index.js +6 -2
- package/dist/styles.css +237 -0
- package/dist/utils/mediaTime.d.ts +14 -4
- package/dist/utils/mediaTime.js +27 -8
- package/dist/utils/mediaTracks.d.ts +154 -0
- package/dist/utils/mediaTracks.js +697 -1
- package/dist/utils/videoSequence.js +35 -4
- package/package.json +4 -2
|
@@ -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:
|
|
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
|
-
|
|
9
|
-
|
|
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 {
|
|
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';
|
package/dist/styles.css
ADDED
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
/* Scan this package so consumers only need to @import this file (no extra @source) */
|
|
2
|
+
@source './components/**/*.{svelte,js}';
|
|
3
|
+
@source './utils/**/*.{svelte,js}';
|
|
4
|
+
|
|
5
|
+
/* Match theme tokens (:root.dark) — not prefers-color-scheme alone */
|
|
6
|
+
@custom-variant dark (&:where(.dark, .dark *));
|
|
7
|
+
|
|
8
|
+
/* ─────────────────────────────────────────────────────────────────────────────
|
|
9
|
+
R2DigiSolutions Design System — Tailwind 4 @theme
|
|
10
|
+
─────────────────────────────────────────────────────────────────────────── */
|
|
11
|
+
|
|
12
|
+
@theme {
|
|
13
|
+
/* Brand colors */
|
|
14
|
+
--color-brand-50: oklch(97% 0.02 265);
|
|
15
|
+
--color-brand-100: oklch(93% 0.05 265);
|
|
16
|
+
--color-brand-200: oklch(86% 0.1 265);
|
|
17
|
+
--color-brand-300: oklch(76% 0.15 265);
|
|
18
|
+
--color-brand-400: oklch(65% 0.2 265);
|
|
19
|
+
--color-brand-500: oklch(55% 0.25 265);
|
|
20
|
+
--color-brand-600: oklch(47% 0.26 265);
|
|
21
|
+
--color-brand-700: oklch(39% 0.24 265);
|
|
22
|
+
--color-brand-800: oklch(31% 0.2 265);
|
|
23
|
+
--color-brand-900: oklch(22% 0.14 265);
|
|
24
|
+
--color-brand-950: oklch(15% 0.08 265);
|
|
25
|
+
|
|
26
|
+
/* Semantic surface tokens */
|
|
27
|
+
--color-surface: var(--surface);
|
|
28
|
+
--color-surface-elevated: var(--surface-elevated);
|
|
29
|
+
--color-surface-overlay: var(--surface-overlay);
|
|
30
|
+
--color-border: var(--border);
|
|
31
|
+
--color-border-strong: var(--border-strong);
|
|
32
|
+
--color-text-primary: var(--text-primary);
|
|
33
|
+
--color-text-secondary: var(--text-secondary);
|
|
34
|
+
--color-text-muted: var(--text-muted);
|
|
35
|
+
--color-text-inverse: var(--text-inverse);
|
|
36
|
+
|
|
37
|
+
/* Typography */
|
|
38
|
+
--font-sans: 'Inter', ui-sans-serif, system-ui, sans-serif;
|
|
39
|
+
--font-mono: 'JetBrains Mono', ui-monospace, monospace;
|
|
40
|
+
|
|
41
|
+
/* Radii */
|
|
42
|
+
--radius-sm: 0.375rem;
|
|
43
|
+
--radius-md: 0.5rem;
|
|
44
|
+
--radius-lg: 0.75rem;
|
|
45
|
+
--radius-xl: 1rem;
|
|
46
|
+
--radius-2xl: 1.5rem;
|
|
47
|
+
--radius-full: 9999px;
|
|
48
|
+
|
|
49
|
+
/* Shadows */
|
|
50
|
+
--shadow-sm: 0 1px 3px 0 oklch(0% 0 0 / 0.08), 0 1px 2px -1px oklch(0% 0 0 / 0.06);
|
|
51
|
+
--shadow-md: 0 4px 6px -1px oklch(0% 0 0 / 0.1), 0 2px 4px -2px oklch(0% 0 0 / 0.08);
|
|
52
|
+
--shadow-lg: 0 10px 15px -3px oklch(0% 0 0 / 0.12), 0 4px 6px -4px oklch(0% 0 0 / 0.08);
|
|
53
|
+
--shadow-xl: 0 20px 25px -5px oklch(0% 0 0 / 0.14), 0 8px 10px -6px oklch(0% 0 0 / 0.08);
|
|
54
|
+
|
|
55
|
+
/* Transitions */
|
|
56
|
+
--ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
|
|
57
|
+
--ease-smooth: cubic-bezier(0.4, 0, 0.2, 1);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/* ─────────────────────────────────────────────────────────────────────────────
|
|
61
|
+
Light mode (default)
|
|
62
|
+
─────────────────────────────────────────────────────────────────────────── */
|
|
63
|
+
|
|
64
|
+
:root {
|
|
65
|
+
color-scheme: light;
|
|
66
|
+
|
|
67
|
+
--surface: oklch(99% 0.005 265);
|
|
68
|
+
--surface-elevated: oklch(100% 0 0);
|
|
69
|
+
--surface-overlay: oklch(97% 0.01 265);
|
|
70
|
+
--border: oklch(88% 0.02 265);
|
|
71
|
+
--border-strong: oklch(75% 0.04 265);
|
|
72
|
+
--text-primary: oklch(15% 0.02 265);
|
|
73
|
+
--text-secondary: oklch(35% 0.03 265);
|
|
74
|
+
--text-muted: oklch(45% 0.02 265);
|
|
75
|
+
--text-inverse: oklch(99% 0 0);
|
|
76
|
+
|
|
77
|
+
/* Alert tones */
|
|
78
|
+
--alert-info-bg: oklch(96% 0.03 240);
|
|
79
|
+
--alert-info-border: oklch(82% 0.06 240);
|
|
80
|
+
--alert-info-fg: oklch(28% 0.08 240);
|
|
81
|
+
--alert-info-muted: oklch(40% 0.06 240);
|
|
82
|
+
--alert-info-icon: oklch(52% 0.14 240);
|
|
83
|
+
--alert-info-accent: oklch(55% 0.16 240);
|
|
84
|
+
|
|
85
|
+
--alert-success-bg: oklch(96% 0.04 150);
|
|
86
|
+
--alert-success-border: oklch(82% 0.07 150);
|
|
87
|
+
--alert-success-fg: oklch(28% 0.08 150);
|
|
88
|
+
--alert-success-muted: oklch(38% 0.06 150);
|
|
89
|
+
--alert-success-icon: oklch(50% 0.14 150);
|
|
90
|
+
--alert-success-accent: oklch(55% 0.16 150);
|
|
91
|
+
|
|
92
|
+
--alert-warning-bg: oklch(96% 0.05 85);
|
|
93
|
+
--alert-warning-border: oklch(84% 0.1 85);
|
|
94
|
+
--alert-warning-fg: oklch(30% 0.08 75);
|
|
95
|
+
--alert-warning-muted: oklch(42% 0.07 75);
|
|
96
|
+
--alert-warning-icon: oklch(58% 0.15 75);
|
|
97
|
+
--alert-warning-accent: oklch(68% 0.16 75);
|
|
98
|
+
|
|
99
|
+
--alert-error-bg: oklch(96% 0.03 25);
|
|
100
|
+
--alert-error-border: oklch(84% 0.08 25);
|
|
101
|
+
--alert-error-fg: oklch(30% 0.1 25);
|
|
102
|
+
--alert-error-muted: oklch(42% 0.08 25);
|
|
103
|
+
--alert-error-icon: oklch(55% 0.18 25);
|
|
104
|
+
--alert-error-accent: oklch(58% 0.2 25);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/* ─────────────────────────────────────────────────────────────────────────────
|
|
108
|
+
Dark mode
|
|
109
|
+
─────────────────────────────────────────────────────────────────────────── */
|
|
110
|
+
|
|
111
|
+
:root.dark {
|
|
112
|
+
color-scheme: dark;
|
|
113
|
+
|
|
114
|
+
--surface: oklch(14% 0.02 265);
|
|
115
|
+
--surface-elevated: oklch(18% 0.025 265);
|
|
116
|
+
--surface-overlay: oklch(20% 0.03 265);
|
|
117
|
+
--border: oklch(28% 0.03 265);
|
|
118
|
+
--border-strong: oklch(40% 0.04 265);
|
|
119
|
+
--text-primary: oklch(96% 0.01 265);
|
|
120
|
+
--text-secondary: oklch(75% 0.03 265);
|
|
121
|
+
--text-muted: oklch(55% 0.03 265);
|
|
122
|
+
--text-inverse: oklch(15% 0.02 265);
|
|
123
|
+
|
|
124
|
+
/* Alert tones */
|
|
125
|
+
--alert-info-bg: oklch(24% 0.04 240);
|
|
126
|
+
--alert-info-border: oklch(38% 0.06 240);
|
|
127
|
+
--alert-info-fg: oklch(92% 0.03 240);
|
|
128
|
+
--alert-info-muted: oklch(78% 0.04 240);
|
|
129
|
+
--alert-info-icon: oklch(72% 0.12 240);
|
|
130
|
+
--alert-info-accent: oklch(65% 0.14 240);
|
|
131
|
+
|
|
132
|
+
--alert-success-bg: oklch(24% 0.04 150);
|
|
133
|
+
--alert-success-border: oklch(38% 0.06 150);
|
|
134
|
+
--alert-success-fg: oklch(92% 0.03 150);
|
|
135
|
+
--alert-success-muted: oklch(78% 0.04 150);
|
|
136
|
+
--alert-success-icon: oklch(72% 0.12 150);
|
|
137
|
+
--alert-success-accent: oklch(65% 0.14 150);
|
|
138
|
+
|
|
139
|
+
--alert-warning-bg: oklch(25% 0.04 85);
|
|
140
|
+
--alert-warning-border: oklch(40% 0.07 85);
|
|
141
|
+
--alert-warning-fg: oklch(93% 0.03 85);
|
|
142
|
+
--alert-warning-muted: oklch(80% 0.04 85);
|
|
143
|
+
--alert-warning-icon: oklch(78% 0.12 85);
|
|
144
|
+
--alert-warning-accent: oklch(72% 0.14 85);
|
|
145
|
+
|
|
146
|
+
--alert-error-bg: oklch(24% 0.05 25);
|
|
147
|
+
--alert-error-border: oklch(40% 0.08 25);
|
|
148
|
+
--alert-error-fg: oklch(93% 0.03 25);
|
|
149
|
+
--alert-error-muted: oklch(80% 0.04 25);
|
|
150
|
+
--alert-error-icon: oklch(72% 0.14 25);
|
|
151
|
+
--alert-error-accent: oklch(65% 0.18 25);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/* ─────────────────────────────────────────────────────────────────────────────
|
|
155
|
+
Base styles
|
|
156
|
+
─────────────────────────────────────────────────────────────────────────── */
|
|
157
|
+
|
|
158
|
+
@layer base {
|
|
159
|
+
*,
|
|
160
|
+
*::before,
|
|
161
|
+
*::after {
|
|
162
|
+
box-sizing: border-box;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
html {
|
|
166
|
+
-webkit-text-size-adjust: 100%;
|
|
167
|
+
-webkit-font-smoothing: antialiased;
|
|
168
|
+
-moz-osx-font-smoothing: grayscale;
|
|
169
|
+
scroll-behavior: smooth;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
body {
|
|
173
|
+
margin: 0;
|
|
174
|
+
background-color: var(--surface);
|
|
175
|
+
color: var(--text-primary);
|
|
176
|
+
font-family: var(--font-sans);
|
|
177
|
+
line-height: 1.6;
|
|
178
|
+
transition:
|
|
179
|
+
background-color 0.2s var(--ease-smooth),
|
|
180
|
+
color 0.2s var(--ease-smooth);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/* Focus visible styles */
|
|
184
|
+
:focus-visible {
|
|
185
|
+
outline: 2px solid oklch(55% 0.25 265);
|
|
186
|
+
outline-offset: 2px;
|
|
187
|
+
border-radius: var(--radius-sm);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/* Selection */
|
|
191
|
+
::selection {
|
|
192
|
+
background-color: oklch(55% 0.25 265 / 0.25);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/* ─────────────────────────────────────────────────────────────────────────────
|
|
197
|
+
Utility layer
|
|
198
|
+
─────────────────────────────────────────────────────────────────────────── */
|
|
199
|
+
|
|
200
|
+
@layer utilities {
|
|
201
|
+
/* Touch-friendly minimum tap target */
|
|
202
|
+
.touch-target {
|
|
203
|
+
min-height: 44px;
|
|
204
|
+
min-width: 44px;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/* Smooth transitions */
|
|
208
|
+
.transition-smooth {
|
|
209
|
+
transition: all 0.2s var(--ease-smooth);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
.transition-spring {
|
|
213
|
+
transition: all 0.3s var(--ease-spring);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/* Glass morphism */
|
|
217
|
+
.glass {
|
|
218
|
+
backdrop-filter: blur(12px) saturate(180%);
|
|
219
|
+
background-color: oklch(100% 0 0 / 0.08);
|
|
220
|
+
border: 1px solid oklch(100% 0 0 / 0.12);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
.dark .glass {
|
|
224
|
+
background-color: oklch(0% 0 0 / 0.2);
|
|
225
|
+
border-color: oklch(100% 0 0 / 0.08);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/* Surface utilities */
|
|
229
|
+
.bg-surface { background-color: var(--surface); }
|
|
230
|
+
.bg-surface-elevated { background-color: var(--surface-elevated); }
|
|
231
|
+
.bg-surface-overlay { background-color: var(--surface-overlay); }
|
|
232
|
+
.border-border { border-color: var(--border); }
|
|
233
|
+
.border-border-strong { border-color: var(--border-strong); }
|
|
234
|
+
.text-primary { color: var(--text-primary); }
|
|
235
|
+
.text-secondary { color: var(--text-secondary); }
|
|
236
|
+
.text-muted { color: var(--text-muted); }
|
|
237
|
+
}
|
|
@@ -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
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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;
|
package/dist/utils/mediaTime.js
CHANGED
|
@@ -40,18 +40,37 @@ export function formatTimecode(ms, opts) {
|
|
|
40
40
|
}
|
|
41
41
|
return `${hh}${mm}:${ss}`;
|
|
42
42
|
}
|
|
43
|
-
|
|
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
|
-
|
|
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
|
-
|
|
54
|
-
|
|
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'>>;
|