From e764e59cdaac28a630a9d9c32956247b343d6734 Mon Sep 17 00:00:00 2001 From: Steve Ruiz Date: Sun, 17 Mar 2024 13:24:32 +0000 Subject: [PATCH] [tiny] Slightly more efficient selection rotated page bounds / page bounds (#3178) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR makes a few tiny improvements to the way that selection page bounds and rotated page bounds are calculated. For bounds, we bail once we find a different rotation among the selected shapes. Previously, we grabbed all of the rotations first before comparing them; we only need to grab rotations until we find a rotation that's different from the first one. For rotating page bounds, we only look at the corners of the calculated bounds, and we mutate the resulting points after we transform them. Previously, we looked at all vertices and make a copy of the points when rotating them. The transform already creates the copy, so we can mutate it; and while the bounds are usually calculated from the vertices, using the corners gives us fewer points to transform. ### Change Type - [x] `sdk` — Changes the tldraw SDK - [ ] `dotcom` — Changes the tldraw.com web app - [ ] `docs` — Changes to the documentation, examples, or templates. - [ ] `vs code` — Changes to the vscode plugin - [ ] `internal` — Does not affect user-facing stuff - [ ] `bugfix` — Bug fix - [ ] `feature` — New feature - [x] `improvement` — Improving existing features - [ ] `chore` — Updating dependencies, other boring stuff - [ ] `galaxy brain` — Architectural changes - [ ] `tests` — Changes to any test code - [ ] `tools` — Changes to infrastructure, CI, internal scripts, debugging tools, etc. - [ ] `dunno` — I don't know ### Release Notes - SDK, slightly more performant selection bounds calculations. --- packages/editor/src/lib/editor/Editor.ts | 31 ++++++++++++++---------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/packages/editor/src/lib/editor/Editor.ts b/packages/editor/src/lib/editor/Editor.ts index fdaba114d..de43e3bc5 100644 --- a/packages/editor/src/lib/editor/Editor.ts +++ b/packages/editor/src/lib/editor/Editor.ts @@ -1647,19 +1647,24 @@ export class Editor extends EventEmitter { */ @computed getSelectionRotation(): number { const selectedShapeIds = this.getSelectedShapeIds() - if (selectedShapeIds.length === 0) { - return 0 - } - if (selectedShapeIds.length === 1) { - return this.getShapePageTransform(this.getSelectedShapeIds()[0])!.rotation() + let foundFirst = false // annoying but we can't use an i===0 check because we need to skip over undefineds + let rotation = 0 + for (let i = 0, n = selectedShapeIds.length; i < n; i++) { + const pageTransform = this.getShapePageTransform(selectedShapeIds[i]) + if (!pageTransform) continue + if (foundFirst) { + if (pageTransform.rotation() !== rotation) { + // There are at least 2 different rotations, so the common rotation is zero + return 0 + } + } else { + // First rotation found + foundFirst = true + rotation = pageTransform.rotation() + } } - const allRotations = selectedShapeIds.map((id) => this.getShapePageTransform(id)!.rotation()) - // if the rotations are all compatible with each other, return the rotation of any one of them - if (allRotations.every((rotation) => Math.abs(rotation - allRotations[0]) < Math.PI / 180)) { - return this.getShapePageTransform(selectedShapeIds[0])!.rotation() - } - return 0 + return rotation } /** @@ -1693,9 +1698,9 @@ export class Editor extends EventEmitter { .flatMap((id) => { const pageTransform = this.getShapePageTransform(id) if (!pageTransform) return [] - return pageTransform.applyToPoints(this.getShapeGeometry(id).vertices) + return pageTransform.applyToPoints(this.getShapeGeometry(id).bounds.corners) }) - .map((p) => Vec.Rot(p, -selectionRotation)) + .map((p) => p.rot(-selectionRotation)) ) // now position box so that it's top-left corner is in the right place boxFromRotatedVertices.point = boxFromRotatedVertices.point.rot(selectionRotation)