mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
feat: support segment midpoints in line editor (#5641)
* feat: support segment midpoints in line editor * fix tests * midpoints working in bezier curve * midpoint working with non zero roughness * calculate beizer curve control points for points >2 * unnecessary rerender * don't show phantom points inside editor for short segments * don't show phantom points for small curves * improve the algo for plotting midpoints on bezier curve by taking arc lengths and doing binary search * fix tests finally * fix naming * cache editor midpoints * clear midpoint cache when undo * fix caching * calculate index properly when not all segments have midpoints * make sure correct element version is fetched from cache * chore * fix * direct comparison for equal points * create arePointsEqual util * upate name * don't update cache except inside getter * don't compute midpoints outside editor unless 2pointer lines * update cache to object and burst when Zoom updated as well * early return if midpoints not present outside editor * don't early return * cleanup * Add specs * fix
This commit is contained in:
parent
c5869979c8
commit
0d1058a596
7 changed files with 666 additions and 113 deletions
|
@ -2718,18 +2718,23 @@ class App extends React.Component<AppProps, AppState> {
|
|||
event,
|
||||
scenePointerX,
|
||||
scenePointerY,
|
||||
this.state.editingLinearElement,
|
||||
this.state.gridSize,
|
||||
this.state,
|
||||
);
|
||||
if (editingLinearElement !== this.state.editingLinearElement) {
|
||||
|
||||
if (
|
||||
editingLinearElement &&
|
||||
editingLinearElement !== this.state.editingLinearElement
|
||||
) {
|
||||
// Since we are reading from previous state which is not possible with
|
||||
// automatic batching in React 18 hence using flush sync to synchronously
|
||||
// update the state. Check https://github.com/excalidraw/excalidraw/pull/5508 for more details.
|
||||
flushSync(() => {
|
||||
this.setState({ editingLinearElement });
|
||||
this.setState({
|
||||
editingLinearElement,
|
||||
});
|
||||
});
|
||||
}
|
||||
if (editingLinearElement.lastUncommittedPoint != null) {
|
||||
if (editingLinearElement?.lastUncommittedPoint != null) {
|
||||
this.maybeSuggestBindingAtCursor(scenePointer);
|
||||
} else {
|
||||
this.setState({ suggestedBindings: [] });
|
||||
|
@ -3058,7 +3063,7 @@ class App extends React.Component<AppProps, AppState> {
|
|||
}
|
||||
if (this.state.selectedLinearElement) {
|
||||
let hoverPointIndex = -1;
|
||||
let midPointHovered = false;
|
||||
let segmentMidPointHoveredCoords = null;
|
||||
if (
|
||||
isHittingElementNotConsideringBoundingBox(element, this.state, [
|
||||
scenePointerX,
|
||||
|
@ -3071,13 +3076,14 @@ class App extends React.Component<AppProps, AppState> {
|
|||
scenePointerX,
|
||||
scenePointerY,
|
||||
);
|
||||
midPointHovered = LinearElementEditor.isHittingMidPoint(
|
||||
linearElementEditor,
|
||||
{ x: scenePointerX, y: scenePointerY },
|
||||
this.state,
|
||||
);
|
||||
segmentMidPointHoveredCoords =
|
||||
LinearElementEditor.getSegmentMidpointHitCoords(
|
||||
linearElementEditor,
|
||||
{ x: scenePointerX, y: scenePointerY },
|
||||
this.state,
|
||||
);
|
||||
|
||||
if (hoverPointIndex >= 0 || midPointHovered) {
|
||||
if (hoverPointIndex >= 0 || segmentMidPointHoveredCoords) {
|
||||
setCursor(this.canvas, CURSOR_TYPE.POINTER);
|
||||
} else {
|
||||
setCursor(this.canvas, CURSOR_TYPE.MOVE);
|
||||
|
@ -3106,12 +3112,15 @@ class App extends React.Component<AppProps, AppState> {
|
|||
}
|
||||
|
||||
if (
|
||||
this.state.selectedLinearElement.midPointHovered !== midPointHovered
|
||||
!LinearElementEditor.arePointsEqual(
|
||||
this.state.selectedLinearElement.segmentMidPointHoveredCoords,
|
||||
segmentMidPointHoveredCoords,
|
||||
)
|
||||
) {
|
||||
this.setState({
|
||||
selectedLinearElement: {
|
||||
...this.state.selectedLinearElement,
|
||||
midPointHovered,
|
||||
segmentMidPointHoveredCoords,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue