sandbox/map/src/components/viewport.tsx

101 lines
2.7 KiB
TypeScript

import react, { useCallback, useState } from 'react';
import _, { constant } from 'lodash';
import MouseHandler from './mouse-handler';
import Layer from './layer';
import '../theme/viewport.css';
import SingleTouchHandler from './single-touch-handler';
import DoubleTouchHandler from './double-touch-handler';
export interface Point {
x: number;
y: number;
}
export interface Translation {
translate: Point;
}
export interface Scale {
scale: {
center: Point;
factor: number;
};
}
export type Transformation = Translation | Scale;
// const transform1: Transformation = { translate: { x: 0, y: 1 } };
// const transform2: Transformation = {
// scale: { center: { x: 10, y: 20 }, factor: 2 },
// };
interface ViewportProps {
children: any;
}
export interface ViewportState {
scale: number;
translation: Point;
}
const Viewport: react.FC<ViewportProps> = (props: ViewportProps) => {
//console.log(`--- Rendering viewport, props: ${JSON.stringify(props)} ---`);
const initialState: ViewportState = { scale: 1, translation: { x: 0, y: 0 } };
const [state, setState] = useState(initialState);
const genericHandler = (event: any) => {
console.log('Log - Event: ' + event.type);
return;
};
const applyTransformations = (transformations: Transformation[]) => {
const newState = transformations.reduce(
(previousState: ViewportState, transformation): ViewportState => {
if ('scale' in transformation) {
return {
scale: previousState.scale * transformation.scale.factor,
translation: {
x:
previousState.translation.x +
(previousState.translation.x - transformation.scale.center.x) *
(transformation.scale.factor - 1),
y:
previousState.translation.y +
(previousState.translation.y - transformation.scale.center.y) *
(transformation.scale.factor - 1),
},
};
}
return {
scale: previousState.scale,
translation: {
x: previousState.translation.x + transformation.translate.x,
y: previousState.translation.y + transformation.translate.y,
},
};
},
state
);
setState(newState);
};
return (
<div className='viewport'>
<MouseHandler applyTransformations={applyTransformations}>
<SingleTouchHandler applyTransformations={applyTransformations}>
<DoubleTouchHandler applyTransformations={applyTransformations}>
<Layer viewportState={state}>{props.children}</Layer>
</DoubleTouchHandler>
</SingleTouchHandler>
</MouseHandler>
</div>
);
};
export default Viewport;