From 2362ff293883a3414f02ebce747bc55cd2b8f02d Mon Sep 17 00:00:00 2001 From: evlist Date: Fri, 14 Oct 2022 20:52:24 +0200 Subject: [PATCH] Loading new tiles when shift requires... --- svgmap/src/components/map/Map.tsx | 82 +++++++++++++++++++---- svgmap/src/components/map/SlippyBoard.tsx | 5 +- svgmap/src/components/map/Tile.tsx | 66 +++++++++--------- 3 files changed, 110 insertions(+), 43 deletions(-) diff --git a/svgmap/src/components/map/Map.tsx b/svgmap/src/components/map/Map.tsx index 70118f8..d078b67 100644 --- a/svgmap/src/components/map/Map.tsx +++ b/svgmap/src/components/map/Map.tsx @@ -1,5 +1,10 @@ -import { IonContent } from '@ionic/react'; -import react, { useState } from 'react'; +import { IonContent, ReactComponentOrElement } from '@ionic/react'; +import react, { + ReactComponentElement, + useEffect, + useRef, + useState, +} from 'react'; import './Map.css'; import MouseHandler from './MouseHandler'; @@ -32,21 +37,74 @@ const Map: react.FC = (props: MapProperties) => { setZoom(zoom * zoomFactor); }; - var tiledLayer: any[] = []; + console.log(`Rendering Map, zoom:${zoom}, shift:${JSON.stringify(shift)}`); + + var initialTiledLayer: any[][] = []; for (let row = 0; row < nbTiles; row++) { + let tileRow = []; for (let col = 0; col < nbTiles; col++) { - tiledLayer.push( - - ); + tileRow.push(); } + initialTiledLayer.push(tileRow); } + const [tiledLayer, setTiledLayer] = useState(initialTiledLayer); + + useEffect(() => { + const firstVisibleTiles = { + x: Math.max(Math.floor(-shift.x / 256), 0), + y: Math.max(Math.floor(-shift.y / 256), 0), + }; + + const lastVisibleTiles = { + x: Math.min( + Math.ceil(firstVisibleTiles.x + props.width / 256), + nbTiles - 1 + ), + y: Math.min( + Math.ceil(firstVisibleTiles.y + props.height / 256), + nbTiles - 1 + ), + }; + console.log( + `Adding new tiles if needed for ${JSON.stringify( + firstVisibleTiles + )}/${JSON.stringify(lastVisibleTiles)}.` + ); + const newTiledLayer: any[][] = []; + for (let row = 0; row < nbTiles; row++) { + let tileRow = []; + for (let col = 0; col < nbTiles; col++) { + const key = `${row}/${col}`; + if ( + tiledLayer[row][col].type === 'g' && + row >= firstVisibleTiles.y && + row <= lastVisibleTiles.y && + col >= firstVisibleTiles.x && + col <= lastVisibleTiles.x + ) { + tileRow.push( + + ); + } else { + // tileRow.push(); + tileRow.push(tiledLayer[row][col]); + } + } + newTiledLayer.push(tileRow); + } + + setTiledLayer(newTiledLayer); + }, [shift, zoom, nbTiles]); + + // console.log(`tiledLayer: ${JSON.stringify(tiledLayer)}`); + return (
= ( diff --git a/svgmap/src/components/map/Tile.tsx b/svgmap/src/components/map/Tile.tsx index 9227629..2f6393e 100644 --- a/svgmap/src/components/map/Tile.tsx +++ b/svgmap/src/components/map/Tile.tsx @@ -1,7 +1,7 @@ import react, { useEffect, useMemo, useRef, useState } from 'react'; interface TileProperties { - href: string; + href?: string; x: number; y: number; delay?: number; @@ -16,32 +16,36 @@ const Tile: react.FC = (props: TileProperties) => { }; useEffect(() => { - const loadImage = async () => { - console.log(`Pre loading: ${JSON.stringify(props.href)}`); - const image = new Image(256, 256); - // const image:SVGImageElement = document.createElement('image') as unknown as SVGImageElement; - // const image = new SVGImageElement(); - image.loading = 'eager'; - 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', '256'); - svgImage.setAttribute('height', '256'); - svgImage.setAttribute('href', props.href); - // svgImage.setAttribute('x', '0'); - // svgImage.setAttribute('y', '0'); - g.current?.replaceChildren(svgImage); - }; - loadImage(); - }, []); + if (props.href !== undefined) { + const loadImage = async () => { + console.log(`Pre loading: ${JSON.stringify(props.href)}`); + const image = new Image(256, 256); + // const image:SVGImageElement = document.createElement('image') as unknown as SVGImageElement; + // const image = new SVGImageElement(); + 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', '256'); + svgImage.setAttribute('height', '256'); + // @ts-ignore + svgImage.setAttribute('href', props.href); + // svgImage.setAttribute('x', '0'); + // svgImage.setAttribute('y', '0'); + g.current?.replaceChildren(svgImage); + }; + loadImage(); + } + }, [props.href]); // const children = useMemo( // () => ( @@ -52,9 +56,11 @@ const Tile: react.FC = (props: TileProperties) => { // [] // ); - return <> - -; + return ( + <> + + + ); }; export default Tile;