Skip to content

UX: Ensure menus handle vertical overflow#1

Draft
n-lark wants to merge 231 commits intomasterfrom
5377/ux-menu-vertical-overflow
Draft

UX: Ensure menus handle vertical overflow#1
n-lark wants to merge 231 commits intomasterfrom
5377/ux-menu-vertical-overflow

Conversation

@n-lark
Copy link
Owner

@n-lark n-lark commented Jan 8, 2026

  • Bugfix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)

Proposed changes

See comment below

Checklist

  • I have read the contribution guidelines
  • For non-bugfix PRs, I have discussed this change on the forum/slack team.
  • I have run npm run test to verify the unit tests pass
  • I have added suitable unit tests to cover the new/changed functionality

dceejay and others added 30 commits October 9, 2024 16:49
- Added space+scroll zoom functionality
- Implemented cursor-centered zoom (focuses on cursor position)
- Enhanced pinch-to-zoom with trackpad support (Ctrl+wheel)
- Added momentum scrolling with edge bounce animation
- Improved touch pinch gesture handling with proper center tracking

Co-authored-by: Dimitrie Hoekstra <dimitrieh@users.noreply.github.com>
- Add smooth zoom animation with 125ms duration and easing curves
- Implement space+scroll zoom mode alongside existing Alt+scroll
- Fix pinch-to-zoom with proper ratio-based scaling and fixed focal point
- Add gesture state management for consistent zoom behavior
- Enhance spacebar handling to prevent scroll artifacts
- Fix zoom button layout (correct zoom in/out direction)
- Add zoom animation utilities (view-zoom-animator.js)
- Add zoom configuration constants (view-zoom-constants.js)
- Fix scale lock issues with improved tolerance handling
- Update Gruntfile to include new zoom modules in build

Features implemented:
- Smooth animated zoom transitions (125ms with ease-out)
- Space+scroll for zoom mode
- Fixed focal point during pinch gestures
- No scroll artifacts when pressing space
- Proper state management when cursor leaves canvas
- Natural acceleration/deceleration curves

Known issue: Trackpad pinch-to-zoom needs additional work on macOS
- Inverted deltaY value for trackpad pinch gestures
- Matches standard macOS trackpad behavior
- Spreading fingers (negative deltaY) zooms in
- Pinching fingers (positive deltaY) zooms out
- Store focal point in workspace coordinates instead of screen coordinates
- Prevents focal point drift when scroll changes due to canvas boundaries
- Maintains consistent zoom focus even when view shifts at edges
- Add early return in zoomView() to prevent unnecessary updates at zoom limits
- Improve gesture state management for both trackpad and touch gestures
- 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
- 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)
- 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
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 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
- 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
- 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
- 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.
- 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.
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.
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.
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.
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.
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.
Remove 5px grey space that appeared at bottom of canvas when scrolled
to maximum position. The viewport scrollHeight was 8005px instead of
8000px due to default browser SVG margins.

- Add explicit padding and margin resets to workspace chart container
- Set SVG to display:block with zero margin/padding to prevent spacing
- Ensures scrollable area exactly matches 8000px canvas dimensions
knolleary and others added 27 commits March 4, 2026 18:21
Do not cache subflow colors as each subflow can have its own
Set showSupportNotice option on i18n
Allow palette.categories to be set via theme plugin
@n-lark n-lark force-pushed the 5377/ux-menu-vertical-overflow branch from 3c3a2f1 to b6cb9e0 Compare March 6, 2026 20:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.