fix: keyframe timeline

This commit is contained in:
2026-03-01 12:46:00 +01:00
parent f9db58122c
commit 1276a10e9a
2 changed files with 10 additions and 9 deletions

View File

@@ -21,7 +21,7 @@ export function AnimationEditor() {
); );
const [previewElement, setPreviewElement] = useState<PreviewElement>('box'); const [previewElement, setPreviewElement] = useState<PreviewElement>('box');
const [mobileTab, setMobileTab] = useState<MobileTab>('edit'); const [mobileTab, setMobileTab] = useState<MobileTab>('edit');
const [rightTab, setRightTab] = useState<RightTab>('keyframes'); const [rightTab, setRightTab] = useState<RightTab>('export');
const selectedKeyframe = config.keyframes.find((k) => k.id === selectedId) ?? null; const selectedKeyframe = config.keyframes.find((k) => k.id === selectedId) ?? null;
@@ -108,6 +108,8 @@ export function AnimationEditor() {
<div className="border-t border-border/25" /> <div className="border-t border-border/25" />
<KeyframeTimeline {...timelineProps} embedded />
<KeyframeProperties keyframe={selectedKeyframe} onChange={updateKeyframeProps} /> <KeyframeProperties keyframe={selectedKeyframe} onChange={updateKeyframeProps} />
</div> </div>
</div> </div>
@@ -123,7 +125,7 @@ export function AnimationEditor() {
<div className="glass rounded-xl p-4 flex flex-col flex-1 min-h-0 overflow-hidden"> <div className="glass rounded-xl p-4 flex flex-col flex-1 min-h-0 overflow-hidden">
{/* Tab switcher */} {/* Tab switcher */}
<div className="flex glass rounded-lg p-0.5 gap-0.5 mb-4 shrink-0"> <div className="flex glass rounded-lg p-0.5 gap-0.5 mb-4 shrink-0">
{(['keyframes', 'export', 'presets'] as RightTab[]).map((t) => ( {(['export', 'presets'] as RightTab[]).map((t) => (
<button <button
key={t} key={t}
onClick={() => setRightTab(t)} onClick={() => setRightTab(t)}
@@ -134,13 +136,12 @@ export function AnimationEditor() {
: 'text-muted-foreground hover:text-foreground' : 'text-muted-foreground hover:text-foreground'
)} )}
> >
{t === 'keyframes' ? 'Keyframes' : t === 'export' ? 'Export' : 'Presets'} {t === 'export' ? 'Export' : 'Presets'}
</button> </button>
))} ))}
</div> </div>
{/* Content */} {/* Content */}
<div className="flex-1 min-h-0 overflow-y-auto scrollbar-thin scrollbar-thumb-primary/20 scrollbar-track-transparent pr-0.5"> <div className="flex-1 min-h-0 overflow-y-auto scrollbar-thin scrollbar-thumb-primary/20 scrollbar-track-transparent pr-0.5">
{rightTab === 'keyframes' && <KeyframeTimeline {...timelineProps} embedded />}
{rightTab === 'export' && <ExportPanel config={config}/>} {rightTab === 'export' && <ExportPanel config={config}/>}
{rightTab === 'presets' && <PresetLibrary onSelect={loadPreset} />} {rightTab === 'presets' && <PresetLibrary onSelect={loadPreset} />}
</div> </div>

View File

@@ -15,7 +15,7 @@ interface Props {
embedded?: boolean; // when true, no glass card wrapper (use inside another card) embedded?: boolean; // when true, no glass card wrapper (use inside another card)
} }
const TICKS = [0, 25, 50, 75, 100]; const TICKS = [25, 50, 75];
const iconBtn = (disabled?: boolean) => const iconBtn = (disabled?: boolean) =>
cn( cn(
@@ -85,14 +85,14 @@ export function KeyframeTimeline({ keyframes, selectedId, onSelect, onAdd, onDel
{/* Track */} {/* Track */}
<div <div
ref={trackRef} ref={trackRef}
className="relative h-14 bg-white/3 rounded-lg border border-border/25 cursor-crosshair select-none" className="relative h-14 bg-white/3 rounded-lg border border-border/25 cursor-crosshair select-none mx-4"
onClick={handleTrackClick} onClick={handleTrackClick}
> >
<div className="absolute inset-x-0 top-1/2 -translate-y-1/2 h-px bg-border/30" /> <div className="absolute inset-x-0 top-1/2 -translate-y-1/2 h-px bg-border/30" />
{TICKS.map((tick) => ( {TICKS.map((tick) => (
<div <div
key={tick} key={tick}
className="absolute top-0 bottom-0 flex flex-col items-center pointer-events-none" className="absolute top-0 bottom-0 flex flex-col items-center pointer-events-none -ml-1.5"
style={{ left: `${tick}%` }} style={{ left: `${tick}%` }}
> >
<div className="w-px h-2 bg-muted-foreground/20" /> <div className="w-px h-2 bg-muted-foreground/20" />
@@ -118,7 +118,7 @@ export function KeyframeTimeline({ keyframes, selectedId, onSelect, onAdd, onDel
</div> </div>
{/* Offset labels */} {/* Offset labels */}
<div className="relative h-4"> <div className="relative h-4 mx-4">
{sorted.map((kf) => ( {sorted.map((kf) => (
<span <span
key={kf.id} key={kf.id}