112 lines
2.7 KiB
TypeScript
112 lines
2.7 KiB
TypeScript
import react, { useEffect, useState } from 'react';
|
|
import Tile from './Tile';
|
|
import fakeTile from './FakeTile.svg';
|
|
|
|
interface Point {
|
|
x: number;
|
|
y: number;
|
|
}
|
|
|
|
interface TiledLayerProperties {
|
|
height: number;
|
|
width: number;
|
|
shift: Point;
|
|
zoom: number;
|
|
tileSize: number;
|
|
nbTiles: number;
|
|
active: boolean;
|
|
}
|
|
|
|
const TiledLayer: react.FC<TiledLayerProperties> = (
|
|
props: TiledLayerProperties
|
|
) => {
|
|
var initialTiledLayer: any[][] = [];
|
|
for (let row = 0; row < props.nbTiles; row++) {
|
|
let tileRow = [];
|
|
for (let col = 0; col < props.nbTiles; col++) {
|
|
tileRow.push(<g key={`${row}/${col}`} />);
|
|
}
|
|
initialTiledLayer.push(tileRow);
|
|
}
|
|
|
|
const [tiledLayer, setTiledLayer] = useState(initialTiledLayer);
|
|
|
|
useEffect(() => {
|
|
if (props.active) {
|
|
const firstVisibleTiles = {
|
|
x: Math.max(
|
|
Math.floor(-props.shift.x / props.tileSize / props.zoom),
|
|
0
|
|
),
|
|
y: Math.max(
|
|
Math.floor(-props.shift.y / props.tileSize / props.zoom),
|
|
0
|
|
),
|
|
};
|
|
|
|
const lastVisibleTiles = {
|
|
x: Math.min(
|
|
Math.ceil(
|
|
firstVisibleTiles.x + props.width / props.tileSize / props.zoom
|
|
),
|
|
props.nbTiles - 1
|
|
),
|
|
y: Math.min(
|
|
Math.ceil(
|
|
firstVisibleTiles.y + props.height / props.tileSize / props.zoom
|
|
),
|
|
props.nbTiles - 1
|
|
),
|
|
};
|
|
console.log(
|
|
`Adding new tiles if needed for ${JSON.stringify(
|
|
firstVisibleTiles
|
|
)}/${JSON.stringify(lastVisibleTiles)}.`
|
|
);
|
|
const newTiledLayer: any[][] = [];
|
|
for (let row = 0; row < props.nbTiles; row++) {
|
|
let tileRow = [];
|
|
for (let col = 0; col < props.nbTiles; col++) {
|
|
const key = `${row}/${col}`;
|
|
if (
|
|
tiledLayer[row][col].type === 'g' &&
|
|
row >= firstVisibleTiles.y &&
|
|
row <= lastVisibleTiles.y &&
|
|
col >= firstVisibleTiles.x &&
|
|
col <= lastVisibleTiles.x
|
|
) {
|
|
console.log(`Adding tile ${row}/${col}`);
|
|
tileRow.push(
|
|
<Tile
|
|
key={key}
|
|
href={fakeTile}
|
|
x={col * props.tileSize}
|
|
y={row * props.tileSize}
|
|
tileSize={props.tileSize}
|
|
delay={1000}
|
|
/>
|
|
);
|
|
} else {
|
|
tileRow.push(tiledLayer[row][col]);
|
|
}
|
|
}
|
|
newTiledLayer.push(tileRow);
|
|
}
|
|
|
|
setTiledLayer(newTiledLayer);
|
|
}
|
|
}, [
|
|
props.shift,
|
|
props.zoom,
|
|
props.nbTiles,
|
|
props.height,
|
|
props.width,
|
|
props.active,
|
|
props.tileSize,
|
|
]);
|
|
|
|
return <>{tiledLayer}</>;
|
|
};
|
|
|
|
export default TiledLayer;
|