Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x | /**
* Hint Animation Hook
*
* Manages the pulsing animation effect when a hint is shown to highlight
* the target region on the map.
*
* Usage:
* ```tsx
* const { hintFlashProgress, isHintAnimating } = useHintAnimation({
* hintActive: props.hintActive,
* })
* ```
*/
'use client'
import { useEffect, useState } from 'react'
import { usePulsingAnimation } from '../animations'
// ============================================================================
// Types
// ============================================================================
export interface HintActive {
regionId: string
timestamp: number
}
export interface UseHintAnimationOptions {
/** The currently active hint, or null if no hint */
hintActive: HintActive | null
}
export interface UseHintAnimationReturn {
/** Pulsing value 0-1 for flash animation */
hintFlashProgress: number
/** Whether animation is currently in progress */
isHintAnimating: boolean
}
// ============================================================================
// Constants
// ============================================================================
/** Duration of the hint animation in milliseconds */
const HINT_ANIMATION_DURATION = 1500
/** Number of pulses during the hint animation */
const HINT_ANIMATION_PULSES = 2
// ============================================================================
// Hook Implementation
// ============================================================================
/**
* Hook for managing hint pulsing animation.
*
* When hintActive changes (detected by timestamp), triggers a brief pulsing
* animation to draw attention to the target region.
*
* @param options - Configuration options
* @returns Hint animation state
*/
export function useHintAnimation(options: UseHintAnimationOptions): UseHintAnimationReturn {
const { hintActive } = options
// Animation state
const [hintFlashProgress, setHintFlashProgress] = useState(0)
const [isHintAnimating, setIsHintAnimating] = useState(false)
// Animation controller
const hintAnimation = usePulsingAnimation()
// Hint animation effect - brief pulse to highlight target region
useEffect(() => {
if (!hintActive) {
setHintFlashProgress(0)
setIsHintAnimating(false)
return
}
// Start animation
setIsHintAnimating(true)
// Animation: 2 pulses over 1.5 seconds (shorter than give-up)
hintAnimation.start({
duration: HINT_ANIMATION_DURATION,
pulses: HINT_ANIMATION_PULSES,
onProgress: setHintFlashProgress,
onComplete: () => {
setHintFlashProgress(0)
setIsHintAnimating(false)
},
})
// Cleanup
return () => {
hintAnimation.cancel()
}
}, [hintActive?.timestamp, hintAnimation]) // Re-run when timestamp changes
return {
hintFlashProgress,
isHintAnimating,
}
}
|