165 lines
4.3 KiB
TypeScript
165 lines
4.3 KiB
TypeScript
import react, { useCallback, useState } from 'react';
|
|
|
|
import _ from 'lodash';
|
|
|
|
import Background from './background';
|
|
|
|
import '../theme/viewport.css';
|
|
|
|
const Viewport: react.FC<{}> = (props: {}) => {
|
|
console.log(`--- Rendering viewport, props: ${JSON.stringify(props)} ---`);
|
|
|
|
const [shift, setShift] = useState({ x: 1000, y: 1000 });
|
|
|
|
const initialMouseState = {
|
|
down: false,
|
|
starting: { x: -1, y: -1 },
|
|
};
|
|
const [mouseState, setMouseState] = useState(initialMouseState);
|
|
const [touchState, setTouchState] = useState(initialMouseState);
|
|
|
|
console.log('viewport, mouseState: ' + JSON.stringify(mouseState));
|
|
console.log('viewport, touchState: ' + JSON.stringify(touchState));
|
|
|
|
const genericHandler = (event: any) => {
|
|
console.log('Log - Event: ' + event.type);
|
|
if (event.type.startsWith('mouse')) {
|
|
console.log(`Mouse : ${event.pageX}, ${event.pageY}`);
|
|
console.log('mouseState: ' + JSON.stringify(mouseState));
|
|
return;
|
|
}
|
|
if (event.type.startsWith('touch')) {
|
|
if (event.touches.length > 0) {
|
|
console.log(
|
|
`Touch : ${event.touches.length} touches, ${event.touches[0].pageX}, ${event.touches[0].pageY}`
|
|
);
|
|
}
|
|
console.log('touchState: ' + JSON.stringify(touchState));
|
|
return;
|
|
}
|
|
};
|
|
|
|
// TODO: implement resize event
|
|
// TODO: check boundaries
|
|
|
|
const mouseLeaveHandler = (event: any) => {
|
|
genericHandler(event);
|
|
event.preventDefault();
|
|
throtteledMouseMoveHandler.cancel();
|
|
setMouseState(initialMouseState);
|
|
setTouchState(initialMouseState);
|
|
};
|
|
|
|
const mouseDownHandler = (event: any) => {
|
|
genericHandler(event);
|
|
event.preventDefault();
|
|
setMouseState({
|
|
down: true,
|
|
starting: { x: event.pageX, y: event.pageY },
|
|
});
|
|
};
|
|
|
|
const mouseUpHandler = (event: any) => {
|
|
genericHandler(event);
|
|
event.preventDefault();
|
|
setMouseState(initialMouseState);
|
|
};
|
|
|
|
const mouseMoveHandler = (event: any) => {
|
|
event.preventDefault();
|
|
if (mouseState.down) {
|
|
genericHandler(event);
|
|
// setShift((shift) => ({
|
|
// x: shift.x + (mouseState.starting.x - event.pageX),
|
|
// y: shift.y + (mouseState.starting.y - event.pageY),
|
|
// }));
|
|
// setMouseState((mouseState) => ({
|
|
// down: true,
|
|
// starting: {
|
|
// x: event.pageX,
|
|
// y: event.pageY,
|
|
// },
|
|
// }));
|
|
setShift({
|
|
x: shift.x + (mouseState.starting.x - event.pageX),
|
|
y: shift.y + (mouseState.starting.y - event.pageY),
|
|
});
|
|
setMouseState({
|
|
down: true,
|
|
starting: {
|
|
x: event.pageX,
|
|
y: event.pageY,
|
|
},
|
|
});
|
|
}
|
|
};
|
|
|
|
const throtteledMouseMoveHandler = useCallback(
|
|
_.throttle(mouseMoveHandler, 50),
|
|
[mouseState.down]
|
|
);
|
|
|
|
// Touch
|
|
|
|
const touchStartHandler = (event: any) => {
|
|
genericHandler(event);
|
|
// event.preventDefault();
|
|
if (event.touches.length === 1) {
|
|
setTouchState({
|
|
down: true,
|
|
starting: { x: event.touches[0].pageX, y: event.touches[0].pageY },
|
|
});
|
|
}
|
|
};
|
|
|
|
const touchEndHandler = (event: any) => {
|
|
genericHandler(event);
|
|
// event.preventDefault();
|
|
setTouchState(initialMouseState);
|
|
throtteledTouchMoveHandler.cancel()
|
|
};
|
|
|
|
const touchMoveHandler = (event: any) => {
|
|
// event.preventDefault();
|
|
if (touchState.down) {
|
|
if (event.touches.length === 1) {
|
|
genericHandler(event);
|
|
setShift({
|
|
x: shift.x + (touchState.starting.x - event.touches[0].pageX),
|
|
y: shift.y + (touchState.starting.y - event.touches[0].pageY),
|
|
});
|
|
setTouchState({
|
|
down: true,
|
|
starting: {
|
|
x: event.touches[0].pageX,
|
|
y: event.touches[0].pageY,
|
|
},
|
|
});
|
|
}
|
|
}
|
|
};
|
|
|
|
const throtteledTouchMoveHandler = useCallback(
|
|
_.throttle(touchMoveHandler, 50),
|
|
[touchState.down]
|
|
);
|
|
|
|
return (
|
|
<div
|
|
className='viewport'
|
|
onMouseDown={mouseDownHandler}
|
|
onMouseMove={throtteledMouseMoveHandler}
|
|
onMouseUp={mouseUpHandler}
|
|
onMouseLeave={mouseLeaveHandler}
|
|
onTouchStart={touchStartHandler}
|
|
onTouchMove={throtteledTouchMoveHandler}
|
|
onTouchEnd={touchEndHandler}
|
|
onTouchCancel={mouseLeaveHandler}
|
|
>
|
|
<Background shift={shift} />
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default Viewport;
|