feat: add gold scrim overlay and improve precision mode messaging

**Better messaging:**
- Changed from confusing "Click here (not map)" to clearer "Click to activate precision mode"
- Message indicates clicking anywhere will activate precision mode
- Focuses on the action (click) and result (precision mode) rather than location

**Visual scrim overlay:**
- Added semi-transparent gold overlay (rgba(251, 191, 36, 0.15)) on magnifier
- Only appears when at or above precision mode threshold
- Acts as visual "barrier" indicating precision mode is needed
- Removed when pointer lock is active
- Combines with existing dimmed/desaturated magnifier effect

**User experience:**
When zoom reaches threshold:
- Magnifier dims (60% brightness, 50% saturation)
- Gold scrim appears over magnifier
- Gold pixel grid visible
- Message: "Click to activate precision mode"
- Clicking anywhere on map activates pointer lock
- All visual barriers removed once precision mode active

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Thomas Hallock 2025-11-23 18:50:41 -06:00
parent c8a9328a6e
commit 4b20d0753f
1 changed files with 38 additions and 2 deletions

View File

@ -2169,9 +2169,9 @@ export function MapRenderer({
const screenPixelRatio =
mainMapSvgUnitsPerScreenPixel * magnifierScreenPixelsPerSvgUnit
// If at or above threshold, show clickable notice to activate precision controls
// If at or above threshold, show notice about activating precision controls
if (screenPixelRatio >= PRECISION_MODE_THRESHOLD) {
return 'Click here (not map) for precision mode'
return 'Click to activate precision mode'
}
// Below threshold - show debug info in dev, simple zoom in prod
@ -2182,6 +2182,42 @@ export function MapRenderer({
return `${z.toFixed(1)}×`
})}
</animated.div>
{/* Scrim overlay - shows when at threshold to indicate barrier */}
{!pointerLocked &&
(() => {
const containerRect = containerRef.current?.getBoundingClientRect()
const svgRect = svgRef.current?.getBoundingClientRect()
if (!containerRect || !svgRect) return null
const magnifierWidth = containerRect.width * 0.5
const viewBoxParts = mapData.viewBox.split(' ').map(Number)
const viewBoxWidth = viewBoxParts[2]
if (!viewBoxWidth || isNaN(viewBoxWidth)) return null
const currentZoom = magnifierSpring.zoom.get()
const magnifiedViewBoxWidth = viewBoxWidth / currentZoom
const magnifierScreenPixelsPerSvgUnit = magnifierWidth / magnifiedViewBoxWidth
const mainMapSvgUnitsPerScreenPixel = viewBoxWidth / svgRect.width
const screenPixelRatio =
mainMapSvgUnitsPerScreenPixel * magnifierScreenPixelsPerSvgUnit
// Only show scrim when at or above threshold
if (screenPixelRatio < PRECISION_MODE_THRESHOLD) return null
return (
<div
data-element="precision-mode-scrim"
style={{
position: 'absolute',
inset: 0,
background: 'rgba(251, 191, 36, 0.15)', // Gold scrim
pointerEvents: 'none',
borderRadius: '12px',
}}
/>
)
})()}
</animated.div>
)}
</div>