Implementing a zoom feature.
This commit is contained in:
parent
2124a0024d
commit
6887cd0102
|
@ -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='' />
|
||||||
|
|
|
@ -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>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue