Handling window resize (and rotate).
This commit is contained in:
parent
7811f00779
commit
61fc42b251
|
@ -26,6 +26,7 @@
|
|||
"jotai": "^1.8.6",
|
||||
"lodash": "^4.17.21",
|
||||
"react": "^18.2.0",
|
||||
"react-cool-dimensions": "^2.0.7",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-router": "^5.2.0",
|
||||
"react-router-dom": "^5.2.0",
|
||||
|
|
|
@ -1,15 +1,12 @@
|
|||
import { Redirect, Route } from 'react-router-dom';
|
||||
import {
|
||||
IonApp,
|
||||
IonButtons,
|
||||
IonContent,
|
||||
IonFooter,
|
||||
IonHeader,
|
||||
IonRouterOutlet,
|
||||
IonToolbar,
|
||||
setupIonicReact,
|
||||
} from '@ionic/react';
|
||||
import { IonReactRouter } from '@ionic/react-router';
|
||||
|
||||
/* Core CSS required for Ionic components to work properly */
|
||||
import '@ionic/react/css/core.css';
|
||||
|
|
|
@ -79,11 +79,7 @@ export const LayerStack: react.FC<LayerStackProperties> = (
|
|||
// console.log(`tiledLayers: ${JSON.stringify(tiledLayers)}`);
|
||||
|
||||
return (
|
||||
<svg
|
||||
width={window.innerWidth}
|
||||
height={window.innerHeight}
|
||||
data-testid='layer-stack'
|
||||
>
|
||||
<svg width='100%' height='100%' data-testid='layer-stack'>
|
||||
<g
|
||||
transform={`translate(${props.coordinateSystem.shift.x}, ${props.coordinateSystem.shift.y}) scale(${props.coordinateSystem.zoom})`}
|
||||
>
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
import react, { useEffect, useState } from 'react';
|
||||
import useDimensions from 'react-cool-dimensions';
|
||||
|
||||
import { MapScope, Point } from './types';
|
||||
import Map from './Map';
|
||||
import Handlers from './Handlers';
|
||||
|
@ -58,6 +60,7 @@ export const LiveMap: react.FC<LiveMapProperties> = (
|
|||
setScope(props.scope);
|
||||
}, [props.scope]);
|
||||
console.log(`LiveMap rendering: ${JSON.stringify(scope)}`);
|
||||
const { observe, width, height } = useDimensions<HTMLDivElement>();
|
||||
const transform = (t: Transformation) => {
|
||||
const deltaZoom = t.deltaZoom === null ? 1 : t.deltaZoom;
|
||||
const deltaZoomLevel = Math.log2(deltaZoom);
|
||||
|
@ -96,12 +99,12 @@ export const LiveMap: react.FC<LiveMapProperties> = (
|
|||
x:
|
||||
tilesCenter.x -
|
||||
actualDeltaShiftTiles.x -
|
||||
(window.innerWidth / 2 / visibleTileSize - actualZoomCenterTiles.x) *
|
||||
(width / 2 / visibleTileSize - actualZoomCenterTiles.x) *
|
||||
(deltaZoom - 1),
|
||||
y:
|
||||
tilesCenter.y -
|
||||
actualDeltaShiftTiles.y -
|
||||
(window.innerHeight / 2 / visibleTileSize - actualZoomCenterTiles.y) *
|
||||
(height / 2 / visibleTileSize - actualZoomCenterTiles.y) *
|
||||
(deltaZoom - 1),
|
||||
};
|
||||
|
||||
|
@ -127,10 +130,10 @@ export const LiveMap: react.FC<LiveMapProperties> = (
|
|||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div style={{ width: '100%', height: '100%' }} ref={observe}>
|
||||
<Handlers transformMap={transform} />
|
||||
<Map scope={scope} numberOfTiledLayers={props.numberOfTiledLayers} />
|
||||
</>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import react from 'react';
|
||||
import useDimensions from 'react-cool-dimensions';
|
||||
|
||||
import { Point, MapScope } from './types';
|
||||
import LayerStack from './LayerStack';
|
||||
|
@ -13,13 +14,15 @@ export interface MapProperties {
|
|||
/**
|
||||
*
|
||||
* @returns A `<Map>` component
|
||||
*
|
||||
*
|
||||
* `<Map>` components display the map specified by their {@link MapProperties}'s scope.
|
||||
*
|
||||
* They can be driven by {@link components/map/LiveMap!LiveMap} component to react to user's event.
|
||||
*
|
||||
* They can be driven by {@link components/map/LiveMap!LiveMap} component to react to user's event.
|
||||
*
|
||||
*/
|
||||
export const Map: react.FC<MapProperties> = (props: MapProperties) => {
|
||||
const { observe, width, height } = useDimensions<HTMLDivElement>();
|
||||
|
||||
const tileProvider = tileProviders[props.scope.tileProvider];
|
||||
|
||||
const tilesZoom = Math.min(
|
||||
|
@ -33,13 +36,13 @@ export const Map: react.FC<MapProperties> = (props: MapProperties) => {
|
|||
const softZoom = props.scope.zoom - tilesZoom;
|
||||
const relativeScale = 2 ** softZoom;
|
||||
const visibleTileSize = tileProvider.tileSize * relativeScale;
|
||||
const nbTilesLeft = window.innerWidth / 2 / visibleTileSize;
|
||||
const nbTilesTop = window.innerHeight / 2 / visibleTileSize;
|
||||
const nbTilesLeft = width / 2 / visibleTileSize;
|
||||
const nbTilesTop = height / 2 / visibleTileSize;
|
||||
const firstTileLeft = Math.floor(tilesCenter.x - nbTilesLeft);
|
||||
const firstTileTop = Math.floor(tilesCenter.y - nbTilesTop);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div style={{ width: '100%', height: '100%' }} ref={observe}>
|
||||
<LayerStack
|
||||
numberOfTiledLayers={props.numberOfTiledLayers}
|
||||
keyObject={{
|
||||
|
@ -56,7 +59,7 @@ export const Map: react.FC<MapProperties> = (props: MapProperties) => {
|
|||
zoom: relativeScale,
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import react from 'react';
|
||||
import react, { useRef } from 'react';
|
||||
import TileSet from './TileSet';
|
||||
import { Point, TileKeyObject } from './types';
|
||||
import { CoordinateSystem } from './LiveMap';
|
||||
|
@ -32,48 +32,52 @@ export interface TiledLayerProperties {
|
|||
export const TiledLayer: react.FC<TiledLayerProperties> = (
|
||||
props: TiledLayerProperties
|
||||
) => {
|
||||
const viewPort =
|
||||
props.zoom === 256
|
||||
? {
|
||||
topLeft: {
|
||||
x:
|
||||
props.keyObject.x +
|
||||
Math.floor(
|
||||
-props.coordinateSystem.shift.x /
|
||||
props.coordinateSystem.zoom /
|
||||
256
|
||||
),
|
||||
y:
|
||||
props.keyObject.y +
|
||||
Math.floor(
|
||||
-props.coordinateSystem.shift.y /
|
||||
props.coordinateSystem.zoom /
|
||||
256
|
||||
),
|
||||
},
|
||||
bottomRight: {
|
||||
x:
|
||||
props.keyObject.x +
|
||||
Math.ceil(
|
||||
(-props.coordinateSystem.shift.x + window.innerWidth) /
|
||||
props.coordinateSystem.zoom /
|
||||
256
|
||||
) -
|
||||
1,
|
||||
y:
|
||||
props.keyObject.y +
|
||||
Math.ceil(
|
||||
(-props.coordinateSystem.shift.y + window.innerHeight) /
|
||||
props.coordinateSystem.zoom /
|
||||
256
|
||||
) -
|
||||
1,
|
||||
},
|
||||
}
|
||||
: undefined;
|
||||
const g = useRef<SVGGElement>(null);
|
||||
var viewPort: any = undefined;
|
||||
if (
|
||||
props.zoom === 256 &&
|
||||
g.current !== null &&
|
||||
g.current.ownerSVGElement !== null &&
|
||||
g.current.ownerSVGElement.parentElement !== null
|
||||
) {
|
||||
const nearerHTMLParent = g.current.ownerSVGElement.parentElement;
|
||||
viewPort = {
|
||||
topLeft: {
|
||||
x:
|
||||
props.keyObject.x +
|
||||
Math.floor(
|
||||
-props.coordinateSystem.shift.x / props.coordinateSystem.zoom / 256
|
||||
),
|
||||
y:
|
||||
props.keyObject.y +
|
||||
Math.floor(
|
||||
-props.coordinateSystem.shift.y / props.coordinateSystem.zoom / 256
|
||||
),
|
||||
},
|
||||
bottomRight: {
|
||||
x:
|
||||
props.keyObject.x +
|
||||
Math.ceil(
|
||||
(-props.coordinateSystem.shift.x + nearerHTMLParent.offsetWidth) /
|
||||
props.coordinateSystem.zoom /
|
||||
256
|
||||
) -
|
||||
1,
|
||||
y:
|
||||
props.keyObject.y +
|
||||
Math.ceil(
|
||||
(-props.coordinateSystem.shift.y + nearerHTMLParent.offsetHeight) /
|
||||
props.coordinateSystem.zoom /
|
||||
256
|
||||
) -
|
||||
1,
|
||||
},
|
||||
};
|
||||
}
|
||||
return (
|
||||
<g
|
||||
transform={`scale(${props.zoom}) translate(${props.shift.x}, ${props.shift.y})`}
|
||||
ref={g}
|
||||
>
|
||||
<TileSet
|
||||
keyObject={{
|
||||
|
|
Loading…
Reference in New Issue