mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-04-14 16:40:58 -04:00
feat: add flipping when resizing multiple elements
This commit is contained in:
parent
b9ba407f96
commit
a941173be4
1 changed files with 39 additions and 23 deletions
|
@ -632,7 +632,17 @@ const resizeMultipleElements = (
|
||||||
? [midX, midY]
|
? [midX, midY]
|
||||||
: mapDirectionsToAnchors[direction];
|
: mapDirectionsToAnchors[direction];
|
||||||
|
|
||||||
const mapDirectionsToPointerSides: Record<
|
const scale =
|
||||||
|
Math.max(
|
||||||
|
Math.abs(pointerX - anchorX) / (maxX - minX),
|
||||||
|
Math.abs(pointerY - anchorY) / (maxY - minY),
|
||||||
|
) * (shouldResizeFromCenter ? 2 : 1);
|
||||||
|
|
||||||
|
if (scale === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const mapDirectionsToFlipConditions: Record<
|
||||||
typeof direction,
|
typeof direction,
|
||||||
[x: boolean, y: boolean]
|
[x: boolean, y: boolean]
|
||||||
> = {
|
> = {
|
||||||
|
@ -642,37 +652,36 @@ const resizeMultipleElements = (
|
||||||
nw: [pointerX <= anchorX, pointerY <= anchorY],
|
nw: [pointerX <= anchorX, pointerY <= anchorY],
|
||||||
};
|
};
|
||||||
|
|
||||||
// pointer side relative to anchor
|
// to flip an element:
|
||||||
const [pointerSideX, pointerSideY] = mapDirectionsToPointerSides[
|
// 1. mirror x,y relative to the anchor over the x/y/both axis (flipFactor)
|
||||||
|
// 2. shift by the width/height/both (flipAdjust) or mirror points in case of
|
||||||
|
// linear/free draw element (hasPoints)
|
||||||
|
// 3. adjust the angle
|
||||||
|
const [flipFactorX, flipFactorY] = mapDirectionsToFlipConditions[
|
||||||
direction
|
direction
|
||||||
].map((condition) => (condition ? 1 : -1));
|
].map((condition) => (condition ? 1 : -1));
|
||||||
|
const isFlippedByX = flipFactorX < 0;
|
||||||
// stop resizing if a pointer is on the other side of selection
|
const isFlippedByY = flipFactorY < 0;
|
||||||
if (pointerSideX < 0 && pointerSideY < 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const scale =
|
|
||||||
Math.max(
|
|
||||||
(pointerSideX * Math.abs(pointerX - anchorX)) / (maxX - minX),
|
|
||||||
(pointerSideY * Math.abs(pointerY - anchorY)) / (maxY - minY),
|
|
||||||
) * (shouldResizeFromCenter ? 2 : 1);
|
|
||||||
|
|
||||||
if (scale === 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
targetElements.forEach((element) => {
|
targetElements.forEach((element) => {
|
||||||
const width = element.orig.width * scale;
|
const width = element.orig.width * scale;
|
||||||
const height = element.orig.height * scale;
|
const height = element.orig.height * scale;
|
||||||
const x = anchorX + (element.orig.x - anchorX) * scale;
|
const angle = element.orig.angle * flipFactorX * flipFactorY;
|
||||||
const y = anchorY + (element.orig.y - anchorY) * scale;
|
|
||||||
|
const hasPoints =
|
||||||
|
isLinearElement(element.orig) || isFreeDrawElement(element.orig);
|
||||||
|
const offsetX = element.orig.x - anchorX;
|
||||||
|
const offsetY = element.orig.y - anchorY;
|
||||||
|
const flipAdjustX = isFlippedByX && !hasPoints ? width : 0;
|
||||||
|
const flipAdjustY = isFlippedByY && !hasPoints ? height : 0;
|
||||||
|
const x = anchorX + flipFactorX * (offsetX * scale + flipAdjustX);
|
||||||
|
const y = anchorY + flipFactorY * (offsetY * scale + flipAdjustY);
|
||||||
|
|
||||||
// readjust points for linear & free draw elements
|
// readjust points for linear & free draw elements
|
||||||
const rescaledPoints = rescalePointsInElement(
|
const rescaledPoints = rescalePointsInElement(
|
||||||
element.orig,
|
element.orig,
|
||||||
width,
|
width * flipFactorX,
|
||||||
height,
|
height * flipFactorY,
|
||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -681,6 +690,7 @@ const resizeMultipleElements = (
|
||||||
height: number;
|
height: number;
|
||||||
x: number;
|
x: number;
|
||||||
y: number;
|
y: number;
|
||||||
|
angle: number;
|
||||||
points?: Point[];
|
points?: Point[];
|
||||||
fontSize?: number;
|
fontSize?: number;
|
||||||
baseline?: number;
|
baseline?: number;
|
||||||
|
@ -689,10 +699,15 @@ const resizeMultipleElements = (
|
||||||
height,
|
height,
|
||||||
x,
|
x,
|
||||||
y,
|
y,
|
||||||
|
angle,
|
||||||
...rescaledPoints,
|
...rescaledPoints,
|
||||||
};
|
};
|
||||||
|
|
||||||
let boundTextUpdates: { fontSize: number; baseline: number } | null = null;
|
let boundTextUpdates: {
|
||||||
|
angle: number;
|
||||||
|
fontSize: number;
|
||||||
|
baseline: number;
|
||||||
|
} | null = null;
|
||||||
|
|
||||||
const boundTextElement = getBoundTextElement(element.latest);
|
const boundTextElement = getBoundTextElement(element.latest);
|
||||||
|
|
||||||
|
@ -715,6 +730,7 @@ const resizeMultipleElements = (
|
||||||
|
|
||||||
if (boundTextElement) {
|
if (boundTextElement) {
|
||||||
boundTextUpdates = {
|
boundTextUpdates = {
|
||||||
|
angle,
|
||||||
fontSize: textMeasurements.size,
|
fontSize: textMeasurements.size,
|
||||||
baseline: textMeasurements.baseline,
|
baseline: textMeasurements.baseline,
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Reference in a new issue