Mouse wheel events were being treated as trackpad input, causing excessive zoom jumps. Added delta magnitude detection (threshold: 50) to distinguish between mouse wheel (large deltas) and trackpad (small deltas), applying appropriate zoom calculation for each device.
Shows minimap briefly when:
- Flow initially loads (if nodes exist)
- Switching between workspace tabs
- Continuing to show during zoom/pan navigation
Implementation:
- Listen to workspace:change events
- Check for active workspace with nodes before showing
- Use 100ms delay to ensure nodes are rendered
- Reuse existing showTemporary() for consistent behavior
- Show grab cursor (open hand) when spacebar is pressed
- Show grabbing cursor (closed hand) when actively panning with spacebar+drag
- Revert to grab cursor on mouse release if spacebar still held
- Clear cursor when spacebar is released
- Apply cursor to SVG element (outer) where mouse events occur
- Handle edge cases: window blur, canvas blur, spacebar release outside canvas
- Emit view:navigate event in animatedZoomView onStart callback
- Minimap now appears when using zoom buttons (in/out/reset/fit)
- Minimap now appears when using zoom hotkeys (Ctrl+/-/0/1)
- Auto-hides after 2 seconds as expected
- Applies to all animated zoom operations consistently
- Store workspace center on first button/hotkey zoom operation
- Maintain same focal point for sequential zooms within 1 second timeout
- Pass workspace center directly to animatedZoomView to prevent recalculation
- Focal point always at viewport center with consistent workspace point
- Works correctly at canvas edges where viewport may shift
- Does not interfere with wheel/pinch zoom which provide explicit focal points
- Fixed viewport jump to 0,0 by preventing click event from being passed as focal point
- Added smooth animation to zoom buttons and keyboard shortcuts (animatedZoomView)
- Doubled zoom step from 0.1 to 0.2 for faster zooming
- Optimized animation performance by only updating transforms during animation frames
- Fixed undefined variable issue (vis/gridScale -> eventLayer/outer)
- Full redraw only happens once at end of animation, eliminating jarring experience
Replace animatedZoomView() with direct zoomView() calls for zoom
buttons and keyboard shortcuts to eliminate jagged animation caused
by redraw() being called on every frame.
- Change zoomIn/zoomOut/zoomZero to use instant zoom like trackpad
- Single redraw per zoom step instead of 8-10 redraws during animation
- Makes all zoom methods (buttons, keyboard, trackpad) feel consistent
- Keep animatedZoomView() only for zoomToFitAll() where animation helps
Fixes stuttering when zooming with buttons or Ctrl+/-/0 shortcuts.
Add fourth zoom button that calculates bounding box of all active nodes
and zooms out to fit them all in viewport with padding.
- Add compress icon button to zoom controls in footer
- Implement zoomToFitAll() function with bounding box calculation
- Add 80px padding around nodes for visual breathing room
- Respect dynamic minimum zoom limit
- Center viewport on bounding box after zoom animation
- Register core:zoom-fit action for keyboard shortcut support
- Update documentation with new zoom-to-fit feature
The minimap was treating scroll position as workspace coordinates,
but scrollLeft/scrollTop are actually in scaled canvas pixels.
At zoom levels other than 1.0, this caused the viewport rectangle
to appear in the wrong position. For example, at 2x zoom viewing
workspace position (500, 500), the scroll position would be 1000px,
and the minimap would incorrectly show it at workspace position 1000.
Fixed by converting scroll position to workspace coordinates first:
position = scrollPos / scaleFactor / nav_scale
The viewport rectangle now accurately reflects the actual visible
area at all zoom levels.
When at minimum zoom with "cover" behavior, the SVG canvas may be
smaller than the viewport in one dimension. This causes the browser's
scrollWidth/scrollHeight to be limited by the SVG size rather than
the full canvas extent.
Added an invisible spacer div that matches the scaled canvas dimensions,
ensuring the scrollable area always reflects the actual canvas size.
This allows proper scrolling to reach all canvas edges without going
beyond canvas boundaries.
Alt+scroll and Space+scroll zoom now maintain a fixed focal point
like trackpad pinch zoom. Previously, the zoom point would drift
during continuous scrolling.
Implemented gesture session tracking that:
- Stores focal point in workspace coordinates for stability
- Locks focal point during continuous scroll events (< 100ms apart)
- Ends gesture after 500ms of inactivity
- Converts focal point back to screen coordinates for each zoom step
This makes all zoom methods (pinch, Alt+scroll, Space+scroll) behave
consistently with stable, cursor-centered zooming.
Alt+scroll and Space+scroll were using fixed zoom steps (0.06/0.08),
making them zoom much faster than trackpad pinch zoom which uses
proportional scaling (0.005 * delta).
Changed to use trackpad-style proportional zoom for consistent feel
across all zoom input methods.
When holding spacebar, browsers fire repeated keydown events. The
previous implementation only prevented default on the first keydown,
allowing subsequent events to trigger browser's space-scroll behavior.
Moved preventDefault() outside conditional to block all spacebar events.
- Remove view:selection-changed listener to prevent minimap showing on node selection
- Remove view:navigate emissions from pan mode entry points (no longer shows when starting pan)
- Add view:navigate emission to touchpad scroll handler for consistent behavior
- Minimap now only appears during actual panning and zooming actions
The minimap previously showed when selecting nodes or just starting a pan gesture,
causing unnecessary flashing. Now it only appears during actual navigation (pan/zoom)
and fades after 2 seconds of inactivity.
- Prevent browser's native axis-locked scroll behavior
- Manually handle both deltaX and deltaY in wheel event handler
- Update touch-action CSS from pan-x pan-y to manipulation
- Add documentation of fix to CANVAS_INTERACTION.md
Fixes issue where trackpad scrolling was restricted to horizontal
or vertical movement only, not both simultaneously.
- Hide scrollbars on canvas while keeping it scrollable
- Add minimap auto-show functionality that triggers on zoom and pan
- Minimap appears for 2 seconds during navigation then fades out
- Add smooth fade in/out animations for minimap visibility
- Emit view:navigate events for all zoom and pan operations
- Minimap stays visible if manually toggled with button
- Recalculate minimum zoom when window resizes to ensure canvas fits properly
- Automatically adjust zoom if current level falls below new minimum after resize
- Ensures canvas boundaries remain appropriate for different viewport sizes
- Add calculateMinZoom() function to dynamically compute minimum zoom based on viewport size
- Ensure canvas always covers the entire viewport (no empty space visible)
- Use 'cover' behavior: zoom limited so canvas fills viewport completely
- Update all zoom methods (buttons, wheel, trackpad, touch) to use calculated minimum
- Prevent zooming out beyond what's needed to fill the viewport with canvas content
Clear touchStartTime timeout when entering two-finger pan mode to prevent
interference with subsequent zoom gestures. The timeout was being used for
long-press detection but wasn't cleared during pan, causing the next
gesture to incorrectly maintain the old touch state.
- Add touch-action CSS to prevent pinch-zoom on UI elements
- Apply touch-action: pan-x pan-y to html, body, and editor
- Apply touch-action: none to canvas for custom gestures
- Add JavaScript prevention for touchpad pinch on non-canvas areas
- Block Ctrl+wheel events outside the workspace chart
- Implement spacebar+left-click panning for desktop
- Add two-finger pan gesture for touch devices
- Use mode locking to prevent laggy gesture switching
- Lock into pan or zoom mode based on initial movement
- Fix focal point regression caused by pan/zoom interaction
- Improve gesture detection with better thresholds (10px for zoom, 5px for pan)
- Make mouse wheel zoom smooth without jarring animations
- Reduce zoom acceleration from 2x to 1.2x max
- Slow down zoom velocity by 40-50% for better control
- Add asymmetric zoom speeds (zoom out slower than zoom in)
- Reduce acceleration range to 0.7-1.1 for gentler transitions
- Disable legacy mousewheel handler in favor of modern wheel event