@tscircuit/pcb-viewer 1.11.260 → 1.11.261

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
@@ -10150,6 +10150,133 @@ function useDiagonalLabel(params) {
10150
10150
  );
10151
10151
  }
10152
10152
 
10153
+ // src/lib/util/get-primitive-snap-points.ts
10154
+ var rotatePoint2 = (point, center, rotationDeg) => {
10155
+ const radians = rotationDeg * Math.PI / 180;
10156
+ const cos = Math.cos(radians);
10157
+ const sin = Math.sin(radians);
10158
+ const translatedX = point.x - center.x;
10159
+ const translatedY = point.y - center.y;
10160
+ const rotatedX = translatedX * cos - translatedY * sin;
10161
+ const rotatedY = translatedX * sin + translatedY * cos;
10162
+ return {
10163
+ x: rotatedX + center.x,
10164
+ y: rotatedY + center.y
10165
+ };
10166
+ };
10167
+ var getNinePointAnchors = (center, halfWidth, halfHeight, rotationDeg) => {
10168
+ const basePoints = {
10169
+ top_left: { x: center.x - halfWidth, y: center.y - halfHeight },
10170
+ top_center: { x: center.x, y: center.y - halfHeight },
10171
+ top_right: { x: center.x + halfWidth, y: center.y - halfHeight },
10172
+ center_left: { x: center.x - halfWidth, y: center.y },
10173
+ center: { x: center.x, y: center.y },
10174
+ center_right: { x: center.x + halfWidth, y: center.y },
10175
+ bottom_left: { x: center.x - halfWidth, y: center.y + halfHeight },
10176
+ bottom_center: { x: center.x, y: center.y + halfHeight },
10177
+ bottom_right: { x: center.x + halfWidth, y: center.y + halfHeight }
10178
+ };
10179
+ if (rotationDeg === 0) {
10180
+ return Object.entries(basePoints).map(([anchor, point]) => ({
10181
+ anchor,
10182
+ point
10183
+ }));
10184
+ }
10185
+ return Object.entries(basePoints).map(([anchor, point]) => ({
10186
+ anchor,
10187
+ point: rotatePoint2(point, center, rotationDeg)
10188
+ }));
10189
+ };
10190
+ var getPrimitiveSnapPoints = (primitive) => {
10191
+ switch (primitive.pcb_drawing_type) {
10192
+ case "rect": {
10193
+ const rotation = primitive.ccw_rotation ?? 0;
10194
+ return getNinePointAnchors(
10195
+ { x: primitive.x, y: primitive.y },
10196
+ primitive.w / 2,
10197
+ primitive.h / 2,
10198
+ rotation
10199
+ );
10200
+ }
10201
+ case "pill": {
10202
+ const rotation = primitive.ccw_rotation ?? 0;
10203
+ return getNinePointAnchors(
10204
+ { x: primitive.x, y: primitive.y },
10205
+ primitive.w / 2,
10206
+ primitive.h / 2,
10207
+ rotation
10208
+ );
10209
+ }
10210
+ case "circle": {
10211
+ return [
10212
+ { anchor: "circle_center", point: { x: primitive.x, y: primitive.y } },
10213
+ {
10214
+ anchor: "circle_right",
10215
+ point: { x: primitive.x + primitive.r, y: primitive.y }
10216
+ },
10217
+ {
10218
+ anchor: "circle_left",
10219
+ point: { x: primitive.x - primitive.r, y: primitive.y }
10220
+ },
10221
+ {
10222
+ anchor: "circle_top",
10223
+ point: { x: primitive.x, y: primitive.y - primitive.r }
10224
+ },
10225
+ {
10226
+ anchor: "circle_bottom",
10227
+ point: { x: primitive.x, y: primitive.y + primitive.r }
10228
+ }
10229
+ ];
10230
+ }
10231
+ case "oval": {
10232
+ return [
10233
+ { anchor: "oval_center", point: { x: primitive.x, y: primitive.y } },
10234
+ {
10235
+ anchor: "oval_right",
10236
+ point: { x: primitive.x + primitive.rX, y: primitive.y }
10237
+ },
10238
+ {
10239
+ anchor: "oval_left",
10240
+ point: { x: primitive.x - primitive.rX, y: primitive.y }
10241
+ },
10242
+ {
10243
+ anchor: "oval_top",
10244
+ point: { x: primitive.x, y: primitive.y - primitive.rY }
10245
+ },
10246
+ {
10247
+ anchor: "oval_bottom",
10248
+ point: { x: primitive.x, y: primitive.y + primitive.rY }
10249
+ }
10250
+ ];
10251
+ }
10252
+ case "line": {
10253
+ const midPoint = {
10254
+ x: (primitive.x1 + primitive.x2) / 2,
10255
+ y: (primitive.y1 + primitive.y2) / 2
10256
+ };
10257
+ return [
10258
+ { anchor: "line_start", point: { x: primitive.x1, y: primitive.y1 } },
10259
+ { anchor: "line_mid", point: midPoint },
10260
+ { anchor: "line_end", point: { x: primitive.x2, y: primitive.y2 } }
10261
+ ];
10262
+ }
10263
+ case "polygon": {
10264
+ return primitive.points.map((point, index) => ({
10265
+ anchor: `polygon_vertex_${index}`,
10266
+ point
10267
+ }));
10268
+ }
10269
+ case "polygon_with_arcs": {
10270
+ return primitive.brep_shape.outer_ring.vertices.map((vertex, index) => ({
10271
+ anchor: `polygon_with_arcs_vertex_${index}`,
10272
+ point: { x: vertex.x, y: vertex.y }
10273
+ }));
10274
+ }
10275
+ default:
10276
+ return [];
10277
+ }
10278
+ };
10279
+
10153
10280
  // src/components/DimensionOverlay.tsx
10154
10281
  import { Fragment, jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
10155
10282
  var SNAP_THRESHOLD_PX = 16;
@@ -10201,6 +10328,9 @@ var DimensionOverlay = ({
10201
10328
  for (const primitive of primitives) {
10202
10329
  if (!primitive._element) continue;
10203
10330
  if (shouldExcludePrimitiveFromSnapping(primitive)) continue;
10331
+ if (primitive.pcb_drawing_type === "pill") continue;
10332
+ if (primitive.pcb_drawing_type === "rect" && primitive.ccw_rotation && primitive.ccw_rotation !== 0)
10333
+ continue;
10204
10334
  const bbox = getPrimitiveBoundingBox(primitive);
10205
10335
  if (!bbox) continue;
10206
10336
  const existing = boundingBoxes.get(primitive._element);
@@ -10211,6 +10341,23 @@ var DimensionOverlay = ({
10211
10341
  }
10212
10342
  return boundingBoxes;
10213
10343
  }, [primitives]);
10344
+ const primitiveSnappingPoints = useMemo4(() => {
10345
+ const snapPoints = [];
10346
+ for (const primitive of primitives) {
10347
+ if (!primitive._element) continue;
10348
+ if (shouldExcludePrimitiveFromSnapping(primitive)) continue;
10349
+ const primitivePoints = getPrimitiveSnapPoints(primitive);
10350
+ if (primitivePoints.length === 0) continue;
10351
+ for (const snap of primitivePoints) {
10352
+ snapPoints.push({
10353
+ anchor: snap.anchor,
10354
+ point: snap.point,
10355
+ element: primitive._element
10356
+ });
10357
+ }
10358
+ }
10359
+ return snapPoints;
10360
+ }, [primitives]);
10214
10361
  const snappingPoints = useMemo4(() => {
10215
10362
  const points = [];
10216
10363
  elementBoundingBoxes.forEach((bounds, element) => {
@@ -10236,13 +10383,16 @@ var DimensionOverlay = ({
10236
10383
  });
10237
10384
  }
10238
10385
  });
10386
+ for (const snap of primitiveSnappingPoints) {
10387
+ points.push(snap);
10388
+ }
10239
10389
  points.push({
10240
10390
  anchor: "origin",
10241
10391
  point: { x: 0, y: 0 },
10242
10392
  element: null
10243
10393
  });
10244
10394
  return points;
10245
- }, [elementBoundingBoxes]);
10395
+ }, [elementBoundingBoxes, primitiveSnappingPoints]);
10246
10396
  const snappingPointsWithScreen = useMemo4(() => {
10247
10397
  return snappingPoints.map((snap, index) => ({
10248
10398
  ...snap,
@@ -12587,7 +12737,7 @@ import { css as css3 } from "@emotion/css";
12587
12737
  // package.json
12588
12738
  var package_default = {
12589
12739
  name: "@tscircuit/pcb-viewer",
12590
- version: "1.11.259",
12740
+ version: "1.11.260",
12591
12741
  main: "dist/index.js",
12592
12742
  type: "module",
12593
12743
  repository: "tscircuit/pcb-viewer",