forked from averyfelts/Lofi_Generator
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
57 lines
1.1 KiB
TypeScript
57 lines
1.1 KiB
TypeScript
'use client';
|
|
|
|
import { cn } from '@/lib/utils';
|
|
|
|
interface KeyframeMarkerProps {
|
|
bar: number;
|
|
pixelsPerBar: number;
|
|
color?: string;
|
|
selected?: boolean;
|
|
onSelect?: () => void;
|
|
onDelete?: () => void;
|
|
className?: string;
|
|
}
|
|
|
|
export function KeyframeMarker({
|
|
bar,
|
|
pixelsPerBar,
|
|
color = 'bg-primary',
|
|
selected = false,
|
|
onSelect,
|
|
onDelete,
|
|
className,
|
|
}: KeyframeMarkerProps) {
|
|
const handleClick = (e: React.MouseEvent) => {
|
|
e.stopPropagation();
|
|
onSelect?.();
|
|
};
|
|
|
|
const handleContextMenu = (e: React.MouseEvent) => {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
onDelete?.();
|
|
};
|
|
|
|
return (
|
|
<div
|
|
className={cn(
|
|
'absolute top-1/2 -translate-y-1/2 cursor-pointer',
|
|
'transition-transform hover:scale-125',
|
|
selected && 'scale-125',
|
|
className
|
|
)}
|
|
style={{ left: bar * pixelsPerBar }}
|
|
onClick={handleClick}
|
|
onContextMenu={handleContextMenu}
|
|
>
|
|
<div
|
|
className={cn(
|
|
'w-3 h-3 rotate-45 border-2',
|
|
color,
|
|
selected ? 'border-white shadow-lg' : 'border-transparent'
|
|
)}
|
|
/>
|
|
</div>
|
|
);
|
|
}
|