sandbox/svgmap/src/components/map/Viewport.tsx

64 lines
1.4 KiB
TypeScript

import react from 'react';
interface ViewportProperties {
boardSize: number;
shift: { x: number; y: number };
zoom: number;
}
/**
*
* Let's call:
* - x and y the SVG coordinates
* - X and Y the screen coordinates (pixels on screen)
*
* X0 = (x + shift.x * zoom) * zoom
* or
* x = X0 * zoom - shift.x
* id for Y
*
* To add a new shift of S screen pixels, we need to apply a zoom of S/zoom
*
* How can we zoom so that X and x stay constant ?
*
* Knowing X0, x0, zoom0, zoom1 and shift.x0,
*
*
* X0 = (x0 + shift.x0 *zoom0) * zoom0
* X1 = (x1 + shift.x1 *zoom1) * zoom1
* X0 = X1 (=X)
* x0 = x1 (=x)
* =>
* (x + shift.x1*zoom1) * zoom1 = (x + shift.x0 * zoom0) * zoom0
* =>
* (x + shift.x1*zoom1) = (x + shift.x0*zoom0) * zoom0 / zoom1
* shift.x1 = ((x + shift.x0) * zoom0 / zoom1 - x) / zoom1
*
* x = 333
* 282 => -25,5
*
*/
/**
*
* viewBox={`${-props.shift.x} ${-props.shift.y} ${
props.boardSize / props.zoom
} ${props.boardSize / props.zoom}`}
*
*/
const Viewport: react.FC<ViewportProperties> = (props: ViewportProperties) => {
return (
<svg height={props.boardSize} width={props.boardSize}>
<g
transform={`translate(${props.shift.x}, ${props.shift.y}) scale(${props.zoom})`}
>
<circle cx='50' cy='50' r='50' />
</g>
</svg>
);
};
export default Viewport;