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'; import '../theme/background.css';
const Background: react.FC<{ shift: { x: number; y: number } }> = (props: { const Background: react.FC<{
shift: { x: number; y: number }; shift: { x: number; y: number };
}) => { zoom: number;
}> = (props: { shift: { x: number; y: number }; zoom: number }) => {
console.log(`--- Rendering background, props: ${JSON.stringify(props)} ---`); console.log(`--- Rendering background, props: ${JSON.stringify(props)} ---`);
return ( return (
<div <div
className='background' className='background'
style={{ 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='' /> <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 [shift, setShift] = useState({ x: 1000, y: 1000 });
const [zoom, setZoom] = useState(1);
const initialMouseState = { const initialMouseState = {
down: false, down: false,
starting: { x: -1, y: -1 }, starting: { x: -1, y: -1 },
@ -22,6 +24,8 @@ const Viewport: react.FC<{}> = (props: {}) => {
{ x: -1, y: -1 }, { x: -1, y: -1 },
{ x: -1, y: -1 }, { x: -1, y: -1 },
], ],
distance: -1,
initialZoom: 1,
}; };
const [mouseState, setMouseState] = useState(initialMouseState); const [mouseState, setMouseState] = useState(initialMouseState);
@ -40,9 +44,14 @@ const Viewport: react.FC<{}> = (props: {}) => {
if (event.type.startsWith('touch')) { if (event.type.startsWith('touch')) {
if (event.touches.length > 0) { if (event.touches.length > 0) {
console.log( 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)); console.log('touchState: ' + JSON.stringify(touchState));
return; return;
} }
@ -118,6 +127,24 @@ const Viewport: react.FC<{}> = (props: {}) => {
setTouchState({ setTouchState({
state: 'pointer', state: 'pointer',
touches: [{ x: event.touches[0].pageX, y: event.touches[0].pageY }], 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, 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( const throtteledTouchMoveHandler = useCallback(
_.throttle(touchMoveHandler, 50), _.throttle(touchMoveHandler, 100),
[touchState.state] [touchState.state]
); );
@ -168,7 +221,7 @@ const Viewport: react.FC<{}> = (props: {}) => {
onTouchEnd={touchEndHandler} onTouchEnd={touchEndHandler}
onTouchCancel={mouseLeaveHandler} onTouchCancel={mouseLeaveHandler}
> >
<Background shift={shift} /> <Background shift={shift} zoom={zoom}/>
</div> </div>
); );
}; };