Lofi_Generator/components/timeline/TimelineRuler.tsx
Nicholai d3158e4c6a feat(timeline-mixer): WIP timeline and mixer components
work in progress implementation of:
- mixer with channel strips, faders, pan knobs, level meters
- timeline with ruler, playhead, sections, keyframe tracks
- pattern and progression pickers for drums/chords
- automation lanes and mute tracks
- loop bracket for loop region selection
- export modal placeholder

known issues:
- drum pattern changes don't update audio engine
- timeline keyframes not connected to scheduler
- some UI bugs remain

this is a checkpoint commit for further iteration
2026-01-20 18:22:10 -07:00

52 lines
1.2 KiB
TypeScript

'use client';
import { useMemo } from 'react';
import { cn } from '@/lib/utils';
interface TimelineRulerProps {
durationBars: number;
pixelsPerBar: number;
className?: string;
}
export function TimelineRuler({
durationBars,
pixelsPerBar,
className,
}: TimelineRulerProps) {
const markers = useMemo(() => {
const items: { bar: number; isMajor: boolean }[] = [];
for (let bar = 0; bar <= durationBars; bar++) {
items.push({ bar, isMajor: bar % 4 === 0 });
}
return items;
}, [durationBars]);
return (
<div
className={cn('relative h-6 bg-muted/30 border-b border-border/50', className)}
style={{ width: durationBars * pixelsPerBar }}
>
{markers.map(({ bar, isMajor }) => (
<div
key={bar}
className="absolute top-0 flex flex-col items-center"
style={{ left: bar * pixelsPerBar }}
>
<div
className={cn(
'w-px',
isMajor ? 'h-4 bg-muted-foreground/60' : 'h-2 bg-muted-foreground/30'
)}
/>
{isMajor && (
<span className="text-[9px] font-mono text-muted-foreground/80 mt-0.5">
{bar + 1}
</span>
)}
</div>
))}
</div>
);
}