2022-10-17 19:23:57 +00:00
|
|
|
import react, { useEffect, useRef } from 'react';
|
|
|
|
|
|
|
|
export interface TileProperties {
|
2022-10-17 19:31:21 +00:00
|
|
|
/** The image's source URL */
|
2022-10-17 19:23:57 +00:00
|
|
|
href: string;
|
2022-10-17 19:31:21 +00:00
|
|
|
/** Its size */
|
2022-10-17 19:23:57 +00:00
|
|
|
size: number;
|
2022-10-17 19:31:21 +00:00
|
|
|
/** A delay to add (for test/debug purposes) */
|
2022-10-17 19:23:57 +00:00
|
|
|
delay?: number;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* @param props
|
|
|
|
* @returns A tile
|
2022-10-17 19:31:21 +00:00
|
|
|
*
|
|
|
|
* Tile components are containers for images.
|
|
|
|
* They return an empty <g/> element immediately so that the rendering can proceed
|
|
|
|
* and append a, <image/> element whenever the image is loaded.
|
2022-10-17 19:23:57 +00:00
|
|
|
*/
|
|
|
|
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;
|