feat: line polygons (#9477)

* Loop Lock/Unlock

* fixed condition. 4 line points are required for the action to be available

* extracted updateLoopLock to improve readability. Removed unnecessary SVG attributes

* lint + added loopLock to restore.ts

* added  loopLock to newElement, updated test snapshots

* lint

* dislocate enpoint when breaking the loop.

* change icon & turn into a state style button

* POC: auto-transform to polygon on bg set

* keep polygon icon constant

* do not split points on de-polygonizing & highlight overlapping points

* rewrite color picker to support no (mixed) colors & fix focus handling

* refactor

* tweak point rendering inside line editor

* do not disable polygon when creating new points via alt

* auto-enable polygon when aligning start/end points

* TBD: remove bg color when disabling polygon

* TBD: only show polygon button for enabled polygons

* fix polygon behavior when adding/removing/moving points within line editor

* convert to polygon when creating line

* labels tweak

* add to command palette

* loopLock -> polygon

* restore `polygon` state on type conversions

* update snapshots

* naming

* break polygon on restore/finalize if invalid & prevent creation

* snapshots

* fix: merge issue and forgotten debug

* snaps

* do not merge points for 3-point lines

---------

Co-authored-by: dwelle <5153846+dwelle@users.noreply.github.com>
This commit is contained in:
zsviczian
2025-05-26 11:14:55 +02:00
committed by GitHub
parent 4dc205537c
commit 87c87a9fb1
26 changed files with 555 additions and 121 deletions

View File

@@ -18,7 +18,7 @@ import {
normalizeLink,
getLineHeight,
} from "@excalidraw/common";
import { getNonDeletedElements } from "@excalidraw/element";
import { getNonDeletedElements, isValidPolygon } from "@excalidraw/element";
import { normalizeFixedPoint } from "@excalidraw/element";
import {
updateElbowArrowPoints,
@@ -34,6 +34,7 @@ import {
isElbowArrow,
isFixedPointBinding,
isLinearElement,
isLineElement,
isTextElement,
isUsingAdaptiveRadius,
} from "@excalidraw/element";
@@ -323,7 +324,8 @@ const restoreElement = (
: element.points;
if (points[0][0] !== 0 || points[0][1] !== 0) {
({ points, x, y } = LinearElementEditor.getNormalizedPoints(element));
({ points, x, y } =
LinearElementEditor.getNormalizeElementPointsAndCoords(element));
}
return restoreElementWithProperties(element, {
@@ -339,6 +341,13 @@ const restoreElement = (
points,
x,
y,
...(isLineElement(element)
? {
polygon: isValidPolygon(element.points)
? element.polygon ?? false
: false,
}
: {}),
...getSizeFromPoints(points),
});
case "arrow": {
@@ -351,7 +360,8 @@ const restoreElement = (
: element.points;
if (points[0][0] !== 0 || points[0][1] !== 0) {
({ points, x, y } = LinearElementEditor.getNormalizedPoints(element));
({ points, x, y } =
LinearElementEditor.getNormalizeElementPointsAndCoords(element));
}
const base = {