Example Usage
Learn how to use the Timeline component with practical examples and quick start guide
Installation & Import
Main Component Import
import Timeline from '@/components/editor/components/advanced-timeline/timeline';
import { TimelineTrack } from '@/components/editor/components/advanced-timeline/types';
Basic Usage Example
Here's a complete example showing how to set up and use the Timeline component:
import React from 'react';
import Timeline from '@/components/editor/components/advanced-timeline/timeline';
import { TimelineTrack } from '@/components/editor/components/advanced-timeline/types';
const VideoEditor = () => {
const [tracks, setTracks] = React.useState<TimelineTrack[]>([
{
id: 'track-1',
name: 'Video Track',
items: [
{
id: 'item-1',
trackId: 'track-1',
start: 0,
end: 10,
type: 'video',
label: 'Video Clip 1',
color: '#3b82f6'
}
]
}
]);
const [currentFrame, setCurrentFrame] = React.useState(0);
const [isPlaying, setIsPlaying] = React.useState(false);
const [selectedItems, setSelectedItems] = React.useState<string[]>([]);
return (
<Timeline
tracks={tracks}
totalDuration={30} // 30 seconds
currentFrame={currentFrame}
fps={30}
onFrameChange={setCurrentFrame}
onTracksChange={setTracks}
selectedItemIds={selectedItems}
onSelectedItemsChange={setSelectedItems}
// Playback controls
isPlaying={isPlaying}
onPlay={() => setIsPlaying(true)}
onPause={() => setIsPlaying(false)}
showPlaybackControls={true}
// UI features
showZoomControls={true}
showTimelineGuidelines={true}
enableTrackDrag={true}
enableMagneticTrack={true}
// Event handlers
onItemMove={(itemId, newStart, newEnd, newTrackId) => {
console.log('Item moved:', { itemId, newStart, newEnd, newTrackId });
}}
onItemResize={(itemId, newStart, newEnd) => {
console.log('Item resized:', { itemId, newStart, newEnd });
}}
onDeleteItems={(itemIds) => {
console.log('Delete items:', itemIds);
}}
/>
);
};
Quick Start Guide
1. Set Up Your Data Structure
First, define your tracks and items:
const initialTracks: TimelineTrack[] = [
{
id: 'video-track',
name: 'Main Video',
items: [
{
id: 'video-1',
trackId: 'video-track',
start: 0,
end: 15,
type: 'video',
label: 'Intro Video',
color: '#3b82f6'
}
]
},
{
id: 'audio-track',
name: 'Background Music',
items: [
{
id: 'audio-1',
trackId: 'audio-track',
start: 0,
end: 30,
type: 'audio',
label: 'Background Track',
color: '#10b981'
}
]
}
];
2. Handle State Management
Set up the necessary state variables:
const [tracks, setTracks] = useState(initialTracks);
const [currentFrame, setCurrentFrame] = useState(0);
const [selectedItems, setSelectedItems] = useState<string[]>([]);
const [isPlaying, setIsPlaying] = useState(false);
3. Implement Event Handlers
Handle timeline interactions:
const handleItemMove = (itemId: string, newStart: number, newEnd: number, newTrackId: string) => {
setTracks(prevTracks =>
prevTracks.map(track => ({
...track,
items: track.items.map(item =>
item.id === itemId
? { ...item, start: newStart, end: newEnd, trackId: newTrackId }
: item
)
}))
);
};
const handleItemResize = (itemId: string, newStart: number, newEnd: number) => {
setTracks(prevTracks =>
prevTracks.map(track => ({
...track,
items: track.items.map(item =>
item.id === itemId
? { ...item, start: newStart, end: newEnd }
: item
)
}))
);
};
const handleDeleteItems = (itemIds: string[]) => {
setTracks(prevTracks =>
prevTracks.map(track => ({
...track,
items: track.items.filter(item => !itemIds.includes(item.id))
}))
);
};
4. Add the Timeline Component
<Timeline
// Required props
tracks={tracks}
totalDuration={60}
// State management
currentFrame={currentFrame}
onFrameChange={setCurrentFrame}
onTracksChange={setTracks}
// Selection
selectedItemIds={selectedItems}
onSelectedItemsChange={setSelectedItems}
// Event handlers
onItemMove={handleItemMove}
onItemResize={handleItemResize}
onDeleteItems={handleDeleteItems}
// UI controls
showPlaybackControls={true}
showZoomControls={true}
showTimelineGuidelines={true}
/>
Common Patterns
Adding New Items
const addNewItem = (trackId: string, start: number, duration: number) => {
const newItem: TimelineItem = {
id: `item-${Date.now()}`,
trackId,
start,
end: start + duration,
type: 'video',
label: 'New Item',
color: '#3b82f6'
};
setTracks(prevTracks =>
prevTracks.map(track =>
track.id === trackId
? { ...track, items: [...track.items, newItem] }
: track
)
);
};
Splitting Items
const handleSplitItem = (itemId: string, splitTime: number) => {
setTracks(prevTracks =>
prevTracks.map(track => ({
...track,
items: track.items.flatMap(item => {
if (item.id !== itemId) return item;
const firstPart = {
...item,
id: `${item.id}-part-1`,
end: splitTime,
mediaEnd: item.mediaStart ? item.mediaStart + (splitTime - item.start) : undefined
};
const secondPart = {
...item,
id: `${item.id}-part-2`,
start: splitTime,
mediaStart: item.mediaStart ? item.mediaStart + (splitTime - item.start) : undefined
};
return [firstPart, secondPart];
})
}))
);
};
Managing Playback
const handlePlayPause = () => {
if (isPlaying) {
setIsPlaying(false);
// Stop your video player
} else {
setIsPlaying(true);
// Start your video player
}
};
const handleFrameChange = (frame: number) => {
setCurrentFrame(frame);
// Sync with your video player
const timeInSeconds = frame / fps;
videoPlayer.currentTime = timeInSeconds;
};