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";
|
||||
|
||||
|
@ -118,13 +118,14 @@ const Panel = ({
|
|||
app: App;
|
||||
elements: ExcalidrawElement[];
|
||||
}) => {
|
||||
let [x1, y2, cx, cy] = [0, 0, 0, 0];
|
||||
let rotatedBottomLeft = [0, 0];
|
||||
|
||||
const { generic, linear } = getSwitchableTypeFromElements(elements);
|
||||
|
||||
const genericElements = generic ? getGenericSwitchableElements(elements) : [];
|
||||
const linearElements = linear ? getLinearSwitchableElements(elements) : [];
|
||||
const genericElements = useMemo(() => {
|
||||
return generic ? getGenericSwitchableElements(elements) : [];
|
||||
}, [generic, elements]);
|
||||
const linearElements = useMemo(() => {
|
||||
return linear ? getLinearSwitchableElements(elements) : [];
|
||||
}, [linear, elements]);
|
||||
|
||||
const sameType = generic
|
||||
? genericElements.every(
|
||||
|
@ -134,34 +135,46 @@ const Panel = ({
|
|||
? linearElements.every((element) => element.type === linearElements[0].type)
|
||||
: 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) {
|
||||
[x1, , , y2, cx, cy] = getElementAbsoluteCoords(
|
||||
const [x1, , , y2, cx, cy] = getElementAbsoluteCoords(
|
||||
elements[0],
|
||||
app.scene.getNonDeletedElementsMap(),
|
||||
);
|
||||
|
||||
rotatedBottomLeft = pointRotateRads(
|
||||
bottomLeft = pointRotateRads(
|
||||
pointFrom(x1, y2),
|
||||
pointFrom(cx, cy),
|
||||
elements[0].angle,
|
||||
);
|
||||
} else {
|
||||
const { minX, maxY, midX, midY } = getCommonBoundingBox(elements);
|
||||
x1 = minX;
|
||||
y2 = maxY;
|
||||
cx = midX;
|
||||
cy = midY;
|
||||
rotatedBottomLeft = pointFrom(x1, y2);
|
||||
const { minX, maxY } = getCommonBoundingBox(elements);
|
||||
bottomLeft = pointFrom(minX, maxY);
|
||||
}
|
||||
|
||||
const { x, y } = sceneCoordsToViewportCoords(
|
||||
{
|
||||
sceneX: rotatedBottomLeft[0],
|
||||
sceneY: rotatedBottomLeft[1],
|
||||
},
|
||||
{ sceneX: bottomLeft[0], sceneY: bottomLeft[1] },
|
||||
app.state,
|
||||
);
|
||||
|
||||
setPanelPosition({ x, y });
|
||||
}, [genericElements, linearElements, app.scene, app.state]);
|
||||
|
||||
const SHAPES: [string, string, ReactNode][] = linear
|
||||
? [
|
||||
["arrow", "5", ArrowIcon],
|
||||
|
@ -180,9 +193,11 @@ const Panel = ({
|
|||
style={{
|
||||
position: "absolute",
|
||||
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`,
|
||||
left: `${x - app.state.offsetLeft - GAP_HORIZONTAL}px`,
|
||||
left: `${panelPosition.x - app.state.offsetLeft - GAP_HORIZONTAL}px`,
|
||||
zIndex: 2,
|
||||
}}
|
||||
className="ShapeSwitch__Panel"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue