From d72f309badd72003d264fc06206f59d26d226a01 Mon Sep 17 00:00:00 2001 From: Thomas Hallock Date: Wed, 19 Nov 2025 10:50:37 -0600 Subject: [PATCH] fix: track both SVG units and screen pixels for zoom and dampening MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The previous commit broke cursor dampening and magnifier triggers by using SVG units for everything. We need both measurements: - **SVG units** (0-1010): Accurate zoom calculation - **Screen pixels**: Cursor dampening and magnifier triggers Changes: - Track detectedSmallestSize (SVG units) for zoom calculation - Track detectedSmallestScreenSize (screen pixels) for dampening - Use screen pixels for getMovementMultiplier() (expects <1px, <5px, <15px) - Use screen pixels for hasSmallRegion trigger (<15px) - Debug logging now shows both values Example for Gibraltar: - SVG size: 0.08 units → 1000x zoom - Screen size: 0.08px → 3% cursor speed (ultra precision) This restores cursor dampening behavior while keeping accurate SVG-based zoom calculations. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .../components/MapRenderer.tsx | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/apps/web/src/arcade-games/know-your-world/components/MapRenderer.tsx b/apps/web/src/arcade-games/know-your-world/components/MapRenderer.tsx index 1267f3e4..bdec7e3b 100644 --- a/apps/web/src/arcade-games/know-your-world/components/MapRenderer.tsx +++ b/apps/web/src/arcade-games/know-your-world/components/MapRenderer.tsx @@ -757,7 +757,8 @@ export function MapRenderer({ let regionsInBox = 0 let hasSmallRegion = false let totalRegionArea = 0 - let detectedSmallestSize = Infinity + let detectedSmallestSize = Infinity // SVG units for zoom calculation + let detectedSmallestScreenSize = Infinity // Screen pixels for dampening const detectedRegions: string[] = [] let regionUnderCursor: string | null = null let smallestDistanceToCenter = Infinity @@ -826,13 +827,15 @@ export function MapRenderer({ } // Track region sizes for adaptive zoom and dampening - // Use SVG path bounding box (from viewBox coordinates) for more accurate sizing - // getBoundingClientRect() gives axis-aligned boxes which are too large for irregular shapes + // - SVG units (from viewBox) for accurate zoom calculation + // - Screen pixels (from getBoundingClientRect) for cursor dampening const svgBBox = calculateBoundingBox(region.path) const svgSize = Math.min(svgBBox.width, svgBBox.height) + const screenSize = Math.min(pixelWidth, pixelHeight) totalRegionArea += pixelArea detectedSmallestSize = Math.min(detectedSmallestSize, svgSize) + detectedSmallestScreenSize = Math.min(detectedSmallestScreenSize, screenSize) } }) @@ -843,9 +846,9 @@ export function MapRenderer({ // Show magnifier if: 7+ regions in detection box OR any region smaller than 15px const shouldShow = regionsInBox >= 7 || hasSmallRegion - // Update smallest region size for adaptive cursor dampening - if (shouldShow && detectedSmallestSize !== Infinity) { - setSmallestRegionSize(detectedSmallestSize) + // Update smallest region size for adaptive cursor dampening (use screen pixels) + if (shouldShow && detectedSmallestScreenSize !== Infinity) { + setSmallestRegionSize(detectedSmallestScreenSize) } else { setSmallestRegionSize(Infinity) } @@ -856,17 +859,18 @@ export function MapRenderer({ setHoveredRegion(regionUnderCursor) } - // Debug logging - ONLY for Gibraltar or ultra-small regions (< 2px) + // Debug logging - ONLY for Gibraltar or ultra-small regions const hasGibraltar = detectedRegions.includes('gi') - if (hasGibraltar || detectedSmallestSize < 2) { + if (hasGibraltar || detectedSmallestSize < 5) { console.log( `[Magnifier] ${hasGibraltar ? '🎯 GIBRALTAR DETECTED' : '🔍 Tiny region'} Detection:`, { detectedRegionIds: detectedRegions, regionsInBox, - smallestSize: detectedSmallestSize.toFixed(2) + 'px', + smallestSvgSize: detectedSmallestSize.toFixed(4) + ' SVG units', + smallestScreenSize: detectedSmallestScreenSize.toFixed(2) + 'px', shouldShow, - movementMultiplier: getMovementMultiplier(detectedSmallestSize).toFixed(2), + movementMultiplier: getMovementMultiplier(detectedSmallestScreenSize).toFixed(2), } ) }