@skillpet/circuit 0.6.0 → 0.6.2
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 +76 -17
- package/dist/circuit.bundle.min.js +19 -19
- package/dist/circuit.esm.js +76 -17
- package/dist/drawing-transition.d.ts +7 -4
- package/dist/index.cjs +76 -17
- package/dist/json/mount.d.ts +1 -0
- package/package.json +1 -1
package/dist/circuit.esm.js
CHANGED
|
@@ -17345,29 +17345,52 @@ 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
|
+
function getOutputAnchors(el) {
|
|
17349
|
+
const pts = [];
|
|
17350
|
+
const aa = el.absanchors;
|
|
17351
|
+
if (aa.end) pts.push(aa.end);
|
|
17352
|
+
if (aa.out && (!aa.end || !pointsClose(aa.out, aa.end, 0.01))) pts.push(aa.out);
|
|
17353
|
+
return pts;
|
|
17354
|
+
}
|
|
17355
|
+
function getInputAnchors(el) {
|
|
17356
|
+
const pts = [];
|
|
17357
|
+
const aa = el.absanchors;
|
|
17358
|
+
if (aa.start) pts.push(aa.start);
|
|
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
|
+
}
|
|
17363
|
+
}
|
|
17364
|
+
return pts;
|
|
17365
|
+
}
|
|
17366
|
+
function pointsClose(a, b, tol) {
|
|
17367
|
+
return Math.hypot(a.x - b.x, a.y - b.y) <= tol;
|
|
17368
|
+
}
|
|
17348
17369
|
function buildConnectionGraph(elements) {
|
|
17349
17370
|
const edges = [];
|
|
17350
17371
|
const seen = /* @__PURE__ */ new Set();
|
|
17351
17372
|
const tol = 0.5;
|
|
17352
17373
|
for (let i = 0; i < elements.length; i++) {
|
|
17353
17374
|
const fromEl = elements[i];
|
|
17354
|
-
const
|
|
17355
|
-
if (
|
|
17375
|
+
const fromPts = getOutputAnchors(fromEl);
|
|
17376
|
+
if (fromPts.length === 0) continue;
|
|
17377
|
+
const fromColor = resolveElementColor(fromEl);
|
|
17356
17378
|
for (let j = 0; j < elements.length; j++) {
|
|
17357
17379
|
if (i === j) continue;
|
|
17358
17380
|
const toEl = elements[j];
|
|
17359
|
-
const
|
|
17360
|
-
if (
|
|
17361
|
-
const dx = fromEnd.x - toStart.x;
|
|
17362
|
-
const dy = fromEnd.y - toStart.y;
|
|
17363
|
-
if (Math.hypot(dx, dy) > tol) continue;
|
|
17364
|
-
const fromColor = resolveElementColor(fromEl);
|
|
17381
|
+
const toPts = getInputAnchors(toEl);
|
|
17382
|
+
if (toPts.length === 0) continue;
|
|
17365
17383
|
const toColor = resolveElementColor(toEl);
|
|
17366
17384
|
if (colorsEqual(fromColor, toColor)) continue;
|
|
17367
|
-
const
|
|
17368
|
-
|
|
17369
|
-
|
|
17370
|
-
|
|
17385
|
+
for (const fp of fromPts) {
|
|
17386
|
+
for (const tp of toPts) {
|
|
17387
|
+
if (!pointsClose(fp, tp, tol)) continue;
|
|
17388
|
+
const key = `${i}|${j}`;
|
|
17389
|
+
if (seen.has(key)) continue;
|
|
17390
|
+
seen.add(key);
|
|
17391
|
+
edges.push({ fromEl, toEl, fromColor, toColor, junctionPt: fp });
|
|
17392
|
+
}
|
|
17393
|
+
}
|
|
17371
17394
|
}
|
|
17372
17395
|
}
|
|
17373
17396
|
return edges;
|
|
@@ -17382,8 +17405,8 @@ function assignLeadTransitionIds(elements, edges, scale) {
|
|
|
17382
17405
|
const cleanups = [];
|
|
17383
17406
|
let n = 0;
|
|
17384
17407
|
for (const edge of edges) {
|
|
17385
|
-
const lead2Seg =
|
|
17386
|
-
const lead1Seg =
|
|
17408
|
+
const lead2Seg = findLeadSegmentFor(edge.fromEl, "out", edge.junctionPt);
|
|
17409
|
+
const lead1Seg = findLeadSegmentFor(edge.toEl, "in", edge.junctionPt);
|
|
17387
17410
|
if (!lead2Seg && !lead1Seg) continue;
|
|
17388
17411
|
if (lead2Seg?.gradientStrokeId && lead1Seg?.gradientStrokeId) continue;
|
|
17389
17412
|
let gx1, gy1, gx2, gy2;
|
|
@@ -17430,11 +17453,32 @@ function assignLeadTransitionIds(elements, edges, scale) {
|
|
|
17430
17453
|
}
|
|
17431
17454
|
};
|
|
17432
17455
|
}
|
|
17433
|
-
function
|
|
17456
|
+
function findLeadSegmentFor(el, side, junctionPt) {
|
|
17457
|
+
const role = side === "in" ? "lead1" : "lead2";
|
|
17434
17458
|
for (const s of el.segments) {
|
|
17435
17459
|
if (s instanceof Segment && s.role === role) return s;
|
|
17436
17460
|
}
|
|
17437
|
-
return
|
|
17461
|
+
return findSegmentNearPoint(el, junctionPt);
|
|
17462
|
+
}
|
|
17463
|
+
function findSegmentNearPoint(el, absPt) {
|
|
17464
|
+
let best;
|
|
17465
|
+
let bestDist = Infinity;
|
|
17466
|
+
const tol = 0.6;
|
|
17467
|
+
for (const s of el.segments) {
|
|
17468
|
+
if (!(s instanceof Segment)) continue;
|
|
17469
|
+
if (s.path.length < 2) continue;
|
|
17470
|
+
if (s.role === "body") continue;
|
|
17471
|
+
const p0 = el.transform.transform(s.path[0]);
|
|
17472
|
+
const pN = el.transform.transform(s.path[s.path.length - 1]);
|
|
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);
|
|
17476
|
+
if (d < bestDist && d < tol) {
|
|
17477
|
+
bestDist = d;
|
|
17478
|
+
best = s;
|
|
17479
|
+
}
|
|
17480
|
+
}
|
|
17481
|
+
return best;
|
|
17438
17482
|
}
|
|
17439
17483
|
function segEndpointsSvg(el, seg, scale) {
|
|
17440
17484
|
const p0 = el.transform.transform(seg.path[0]);
|
|
@@ -30527,13 +30571,28 @@ var SchemdrawController = class {
|
|
|
30527
30571
|
}
|
|
30528
30572
|
_initTooltip() {
|
|
30529
30573
|
const tip = document.createElement("div");
|
|
30530
|
-
tip.
|
|
30574
|
+
tip.className = "schemdraw-tooltip";
|
|
30575
|
+
tip.style.cssText = "position:fixed;z-index:99999;pointer-events:none;opacity:0;transition:opacity .15s ease;font-size:12px;line-height:1.4;padding:6px 12px;border-radius:6px;max-width:260px;white-space:pre-wrap;";
|
|
30576
|
+
this._applyTooltipTheme(tip);
|
|
30531
30577
|
document.body.appendChild(tip);
|
|
30532
30578
|
this._tooltipEl = tip;
|
|
30533
30579
|
}
|
|
30580
|
+
_applyTooltipTheme(tip) {
|
|
30581
|
+
const isDark = document.documentElement.classList.contains("dark") || document.documentElement.getAttribute("data-theme") === "dark" || typeof window !== "undefined" && window.matchMedia?.("(prefers-color-scheme: dark)").matches && !document.documentElement.classList.contains("light");
|
|
30582
|
+
if (isDark) {
|
|
30583
|
+
tip.style.background = "rgba(250,250,250,.95)";
|
|
30584
|
+
tip.style.color = "#1a1a1a";
|
|
30585
|
+
tip.style.boxShadow = "0 2px 12px rgba(0,0,0,.4)";
|
|
30586
|
+
} else {
|
|
30587
|
+
tip.style.background = "rgba(15,15,15,.92)";
|
|
30588
|
+
tip.style.color = "#fff";
|
|
30589
|
+
tip.style.boxShadow = "0 2px 8px rgba(0,0,0,.2)";
|
|
30590
|
+
}
|
|
30591
|
+
}
|
|
30534
30592
|
_showTooltip(text2, clientX, clientY) {
|
|
30535
30593
|
const tip = this._tooltipEl;
|
|
30536
30594
|
if (!tip) return;
|
|
30595
|
+
this._applyTooltipTheme(tip);
|
|
30537
30596
|
tip.textContent = text2;
|
|
30538
30597
|
tip.style.opacity = "1";
|
|
30539
30598
|
const gap2 = 10;
|
|
@@ -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
|
fromEl: Element;
|
|
11
12
|
toEl: Element;
|
|
12
13
|
fromColor: string;
|
|
13
14
|
toColor: string;
|
|
15
|
+
/** The absolute point where the connection occurs. */
|
|
16
|
+
junctionPt: Point;
|
|
14
17
|
}
|
|
15
18
|
/**
|
|
16
|
-
* Find directed pairs (fromEl → toEl) where
|
|
17
|
-
*
|
|
19
|
+
* Find directed pairs (fromEl → toEl) where an output anchor of fromEl meets
|
|
20
|
+
* an input anchor of toEl (within tolerance) and resolved stroke colors differ.
|
|
18
21
|
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
22
|
+
* Checks end/out → start/in1/in2/… to support both two-terminal chains
|
|
23
|
+
* and multi-terminal elements (logic gates, opamps, etc.).
|
|
21
24
|
*/
|
|
22
25
|
export declare function buildConnectionGraph(elements: readonly Element[]): ConnectionEdge[];
|
|
23
26
|
/**
|
package/dist/index.cjs
CHANGED
|
@@ -17732,29 +17732,52 @@ 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
|
+
function getOutputAnchors(el) {
|
|
17736
|
+
const pts = [];
|
|
17737
|
+
const aa = el.absanchors;
|
|
17738
|
+
if (aa.end) pts.push(aa.end);
|
|
17739
|
+
if (aa.out && (!aa.end || !pointsClose(aa.out, aa.end, 0.01))) pts.push(aa.out);
|
|
17740
|
+
return pts;
|
|
17741
|
+
}
|
|
17742
|
+
function getInputAnchors(el) {
|
|
17743
|
+
const pts = [];
|
|
17744
|
+
const aa = el.absanchors;
|
|
17745
|
+
if (aa.start) pts.push(aa.start);
|
|
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
|
+
}
|
|
17750
|
+
}
|
|
17751
|
+
return pts;
|
|
17752
|
+
}
|
|
17753
|
+
function pointsClose(a, b, tol) {
|
|
17754
|
+
return Math.hypot(a.x - b.x, a.y - b.y) <= tol;
|
|
17755
|
+
}
|
|
17735
17756
|
function buildConnectionGraph(elements) {
|
|
17736
17757
|
const edges = [];
|
|
17737
17758
|
const seen = /* @__PURE__ */ new Set();
|
|
17738
17759
|
const tol = 0.5;
|
|
17739
17760
|
for (let i = 0; i < elements.length; i++) {
|
|
17740
17761
|
const fromEl = elements[i];
|
|
17741
|
-
const
|
|
17742
|
-
if (
|
|
17762
|
+
const fromPts = getOutputAnchors(fromEl);
|
|
17763
|
+
if (fromPts.length === 0) continue;
|
|
17764
|
+
const fromColor = resolveElementColor(fromEl);
|
|
17743
17765
|
for (let j = 0; j < elements.length; j++) {
|
|
17744
17766
|
if (i === j) continue;
|
|
17745
17767
|
const toEl = elements[j];
|
|
17746
|
-
const
|
|
17747
|
-
if (
|
|
17748
|
-
const dx = fromEnd.x - toStart.x;
|
|
17749
|
-
const dy = fromEnd.y - toStart.y;
|
|
17750
|
-
if (Math.hypot(dx, dy) > tol) continue;
|
|
17751
|
-
const fromColor = resolveElementColor(fromEl);
|
|
17768
|
+
const toPts = getInputAnchors(toEl);
|
|
17769
|
+
if (toPts.length === 0) continue;
|
|
17752
17770
|
const toColor = resolveElementColor(toEl);
|
|
17753
17771
|
if (colorsEqual(fromColor, toColor)) continue;
|
|
17754
|
-
const
|
|
17755
|
-
|
|
17756
|
-
|
|
17757
|
-
|
|
17772
|
+
for (const fp of fromPts) {
|
|
17773
|
+
for (const tp of toPts) {
|
|
17774
|
+
if (!pointsClose(fp, tp, tol)) continue;
|
|
17775
|
+
const key = `${i}|${j}`;
|
|
17776
|
+
if (seen.has(key)) continue;
|
|
17777
|
+
seen.add(key);
|
|
17778
|
+
edges.push({ fromEl, toEl, fromColor, toColor, junctionPt: fp });
|
|
17779
|
+
}
|
|
17780
|
+
}
|
|
17758
17781
|
}
|
|
17759
17782
|
}
|
|
17760
17783
|
return edges;
|
|
@@ -17769,8 +17792,8 @@ function assignLeadTransitionIds(elements, edges, scale) {
|
|
|
17769
17792
|
const cleanups = [];
|
|
17770
17793
|
let n = 0;
|
|
17771
17794
|
for (const edge of edges) {
|
|
17772
|
-
const lead2Seg =
|
|
17773
|
-
const lead1Seg =
|
|
17795
|
+
const lead2Seg = findLeadSegmentFor(edge.fromEl, "out", edge.junctionPt);
|
|
17796
|
+
const lead1Seg = findLeadSegmentFor(edge.toEl, "in", edge.junctionPt);
|
|
17774
17797
|
if (!lead2Seg && !lead1Seg) continue;
|
|
17775
17798
|
if (lead2Seg?.gradientStrokeId && lead1Seg?.gradientStrokeId) continue;
|
|
17776
17799
|
let gx1, gy1, gx2, gy2;
|
|
@@ -17817,11 +17840,32 @@ function assignLeadTransitionIds(elements, edges, scale) {
|
|
|
17817
17840
|
}
|
|
17818
17841
|
};
|
|
17819
17842
|
}
|
|
17820
|
-
function
|
|
17843
|
+
function findLeadSegmentFor(el, side, junctionPt) {
|
|
17844
|
+
const role = side === "in" ? "lead1" : "lead2";
|
|
17821
17845
|
for (const s of el.segments) {
|
|
17822
17846
|
if (s instanceof Segment && s.role === role) return s;
|
|
17823
17847
|
}
|
|
17824
|
-
return
|
|
17848
|
+
return findSegmentNearPoint(el, junctionPt);
|
|
17849
|
+
}
|
|
17850
|
+
function findSegmentNearPoint(el, absPt) {
|
|
17851
|
+
let best;
|
|
17852
|
+
let bestDist = Infinity;
|
|
17853
|
+
const tol = 0.6;
|
|
17854
|
+
for (const s of el.segments) {
|
|
17855
|
+
if (!(s instanceof Segment)) continue;
|
|
17856
|
+
if (s.path.length < 2) continue;
|
|
17857
|
+
if (s.role === "body") continue;
|
|
17858
|
+
const p0 = el.transform.transform(s.path[0]);
|
|
17859
|
+
const pN = el.transform.transform(s.path[s.path.length - 1]);
|
|
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);
|
|
17863
|
+
if (d < bestDist && d < tol) {
|
|
17864
|
+
bestDist = d;
|
|
17865
|
+
best = s;
|
|
17866
|
+
}
|
|
17867
|
+
}
|
|
17868
|
+
return best;
|
|
17825
17869
|
}
|
|
17826
17870
|
function segEndpointsSvg(el, seg, scale) {
|
|
17827
17871
|
const p0 = el.transform.transform(seg.path[0]);
|
|
@@ -30914,13 +30958,28 @@ var SchemdrawController = class {
|
|
|
30914
30958
|
}
|
|
30915
30959
|
_initTooltip() {
|
|
30916
30960
|
const tip = document.createElement("div");
|
|
30917
|
-
tip.
|
|
30961
|
+
tip.className = "schemdraw-tooltip";
|
|
30962
|
+
tip.style.cssText = "position:fixed;z-index:99999;pointer-events:none;opacity:0;transition:opacity .15s ease;font-size:12px;line-height:1.4;padding:6px 12px;border-radius:6px;max-width:260px;white-space:pre-wrap;";
|
|
30963
|
+
this._applyTooltipTheme(tip);
|
|
30918
30964
|
document.body.appendChild(tip);
|
|
30919
30965
|
this._tooltipEl = tip;
|
|
30920
30966
|
}
|
|
30967
|
+
_applyTooltipTheme(tip) {
|
|
30968
|
+
const isDark = document.documentElement.classList.contains("dark") || document.documentElement.getAttribute("data-theme") === "dark" || typeof window !== "undefined" && window.matchMedia?.("(prefers-color-scheme: dark)").matches && !document.documentElement.classList.contains("light");
|
|
30969
|
+
if (isDark) {
|
|
30970
|
+
tip.style.background = "rgba(250,250,250,.95)";
|
|
30971
|
+
tip.style.color = "#1a1a1a";
|
|
30972
|
+
tip.style.boxShadow = "0 2px 12px rgba(0,0,0,.4)";
|
|
30973
|
+
} else {
|
|
30974
|
+
tip.style.background = "rgba(15,15,15,.92)";
|
|
30975
|
+
tip.style.color = "#fff";
|
|
30976
|
+
tip.style.boxShadow = "0 2px 8px rgba(0,0,0,.2)";
|
|
30977
|
+
}
|
|
30978
|
+
}
|
|
30921
30979
|
_showTooltip(text2, clientX, clientY) {
|
|
30922
30980
|
const tip = this._tooltipEl;
|
|
30923
30981
|
if (!tip) return;
|
|
30982
|
+
this._applyTooltipTheme(tip);
|
|
30924
30983
|
tip.textContent = text2;
|
|
30925
30984
|
tip.style.opacity = "1";
|
|
30926
30985
|
const gap2 = 10;
|
package/dist/json/mount.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@skillpet/circuit",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.2",
|
|
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",
|