mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
scroll the closest element to center (#1670)
Co-authored-by: Sanghyeon Lee <yongdamsh@gmail.com>
This commit is contained in:
parent
0db7ac78c4
commit
fa359034c5
10 changed files with 100 additions and 15 deletions
|
@ -1,12 +1,43 @@
|
|||
import { FlooredNumber } from "../types";
|
||||
import { AppState, FlooredNumber } from "../types";
|
||||
import { ExcalidrawElement } from "../element/types";
|
||||
import { getCommonBounds } from "../element";
|
||||
import { getCommonBounds, getClosestElementBounds } from "../element";
|
||||
|
||||
import {
|
||||
sceneCoordsToViewportCoords,
|
||||
viewportCoordsToSceneCoords,
|
||||
} from "../utils";
|
||||
|
||||
export const normalizeScroll = (pos: number) =>
|
||||
Math.floor(pos) as FlooredNumber;
|
||||
|
||||
function isOutsideViewPort(
|
||||
appState: AppState,
|
||||
canvas: HTMLCanvasElement | null,
|
||||
cords: Array<number>,
|
||||
) {
|
||||
const [x1, y1, x2, y2] = cords;
|
||||
const { x: viewportX1, y: viewportY1 } = sceneCoordsToViewportCoords(
|
||||
{ sceneX: x1, sceneY: y1 },
|
||||
appState,
|
||||
canvas,
|
||||
window.devicePixelRatio,
|
||||
);
|
||||
const { x: viewportX2, y: viewportY2 } = sceneCoordsToViewportCoords(
|
||||
{ sceneX: x2, sceneY: y2 },
|
||||
appState,
|
||||
canvas,
|
||||
window.devicePixelRatio,
|
||||
);
|
||||
return (
|
||||
viewportX2 - viewportX1 > window.innerWidth ||
|
||||
viewportY2 - viewportY1 > window.innerHeight
|
||||
);
|
||||
}
|
||||
|
||||
export const calculateScrollCenter = (
|
||||
elements: readonly ExcalidrawElement[],
|
||||
appState: AppState,
|
||||
canvas: HTMLCanvasElement | null,
|
||||
): { scrollX: FlooredNumber; scrollY: FlooredNumber } => {
|
||||
if (!elements.length) {
|
||||
return {
|
||||
|
@ -14,8 +45,19 @@ export const calculateScrollCenter = (
|
|||
scrollY: normalizeScroll(0),
|
||||
};
|
||||
}
|
||||
|
||||
const [x1, y1, x2, y2] = getCommonBounds(elements);
|
||||
const scale = window.devicePixelRatio;
|
||||
let [x1, y1, x2, y2] = getCommonBounds(elements);
|
||||
if (isOutsideViewPort(appState, canvas, [x1, y1, x2, y2])) {
|
||||
[x1, y1, x2, y2] = getClosestElementBounds(
|
||||
elements,
|
||||
viewportCoordsToSceneCoords(
|
||||
{ clientX: appState.scrollX, clientY: appState.scrollY },
|
||||
appState,
|
||||
canvas,
|
||||
scale,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
const centerX = (x1 + x2) / 2;
|
||||
const centerY = (y1 + y2) / 2;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue