Figuring out theright geometry for scaling and translating...
This commit is contained in:
parent
c929c6758d
commit
38183bb5fe
|
@ -6,6 +6,7 @@ import { Point } from './viewport';
|
||||||
|
|
||||||
interface DoubleTouchHandlerProps {
|
interface DoubleTouchHandlerProps {
|
||||||
updateZoom: (zoomFactor: number, center: Point) => void;
|
updateZoom: (zoomFactor: number, center: Point) => void;
|
||||||
|
updateShift: (shiftDelta: Point) => void;
|
||||||
children: any;
|
children: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,10 +89,19 @@ const DoubleTouchHandler: react.FC<DoubleTouchHandlerProps> = (
|
||||||
distance: touchState.distance,
|
distance: touchState.distance,
|
||||||
initialZoom: 1,
|
initialZoom: 1,
|
||||||
});
|
});
|
||||||
props.updateZoom(factor, {
|
const previousCenter = {
|
||||||
|
x: (touchState.touches[0].x + touchState.touches[1].x) / 2,
|
||||||
|
y: (touchState.touches[0].y + touchState.touches[1].y) / 2,
|
||||||
|
};
|
||||||
|
const currentCenter = {
|
||||||
x: (event.touches[0].pageX + event.touches[1].pageX) / 2,
|
x: (event.touches[0].pageX + event.touches[1].pageX) / 2,
|
||||||
y: (event.touches[0].pageY + event.touches[1].pageY) / 2,
|
y: (event.touches[0].pageY + event.touches[1].pageY) / 2,
|
||||||
});
|
};
|
||||||
|
props.updateZoom(factor, currentCenter);
|
||||||
|
// props.updateShift({
|
||||||
|
// x: currentCenter.x - previousCenter.x,
|
||||||
|
// y: currentCenter.y - previousCenter.y,
|
||||||
|
// });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -103,7 +113,7 @@ const DoubleTouchHandler: react.FC<DoubleTouchHandlerProps> = (
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className='viewport single-touch-handler'
|
className='viewport double-touch-handler'
|
||||||
onTouchStart={touchStartHandler}
|
onTouchStart={touchStartHandler}
|
||||||
onTouchMove={throtteledTouchMoveHandler}
|
onTouchMove={throtteledTouchMoveHandler}
|
||||||
onTouchEnd={touchEndHandler}
|
onTouchEnd={touchEndHandler}
|
||||||
|
|
|
@ -18,7 +18,7 @@ const Layer: react.FC<{
|
||||||
<div
|
<div
|
||||||
className='background'
|
className='background'
|
||||||
style={{
|
style={{
|
||||||
transform: `translate(${-props.shift.x}px, ${-props.shift.y}px) scale(${
|
transform: `translate(${props.shift.x}px, ${props.shift.y}px) scale(${
|
||||||
props.zoom
|
props.zoom
|
||||||
})`,
|
})`,
|
||||||
}}
|
}}
|
||||||
|
|
|
@ -6,13 +6,13 @@ import { Point } from './viewport';
|
||||||
|
|
||||||
interface MouseHandlerProps {
|
interface MouseHandlerProps {
|
||||||
updateShift: (shiftDelta: Point) => void;
|
updateShift: (shiftDelta: Point) => void;
|
||||||
|
updateZoom: (zoomFactor: number, center: Point) => void;
|
||||||
children: any;
|
children: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
const MouseHandler: react.FC<MouseHandlerProps> = (
|
const MouseHandler: react.FC<MouseHandlerProps> = (
|
||||||
props: MouseHandlerProps
|
props: MouseHandlerProps
|
||||||
) => {
|
) => {
|
||||||
|
|
||||||
const initialMouseState = {
|
const initialMouseState = {
|
||||||
down: false,
|
down: false,
|
||||||
starting: { x: -1, y: -1 },
|
starting: { x: -1, y: -1 },
|
||||||
|
@ -24,7 +24,7 @@ const MouseHandler: react.FC<MouseHandlerProps> = (
|
||||||
|
|
||||||
const genericHandler = (event: any) => {
|
const genericHandler = (event: any) => {
|
||||||
console.log('Log - Event: ' + event.type);
|
console.log('Log - Event: ' + event.type);
|
||||||
if (event.type.startsWith('mouse')) {
|
if (event.pageX !== undefined) {
|
||||||
console.log(`Mouse : ${event.pageX}, ${event.pageY}`);
|
console.log(`Mouse : ${event.pageX}, ${event.pageY}`);
|
||||||
console.log('mouseState: ' + JSON.stringify(mouseState));
|
console.log('mouseState: ' + JSON.stringify(mouseState));
|
||||||
return;
|
return;
|
||||||
|
@ -38,8 +38,8 @@ const MouseHandler: react.FC<MouseHandlerProps> = (
|
||||||
};
|
};
|
||||||
|
|
||||||
const mouseDownHandler = (event: any) => {
|
const mouseDownHandler = (event: any) => {
|
||||||
genericHandler(event);
|
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
genericHandler(event);
|
||||||
setMouseState({
|
setMouseState({
|
||||||
down: true,
|
down: true,
|
||||||
starting: { x: event.pageX, y: event.pageY },
|
starting: { x: event.pageX, y: event.pageY },
|
||||||
|
@ -57,8 +57,8 @@ const MouseHandler: react.FC<MouseHandlerProps> = (
|
||||||
if (mouseState.down) {
|
if (mouseState.down) {
|
||||||
genericHandler(event);
|
genericHandler(event);
|
||||||
props.updateShift({
|
props.updateShift({
|
||||||
x: mouseState.starting.x - event.pageX,
|
x: event.pageX - mouseState.starting.x,
|
||||||
y: mouseState.starting.y - event.pageY,
|
y: event.pageY - mouseState.starting.y,
|
||||||
});
|
});
|
||||||
setMouseState({
|
setMouseState({
|
||||||
down: true,
|
down: true,
|
||||||
|
@ -75,13 +75,19 @@ const MouseHandler: react.FC<MouseHandlerProps> = (
|
||||||
[mouseState.down]
|
[mouseState.down]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const doubleClickHandler = (event: any) => {
|
||||||
|
genericHandler(event);
|
||||||
|
props.updateZoom(2, { x: event.pageX, y: event.pageY });
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className='viewport'
|
className='viewport mouse-handler'
|
||||||
onMouseDown={mouseDownHandler}
|
onMouseDown={mouseDownHandler}
|
||||||
onMouseMove={throtteledMouseMoveHandler}
|
onMouseMove={throtteledMouseMoveHandler}
|
||||||
onMouseUp={mouseUpHandler}
|
onMouseUp={mouseUpHandler}
|
||||||
onMouseLeave={mouseLeaveHandler}
|
onMouseLeave={mouseLeaveHandler}
|
||||||
|
onDoubleClick={doubleClickHandler}
|
||||||
>
|
>
|
||||||
{props.children}
|
{props.children}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -64,8 +64,8 @@ const SingleTouchHandler: react.FC<SingleTouchHandlerProps> = (
|
||||||
if (event.touches.length === 1) {
|
if (event.touches.length === 1) {
|
||||||
genericHandler(event);
|
genericHandler(event);
|
||||||
props.updateShift({
|
props.updateShift({
|
||||||
x: touchState.touch.x - event.touches[0].pageX,
|
x: event.touches[0].pageX - touchState.touch.x,
|
||||||
y: touchState.touch.y - event.touches[0].pageY,
|
y: event.touches[0].pageY - touchState.touch.y,
|
||||||
});
|
});
|
||||||
setTouchState({
|
setTouchState({
|
||||||
state: 'pointer',
|
state: 'pointer',
|
||||||
|
@ -85,7 +85,7 @@ const SingleTouchHandler: react.FC<SingleTouchHandlerProps> = (
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className='viewport'
|
className='viewport single-touch-handler'
|
||||||
onTouchStart={touchStartHandler}
|
onTouchStart={touchStartHandler}
|
||||||
onTouchMove={throtteledTouchMoveHandler}
|
onTouchMove={throtteledTouchMoveHandler}
|
||||||
onTouchEnd={touchEndHandler}
|
onTouchEnd={touchEndHandler}
|
||||||
|
|
|
@ -41,22 +41,18 @@ const Viewport: react.FC<ViewportProps> = (props: ViewportProps) => {
|
||||||
|
|
||||||
const updateZoom = (zoomFactor: number, center: Point) => {
|
const updateZoom = (zoomFactor: number, center: Point) => {
|
||||||
const newZoom = zoom * zoomFactor;
|
const newZoom = zoom * zoomFactor;
|
||||||
setZoom(newZoom);
|
updateShift({
|
||||||
setShift({
|
x: (shift.x - center.x) * (zoomFactor - 1),
|
||||||
x: shift.x + center.x / zoom - center.x / newZoom,
|
y: (shift.y - center.y) * (zoomFactor - 1),
|
||||||
y: shift.y + center.y / zoom - center.y / newZoom,
|
|
||||||
});
|
});
|
||||||
// setShift({
|
setZoom(newZoom);
|
||||||
// x: shift.x + 1440 / 2 / zoom - window.innerWidth / 2 / newZoom,
|
|
||||||
// y: shift.y + 2904 / 2 / zoom - window.innerHeight / 2 / newZoom,
|
|
||||||
// });
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='viewport'>
|
<div className='viewport'>
|
||||||
<MouseHandler updateShift={updateShift}>
|
<MouseHandler updateShift={updateShift} updateZoom={updateZoom}>
|
||||||
<SingleTouchHandler updateShift={updateShift}>
|
<SingleTouchHandler updateShift={updateShift}>
|
||||||
<DoubleTouchHandler updateZoom={updateZoom}>
|
<DoubleTouchHandler updateZoom={updateZoom} updateShift={updateShift}>
|
||||||
<Layer shift={shift} zoom={zoom}>
|
<Layer shift={shift} zoom={zoom}>
|
||||||
{props.children}
|
{props.children}
|
||||||
</Layer>
|
</Layer>
|
||||||
|
|
Loading…
Reference in New Issue