54 lines
1.3 KiB
TypeScript
54 lines
1.3 KiB
TypeScript
|
import react, { useEffect, useRef } from 'react';
|
||
|
|
||
|
export interface TileProperties {
|
||
|
// The image's source URL
|
||
|
href: string;
|
||
|
// Its size
|
||
|
size: number;
|
||
|
// A delay to add (for test/debug purposes)
|
||
|
delay?: number;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
*
|
||
|
* @param props
|
||
|
* @returns A tile
|
||
|
*/
|
||
|
export const Tile: react.FC<TileProperties> = (props: TileProperties) => {
|
||
|
const g = useRef<SVGGElement>(null);
|
||
|
|
||
|
const timeout = (ms: number) => {
|
||
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
||
|
};
|
||
|
|
||
|
useEffect(() => {
|
||
|
const loadImage = async () => {
|
||
|
console.log(`Pre loading: ${props.href}`);
|
||
|
const image = new Image(props.size, props.size);
|
||
|
image.loading = 'eager';
|
||
|
// @ts-ignore
|
||
|
image.setAttribute('href', props.href);
|
||
|
if (!image.complete) {
|
||
|
await image.decode();
|
||
|
}
|
||
|
if (props.delay !== undefined) {
|
||
|
await timeout(props.delay);
|
||
|
}
|
||
|
const svgImage = document.createElementNS(
|
||
|
'http://www.w3.org/2000/svg',
|
||
|
'image'
|
||
|
) as unknown as SVGImageElement;
|
||
|
svgImage.setAttribute('width', props.size.toString());
|
||
|
svgImage.setAttribute('height', props.size.toString());
|
||
|
// @ts-ignore
|
||
|
svgImage.setAttribute('href', props.href);
|
||
|
g.current?.replaceChildren(svgImage);
|
||
|
};
|
||
|
loadImage();
|
||
|
}, [props.href, props.size]);
|
||
|
|
||
|
return <g ref={g} />;
|
||
|
};
|
||
|
|
||
|
export default Tile;
|