Implementing a zoom feature.

This commit is contained in:
Eric van der Vlist 2022-09-08 22:39:00 +02:00
parent 2124a0024d
commit 6887cd0102
2 changed files with 60 additions and 6 deletions

View File

@ -2,16 +2,17 @@ import react from 'react';
import '../theme/background.css';
const Background: react.FC<{ shift: { x: number; y: number } }> = (props: {
const Background: react.FC<{
shift: { x: number; y: number };
}) => {
zoom: number;
}> = (props: { shift: { x: number; y: number }; zoom: number }) => {
console.log(`--- Rendering background, props: ${JSON.stringify(props)} ---`);
return (
<div
className='background'
style={{
transform: `translate(${-props.shift.x}px, ${-props.shift.y}px)`,
transform: `translate(${-props.shift.x}px, ${-props.shift.y}px) scale(${props.zoom})`,
}}
>
<img src='/assets/background.jpg' alt='' />

View File

@ -11,6 +11,8 @@ const Viewport: react.FC<{}> = (props: {}) => {
const [shift, setShift] = useState({ x: 1000, y: 1000 });
const [zoom, setZoom] = useState(1);
const initialMouseState = {
down: false,
starting: { x: -1, y: -1 },
@ -22,6 +24,8 @@ const Viewport: react.FC<{}> = (props: {}) => {
{ x: -1, y: -1 },
{ x: -1, y: -1 },
],
distance: -1,
initialZoom: 1,
};
const [mouseState, setMouseState] = useState(initialMouseState);
@ -40,9 +44,14 @@ const Viewport: react.FC<{}> = (props: {}) => {
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}`
`Touch : ${event.touches.length} touches, ${
event.touches[0].pageX
}, ${event.touches[0].pageY}, ${
event.touches.length > 1 ? event.touches[1].pageX : '-'
}, ${event.touches.length > 1 ? event.touches[1].pageY : '-'}`
);
}
console.log('touchState: ' + JSON.stringify(touchState));
return;
}
@ -118,6 +127,24 @@ const Viewport: react.FC<{}> = (props: {}) => {
setTouchState({
state: 'pointer',
touches: [{ x: event.touches[0].pageX, y: event.touches[0].pageY }],
distance: -1,
initialZoom: -1,
});
return;
}
if (event.touches.length === 2) {
setTouchState({
state: 'double',
touches: [
{ x: event.touches[0].pageX, y: event.touches[0].pageY },
{ x: event.touches[1].pageX, y: event.touches[1].pageY },
],
distance: Math.sqrt(
(event.touches[0].pageX - event.touches[1].pageX) ** 2 +
(event.touches[0].pageY - event.touches[1].pageY) ** 2
),
initialZoom: zoom,
});
}
};
@ -146,13 +173,39 @@ const Viewport: react.FC<{}> = (props: {}) => {
y: event.touches[0].pageY,
},
],
distance: 0,
initialZoom: -1,
});
}
return;
}
if (touchState.state === 'double') {
if (event.touches.length === 2) {
genericHandler(event);
const newDistance = Math.sqrt(
(event.touches[0].pageX - event.touches[1].pageX) ** 2 +
(event.touches[0].pageY - event.touches[1].pageY) ** 2
);
const factor = newDistance / touchState.distance;
console.log(`+++++++++ ZOOM Factor is ${factor} ++++++++++`);
setTouchState({
state: 'double',
touches: [
{ x: event.touches[0].pageX, y: event.touches[0].pageY },
{ x: event.touches[1].pageX, y: event.touches[1].pageY },
],
distance: touchState.distance,
initialZoom: zoom,
});
setZoom(zoom * factor);
}
return;
}
};
const throtteledTouchMoveHandler = useCallback(
_.throttle(touchMoveHandler, 50),
_.throttle(touchMoveHandler, 100),
[touchState.state]
);
@ -168,7 +221,7 @@ const Viewport: react.FC<{}> = (props: {}) => {
onTouchEnd={touchEndHandler}
onTouchCancel={mouseLeaveHandler}
>
<Background shift={shift} />
<Background shift={shift} zoom={zoom}/>
</div>
);
};