You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
78 lines
1.9 KiB
TypeScript
78 lines
1.9 KiB
TypeScript
4 years ago
|
import { AppState, PointerCoords, Zoom } from "../types";
|
||
5 years ago
|
import { ExcalidrawElement } from "../element/types";
|
||
4 years ago
|
import {
|
||
|
getCommonBounds,
|
||
|
getClosestElementBounds,
|
||
|
getVisibleElements,
|
||
|
} from "../element";
|
||
5 years ago
|
|
||
|
import {
|
||
|
sceneCoordsToViewportCoords,
|
||
|
viewportCoordsToSceneCoords,
|
||
|
} from "../utils";
|
||
5 years ago
|
|
||
1 year ago
|
const isOutsideViewPort = (appState: AppState, cords: Array<number>) => {
|
||
5 years ago
|
const [x1, y1, x2, y2] = cords;
|
||
|
const { x: viewportX1, y: viewportY1 } = sceneCoordsToViewportCoords(
|
||
|
{ sceneX: x1, sceneY: y1 },
|
||
|
appState,
|
||
|
);
|
||
|
const { x: viewportX2, y: viewportY2 } = sceneCoordsToViewportCoords(
|
||
|
{ sceneX: x2, sceneY: y2 },
|
||
|
appState,
|
||
|
);
|
||
|
return (
|
||
5 years ago
|
viewportX2 - viewportX1 > appState.width ||
|
||
|
viewportY2 - viewportY1 > appState.height
|
||
5 years ago
|
);
|
||
4 years ago
|
};
|
||
5 years ago
|
|
||
4 years ago
|
export const centerScrollOn = ({
|
||
|
scenePoint,
|
||
|
viewportDimensions,
|
||
|
zoom,
|
||
|
}: {
|
||
|
scenePoint: PointerCoords;
|
||
|
viewportDimensions: { height: number; width: number };
|
||
|
zoom: Zoom;
|
||
|
}) => {
|
||
|
return {
|
||
2 years ago
|
scrollX: viewportDimensions.width / 2 / zoom.value - scenePoint.x,
|
||
|
scrollY: viewportDimensions.height / 2 / zoom.value - scenePoint.y,
|
||
4 years ago
|
};
|
||
|
};
|
||
|
|
||
5 years ago
|
export const calculateScrollCenter = (
|
||
5 years ago
|
elements: readonly ExcalidrawElement[],
|
||
5 years ago
|
appState: AppState,
|
||
4 years ago
|
): { scrollX: number; scrollY: number } => {
|
||
4 years ago
|
elements = getVisibleElements(elements);
|
||
|
|
||
5 years ago
|
if (!elements.length) {
|
||
|
return {
|
||
4 years ago
|
scrollX: 0,
|
||
|
scrollY: 0,
|
||
5 years ago
|
};
|
||
|
}
|
||
5 years ago
|
let [x1, y1, x2, y2] = getCommonBounds(elements);
|
||
5 years ago
|
|
||
1 year ago
|
if (isOutsideViewPort(appState, [x1, y1, x2, y2])) {
|
||
5 years ago
|
[x1, y1, x2, y2] = getClosestElementBounds(
|
||
|
elements,
|
||
|
viewportCoordsToSceneCoords(
|
||
|
{ clientX: appState.scrollX, clientY: appState.scrollY },
|
||
|
appState,
|
||
|
),
|
||
|
);
|
||
|
}
|
||
5 years ago
|
|
||
|
const centerX = (x1 + x2) / 2;
|
||
|
const centerY = (y1 + y2) / 2;
|
||
|
|
||
4 years ago
|
return centerScrollOn({
|
||
|
scenePoint: { x: centerX, y: centerY },
|
||
|
viewportDimensions: { width: appState.width, height: appState.height },
|
||
|
zoom: appState.zoom,
|
||
|
});
|
||
5 years ago
|
};
|