@tscircuit/pcb-viewer 1.5.0 → 1.6.0

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.js CHANGED
@@ -13390,7 +13390,7 @@ var import_soup2 = __toESM(require_dist());
13390
13390
  // package.json
13391
13391
  var package_default = {
13392
13392
  name: "@tscircuit/pcb-viewer",
13393
- version: "1.4.6",
13393
+ version: "1.5.0",
13394
13394
  main: "dist/index.js",
13395
13395
  repository: "tscircuit/pcb-viewer",
13396
13396
  license: "MIT",
@@ -14243,48 +14243,57 @@ var EditTraceHintOverlay = function(param) {
14243
14243
  var route = e.route;
14244
14244
  var pcb_port = (0, import_soup_util2.su)(soup).pcb_port.get(e.pcb_port_id);
14245
14245
  var pcb_port_screen = (0, import_transformation_matrix6.applyToPoint)(transform, pcb_port);
14246
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react13.Fragment, {
14246
+ var strokeInput = [
14247
+ {
14248
+ x: pcb_port_screen.x,
14249
+ y: pcb_port_screen.y,
14250
+ trace_width: 0.5
14251
+ }
14252
+ ].concat(// Start with a small width
14253
+ _to_consumable_array(route.map(function(r) {
14254
+ if (r === void 0) {
14255
+ throw new Error("route contains undefined point");
14256
+ }
14257
+ return {
14258
+ x: (0, import_transformation_matrix6.applyToPoint)(transform, r).x,
14259
+ y: (0, import_transformation_matrix6.applyToPoint)(transform, r).y,
14260
+ trace_width: r.trace_width
14261
+ };
14262
+ })));
14263
+ var expandedStroke = getExpandedStroke(strokeInput, 0.5);
14264
+ var expandedPath = expandedStroke.map(function(point, index) {
14265
+ return "".concat(index === 0 ? "M" : "L", " ").concat(point.x, ",").concat(point.y);
14266
+ }).join(" ") + " Z";
14267
+ var originalPath = strokeInput.map(function(point, index) {
14268
+ return "".concat(index === 0 ? "M" : "L", " ").concat(point.x, ",").concat(point.y);
14269
+ }).join(" ");
14270
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("g", {
14247
14271
  children: [
14248
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("rect", {
14249
- x: pcb_port_screen.x - 10,
14250
- y: pcb_port_screen.y - 10,
14251
- width: 20,
14252
- height: 20,
14272
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", {
14273
+ d: expandedPath,
14274
+ fill: "red"
14275
+ }, "expanded-path-".concat(e.pcb_port_id)),
14276
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", {
14277
+ d: originalPath,
14278
+ style: {
14279
+ mixBlendMode: "difference"
14280
+ },
14253
14281
  stroke: "red"
14254
- }, "rect-".concat(e.pcb_port_id)),
14255
- route.map(function(r, index) {
14256
- var start = index === 0 ? pcb_port_screen : (0, import_transformation_matrix6.applyToPoint)(transform, route[index - 1]);
14257
- var end = (0, import_transformation_matrix6.applyToPoint)(transform, r);
14258
- var width = r === null || r === void 0 ? void 0 : r.trace_width;
14259
- var angle = Math.atan2(end.y - start.y, end.x - start.x);
14260
- var dx = width !== null && width !== void 0 ? width : 0.5 * Math.sin(angle);
14261
- var dy = width !== null && width !== void 0 ? width : 0.5 * -Math.cos(angle);
14262
- var topLeft = "".concat(start.x - dx, ",").concat(start.y - dy);
14263
- var topRight = "".concat(end.x - dx, ",").concat(end.y - dy);
14264
- var bottomRight = "".concat(end.x + dx, ",").concat(end.y + dy);
14265
- var bottomLeft = "".concat(start.x + dx, ",").concat(start.y + dy);
14266
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", {
14267
- fill: "red",
14268
- d: "M ".concat(topLeft, " L ").concat(topRight, " L ").concat(bottomRight, " L ").concat(bottomLeft, " Z")
14269
- }, "path-".concat(e.pcb_port_id, "-").concat(index));
14270
- }),
14271
- route.map(function(r) {
14272
- return _object_spread({}, r, (0, import_transformation_matrix6.applyToPoint)(transform, r));
14273
- }).map(function(r, i) {
14274
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react13.Fragment, {
14282
+ }, "original-path-".concat(e.pcb_port_id)),
14283
+ strokeInput.map(function(r, i) {
14284
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("g", {
14275
14285
  children: [
14276
14286
  /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("circle", {
14277
14287
  cx: r.x,
14278
14288
  cy: r.y,
14279
- r: 8,
14289
+ r: r.trace_width ? r.trace_width / 2 : 8,
14280
14290
  stroke: "red"
14281
14291
  }),
14282
14292
  r.via && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("circle", {
14283
14293
  cx: r.x,
14284
14294
  cy: r.y,
14285
- r: 16,
14286
- stroke: "red",
14287
- fill: "transparent"
14295
+ r: r.trace_width ? r.trace_width / 2 : 8,
14296
+ stroke: "red"
14288
14297
  })
14289
14298
  ]
14290
14299
  }, i);
@@ -14314,6 +14323,83 @@ var EditTraceHintOverlay = function(param) {
14314
14323
  ]
14315
14324
  });
14316
14325
  };
14326
+ function getExpandedStroke(strokeInput, defaultWidth) {
14327
+ if (strokeInput.length < 2) {
14328
+ throw new Error("Stroke must have at least two points");
14329
+ }
14330
+ var stroke = strokeInput.map(function(point) {
14331
+ if (Array.isArray(point)) {
14332
+ return {
14333
+ x: point[0],
14334
+ y: point[1]
14335
+ };
14336
+ }
14337
+ return point;
14338
+ });
14339
+ var leftSide = [];
14340
+ var rightSide = [];
14341
+ function getNormal(p1, p2) {
14342
+ var dx = p2.x - p1.x;
14343
+ var dy = p2.y - p1.y;
14344
+ var length = Math.sqrt(dx * dx + dy * dy);
14345
+ return {
14346
+ x: -dy / length,
14347
+ y: dx / length
14348
+ };
14349
+ }
14350
+ function addPoint(point, normal, factor, width) {
14351
+ var halfWidth = width / 2;
14352
+ var newPoint = {
14353
+ x: point.x + normal.x * halfWidth * factor,
14354
+ y: point.y + normal.y * halfWidth * factor
14355
+ };
14356
+ if (factor > 0) {
14357
+ leftSide.push(newPoint);
14358
+ } else {
14359
+ rightSide.unshift(newPoint);
14360
+ }
14361
+ }
14362
+ var firstNormal = getNormal(stroke[0], stroke[1]);
14363
+ var _stroke__trace_width;
14364
+ var firstWidth = (_stroke__trace_width = stroke[0].trace_width) !== null && _stroke__trace_width !== void 0 ? _stroke__trace_width : defaultWidth;
14365
+ addPoint(stroke[0], firstNormal, 1, firstWidth);
14366
+ addPoint(stroke[0], firstNormal, -1, firstWidth);
14367
+ for(var i = 1; i < stroke.length - 1; i++){
14368
+ var prev = stroke[i - 1];
14369
+ var current = stroke[i];
14370
+ var next = stroke[i + 1];
14371
+ var normalPrev = getNormal(prev, current);
14372
+ var normalNext = getNormal(current, next);
14373
+ var miterX = normalPrev.x + normalNext.x;
14374
+ var miterY = normalPrev.y + normalNext.y;
14375
+ var miterLength = Math.sqrt(miterX * miterX + miterY * miterY);
14376
+ var _current_trace_width;
14377
+ var currentWidth = (_current_trace_width = current.trace_width) !== null && _current_trace_width !== void 0 ? _current_trace_width : defaultWidth;
14378
+ var miterLimit = 2;
14379
+ if (miterLength / 2 > miterLimit * (currentWidth / 2)) {
14380
+ addPoint(current, normalPrev, 1, currentWidth);
14381
+ addPoint(current, normalNext, 1, currentWidth);
14382
+ addPoint(current, normalPrev, -1, currentWidth);
14383
+ addPoint(current, normalNext, -1, currentWidth);
14384
+ } else {
14385
+ var scale2 = 1 / miterLength;
14386
+ addPoint(current, {
14387
+ x: miterX * scale2,
14388
+ y: miterY * scale2
14389
+ }, 1, currentWidth);
14390
+ addPoint(current, {
14391
+ x: miterX * scale2,
14392
+ y: miterY * scale2
14393
+ }, -1, currentWidth);
14394
+ }
14395
+ }
14396
+ var lastNormal = getNormal(stroke[stroke.length - 2], stroke[stroke.length - 1]);
14397
+ var _stroke__trace_width1;
14398
+ var lastWidth = (_stroke__trace_width1 = stroke[stroke.length - 1].trace_width) !== null && _stroke__trace_width1 !== void 0 ? _stroke__trace_width1 : defaultWidth;
14399
+ addPoint(stroke[stroke.length - 1], lastNormal, 1, lastWidth);
14400
+ addPoint(stroke[stroke.length - 1], lastNormal, -1, lastWidth);
14401
+ return _to_consumable_array(leftSide).concat(_to_consumable_array(rightSide));
14402
+ }
14317
14403
  // src/components/RatsNestOverlay.tsx
14318
14404
  var import_transformation_matrix7 = require("transformation-matrix");
14319
14405
  var import_soup_util3 = __toESM(require_dist2());