mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
cache initial panel position
This commit is contained in:
parent
1c4b3cc0b1
commit
eff67c5e01
1 changed files with 48 additions and 33 deletions
|
@ -1,4 +1,4 @@
|
||||||
import { type ReactNode, useEffect, useMemo, useRef } from "react";
|
import { type ReactNode, useEffect, useMemo, useRef, useState } from "react";
|
||||||
|
|
||||||
import { pointFrom, pointRotateRads } from "@excalidraw/math";
|
import { pointFrom, pointRotateRads } from "@excalidraw/math";
|
||||||
|
|
||||||
|
@ -118,13 +118,14 @@ const Panel = ({
|
||||||
app: App;
|
app: App;
|
||||||
elements: ExcalidrawElement[];
|
elements: ExcalidrawElement[];
|
||||||
}) => {
|
}) => {
|
||||||
let [x1, y2, cx, cy] = [0, 0, 0, 0];
|
|
||||||
let rotatedBottomLeft = [0, 0];
|
|
||||||
|
|
||||||
const { generic, linear } = getSwitchableTypeFromElements(elements);
|
const { generic, linear } = getSwitchableTypeFromElements(elements);
|
||||||
|
|
||||||
const genericElements = generic ? getGenericSwitchableElements(elements) : [];
|
const genericElements = useMemo(() => {
|
||||||
const linearElements = linear ? getLinearSwitchableElements(elements) : [];
|
return generic ? getGenericSwitchableElements(elements) : [];
|
||||||
|
}, [generic, elements]);
|
||||||
|
const linearElements = useMemo(() => {
|
||||||
|
return linear ? getLinearSwitchableElements(elements) : [];
|
||||||
|
}, [linear, elements]);
|
||||||
|
|
||||||
const sameType = generic
|
const sameType = generic
|
||||||
? genericElements.every(
|
? genericElements.every(
|
||||||
|
@ -134,34 +135,46 @@ const Panel = ({
|
||||||
? linearElements.every((element) => element.type === linearElements[0].type)
|
? linearElements.every((element) => element.type === linearElements[0].type)
|
||||||
: false;
|
: false;
|
||||||
|
|
||||||
|
const [panelPosition, setPanelPosition] = useState({ x: 0, y: 0 });
|
||||||
|
const selectedElementsRef = useRef("");
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const elements = [...genericElements, ...linearElements].sort((a, b) =>
|
||||||
|
a.id.localeCompare(b.id),
|
||||||
|
);
|
||||||
|
const elementsRef = elements.join(",");
|
||||||
|
|
||||||
|
if (elementsRef === selectedElementsRef.current) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
selectedElementsRef.current = elementsRef;
|
||||||
|
|
||||||
|
let bottomLeft;
|
||||||
|
|
||||||
if (elements.length === 1) {
|
if (elements.length === 1) {
|
||||||
[x1, , , y2, cx, cy] = getElementAbsoluteCoords(
|
const [x1, , , y2, cx, cy] = getElementAbsoluteCoords(
|
||||||
elements[0],
|
elements[0],
|
||||||
app.scene.getNonDeletedElementsMap(),
|
app.scene.getNonDeletedElementsMap(),
|
||||||
);
|
);
|
||||||
|
bottomLeft = pointRotateRads(
|
||||||
rotatedBottomLeft = pointRotateRads(
|
|
||||||
pointFrom(x1, y2),
|
pointFrom(x1, y2),
|
||||||
pointFrom(cx, cy),
|
pointFrom(cx, cy),
|
||||||
elements[0].angle,
|
elements[0].angle,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
const { minX, maxY, midX, midY } = getCommonBoundingBox(elements);
|
const { minX, maxY } = getCommonBoundingBox(elements);
|
||||||
x1 = minX;
|
bottomLeft = pointFrom(minX, maxY);
|
||||||
y2 = maxY;
|
|
||||||
cx = midX;
|
|
||||||
cy = midY;
|
|
||||||
rotatedBottomLeft = pointFrom(x1, y2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const { x, y } = sceneCoordsToViewportCoords(
|
const { x, y } = sceneCoordsToViewportCoords(
|
||||||
{
|
{ sceneX: bottomLeft[0], sceneY: bottomLeft[1] },
|
||||||
sceneX: rotatedBottomLeft[0],
|
|
||||||
sceneY: rotatedBottomLeft[1],
|
|
||||||
},
|
|
||||||
app.state,
|
app.state,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
setPanelPosition({ x, y });
|
||||||
|
}, [genericElements, linearElements, app.scene, app.state]);
|
||||||
|
|
||||||
const SHAPES: [string, string, ReactNode][] = linear
|
const SHAPES: [string, string, ReactNode][] = linear
|
||||||
? [
|
? [
|
||||||
["arrow", "5", ArrowIcon],
|
["arrow", "5", ArrowIcon],
|
||||||
|
@ -180,9 +193,11 @@ const Panel = ({
|
||||||
style={{
|
style={{
|
||||||
position: "absolute",
|
position: "absolute",
|
||||||
top: `${
|
top: `${
|
||||||
y + (GAP_VERTICAL + 8) * app.state.zoom.value - app.state.offsetTop
|
panelPosition.y +
|
||||||
|
(GAP_VERTICAL + 8) * app.state.zoom.value -
|
||||||
|
app.state.offsetTop
|
||||||
}px`,
|
}px`,
|
||||||
left: `${x - app.state.offsetLeft - GAP_HORIZONTAL}px`,
|
left: `${panelPosition.x - app.state.offsetLeft - GAP_HORIZONTAL}px`,
|
||||||
zIndex: 2,
|
zIndex: 2,
|
||||||
}}
|
}}
|
||||||
className="ShapeSwitch__Panel"
|
className="ShapeSwitch__Panel"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue