'use client'; import { useCallback, useState } from 'react'; import { cn } from '@/lib/utils'; interface PlayheadProps { bar: number; beat: number; pixelsPerBar: number; height: number; durationBars: number; onSeek?: (bar: number, beat: number) => void; className?: string; } export function Playhead({ bar, beat, pixelsPerBar, height, durationBars, onSeek, className, }: PlayheadProps) { const [isDragging, setIsDragging] = useState(false); const pixelsPerBeat = pixelsPerBar / 4; const position = bar * pixelsPerBar + beat * pixelsPerBeat; const handleDrag = useCallback( (clientX: number, containerLeft: number) => { if (!onSeek) return; const x = clientX - containerLeft; const totalBeats = x / pixelsPerBeat; const newBar = Math.floor(totalBeats / 4); const newBeat = Math.floor(totalBeats % 4); if (newBar >= 0 && newBar < durationBars) { onSeek(newBar, Math.max(0, Math.min(3, newBeat))); } }, [onSeek, pixelsPerBeat, durationBars] ); const handleMouseDown = useCallback( (e: React.MouseEvent) => { if (!onSeek) return; e.preventDefault(); e.stopPropagation(); setIsDragging(true); const container = (e.currentTarget as HTMLElement).parentElement; if (!container) return; const containerRect = container.getBoundingClientRect(); const handleMouseMove = (e: MouseEvent) => { handleDrag(e.clientX, containerRect.left); }; const handleMouseUp = () => { setIsDragging(false); window.removeEventListener('mousemove', handleMouseMove); window.removeEventListener('mouseup', handleMouseUp); }; window.addEventListener('mousemove', handleMouseMove); window.addEventListener('mouseup', handleMouseUp); }, [onSeek, handleDrag] ); return (
); }