-
-
Notifications
You must be signed in to change notification settings - Fork 11.4k
feat: Elbow arrow segment fixing & positioning #8952
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
…draw/excalidraw into feat/elbow-arrow-movable-segments
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
dwelle
approved these changes
Jan 17, 2025
|
Let's do this! 🔥🚀 Thanks @mtolmacs! ❤️ |
zsviczian
added a commit
to zsviczian/excalidraw
that referenced
this pull request
Jan 18, 2025
feat: Elbow arrow segment fixing & positioning (excalidraw#8952)
|
This is amazing work! 👏 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
What's in this PR?
mutateElement()so the complexity is hidden for other developers.Key implementation details
packages/excalidraw/element/routing.tsis renamed topackages/excalidraw/element/elbowarrow.tsThe
LinearElementEditorclass contains handlers for segment midpoint logic, but due to a likely state mismatch / race condition a completely new midpoint handling was implemented for elbow arrows.Elbow arrow creation and updates needed different inputs, so the
LinearElementEditor::movePoints()function was extensively updated to cover both elbow arrows and simple arrows.Due to a UX requirement where an elbow arrow is bound on both ends and the second segment is fixed, then the start (or end) of the arrow is dragged to a perpendicular side of the bound element, there are two new properties on elbow arrow elements,

startIsSpecialandendIsSpecialrespectively.To store the fixed segments data on the elbow arrow elements a new property is introduced, called
fixedSegments. It is an array of objects, the objects containpointsproperty (so it goes from 1 to length -1)LocalPointcoordinate of the start of the fixed segmentLocalPointcoordinate of the end of the fixed segmentThe elbow arrow generating algorithm on its own creates suboptimal arrow points with duplicates and hooks, which are simplified in a post processing step. This simplification results in loss of information for subsequent modification requests, so there are a lot of subtle heuristics to "guess" the lost information, which would be required to keep a stable visual experience.
The visual debugging is enhanced and refactored to make development easier (beyond elbow arrows)
Where to start a review
elbowarrow.ts
packages/excalidraw/element/elbowarrow.ts. The code in this file is organized around a single main entrypoint,updateElbowArrowPoints(...). This is called frommutateElement(...)to calculate the changes needed, then returns the element updates required in the form ofElementUpdate<ExcalidrawElbowArrowElement>, which is then woven into the original logic ofmutateElement(...)updateElbowArrowPoints(...)function is a dispatch function to handle 6 different use cases individually.getElbowArrowData(...)which just calculates the common parameters used by all the functions androuteElbowArrow(...)which contain the routing algorithm. The modifications in these compared to the original is minimal, only affecting spacing around bound elements.mutateElement.ts
updateElbowArrowPoints(...)inelbowarrow.tsas a separate branch before the original code. This branch prepares the function arguments required for the elbow arrow code, then applies the resolved changes before handing over the control flow to the old code.optionsargument is added to the interface ofmutateElement(...)which affects the public API.LinearElementEditor.ts
movePoints(...)there are small modifications to the original code to handle elbow arrowsmoveFixedSegment(...)anddeleteFixedSegment(...)components/App.tsxhandlers.packages/excalidraw/components/App.tsx
LinearElementEditor.dragElement.ts,resizeElement.tsandrestore.tsfractionalIndex.ts
mutateElement(...)changes were needed insyncInvalidIndices(...)andsyncMovedIndices(...)