mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
parent
facde7ace0
commit
566e6a5ede
24 changed files with 912 additions and 357 deletions
|
@ -1,5 +1,5 @@
|
|||
import React from "react";
|
||||
import { AppState } from "../types";
|
||||
import { AppState, Zoom } from "../types";
|
||||
import { ExcalidrawElement } from "../element/types";
|
||||
import { ActionManager } from "../actions/manager";
|
||||
import {
|
||||
|
@ -183,14 +183,16 @@ export const ZoomActions = ({
|
|||
zoom,
|
||||
}: {
|
||||
renderAction: ActionManager["renderAction"];
|
||||
zoom: number;
|
||||
zoom: Zoom;
|
||||
}) => (
|
||||
<Stack.Col gap={1}>
|
||||
<Stack.Row gap={1} align="center">
|
||||
{renderAction("zoomIn")}
|
||||
{renderAction("zoomOut")}
|
||||
{renderAction("resetZoom")}
|
||||
<div style={{ marginInlineStart: 4 }}>{(zoom * 100).toFixed(0)}%</div>
|
||||
<div style={{ marginInlineStart: 4 }}>
|
||||
{(zoom.value * 100).toFixed(0)}%
|
||||
</div>
|
||||
</Stack.Row>
|
||||
</Stack.Col>
|
||||
);
|
||||
|
|
|
@ -180,6 +180,7 @@ import {
|
|||
saveToFirebase,
|
||||
isSavedToFirebase,
|
||||
} from "../data/firebase";
|
||||
import { getNewZoom } from "../scene/zoom";
|
||||
|
||||
/**
|
||||
* @param func handler taking at most single parameter (event).
|
||||
|
@ -935,8 +936,6 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
|||
sceneY: user.pointer.y,
|
||||
},
|
||||
this.state,
|
||||
this.canvas,
|
||||
window.devicePixelRatio,
|
||||
);
|
||||
cursorButton[socketId] = user.button;
|
||||
});
|
||||
|
@ -1146,8 +1145,6 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
|||
const { x, y } = viewportCoordsToSceneCoords(
|
||||
{ clientX, clientY },
|
||||
this.state,
|
||||
this.canvas,
|
||||
window.devicePixelRatio,
|
||||
);
|
||||
|
||||
const dx = x - elementsCenterX;
|
||||
|
@ -1205,8 +1202,6 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
|||
const { x, y } = viewportCoordsToSceneCoords(
|
||||
{ clientX: cursorX, clientY: cursorY },
|
||||
this.state,
|
||||
this.canvas,
|
||||
window.devicePixelRatio,
|
||||
);
|
||||
|
||||
const element = newTextElement({
|
||||
|
@ -1719,15 +1714,19 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
|||
this.setState({
|
||||
selectedElementIds: {},
|
||||
});
|
||||
gesture.initialScale = this.state.zoom;
|
||||
gesture.initialScale = this.state.zoom.value;
|
||||
});
|
||||
|
||||
private onGestureChange = withBatchedUpdates((event: GestureEvent) => {
|
||||
event.preventDefault();
|
||||
|
||||
this.setState({
|
||||
zoom: getNormalizedZoom(gesture.initialScale! * event.scale),
|
||||
});
|
||||
const gestureCenter = getCenter(gesture.pointers);
|
||||
this.setState(({ zoom }) => ({
|
||||
zoom: getNewZoom(
|
||||
getNormalizedZoom(gesture.initialScale! * event.scale),
|
||||
zoom,
|
||||
gestureCenter,
|
||||
),
|
||||
}));
|
||||
});
|
||||
|
||||
private onGestureEnd = withBatchedUpdates((event: GestureEvent) => {
|
||||
|
@ -1771,8 +1770,6 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
|||
sceneY: y,
|
||||
},
|
||||
this.state,
|
||||
this.canvas,
|
||||
window.devicePixelRatio,
|
||||
);
|
||||
return [viewportX, viewportY];
|
||||
},
|
||||
|
@ -1990,8 +1987,6 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
|||
const { x: sceneX, y: sceneY } = viewportCoordsToSceneCoords(
|
||||
event,
|
||||
this.state,
|
||||
this.canvas,
|
||||
window.devicePixelRatio,
|
||||
);
|
||||
|
||||
const selectedGroupIds = getSelectedGroupIds(this.state);
|
||||
|
@ -2051,12 +2046,16 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
|||
const distance = getDistance(Array.from(gesture.pointers.values()));
|
||||
const scaleFactor = distance / gesture.initialDistance!;
|
||||
|
||||
this.setState({
|
||||
scrollX: normalizeScroll(this.state.scrollX + deltaX / this.state.zoom),
|
||||
scrollY: normalizeScroll(this.state.scrollY + deltaY / this.state.zoom),
|
||||
zoom: getNormalizedZoom(gesture.initialScale! * scaleFactor),
|
||||
this.setState(({ zoom, scrollX, scrollY }) => ({
|
||||
scrollX: normalizeScroll(scrollX + deltaX / zoom.value),
|
||||
scrollY: normalizeScroll(scrollY + deltaY / zoom.value),
|
||||
zoom: getNewZoom(
|
||||
getNormalizedZoom(gesture.initialScale! * scaleFactor),
|
||||
zoom,
|
||||
center,
|
||||
),
|
||||
shouldCacheIgnoreZoom: true,
|
||||
});
|
||||
}));
|
||||
this.resetShouldCacheIgnoreZoomDebounced();
|
||||
} else {
|
||||
gesture.lastCenter = gesture.initialDistance = gesture.initialScale = null;
|
||||
|
@ -2079,12 +2078,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
|||
}
|
||||
}
|
||||
|
||||
const scenePointer = viewportCoordsToSceneCoords(
|
||||
event,
|
||||
this.state,
|
||||
this.canvas,
|
||||
window.devicePixelRatio,
|
||||
);
|
||||
const scenePointer = viewportCoordsToSceneCoords(event, this.state);
|
||||
const { x: scenePointerX, y: scenePointerY } = scenePointer;
|
||||
|
||||
if (
|
||||
|
@ -2453,8 +2447,12 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
|||
}
|
||||
|
||||
this.setState({
|
||||
scrollX: normalizeScroll(this.state.scrollX - deltaX / this.state.zoom),
|
||||
scrollY: normalizeScroll(this.state.scrollY - deltaY / this.state.zoom),
|
||||
scrollX: normalizeScroll(
|
||||
this.state.scrollX - deltaX / this.state.zoom.value,
|
||||
),
|
||||
scrollY: normalizeScroll(
|
||||
this.state.scrollY - deltaY / this.state.zoom.value,
|
||||
),
|
||||
});
|
||||
});
|
||||
const teardown = withBatchedUpdates(
|
||||
|
@ -2491,7 +2489,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
|||
|
||||
if (gesture.pointers.size === 2) {
|
||||
gesture.lastCenter = getCenter(gesture.pointers);
|
||||
gesture.initialScale = this.state.zoom;
|
||||
gesture.initialScale = this.state.zoom.value;
|
||||
gesture.initialDistance = getDistance(
|
||||
Array.from(gesture.pointers.values()),
|
||||
);
|
||||
|
@ -2501,12 +2499,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
|||
private initialPointerDownState(
|
||||
event: React.PointerEvent<HTMLCanvasElement>,
|
||||
): PointerDownState {
|
||||
const origin = viewportCoordsToSceneCoords(
|
||||
event,
|
||||
this.state,
|
||||
this.canvas,
|
||||
window.devicePixelRatio,
|
||||
);
|
||||
const origin = viewportCoordsToSceneCoords(event, this.state);
|
||||
const selectedElements = getSelectedElements(
|
||||
this.scene.getElements(),
|
||||
this.state,
|
||||
|
@ -2790,7 +2783,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
|||
}
|
||||
|
||||
// How many pixels off the shape boundary we still consider a hit
|
||||
const threshold = 10 / this.state.zoom;
|
||||
const threshold = 10 / this.state.zoom.value;
|
||||
const [x1, y1, x2, y2] = getCommonBounds(selectedElements);
|
||||
return (
|
||||
point.x > x1 - threshold &&
|
||||
|
@ -2985,12 +2978,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
|||
return;
|
||||
}
|
||||
|
||||
const pointerCoords = viewportCoordsToSceneCoords(
|
||||
event,
|
||||
this.state,
|
||||
this.canvas,
|
||||
window.devicePixelRatio,
|
||||
);
|
||||
const pointerCoords = viewportCoordsToSceneCoords(event, this.state);
|
||||
const [gridX, gridY] = getGridPoint(
|
||||
pointerCoords.x,
|
||||
pointerCoords.y,
|
||||
|
@ -3212,7 +3200,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
|||
mutateElement(draggingElement, {
|
||||
points: simplify(
|
||||
[...(points as Point[]), [dx, dy]],
|
||||
0.7 / this.state.zoom,
|
||||
0.7 / this.state.zoom.value,
|
||||
),
|
||||
});
|
||||
} else {
|
||||
|
@ -3300,7 +3288,9 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
|||
const x = event.clientX;
|
||||
const dx = x - pointerDownState.lastCoords.x;
|
||||
this.setState({
|
||||
scrollX: normalizeScroll(this.state.scrollX - dx / this.state.zoom),
|
||||
scrollX: normalizeScroll(
|
||||
this.state.scrollX - dx / this.state.zoom.value,
|
||||
),
|
||||
});
|
||||
pointerDownState.lastCoords.x = x;
|
||||
return true;
|
||||
|
@ -3310,7 +3300,9 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
|||
const y = event.clientY;
|
||||
const dy = y - pointerDownState.lastCoords.y;
|
||||
this.setState({
|
||||
scrollY: normalizeScroll(this.state.scrollY - dy / this.state.zoom),
|
||||
scrollY: normalizeScroll(
|
||||
this.state.scrollY - dy / this.state.zoom.value,
|
||||
),
|
||||
});
|
||||
pointerDownState.lastCoords.y = y;
|
||||
return true;
|
||||
|
@ -3387,8 +3379,6 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
|||
const pointerCoords = viewportCoordsToSceneCoords(
|
||||
childEvent,
|
||||
this.state,
|
||||
this.canvas,
|
||||
window.devicePixelRatio,
|
||||
);
|
||||
|
||||
if (
|
||||
|
@ -3808,8 +3798,6 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
|||
const { x, y } = viewportCoordsToSceneCoords(
|
||||
{ clientX, clientY },
|
||||
this.state,
|
||||
this.canvas,
|
||||
window.devicePixelRatio,
|
||||
);
|
||||
|
||||
const elements = this.scene.getElements();
|
||||
|
@ -3885,7 +3873,6 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
|||
|
||||
const { deltaX, deltaY } = event;
|
||||
const { selectedElementIds, previousSelectedElementIds } = this.state;
|
||||
|
||||
// note that event.ctrlKey is necessary to handle pinch zooming
|
||||
if (event.metaKey || event.ctrlKey) {
|
||||
const sign = Math.sign(deltaY);
|
||||
|
@ -3903,8 +3890,12 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
|||
});
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
this.setState(({ zoom }) => ({
|
||||
zoom: getNormalizedZoom(zoom - delta / 100),
|
||||
zoom: getNewZoom(getNormalizedZoom(zoom.value - delta / 100), zoom, {
|
||||
x: cursorX,
|
||||
y: cursorY,
|
||||
}),
|
||||
selectedElementIds: {},
|
||||
previousSelectedElementIds:
|
||||
Object.keys(selectedElementIds).length !== 0
|
||||
|
@ -3920,14 +3911,14 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
|||
if (event.shiftKey) {
|
||||
this.setState(({ zoom, scrollX }) => ({
|
||||
// on Mac, shift+wheel tends to result in deltaX
|
||||
scrollX: normalizeScroll(scrollX - (deltaY || deltaX) / zoom),
|
||||
scrollX: normalizeScroll(scrollX - (deltaY || deltaX) / zoom.value),
|
||||
}));
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState(({ zoom, scrollX, scrollY }) => ({
|
||||
scrollX: normalizeScroll(scrollX - deltaX / zoom),
|
||||
scrollY: normalizeScroll(scrollY - deltaY / zoom),
|
||||
scrollX: normalizeScroll(scrollX - deltaX / zoom.value),
|
||||
scrollY: normalizeScroll(scrollY - deltaY / zoom.value),
|
||||
}));
|
||||
});
|
||||
|
||||
|
@ -3960,8 +3951,6 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
|||
const { x: viewportX, y: viewportY } = sceneCoordsToViewportCoords(
|
||||
{ sceneX: elementCenterX, sceneY: elementCenterY },
|
||||
appState,
|
||||
canvas,
|
||||
scale,
|
||||
);
|
||||
return { viewportX, viewportY, elementCenterX, elementCenterY };
|
||||
}
|
||||
|
@ -3975,8 +3964,6 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
|||
const pointer = viewportCoordsToSceneCoords(
|
||||
{ clientX: x, clientY: y },
|
||||
this.state,
|
||||
this.canvas,
|
||||
window.devicePixelRatio,
|
||||
);
|
||||
|
||||
if (isNaN(pointer.x) || isNaN(pointer.y)) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue