From 9c7d2fab5f04a11dc97f6f5db63b91c153aec98d Mon Sep 17 00:00:00 2001 From: Thomas Hallock Date: Mon, 24 Nov 2025 19:05:58 -0600 Subject: [PATCH] feat: add debug bounding boxes to magnifier view MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the same debug bounding box visualization (color-coded rectangles and importance score labels) to the magnifier view that was previously added to the main map. Key features: - SVG rectangles show bounding boxes for all detected regions - HTML overlay labels show region IDs and importance scores - Color-coded by importance (green=accepted, orange=high, yellow=medium, gray=low) - Only shows labels for regions within magnified viewport - Properly converts SVG coordinates to magnifier pixel coordinates - Behind SHOW_DEBUG_BOUNDING_BOXES dev flag This helps debug the adaptive zoom search algorithm by showing which regions are being considered and their importance rankings inside the magnifier. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .../components/MapRenderer.tsx | 121 ++++++++++++++++++ 1 file changed, 121 insertions(+) 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 cd5d5553..e724446a 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 @@ -1942,8 +1942,129 @@ export function MapRenderer({ ) })()} + + {/* Debug: Bounding boxes for detected regions in magnifier */} + {SHOW_DEBUG_BOUNDING_BOXES && + debugBoundingBoxes.map((bbox) => { + const importance = bbox.importance ?? 0 + + // Color-code by importance + let strokeColor = '#888888' // Gray for low importance + if (bbox.wasAccepted) { + strokeColor = '#00ff00' // Green for accepted region + } else if (importance > 1.5) { + strokeColor = '#ff6600' // Orange for high importance + } else if (importance > 0.5) { + strokeColor = '#ffcc00' // Yellow for medium importance + } + + return ( + + ) + })} + {/* Debug: Bounding box labels in magnifier as HTML overlays */} + {SHOW_DEBUG_BOUNDING_BOXES && + containerRef.current && + svgRef.current && + debugBoundingBoxes.map((bbox) => { + const importance = bbox.importance ?? 0 + let strokeColor = '#888888' + + if (bbox.wasAccepted) { + strokeColor = '#00ff00' + } else if (importance > 1.5) { + strokeColor = '#ff6600' + } else if (importance > 0.5) { + strokeColor = '#ffcc00' + } + + // Get magnifier dimensions + const containerRect = containerRef.current!.getBoundingClientRect() + const magnifierWidth = containerRect.width * 0.5 + const magnifierHeight = magnifierWidth / 2 + + // Parse viewBox + const viewBoxParts = mapData.viewBox.split(' ').map(Number) + const viewBoxX = viewBoxParts[0] || 0 + const viewBoxY = viewBoxParts[1] || 0 + const viewBoxWidth = viewBoxParts[2] || 1000 + const viewBoxHeight = viewBoxParts[3] || 1000 + + // Get current zoom (use animated value) + const currentZoom = getCurrentZoom() + + // Calculate magnified viewBox (same logic as the magnifier's viewBox calculation) + const svgRect = svgRef.current!.getBoundingClientRect() + const scaleX = viewBoxWidth / svgRect.width + const scaleY = viewBoxHeight / svgRect.height + const svgOffsetX = svgRect.left - containerRect.left + const svgOffsetY = svgRect.top - containerRect.top + + if (!cursorPosition) return null + + const cursorSvgX = (cursorPosition.x - svgOffsetX) * scaleX + viewBoxX + const cursorSvgY = (cursorPosition.y - svgOffsetY) * scaleY + viewBoxY + + const magnifiedWidth = viewBoxWidth / currentZoom + const magnifiedHeight = viewBoxHeight / currentZoom + + const magnifiedViewBoxX = cursorSvgX - magnifiedWidth / 2 + const magnifiedViewBoxY = cursorSvgY - magnifiedHeight / 2 + + // Convert bbox center from SVG coords to magnifier pixel coords + const bboxCenterSvgX = bbox.x + bbox.width / 2 + const bboxCenterSvgY = bbox.y + bbox.height / 2 + + // Calculate position within magnified viewBox + const relativeX = (bboxCenterSvgX - magnifiedViewBoxX) / magnifiedWidth + const relativeY = (bboxCenterSvgY - magnifiedViewBoxY) / magnifiedHeight + + // Check if bbox is within magnified viewport + if (relativeX < 0 || relativeX > 1 || relativeY < 0 || relativeY > 1) { + return null // Don't show labels for regions outside magnifier viewport + } + + // Convert to pixel position within magnifier + const labelX = relativeX * magnifierWidth + const labelY = relativeY * magnifierHeight + + return ( +
+
{bbox.regionId}
+
{importance.toFixed(2)}
+
+ ) + })} + {/* Magnifier label */}