The interactive canvas (selection outlines, transform handles, binding
highlights, collaborator cursors, snap lines, scrollbars) was still
composited through `filter: invert(93%) hue-rotate(180deg)` in dark mode
(#10578 only de-filtered the static canvas). The canvas covers the whole
viewport and repaints on nearly every pointer move, so browsers that
composite in software (Firefox/Zen on software WebRender or with hardware
acceleration disabled) paid for a full-viewport color-matrix pass per frame
and dropped from 120fps to ~40fps during marquee/drag. Light mode was
unaffected.
Colors are now mapped in JS via `applyDarkModeFilter`, like the static
canvas. Hardcoded dark-mode values are the exact post-filter equivalents of
the previous ones, so rendering is unchanged, with two intentional
exceptions:
- collaborator cursors and remote selection outlines render in the
collaborators' actual colors (matching their avatars) instead of inverted
ones (per the existing TODO in clients.ts)
- the lasso trail now uses the theme's `--color-selection` like the marquee
selection, instead of a hardcoded light-theme purple that never matched in
dark mode
`--color-selection` for the dark theme now holds the actual rendered color
(#b4b0ff); hosts overriding it no longer need to pre-invert.
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Arrow labels can be dragged along their arrow. A label's place is stored on the text element as labelPosition, a normalized arc-length parameter (0–1) over the arrow's whole path, and the label's x/y is derived from it. Because the parameter covers the whole path rather than one segment, the label keeps its place when points are dragged, when midpoints are inserted or removed, and when the arrow is resized. (An earlier iteration anchored labels to a segment; that approach is gone.)
Closes#9338.
---------
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
Co-authored-by: Mark Tolmacs <mark@lazycat.hu>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-authored-by: dwelle <5153846+dwelle@users.noreply.github.com>
* Initial commit
* Segments detection
* Remove aspect ratio
* Refactor
* Fix tests
* Toggle shapeSnap
* Fix linting
* debug: live preview
* Rebase fixes
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
* Bind to elements (no hover background)
* Shape closed
* Fix rad calc + rename segments
* Comments
* Fix binding highlighting + lints
* Rename to convert to shape
* fix: Binding
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
* chore: Refactor spline simplification
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
* chore: Remove unused doBoundsIntersect
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
* fix: Restore type signature
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
* feat: Propose new button shapes
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
* chore: Remove unused types
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
* chore: Icon shapes
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
* fix: Element cloning
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
* fix: Element cloning
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
* fix: Remove unused
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
* feat: Shape settings in recognition mode
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
* chore: Remove debug
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
* feat: Actions
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
* fix: Lint
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
* fix: Arrowheads for freedraw
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
* feat: Draw shape tool instead of freedraw
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
* fix: Test
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
* fix: Lint
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
* fix: Keyboard shortcut visibility
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
* feat: Unique cursor for draw shape
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
* fix: Remove selection
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
* fix: Shape selection
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
* feat: Improve shape recognition
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
* fix: Further refine shape recognition
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
* feat: Preview
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
* feat: Add hint
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
* fix: Refined shape recognition
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
* fix: Less ellipse more rectanguloid
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
* fix: Refined arrow recognition
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
* fix: Refinerecognition
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
* chore: Lower linear threshold
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
* feat: Rectangle head arrow
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
* feat: More arrowhead sizes
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
* fix: Arrow remains an arrow
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
* feat: Draw line between elements converts to arrow
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
* remove pendingDrawShapeElement
* fix: Arrow start point binding
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
* fix: Different arrow endpoint heuristic
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
* fix: Point type
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
* fix: Various small fixes
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
* fix: Avoid recompute
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
* fix: Type issues
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
* test(editor): cover the drawShape (snap-to-shape) tool
The drawShape tool had no dedicated tests, which let master's toolbar /
active-tool rewrite silently break it during the merge: actionFinalize
reverted to the selection tool after every sketch, because the drawShape
flow finalizes without a `newElement` and so failed master's new
`&& element` guard.
Covers the behavior the merge had to preserve:
- sketch recognition (rectangle, ellipse) and the too-small no-op
- the tool stays active after finalizing, so shapes can be sketched
consecutively (regression guard for the above)
- activation via the S shortcut and the extra-tools dropdown
- the tool's own cursor
Points are fed into the trail directly rather than through pointermove,
which is rAF-throttled and would drop all but one point per frame — the
same approach lasso.test.tsx uses.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* feat: Add test
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
* feat: Breakout from App.tsx
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
* fix: Shortcut is now Shift+X
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
* fix: No selecting arrows for shape recog
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
* fix: Double history
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
* feat: PCA + feature extraction recognition
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
* reduce and normalize min-size gates
* never select newElement when shape recog tool active
* simplify lifecycle & remove double finalize
* make arrows bindings orbit
* funnel though actionFinalize & fix two unrelated cleanup cases
* use crosshair cursor
* show strokeWidth
* switch icons for drawShape & extraTools
* dedupe getBoundsFromPoints
* remove unused helpers
* jsdoc cleanup
* dynamic trail size
* improve rectangle recognition
* disallow linears to deviate too much from a straight line
* put under freedraw tool on tablet/mobile
* tweak label
* rename `drawShape` -> `autoshape`
---------
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
Co-authored-by: dwelle <5153846+dwelle@users.noreply.github.com>
Co-authored-by: Mark Tolmacs <mark@lazycat.hu>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
* feat(packages/excalidraw): add `props.interaction` and `props.ui`
* fix: prevent browser zoom when interaction disabled
* changelog
* clean up interactive state on disable and consolidate `viewMode` and interaction state updates
* render UI rendered to `children` even if editor-exported
* support `allowed.navigation` and `allowed.embeds/interactiveContent`
* change naming `allowed` -> `enabled`
* changelog: add PR links
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* clear flowchart sessions via consolidated `app.flowchart` after master merge
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* refactor getters -> methods
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>