From 0c6871e40a1ec4378b24178f95b5db3f41a25fc4 Mon Sep 17 00:00:00 2001 From: Gabe Serna Date: Thu, 14 Nov 2024 08:45:09 -0500 Subject: [PATCH] Add Dynamic Resizing to Piano Roll --- app/DemoSection.tsx | 3 ++- app/audio/midi/page.tsx | 10 --------- components/AudioMidiVisualizer.tsx | 3 +++ components/PianoRoll.tsx | 33 +++++++++++++++++++++++++++--- 4 files changed, 35 insertions(+), 14 deletions(-) delete mode 100644 app/audio/midi/page.tsx diff --git a/app/DemoSection.tsx b/app/DemoSection.tsx index 77eed29..c8f70ad 100644 --- a/app/DemoSection.tsx +++ b/app/DemoSection.tsx @@ -76,7 +76,7 @@ export default function DemoSection() { return (

Try it Out! @@ -89,6 +89,7 @@ export default function DemoSection() { midiFile={samples.midiBlob as Blob} controls={[midiControls, originalAudioControls]} pageUpdate={pageUpdate} + isDemo={true} /> )} -

MIDI Metadata Viewer

- - - ); -} diff --git a/components/AudioMidiVisualizer.tsx b/components/AudioMidiVisualizer.tsx index d12100b..8ff836a 100644 --- a/components/AudioMidiVisualizer.tsx +++ b/components/AudioMidiVisualizer.tsx @@ -19,6 +19,7 @@ interface Props { midiFile: Blob; controls: Controls[]; pageUpdate: boolean; + isDemo?: boolean; } export default function AudioMidiVisualizer({ @@ -27,6 +28,7 @@ export default function AudioMidiVisualizer({ midiFile, controls, pageUpdate, + isDemo = false, }: Props) { const wavesurferRef = useRef(null); const parentRef = useRef(null); @@ -211,6 +213,7 @@ export default function AudioMidiVisualizer({ duration={duration} volume={midiVol} pan={midiPan} + isDemo={isDemo} /> ) : ( diff --git a/components/PianoRoll.tsx b/components/PianoRoll.tsx index cfe8695..b739cbf 100644 --- a/components/PianoRoll.tsx +++ b/components/PianoRoll.tsx @@ -18,6 +18,7 @@ interface PianoRollProps { duration: number; volume: number; pan: number; + isDemo?: boolean; } interface MidiNote { @@ -36,6 +37,7 @@ const PianoRoll: React.FC = ({ duration, volume, pan, + isDemo = false, }) => { const parentRef = useRef(null); const pianoKeysCanvasRef = useRef(null); @@ -56,7 +58,7 @@ const PianoRoll: React.FC = ({ // Constants const pianoKeyWidth = 50; - const containerWidth = parentRef.current?.clientWidth || 800 - pianoKeyWidth; + const [containerWidth, setContainerWidth] = useState(0); const noteHeight = containerWidth > 600 ? 7 : containerWidth > 300 ? 6 : 5; const totalNotes = 88; const canvasHeight = totalNotes * noteHeight; @@ -72,6 +74,11 @@ const PianoRoll: React.FC = ({ useEffect(() => { // Parse the MIDI file + if (!parentRef.current) return; + if (containerWidth === 0) { + setContainerWidth(parentRef.current.clientWidth - pianoKeyWidth); + return; + } const reader = new FileReader(); reader.onload = async () => { const arrayBuffer = await midiFile.arrayBuffer(); @@ -101,7 +108,7 @@ const PianoRoll: React.FC = ({ }; reader.readAsArrayBuffer(midiFile); - }, [midiFile]); + }, [midiFile, containerWidth]); // Draw piano keys with active notes highlighted const drawPianoKeys = (activeNotes: Set = activeNotesRef.current) => { @@ -176,7 +183,9 @@ const PianoRoll: React.FC = ({ const measures = containerWidth > 600 ? 8 : containerWidth > 300 ? 6 : 4; const viewLength = measures * 4 * secondsPerBeat; const timeScale = containerWidth / viewLength; // Pixels Per Second - canvas.width = duration * timeScale + containerWidth - pianoKeyWidth; + canvas.width = duration * timeScale + containerWidth; + if (!isDemo) canvas.width -= pianoKeyWidth - 40; + else canvas.width -= 5; ctx.clearRect(0, 0, containerWidth, height); @@ -331,6 +340,24 @@ const PianoRoll: React.FC = ({ } }, [pageUpdate]); + // Add ResizeObserver effect + useEffect(() => { + if (!parentRef.current) return; + + const resizeObserver = new ResizeObserver((entries) => { + for (const entry of entries) { + setContainerWidth(entry.contentRect.width - pianoKeyWidth); + } + }); + + resizeObserver.observe(parentRef.current); + + // Cleanup + return () => { + resizeObserver.disconnect(); + }; + }, []); + return ( <>