fix: resume zoom animation when target drops below threshold
Fixed issue where zoom animation would stay paused even when auto-zoom wanted to zoom back out below the precision mode threshold. **Problem:** - Animation paused when hitting 20 px/px threshold - If user moved to larger region, target zoom would drop - But animation stayed paused, not resuming to zoom out **Solution:** - Check both CURRENT zoom and TARGET zoom thresholds - Only pause if: current at threshold AND target also at/above threshold - Resume if: current at threshold BUT target below threshold (zooming out) **Pause conditions:** - `shouldPause = currentIsAtThreshold && zoomIsAnimating && targetIsAtThreshold` - If current is at threshold but target is safe → resume and zoom out - If current is at threshold and target also at threshold → stay paused - Added console log when resuming due to zoom-out **User experience:** - Zoom pauses at threshold when trying to zoom IN further - Zoom resumes smoothly when auto-zoom wants to zoom OUT - No stuck animations - always responsive to target changes 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
c4989b3ab0
commit
e73b59d510
|
|
@ -380,12 +380,11 @@ export function MapRenderer({
|
|||
const currentZoom = magnifierSpring.zoom.get()
|
||||
const zoomIsAnimating = Math.abs(currentZoom - targetZoom) > 0.01
|
||||
|
||||
// Check if we're at the threshold (zoom is capped)
|
||||
const isAtThreshold =
|
||||
// Check if CURRENT zoom is at/above the threshold (zoom is capped)
|
||||
const currentIsAtThreshold =
|
||||
!pointerLocked &&
|
||||
containerRef.current &&
|
||||
svgRef.current &&
|
||||
zoomIsAnimating &&
|
||||
(() => {
|
||||
const containerRect = containerRef.current.getBoundingClientRect()
|
||||
const svgRect = svgRef.current.getBoundingClientRect()
|
||||
|
|
@ -403,12 +402,43 @@ export function MapRenderer({
|
|||
return screenPixelRatio >= PRECISION_MODE_THRESHOLD
|
||||
})()
|
||||
|
||||
if (isAtThreshold) {
|
||||
// Check if TARGET zoom would be at/above the threshold
|
||||
const targetIsAtThreshold =
|
||||
!pointerLocked &&
|
||||
containerRef.current &&
|
||||
svgRef.current &&
|
||||
(() => {
|
||||
const containerRect = containerRef.current.getBoundingClientRect()
|
||||
const svgRect = svgRef.current.getBoundingClientRect()
|
||||
const magnifierWidth = containerRect.width * 0.5
|
||||
const viewBoxParts = mapData.viewBox.split(' ').map(Number)
|
||||
const viewBoxWidth = viewBoxParts[2]
|
||||
|
||||
if (!viewBoxWidth || isNaN(viewBoxWidth)) return false
|
||||
|
||||
const magnifiedViewBoxWidth = viewBoxWidth / targetZoom
|
||||
const magnifierScreenPixelsPerSvgUnit = magnifierWidth / magnifiedViewBoxWidth
|
||||
const mainMapSvgUnitsPerScreenPixel = viewBoxWidth / svgRect.width
|
||||
const screenPixelRatio = mainMapSvgUnitsPerScreenPixel * magnifierScreenPixelsPerSvgUnit
|
||||
|
||||
return screenPixelRatio >= PRECISION_MODE_THRESHOLD
|
||||
})()
|
||||
|
||||
// Pause conditions:
|
||||
// 1. Currently at threshold AND animating toward even higher zoom (would exceed threshold more)
|
||||
// 2. OR: Currently at threshold and target is also at threshold (should stay paused)
|
||||
const shouldPause = currentIsAtThreshold && zoomIsAnimating && targetIsAtThreshold
|
||||
|
||||
if (shouldPause) {
|
||||
// Pause the zoom animation - we're waiting for precision mode
|
||||
console.log('[Zoom] Pausing at threshold - waiting for precision mode')
|
||||
magnifierApi.pause()
|
||||
} else {
|
||||
// Update spring values and ensure it's not paused
|
||||
// This will resume if we were paused and now target is below threshold (zooming out)
|
||||
if (currentIsAtThreshold && !targetIsAtThreshold) {
|
||||
console.log('[Zoom] Resuming - target zoom is below threshold (zooming out)')
|
||||
}
|
||||
magnifierApi.start({
|
||||
zoom: targetZoom,
|
||||
opacity: targetOpacity,
|
||||
|
|
|
|||
Loading…
Reference in New Issue