diff --git a/packages/excalidraw/actions/actionLinearEditor.tsx b/packages/excalidraw/actions/actionLinearEditor.tsx index a62a88cb3..943474313 100644 --- a/packages/excalidraw/actions/actionLinearEditor.tsx +++ b/packages/excalidraw/actions/actionLinearEditor.tsx @@ -118,6 +118,53 @@ const updateLoopLock = ( firstPoint[1], ); } + } else if (element.loopLock) { + // When toggling from loopLock=true to loopLock=false + // We need to dislocate the end point by 15 points + + // When loopLock is true, the last point is the same as the first point + // We'll use the direction from second-to-last point to first point + const firstPoint = updatedPoints[0]; + + if (updatedPoints.length >= 3) { + const secondLastPoint = updatedPoints[updatedPoints.length - 2]; + + // Get direction from second-last to first + const dx = firstPoint[0] - secondLastPoint[0]; + const dy = firstPoint[1] - secondLastPoint[1]; + + // Calculate perpendicular direction (rotate 90 degrees) + // This creates a visible gap perpendicular to the line direction + const perpDx = dy; + const perpDy = -dx; + + // Normalize the perpendicular direction vector + const perpLength = Math.sqrt(perpDx * perpDx + perpDy * perpDy); + let normalizedPerpDx = 0; + let normalizedPerpDy = 0; + + if (perpLength > 0) { + normalizedPerpDx = perpDx / perpLength; + normalizedPerpDy = perpDy / perpLength; + } else { + // Default perpendicular if points are the same + normalizedPerpDx = -0.7071; + normalizedPerpDy = 0.7071; + } + + // Move the end point perpendicular to the line direction + updatedPoints[updatedPoints.length - 1] = pointFrom( + firstPoint[0] + normalizedPerpDx * 15, + firstPoint[1] + normalizedPerpDy * 15, + ); + } else { + // For simple lines with fewer than 3 points + // Just move away from the first point at a 45-degree angle + updatedPoints[updatedPoints.length - 1] = pointFrom( + firstPoint[0] + 10.6, + firstPoint[1] - 10.6, // Different direction to avoid crossing + ); + } } app.scene.mutateElement(element, {