@twick/video-editor 0.15.14 → 0.15.16
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/dist/components/controls/control-manager.d.ts +2 -1
- package/dist/components/controls/player-controls.d.ts +13 -3
- package/dist/components/controls/seek-control.d.ts +3 -1
- package/dist/components/player/canvas-context-menu.d.ts +18 -0
- package/dist/components/player/player-manager.d.ts +5 -1
- package/dist/components/timeline/marquee-overlay.d.ts +12 -0
- package/dist/components/timeline/timeline-view.d.ts +21 -3
- package/dist/components/track/seek-track.d.ts +7 -1
- package/dist/components/track/track-base.d.ts +3 -2
- package/dist/components/track/track-element.d.ts +2 -1
- package/dist/components/track/track-header.d.ts +3 -3
- package/dist/components/video-editor.d.ts +6 -1
- package/dist/helpers/asset-type.d.ts +6 -0
- package/dist/helpers/constants.d.ts +8 -105
- package/dist/helpers/function.utils.d.ts +18 -0
- package/dist/helpers/snap-targets.d.ts +7 -0
- package/dist/helpers/types.d.ts +10 -0
- package/dist/hooks/use-canvas-drop.d.ts +25 -0
- package/dist/hooks/use-canvas-keyboard.d.ts +13 -0
- package/dist/hooks/use-marquee-selection.d.ts +24 -0
- package/dist/hooks/use-player-manager.d.ts +16 -3
- package/dist/hooks/use-playhead-scroll.d.ts +19 -0
- package/dist/hooks/use-timeline-control.d.ts +1 -1
- package/dist/hooks/use-timeline-drop.d.ts +40 -0
- package/dist/hooks/use-timeline-selection.d.ts +13 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.js +2089 -645
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2091 -647
- package/dist/index.mjs.map +1 -1
- package/dist/video-editor.css +180 -31
- package/package.json +5 -5
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { TimelineZoomConfig } from '../video-editor';
|
|
2
2
|
|
|
3
|
-
declare const ControlManager: ({ trackZoom, setTrackZoom, zoomConfig, }: {
|
|
3
|
+
declare const ControlManager: ({ trackZoom, setTrackZoom, zoomConfig, fps, }: {
|
|
4
4
|
trackZoom: number;
|
|
5
5
|
setTrackZoom: (zoom: number) => void;
|
|
6
6
|
zoomConfig: TimelineZoomConfig;
|
|
7
|
+
fps?: number;
|
|
7
8
|
}) => import("react/jsx-runtime").JSX.Element;
|
|
8
9
|
export default ControlManager;
|
|
@@ -27,8 +27,10 @@ import { TimelineZoomConfig } from '../video-editor';
|
|
|
27
27
|
* ```
|
|
28
28
|
*/
|
|
29
29
|
export interface PlayerControlsProps {
|
|
30
|
-
/** Currently selected timeline element or track */
|
|
30
|
+
/** Currently selected timeline element or track (primary) */
|
|
31
31
|
selectedItem: TrackElement | Track | null;
|
|
32
|
+
/** Set of selected IDs for multi-select */
|
|
33
|
+
selectedIds?: Set<string>;
|
|
32
34
|
/** Current playback time in seconds */
|
|
33
35
|
currentTime: number;
|
|
34
36
|
/** Total duration of the timeline in seconds */
|
|
@@ -45,8 +47,8 @@ export interface PlayerControlsProps {
|
|
|
45
47
|
onUndo?: () => void;
|
|
46
48
|
/** Optional callback for redo operation */
|
|
47
49
|
onRedo?: () => void;
|
|
48
|
-
/** Optional callback for delete operation */
|
|
49
|
-
onDelete?: (
|
|
50
|
+
/** Optional callback for delete operation (deletes all selected) */
|
|
51
|
+
onDelete?: () => void;
|
|
50
52
|
/** Optional callback for split operation */
|
|
51
53
|
onSplit?: (item: TrackElement, splitTime: number) => void;
|
|
52
54
|
/** Current zoom level for timeline */
|
|
@@ -57,6 +59,14 @@ export interface PlayerControlsProps {
|
|
|
57
59
|
className?: string;
|
|
58
60
|
/** Timeline zoom configuration (min, max, step, default) */
|
|
59
61
|
zoomConfig?: TimelineZoomConfig;
|
|
62
|
+
/** Frames per second for time display (MM:SS.FF format) */
|
|
63
|
+
fps?: number;
|
|
64
|
+
/** Callback to seek to a specific time (for jump to start/end) */
|
|
65
|
+
onSeek?: (time: number) => void;
|
|
66
|
+
/** Whether timeline follows playhead during playback */
|
|
67
|
+
followPlayheadEnabled?: boolean;
|
|
68
|
+
/** Toggle follow playhead */
|
|
69
|
+
onFollowPlayheadToggle?: () => void;
|
|
60
70
|
}
|
|
61
71
|
declare const PlayerControls: React.FC<PlayerControlsProps>;
|
|
62
72
|
export default PlayerControls;
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
+
import { PlayheadState } from '../track/seek-track';
|
|
1
2
|
import { TimelineTickConfig } from '../video-editor';
|
|
2
3
|
|
|
3
|
-
declare const SeekControl: ({ duration, zoom, timelineCount, onSeek, timelineTickConfigs, }: {
|
|
4
|
+
declare const SeekControl: ({ duration, zoom, timelineCount, onSeek, timelineTickConfigs, onPlayheadUpdate, }: {
|
|
4
5
|
duration: number;
|
|
5
6
|
zoom: number;
|
|
6
7
|
timelineCount: number;
|
|
7
8
|
onSeek: (time: number) => void;
|
|
8
9
|
timelineTickConfigs?: TimelineTickConfig[];
|
|
10
|
+
onPlayheadUpdate?: (state: PlayheadState) => void;
|
|
9
11
|
}) => import("react/jsx-runtime").JSX.Element;
|
|
10
12
|
export default SeekControl;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
|
|
3
|
+
export interface CanvasContextMenuProps {
|
|
4
|
+
x: number;
|
|
5
|
+
y: number;
|
|
6
|
+
elementId: string;
|
|
7
|
+
onBringToFront: (elementId: string) => void;
|
|
8
|
+
onSendToBack: (elementId: string) => void;
|
|
9
|
+
onBringForward: (elementId: string) => void;
|
|
10
|
+
onSendBackward: (elementId: string) => void;
|
|
11
|
+
onDelete: (elementId: string) => void;
|
|
12
|
+
onClose: () => void;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Context menu for canvas elements: z-order actions (Bring to Front, Send to Back, etc.).
|
|
16
|
+
* Renders at the given coordinates and closes on action or click outside.
|
|
17
|
+
*/
|
|
18
|
+
export declare const CanvasContextMenu: React.FC<CanvasContextMenuProps>;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { CanvasConfig } from '../../helpers/types';
|
|
1
2
|
|
|
2
3
|
/**
|
|
3
4
|
* PlayerManager component that manages video playback and canvas rendering.
|
|
@@ -9,6 +10,7 @@
|
|
|
9
10
|
* @param props.videoProps - Video dimensions and background color
|
|
10
11
|
* @param props.playerProps - Optional player quality settings
|
|
11
12
|
* @param props.canvasMode - Whether to show canvas overlay when paused
|
|
13
|
+
* @param props.canvasConfig - Canvas behavior options (e.g. enableShiftAxisLock)
|
|
12
14
|
* @returns JSX element containing player and canvas components
|
|
13
15
|
*
|
|
14
16
|
* @example
|
|
@@ -17,10 +19,11 @@
|
|
|
17
19
|
* videoProps={{ width: 1920, height: 1080, backgroundColor: '#000' }}
|
|
18
20
|
* playerProps={{ quality: 720 }}
|
|
19
21
|
* canvasMode={true}
|
|
22
|
+
* canvasConfig={{ enableShiftAxisLock: true }}
|
|
20
23
|
* />
|
|
21
24
|
* ```
|
|
22
25
|
*/
|
|
23
|
-
export declare const PlayerManager: ({ videoProps, playerProps, canvasMode, }: {
|
|
26
|
+
export declare const PlayerManager: ({ videoProps, playerProps, canvasMode, canvasConfig, }: {
|
|
24
27
|
videoProps: {
|
|
25
28
|
width: number;
|
|
26
29
|
height: number;
|
|
@@ -30,4 +33,5 @@ export declare const PlayerManager: ({ videoProps, playerProps, canvasMode, }: {
|
|
|
30
33
|
quality?: number;
|
|
31
34
|
};
|
|
32
35
|
canvasMode: boolean;
|
|
36
|
+
canvasConfig?: CanvasConfig;
|
|
33
37
|
}) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
interface MarqueeRect {
|
|
2
|
+
startX: number;
|
|
3
|
+
startY: number;
|
|
4
|
+
endX: number;
|
|
5
|
+
endY: number;
|
|
6
|
+
}
|
|
7
|
+
interface MarqueeOverlayProps {
|
|
8
|
+
marquee: MarqueeRect | null;
|
|
9
|
+
}
|
|
10
|
+
/** Renders the marquee selection rectangle. Does not capture pointer events. */
|
|
11
|
+
export declare function MarqueeOverlay({ marquee }: MarqueeOverlayProps): import("react/jsx-runtime").JSX.Element;
|
|
12
|
+
export {};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Track, TrackElement } from '@twick/timeline';
|
|
1
|
+
import { Track, TrackElement, Size } from '@twick/timeline';
|
|
2
2
|
import { ElementColors } from '../../helpers/types';
|
|
3
3
|
|
|
4
|
-
declare function TimelineView({ zoomLevel, selectedItem, duration, tracks, seekTrack, onAddTrack, onReorder,
|
|
4
|
+
declare function TimelineView({ zoomLevel, selectedItem, duration, tracks, seekTrack, onAddTrack, onReorder, onItemSelect, onEmptyClick, onMarqueeSelect, onElementDrag, elementColors, selectedIds, playheadPositionPx, isPlayheadActive, onDropOnTimeline, videoResolution, enableDropOnTimeline, }: {
|
|
5
5
|
zoomLevel: number;
|
|
6
6
|
duration: number;
|
|
7
7
|
tracks: Track[];
|
|
@@ -18,8 +18,26 @@ declare function TimelineView({ zoomLevel, selectedItem, duration, tracks, seekT
|
|
|
18
18
|
};
|
|
19
19
|
}) => void;
|
|
20
20
|
onSeek: (time: number) => void;
|
|
21
|
-
|
|
21
|
+
onItemSelect: (item: Track | TrackElement, event: React.MouseEvent) => void;
|
|
22
|
+
onEmptyClick: () => void;
|
|
23
|
+
onMarqueeSelect: (ids: Set<string>) => void;
|
|
22
24
|
onDeletion: (element: TrackElement | Track) => void;
|
|
25
|
+
selectedIds: Set<string>;
|
|
23
26
|
elementColors?: ElementColors;
|
|
27
|
+
/** Playhead position in pixels (for auto-scroll) */
|
|
28
|
+
playheadPositionPx?: number;
|
|
29
|
+
/** Whether playhead is moving (playing or dragging) */
|
|
30
|
+
isPlayheadActive?: boolean;
|
|
31
|
+
/** Called when a file or panel media item is dropped on the timeline */
|
|
32
|
+
onDropOnTimeline?: (params: {
|
|
33
|
+
track: Track | null;
|
|
34
|
+
timeSec: number;
|
|
35
|
+
type: "video" | "audio" | "image";
|
|
36
|
+
url: string;
|
|
37
|
+
}) => Promise<void>;
|
|
38
|
+
/** Video resolution for creating elements from dropped files */
|
|
39
|
+
videoResolution?: Size;
|
|
40
|
+
/** Whether to enable drop-on-timeline */
|
|
41
|
+
enableDropOnTimeline?: boolean;
|
|
24
42
|
}): import("react/jsx-runtime").JSX.Element;
|
|
25
43
|
export default TimelineView;
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { TimelineTickConfig } from '../video-editor';
|
|
2
2
|
|
|
3
|
+
export interface PlayheadState {
|
|
4
|
+
positionPx: number;
|
|
5
|
+
isDragging: boolean;
|
|
6
|
+
}
|
|
3
7
|
interface SeekTrackProps {
|
|
4
8
|
currentTime: number;
|
|
5
9
|
duration: number;
|
|
@@ -7,6 +11,8 @@ interface SeekTrackProps {
|
|
|
7
11
|
onSeek: (time: number) => void;
|
|
8
12
|
timelineCount?: number;
|
|
9
13
|
timelineTickConfigs?: TimelineTickConfig[];
|
|
14
|
+
/** Called when playhead position or drag state changes (for auto-scroll) */
|
|
15
|
+
onPlayheadUpdate?: (state: PlayheadState) => void;
|
|
10
16
|
}
|
|
11
|
-
export default function SeekTrack({ currentTime, duration, zoom, onSeek, timelineCount, timelineTickConfigs, }: SeekTrackProps): import("react/jsx-runtime").JSX.Element;
|
|
17
|
+
export default function SeekTrack({ currentTime, duration, zoom, onSeek, timelineCount, timelineTickConfigs, onPlayheadUpdate, }: SeekTrackProps): import("react/jsx-runtime").JSX.Element;
|
|
12
18
|
export {};
|
|
@@ -7,8 +7,9 @@ interface TrackBaseProps {
|
|
|
7
7
|
track: Track;
|
|
8
8
|
trackWidth: number;
|
|
9
9
|
selectedItem: TrackElement | null;
|
|
10
|
+
selectedIds: Set<string>;
|
|
10
11
|
allowOverlap?: boolean;
|
|
11
|
-
onItemSelection: (element: TrackElement) => void;
|
|
12
|
+
onItemSelection: (element: TrackElement, event: React.MouseEvent) => void;
|
|
12
13
|
onDrag: ({ element, dragType, updates, }: {
|
|
13
14
|
element: TrackElement;
|
|
14
15
|
dragType: string;
|
|
@@ -19,5 +20,5 @@ interface TrackBaseProps {
|
|
|
19
20
|
}) => void;
|
|
20
21
|
elementColors?: ElementColors;
|
|
21
22
|
}
|
|
22
|
-
declare const TrackBase: ({ duration, zoom, track, trackWidth, selectedItem, onItemSelection, onDrag, allowOverlap, elementColors, }: TrackBaseProps) => import("react/jsx-runtime").JSX.Element;
|
|
23
|
+
declare const TrackBase: ({ duration, zoom, track, trackWidth, selectedItem, selectedIds, onItemSelection, onDrag, allowOverlap, elementColors, }: TrackBaseProps) => import("react/jsx-runtime").JSX.Element;
|
|
23
24
|
export default TrackBase;
|
|
@@ -4,12 +4,13 @@ import { ElementColors } from '../../helpers/types';
|
|
|
4
4
|
export declare const TrackElementView: React.FC<{
|
|
5
5
|
element: TrackElement;
|
|
6
6
|
selectedItem: TrackElement | null;
|
|
7
|
+
selectedIds: Set<string>;
|
|
7
8
|
parentWidth: number;
|
|
8
9
|
duration: number;
|
|
9
10
|
nextStart: number | null;
|
|
10
11
|
prevEnd: number;
|
|
11
12
|
allowOverlap: boolean;
|
|
12
|
-
onSelection: (element: TrackElement) => void;
|
|
13
|
+
onSelection: (element: TrackElement, event: React.MouseEvent) => void;
|
|
13
14
|
onDrag: ({ element, dragType, updates, }: {
|
|
14
15
|
element: TrackElement;
|
|
15
16
|
dragType: string;
|
|
@@ -3,11 +3,11 @@ import { Track } from '@twick/timeline';
|
|
|
3
3
|
|
|
4
4
|
interface TrackHeaderProps {
|
|
5
5
|
track: Track;
|
|
6
|
-
|
|
7
|
-
onSelect: (track: Track) => void;
|
|
6
|
+
selectedIds: Set<string>;
|
|
7
|
+
onSelect: (track: Track, event: React.MouseEvent) => void;
|
|
8
8
|
onDragStart: (e: React.DragEvent, track: Track) => void;
|
|
9
9
|
onDragOver: (e: React.DragEvent) => void;
|
|
10
10
|
onDrop: (e: React.DragEvent, track: Track) => void;
|
|
11
11
|
}
|
|
12
|
-
declare const TrackHeader: ({ track,
|
|
12
|
+
declare const TrackHeader: ({ track, selectedIds, onDragStart, onDragOver, onDrop, onSelect, }: TrackHeaderProps) => import("react/jsx-runtime").JSX.Element;
|
|
13
13
|
export default TrackHeader;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { default as React } from 'react';
|
|
2
|
-
import { ElementColors } from '../helpers/types';
|
|
2
|
+
import { CanvasConfig, ElementColors } from '../helpers/types';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Configuration for timeline tick marks at specific duration ranges.
|
|
@@ -55,6 +55,7 @@ export interface TimelineZoomConfig {
|
|
|
55
55
|
* const editorConfig = {
|
|
56
56
|
* videoProps: { width: 1920, height: 1080 },
|
|
57
57
|
* canvasMode: true,
|
|
58
|
+
* canvasConfig: { enableShiftAxisLock: true },
|
|
58
59
|
* timelineTickConfigs: [
|
|
59
60
|
* { durationThreshold: 30, majorInterval: 5, minorTicks: 5 },
|
|
60
61
|
* { durationThreshold: 300, majorInterval: 30, minorTicks: 6 }
|
|
@@ -87,12 +88,16 @@ export interface VideoEditorConfig {
|
|
|
87
88
|
};
|
|
88
89
|
/** Whether to use canvas mode for rendering */
|
|
89
90
|
canvasMode?: boolean;
|
|
91
|
+
/** Canvas behavior options (axis lock, zoom, snapping, etc.). Used by TwickEditor and TwickStudio. */
|
|
92
|
+
canvasConfig?: CanvasConfig;
|
|
90
93
|
/** Custom timeline tick configurations for different duration ranges */
|
|
91
94
|
timelineTickConfigs?: TimelineTickConfig[];
|
|
92
95
|
/** Custom timeline zoom configuration (min, max, step, default) */
|
|
93
96
|
timelineZoomConfig?: TimelineZoomConfig;
|
|
94
97
|
/** Custom element colors for timeline elements */
|
|
95
98
|
elementColors?: ElementColors;
|
|
99
|
+
/** Frames per second for time display (MM:SS.FF format) */
|
|
100
|
+
fps?: number;
|
|
96
101
|
}
|
|
97
102
|
/**
|
|
98
103
|
* Props for the VideoEditor component.
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Maps file MIME type or extension to timeline element type.
|
|
3
|
+
* Used for drop-on-timeline to determine which element to create.
|
|
4
|
+
*/
|
|
5
|
+
export type DroppableAssetType = "video" | "audio" | "image";
|
|
6
|
+
export declare function getAssetTypeFromFile(file: File): DroppableAssetType | null;
|
|
@@ -4,17 +4,6 @@ import { TimelineTickConfig } from '../components/video-editor';
|
|
|
4
4
|
/**
|
|
5
5
|
* Initial timeline data structure for new video editor projects.
|
|
6
6
|
* Provides a default timeline with a sample text element to get started.
|
|
7
|
-
*
|
|
8
|
-
* @example
|
|
9
|
-
* ```js
|
|
10
|
-
* import { INITIAL_TIMELINE_DATA } from '@twick/video-editor';
|
|
11
|
-
*
|
|
12
|
-
* // Use as starting point for new projects
|
|
13
|
-
* const newProject = {
|
|
14
|
-
* ...INITIAL_TIMELINE_DATA,
|
|
15
|
-
* tracks: [...INITIAL_TIMELINE_DATA.tracks, newTrack]
|
|
16
|
-
* };
|
|
17
|
-
* ```
|
|
18
7
|
*/
|
|
19
8
|
export declare const INITIAL_TIMELINE_DATA: {
|
|
20
9
|
tracks: {
|
|
@@ -39,39 +28,9 @@ export declare const INITIAL_TIMELINE_DATA: {
|
|
|
39
28
|
/**
|
|
40
29
|
* Minimum duration for timeline elements in seconds.
|
|
41
30
|
* Used to prevent elements from having zero or negative duration.
|
|
42
|
-
*
|
|
43
|
-
* @example
|
|
44
|
-
* ```js
|
|
45
|
-
* import { MIN_DURATION } from '@twick/video-editor';
|
|
46
|
-
*
|
|
47
|
-
* const elementDuration = Math.max(duration, MIN_DURATION);
|
|
48
|
-
* // Ensures element has at least 0.1 seconds duration
|
|
49
|
-
* ```
|
|
50
31
|
*/
|
|
51
32
|
export declare const MIN_DURATION = 0.1;
|
|
52
|
-
|
|
53
|
-
* Drag operation types for timeline interactions.
|
|
54
|
-
* Defines the different phases of drag operations on timeline elements.
|
|
55
|
-
*
|
|
56
|
-
* @example
|
|
57
|
-
* ```js
|
|
58
|
-
* import { DRAG_TYPE } from '@twick/video-editor';
|
|
59
|
-
*
|
|
60
|
-
* function handleDrag(type) {
|
|
61
|
-
* switch (type) {
|
|
62
|
-
* case DRAG_TYPE.START:
|
|
63
|
-
* // Handle drag start
|
|
64
|
-
* break;
|
|
65
|
-
* case DRAG_TYPE.MOVE:
|
|
66
|
-
* // Handle drag move
|
|
67
|
-
* break;
|
|
68
|
-
* case DRAG_TYPE.END:
|
|
69
|
-
* // Handle drag end
|
|
70
|
-
* break;
|
|
71
|
-
* }
|
|
72
|
-
* }
|
|
73
|
-
* ```
|
|
74
|
-
*/
|
|
33
|
+
export declare const TIMELINE_DROP_MEDIA_TYPE = "application/x-twick-media";
|
|
75
34
|
export declare const DRAG_TYPE: {
|
|
76
35
|
/** Drag operation is starting */
|
|
77
36
|
readonly START: "start";
|
|
@@ -80,36 +39,18 @@ export declare const DRAG_TYPE: {
|
|
|
80
39
|
/** Drag operation has ended */
|
|
81
40
|
readonly END: "end";
|
|
82
41
|
};
|
|
83
|
-
/**
|
|
84
|
-
* Default zoom level for timeline view.
|
|
85
|
-
* Controls the initial magnification of the timeline interface.
|
|
86
|
-
*
|
|
87
|
-
* @example
|
|
88
|
-
* ```js
|
|
89
|
-
* import { DEFAULT_TIMELINE_ZOOM } from '@twick/video-editor';
|
|
90
|
-
*
|
|
91
|
-
* const [zoom, setZoom] = useState(DEFAULT_TIMELINE_ZOOM);
|
|
92
|
-
* // Timeline starts with 1.5x zoom
|
|
93
|
-
* ```
|
|
94
|
-
*/
|
|
95
42
|
export declare const DEFAULT_TIMELINE_ZOOM = 1.5;
|
|
96
43
|
/**
|
|
97
44
|
* Default timeline zoom configuration including min, max, step, and default values.
|
|
98
45
|
* Controls the zoom behavior and constraints for the timeline view.
|
|
99
|
-
*
|
|
100
|
-
* @example
|
|
101
|
-
* ```js
|
|
102
|
-
* import { DEFAULT_TIMELINE_ZOOM_CONFIG } from '@twick/video-editor';
|
|
103
|
-
*
|
|
104
|
-
* // Use default zoom configuration
|
|
105
|
-
* <VideoEditor
|
|
106
|
-
* editorConfig={{
|
|
107
|
-
* videoProps: { width: 1920, height: 1080 },
|
|
108
|
-
* timelineZoomConfig: DEFAULT_TIMELINE_ZOOM_CONFIG
|
|
109
|
-
* }}
|
|
110
|
-
* />
|
|
111
|
-
* ```
|
|
112
46
|
*/
|
|
47
|
+
/**
|
|
48
|
+
* Default frames per second for timeline time display.
|
|
49
|
+
* Used for MM:SS.FF format (e.g. 00:15.12 = 15.4 seconds at 30fps).
|
|
50
|
+
*/
|
|
51
|
+
export declare const DEFAULT_FPS = 30;
|
|
52
|
+
/** Snap threshold in pixels - used to convert to seconds based on zoom */
|
|
53
|
+
export declare const SNAP_THRESHOLD_PX = 10;
|
|
113
54
|
export declare const DEFAULT_TIMELINE_ZOOM_CONFIG: {
|
|
114
55
|
/** Minimum zoom level (10%) */
|
|
115
56
|
min: number;
|
|
@@ -127,54 +68,16 @@ export declare const DEFAULT_TIMELINE_ZOOM_CONFIG: {
|
|
|
127
68
|
*
|
|
128
69
|
* Each configuration applies when the duration is less than the specified threshold.
|
|
129
70
|
* Configurations are ordered by duration threshold ascending.
|
|
130
|
-
*
|
|
131
|
-
* @example
|
|
132
|
-
* ```js
|
|
133
|
-
* import { DEFAULT_TIMELINE_TICK_CONFIGS } from '@twick/video-editor';
|
|
134
|
-
*
|
|
135
|
-
* // Use default configurations
|
|
136
|
-
* <VideoEditor
|
|
137
|
-
* editorConfig={{
|
|
138
|
-
* videoProps: { width: 1920, height: 1080 },
|
|
139
|
-
* timelineTickConfigs: DEFAULT_TIMELINE_TICK_CONFIGS
|
|
140
|
-
* }}
|
|
141
|
-
* />
|
|
142
|
-
* ```
|
|
143
71
|
*/
|
|
144
72
|
export declare const DEFAULT_TIMELINE_TICK_CONFIGS: TimelineTickConfig[];
|
|
145
73
|
/**
|
|
146
74
|
* Default color scheme for different element types in the timeline.
|
|
147
75
|
* Provides consistent visual distinction between various timeline elements.
|
|
148
|
-
*
|
|
149
|
-
* @example
|
|
150
|
-
* ```js
|
|
151
|
-
* import { DEFAULT_ELEMENT_COLORS } from '@twick/video-editor';
|
|
152
|
-
*
|
|
153
|
-
* const videoColor = DEFAULT_ELEMENT_COLORS.video; // "#4B2E83"
|
|
154
|
-
* const textColor = DEFAULT_ELEMENT_COLORS.text; // "#375A7F"
|
|
155
|
-
*
|
|
156
|
-
* // Apply colors to timeline elements
|
|
157
|
-
* element.style.backgroundColor = DEFAULT_ELEMENT_COLORS[element.type];
|
|
158
|
-
* ```
|
|
159
76
|
*/
|
|
160
77
|
export declare const DEFAULT_ELEMENT_COLORS: ElementColors;
|
|
161
78
|
/**
|
|
162
79
|
* Available text fonts for video editor text elements.
|
|
163
80
|
* Includes Google Fonts, display fonts, and custom CDN fonts.
|
|
164
|
-
*
|
|
165
|
-
* @example
|
|
166
|
-
* ```js
|
|
167
|
-
* import { AVAILABLE_TEXT_FONTS } from '@twick/video-editor';
|
|
168
|
-
*
|
|
169
|
-
* // Use Google Fonts
|
|
170
|
-
* const googleFont = AVAILABLE_TEXT_FONTS.ROBOTO; // "Roboto"
|
|
171
|
-
*
|
|
172
|
-
* // Use decorative fonts
|
|
173
|
-
* const decorativeFont = AVAILABLE_TEXT_FONTS.BANGERS; // "Bangers"
|
|
174
|
-
*
|
|
175
|
-
* // Apply font to text element
|
|
176
|
-
* textElement.style.fontFamily = AVAILABLE_TEXT_FONTS.POPPINS;
|
|
177
|
-
* ```
|
|
178
81
|
*/
|
|
179
82
|
export declare const AVAILABLE_TEXT_FONTS: {
|
|
180
83
|
/** Modern sans-serif font */
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates a debounced version of a function.
|
|
3
|
+
* The function will only be called after it has not been invoked
|
|
4
|
+
* for the specified delay.
|
|
5
|
+
*
|
|
6
|
+
* Useful for expensive operations that should not run on every
|
|
7
|
+
* keystroke / mouse move (e.g. resize handlers, search, etc.).
|
|
8
|
+
*/
|
|
9
|
+
export declare function debounce<T extends (...args: any[]) => any>(fn: T, delay: number): (...args: Parameters<T>) => void;
|
|
10
|
+
/**
|
|
11
|
+
* Creates a throttled version of a function.
|
|
12
|
+
* The function will be called at most once in every `interval`
|
|
13
|
+
* milliseconds, ignoring additional calls in between.
|
|
14
|
+
*
|
|
15
|
+
* Useful for high–frequency events like scroll / mousemove where
|
|
16
|
+
* you still want regular updates but not on every event.
|
|
17
|
+
*/
|
|
18
|
+
export declare function throttle<T extends (...args: any[]) => any>(fn: T, interval: number): (...args: Parameters<T>) => void;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Track } from '@twick/timeline';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Collects snap target times for the timeline.
|
|
5
|
+
* Includes: playhead, clip edges (excluding the dragging element), 0, and duration.
|
|
6
|
+
*/
|
|
7
|
+
export declare function getSnapTargets(tracks: Track[], currentTime: number, duration: number, excludeElementId?: string): number[];
|
package/dist/helpers/types.d.ts
CHANGED
|
@@ -67,3 +67,13 @@ export interface ElementColors {
|
|
|
67
67
|
transition: string;
|
|
68
68
|
animation: string;
|
|
69
69
|
}
|
|
70
|
+
/**
|
|
71
|
+
* Canvas behavior options for TwickEditor / TwickStudio.
|
|
72
|
+
* Customers set these via editorConfig.canvasConfig or studioConfig.
|
|
73
|
+
*/
|
|
74
|
+
export interface CanvasConfig {
|
|
75
|
+
/** When true, holding Shift while dragging restricts movement to horizontal or vertical (dominant axis). Default: false. */
|
|
76
|
+
enableShiftAxisLock?: boolean;
|
|
77
|
+
/** When true, element resize keeps aspect ratio (uniform scaling). Can be overridden per element via props. Default: true for media. */
|
|
78
|
+
lockAspectRatio?: boolean;
|
|
79
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { DroppableAssetType } from '../helpers/asset-type';
|
|
2
|
+
|
|
3
|
+
export interface CanvasDropPayload {
|
|
4
|
+
type: DroppableAssetType;
|
|
5
|
+
url: string;
|
|
6
|
+
canvasX?: number;
|
|
7
|
+
canvasY?: number;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Hook for handling file/media drops on the canvas.
|
|
11
|
+
* Accepts both files from OS and media dragged from studio panels.
|
|
12
|
+
*/
|
|
13
|
+
export declare function useCanvasDrop({ containerRef, videoSize, onDrop, enabled, }: {
|
|
14
|
+
containerRef: React.RefObject<HTMLElement | null>;
|
|
15
|
+
videoSize: {
|
|
16
|
+
width: number;
|
|
17
|
+
height: number;
|
|
18
|
+
};
|
|
19
|
+
onDrop: (payload: CanvasDropPayload) => Promise<void>;
|
|
20
|
+
enabled?: boolean;
|
|
21
|
+
}): {
|
|
22
|
+
handleDragOver: (e: React.DragEvent) => void;
|
|
23
|
+
handleDragLeave: (e: React.DragEvent) => void;
|
|
24
|
+
handleDrop: (e: React.DragEvent) => Promise<void>;
|
|
25
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Registers keyboard shortcuts for editor actions.
|
|
3
|
+
* - Delete, Backspace: delete
|
|
4
|
+
* - Cmd/Ctrl+Z: undo
|
|
5
|
+
* - Cmd/Ctrl+Shift+Z or Cmd/Ctrl+Y: redo
|
|
6
|
+
* Ignores events when focus is in input, textarea, or contenteditable.
|
|
7
|
+
*/
|
|
8
|
+
export declare function useCanvasKeyboard({ onDelete, onUndo, onRedo, enabled, }: {
|
|
9
|
+
onDelete?: () => void;
|
|
10
|
+
onUndo?: () => void;
|
|
11
|
+
onRedo?: () => void;
|
|
12
|
+
enabled?: boolean;
|
|
13
|
+
}): void;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Track } from '@twick/timeline';
|
|
2
|
+
|
|
3
|
+
export interface MarqueeRect {
|
|
4
|
+
startX: number;
|
|
5
|
+
startY: number;
|
|
6
|
+
endX: number;
|
|
7
|
+
endY: number;
|
|
8
|
+
}
|
|
9
|
+
interface UseMarqueeSelectionOptions {
|
|
10
|
+
duration: number;
|
|
11
|
+
zoomLevel: number;
|
|
12
|
+
labelWidth: number;
|
|
13
|
+
trackCount: number;
|
|
14
|
+
trackHeight: number;
|
|
15
|
+
tracks: Track[];
|
|
16
|
+
containerRef: React.RefObject<HTMLDivElement | null>;
|
|
17
|
+
onMarqueeSelect: (ids: Set<string>) => void;
|
|
18
|
+
onEmptyClick: () => void;
|
|
19
|
+
}
|
|
20
|
+
export declare function useMarqueeSelection({ duration, zoomLevel, labelWidth, trackCount, trackHeight, tracks, containerRef, onMarqueeSelect, onEmptyClick, }: UseMarqueeSelectionOptions): {
|
|
21
|
+
marquee: MarqueeRect | null;
|
|
22
|
+
handleMouseDown: (e: React.MouseEvent<HTMLDivElement>) => void;
|
|
23
|
+
};
|
|
24
|
+
export {};
|
|
@@ -1,28 +1,41 @@
|
|
|
1
|
+
import { CanvasDropPayload } from './use-canvas-drop';
|
|
2
|
+
import { CanvasConfig } from '../helpers/types';
|
|
3
|
+
|
|
1
4
|
/**
|
|
2
5
|
* Custom hook to manage player state and canvas interactions.
|
|
3
6
|
* Handles player data updates, canvas operations, and timeline synchronization
|
|
4
7
|
* for the video editor component.
|
|
5
8
|
*
|
|
6
9
|
* @param videoProps - Object containing video dimensions
|
|
10
|
+
* @param canvasConfig - Canvas behavior options (e.g. enableShiftAxisLock) from editorConfig / studioConfig
|
|
7
11
|
* @returns Object containing player management functions and state
|
|
8
12
|
*
|
|
9
13
|
* @example
|
|
10
14
|
* ```js
|
|
11
15
|
* const { twickCanvas, projectData, updateCanvas } = usePlayerManager({
|
|
12
|
-
* videoProps: { width: 1920, height: 1080 }
|
|
16
|
+
* videoProps: { width: 1920, height: 1080 },
|
|
17
|
+
* canvasConfig: { enableShiftAxisLock: true }
|
|
13
18
|
* });
|
|
14
19
|
* ```
|
|
15
20
|
*/
|
|
16
|
-
export declare const usePlayerManager: ({ videoProps, }: {
|
|
21
|
+
export declare const usePlayerManager: ({ videoProps, canvasConfig, }: {
|
|
17
22
|
videoProps: {
|
|
18
23
|
width: number;
|
|
19
24
|
height: number;
|
|
20
25
|
};
|
|
26
|
+
canvasConfig?: CanvasConfig;
|
|
21
27
|
}) => {
|
|
22
28
|
twickCanvas: any;
|
|
23
29
|
projectData: any;
|
|
24
|
-
updateCanvas: (seekTime: number) => void;
|
|
30
|
+
updateCanvas: (seekTime: number, forceRefresh?: boolean) => void;
|
|
25
31
|
buildCanvas: any;
|
|
32
|
+
resizeCanvas: any;
|
|
26
33
|
onPlayerUpdate: (event: CustomEvent) => void;
|
|
27
34
|
playerUpdating: boolean;
|
|
35
|
+
handleDropOnCanvas: (payload: CanvasDropPayload) => Promise<void>;
|
|
36
|
+
bringToFront: any;
|
|
37
|
+
sendToBack: any;
|
|
38
|
+
bringForward: any;
|
|
39
|
+
sendBackward: any;
|
|
40
|
+
deleteElement: (elementId: string) => void;
|
|
28
41
|
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration for playhead scroll behavior.
|
|
3
|
+
*/
|
|
4
|
+
export interface PlayheadScrollConfig {
|
|
5
|
+
/** Pixels to keep between playhead and viewport edge before auto-scrolling */
|
|
6
|
+
margin?: number;
|
|
7
|
+
/** Width of the label/track-header area (left of seek track) in pixels */
|
|
8
|
+
labelWidth?: number;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Scrolls the timeline container to keep the playhead visible when it reaches
|
|
12
|
+
* the viewport edge. Used during playback and when dragging the playhead.
|
|
13
|
+
*
|
|
14
|
+
* @param scrollContainerRef - Ref to the scrollable timeline container
|
|
15
|
+
* @param playheadPositionPx - Playhead position in pixels (from left of content)
|
|
16
|
+
* @param isActive - Whether to run scroll logic (playing or dragging)
|
|
17
|
+
* @param config - Optional margin and label width
|
|
18
|
+
*/
|
|
19
|
+
export declare function usePlayheadScroll(scrollContainerRef: React.RefObject<HTMLElement | null>, playheadPositionPx: number, isActive: boolean, config?: PlayheadScrollConfig): void;
|
|
@@ -20,7 +20,7 @@ import { TrackElement, Track } from '@twick/timeline';
|
|
|
20
20
|
*/
|
|
21
21
|
declare const useTimelineControl: () => {
|
|
22
22
|
splitElement: (element: TrackElement, currentTime: number) => void;
|
|
23
|
-
deleteItem: (item
|
|
23
|
+
deleteItem: (item?: Track | TrackElement) => void;
|
|
24
24
|
handleUndo: () => void;
|
|
25
25
|
handleRedo: () => void;
|
|
26
26
|
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Track, VideoElement, AudioElement, ImageElement, Size } from '@twick/timeline';
|
|
2
|
+
import { DroppableAssetType } from '../helpers/asset-type';
|
|
3
|
+
|
|
4
|
+
export interface DropPreview {
|
|
5
|
+
trackIndex: number;
|
|
6
|
+
timeSec: number;
|
|
7
|
+
/** Approximate width for preview (based on default duration) */
|
|
8
|
+
widthPct: number;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Hook for handling file drops on the timeline.
|
|
12
|
+
* Computes drop position from coordinates and provides handlers for drag/drop.
|
|
13
|
+
*/
|
|
14
|
+
export declare function useTimelineDrop({ containerRef, scrollContainerRef, tracks, duration, zoomLevel, labelWidth, trackHeight,
|
|
15
|
+
/** Width of the track content area (timeline minus labels). Used for accurate time mapping. */
|
|
16
|
+
trackContentWidth, onDrop, enabled, }: {
|
|
17
|
+
containerRef: React.RefObject<HTMLElement | null>;
|
|
18
|
+
/** Ref to scroll container; used for scrollLeft. Falls back to containerRef if not provided. */
|
|
19
|
+
scrollContainerRef?: React.RefObject<HTMLElement | null>;
|
|
20
|
+
tracks: Track[];
|
|
21
|
+
duration: number;
|
|
22
|
+
zoomLevel: number;
|
|
23
|
+
labelWidth: number;
|
|
24
|
+
trackHeight: number;
|
|
25
|
+
trackContentWidth?: number;
|
|
26
|
+
onDrop: (params: {
|
|
27
|
+
track: Track | null;
|
|
28
|
+
timeSec: number;
|
|
29
|
+
type: DroppableAssetType;
|
|
30
|
+
url: string;
|
|
31
|
+
}) => Promise<void>;
|
|
32
|
+
enabled?: boolean;
|
|
33
|
+
}): {
|
|
34
|
+
preview: DropPreview | null;
|
|
35
|
+
isDraggingOver: boolean;
|
|
36
|
+
handleDragOver: (e: React.DragEvent) => void;
|
|
37
|
+
handleDragLeave: (e: React.DragEvent) => void;
|
|
38
|
+
handleDrop: (e: React.DragEvent) => Promise<void>;
|
|
39
|
+
};
|
|
40
|
+
export declare function createElementFromDrop(type: DroppableAssetType, blobUrl: string, parentSize: Size): VideoElement | AudioElement | ImageElement;
|