fix: Visibility and zooming when canvas offset is not zero (#2534)

This commit is contained in:
João Forja 2020-12-14 14:14:56 +00:00 committed by GitHub
parent 60864ace54
commit 4c7b1a2269
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 53 additions and 19 deletions

View File

@ -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(
1 as NormalizedZoomValue,
appState.zoom,
{ left: appState.offsetLeft, top: appState.offsetTop },
{
x: appState.width / 2, x: appState.width / 2,
y: appState.height / 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;

View File

@ -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,
@ -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(
getNormalizedZoom(zoom.value - delta / 100),
zoom,
{ left: offsetLeft, top: offsetTop },
{
x: cursorX, x: cursorX,
y: cursorY, y: cursorY,
}), },
),
selectedElementIds: {}, selectedElementIds: {},
previousSelectedElementIds: previousSelectedElementIds:
Object.keys(selectedElementIds).length !== 0 Object.keys(selectedElementIds).length !== 0

View File

@ -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

View File

@ -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 &&

View File

@ -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),
}, },
}; };