40 lines
796 B
TypeScript
40 lines
796 B
TypeScript
// frontend\src\components\ui\SpritePreloader.tsx
|
|
|
|
'use client'
|
|
|
|
import { useEffect } from 'react'
|
|
|
|
const loadedSpriteUrls = new Set<string>()
|
|
|
|
type Props = {
|
|
src?: string | null
|
|
enabled?: boolean
|
|
}
|
|
|
|
export default function SpritePreloader({
|
|
src,
|
|
enabled = true,
|
|
}: Props) {
|
|
useEffect(() => {
|
|
const url = String(src ?? '').trim()
|
|
if (!enabled || !url || loadedSpriteUrls.has(url)) return
|
|
|
|
const img = new Image()
|
|
;(img as any).fetchPriority = 'low'
|
|
img.decoding = 'async'
|
|
img.src = url
|
|
|
|
const markDone = () => {
|
|
loadedSpriteUrls.add(url)
|
|
}
|
|
|
|
if (typeof img.decode === 'function') {
|
|
img.decode().then(markDone).catch(markDone)
|
|
} else {
|
|
img.onload = markDone
|
|
img.onerror = markDone
|
|
}
|
|
}, [src, enabled])
|
|
|
|
return null
|
|
} |