circuit-to-canvas 0.0.31 → 0.0.33
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.d.ts +50 -5
- package/dist/index.js +237 -115
- package/lib/drawer/CircuitToCanvasDrawer.ts +22 -0
- package/lib/drawer/elements/index.ts +10 -0
- package/lib/drawer/elements/pcb-fabrication-note-dimension.ts +42 -0
- package/lib/drawer/elements/pcb-hole.ts +2 -2
- package/lib/drawer/elements/pcb-note-dimension.ts +16 -179
- package/lib/drawer/elements/pcb-plated-hole.ts +6 -6
- package/lib/drawer/elements/pcb-silkscreen-oval.ts +35 -0
- package/lib/drawer/shapes/dimension-line.ts +228 -0
- package/lib/drawer/shapes/index.ts +4 -0
- package/lib/drawer/shapes/oval.ts +25 -10
- package/package.json +3 -3
- package/tests/elements/__snapshots__/pcb-fabrication-note-dimension.snap.png +0 -0
- package/tests/elements/__snapshots__/pcb-note-dimension-angled-and-vertical.snap.png +0 -0
- package/tests/elements/__snapshots__/pcb-note-dimension-basic.snap.png +0 -0
- package/tests/elements/__snapshots__/pcb-note-dimension-vertical.snap.png +0 -0
- package/tests/elements/__snapshots__/pcb-note-dimension-with-offset.snap.png +0 -0
- package/tests/elements/__snapshots__/pcb-silkscreen-oval.snap.png +0 -0
- package/tests/elements/pcb-fabrication-note-dimension.test.ts +40 -0
- package/tests/elements/pcb-silkscreen-oval.test.ts +37 -0
- package/tests/shapes/__snapshots__/dimension-line.snap.png +0 -0
- package/tests/shapes/__snapshots__/oval.snap.png +0 -0
- package/tests/shapes/dimension-line.test.ts +46 -0
- package/tests/shapes/oval.test.ts +3 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AnyCircuitElement, PcbRenderLayer, NinePointAnchor, PcbPlatedHole, PCBVia, PCBHole, PcbSmtPad, PCBTrace, PcbBoard, PcbSilkscreenText, PcbSilkscreenRect, PcbSilkscreenCircle, PcbSilkscreenLine, PcbSilkscreenPath, PcbSilkscreenPill, PcbCutout, PcbCopperPour, PcbCopperText, PcbFabricationNoteText, PcbFabricationNoteRect, PcbNoteRect, PcbFabricationNotePath, PcbNotePath, PcbNoteText, PcbNoteDimension } from 'circuit-json';
|
|
1
|
+
import { AnyCircuitElement, PcbRenderLayer, NinePointAnchor, PcbPlatedHole, PCBVia, PCBHole, PcbSmtPad, PCBTrace, PcbBoard, PcbSilkscreenText, PcbSilkscreenRect, PcbSilkscreenCircle, PcbSilkscreenLine, PcbSilkscreenPath, PcbSilkscreenPill, PcbSilkscreenOval, PcbCutout, PcbCopperPour, PcbCopperText, PcbFabricationNoteText, PcbFabricationNoteRect, PcbNoteRect, PcbFabricationNotePath, PcbNotePath, PcbNoteText, PcbNoteDimension, PcbFabricationNoteDimension } from 'circuit-json';
|
|
2
2
|
import { Matrix } from 'transformation-matrix';
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -139,9 +139,11 @@ interface DrawOvalParams {
|
|
|
139
139
|
x: number;
|
|
140
140
|
y: number;
|
|
141
141
|
};
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
fill
|
|
142
|
+
radius_x: number;
|
|
143
|
+
radius_y: number;
|
|
144
|
+
fill?: string;
|
|
145
|
+
stroke?: string;
|
|
146
|
+
strokeWidth?: number;
|
|
145
147
|
realToCanvasMat: Matrix;
|
|
146
148
|
rotation?: number;
|
|
147
149
|
}
|
|
@@ -219,6 +221,33 @@ interface DrawArrowParams {
|
|
|
219
221
|
*/
|
|
220
222
|
declare function drawArrow(params: DrawArrowParams): void;
|
|
221
223
|
|
|
224
|
+
interface DrawDimensionLineParams {
|
|
225
|
+
ctx: CanvasContext;
|
|
226
|
+
from: {
|
|
227
|
+
x: number;
|
|
228
|
+
y: number;
|
|
229
|
+
};
|
|
230
|
+
to: {
|
|
231
|
+
x: number;
|
|
232
|
+
y: number;
|
|
233
|
+
};
|
|
234
|
+
realToCanvasMat: Matrix;
|
|
235
|
+
color: string;
|
|
236
|
+
fontSize: number;
|
|
237
|
+
arrowSize?: number;
|
|
238
|
+
strokeWidth?: number;
|
|
239
|
+
text?: string;
|
|
240
|
+
textRotation?: number;
|
|
241
|
+
offset?: {
|
|
242
|
+
distance: number;
|
|
243
|
+
direction: {
|
|
244
|
+
x: number;
|
|
245
|
+
y: number;
|
|
246
|
+
};
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
declare function drawDimensionLine(params: DrawDimensionLineParams): void;
|
|
250
|
+
|
|
222
251
|
interface StrokeAlphabetTextParams {
|
|
223
252
|
ctx: CanvasContext;
|
|
224
253
|
text: string;
|
|
@@ -377,6 +406,14 @@ interface DrawPcbSilkscreenPillParams {
|
|
|
377
406
|
}
|
|
378
407
|
declare function drawPcbSilkscreenPill(params: DrawPcbSilkscreenPillParams): void;
|
|
379
408
|
|
|
409
|
+
interface DrawPcbSilkscreenOvalParams {
|
|
410
|
+
ctx: CanvasContext;
|
|
411
|
+
oval: PcbSilkscreenOval;
|
|
412
|
+
realToCanvasMat: Matrix;
|
|
413
|
+
colorMap: PcbColorMap;
|
|
414
|
+
}
|
|
415
|
+
declare function drawPcbSilkscreenOval(params: DrawPcbSilkscreenOvalParams): void;
|
|
416
|
+
|
|
380
417
|
interface DrawPcbCutoutParams {
|
|
381
418
|
ctx: CanvasContext;
|
|
382
419
|
cutout: PcbCutout;
|
|
@@ -457,4 +494,12 @@ interface DrawPcbNoteDimensionParams {
|
|
|
457
494
|
}
|
|
458
495
|
declare function drawPcbNoteDimension(params: DrawPcbNoteDimensionParams): void;
|
|
459
496
|
|
|
460
|
-
|
|
497
|
+
interface DrawPcbFabricationNoteDimensionParams {
|
|
498
|
+
ctx: CanvasContext;
|
|
499
|
+
pcbFabricationNoteDimension: PcbFabricationNoteDimension;
|
|
500
|
+
realToCanvasMat: Matrix;
|
|
501
|
+
colorMap: PcbColorMap;
|
|
502
|
+
}
|
|
503
|
+
declare function drawPcbFabricationNoteDimension(params: DrawPcbFabricationNoteDimensionParams): void;
|
|
504
|
+
|
|
505
|
+
export { type AlphabetLayout, type AnchorAlignment, type CameraBounds, type CanvasContext, CircuitToCanvasDrawer, type CopperColorMap, type CopperLayerName, DEFAULT_PCB_COLOR_MAP, type DrawArrowParams, type DrawCircleParams, type DrawContext, type DrawDimensionLineParams, type DrawElementsOptions, type DrawLineParams, type DrawOvalParams, type DrawPathParams, type DrawPcbBoardParams, type DrawPcbCopperPourParams, type DrawPcbCopperTextParams, type DrawPcbCutoutParams, type DrawPcbFabricationNoteDimensionParams, type DrawPcbFabricationNotePathParams, type DrawPcbFabricationNoteRectParams, type DrawPcbFabricationNoteTextParams, type DrawPcbHoleParams, type DrawPcbNoteDimensionParams, type DrawPcbNotePathParams, type DrawPcbNoteRectParams, type DrawPcbNoteTextParams, type DrawPcbPlatedHoleParams, type DrawPcbSilkscreenCircleParams, type DrawPcbSilkscreenLineParams, type DrawPcbSilkscreenOvalParams, type DrawPcbSilkscreenPathParams, type DrawPcbSilkscreenPillParams, type DrawPcbSilkscreenRectParams, type DrawPcbSilkscreenTextParams, type DrawPcbSmtPadParams, type DrawPcbTraceParams, type DrawPcbViaParams, type DrawPillParams, type DrawPolygonParams, type DrawRectParams, type DrawTextParams, type DrawerConfig, type PcbColorMap, drawArrow, drawCircle, drawDimensionLine, drawLine, drawOval, drawPath, drawPcbBoard, drawPcbCopperPour, drawPcbCopperText, drawPcbCutout, drawPcbFabricationNoteDimension, drawPcbFabricationNotePath, drawPcbFabricationNoteRect, drawPcbFabricationNoteText, drawPcbHole, drawPcbNoteDimension, drawPcbNotePath, drawPcbNoteRect, drawPcbNoteText, drawPcbPlatedHole, drawPcbSilkscreenCircle, drawPcbSilkscreenLine, drawPcbSilkscreenOval, drawPcbSilkscreenPath, drawPcbSilkscreenPill, drawPcbSilkscreenRect, drawPcbSilkscreenText, drawPcbSmtPad, drawPcbTrace, drawPcbVia, drawPill, drawPolygon, drawRect, drawSoldermaskRingForCircle, drawSoldermaskRingForPill, drawSoldermaskRingForRect, drawText, getAlphabetLayout, getTextStartPosition, strokeAlphabetText };
|
package/dist/index.js
CHANGED
|
@@ -138,24 +138,34 @@ function drawOval(params) {
|
|
|
138
138
|
const {
|
|
139
139
|
ctx,
|
|
140
140
|
center,
|
|
141
|
-
|
|
142
|
-
|
|
141
|
+
radius_x,
|
|
142
|
+
radius_y,
|
|
143
143
|
fill,
|
|
144
|
+
stroke,
|
|
145
|
+
strokeWidth = 0.1,
|
|
144
146
|
realToCanvasMat,
|
|
145
147
|
rotation = 0
|
|
146
148
|
} = params;
|
|
147
149
|
const [cx, cy] = applyToPoint3(realToCanvasMat, [center.x, center.y]);
|
|
148
|
-
const
|
|
149
|
-
const
|
|
150
|
+
const scaledRadiusX = radius_x * Math.abs(realToCanvasMat.a);
|
|
151
|
+
const scaledRadiusY = radius_y * Math.abs(realToCanvasMat.a);
|
|
152
|
+
const scaledStrokeWidth = strokeWidth * Math.abs(realToCanvasMat.a);
|
|
150
153
|
ctx.save();
|
|
151
154
|
ctx.translate(cx, cy);
|
|
152
155
|
if (rotation !== 0) {
|
|
153
156
|
ctx.rotate(-rotation * (Math.PI / 180));
|
|
154
157
|
}
|
|
155
158
|
ctx.beginPath();
|
|
156
|
-
ctx.ellipse(0, 0,
|
|
157
|
-
|
|
158
|
-
|
|
159
|
+
ctx.ellipse(0, 0, scaledRadiusX, scaledRadiusY, 0, 0, Math.PI * 2);
|
|
160
|
+
if (fill) {
|
|
161
|
+
ctx.fillStyle = fill;
|
|
162
|
+
ctx.fill();
|
|
163
|
+
}
|
|
164
|
+
if (stroke) {
|
|
165
|
+
ctx.strokeStyle = stroke;
|
|
166
|
+
ctx.lineWidth = scaledStrokeWidth;
|
|
167
|
+
ctx.stroke();
|
|
168
|
+
}
|
|
159
169
|
ctx.restore();
|
|
160
170
|
}
|
|
161
171
|
|
|
@@ -263,8 +273,8 @@ function drawPcbPlatedHole(params) {
|
|
|
263
273
|
drawOval({
|
|
264
274
|
ctx,
|
|
265
275
|
center: { x: hole.x, y: hole.y },
|
|
266
|
-
|
|
267
|
-
|
|
276
|
+
radius_x: hole.outer_width / 2,
|
|
277
|
+
radius_y: hole.outer_height / 2,
|
|
268
278
|
fill: colorMap.copper.top,
|
|
269
279
|
realToCanvasMat,
|
|
270
280
|
rotation: hole.ccw_rotation
|
|
@@ -272,8 +282,8 @@ function drawPcbPlatedHole(params) {
|
|
|
272
282
|
drawOval({
|
|
273
283
|
ctx,
|
|
274
284
|
center: { x: hole.x, y: hole.y },
|
|
275
|
-
|
|
276
|
-
|
|
285
|
+
radius_x: hole.hole_width / 2,
|
|
286
|
+
radius_y: hole.hole_height / 2,
|
|
277
287
|
fill: colorMap.drill,
|
|
278
288
|
realToCanvasMat,
|
|
279
289
|
rotation: hole.ccw_rotation
|
|
@@ -397,8 +407,8 @@ function drawPcbPlatedHole(params) {
|
|
|
397
407
|
drawOval({
|
|
398
408
|
ctx,
|
|
399
409
|
center: { x: holeX, y: holeY },
|
|
400
|
-
|
|
401
|
-
|
|
410
|
+
radius_x: (hole.hole_width ?? 0) / 2,
|
|
411
|
+
radius_y: (hole.hole_height ?? 0) / 2,
|
|
402
412
|
fill: colorMap.drill,
|
|
403
413
|
realToCanvasMat
|
|
404
414
|
});
|
|
@@ -472,8 +482,8 @@ function drawPcbHole(params) {
|
|
|
472
482
|
drawOval({
|
|
473
483
|
ctx,
|
|
474
484
|
center: { x: hole.x, y: hole.y },
|
|
475
|
-
|
|
476
|
-
|
|
485
|
+
radius_x: hole.hole_width / 2,
|
|
486
|
+
radius_y: hole.hole_height / 2,
|
|
477
487
|
fill: colorMap.drill,
|
|
478
488
|
realToCanvasMat
|
|
479
489
|
});
|
|
@@ -1275,13 +1285,32 @@ function drawPcbSilkscreenPath(params) {
|
|
|
1275
1285
|
}
|
|
1276
1286
|
}
|
|
1277
1287
|
|
|
1278
|
-
// lib/drawer/elements/pcb-silkscreen-
|
|
1288
|
+
// lib/drawer/elements/pcb-silkscreen-oval.ts
|
|
1279
1289
|
function layerToSilkscreenColor6(layer, colorMap) {
|
|
1280
1290
|
return layer === "bottom" ? colorMap.silkscreen.bottom : colorMap.silkscreen.top;
|
|
1281
1291
|
}
|
|
1292
|
+
function drawPcbSilkscreenOval(params) {
|
|
1293
|
+
const { ctx, oval, realToCanvasMat, colorMap } = params;
|
|
1294
|
+
const color = layerToSilkscreenColor6(oval.layer, colorMap);
|
|
1295
|
+
drawOval({
|
|
1296
|
+
ctx,
|
|
1297
|
+
center: oval.center,
|
|
1298
|
+
radius_x: oval.radius_x,
|
|
1299
|
+
radius_y: oval.radius_y,
|
|
1300
|
+
stroke: color,
|
|
1301
|
+
strokeWidth: 0.1,
|
|
1302
|
+
realToCanvasMat,
|
|
1303
|
+
rotation: oval.ccw_rotation ?? 0
|
|
1304
|
+
});
|
|
1305
|
+
}
|
|
1306
|
+
|
|
1307
|
+
// lib/drawer/elements/pcb-silkscreen-pill.ts
|
|
1308
|
+
function layerToSilkscreenColor7(layer, colorMap) {
|
|
1309
|
+
return layer === "bottom" ? colorMap.silkscreen.bottom : colorMap.silkscreen.top;
|
|
1310
|
+
}
|
|
1282
1311
|
function drawPcbSilkscreenPill(params) {
|
|
1283
1312
|
const { ctx, pill, realToCanvasMat, colorMap } = params;
|
|
1284
|
-
const color =
|
|
1313
|
+
const color = layerToSilkscreenColor7(pill.layer, colorMap);
|
|
1285
1314
|
const strokeWidth = 0.2;
|
|
1286
1315
|
drawPill({
|
|
1287
1316
|
ctx,
|
|
@@ -1589,7 +1618,7 @@ function drawPcbNoteText(params) {
|
|
|
1589
1618
|
});
|
|
1590
1619
|
}
|
|
1591
1620
|
|
|
1592
|
-
// lib/drawer/
|
|
1621
|
+
// lib/drawer/shapes/dimension-line.ts
|
|
1593
1622
|
import { applyToPoint as applyToPoint13 } from "transformation-matrix";
|
|
1594
1623
|
|
|
1595
1624
|
// lib/drawer/shapes/arrow.ts
|
|
@@ -1611,134 +1640,208 @@ function drawArrow(params) {
|
|
|
1611
1640
|
ctx.restore();
|
|
1612
1641
|
}
|
|
1613
1642
|
|
|
1614
|
-
// lib/drawer/
|
|
1615
|
-
var
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
const
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
const
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
}
|
|
1647
|
-
const
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1643
|
+
// lib/drawer/shapes/dimension-line.ts
|
|
1644
|
+
var TEXT_OFFSET_MULTIPLIER = 1.5;
|
|
1645
|
+
var CHARACTER_WIDTH_MULTIPLIER = 0.6;
|
|
1646
|
+
var TEXT_INTERSECTION_PADDING_MULTIPLIER = 0.3;
|
|
1647
|
+
function normalize(v) {
|
|
1648
|
+
const len = Math.hypot(v.x, v.y) || 1;
|
|
1649
|
+
return { x: v.x / len, y: v.y / len };
|
|
1650
|
+
}
|
|
1651
|
+
function drawDimensionLine(params) {
|
|
1652
|
+
const {
|
|
1653
|
+
ctx,
|
|
1654
|
+
from,
|
|
1655
|
+
to,
|
|
1656
|
+
realToCanvasMat,
|
|
1657
|
+
color,
|
|
1658
|
+
fontSize,
|
|
1659
|
+
arrowSize = 1,
|
|
1660
|
+
strokeWidth: manualStrokeWidth,
|
|
1661
|
+
text,
|
|
1662
|
+
textRotation,
|
|
1663
|
+
offset
|
|
1664
|
+
} = params;
|
|
1665
|
+
const direction = normalize({ x: to.x - from.x, y: to.y - from.y });
|
|
1666
|
+
const perpendicular = { x: -direction.y, y: direction.x };
|
|
1667
|
+
const hasOffsetDirection = offset?.direction && typeof offset.direction.x === "number" && typeof offset.direction.y === "number";
|
|
1668
|
+
const normalizedOffsetDirection = hasOffsetDirection ? normalize(offset.direction) : { x: 0, y: 0 };
|
|
1669
|
+
const offsetMagnitude = offset?.distance ?? 0;
|
|
1670
|
+
const offsetVector = {
|
|
1671
|
+
x: normalizedOffsetDirection.x * offsetMagnitude,
|
|
1672
|
+
y: normalizedOffsetDirection.y * offsetMagnitude
|
|
1673
|
+
};
|
|
1674
|
+
const fromOffset = { x: from.x + offsetVector.x, y: from.y + offsetVector.y };
|
|
1675
|
+
const toOffset = { x: to.x + offsetVector.x, y: to.y + offsetVector.y };
|
|
1676
|
+
const fromBase = {
|
|
1677
|
+
x: fromOffset.x + direction.x * arrowSize,
|
|
1678
|
+
y: fromOffset.y + direction.y * arrowSize
|
|
1679
|
+
};
|
|
1680
|
+
const toBase = {
|
|
1681
|
+
x: toOffset.x - direction.x * arrowSize,
|
|
1682
|
+
y: toOffset.y - direction.y * arrowSize
|
|
1683
|
+
};
|
|
1684
|
+
const scaleValue = Math.abs(realToCanvasMat.a);
|
|
1685
|
+
const strokeWidth = manualStrokeWidth ?? arrowSize / 5;
|
|
1686
|
+
const lineColor = color || "rgba(255,255,255,0.5)";
|
|
1687
|
+
const extensionDirection = hasOffsetDirection && (Math.abs(normalizedOffsetDirection.x) > Number.EPSILON || Math.abs(normalizedOffsetDirection.y) > Number.EPSILON) ? normalizedOffsetDirection : perpendicular;
|
|
1688
|
+
const extensionLength = offsetMagnitude + 0.5;
|
|
1689
|
+
const drawExtension = (anchor) => {
|
|
1690
|
+
const endPoint = {
|
|
1691
|
+
x: anchor.x + extensionDirection.x * extensionLength,
|
|
1692
|
+
y: anchor.y + extensionDirection.y * extensionLength
|
|
1693
|
+
};
|
|
1661
1694
|
drawLine({
|
|
1662
1695
|
ctx,
|
|
1663
|
-
start:
|
|
1664
|
-
end:
|
|
1696
|
+
start: anchor,
|
|
1697
|
+
end: endPoint,
|
|
1665
1698
|
strokeWidth,
|
|
1666
|
-
stroke:
|
|
1699
|
+
stroke: lineColor,
|
|
1667
1700
|
realToCanvasMat
|
|
1668
1701
|
});
|
|
1669
|
-
}
|
|
1702
|
+
};
|
|
1703
|
+
drawExtension(from);
|
|
1704
|
+
drawExtension(to);
|
|
1670
1705
|
drawLine({
|
|
1671
1706
|
ctx,
|
|
1672
|
-
start:
|
|
1673
|
-
end:
|
|
1707
|
+
start: fromBase,
|
|
1708
|
+
end: toBase,
|
|
1674
1709
|
strokeWidth,
|
|
1675
|
-
stroke:
|
|
1710
|
+
stroke: lineColor,
|
|
1676
1711
|
realToCanvasMat
|
|
1677
1712
|
});
|
|
1678
1713
|
const [canvasFromX, canvasFromY] = applyToPoint13(realToCanvasMat, [
|
|
1679
|
-
|
|
1680
|
-
|
|
1714
|
+
fromOffset.x,
|
|
1715
|
+
fromOffset.y
|
|
1681
1716
|
]);
|
|
1682
|
-
const [canvasToX, canvasToY] = applyToPoint13(realToCanvasMat, [
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
const
|
|
1687
|
-
|
|
1688
|
-
|
|
1717
|
+
const [canvasToX, canvasToY] = applyToPoint13(realToCanvasMat, [
|
|
1718
|
+
toOffset.x,
|
|
1719
|
+
toOffset.y
|
|
1720
|
+
]);
|
|
1721
|
+
const [canvasToDirX, canvasToDirY] = applyToPoint13(realToCanvasMat, [
|
|
1722
|
+
toOffset.x + direction.x,
|
|
1723
|
+
toOffset.y + direction.y
|
|
1724
|
+
]);
|
|
1725
|
+
const canvasLineAngle = Math.atan2(
|
|
1726
|
+
canvasToDirY - canvasToY,
|
|
1727
|
+
canvasToDirX - canvasToX
|
|
1728
|
+
);
|
|
1689
1729
|
drawArrow({
|
|
1690
1730
|
ctx,
|
|
1691
1731
|
x: canvasFromX,
|
|
1692
1732
|
y: canvasFromY,
|
|
1693
|
-
angle:
|
|
1694
|
-
arrowSize:
|
|
1695
|
-
color,
|
|
1696
|
-
strokeWidth:
|
|
1733
|
+
angle: canvasLineAngle + Math.PI,
|
|
1734
|
+
arrowSize: arrowSize * scaleValue,
|
|
1735
|
+
color: lineColor,
|
|
1736
|
+
strokeWidth: strokeWidth * scaleValue
|
|
1697
1737
|
});
|
|
1698
1738
|
drawArrow({
|
|
1699
1739
|
ctx,
|
|
1700
1740
|
x: canvasToX,
|
|
1701
1741
|
y: canvasToY,
|
|
1702
|
-
angle:
|
|
1703
|
-
arrowSize:
|
|
1704
|
-
color,
|
|
1705
|
-
strokeWidth:
|
|
1742
|
+
angle: canvasLineAngle,
|
|
1743
|
+
arrowSize: arrowSize * scaleValue,
|
|
1744
|
+
color: lineColor,
|
|
1745
|
+
strokeWidth: strokeWidth * scaleValue
|
|
1706
1746
|
});
|
|
1707
|
-
if (
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
const
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1747
|
+
if (text) {
|
|
1748
|
+
const midPoint = {
|
|
1749
|
+
x: (from.x + to.x) / 2 + offsetVector.x,
|
|
1750
|
+
y: (from.y + to.y) / 2 + offsetVector.y
|
|
1751
|
+
};
|
|
1752
|
+
const [screenFromX, screenFromY] = applyToPoint13(realToCanvasMat, [
|
|
1753
|
+
fromOffset.x,
|
|
1754
|
+
fromOffset.y
|
|
1755
|
+
]);
|
|
1756
|
+
const [screenToX, screenToY] = applyToPoint13(realToCanvasMat, [
|
|
1757
|
+
toOffset.x,
|
|
1758
|
+
toOffset.y
|
|
1759
|
+
]);
|
|
1760
|
+
const screenDirection = normalize({
|
|
1761
|
+
x: screenToX - screenFromX,
|
|
1762
|
+
y: screenToY - screenFromY
|
|
1763
|
+
});
|
|
1764
|
+
let textAngle = Math.atan2(screenDirection.y, screenDirection.x) * 180 / Math.PI;
|
|
1765
|
+
if (textAngle > 90 || textAngle < -90) {
|
|
1766
|
+
textAngle += 180;
|
|
1719
1767
|
}
|
|
1720
|
-
const
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1768
|
+
const finalTextAngle = typeof textRotation === "number" && Number.isFinite(textRotation) ? textAngle - textRotation : textAngle;
|
|
1769
|
+
let additionalOffset = 0;
|
|
1770
|
+
if (text && typeof textRotation === "number" && Number.isFinite(textRotation)) {
|
|
1771
|
+
const textWidth = text.length * fontSize * CHARACTER_WIDTH_MULTIPLIER;
|
|
1772
|
+
const textHeight = fontSize;
|
|
1773
|
+
const rotationRad = textRotation * Math.PI / 180;
|
|
1774
|
+
const sinRot = Math.abs(Math.sin(rotationRad));
|
|
1775
|
+
const cosRot = Math.abs(Math.cos(rotationRad));
|
|
1776
|
+
const halfWidth = textWidth / 2;
|
|
1777
|
+
const halfHeight = textHeight / 2;
|
|
1778
|
+
const maxExtension = halfWidth * sinRot + halfHeight * cosRot;
|
|
1779
|
+
additionalOffset = maxExtension + fontSize * TEXT_INTERSECTION_PADDING_MULTIPLIER;
|
|
1780
|
+
}
|
|
1781
|
+
const textOffset = arrowSize * TEXT_OFFSET_MULTIPLIER + additionalOffset;
|
|
1782
|
+
const textPoint = {
|
|
1783
|
+
x: midPoint.x + perpendicular.x * textOffset,
|
|
1784
|
+
y: midPoint.y + perpendicular.y * textOffset
|
|
1785
|
+
};
|
|
1728
1786
|
drawText({
|
|
1729
1787
|
ctx,
|
|
1730
|
-
text
|
|
1731
|
-
x:
|
|
1732
|
-
y:
|
|
1733
|
-
fontSize
|
|
1734
|
-
color,
|
|
1788
|
+
text,
|
|
1789
|
+
x: textPoint.x,
|
|
1790
|
+
y: textPoint.y,
|
|
1791
|
+
fontSize,
|
|
1792
|
+
color: lineColor,
|
|
1735
1793
|
realToCanvasMat,
|
|
1736
1794
|
anchorAlignment: "center",
|
|
1737
|
-
rotation:
|
|
1795
|
+
rotation: -finalTextAngle
|
|
1796
|
+
// drawText expects CCW rotation in degrees
|
|
1738
1797
|
});
|
|
1739
1798
|
}
|
|
1740
1799
|
}
|
|
1741
1800
|
|
|
1801
|
+
// lib/drawer/elements/pcb-note-dimension.ts
|
|
1802
|
+
var DEFAULT_NOTE_COLOR = "rgba(255,255,255,0.5)";
|
|
1803
|
+
function drawPcbNoteDimension(params) {
|
|
1804
|
+
const { ctx, pcbNoteDimension, realToCanvasMat } = params;
|
|
1805
|
+
const color = pcbNoteDimension.color ?? DEFAULT_NOTE_COLOR;
|
|
1806
|
+
drawDimensionLine({
|
|
1807
|
+
ctx,
|
|
1808
|
+
from: pcbNoteDimension.from,
|
|
1809
|
+
to: pcbNoteDimension.to,
|
|
1810
|
+
realToCanvasMat,
|
|
1811
|
+
color,
|
|
1812
|
+
fontSize: pcbNoteDimension.font_size,
|
|
1813
|
+
arrowSize: pcbNoteDimension.arrow_size,
|
|
1814
|
+
text: pcbNoteDimension.text,
|
|
1815
|
+
textRotation: pcbNoteDimension.text_ccw_rotation,
|
|
1816
|
+
offset: pcbNoteDimension.offset_distance && pcbNoteDimension.offset_direction ? {
|
|
1817
|
+
distance: pcbNoteDimension.offset_distance,
|
|
1818
|
+
direction: pcbNoteDimension.offset_direction
|
|
1819
|
+
} : void 0
|
|
1820
|
+
});
|
|
1821
|
+
}
|
|
1822
|
+
|
|
1823
|
+
// lib/drawer/elements/pcb-fabrication-note-dimension.ts
|
|
1824
|
+
var DEFAULT_FABRICATION_NOTE_COLOR2 = "rgba(255,255,255,0.5)";
|
|
1825
|
+
function drawPcbFabricationNoteDimension(params) {
|
|
1826
|
+
const { ctx, pcbFabricationNoteDimension, realToCanvasMat } = params;
|
|
1827
|
+
const color = pcbFabricationNoteDimension.color ?? DEFAULT_FABRICATION_NOTE_COLOR2;
|
|
1828
|
+
drawDimensionLine({
|
|
1829
|
+
ctx,
|
|
1830
|
+
from: pcbFabricationNoteDimension.from,
|
|
1831
|
+
to: pcbFabricationNoteDimension.to,
|
|
1832
|
+
realToCanvasMat,
|
|
1833
|
+
color,
|
|
1834
|
+
fontSize: pcbFabricationNoteDimension.font_size ?? 1,
|
|
1835
|
+
arrowSize: pcbFabricationNoteDimension.arrow_size ?? 1,
|
|
1836
|
+
text: pcbFabricationNoteDimension.text,
|
|
1837
|
+
textRotation: pcbFabricationNoteDimension.text_ccw_rotation,
|
|
1838
|
+
offset: pcbFabricationNoteDimension.offset_distance && pcbFabricationNoteDimension.offset_direction ? {
|
|
1839
|
+
distance: pcbFabricationNoteDimension.offset_distance,
|
|
1840
|
+
direction: pcbFabricationNoteDimension.offset_direction
|
|
1841
|
+
} : void 0
|
|
1842
|
+
});
|
|
1843
|
+
}
|
|
1844
|
+
|
|
1742
1845
|
// lib/drawer/elements/pcb-note-line.ts
|
|
1743
1846
|
import { applyToPoint as applyToPoint14 } from "transformation-matrix";
|
|
1744
1847
|
function drawPcbNoteLine(params) {
|
|
@@ -2002,6 +2105,14 @@ var CircuitToCanvasDrawer = class {
|
|
|
2002
2105
|
colorMap: this.colorMap
|
|
2003
2106
|
});
|
|
2004
2107
|
}
|
|
2108
|
+
if (element.type === "pcb_silkscreen_oval") {
|
|
2109
|
+
drawPcbSilkscreenOval({
|
|
2110
|
+
ctx: this.ctx,
|
|
2111
|
+
oval: element,
|
|
2112
|
+
realToCanvasMat: this.realToCanvasMat,
|
|
2113
|
+
colorMap: this.colorMap
|
|
2114
|
+
});
|
|
2115
|
+
}
|
|
2005
2116
|
if (element.type === "pcb_cutout") {
|
|
2006
2117
|
drawPcbCutout({
|
|
2007
2118
|
ctx: this.ctx,
|
|
@@ -2090,6 +2201,14 @@ var CircuitToCanvasDrawer = class {
|
|
|
2090
2201
|
colorMap: this.colorMap
|
|
2091
2202
|
});
|
|
2092
2203
|
}
|
|
2204
|
+
if (element.type === "pcb_fabrication_note_dimension") {
|
|
2205
|
+
drawPcbFabricationNoteDimension({
|
|
2206
|
+
ctx: this.ctx,
|
|
2207
|
+
pcbFabricationNoteDimension: element,
|
|
2208
|
+
realToCanvasMat: this.realToCanvasMat,
|
|
2209
|
+
colorMap: this.colorMap
|
|
2210
|
+
});
|
|
2211
|
+
}
|
|
2093
2212
|
}
|
|
2094
2213
|
};
|
|
2095
2214
|
export {
|
|
@@ -2097,6 +2216,7 @@ export {
|
|
|
2097
2216
|
DEFAULT_PCB_COLOR_MAP,
|
|
2098
2217
|
drawArrow,
|
|
2099
2218
|
drawCircle,
|
|
2219
|
+
drawDimensionLine,
|
|
2100
2220
|
drawLine,
|
|
2101
2221
|
drawOval,
|
|
2102
2222
|
drawPath,
|
|
@@ -2104,6 +2224,7 @@ export {
|
|
|
2104
2224
|
drawPcbCopperPour,
|
|
2105
2225
|
drawPcbCopperText,
|
|
2106
2226
|
drawPcbCutout,
|
|
2227
|
+
drawPcbFabricationNoteDimension,
|
|
2107
2228
|
drawPcbFabricationNotePath,
|
|
2108
2229
|
drawPcbFabricationNoteRect,
|
|
2109
2230
|
drawPcbFabricationNoteText,
|
|
@@ -2115,6 +2236,7 @@ export {
|
|
|
2115
2236
|
drawPcbPlatedHole,
|
|
2116
2237
|
drawPcbSilkscreenCircle,
|
|
2117
2238
|
drawPcbSilkscreenLine,
|
|
2239
|
+
drawPcbSilkscreenOval,
|
|
2118
2240
|
drawPcbSilkscreenPath,
|
|
2119
2241
|
drawPcbSilkscreenPill,
|
|
2120
2242
|
drawPcbSilkscreenRect,
|
|
@@ -10,6 +10,7 @@ import type {
|
|
|
10
10
|
PcbSilkscreenRect,
|
|
11
11
|
PcbSilkscreenCircle,
|
|
12
12
|
PcbSilkscreenLine,
|
|
13
|
+
PcbSilkscreenOval,
|
|
13
14
|
PcbSilkscreenPath,
|
|
14
15
|
PcbSilkscreenPill,
|
|
15
16
|
PcbCutout,
|
|
@@ -22,6 +23,7 @@ import type {
|
|
|
22
23
|
PcbNotePath,
|
|
23
24
|
PcbNoteText,
|
|
24
25
|
PcbNoteDimension,
|
|
26
|
+
PcbFabricationNoteDimension,
|
|
25
27
|
PcbNoteLine,
|
|
26
28
|
PcbRenderLayer,
|
|
27
29
|
} from "circuit-json"
|
|
@@ -54,6 +56,7 @@ import { drawPcbSilkscreenRect } from "./elements/pcb-silkscreen-rect"
|
|
|
54
56
|
import { drawPcbSilkscreenCircle } from "./elements/pcb-silkscreen-circle"
|
|
55
57
|
import { drawPcbSilkscreenLine } from "./elements/pcb-silkscreen-line"
|
|
56
58
|
import { drawPcbSilkscreenPath } from "./elements/pcb-silkscreen-path"
|
|
59
|
+
import { drawPcbSilkscreenOval } from "./elements/pcb-silkscreen-oval"
|
|
57
60
|
import { drawPcbSilkscreenPill } from "./elements/pcb-silkscreen-pill"
|
|
58
61
|
import { drawPcbCutout } from "./elements/pcb-cutout"
|
|
59
62
|
import { drawPcbCopperPour } from "./elements/pcb-copper-pour"
|
|
@@ -65,6 +68,7 @@ import { drawPcbFabricationNotePath } from "./elements/pcb-fabrication-note-path
|
|
|
65
68
|
import { drawPcbNotePath } from "./elements/pcb-note-path"
|
|
66
69
|
import { drawPcbNoteText } from "./elements/pcb-note-text"
|
|
67
70
|
import { drawPcbNoteDimension } from "./elements/pcb-note-dimension"
|
|
71
|
+
import { drawPcbFabricationNoteDimension } from "./elements/pcb-fabrication-note-dimension"
|
|
68
72
|
import { drawPcbNoteLine } from "./elements/pcb-note-line"
|
|
69
73
|
|
|
70
74
|
export interface DrawElementsOptions {
|
|
@@ -373,6 +377,15 @@ export class CircuitToCanvasDrawer {
|
|
|
373
377
|
})
|
|
374
378
|
}
|
|
375
379
|
|
|
380
|
+
if (element.type === "pcb_silkscreen_oval") {
|
|
381
|
+
drawPcbSilkscreenOval({
|
|
382
|
+
ctx: this.ctx,
|
|
383
|
+
oval: element as PcbSilkscreenOval,
|
|
384
|
+
realToCanvasMat: this.realToCanvasMat,
|
|
385
|
+
colorMap: this.colorMap,
|
|
386
|
+
})
|
|
387
|
+
}
|
|
388
|
+
|
|
376
389
|
if (element.type === "pcb_cutout") {
|
|
377
390
|
drawPcbCutout({
|
|
378
391
|
ctx: this.ctx,
|
|
@@ -471,5 +484,14 @@ export class CircuitToCanvasDrawer {
|
|
|
471
484
|
colorMap: this.colorMap,
|
|
472
485
|
})
|
|
473
486
|
}
|
|
487
|
+
|
|
488
|
+
if (element.type === "pcb_fabrication_note_dimension") {
|
|
489
|
+
drawPcbFabricationNoteDimension({
|
|
490
|
+
ctx: this.ctx,
|
|
491
|
+
pcbFabricationNoteDimension: element as PcbFabricationNoteDimension,
|
|
492
|
+
realToCanvasMat: this.realToCanvasMat,
|
|
493
|
+
colorMap: this.colorMap,
|
|
494
|
+
})
|
|
495
|
+
}
|
|
474
496
|
}
|
|
475
497
|
}
|
|
@@ -48,6 +48,11 @@ export {
|
|
|
48
48
|
type DrawPcbSilkscreenPillParams,
|
|
49
49
|
} from "./pcb-silkscreen-pill"
|
|
50
50
|
|
|
51
|
+
export {
|
|
52
|
+
drawPcbSilkscreenOval,
|
|
53
|
+
type DrawPcbSilkscreenOvalParams,
|
|
54
|
+
} from "./pcb-silkscreen-oval"
|
|
55
|
+
|
|
51
56
|
export { drawPcbCutout, type DrawPcbCutoutParams } from "./pcb-cutout"
|
|
52
57
|
|
|
53
58
|
export {
|
|
@@ -94,3 +99,8 @@ export {
|
|
|
94
99
|
drawPcbNoteDimension,
|
|
95
100
|
type DrawPcbNoteDimensionParams,
|
|
96
101
|
} from "./pcb-note-dimension"
|
|
102
|
+
|
|
103
|
+
export {
|
|
104
|
+
drawPcbFabricationNoteDimension,
|
|
105
|
+
type DrawPcbFabricationNoteDimensionParams,
|
|
106
|
+
} from "./pcb-fabrication-note-dimension"
|