diff --git a/src/components/ModuleNode.jsx b/src/components/ModuleNode.jsx index a7a1247..9116795 100644 --- a/src/components/ModuleNode.jsx +++ b/src/components/ModuleNode.jsx @@ -8,6 +8,20 @@ import KeyboardWidget from './KeyboardWidget.jsx'; import SequencerWidget from './SequencerWidget.jsx'; import PianoRollWidget from './PianoRollWidget.jsx'; +// Dynamic module widths for sequencer/pianoroll based on step/bar count +function getModuleWidth(mod, type) { + if (type === 'sequencer') { + const numSteps = parseInt(mod?.params?.steps || '16'); + return Math.max(200, numSteps * 18 + 20); // CELL_W=18 + padding + } + if (type === 'pianoroll') { + const bars = parseInt(mod?.params?.bars || '4'); + const totalBeats = bars * 4; + return 24 + totalBeats * 30 + 20; // KEY_W + beats*BEAT_PX + padding + } + return undefined; +} + // Map input port names → the param name they modulate (for visual feedback) const PORT_TO_PARAM = { filter: { cutoff: 'frequency' }, @@ -150,7 +164,7 @@ export default function ModuleNode({ mod, zoom, onStartConnect, onPortPosition } style={{ left: mod.x * zoom, top: mod.y * zoom, transform: `scale(${zoom})`, transformOrigin: 'top left', - ...(mod.type === 'pianoroll' ? { width: 520 } : mod.type === 'sequencer' ? { width: 310 } : {}), + ...(mod.type === 'pianoroll' ? { width: getModuleWidth(mod, 'pianoroll') } : mod.type === 'sequencer' ? { width: getModuleWidth(mod, 'sequencer') } : {}), }} data-module-id={mod.id} onPointerDown={(e) => { diff --git a/src/components/PianoRollWidget.jsx b/src/components/PianoRollWidget.jsx index 2585d8a..9e22f36 100644 --- a/src/components/PianoRollWidget.jsx +++ b/src/components/PianoRollWidget.jsx @@ -79,7 +79,7 @@ const MARIO_MELODY = [ { note: 71, start: 70*s, duration: 2*s }, // B4 ]; -const ROLL_W = 500; +const BEAT_PX = 30; // pixels per beat — constant density regardless of bar count const ROLL_H = 200; const KEY_W = 24; const MIN_NOTE = 48; // C3 @@ -110,7 +110,8 @@ export default function PianoRollWidget({ moduleId }) { const notesRef = useRef(notes); notesRef.current = notes; - const beatW = (ROLL_W - KEY_W) / totalBeats; + const rollW = KEY_W + totalBeats * BEAT_PX; + const beatW = BEAT_PX; // Draw the piano roll const draw = useCallback(() => { @@ -220,7 +221,7 @@ export default function PianoRollWidget({ moduleId }) { ctx.fillStyle = 'rgba(0,229,255,0.3)'; ctx.fillRect(x, row * ROW_H, Math.max(nw, 2), ROW_H); } - }, [totalBeats, beatW, playPos]); + }, [totalBeats, beatW, playPos, rollW]); // Animation loop useEffect(() => { @@ -415,7 +416,7 @@ export default function PianoRollWidget({ moduleId }) { }, [mod]); return ( -