fix: Visibility and zooming when canvas offset is not zero (#2534)
This commit is contained in:
parent
60864ace54
commit
4c7b1a2269
@ -95,6 +95,7 @@ export const actionZoomIn = register({
|
|||||||
const zoom = getNewZoom(
|
const zoom = getNewZoom(
|
||||||
getNormalizedZoom(appState.zoom.value + ZOOM_STEP),
|
getNormalizedZoom(appState.zoom.value + ZOOM_STEP),
|
||||||
appState.zoom,
|
appState.zoom,
|
||||||
|
{ left: appState.offsetLeft, top: appState.offsetTop },
|
||||||
{ x: appState.width / 2, y: appState.height / 2 },
|
{ x: appState.width / 2, y: appState.height / 2 },
|
||||||
);
|
);
|
||||||
trackEvent(EVENT_ACTION, "zoom", "in", zoom.value * 100);
|
trackEvent(EVENT_ACTION, "zoom", "in", zoom.value * 100);
|
||||||
@ -128,6 +129,7 @@ export const actionZoomOut = register({
|
|||||||
const zoom = getNewZoom(
|
const zoom = getNewZoom(
|
||||||
getNormalizedZoom(appState.zoom.value - ZOOM_STEP),
|
getNormalizedZoom(appState.zoom.value - ZOOM_STEP),
|
||||||
appState.zoom,
|
appState.zoom,
|
||||||
|
{ left: appState.offsetLeft, top: appState.offsetTop },
|
||||||
{ x: appState.width / 2, y: appState.height / 2 },
|
{ x: appState.width / 2, y: appState.height / 2 },
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -163,10 +165,15 @@ export const actionResetZoom = register({
|
|||||||
return {
|
return {
|
||||||
appState: {
|
appState: {
|
||||||
...appState,
|
...appState,
|
||||||
zoom: getNewZoom(1 as NormalizedZoomValue, appState.zoom, {
|
zoom: getNewZoom(
|
||||||
x: appState.width / 2,
|
1 as NormalizedZoomValue,
|
||||||
y: appState.height / 2,
|
appState.zoom,
|
||||||
}),
|
{ left: appState.offsetLeft, top: appState.offsetTop },
|
||||||
|
{
|
||||||
|
x: appState.width / 2,
|
||||||
|
y: appState.height / 2,
|
||||||
|
},
|
||||||
|
),
|
||||||
},
|
},
|
||||||
commitToHistory: false,
|
commitToHistory: false,
|
||||||
};
|
};
|
||||||
@ -223,7 +230,10 @@ const zoomToFitElements = (
|
|||||||
width: appState.width,
|
width: appState.width,
|
||||||
height: appState.height,
|
height: appState.height,
|
||||||
});
|
});
|
||||||
const newZoom = getNewZoom(zoomValue, appState.zoom);
|
const newZoom = getNewZoom(zoomValue, appState.zoom, {
|
||||||
|
left: appState.offsetLeft,
|
||||||
|
top: appState.offsetTop,
|
||||||
|
});
|
||||||
const action = zoomToSelection ? "selection" : "fit";
|
const action = zoomToSelection ? "selection" : "fit";
|
||||||
|
|
||||||
const [x1, y1, x2, y2] = commonBounds;
|
const [x1, y1, x2, y2] = commonBounds;
|
||||||
|
@ -1423,10 +1423,11 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
|||||||
|
|
||||||
private onGestureChange = withBatchedUpdates((event: GestureEvent) => {
|
private onGestureChange = withBatchedUpdates((event: GestureEvent) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
this.setState(({ zoom }) => ({
|
this.setState(({ zoom, offsetLeft, offsetTop }) => ({
|
||||||
zoom: getNewZoom(
|
zoom: getNewZoom(
|
||||||
getNormalizedZoom(gesture.initialScale! * event.scale),
|
getNormalizedZoom(gesture.initialScale! * event.scale),
|
||||||
zoom,
|
zoom,
|
||||||
|
{ left: offsetLeft, top: offsetTop },
|
||||||
{ x: cursorX, y: cursorY },
|
{ x: cursorX, y: cursorY },
|
||||||
),
|
),
|
||||||
}));
|
}));
|
||||||
@ -1750,12 +1751,13 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
|||||||
const distance = getDistance(Array.from(gesture.pointers.values()));
|
const distance = getDistance(Array.from(gesture.pointers.values()));
|
||||||
const scaleFactor = distance / gesture.initialDistance!;
|
const scaleFactor = distance / gesture.initialDistance!;
|
||||||
|
|
||||||
this.setState(({ zoom, scrollX, scrollY }) => ({
|
this.setState(({ zoom, scrollX, scrollY, offsetLeft, offsetTop }) => ({
|
||||||
scrollX: normalizeScroll(scrollX + deltaX / zoom.value),
|
scrollX: normalizeScroll(scrollX + deltaX / zoom.value),
|
||||||
scrollY: normalizeScroll(scrollY + deltaY / zoom.value),
|
scrollY: normalizeScroll(scrollY + deltaY / zoom.value),
|
||||||
zoom: getNewZoom(
|
zoom: getNewZoom(
|
||||||
getNormalizedZoom(gesture.initialScale! * scaleFactor),
|
getNormalizedZoom(gesture.initialScale! * scaleFactor),
|
||||||
zoom,
|
zoom,
|
||||||
|
{ left: offsetLeft, top: offsetTop },
|
||||||
center,
|
center,
|
||||||
),
|
),
|
||||||
shouldCacheIgnoreZoom: true,
|
shouldCacheIgnoreZoom: true,
|
||||||
@ -2586,9 +2588,9 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
/* If arrow is pre-arrowheads, it will have undefined for both start and end arrowheads.
|
/* If arrow is pre-arrowheads, it will have undefined for both start and end arrowheads.
|
||||||
If so, we want it to be null for start and "arrow" for end. If the linear item is not
|
If so, we want it to be null for start and "arrow" for end. If the linear item is not
|
||||||
an arrow, we want it to be null for both. Otherwise, we want it to use the
|
an arrow, we want it to be null for both. Otherwise, we want it to use the
|
||||||
values from appState. */
|
values from appState. */
|
||||||
|
|
||||||
const { currentItemStartArrowhead, currentItemEndArrowhead } = this.state;
|
const { currentItemStartArrowhead, currentItemEndArrowhead } = this.state;
|
||||||
const [startArrowhead, endArrowhead] =
|
const [startArrowhead, endArrowhead] =
|
||||||
@ -3702,11 +3704,16 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
|||||||
}, 1000);
|
}, 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setState(({ zoom }) => ({
|
this.setState(({ zoom, offsetLeft, offsetTop }) => ({
|
||||||
zoom: getNewZoom(getNormalizedZoom(zoom.value - delta / 100), zoom, {
|
zoom: getNewZoom(
|
||||||
x: cursorX,
|
getNormalizedZoom(zoom.value - delta / 100),
|
||||||
y: cursorY,
|
zoom,
|
||||||
}),
|
{ left: offsetLeft, top: offsetTop },
|
||||||
|
{
|
||||||
|
x: cursorX,
|
||||||
|
y: cursorY,
|
||||||
|
},
|
||||||
|
),
|
||||||
selectedElementIds: {},
|
selectedElementIds: {},
|
||||||
previousSelectedElementIds:
|
previousSelectedElementIds:
|
||||||
Object.keys(selectedElementIds).length !== 0
|
Object.keys(selectedElementIds).length !== 0
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
Guidelines for changelog:
|
Guidelines for changelog:
|
||||||
The change should be grouped under one of the below section and must contain PR link.
|
The change should be grouped under one of the below section and must contain PR link.
|
||||||
@ -14,6 +15,7 @@ Please add the latest change on the top under the correct section.
|
|||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
- Add zoom to selection [#2522](https://github.com/excalidraw/excalidraw/pull/2522)
|
- Add zoom to selection [#2522](https://github.com/excalidraw/excalidraw/pull/2522)
|
||||||
- Insert Library items in the middle of the screen [#2527](https://github.com/excalidraw/excalidraw/pull/2527)
|
- Insert Library items in the middle of the screen [#2527](https://github.com/excalidraw/excalidraw/pull/2527)
|
||||||
- Show shortcut context menu [#2501](https://github.com/excalidraw/excalidraw/pull/2501)
|
- Show shortcut context menu [#2501](https://github.com/excalidraw/excalidraw/pull/2501)
|
||||||
@ -23,9 +25,12 @@ Please add the latest change on the top under the correct section.
|
|||||||
- Support CSV graphs and improve the look and feel [#2495](https://github.com/excalidraw/excalidraw/pull/2495)
|
- Support CSV graphs and improve the look and feel [#2495](https://github.com/excalidraw/excalidraw/pull/2495)
|
||||||
|
|
||||||
### Fixes
|
### Fixes
|
||||||
|
|
||||||
|
- Fix element visibility and zoom on cursor when canvas offset isn't 0. [#2534](https://github.com/excalidraw/excalidraw/pull/2534)
|
||||||
- Fix Library Menu Layout [#2502](https://github.com/excalidraw/excalidraw/pull/2502)
|
- Fix Library Menu Layout [#2502](https://github.com/excalidraw/excalidraw/pull/2502)
|
||||||
|
|
||||||
### Improvements
|
### Improvements
|
||||||
|
|
||||||
- Add tooltip with icon for embedding scenes [#2532](https://github.com/excalidraw/excalidraw/pull/2532)
|
- Add tooltip with icon for embedding scenes [#2532](https://github.com/excalidraw/excalidraw/pull/2532)
|
||||||
- RTL support for the stats dialog [#2530](https://github.com/excalidraw/excalidraw/pull/2530)
|
- RTL support for the stats dialog [#2530](https://github.com/excalidraw/excalidraw/pull/2530)
|
||||||
- Expand canvas padding based on zoom. [#2515](https://github.com/excalidraw/excalidraw/pull/2515)
|
- Expand canvas padding based on zoom. [#2515](https://github.com/excalidraw/excalidraw/pull/2515)
|
||||||
@ -33,11 +38,13 @@ Please add the latest change on the top under the correct section.
|
|||||||
- Hide stats and scrollToContent-button when mobile menus open [#2509](https://github.com/excalidraw/excalidraw/pull/2509)
|
- Hide stats and scrollToContent-button when mobile menus open [#2509](https://github.com/excalidraw/excalidraw/pull/2509)
|
||||||
|
|
||||||
### Chore
|
### Chore
|
||||||
|
|
||||||
- Bump ini from 1.3.5 to 1.3.7 in /src/packages/excalidraw [#2500](https://github.com/excalidraw/excalidraw/pull/2500)
|
- Bump ini from 1.3.5 to 1.3.7 in /src/packages/excalidraw [#2500](https://github.com/excalidraw/excalidraw/pull/2500)
|
||||||
|
|
||||||
## 0.1.1
|
## 0.1.1
|
||||||
|
|
||||||
#### Fix
|
#### Fix
|
||||||
|
|
||||||
- Update the homepage URL so it redirects to correct readme [#2498](https://github.com/excalidraw/excalidraw/pull/2498)
|
- Update the homepage URL so it redirects to correct readme [#2498](https://github.com/excalidraw/excalidraw/pull/2498)
|
||||||
|
|
||||||
## 0.1.0
|
## 0.1.0
|
||||||
|
@ -763,13 +763,20 @@ const isVisibleElement = (
|
|||||||
) => {
|
) => {
|
||||||
const [x1, y1, x2, y2] = getElementBounds(element); // scene coordinates
|
const [x1, y1, x2, y2] = getElementBounds(element); // scene coordinates
|
||||||
const topLeftSceneCoords = viewportCoordsToSceneCoords(
|
const topLeftSceneCoords = viewportCoordsToSceneCoords(
|
||||||
{ clientX: 0, clientY: 0 },
|
{
|
||||||
|
clientX: viewTransformations.offsetLeft,
|
||||||
|
clientY: viewTransformations.offsetTop,
|
||||||
|
},
|
||||||
viewTransformations,
|
viewTransformations,
|
||||||
);
|
);
|
||||||
const bottomRightSceneCoords = viewportCoordsToSceneCoords(
|
const bottomRightSceneCoords = viewportCoordsToSceneCoords(
|
||||||
{ clientX: canvasWidth, clientY: canvasHeight },
|
{
|
||||||
|
clientX: viewTransformations.offsetLeft + canvasWidth,
|
||||||
|
clientY: viewTransformations.offsetTop + canvasHeight,
|
||||||
|
},
|
||||||
viewTransformations,
|
viewTransformations,
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
topLeftSceneCoords.x <= x2 &&
|
topLeftSceneCoords.x <= x2 &&
|
||||||
topLeftSceneCoords.y <= y2 &&
|
topLeftSceneCoords.y <= y2 &&
|
||||||
|
@ -3,6 +3,7 @@ import { NormalizedZoomValue, PointerCoords, Zoom } from "../types";
|
|||||||
export const getNewZoom = (
|
export const getNewZoom = (
|
||||||
newZoomValue: NormalizedZoomValue,
|
newZoomValue: NormalizedZoomValue,
|
||||||
prevZoom: Zoom,
|
prevZoom: Zoom,
|
||||||
|
canvasOffset: { left: number; top: number },
|
||||||
zoomOnViewportPoint: PointerCoords = { x: 0, y: 0 },
|
zoomOnViewportPoint: PointerCoords = { x: 0, y: 0 },
|
||||||
): Zoom => {
|
): Zoom => {
|
||||||
return {
|
return {
|
||||||
@ -10,11 +11,13 @@ export const getNewZoom = (
|
|||||||
translation: {
|
translation: {
|
||||||
x:
|
x:
|
||||||
zoomOnViewportPoint.x -
|
zoomOnViewportPoint.x -
|
||||||
(zoomOnViewportPoint.x - prevZoom.translation.x) *
|
canvasOffset.left -
|
||||||
|
(zoomOnViewportPoint.x - canvasOffset.left - prevZoom.translation.x) *
|
||||||
(newZoomValue / prevZoom.value),
|
(newZoomValue / prevZoom.value),
|
||||||
y:
|
y:
|
||||||
zoomOnViewportPoint.y -
|
zoomOnViewportPoint.y -
|
||||||
(zoomOnViewportPoint.y - prevZoom.translation.y) *
|
canvasOffset.top -
|
||||||
|
(zoomOnViewportPoint.y - canvasOffset.top - prevZoom.translation.y) *
|
||||||
(newZoomValue / prevZoom.value),
|
(newZoomValue / prevZoom.value),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user