feat: Bind to frame when frame-bound object hidden part is approached

This commit is contained in:
Mark Tolmacs
2025-10-21 18:28:44 +02:00
parent 7e10773ecf
commit 12c67386cf
2 changed files with 41 additions and 36 deletions

View File

@@ -596,15 +596,15 @@ export const getBindingStrategyForDraggingBindingElementEndpoints = (
return { return {
start: startDragged start: startDragged
? { ? {
mode: "inside", mode: "orbit",
element: hoveredElement, element: enclosingFrame,
focusPoint: globalPoint, focusPoint: globalPoint,
} }
: start, : start,
end: endDragged end: endDragged
? { ? {
mode: "inside", mode: "orbit",
element: hoveredElement, element: enclosingFrame,
focusPoint: globalPoint, focusPoint: globalPoint,
} }
: end, : end,

View File

@@ -409,44 +409,49 @@ const renderBindingHighlightForBindableElement = (
const radius = 0.5 * (Math.min(element.width, element.height) / 2); const radius = 0.5 * (Math.min(element.width, element.height) / 2);
// Draw center snap area // Draw center snap area
context.save(); if (!isFrameLikeElement(element)) {
context.translate(element.x + appState.scrollX, element.y + appState.scrollY); context.save();
context.translate(
element.x + appState.scrollX,
element.y + appState.scrollY,
);
const PROGRESS_RATIO = (1 / BIND_MODE_TIMEOUT) * remainingTime; const PROGRESS_RATIO = (1 / BIND_MODE_TIMEOUT) * remainingTime;
context.strokeStyle = "rgba(0, 0, 0, 0.2)"; context.strokeStyle = "rgba(0, 0, 0, 0.2)";
context.lineWidth = 1 / appState.zoom.value; context.lineWidth = 1 / appState.zoom.value;
context.setLineDash([4 / appState.zoom.value, 4 / appState.zoom.value]); context.setLineDash([4 / appState.zoom.value, 4 / appState.zoom.value]);
context.lineDashOffset = (-PROGRESS_RATIO * 10) / appState.zoom.value; context.lineDashOffset = (-PROGRESS_RATIO * 10) / appState.zoom.value;
context.beginPath(); context.beginPath();
context.ellipse( context.ellipse(
element.width / 2, element.width / 2,
element.height / 2, element.height / 2,
radius, radius,
radius, radius,
0, 0,
0, 0,
2 * Math.PI, 2 * Math.PI,
); );
context.stroke(); context.stroke();
// context.strokeStyle = "transparent"; // context.strokeStyle = "transparent";
context.fillStyle = "rgba(0, 0, 0, 0.04)"; context.fillStyle = "rgba(0, 0, 0, 0.04)";
context.beginPath(); context.beginPath();
context.ellipse( context.ellipse(
element.width / 2, element.width / 2,
element.height / 2, element.height / 2,
radius * (1 - opacity), radius * (1 - opacity),
radius * (1 - opacity), radius * (1 - opacity),
0, 0,
0, 0,
2 * Math.PI, 2 * Math.PI,
); );
context.fill(); context.fill();
context.restore(); context.restore();
}
return { return {
runtime: (state?.runtime ?? 0) + deltaTime, runtime: (state?.runtime ?? 0) + deltaTime,