@canvas-harness/core 0.1.10 → 0.1.12

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 CHANGED
@@ -284,15 +284,6 @@ var projectToNodeBoundary = (world, node) => {
284
284
  // src/edges/auto-route.ts
285
285
  var CONTROL_MAX = 200;
286
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
287
  var sideOf = (node, localX, localY) => {
297
288
  const distLeft = localX;
298
289
  const distRight = node.w - localX;
@@ -336,55 +327,17 @@ var autoRouteControls = (sourceWorld, targetWorld, sourceNormalWorld, targetNorm
336
327
  c2: { x: targetWorld.x + nt.x * offset, y: targetWorld.y + nt.y * offset }
337
328
  };
338
329
  };
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 };
330
+ var sideToward = (node, towardWorld) => {
331
+ const local = worldToNodeLocal(towardWorld, node);
332
+ const halfW = node.w / 2;
333
+ const halfH = node.h / 2;
334
+ const dx = local.x - halfW;
335
+ const dy = local.y - halfH;
336
+ if (dx === 0 && dy === 0) return "e";
337
+ const tx = dx === 0 ? Number.POSITIVE_INFINITY : (dx > 0 ? halfW : -halfW) / dx;
338
+ const ty = dy === 0 ? Number.POSITIVE_INFINITY : (dy > 0 ? halfH : -halfH) / dy;
339
+ if (tx <= ty) return dx > 0 ? "e" : "w";
340
+ return dy > 0 ? "s" : "n";
388
341
  };
389
342
 
390
343
  // src/edges/clip.ts
@@ -647,8 +600,8 @@ var computeEdgeGeometry = (edge, getNode) => {
647
600
  targetNodeId
648
601
  };
649
602
  }
650
- let sourceWorld = projectEndToWorld(edge.source, getNode);
651
- let targetWorld = projectEndToWorld(edge.target, getNode);
603
+ const sourceWorld = projectEndToWorld(edge.source, getNode);
604
+ const targetWorld = projectEndToWorld(edge.target, getNode);
652
605
  if (!sourceWorld || !targetWorld) return null;
653
606
  let samples;
654
607
  if (edge.pathStyle === "bezier") {
@@ -657,25 +610,9 @@ var computeEdgeGeometry = (edge, getNode) => {
657
610
  if (edge.control && edge.control.length >= 2) {
658
611
  c1 = edge.control[0];
659
612
  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;
666
613
  } else {
667
- const sourceNormal = sourceNode && isAttached(edge.source) ? rotateVecByAngle(
668
- sideNormalLocal(
669
- sideOf(sourceNode, edge.source.localOffset.x, edge.source.localOffset.y)
670
- ),
671
- sourceNode.angle
672
- ) : null;
673
- const targetNormal = targetNode && isAttached(edge.target) ? rotateVecByAngle(
674
- sideNormalLocal(
675
- sideOf(targetNode, edge.target.localOffset.x, edge.target.localOffset.y)
676
- ),
677
- targetNode.angle
678
- ) : null;
614
+ const sourceNormal = sourceNode ? rotateVecByAngle(sideNormalLocal(sideToward(sourceNode, targetWorld)), sourceNode.angle) : null;
615
+ const targetNormal = targetNode ? rotateVecByAngle(sideNormalLocal(sideToward(targetNode, sourceWorld)), targetNode.angle) : null;
679
616
  ({ c1, c2 } = autoRouteControls(sourceWorld, targetWorld, sourceNormal, targetNormal));
680
617
  }
681
618
  samples = samplesFor("bezier", sourceWorld, targetWorld, [c1, c2]);
@@ -2338,6 +2275,7 @@ var createDefaultTextareaEditor = ({
2338
2275
  wrap.style.borderRadius = "4px";
2339
2276
  wrap.style.background = style.backgroundColor ?? "#ffffff";
2340
2277
  wrap.style.zIndex = "20";
2278
+ wrap.style.pointerEvents = "auto";
2341
2279
  const ta = document.createElement("textarea");
2342
2280
  ta.value = node.content ?? "";
2343
2281
  ta.spellcheck = false;
@@ -4786,7 +4724,13 @@ var paintAtomicRough = (rc, ctx, type, w, h, style, scale, theme, seed) => {
4786
4724
  strokeWidth,
4787
4725
  roughness,
4788
4726
  seed,
4789
- strokeLineDash: dash.length > 0 ? dash : void 0,
4727
+ // Always pass an explicit array (empty = solid) so rough.js calls
4728
+ // ctx.setLineDash() to a known state. Passing `undefined` makes
4729
+ // rough skip that call, and the canvas inherits whatever the
4730
+ // previous draw left behind — a transparent-stroke node's
4731
+ // fill-derived outline would pick up the dash from an earlier
4732
+ // dashed node in the same paint pass.
4733
+ strokeLineDash: dash,
4790
4734
  curveStepCount: detail.curveStepCount,
4791
4735
  maxRandomnessOffset: detail.maxRandomnessOffset
4792
4736
  });
@@ -6812,6 +6756,7 @@ exports.shouldAutoFit = shouldAutoFit;
6812
6756
  exports.shouldRejectTouch = shouldRejectTouch;
6813
6757
  exports.sideNormalLocal = sideNormalLocal;
6814
6758
  exports.sideOf = sideOf;
6759
+ exports.sideToward = sideToward;
6815
6760
  exports.sizeSurface = sizeSurface;
6816
6761
  exports.storeToJSON = storeToJSON;
6817
6762
  exports.subscribeFontEpoch = subscribeFontEpoch;