From c3b83fba385cc0455cb1fa46f95259852eec8af0 Mon Sep 17 00:00:00 2001 From: Daishi Kato Date: Tue, 7 Apr 2020 23:04:20 +0900 Subject: [PATCH] fix detecting rotated elements with selection (#1273) * fix #1232 * Update src/element/bounds.ts * prefer arrow functions * fix merging Co-authored-by: Lipis --- src/element/bounds.ts | 40 +++++++++++++++++++++++++--------------- src/element/index.ts | 1 + src/scene/selection.ts | 11 ++++------- 3 files changed, 30 insertions(+), 22 deletions(-) diff --git a/src/element/bounds.ts b/src/element/bounds.ts index df492766..9a66cf6a 100644 --- a/src/element/bounds.ts +++ b/src/element/bounds.ts @@ -188,9 +188,26 @@ export function getArrowPoints( return [x2, y2, x3, y3, x4, y4]; } -export function getCommonBounds( +export const getElementBounds = ( + element: ExcalidrawElement, +): [number, number, number, number] => { + const [x1, y1, x2, y2] = getElementAbsoluteCoords(element); + const cx = (x1 + x2) / 2; + const cy = (y1 + y2) / 2; + const [x11, y11] = rotate(x1, y1, cx, cy, element.angle); + const [x12, y12] = rotate(x1, y2, cx, cy, element.angle); + const [x22, y22] = rotate(x2, y2, cx, cy, element.angle); + const [x21, y21] = rotate(x2, y1, cx, cy, element.angle); + const minX = Math.min(x11, x12, x22, x21); + const minY = Math.min(y11, y12, y22, y21); + const maxX = Math.max(x11, x12, x22, x21); + const maxY = Math.max(y11, y12, y22, y21); + return [minX, minY, maxX, maxY]; +}; + +export const getCommonBounds = ( elements: readonly ExcalidrawElement[], -): [number, number, number, number] { +): [number, number, number, number] => { if (!elements.length) { return [0, 0, 0, 0]; } @@ -201,19 +218,12 @@ export function getCommonBounds( let maxY = -Infinity; elements.forEach((element) => { - const [x1, y1, x2, y2] = getElementAbsoluteCoords(element); - const angle = element.angle; - const cx = (x1 + x2) / 2; - const cy = (y1 + y2) / 2; - const [x11, y11] = rotate(x1, y1, cx, cy, angle); - const [x12, y12] = rotate(x1, y2, cx, cy, angle); - const [x22, y22] = rotate(x2, y2, cx, cy, angle); - const [x21, y21] = rotate(x2, y1, cx, cy, angle); - minX = Math.min(minX, x11, x12, x22, x21); - minY = Math.min(minY, y11, y12, y22, y21); - maxX = Math.max(maxX, x11, x12, x22, x21); - maxY = Math.max(maxY, y11, y12, y22, y21); + const [x1, y1, x2, y2] = getElementBounds(element); + minX = Math.min(minX, x1); + minY = Math.min(minY, y1); + maxX = Math.max(maxX, x2); + maxY = Math.max(maxY, y2); }); return [minX, minY, maxX, maxY]; -} +}; diff --git a/src/element/index.ts b/src/element/index.ts index 42086543..d3a4b38c 100644 --- a/src/element/index.ts +++ b/src/element/index.ts @@ -9,6 +9,7 @@ export { } from "./newElement"; export { getElementAbsoluteCoords, + getElementBounds, getCommonBounds, getDiamondPoints, getArrowPoints, diff --git a/src/scene/selection.ts b/src/scene/selection.ts index c729252c..4fff25e5 100644 --- a/src/scene/selection.ts +++ b/src/scene/selection.ts @@ -1,5 +1,5 @@ import { ExcalidrawElement } from "../element/types"; -import { getElementAbsoluteCoords } from "../element"; +import { getElementAbsoluteCoords, getElementBounds } from "../element"; import { AppState } from "../types"; import { newElementWith } from "../element/mutateElement"; @@ -14,12 +14,9 @@ export function getElementsWithinSelection( selectionY2, ] = getElementAbsoluteCoords(selection); return elements.filter((element) => { - const [ - elementX1, - elementY1, - elementX2, - elementY2, - ] = getElementAbsoluteCoords(element); + const [elementX1, elementY1, elementX2, elementY2] = getElementBounds( + element, + ); return ( element.type !== "selection" &&