@skillpet/circuit 0.6.2 → 0.6.4
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/README.de.md +150 -0
- package/README.es.md +150 -0
- package/README.fr.md +150 -0
- package/README.ja.md +150 -0
- package/README.ko.md +150 -0
- package/README.md +26 -1
- package/README.zh-CN.md +150 -0
- package/dist/circuit.bundle.js +87 -68
- package/dist/circuit.bundle.min.js +20 -20
- package/dist/circuit.esm.js +87 -68
- package/dist/drawing-transition.d.ts +9 -9
- package/dist/index.cjs +87 -68
- package/package.json +1 -1
package/dist/circuit.esm.js
CHANGED
|
@@ -15146,8 +15146,8 @@ var _SvgFigure = class _SvgFigure {
|
|
|
15146
15146
|
let [x0, y0] = this.xform(x, y);
|
|
15147
15147
|
const fontsize = opts.fontsize ?? 14;
|
|
15148
15148
|
let font = opts.fontfamily ?? "sans-serif";
|
|
15149
|
-
if (font.toLowerCase() === "sans
|
|
15150
|
-
font = "sans";
|
|
15149
|
+
if (font.toLowerCase() === "sans" || font.toLowerCase() === "arial") {
|
|
15150
|
+
font = "sans-serif";
|
|
15151
15151
|
}
|
|
15152
15152
|
const valign = opts.valign ?? "center";
|
|
15153
15153
|
if (valign === "base") {
|
|
@@ -15159,14 +15159,13 @@ var _SvgFigure = class _SvgFigure {
|
|
|
15159
15159
|
const rot = opts.rotation ?? 0;
|
|
15160
15160
|
const transform = rot !== 0 ? ` transform="rotate(${fmt(rot)} ${fmt(x0)} ${fmt(y0)})"` : "";
|
|
15161
15161
|
const color = opts.color ?? "black";
|
|
15162
|
-
const textY = y0 - fontsize;
|
|
15163
15162
|
let textContent;
|
|
15164
15163
|
if (opts.textDecoration) {
|
|
15165
15164
|
textContent = `<tspan text-decoration="${opts.textDecoration}">${escapeXml(s)}</tspan>`;
|
|
15166
15165
|
} else {
|
|
15167
15166
|
textContent = escapeXml(s);
|
|
15168
15167
|
}
|
|
15169
|
-
let inner2 = `<text x="${fmt(x0)}" y="${fmt(
|
|
15168
|
+
let inner2 = `<text x="${fmt(x0)}" y="${fmt(y0)}" dominant-baseline="${baseline}" fill="${escapeXml(color)}" font-size="${fmt(fontsize)}" font-family="${escapeXml(font)}" text-anchor="${anchor}"${transform}>${textContent}</text>`;
|
|
15170
15169
|
if (opts.href) {
|
|
15171
15170
|
inner2 = `<a href="${escapeXml(opts.href)}">${inner2}</a>`;
|
|
15172
15171
|
}
|
|
@@ -17345,51 +17344,55 @@ function resolveElementColor(el) {
|
|
|
17345
17344
|
const p = mergeParamsFirstWins(el.userParams, el.elmParams, el.defaults, el.dwgParams);
|
|
17346
17345
|
return p.color ?? "black";
|
|
17347
17346
|
}
|
|
17348
|
-
|
|
17349
|
-
|
|
17350
|
-
|
|
17351
|
-
|
|
17352
|
-
|
|
17353
|
-
|
|
17347
|
+
var EXCLUDED_ANCHORS = /* @__PURE__ */ new Set([
|
|
17348
|
+
"xy",
|
|
17349
|
+
"center",
|
|
17350
|
+
"istart",
|
|
17351
|
+
"iend",
|
|
17352
|
+
"mid",
|
|
17353
|
+
"label",
|
|
17354
|
+
"vd",
|
|
17355
|
+
"vs",
|
|
17356
|
+
"n1",
|
|
17357
|
+
"n2",
|
|
17358
|
+
"n1a",
|
|
17359
|
+
"n2a"
|
|
17360
|
+
]);
|
|
17361
|
+
function isConnectionAnchor(name) {
|
|
17362
|
+
return !EXCLUDED_ANCHORS.has(name);
|
|
17354
17363
|
}
|
|
17355
|
-
function
|
|
17364
|
+
function getConnectionAnchors(el) {
|
|
17356
17365
|
const pts = [];
|
|
17357
|
-
const
|
|
17358
|
-
|
|
17359
|
-
for (const [name, pt] of Object.entries(aa)) {
|
|
17360
|
-
if (name.startsWith("in") && /^in\d+$/.test(name)) {
|
|
17361
|
-
if (!aa.start || !pointsClose(pt, aa.start, 0.01)) pts.push(pt);
|
|
17362
|
-
}
|
|
17366
|
+
for (const [name, pt] of Object.entries(el.absanchors)) {
|
|
17367
|
+
if (isConnectionAnchor(name)) pts.push(pt);
|
|
17363
17368
|
}
|
|
17364
17369
|
return pts;
|
|
17365
17370
|
}
|
|
17366
|
-
function pointsClose(a, b, tol) {
|
|
17367
|
-
return Math.hypot(a.x - b.x, a.y - b.y) <= tol;
|
|
17368
|
-
}
|
|
17369
17371
|
function buildConnectionGraph(elements) {
|
|
17370
17372
|
const edges = [];
|
|
17371
17373
|
const seen = /* @__PURE__ */ new Set();
|
|
17372
17374
|
const tol = 0.5;
|
|
17373
17375
|
for (let i = 0; i < elements.length; i++) {
|
|
17374
|
-
const
|
|
17375
|
-
const
|
|
17376
|
-
|
|
17377
|
-
|
|
17378
|
-
for (let j =
|
|
17379
|
-
|
|
17380
|
-
const
|
|
17381
|
-
|
|
17382
|
-
|
|
17383
|
-
|
|
17384
|
-
|
|
17385
|
-
|
|
17386
|
-
|
|
17387
|
-
if (!pointsClose(fp, tp, tol)) continue;
|
|
17376
|
+
const elA = elements[i];
|
|
17377
|
+
const colorA = resolveElementColor(elA);
|
|
17378
|
+
const anchorsA = getConnectionAnchors(elA);
|
|
17379
|
+
if (anchorsA.length === 0) continue;
|
|
17380
|
+
for (let j = i + 1; j < elements.length; j++) {
|
|
17381
|
+
const elB = elements[j];
|
|
17382
|
+
const colorB = resolveElementColor(elB);
|
|
17383
|
+
if (colorsEqual(colorA, colorB)) continue;
|
|
17384
|
+
const anchorsB = getConnectionAnchors(elB);
|
|
17385
|
+
if (anchorsB.length === 0) continue;
|
|
17386
|
+
for (const pa of anchorsA) {
|
|
17387
|
+
for (const pb of anchorsB) {
|
|
17388
|
+
if (Math.hypot(pa.x - pb.x, pa.y - pb.y) > tol) continue;
|
|
17388
17389
|
const key = `${i}|${j}`;
|
|
17389
17390
|
if (seen.has(key)) continue;
|
|
17390
17391
|
seen.add(key);
|
|
17391
|
-
edges.push({
|
|
17392
|
+
edges.push({ elA, elB, colorA, colorB, junctionPt: pa });
|
|
17393
|
+
break;
|
|
17392
17394
|
}
|
|
17395
|
+
if (seen.has(`${i}|${j}`)) break;
|
|
17393
17396
|
}
|
|
17394
17397
|
}
|
|
17395
17398
|
}
|
|
@@ -17405,26 +17408,28 @@ function assignLeadTransitionIds(elements, edges, scale) {
|
|
|
17405
17408
|
const cleanups = [];
|
|
17406
17409
|
let n = 0;
|
|
17407
17410
|
for (const edge of edges) {
|
|
17408
|
-
const
|
|
17409
|
-
const
|
|
17410
|
-
if (!
|
|
17411
|
-
if (
|
|
17411
|
+
const segA = findSegAtJunction(edge.elA, edge.junctionPt);
|
|
17412
|
+
const segB = findSegAtJunction(edge.elB, edge.junctionPt);
|
|
17413
|
+
if (!segA && !segB) continue;
|
|
17414
|
+
if (segA?.gradientStrokeId && segB?.gradientStrokeId) continue;
|
|
17412
17415
|
let gx1, gy1, gx2, gy2;
|
|
17413
|
-
if (
|
|
17414
|
-
const
|
|
17415
|
-
const
|
|
17416
|
-
|
|
17417
|
-
|
|
17418
|
-
|
|
17419
|
-
|
|
17420
|
-
|
|
17421
|
-
|
|
17416
|
+
if (segA && segB) {
|
|
17417
|
+
const a = segEndpointsSvg(edge.elA, segA, scale);
|
|
17418
|
+
const b = segEndpointsSvg(edge.elB, segB, scale);
|
|
17419
|
+
const aNear = nearFarSvg(edge.elA, segA, edge.junctionPt, scale);
|
|
17420
|
+
const bNear = nearFarSvg(edge.elB, segB, edge.junctionPt, scale);
|
|
17421
|
+
gx1 = aNear.farX;
|
|
17422
|
+
gy1 = aNear.farY;
|
|
17423
|
+
gx2 = bNear.farX;
|
|
17424
|
+
gy2 = bNear.farY;
|
|
17425
|
+
} else if (segA) {
|
|
17426
|
+
const c = segEndpointsSvg(edge.elA, segA, scale);
|
|
17422
17427
|
gx1 = c.x1;
|
|
17423
17428
|
gy1 = c.y1;
|
|
17424
17429
|
gx2 = c.x2;
|
|
17425
17430
|
gy2 = c.y2;
|
|
17426
17431
|
} else {
|
|
17427
|
-
const c = segEndpointsSvg(edge.
|
|
17432
|
+
const c = segEndpointsSvg(edge.elB, segB, scale);
|
|
17428
17433
|
gx1 = c.x1;
|
|
17429
17434
|
gy1 = c.y1;
|
|
17430
17435
|
gx2 = c.x2;
|
|
@@ -17432,17 +17437,17 @@ function assignLeadTransitionIds(elements, edges, scale) {
|
|
|
17432
17437
|
}
|
|
17433
17438
|
if (gradientVectorLength({ x1: gx1, y1: gy1, x2: gx2, y2: gy2 }) < 1e-6) continue;
|
|
17434
17439
|
const id = `sd-trans-${n++}`;
|
|
17435
|
-
parts.push(gradientXml(id, gx1, gy1, gx2, gy2, edge.
|
|
17436
|
-
if (
|
|
17437
|
-
|
|
17440
|
+
parts.push(gradientXml(id, gx1, gy1, gx2, gy2, edge.colorA, edge.colorB));
|
|
17441
|
+
if (segA && !segA.gradientStrokeId) {
|
|
17442
|
+
segA.gradientStrokeId = id;
|
|
17438
17443
|
cleanups.push(() => {
|
|
17439
|
-
|
|
17444
|
+
segA.gradientStrokeId = void 0;
|
|
17440
17445
|
});
|
|
17441
17446
|
}
|
|
17442
|
-
if (
|
|
17443
|
-
|
|
17447
|
+
if (segB && !segB.gradientStrokeId) {
|
|
17448
|
+
segB.gradientStrokeId = id;
|
|
17444
17449
|
cleanups.push(() => {
|
|
17445
|
-
|
|
17450
|
+
segB.gradientStrokeId = void 0;
|
|
17446
17451
|
});
|
|
17447
17452
|
}
|
|
17448
17453
|
}
|
|
@@ -17453,26 +17458,21 @@ function assignLeadTransitionIds(elements, edges, scale) {
|
|
|
17453
17458
|
}
|
|
17454
17459
|
};
|
|
17455
17460
|
}
|
|
17456
|
-
function
|
|
17457
|
-
const
|
|
17461
|
+
function findSegAtJunction(el, junctionPt) {
|
|
17462
|
+
const tol = 0.6;
|
|
17458
17463
|
for (const s of el.segments) {
|
|
17459
|
-
if (s instanceof Segment
|
|
17464
|
+
if (!(s instanceof Segment)) continue;
|
|
17465
|
+
if (s.role !== "lead1" && s.role !== "lead2") continue;
|
|
17466
|
+
if (segTouchesPoint(el, s, junctionPt, tol)) return s;
|
|
17460
17467
|
}
|
|
17461
|
-
return findSegmentNearPoint(el, junctionPt);
|
|
17462
|
-
}
|
|
17463
|
-
function findSegmentNearPoint(el, absPt) {
|
|
17464
17468
|
let best;
|
|
17465
17469
|
let bestDist = Infinity;
|
|
17466
|
-
const tol = 0.6;
|
|
17467
17470
|
for (const s of el.segments) {
|
|
17468
17471
|
if (!(s instanceof Segment)) continue;
|
|
17469
17472
|
if (s.path.length < 2) continue;
|
|
17470
17473
|
if (s.role === "body") continue;
|
|
17471
|
-
|
|
17472
|
-
const
|
|
17473
|
-
const d0 = Math.hypot(p0.x - absPt.x, p0.y - absPt.y);
|
|
17474
|
-
const dN = Math.hypot(pN.x - absPt.x, pN.y - absPt.y);
|
|
17475
|
-
const d = Math.min(d0, dN);
|
|
17474
|
+
if (s.path.length > 6) continue;
|
|
17475
|
+
const d = segDistToPoint(el, s, junctionPt);
|
|
17476
17476
|
if (d < bestDist && d < tol) {
|
|
17477
17477
|
bestDist = d;
|
|
17478
17478
|
best = s;
|
|
@@ -17480,6 +17480,25 @@ function findSegmentNearPoint(el, absPt) {
|
|
|
17480
17480
|
}
|
|
17481
17481
|
return best;
|
|
17482
17482
|
}
|
|
17483
|
+
function segTouchesPoint(el, seg, absPt, tol) {
|
|
17484
|
+
return segDistToPoint(el, seg, absPt) < tol;
|
|
17485
|
+
}
|
|
17486
|
+
function segDistToPoint(el, seg, absPt) {
|
|
17487
|
+
const p0 = el.transform.transform(seg.path[0]);
|
|
17488
|
+
const pN = el.transform.transform(seg.path[seg.path.length - 1]);
|
|
17489
|
+
return Math.min(
|
|
17490
|
+
Math.hypot(p0.x - absPt.x, p0.y - absPt.y),
|
|
17491
|
+
Math.hypot(pN.x - absPt.x, pN.y - absPt.y)
|
|
17492
|
+
);
|
|
17493
|
+
}
|
|
17494
|
+
function nearFarSvg(el, seg, junctionPt, scale) {
|
|
17495
|
+
const p0 = el.transform.transform(seg.path[0]);
|
|
17496
|
+
const pN = el.transform.transform(seg.path[seg.path.length - 1]);
|
|
17497
|
+
const d0 = Math.hypot(p0.x - junctionPt.x, p0.y - junctionPt.y);
|
|
17498
|
+
const dN = Math.hypot(pN.x - junctionPt.x, pN.y - junctionPt.y);
|
|
17499
|
+
const far = d0 > dN ? p0 : pN;
|
|
17500
|
+
return { farX: far.x * scale, farY: -far.y * scale };
|
|
17501
|
+
}
|
|
17483
17502
|
function segEndpointsSvg(el, seg, scale) {
|
|
17484
17503
|
const p0 = el.transform.transform(seg.path[0]);
|
|
17485
17504
|
const p1 = el.transform.transform(seg.path[seg.path.length - 1]);
|
|
@@ -8,19 +8,19 @@
|
|
|
8
8
|
import type { Element } from "./element.js";
|
|
9
9
|
import { Point } from "./geometry/point.js";
|
|
10
10
|
interface ConnectionEdge {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
/** The absolute point where the
|
|
11
|
+
elA: Element;
|
|
12
|
+
elB: Element;
|
|
13
|
+
colorA: string;
|
|
14
|
+
colorB: string;
|
|
15
|
+
/** The absolute point where the two elements meet. */
|
|
16
16
|
junctionPt: Point;
|
|
17
17
|
}
|
|
18
18
|
/**
|
|
19
|
-
* Find
|
|
20
|
-
*
|
|
19
|
+
* Find pairs of elements that share a connection point (any pin anchor within
|
|
20
|
+
* tolerance) and have different resolved colors.
|
|
21
21
|
*
|
|
22
|
-
* Checks end
|
|
23
|
-
*
|
|
22
|
+
* Checks pin-level anchors (start, end, out, in1, in2, base, collector, etc.)
|
|
23
|
+
* so connections via named pins on multi-terminal elements are detected.
|
|
24
24
|
*/
|
|
25
25
|
export declare function buildConnectionGraph(elements: readonly Element[]): ConnectionEdge[];
|
|
26
26
|
/**
|
package/dist/index.cjs
CHANGED
|
@@ -15533,8 +15533,8 @@ var _SvgFigure = class _SvgFigure {
|
|
|
15533
15533
|
let [x0, y0] = this.xform(x, y);
|
|
15534
15534
|
const fontsize = opts.fontsize ?? 14;
|
|
15535
15535
|
let font = opts.fontfamily ?? "sans-serif";
|
|
15536
|
-
if (font.toLowerCase() === "sans
|
|
15537
|
-
font = "sans";
|
|
15536
|
+
if (font.toLowerCase() === "sans" || font.toLowerCase() === "arial") {
|
|
15537
|
+
font = "sans-serif";
|
|
15538
15538
|
}
|
|
15539
15539
|
const valign = opts.valign ?? "center";
|
|
15540
15540
|
if (valign === "base") {
|
|
@@ -15546,14 +15546,13 @@ var _SvgFigure = class _SvgFigure {
|
|
|
15546
15546
|
const rot = opts.rotation ?? 0;
|
|
15547
15547
|
const transform = rot !== 0 ? ` transform="rotate(${fmt(rot)} ${fmt(x0)} ${fmt(y0)})"` : "";
|
|
15548
15548
|
const color = opts.color ?? "black";
|
|
15549
|
-
const textY = y0 - fontsize;
|
|
15550
15549
|
let textContent;
|
|
15551
15550
|
if (opts.textDecoration) {
|
|
15552
15551
|
textContent = `<tspan text-decoration="${opts.textDecoration}">${escapeXml(s)}</tspan>`;
|
|
15553
15552
|
} else {
|
|
15554
15553
|
textContent = escapeXml(s);
|
|
15555
15554
|
}
|
|
15556
|
-
let inner2 = `<text x="${fmt(x0)}" y="${fmt(
|
|
15555
|
+
let inner2 = `<text x="${fmt(x0)}" y="${fmt(y0)}" dominant-baseline="${baseline}" fill="${escapeXml(color)}" font-size="${fmt(fontsize)}" font-family="${escapeXml(font)}" text-anchor="${anchor}"${transform}>${textContent}</text>`;
|
|
15557
15556
|
if (opts.href) {
|
|
15558
15557
|
inner2 = `<a href="${escapeXml(opts.href)}">${inner2}</a>`;
|
|
15559
15558
|
}
|
|
@@ -17732,51 +17731,55 @@ function resolveElementColor(el) {
|
|
|
17732
17731
|
const p = mergeParamsFirstWins(el.userParams, el.elmParams, el.defaults, el.dwgParams);
|
|
17733
17732
|
return p.color ?? "black";
|
|
17734
17733
|
}
|
|
17735
|
-
|
|
17736
|
-
|
|
17737
|
-
|
|
17738
|
-
|
|
17739
|
-
|
|
17740
|
-
|
|
17734
|
+
var EXCLUDED_ANCHORS = /* @__PURE__ */ new Set([
|
|
17735
|
+
"xy",
|
|
17736
|
+
"center",
|
|
17737
|
+
"istart",
|
|
17738
|
+
"iend",
|
|
17739
|
+
"mid",
|
|
17740
|
+
"label",
|
|
17741
|
+
"vd",
|
|
17742
|
+
"vs",
|
|
17743
|
+
"n1",
|
|
17744
|
+
"n2",
|
|
17745
|
+
"n1a",
|
|
17746
|
+
"n2a"
|
|
17747
|
+
]);
|
|
17748
|
+
function isConnectionAnchor(name) {
|
|
17749
|
+
return !EXCLUDED_ANCHORS.has(name);
|
|
17741
17750
|
}
|
|
17742
|
-
function
|
|
17751
|
+
function getConnectionAnchors(el) {
|
|
17743
17752
|
const pts = [];
|
|
17744
|
-
const
|
|
17745
|
-
|
|
17746
|
-
for (const [name, pt] of Object.entries(aa)) {
|
|
17747
|
-
if (name.startsWith("in") && /^in\d+$/.test(name)) {
|
|
17748
|
-
if (!aa.start || !pointsClose(pt, aa.start, 0.01)) pts.push(pt);
|
|
17749
|
-
}
|
|
17753
|
+
for (const [name, pt] of Object.entries(el.absanchors)) {
|
|
17754
|
+
if (isConnectionAnchor(name)) pts.push(pt);
|
|
17750
17755
|
}
|
|
17751
17756
|
return pts;
|
|
17752
17757
|
}
|
|
17753
|
-
function pointsClose(a, b, tol) {
|
|
17754
|
-
return Math.hypot(a.x - b.x, a.y - b.y) <= tol;
|
|
17755
|
-
}
|
|
17756
17758
|
function buildConnectionGraph(elements) {
|
|
17757
17759
|
const edges = [];
|
|
17758
17760
|
const seen = /* @__PURE__ */ new Set();
|
|
17759
17761
|
const tol = 0.5;
|
|
17760
17762
|
for (let i = 0; i < elements.length; i++) {
|
|
17761
|
-
const
|
|
17762
|
-
const
|
|
17763
|
-
|
|
17764
|
-
|
|
17765
|
-
for (let j =
|
|
17766
|
-
|
|
17767
|
-
const
|
|
17768
|
-
|
|
17769
|
-
|
|
17770
|
-
|
|
17771
|
-
|
|
17772
|
-
|
|
17773
|
-
|
|
17774
|
-
if (!pointsClose(fp, tp, tol)) continue;
|
|
17763
|
+
const elA = elements[i];
|
|
17764
|
+
const colorA = resolveElementColor(elA);
|
|
17765
|
+
const anchorsA = getConnectionAnchors(elA);
|
|
17766
|
+
if (anchorsA.length === 0) continue;
|
|
17767
|
+
for (let j = i + 1; j < elements.length; j++) {
|
|
17768
|
+
const elB = elements[j];
|
|
17769
|
+
const colorB = resolveElementColor(elB);
|
|
17770
|
+
if (colorsEqual(colorA, colorB)) continue;
|
|
17771
|
+
const anchorsB = getConnectionAnchors(elB);
|
|
17772
|
+
if (anchorsB.length === 0) continue;
|
|
17773
|
+
for (const pa of anchorsA) {
|
|
17774
|
+
for (const pb of anchorsB) {
|
|
17775
|
+
if (Math.hypot(pa.x - pb.x, pa.y - pb.y) > tol) continue;
|
|
17775
17776
|
const key = `${i}|${j}`;
|
|
17776
17777
|
if (seen.has(key)) continue;
|
|
17777
17778
|
seen.add(key);
|
|
17778
|
-
edges.push({
|
|
17779
|
+
edges.push({ elA, elB, colorA, colorB, junctionPt: pa });
|
|
17780
|
+
break;
|
|
17779
17781
|
}
|
|
17782
|
+
if (seen.has(`${i}|${j}`)) break;
|
|
17780
17783
|
}
|
|
17781
17784
|
}
|
|
17782
17785
|
}
|
|
@@ -17792,26 +17795,28 @@ function assignLeadTransitionIds(elements, edges, scale) {
|
|
|
17792
17795
|
const cleanups = [];
|
|
17793
17796
|
let n = 0;
|
|
17794
17797
|
for (const edge of edges) {
|
|
17795
|
-
const
|
|
17796
|
-
const
|
|
17797
|
-
if (!
|
|
17798
|
-
if (
|
|
17798
|
+
const segA = findSegAtJunction(edge.elA, edge.junctionPt);
|
|
17799
|
+
const segB = findSegAtJunction(edge.elB, edge.junctionPt);
|
|
17800
|
+
if (!segA && !segB) continue;
|
|
17801
|
+
if (segA?.gradientStrokeId && segB?.gradientStrokeId) continue;
|
|
17799
17802
|
let gx1, gy1, gx2, gy2;
|
|
17800
|
-
if (
|
|
17801
|
-
const
|
|
17802
|
-
const
|
|
17803
|
-
|
|
17804
|
-
|
|
17805
|
-
|
|
17806
|
-
|
|
17807
|
-
|
|
17808
|
-
|
|
17803
|
+
if (segA && segB) {
|
|
17804
|
+
const a = segEndpointsSvg(edge.elA, segA, scale);
|
|
17805
|
+
const b = segEndpointsSvg(edge.elB, segB, scale);
|
|
17806
|
+
const aNear = nearFarSvg(edge.elA, segA, edge.junctionPt, scale);
|
|
17807
|
+
const bNear = nearFarSvg(edge.elB, segB, edge.junctionPt, scale);
|
|
17808
|
+
gx1 = aNear.farX;
|
|
17809
|
+
gy1 = aNear.farY;
|
|
17810
|
+
gx2 = bNear.farX;
|
|
17811
|
+
gy2 = bNear.farY;
|
|
17812
|
+
} else if (segA) {
|
|
17813
|
+
const c = segEndpointsSvg(edge.elA, segA, scale);
|
|
17809
17814
|
gx1 = c.x1;
|
|
17810
17815
|
gy1 = c.y1;
|
|
17811
17816
|
gx2 = c.x2;
|
|
17812
17817
|
gy2 = c.y2;
|
|
17813
17818
|
} else {
|
|
17814
|
-
const c = segEndpointsSvg(edge.
|
|
17819
|
+
const c = segEndpointsSvg(edge.elB, segB, scale);
|
|
17815
17820
|
gx1 = c.x1;
|
|
17816
17821
|
gy1 = c.y1;
|
|
17817
17822
|
gx2 = c.x2;
|
|
@@ -17819,17 +17824,17 @@ function assignLeadTransitionIds(elements, edges, scale) {
|
|
|
17819
17824
|
}
|
|
17820
17825
|
if (gradientVectorLength({ x1: gx1, y1: gy1, x2: gx2, y2: gy2 }) < 1e-6) continue;
|
|
17821
17826
|
const id = `sd-trans-${n++}`;
|
|
17822
|
-
parts.push(gradientXml(id, gx1, gy1, gx2, gy2, edge.
|
|
17823
|
-
if (
|
|
17824
|
-
|
|
17827
|
+
parts.push(gradientXml(id, gx1, gy1, gx2, gy2, edge.colorA, edge.colorB));
|
|
17828
|
+
if (segA && !segA.gradientStrokeId) {
|
|
17829
|
+
segA.gradientStrokeId = id;
|
|
17825
17830
|
cleanups.push(() => {
|
|
17826
|
-
|
|
17831
|
+
segA.gradientStrokeId = void 0;
|
|
17827
17832
|
});
|
|
17828
17833
|
}
|
|
17829
|
-
if (
|
|
17830
|
-
|
|
17834
|
+
if (segB && !segB.gradientStrokeId) {
|
|
17835
|
+
segB.gradientStrokeId = id;
|
|
17831
17836
|
cleanups.push(() => {
|
|
17832
|
-
|
|
17837
|
+
segB.gradientStrokeId = void 0;
|
|
17833
17838
|
});
|
|
17834
17839
|
}
|
|
17835
17840
|
}
|
|
@@ -17840,26 +17845,21 @@ function assignLeadTransitionIds(elements, edges, scale) {
|
|
|
17840
17845
|
}
|
|
17841
17846
|
};
|
|
17842
17847
|
}
|
|
17843
|
-
function
|
|
17844
|
-
const
|
|
17848
|
+
function findSegAtJunction(el, junctionPt) {
|
|
17849
|
+
const tol = 0.6;
|
|
17845
17850
|
for (const s of el.segments) {
|
|
17846
|
-
if (s instanceof Segment
|
|
17851
|
+
if (!(s instanceof Segment)) continue;
|
|
17852
|
+
if (s.role !== "lead1" && s.role !== "lead2") continue;
|
|
17853
|
+
if (segTouchesPoint(el, s, junctionPt, tol)) return s;
|
|
17847
17854
|
}
|
|
17848
|
-
return findSegmentNearPoint(el, junctionPt);
|
|
17849
|
-
}
|
|
17850
|
-
function findSegmentNearPoint(el, absPt) {
|
|
17851
17855
|
let best;
|
|
17852
17856
|
let bestDist = Infinity;
|
|
17853
|
-
const tol = 0.6;
|
|
17854
17857
|
for (const s of el.segments) {
|
|
17855
17858
|
if (!(s instanceof Segment)) continue;
|
|
17856
17859
|
if (s.path.length < 2) continue;
|
|
17857
17860
|
if (s.role === "body") continue;
|
|
17858
|
-
|
|
17859
|
-
const
|
|
17860
|
-
const d0 = Math.hypot(p0.x - absPt.x, p0.y - absPt.y);
|
|
17861
|
-
const dN = Math.hypot(pN.x - absPt.x, pN.y - absPt.y);
|
|
17862
|
-
const d = Math.min(d0, dN);
|
|
17861
|
+
if (s.path.length > 6) continue;
|
|
17862
|
+
const d = segDistToPoint(el, s, junctionPt);
|
|
17863
17863
|
if (d < bestDist && d < tol) {
|
|
17864
17864
|
bestDist = d;
|
|
17865
17865
|
best = s;
|
|
@@ -17867,6 +17867,25 @@ function findSegmentNearPoint(el, absPt) {
|
|
|
17867
17867
|
}
|
|
17868
17868
|
return best;
|
|
17869
17869
|
}
|
|
17870
|
+
function segTouchesPoint(el, seg, absPt, tol) {
|
|
17871
|
+
return segDistToPoint(el, seg, absPt) < tol;
|
|
17872
|
+
}
|
|
17873
|
+
function segDistToPoint(el, seg, absPt) {
|
|
17874
|
+
const p0 = el.transform.transform(seg.path[0]);
|
|
17875
|
+
const pN = el.transform.transform(seg.path[seg.path.length - 1]);
|
|
17876
|
+
return Math.min(
|
|
17877
|
+
Math.hypot(p0.x - absPt.x, p0.y - absPt.y),
|
|
17878
|
+
Math.hypot(pN.x - absPt.x, pN.y - absPt.y)
|
|
17879
|
+
);
|
|
17880
|
+
}
|
|
17881
|
+
function nearFarSvg(el, seg, junctionPt, scale) {
|
|
17882
|
+
const p0 = el.transform.transform(seg.path[0]);
|
|
17883
|
+
const pN = el.transform.transform(seg.path[seg.path.length - 1]);
|
|
17884
|
+
const d0 = Math.hypot(p0.x - junctionPt.x, p0.y - junctionPt.y);
|
|
17885
|
+
const dN = Math.hypot(pN.x - junctionPt.x, pN.y - junctionPt.y);
|
|
17886
|
+
const far = d0 > dN ? p0 : pN;
|
|
17887
|
+
return { farX: far.x * scale, farY: -far.y * scale };
|
|
17888
|
+
}
|
|
17870
17889
|
function segEndpointsSvg(el, seg, scale) {
|
|
17871
17890
|
const p0 = el.transform.transform(seg.path[0]);
|
|
17872
17891
|
const p1 = el.transform.transform(seg.path[seg.path.length - 1]);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@skillpet/circuit",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.4",
|
|
4
4
|
"description": "Circuit diagram library — render electrical schematics from JSON, with interactive SVG, themes, and Vue/React components",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"type": "module",
|