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
|
@ -197,12 +197,7 @@ const renderLinearPointHandles = (
|
|||
context.translate(renderConfig.scrollX, renderConfig.scrollY);
|
||||
context.lineWidth = 1 / renderConfig.zoom.value;
|
||||
const points = LinearElementEditor.getPointsGlobalCoordinates(element);
|
||||
const centerPoint = LinearElementEditor.getMidPoint(
|
||||
appState.selectedLinearElement,
|
||||
);
|
||||
if (!centerPoint) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { POINT_HANDLE_SIZE } = LinearElementEditor;
|
||||
const radius = appState.editingLinearElement
|
||||
? POINT_HANDLE_SIZE
|
||||
|
@ -221,11 +216,20 @@ const renderLinearPointHandles = (
|
|||
);
|
||||
});
|
||||
|
||||
if (points.length < 3) {
|
||||
if (appState.selectedLinearElement.midPointHovered) {
|
||||
const centerPoint = LinearElementEditor.getMidPoint(
|
||||
appState.selectedLinearElement,
|
||||
)!;
|
||||
//Rendering segment mid points
|
||||
const midPoints = LinearElementEditor.getEditorMidPoints(
|
||||
element,
|
||||
appState,
|
||||
).filter((midPoint) => midPoint !== null) as Point[];
|
||||
|
||||
midPoints.forEach((segmentMidPoint) => {
|
||||
if (
|
||||
appState?.selectedLinearElement?.segmentMidPointHoveredCoords &&
|
||||
LinearElementEditor.arePointsEqual(
|
||||
segmentMidPoint,
|
||||
appState.selectedLinearElement.segmentMidPointHoveredCoords,
|
||||
)
|
||||
) {
|
||||
// The order of renderingSingleLinearPoint and highLight points is different
|
||||
// inside vs outside editor as hover states are different,
|
||||
// in editor when hovered the original point is not visible as hover state fully covers it whereas outside the
|
||||
|
@ -235,34 +239,34 @@ const renderLinearPointHandles = (
|
|||
context,
|
||||
appState,
|
||||
renderConfig,
|
||||
centerPoint,
|
||||
segmentMidPoint,
|
||||
radius,
|
||||
false,
|
||||
);
|
||||
highlightPoint(centerPoint, context, renderConfig);
|
||||
highlightPoint(segmentMidPoint, context, renderConfig);
|
||||
} else {
|
||||
highlightPoint(centerPoint, context, renderConfig);
|
||||
highlightPoint(segmentMidPoint, context, renderConfig);
|
||||
renderSingleLinearPoint(
|
||||
context,
|
||||
appState,
|
||||
renderConfig,
|
||||
centerPoint,
|
||||
segmentMidPoint,
|
||||
radius,
|
||||
false,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
} else if (appState.editingLinearElement || points.length === 2) {
|
||||
renderSingleLinearPoint(
|
||||
context,
|
||||
appState,
|
||||
renderConfig,
|
||||
centerPoint,
|
||||
segmentMidPoint,
|
||||
POINT_HANDLE_SIZE / 2,
|
||||
false,
|
||||
true,
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
context.restore();
|
||||
};
|
||||
|
@ -403,6 +407,20 @@ export const _renderScene = ({
|
|||
visibleElements.forEach((element) => {
|
||||
try {
|
||||
renderElement(element, rc, context, renderConfig);
|
||||
// Getting the element using LinearElementEditor during collab mismatches version - being one head of visible elements due to
|
||||
// ShapeCache returns empty hence making sure that we get the
|
||||
// correct element from visible elements
|
||||
if (appState.editingLinearElement?.elementId === element.id) {
|
||||
if (element) {
|
||||
renderLinearPointHandles(
|
||||
context,
|
||||
appState,
|
||||
renderConfig,
|
||||
element as NonDeleted<ExcalidrawLinearElement>,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (!isExporting) {
|
||||
renderLinkIcon(element, context, appState);
|
||||
}
|
||||
|
@ -411,15 +429,6 @@ export const _renderScene = ({
|
|||
}
|
||||
});
|
||||
|
||||
if (appState.editingLinearElement) {
|
||||
const element = LinearElementEditor.getElement(
|
||||
appState.editingLinearElement.elementId,
|
||||
);
|
||||
if (element) {
|
||||
renderLinearPointHandles(context, appState, renderConfig, element);
|
||||
}
|
||||
}
|
||||
|
||||
// Paint selection element
|
||||
if (appState.selectionElement) {
|
||||
try {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue