@canvas-harness/core 0.1.5 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +156 -63
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +30 -5
- package/dist/index.d.ts +30 -5
- package/dist/index.js +156 -63
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -233,53 +233,6 @@ var rotatePoint = (px, py, cx, cy, cos, sin) => {
|
|
|
233
233
|
return { x: cx + dx * cos - dy * sin, y: cy + dx * sin + dy * cos };
|
|
234
234
|
};
|
|
235
235
|
|
|
236
|
-
// src/edges/auto-route.ts
|
|
237
|
-
var CONTROL_MAX = 200;
|
|
238
|
-
var CONTROL_FRACTION = 0.4;
|
|
239
|
-
var sideOf = (node, localX, localY) => {
|
|
240
|
-
const distLeft = localX;
|
|
241
|
-
const distRight = node.w - localX;
|
|
242
|
-
const distTop = localY;
|
|
243
|
-
const distBottom = node.h - localY;
|
|
244
|
-
const minDist = Math.min(distLeft, distRight, distTop, distBottom);
|
|
245
|
-
if (minDist === distLeft) return "w";
|
|
246
|
-
if (minDist === distRight) return "e";
|
|
247
|
-
if (minDist === distTop) return "n";
|
|
248
|
-
return "s";
|
|
249
|
-
};
|
|
250
|
-
var sideNormalLocal = (side) => {
|
|
251
|
-
switch (side) {
|
|
252
|
-
case "n":
|
|
253
|
-
return { x: 0, y: -1 };
|
|
254
|
-
case "s":
|
|
255
|
-
return { x: 0, y: 1 };
|
|
256
|
-
case "e":
|
|
257
|
-
return { x: 1, y: 0 };
|
|
258
|
-
case "w":
|
|
259
|
-
return { x: -1, y: 0 };
|
|
260
|
-
}
|
|
261
|
-
};
|
|
262
|
-
var rotateVecByAngle = (v, angle) => {
|
|
263
|
-
if (angle === 0) return v;
|
|
264
|
-
const cos = Math.cos(angle);
|
|
265
|
-
const sin = Math.sin(angle);
|
|
266
|
-
return { x: v.x * cos - v.y * sin, y: v.x * sin + v.y * cos };
|
|
267
|
-
};
|
|
268
|
-
var autoRouteControls = (sourceWorld, targetWorld, sourceNormalWorld, targetNormalWorld) => {
|
|
269
|
-
const dx = targetWorld.x - sourceWorld.x;
|
|
270
|
-
const dy = targetWorld.y - sourceWorld.y;
|
|
271
|
-
const dist = Math.hypot(dx, dy);
|
|
272
|
-
const offset = Math.min(CONTROL_MAX, CONTROL_FRACTION * dist);
|
|
273
|
-
const fallbackSource = dist > 0 ? { x: dx / dist, y: dy / dist } : { x: 1, y: 0 };
|
|
274
|
-
const fallbackTarget = dist > 0 ? { x: -dx / dist, y: -dy / dist } : { x: -1, y: 0 };
|
|
275
|
-
const ns = sourceNormalWorld ?? fallbackSource;
|
|
276
|
-
const nt = targetNormalWorld ?? fallbackTarget;
|
|
277
|
-
return {
|
|
278
|
-
c1: { x: sourceWorld.x + ns.x * offset, y: sourceWorld.y + ns.y * offset },
|
|
279
|
-
c2: { x: targetWorld.x + nt.x * offset, y: targetWorld.y + nt.y * offset }
|
|
280
|
-
};
|
|
281
|
-
};
|
|
282
|
-
|
|
283
236
|
// src/edges/project.ts
|
|
284
237
|
var projectEndToWorld = (end, getNode) => {
|
|
285
238
|
if (!isAttached(end)) return end.worldPoint;
|
|
@@ -328,6 +281,112 @@ var projectToNodeBoundary = (world, node) => {
|
|
|
328
281
|
return { x: clampedX, y: node.h };
|
|
329
282
|
};
|
|
330
283
|
|
|
284
|
+
// src/edges/auto-route.ts
|
|
285
|
+
var CONTROL_MAX = 200;
|
|
286
|
+
var CONTROL_FRACTION = 0.4;
|
|
287
|
+
var BOUNDARY_EPS = 0.5;
|
|
288
|
+
var isLocalOffsetInsideBody = (localOffset, node) => {
|
|
289
|
+
const onLeft = Math.abs(localOffset.x) <= BOUNDARY_EPS;
|
|
290
|
+
const onRight = Math.abs(localOffset.x - node.w) <= BOUNDARY_EPS;
|
|
291
|
+
const onTop = Math.abs(localOffset.y) <= BOUNDARY_EPS;
|
|
292
|
+
const onBottom = Math.abs(localOffset.y - node.h) <= BOUNDARY_EPS;
|
|
293
|
+
const inside = localOffset.x > -BOUNDARY_EPS && localOffset.x < node.w + BOUNDARY_EPS && localOffset.y > -BOUNDARY_EPS && localOffset.y < node.h + BOUNDARY_EPS;
|
|
294
|
+
return inside && !onLeft && !onRight && !onTop && !onBottom;
|
|
295
|
+
};
|
|
296
|
+
var sideOf = (node, localX, localY) => {
|
|
297
|
+
const distLeft = localX;
|
|
298
|
+
const distRight = node.w - localX;
|
|
299
|
+
const distTop = localY;
|
|
300
|
+
const distBottom = node.h - localY;
|
|
301
|
+
const minDist = Math.min(distLeft, distRight, distTop, distBottom);
|
|
302
|
+
if (minDist === distLeft) return "w";
|
|
303
|
+
if (minDist === distRight) return "e";
|
|
304
|
+
if (minDist === distTop) return "n";
|
|
305
|
+
return "s";
|
|
306
|
+
};
|
|
307
|
+
var sideNormalLocal = (side) => {
|
|
308
|
+
switch (side) {
|
|
309
|
+
case "n":
|
|
310
|
+
return { x: 0, y: -1 };
|
|
311
|
+
case "s":
|
|
312
|
+
return { x: 0, y: 1 };
|
|
313
|
+
case "e":
|
|
314
|
+
return { x: 1, y: 0 };
|
|
315
|
+
case "w":
|
|
316
|
+
return { x: -1, y: 0 };
|
|
317
|
+
}
|
|
318
|
+
};
|
|
319
|
+
var rotateVecByAngle = (v, angle) => {
|
|
320
|
+
if (angle === 0) return v;
|
|
321
|
+
const cos = Math.cos(angle);
|
|
322
|
+
const sin = Math.sin(angle);
|
|
323
|
+
return { x: v.x * cos - v.y * sin, y: v.x * sin + v.y * cos };
|
|
324
|
+
};
|
|
325
|
+
var autoRouteControls = (sourceWorld, targetWorld, sourceNormalWorld, targetNormalWorld) => {
|
|
326
|
+
const dx = targetWorld.x - sourceWorld.x;
|
|
327
|
+
const dy = targetWorld.y - sourceWorld.y;
|
|
328
|
+
const dist = Math.hypot(dx, dy);
|
|
329
|
+
const offset = Math.min(CONTROL_MAX, CONTROL_FRACTION * dist);
|
|
330
|
+
const fallbackSource = dist > 0 ? { x: dx / dist, y: dy / dist } : { x: 1, y: 0 };
|
|
331
|
+
const fallbackTarget = dist > 0 ? { x: -dx / dist, y: -dy / dist } : { x: -1, y: 0 };
|
|
332
|
+
const ns = sourceNormalWorld ?? fallbackSource;
|
|
333
|
+
const nt = targetNormalWorld ?? fallbackTarget;
|
|
334
|
+
return {
|
|
335
|
+
c1: { x: sourceWorld.x + ns.x * offset, y: sourceWorld.y + ns.y * offset },
|
|
336
|
+
c2: { x: targetWorld.x + nt.x * offset, y: targetWorld.y + nt.y * offset }
|
|
337
|
+
};
|
|
338
|
+
};
|
|
339
|
+
var computeAsymmetricRoute = (sourceNode, targetNode) => {
|
|
340
|
+
const srcCenterWorld = {
|
|
341
|
+
x: sourceNode.x + sourceNode.w / 2,
|
|
342
|
+
y: sourceNode.y + sourceNode.h / 2
|
|
343
|
+
};
|
|
344
|
+
const srcInTgtLocal = worldToNodeLocal(srcCenterWorld, targetNode);
|
|
345
|
+
const tgtHalfW = targetNode.w / 2;
|
|
346
|
+
const tgtHalfH = targetNode.h / 2;
|
|
347
|
+
const dxNorm = (srcInTgtLocal.x - tgtHalfW) / Math.max(1, tgtHalfW);
|
|
348
|
+
const dyNorm = (srcInTgtLocal.y - tgtHalfH) / Math.max(1, tgtHalfH);
|
|
349
|
+
const targetSide = Math.abs(dxNorm) >= Math.abs(dyNorm) ? dxNorm > 0 ? "e" : "w" : dyNorm > 0 ? "s" : "n";
|
|
350
|
+
let tgtEntryLocal;
|
|
351
|
+
if (targetSide === "n" || targetSide === "s") {
|
|
352
|
+
const sideY = targetSide === "n" ? 0 : targetNode.h;
|
|
353
|
+
const clampX = Math.max(0, Math.min(targetNode.w, srcInTgtLocal.x));
|
|
354
|
+
tgtEntryLocal = { x: clampX, y: sideY };
|
|
355
|
+
} else {
|
|
356
|
+
const sideX = targetSide === "w" ? 0 : targetNode.w;
|
|
357
|
+
const clampY = Math.max(0, Math.min(targetNode.h, srcInTgtLocal.y));
|
|
358
|
+
tgtEntryLocal = { x: sideX, y: clampY };
|
|
359
|
+
}
|
|
360
|
+
const targetEntryWorld = nodeLocalToWorld(tgtEntryLocal, targetNode);
|
|
361
|
+
const tgtEntryInSrcLocal = worldToNodeLocal(targetEntryWorld, sourceNode);
|
|
362
|
+
const srcHalfW = sourceNode.w / 2;
|
|
363
|
+
const srcHalfH = sourceNode.h / 2;
|
|
364
|
+
const rayDx = tgtEntryInSrcLocal.x - srcHalfW;
|
|
365
|
+
const rayDy = tgtEntryInSrcLocal.y - srcHalfH;
|
|
366
|
+
const tx = rayDx === 0 ? Number.POSITIVE_INFINITY : (rayDx > 0 ? srcHalfW : -srcHalfW) / rayDx;
|
|
367
|
+
const ty = rayDy === 0 ? Number.POSITIVE_INFINITY : (rayDy > 0 ? srcHalfH : -srcHalfH) / rayDy;
|
|
368
|
+
const t = Math.min(tx, ty);
|
|
369
|
+
const srcExitLocal = {
|
|
370
|
+
x: srcHalfW + rayDx * t,
|
|
371
|
+
y: srcHalfH + rayDy * t
|
|
372
|
+
};
|
|
373
|
+
const sourceExitWorld = nodeLocalToWorld(srcExitLocal, sourceNode);
|
|
374
|
+
const dxWorld = targetEntryWorld.x - sourceExitWorld.x;
|
|
375
|
+
const dyWorld = targetEntryWorld.y - sourceExitWorld.y;
|
|
376
|
+
const distance2 = Math.hypot(dxWorld, dyWorld);
|
|
377
|
+
const offset = Math.min(CONTROL_MAX, CONTROL_FRACTION * distance2);
|
|
378
|
+
const c1 = distance2 > 0 ? {
|
|
379
|
+
x: sourceExitWorld.x + dxWorld / distance2 * offset,
|
|
380
|
+
y: sourceExitWorld.y + dyWorld / distance2 * offset
|
|
381
|
+
} : { ...sourceExitWorld };
|
|
382
|
+
const tgtNormalWorld = rotateVecByAngle(sideNormalLocal(targetSide), targetNode.angle);
|
|
383
|
+
const c2 = {
|
|
384
|
+
x: targetEntryWorld.x + tgtNormalWorld.x * offset,
|
|
385
|
+
y: targetEntryWorld.y + tgtNormalWorld.y * offset
|
|
386
|
+
};
|
|
387
|
+
return { source: sourceExitWorld, target: targetEntryWorld, c1, c2 };
|
|
388
|
+
};
|
|
389
|
+
|
|
331
390
|
// src/edges/clip.ts
|
|
332
391
|
var fullVisibleClipResult = (samples) => ({
|
|
333
392
|
startIndex: 0,
|
|
@@ -588,8 +647,8 @@ var computeEdgeGeometry = (edge, getNode) => {
|
|
|
588
647
|
targetNodeId
|
|
589
648
|
};
|
|
590
649
|
}
|
|
591
|
-
|
|
592
|
-
|
|
650
|
+
let sourceWorld = projectEndToWorld(edge.source, getNode);
|
|
651
|
+
let targetWorld = projectEndToWorld(edge.target, getNode);
|
|
593
652
|
if (!sourceWorld || !targetWorld) return null;
|
|
594
653
|
let samples;
|
|
595
654
|
if (edge.pathStyle === "bezier") {
|
|
@@ -598,6 +657,12 @@ var computeEdgeGeometry = (edge, getNode) => {
|
|
|
598
657
|
if (edge.control && edge.control.length >= 2) {
|
|
599
658
|
c1 = edge.control[0];
|
|
600
659
|
c2 = edge.control[1];
|
|
660
|
+
} else if (sourceNode && targetNode && isAttached(edge.source) && isAttached(edge.target) && isLocalOffsetInsideBody(edge.source.localOffset, sourceNode) && isLocalOffsetInsideBody(edge.target.localOffset, targetNode)) {
|
|
661
|
+
const r = computeAsymmetricRoute(sourceNode, targetNode);
|
|
662
|
+
sourceWorld = r.source;
|
|
663
|
+
targetWorld = r.target;
|
|
664
|
+
c1 = r.c1;
|
|
665
|
+
c2 = r.c2;
|
|
601
666
|
} else {
|
|
602
667
|
const sourceNormal = sourceNode && isAttached(edge.source) ? rotateVecByAngle(
|
|
603
668
|
sideNormalLocal(
|
|
@@ -1050,7 +1115,6 @@ var COMPOSITE = /* @__PURE__ */ new Set([
|
|
|
1050
1115
|
var isCompositePrimitive = (type) => COMPOSITE.has(type);
|
|
1051
1116
|
var isDrawablePrimitive = (type) => ATOMIC.has(type) || COMPOSITE.has(type);
|
|
1052
1117
|
var PLAIN_RECT_CORNER_THRESHOLD_PX = 1.5;
|
|
1053
|
-
var STROKE_VISIBILITY_THRESHOLD_PX = 0.5;
|
|
1054
1118
|
var LAYERED_OFFSET = 12;
|
|
1055
1119
|
var drawShape = (ctx, node, scale, theme, opts) => {
|
|
1056
1120
|
if (!isDrawablePrimitive(node.type)) return;
|
|
@@ -1069,7 +1133,7 @@ var drawAtomic = (ctx, type, w, h, style, scale, theme, opts) => {
|
|
|
1069
1133
|
const fill = resolveColor(style, "backgroundColor", DEFAULT_STYLE.backgroundColor, theme);
|
|
1070
1134
|
const stroke = resolveColor(style, "strokeColor", DEFAULT_STYLE.strokeColor, theme);
|
|
1071
1135
|
const fillVisible = !isFullyTransparent(fill);
|
|
1072
|
-
const strokeVisible = strokeWidth > 0 &&
|
|
1136
|
+
const strokeVisible = strokeWidth > 0 && !isFullyTransparent(stroke);
|
|
1073
1137
|
if (!fillVisible && !strokeVisible) return;
|
|
1074
1138
|
const cornerRadius = (style?.roundness ?? DEFAULT_STYLE.roundness) * 4;
|
|
1075
1139
|
switch (type) {
|
|
@@ -1106,7 +1170,7 @@ var drawAtomic = (ctx, type, w, h, style, scale, theme, opts) => {
|
|
|
1106
1170
|
}
|
|
1107
1171
|
if (strokeVisible && !opts?.skipStroke) {
|
|
1108
1172
|
ctx.strokeStyle = stroke;
|
|
1109
|
-
ctx.lineWidth = strokeWidth;
|
|
1173
|
+
ctx.lineWidth = Math.max(strokeWidth, 1 / scale);
|
|
1110
1174
|
ctx.setLineDash(dashPatternFor(style?.strokeStyle, strokeWidth));
|
|
1111
1175
|
ctx.stroke();
|
|
1112
1176
|
}
|
|
@@ -1482,13 +1546,16 @@ var paintAtomicRough = (rc, ctx, type, w, h, style, scale, theme, seed) => {
|
|
|
1482
1546
|
const isDark = theme?.("mode") === "dark";
|
|
1483
1547
|
const fill = resolveColor(style, "backgroundColor", DEFAULT_STYLE.backgroundColor, theme);
|
|
1484
1548
|
const strokeColor = deriveRoughStrokeColor(rawStroke, fill, isDark);
|
|
1485
|
-
const
|
|
1486
|
-
if (
|
|
1549
|
+
const rawStrokeWidth = resolveStrokeWidth(style, theme);
|
|
1550
|
+
if (rawStrokeWidth <= 0) return;
|
|
1487
1551
|
const roughness = style?.roughness ?? 0;
|
|
1488
1552
|
if (roughness <= 0) return;
|
|
1553
|
+
const isNoBorderIntent = isFullyTransparent(rawStroke);
|
|
1554
|
+
const effectiveStrokeStyle = isNoBorderIntent ? "solid" : style?.strokeStyle ?? "solid";
|
|
1555
|
+
const strokeWidth = isNoBorderIntent ? DEFAULT_STYLE.strokeWidth : rawStrokeWidth;
|
|
1489
1556
|
const cornerRadius = (style?.roundness ?? DEFAULT_STYLE.roundness) * 4;
|
|
1490
1557
|
const radius = Math.max(0, Math.min(cornerRadius, w / 2, h / 2));
|
|
1491
|
-
const dash = dashPatternFor(
|
|
1558
|
+
const dash = dashPatternFor(effectiveStrokeStyle, strokeWidth);
|
|
1492
1559
|
const detail = apparentDetail(Math.max(w, h), scale);
|
|
1493
1560
|
const cacheKey = [
|
|
1494
1561
|
type,
|
|
@@ -1497,7 +1564,7 @@ var paintAtomicRough = (rc, ctx, type, w, h, style, scale, theme, seed) => {
|
|
|
1497
1564
|
radius.toFixed(1),
|
|
1498
1565
|
strokeColor,
|
|
1499
1566
|
strokeWidth.toFixed(2),
|
|
1500
|
-
|
|
1567
|
+
effectiveStrokeStyle,
|
|
1501
1568
|
roughness.toFixed(2),
|
|
1502
1569
|
seed,
|
|
1503
1570
|
detail.curveStepCount,
|
|
@@ -1605,7 +1672,7 @@ var buildPath = (type, x, y, w, h, radius) => {
|
|
|
1605
1672
|
};
|
|
1606
1673
|
|
|
1607
1674
|
// src/text/tokens.ts
|
|
1608
|
-
var INLINE_PATTERN = /(
|
|
1675
|
+
var INLINE_PATTERN = /(\$\$[^\n]+?\$\$|\*\*[^*]+\*\*|==[^=\s](?:[^=]*?[^=\s])?==|`[^`]+`|\*[^*]+\*|__[^_]+__|~~[^~]+~~|_[^_]+_|\[[^\]]+\]\([^)]+\))/g;
|
|
1609
1676
|
var HR_LINE_PATTERN = /^[ \t]*---[ \t]*$/;
|
|
1610
1677
|
var DOUBLE_HR_LINE_PATTERN = /^[ \t]*===[ \t]*$/;
|
|
1611
1678
|
var transformSymbols = (value) => value.replace(/<=>|<->|<-|->|\[\]|\[[vx]\]/gi, (match) => {
|
|
@@ -1643,8 +1710,8 @@ var tokenizeInline = (segment) => {
|
|
|
1643
1710
|
tokens.push({ type: "link", content: transformSymbols(match.slice(1, splitIndex)) });
|
|
1644
1711
|
} else if (match.startsWith("`") && match.endsWith("`")) {
|
|
1645
1712
|
tokens.push({ type: "code", content: match.slice(1, -1) });
|
|
1646
|
-
} else if (match.startsWith("
|
|
1647
|
-
tokens.push({ type: "math", content: match.slice(
|
|
1713
|
+
} else if (match.startsWith("$$") && match.endsWith("$$")) {
|
|
1714
|
+
tokens.push({ type: "math", content: match.slice(2, -2) });
|
|
1648
1715
|
} else {
|
|
1649
1716
|
tokens.push({ type: "text", content: transformSymbols(match) });
|
|
1650
1717
|
}
|
|
@@ -2648,7 +2715,7 @@ var DEFAULT_EDGE_STYLE = {
|
|
|
2648
2715
|
sourceArrowhead: "none",
|
|
2649
2716
|
targetArrowhead: "arrow-filled"
|
|
2650
2717
|
};
|
|
2651
|
-
var
|
|
2718
|
+
var STROKE_VISIBILITY_THRESHOLD_PX = 0.5;
|
|
2652
2719
|
var ARROWHEAD_VISIBILITY_THRESHOLD_PX = 2;
|
|
2653
2720
|
var samplePaintStride = (scale) => {
|
|
2654
2721
|
if (scale < 0.15) return 8;
|
|
@@ -2662,7 +2729,7 @@ var drawEdge = (ctx, edge, geom, sourceNode, targetNode, scale, theme, opts) =>
|
|
|
2662
2729
|
if (samples.length < 2) return;
|
|
2663
2730
|
const style = edge.style;
|
|
2664
2731
|
const strokeWidth = typeof style?.strokeWidth === "number" ? style.strokeWidth : theme?.("strokeWidth") ?? DEFAULT_EDGE_STYLE.strokeWidth;
|
|
2665
|
-
if (strokeWidth * scale <
|
|
2732
|
+
if (strokeWidth * scale < STROKE_VISIBILITY_THRESHOLD_PX) return;
|
|
2666
2733
|
const strokeColor = typeof style?.strokeColor === "string" ? style.strokeColor : theme?.("edge.strokeColor") ?? DEFAULT_EDGE_STYLE.strokeColor;
|
|
2667
2734
|
const sourceArrowhead = style?.sourceArrowhead ?? DEFAULT_EDGE_STYLE.sourceArrowhead;
|
|
2668
2735
|
const targetArrowhead = style?.targetArrowhead ?? DEFAULT_EDGE_STYLE.targetArrowhead;
|
|
@@ -3378,6 +3445,8 @@ var idleInteractionState = () => ({
|
|
|
3378
3445
|
resizeHandle: null,
|
|
3379
3446
|
resizeLockAspect: false,
|
|
3380
3447
|
resizeFromCenter: false,
|
|
3448
|
+
resizeDraft: null,
|
|
3449
|
+
midpointDraft: null,
|
|
3381
3450
|
marqueeRect: null,
|
|
3382
3451
|
marqueeAdditive: false,
|
|
3383
3452
|
draftEdge: null,
|
|
@@ -4954,7 +5023,9 @@ var createRenderer = (opts) => {
|
|
|
4954
5023
|
const scale = camera.z * surface.dpr;
|
|
4955
5024
|
const interaction = store.getInteractionState();
|
|
4956
5025
|
const excludedNodes = interaction.mode === "dragging" || interaction.mode === "resizing" ? new Set(interaction.draggedIds) : null;
|
|
4957
|
-
const
|
|
5026
|
+
const baseExcludedEdges = excludedNodes ? incidentEdgeIds(excludedNodes) : null;
|
|
5027
|
+
const midpointEdgeId = interaction.midpointDraft?.edgeId ?? null;
|
|
5028
|
+
const excludedEdges = midpointEdgeId !== null ? /* @__PURE__ */ new Set([...baseExcludedEdges ?? [], midpointEdgeId]) : baseExcludedEdges;
|
|
4958
5029
|
paintBackground(surface.ctx, { viewport, zoom: camera.z, background });
|
|
4959
5030
|
const visible = visibleNodes(camera, viewport);
|
|
4960
5031
|
const isMoving2 = interaction.mode === "panning" || interaction.mode === "zooming" || interaction.mode === "dragging" || interaction.mode === "resizing" || interaction.mode === "rotating";
|
|
@@ -5366,6 +5437,23 @@ var createRenderer = (opts) => {
|
|
|
5366
5437
|
}
|
|
5367
5438
|
}
|
|
5368
5439
|
}
|
|
5440
|
+
if (interaction.midpointDraft) {
|
|
5441
|
+
const { edgeId, control } = interaction.midpointDraft;
|
|
5442
|
+
const edge = store.getEdge(edgeId);
|
|
5443
|
+
if (edge) {
|
|
5444
|
+
const draftEdge = { ...edge, control };
|
|
5445
|
+
const geom = computeEdgeGeometry(draftEdge, (id) => store.getNode(id));
|
|
5446
|
+
if (geom) {
|
|
5447
|
+
const sourceNode = geom.sourceNodeId ? store.getNode(geom.sourceNodeId) ?? null : null;
|
|
5448
|
+
const targetNode = geom.targetNodeId ? store.getNode(geom.targetNodeId) ?? null : null;
|
|
5449
|
+
drawEdge(ctx, draftEdge, geom, sourceNode, targetNode, scale, theme, {
|
|
5450
|
+
zoom: camera.z,
|
|
5451
|
+
dpr: interactiveSurface.dpr,
|
|
5452
|
+
isMoving: true
|
|
5453
|
+
});
|
|
5454
|
+
}
|
|
5455
|
+
}
|
|
5456
|
+
}
|
|
5369
5457
|
const selection = store.getSelection();
|
|
5370
5458
|
const selectedNodeIds = [];
|
|
5371
5459
|
const selectedEdgeIds = [];
|
|
@@ -5438,7 +5526,12 @@ var createRenderer = (opts) => {
|
|
|
5438
5526
|
y: orig.y + interaction.dragDelta.y
|
|
5439
5527
|
});
|
|
5440
5528
|
} else {
|
|
5441
|
-
|
|
5529
|
+
const d = interaction.resizeDraft;
|
|
5530
|
+
if (d) {
|
|
5531
|
+
m.set(orig.id, { ...live, x: d.x, y: d.y, w: d.w, h: d.h, angle: d.angle });
|
|
5532
|
+
} else {
|
|
5533
|
+
m.set(orig.id, live);
|
|
5534
|
+
}
|
|
5442
5535
|
}
|
|
5443
5536
|
}
|
|
5444
5537
|
return m;
|