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

53 lines
1.2 KiB
TypeScript

'use client';
import { useMemo } from 'react';
import { cn } from '@/lib/utils';
interface LevelMeterProps {
level: number;
className?: string;
orientation?: 'vertical' | 'horizontal';
}
export function LevelMeter({
level,
className,
orientation = 'vertical',
}: LevelMeterProps) {
const segments = useMemo(() => {
const count = 8;
const filled = Math.round(level * count);
return Array.from({ length: count }, (_, i) => {
const segmentLevel = (i + 1) / count;
const isActive = i < filled;
let color = 'bg-emerald-500';
if (segmentLevel > 0.85) color = 'bg-red-500';
else if (segmentLevel > 0.7) color = 'bg-yellow-500';
return { isActive, color };
});
}, [level]);
const isVertical = orientation === 'vertical';
return (
<div
className={cn(
'flex gap-0.5',
isVertical ? 'flex-col-reverse w-2' : 'flex-row h-2 w-16',
className
)}
>
{segments.map((seg, i) => (
<div
key={i}
className={cn(
'flex-1 rounded-sm transition-opacity duration-75',
seg.isActive ? seg.color : 'bg-muted/30',
seg.isActive ? 'opacity-100' : 'opacity-50'
)}
/>
))}
</div>
);
}