diff --git a/js/events.js b/js/events.js index 128b767..95e2976 100644 --- a/js/events.js +++ b/js/events.js @@ -214,12 +214,26 @@ export function initEvents() { document.getElementById('wave-step').addEventListener('click', manualStep); document.getElementById('wave-zoom-in').addEventListener('click', () => { - state.waveZoom = Math.min(60, state.waveZoom + 5); + state.waveZoom = Math.min(100, state.waveZoom + 5); }); document.getElementById('wave-zoom-out').addEventListener('click', () => { - state.waveZoom = Math.max(5, state.waveZoom - 5); + state.waveZoom = Math.max(2, state.waveZoom - 5); }); + // Scroll waveform with mouse wheel + document.getElementById('wave-canvas').addEventListener('wheel', e => { + e.preventDefault(); + if (e.ctrlKey || e.metaKey) { + // Ctrl+wheel = zoom waveform + const delta = e.deltaY > 0 ? -3 : 3; + state.waveZoom = Math.max(2, Math.min(100, state.waveZoom + delta)); + } else { + // Wheel = scroll waveform horizontally + const scrollDelta = e.deltaY > 0 ? 3 : -3; + state.waveScroll = Math.max(0, state.waveScroll + scrollDelta); + } + }, { passive: false }); + // ==================== SIMULATION CONTROLS ==================== document.getElementById('sim-run-btn').addEventListener('click', () => { if (state.simRunning) stopSim(); else startSim(); diff --git a/js/simulation.js b/js/simulation.js index 46fc7fb..463a5af 100644 --- a/js/simulation.js +++ b/js/simulation.js @@ -20,7 +20,7 @@ export function simTick() { export function startSim() { if (state.simRunning) return; const hasClocks = state.gates.some(g => g.type === 'CLOCK'); - if (!hasClocks) { alert('Place a CLOCK gate first!'); return; } + if (!hasClocks) return; state.simRunning = true; diff --git a/js/waveform.js b/js/waveform.js index 7c10274..020e769 100644 --- a/js/waveform.js +++ b/js/waveform.js @@ -121,11 +121,14 @@ export function drawWaveforms() { return; } - // Auto-scroll to show latest + // Auto-scroll to show latest (only if we're already near the end) const maxVisible = Math.floor(wc.width / state.waveZoom); - if (state.timeStep > maxVisible) { + const isNearEnd = state.waveScroll >= state.timeStep - maxVisible - 2; + if (state.timeStep > maxVisible && isNearEnd) { state.waveScroll = state.timeStep - maxVisible; } + // Clamp scroll to valid range + state.waveScroll = Math.max(0, Math.min(state.timeStep - 1, state.waveScroll)); // Draw time grid wctx.strokeStyle = '#151520';