Canvas zooming (#716)

* Zoom icons.

* Actions.

* Min zoom of 0 does not make sense.

* Zoom logic.

* Modify how zoom affects selection rendering.

* More precise scrollbar dimensions.

* Adjust elements visibility and scrollbars.

* Normalized canvas width and height.

* Apply zoom to resize test.

* [WIP] Zoom using canvas center as an origin.

* Undo zoom on `getScrollBars`.

* WIP: center zoom origin via scroll

* This was wrong for sure.

* Finish scaling using center as origin.

* Almost there.

* Scroll offset should be not part of zoom transforms.

* Better naming.

* Wheel movement should be the same no matter the zoom level.

* Panning movement should be the same no matter the zoom level.

* Fix elements pasting.

* Fix text WYSIWGT.

* Fix scrollbars and visibility.
This commit is contained in:
Enzo Ferey 2020-02-15 21:03:32 +01:00 committed by GitHub
parent dd2d7e1a88
commit c7ff4c2ed6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 612 additions and 272 deletions

View file

@ -9,8 +9,15 @@ export function getScrollBars(
elements: readonly ExcalidrawElement[],
viewportWidth: number,
viewportHeight: number,
scrollX: number,
scrollY: number,
{
scrollX,
scrollY,
zoom,
}: {
scrollX: number;
scrollY: number;
zoom: number;
},
) {
// This is the bounding box of all the elements
const [
@ -20,11 +27,18 @@ export function getScrollBars(
elementsMaxY,
] = getCommonBounds(elements);
// Apply zoom
const viewportWidthWithZoom = viewportWidth / zoom;
const viewportHeightWithZoom = viewportHeight / zoom;
const viewportWidthDiff = viewportWidth - viewportWidthWithZoom;
const viewportHeightDiff = viewportHeight - viewportHeightWithZoom;
// The viewport is the rectangle currently visible for the user
const viewportMinX = -scrollX;
const viewportMinY = -scrollY;
const viewportMaxX = -scrollX + viewportWidth;
const viewportMaxY = -scrollY + viewportHeight;
const viewportMinX = -scrollX + viewportWidthDiff / 2;
const viewportMinY = -scrollY + viewportHeightDiff / 2;
const viewportMaxX = viewportMinX + viewportWidthWithZoom;
const viewportMaxY = viewportMinY + viewportHeightWithZoom;
// The scene is the bounding box of both the elements and viewport
const sceneMinX = Math.min(elementsMinX, viewportMinX);
@ -74,16 +88,21 @@ export function isOverScrollBars(
y: number,
viewportWidth: number,
viewportHeight: number,
scrollX: number,
scrollY: number,
) {
const scrollBars = getScrollBars(
elements,
viewportWidth,
viewportHeight,
{
scrollX,
scrollY,
);
zoom,
}: {
scrollX: number;
scrollY: number;
zoom: number;
},
) {
const scrollBars = getScrollBars(elements, viewportWidth, viewportHeight, {
scrollX,
scrollY,
zoom,
});
const [isOverHorizontalScrollBar, isOverVerticalScrollBar] = [
scrollBars.horizontal,