@skillpet/circuit 0.6.1 → 0.6.3
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/circuit.bundle.js +106 -42
- package/dist/circuit.bundle.min.js +20 -20
- package/dist/circuit.esm.js +106 -42
- package/dist/drawing-transition.d.ts +11 -8
- package/dist/index.cjs +106 -42
- package/package.json +1 -1
package/dist/circuit.esm.js
CHANGED
|
@@ -17345,29 +17345,56 @@ function resolveElementColor(el) {
|
|
|
17345
17345
|
const p = mergeParamsFirstWins(el.userParams, el.elmParams, el.defaults, el.dwgParams);
|
|
17346
17346
|
return p.color ?? "black";
|
|
17347
17347
|
}
|
|
17348
|
+
var EXCLUDED_ANCHORS = /* @__PURE__ */ new Set([
|
|
17349
|
+
"xy",
|
|
17350
|
+
"center",
|
|
17351
|
+
"istart",
|
|
17352
|
+
"iend",
|
|
17353
|
+
"mid",
|
|
17354
|
+
"label",
|
|
17355
|
+
"vd",
|
|
17356
|
+
"vs",
|
|
17357
|
+
"n1",
|
|
17358
|
+
"n2",
|
|
17359
|
+
"n1a",
|
|
17360
|
+
"n2a"
|
|
17361
|
+
]);
|
|
17362
|
+
function isConnectionAnchor(name) {
|
|
17363
|
+
return !EXCLUDED_ANCHORS.has(name);
|
|
17364
|
+
}
|
|
17365
|
+
function getConnectionAnchors(el) {
|
|
17366
|
+
const pts = [];
|
|
17367
|
+
for (const [name, pt] of Object.entries(el.absanchors)) {
|
|
17368
|
+
if (isConnectionAnchor(name)) pts.push(pt);
|
|
17369
|
+
}
|
|
17370
|
+
return pts;
|
|
17371
|
+
}
|
|
17348
17372
|
function buildConnectionGraph(elements) {
|
|
17349
17373
|
const edges = [];
|
|
17350
17374
|
const seen = /* @__PURE__ */ new Set();
|
|
17351
17375
|
const tol = 0.5;
|
|
17352
17376
|
for (let i = 0; i < elements.length; i++) {
|
|
17353
|
-
const
|
|
17354
|
-
const
|
|
17355
|
-
|
|
17356
|
-
|
|
17357
|
-
|
|
17358
|
-
const
|
|
17359
|
-
const
|
|
17360
|
-
if (
|
|
17361
|
-
const
|
|
17362
|
-
|
|
17363
|
-
|
|
17364
|
-
|
|
17365
|
-
|
|
17366
|
-
|
|
17367
|
-
|
|
17368
|
-
|
|
17369
|
-
|
|
17370
|
-
|
|
17377
|
+
const elA = elements[i];
|
|
17378
|
+
const colorA = resolveElementColor(elA);
|
|
17379
|
+
const anchorsA = getConnectionAnchors(elA);
|
|
17380
|
+
if (anchorsA.length === 0) continue;
|
|
17381
|
+
for (let j = i + 1; j < elements.length; j++) {
|
|
17382
|
+
const elB = elements[j];
|
|
17383
|
+
const colorB = resolveElementColor(elB);
|
|
17384
|
+
if (colorsEqual(colorA, colorB)) continue;
|
|
17385
|
+
const anchorsB = getConnectionAnchors(elB);
|
|
17386
|
+
if (anchorsB.length === 0) continue;
|
|
17387
|
+
for (const pa of anchorsA) {
|
|
17388
|
+
for (const pb of anchorsB) {
|
|
17389
|
+
if (Math.hypot(pa.x - pb.x, pa.y - pb.y) > tol) continue;
|
|
17390
|
+
const key = `${i}|${j}`;
|
|
17391
|
+
if (seen.has(key)) continue;
|
|
17392
|
+
seen.add(key);
|
|
17393
|
+
edges.push({ elA, elB, colorA, colorB, junctionPt: pa });
|
|
17394
|
+
break;
|
|
17395
|
+
}
|
|
17396
|
+
if (seen.has(`${i}|${j}`)) break;
|
|
17397
|
+
}
|
|
17371
17398
|
}
|
|
17372
17399
|
}
|
|
17373
17400
|
return edges;
|
|
@@ -17382,26 +17409,28 @@ function assignLeadTransitionIds(elements, edges, scale) {
|
|
|
17382
17409
|
const cleanups = [];
|
|
17383
17410
|
let n = 0;
|
|
17384
17411
|
for (const edge of edges) {
|
|
17385
|
-
const
|
|
17386
|
-
const
|
|
17387
|
-
if (!
|
|
17388
|
-
if (
|
|
17412
|
+
const segA = findSegAtJunction(edge.elA, edge.junctionPt);
|
|
17413
|
+
const segB = findSegAtJunction(edge.elB, edge.junctionPt);
|
|
17414
|
+
if (!segA && !segB) continue;
|
|
17415
|
+
if (segA?.gradientStrokeId && segB?.gradientStrokeId) continue;
|
|
17389
17416
|
let gx1, gy1, gx2, gy2;
|
|
17390
|
-
if (
|
|
17391
|
-
const
|
|
17392
|
-
const
|
|
17393
|
-
|
|
17394
|
-
|
|
17395
|
-
|
|
17396
|
-
|
|
17397
|
-
|
|
17398
|
-
|
|
17417
|
+
if (segA && segB) {
|
|
17418
|
+
const a = segEndpointsSvg(edge.elA, segA, scale);
|
|
17419
|
+
const b = segEndpointsSvg(edge.elB, segB, scale);
|
|
17420
|
+
const aNear = nearFarSvg(edge.elA, segA, edge.junctionPt, scale);
|
|
17421
|
+
const bNear = nearFarSvg(edge.elB, segB, edge.junctionPt, scale);
|
|
17422
|
+
gx1 = aNear.farX;
|
|
17423
|
+
gy1 = aNear.farY;
|
|
17424
|
+
gx2 = bNear.farX;
|
|
17425
|
+
gy2 = bNear.farY;
|
|
17426
|
+
} else if (segA) {
|
|
17427
|
+
const c = segEndpointsSvg(edge.elA, segA, scale);
|
|
17399
17428
|
gx1 = c.x1;
|
|
17400
17429
|
gy1 = c.y1;
|
|
17401
17430
|
gx2 = c.x2;
|
|
17402
17431
|
gy2 = c.y2;
|
|
17403
17432
|
} else {
|
|
17404
|
-
const c = segEndpointsSvg(edge.
|
|
17433
|
+
const c = segEndpointsSvg(edge.elB, segB, scale);
|
|
17405
17434
|
gx1 = c.x1;
|
|
17406
17435
|
gy1 = c.y1;
|
|
17407
17436
|
gx2 = c.x2;
|
|
@@ -17409,17 +17438,17 @@ function assignLeadTransitionIds(elements, edges, scale) {
|
|
|
17409
17438
|
}
|
|
17410
17439
|
if (gradientVectorLength({ x1: gx1, y1: gy1, x2: gx2, y2: gy2 }) < 1e-6) continue;
|
|
17411
17440
|
const id = `sd-trans-${n++}`;
|
|
17412
|
-
parts.push(gradientXml(id, gx1, gy1, gx2, gy2, edge.
|
|
17413
|
-
if (
|
|
17414
|
-
|
|
17441
|
+
parts.push(gradientXml(id, gx1, gy1, gx2, gy2, edge.colorA, edge.colorB));
|
|
17442
|
+
if (segA && !segA.gradientStrokeId) {
|
|
17443
|
+
segA.gradientStrokeId = id;
|
|
17415
17444
|
cleanups.push(() => {
|
|
17416
|
-
|
|
17445
|
+
segA.gradientStrokeId = void 0;
|
|
17417
17446
|
});
|
|
17418
17447
|
}
|
|
17419
|
-
if (
|
|
17420
|
-
|
|
17448
|
+
if (segB && !segB.gradientStrokeId) {
|
|
17449
|
+
segB.gradientStrokeId = id;
|
|
17421
17450
|
cleanups.push(() => {
|
|
17422
|
-
|
|
17451
|
+
segB.gradientStrokeId = void 0;
|
|
17423
17452
|
});
|
|
17424
17453
|
}
|
|
17425
17454
|
}
|
|
@@ -17430,11 +17459,46 @@ function assignLeadTransitionIds(elements, edges, scale) {
|
|
|
17430
17459
|
}
|
|
17431
17460
|
};
|
|
17432
17461
|
}
|
|
17433
|
-
function
|
|
17462
|
+
function findSegAtJunction(el, junctionPt) {
|
|
17463
|
+
const tol = 0.6;
|
|
17434
17464
|
for (const s of el.segments) {
|
|
17435
|
-
if (s instanceof Segment
|
|
17465
|
+
if (!(s instanceof Segment)) continue;
|
|
17466
|
+
if (s.role !== "lead1" && s.role !== "lead2") continue;
|
|
17467
|
+
if (segTouchesPoint(el, s, junctionPt, tol)) return s;
|
|
17436
17468
|
}
|
|
17437
|
-
|
|
17469
|
+
let best;
|
|
17470
|
+
let bestDist = Infinity;
|
|
17471
|
+
for (const s of el.segments) {
|
|
17472
|
+
if (!(s instanceof Segment)) continue;
|
|
17473
|
+
if (s.path.length < 2) continue;
|
|
17474
|
+
if (s.role === "body") continue;
|
|
17475
|
+
if (s.path.length > 6) continue;
|
|
17476
|
+
const d = segDistToPoint(el, s, junctionPt);
|
|
17477
|
+
if (d < bestDist && d < tol) {
|
|
17478
|
+
bestDist = d;
|
|
17479
|
+
best = s;
|
|
17480
|
+
}
|
|
17481
|
+
}
|
|
17482
|
+
return best;
|
|
17483
|
+
}
|
|
17484
|
+
function segTouchesPoint(el, seg, absPt, tol) {
|
|
17485
|
+
return segDistToPoint(el, seg, absPt) < tol;
|
|
17486
|
+
}
|
|
17487
|
+
function segDistToPoint(el, seg, absPt) {
|
|
17488
|
+
const p0 = el.transform.transform(seg.path[0]);
|
|
17489
|
+
const pN = el.transform.transform(seg.path[seg.path.length - 1]);
|
|
17490
|
+
return Math.min(
|
|
17491
|
+
Math.hypot(p0.x - absPt.x, p0.y - absPt.y),
|
|
17492
|
+
Math.hypot(pN.x - absPt.x, pN.y - absPt.y)
|
|
17493
|
+
);
|
|
17494
|
+
}
|
|
17495
|
+
function nearFarSvg(el, seg, junctionPt, scale) {
|
|
17496
|
+
const p0 = el.transform.transform(seg.path[0]);
|
|
17497
|
+
const pN = el.transform.transform(seg.path[seg.path.length - 1]);
|
|
17498
|
+
const d0 = Math.hypot(p0.x - junctionPt.x, p0.y - junctionPt.y);
|
|
17499
|
+
const dN = Math.hypot(pN.x - junctionPt.x, pN.y - junctionPt.y);
|
|
17500
|
+
const far = d0 > dN ? p0 : pN;
|
|
17501
|
+
return { farX: far.x * scale, farY: -far.y * scale };
|
|
17438
17502
|
}
|
|
17439
17503
|
function segEndpointsSvg(el, seg, scale) {
|
|
17440
17504
|
const p0 = el.transform.transform(seg.path[0]);
|
|
@@ -6,18 +6,21 @@
|
|
|
6
6
|
* a smooth color fade at the junction.
|
|
7
7
|
*/
|
|
8
8
|
import type { Element } from "./element.js";
|
|
9
|
+
import { Point } from "./geometry/point.js";
|
|
9
10
|
interface ConnectionEdge {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
elA: Element;
|
|
12
|
+
elB: Element;
|
|
13
|
+
colorA: string;
|
|
14
|
+
colorB: string;
|
|
15
|
+
/** The absolute point where the two elements meet. */
|
|
16
|
+
junctionPt: Point;
|
|
14
17
|
}
|
|
15
18
|
/**
|
|
16
|
-
* Find
|
|
17
|
-
*
|
|
19
|
+
* Find pairs of elements that share a connection point (any pin anchor within
|
|
20
|
+
* tolerance) and have different resolved colors.
|
|
18
21
|
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
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.
|
|
21
24
|
*/
|
|
22
25
|
export declare function buildConnectionGraph(elements: readonly Element[]): ConnectionEdge[];
|
|
23
26
|
/**
|
package/dist/index.cjs
CHANGED
|
@@ -17732,29 +17732,56 @@ function resolveElementColor(el) {
|
|
|
17732
17732
|
const p = mergeParamsFirstWins(el.userParams, el.elmParams, el.defaults, el.dwgParams);
|
|
17733
17733
|
return p.color ?? "black";
|
|
17734
17734
|
}
|
|
17735
|
+
var EXCLUDED_ANCHORS = /* @__PURE__ */ new Set([
|
|
17736
|
+
"xy",
|
|
17737
|
+
"center",
|
|
17738
|
+
"istart",
|
|
17739
|
+
"iend",
|
|
17740
|
+
"mid",
|
|
17741
|
+
"label",
|
|
17742
|
+
"vd",
|
|
17743
|
+
"vs",
|
|
17744
|
+
"n1",
|
|
17745
|
+
"n2",
|
|
17746
|
+
"n1a",
|
|
17747
|
+
"n2a"
|
|
17748
|
+
]);
|
|
17749
|
+
function isConnectionAnchor(name) {
|
|
17750
|
+
return !EXCLUDED_ANCHORS.has(name);
|
|
17751
|
+
}
|
|
17752
|
+
function getConnectionAnchors(el) {
|
|
17753
|
+
const pts = [];
|
|
17754
|
+
for (const [name, pt] of Object.entries(el.absanchors)) {
|
|
17755
|
+
if (isConnectionAnchor(name)) pts.push(pt);
|
|
17756
|
+
}
|
|
17757
|
+
return pts;
|
|
17758
|
+
}
|
|
17735
17759
|
function buildConnectionGraph(elements) {
|
|
17736
17760
|
const edges = [];
|
|
17737
17761
|
const seen = /* @__PURE__ */ new Set();
|
|
17738
17762
|
const tol = 0.5;
|
|
17739
17763
|
for (let i = 0; i < elements.length; i++) {
|
|
17740
|
-
const
|
|
17741
|
-
const
|
|
17742
|
-
|
|
17743
|
-
|
|
17744
|
-
|
|
17745
|
-
const
|
|
17746
|
-
const
|
|
17747
|
-
if (
|
|
17748
|
-
const
|
|
17749
|
-
|
|
17750
|
-
|
|
17751
|
-
|
|
17752
|
-
|
|
17753
|
-
|
|
17754
|
-
|
|
17755
|
-
|
|
17756
|
-
|
|
17757
|
-
|
|
17764
|
+
const elA = elements[i];
|
|
17765
|
+
const colorA = resolveElementColor(elA);
|
|
17766
|
+
const anchorsA = getConnectionAnchors(elA);
|
|
17767
|
+
if (anchorsA.length === 0) continue;
|
|
17768
|
+
for (let j = i + 1; j < elements.length; j++) {
|
|
17769
|
+
const elB = elements[j];
|
|
17770
|
+
const colorB = resolveElementColor(elB);
|
|
17771
|
+
if (colorsEqual(colorA, colorB)) continue;
|
|
17772
|
+
const anchorsB = getConnectionAnchors(elB);
|
|
17773
|
+
if (anchorsB.length === 0) continue;
|
|
17774
|
+
for (const pa of anchorsA) {
|
|
17775
|
+
for (const pb of anchorsB) {
|
|
17776
|
+
if (Math.hypot(pa.x - pb.x, pa.y - pb.y) > tol) continue;
|
|
17777
|
+
const key = `${i}|${j}`;
|
|
17778
|
+
if (seen.has(key)) continue;
|
|
17779
|
+
seen.add(key);
|
|
17780
|
+
edges.push({ elA, elB, colorA, colorB, junctionPt: pa });
|
|
17781
|
+
break;
|
|
17782
|
+
}
|
|
17783
|
+
if (seen.has(`${i}|${j}`)) break;
|
|
17784
|
+
}
|
|
17758
17785
|
}
|
|
17759
17786
|
}
|
|
17760
17787
|
return edges;
|
|
@@ -17769,26 +17796,28 @@ function assignLeadTransitionIds(elements, edges, scale) {
|
|
|
17769
17796
|
const cleanups = [];
|
|
17770
17797
|
let n = 0;
|
|
17771
17798
|
for (const edge of edges) {
|
|
17772
|
-
const
|
|
17773
|
-
const
|
|
17774
|
-
if (!
|
|
17775
|
-
if (
|
|
17799
|
+
const segA = findSegAtJunction(edge.elA, edge.junctionPt);
|
|
17800
|
+
const segB = findSegAtJunction(edge.elB, edge.junctionPt);
|
|
17801
|
+
if (!segA && !segB) continue;
|
|
17802
|
+
if (segA?.gradientStrokeId && segB?.gradientStrokeId) continue;
|
|
17776
17803
|
let gx1, gy1, gx2, gy2;
|
|
17777
|
-
if (
|
|
17778
|
-
const
|
|
17779
|
-
const
|
|
17780
|
-
|
|
17781
|
-
|
|
17782
|
-
|
|
17783
|
-
|
|
17784
|
-
|
|
17785
|
-
|
|
17804
|
+
if (segA && segB) {
|
|
17805
|
+
const a = segEndpointsSvg(edge.elA, segA, scale);
|
|
17806
|
+
const b = segEndpointsSvg(edge.elB, segB, scale);
|
|
17807
|
+
const aNear = nearFarSvg(edge.elA, segA, edge.junctionPt, scale);
|
|
17808
|
+
const bNear = nearFarSvg(edge.elB, segB, edge.junctionPt, scale);
|
|
17809
|
+
gx1 = aNear.farX;
|
|
17810
|
+
gy1 = aNear.farY;
|
|
17811
|
+
gx2 = bNear.farX;
|
|
17812
|
+
gy2 = bNear.farY;
|
|
17813
|
+
} else if (segA) {
|
|
17814
|
+
const c = segEndpointsSvg(edge.elA, segA, scale);
|
|
17786
17815
|
gx1 = c.x1;
|
|
17787
17816
|
gy1 = c.y1;
|
|
17788
17817
|
gx2 = c.x2;
|
|
17789
17818
|
gy2 = c.y2;
|
|
17790
17819
|
} else {
|
|
17791
|
-
const c = segEndpointsSvg(edge.
|
|
17820
|
+
const c = segEndpointsSvg(edge.elB, segB, scale);
|
|
17792
17821
|
gx1 = c.x1;
|
|
17793
17822
|
gy1 = c.y1;
|
|
17794
17823
|
gx2 = c.x2;
|
|
@@ -17796,17 +17825,17 @@ function assignLeadTransitionIds(elements, edges, scale) {
|
|
|
17796
17825
|
}
|
|
17797
17826
|
if (gradientVectorLength({ x1: gx1, y1: gy1, x2: gx2, y2: gy2 }) < 1e-6) continue;
|
|
17798
17827
|
const id = `sd-trans-${n++}`;
|
|
17799
|
-
parts.push(gradientXml(id, gx1, gy1, gx2, gy2, edge.
|
|
17800
|
-
if (
|
|
17801
|
-
|
|
17828
|
+
parts.push(gradientXml(id, gx1, gy1, gx2, gy2, edge.colorA, edge.colorB));
|
|
17829
|
+
if (segA && !segA.gradientStrokeId) {
|
|
17830
|
+
segA.gradientStrokeId = id;
|
|
17802
17831
|
cleanups.push(() => {
|
|
17803
|
-
|
|
17832
|
+
segA.gradientStrokeId = void 0;
|
|
17804
17833
|
});
|
|
17805
17834
|
}
|
|
17806
|
-
if (
|
|
17807
|
-
|
|
17835
|
+
if (segB && !segB.gradientStrokeId) {
|
|
17836
|
+
segB.gradientStrokeId = id;
|
|
17808
17837
|
cleanups.push(() => {
|
|
17809
|
-
|
|
17838
|
+
segB.gradientStrokeId = void 0;
|
|
17810
17839
|
});
|
|
17811
17840
|
}
|
|
17812
17841
|
}
|
|
@@ -17817,11 +17846,46 @@ function assignLeadTransitionIds(elements, edges, scale) {
|
|
|
17817
17846
|
}
|
|
17818
17847
|
};
|
|
17819
17848
|
}
|
|
17820
|
-
function
|
|
17849
|
+
function findSegAtJunction(el, junctionPt) {
|
|
17850
|
+
const tol = 0.6;
|
|
17821
17851
|
for (const s of el.segments) {
|
|
17822
|
-
if (s instanceof Segment
|
|
17852
|
+
if (!(s instanceof Segment)) continue;
|
|
17853
|
+
if (s.role !== "lead1" && s.role !== "lead2") continue;
|
|
17854
|
+
if (segTouchesPoint(el, s, junctionPt, tol)) return s;
|
|
17823
17855
|
}
|
|
17824
|
-
|
|
17856
|
+
let best;
|
|
17857
|
+
let bestDist = Infinity;
|
|
17858
|
+
for (const s of el.segments) {
|
|
17859
|
+
if (!(s instanceof Segment)) continue;
|
|
17860
|
+
if (s.path.length < 2) continue;
|
|
17861
|
+
if (s.role === "body") continue;
|
|
17862
|
+
if (s.path.length > 6) continue;
|
|
17863
|
+
const d = segDistToPoint(el, s, junctionPt);
|
|
17864
|
+
if (d < bestDist && d < tol) {
|
|
17865
|
+
bestDist = d;
|
|
17866
|
+
best = s;
|
|
17867
|
+
}
|
|
17868
|
+
}
|
|
17869
|
+
return best;
|
|
17870
|
+
}
|
|
17871
|
+
function segTouchesPoint(el, seg, absPt, tol) {
|
|
17872
|
+
return segDistToPoint(el, seg, absPt) < tol;
|
|
17873
|
+
}
|
|
17874
|
+
function segDistToPoint(el, seg, absPt) {
|
|
17875
|
+
const p0 = el.transform.transform(seg.path[0]);
|
|
17876
|
+
const pN = el.transform.transform(seg.path[seg.path.length - 1]);
|
|
17877
|
+
return Math.min(
|
|
17878
|
+
Math.hypot(p0.x - absPt.x, p0.y - absPt.y),
|
|
17879
|
+
Math.hypot(pN.x - absPt.x, pN.y - absPt.y)
|
|
17880
|
+
);
|
|
17881
|
+
}
|
|
17882
|
+
function nearFarSvg(el, seg, junctionPt, scale) {
|
|
17883
|
+
const p0 = el.transform.transform(seg.path[0]);
|
|
17884
|
+
const pN = el.transform.transform(seg.path[seg.path.length - 1]);
|
|
17885
|
+
const d0 = Math.hypot(p0.x - junctionPt.x, p0.y - junctionPt.y);
|
|
17886
|
+
const dN = Math.hypot(pN.x - junctionPt.x, pN.y - junctionPt.y);
|
|
17887
|
+
const far = d0 > dN ? p0 : pN;
|
|
17888
|
+
return { farX: far.x * scale, farY: -far.y * scale };
|
|
17825
17889
|
}
|
|
17826
17890
|
function segEndpointsSvg(el, seg, scale) {
|
|
17827
17891
|
const p0 = el.transform.transform(seg.path[0]);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@skillpet/circuit",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.3",
|
|
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",
|