graphics-debug 0.0.30 → 0.0.32
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/{chunk-BWBQQ6Y7.js → chunk-A4VFIZRQ.js} +6 -4
- package/dist/chunk-A4VFIZRQ.js.map +1 -0
- package/dist/{chunk-6WVCPMEL.js → chunk-CZLSXU7Y.js} +7 -2
- package/dist/{chunk-6WVCPMEL.js.map → chunk-CZLSXU7Y.js.map} +1 -1
- package/dist/{chunk-ZEG3QOSQ.js → chunk-KXJRUEMA.js} +2 -2
- package/dist/cli/cli.js +3 -3
- package/dist/lib/drawGraphicsToCanvas.js +1 -1
- package/dist/lib/getSvgFromGraphicsObject.d.ts +3 -1
- package/dist/lib/getSvgFromGraphicsObject.js +1 -1
- package/dist/lib/index.js +3 -3
- package/dist/lib/matcher.js +1 -1
- package/dist/lib/react.d.ts +2 -1
- package/dist/lib/react.js +72 -48
- package/dist/lib/react.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-BWBQQ6Y7.js.map +0 -1
- /package/dist/{chunk-ZEG3QOSQ.js.map → chunk-KXJRUEMA.js.map} +0 -0
|
@@ -65,7 +65,9 @@ function projectPoint(point, matrix) {
|
|
|
65
65
|
const projected = applyToPoint(matrix, { x: point.x, y: point.y });
|
|
66
66
|
return { ...point, ...projected };
|
|
67
67
|
}
|
|
68
|
-
function getSvgFromGraphicsObject(graphics
|
|
68
|
+
function getSvgFromGraphicsObject(graphics, {
|
|
69
|
+
includeTextLabels = false
|
|
70
|
+
} = {}) {
|
|
69
71
|
const bounds = getBounds(graphics);
|
|
70
72
|
const matrix = getProjectionMatrix(bounds, graphics.coordinateSystem);
|
|
71
73
|
const svgObject = {
|
|
@@ -100,7 +102,7 @@ function getSvgFromGraphicsObject(graphics) {
|
|
|
100
102
|
fill: point.color || "black"
|
|
101
103
|
}
|
|
102
104
|
},
|
|
103
|
-
...point.label ? [
|
|
105
|
+
...includeTextLabels && point.label ? [
|
|
104
106
|
{
|
|
105
107
|
name: "text",
|
|
106
108
|
type: "element",
|
|
@@ -126,7 +128,7 @@ function getSvgFromGraphicsObject(graphics) {
|
|
|
126
128
|
points: line.points.map((p) => projectPoint(p, matrix)).map((p) => `${p.x},${p.y}`).join(" "),
|
|
127
129
|
fill: "none",
|
|
128
130
|
stroke: line.strokeColor || "black",
|
|
129
|
-
"stroke-width": (line.strokeWidth
|
|
131
|
+
"stroke-width": (line.strokeWidth ? line.strokeWidth * matrix.a : 1).toString()
|
|
130
132
|
}
|
|
131
133
|
})),
|
|
132
134
|
// Rectangles
|
|
@@ -288,4 +290,4 @@ function getSvgFromGraphicsObject(graphics) {
|
|
|
288
290
|
export {
|
|
289
291
|
getSvgFromGraphicsObject
|
|
290
292
|
};
|
|
291
|
-
//# sourceMappingURL=chunk-
|
|
293
|
+
//# sourceMappingURL=chunk-A4VFIZRQ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../lib/getSvgFromGraphicsObject.ts"],"sourcesContent":["import {\n transform,\n compose,\n translate,\n scale,\n applyToPoint,\n identity,\n type Matrix,\n} from \"transformation-matrix\"\nimport type { GraphicsObject, Point } from \"./types\"\nimport { stringify } from \"svgson\"\nimport pretty from \"pretty\"\n\nconst DEFAULT_SVG_SIZE = 640\nconst PADDING = 40\n\ninterface Bounds {\n minX: number\n maxX: number\n minY: number\n maxY: number\n}\n\nfunction getBounds(graphics: GraphicsObject): Bounds {\n const points: Point[] = [\n ...(graphics.points || []),\n ...(graphics.lines || []).flatMap((line) => line.points),\n ...(graphics.rects || []).flatMap((rect) => {\n const halfWidth = rect.width / 2\n const halfHeight = rect.height / 2\n return [\n { x: rect.center.x - halfWidth, y: rect.center.y - halfHeight },\n { x: rect.center.x + halfWidth, y: rect.center.y - halfHeight },\n { x: rect.center.x - halfWidth, y: rect.center.y + halfHeight },\n { x: rect.center.x + halfWidth, y: rect.center.y + halfHeight },\n ]\n }),\n ...(graphics.circles || []).flatMap((circle) => [\n { x: circle.center.x - circle.radius, y: circle.center.y }, // left\n { x: circle.center.x + circle.radius, y: circle.center.y }, // right\n { x: circle.center.x, y: circle.center.y - circle.radius }, // top\n { x: circle.center.x, y: circle.center.y + circle.radius }, // bottom\n ]),\n ]\n\n if (points.length === 0) {\n return { minX: -1, maxX: 1, minY: -1, maxY: 1 }\n }\n\n return points.reduce(\n (bounds, point) => ({\n minX: Math.min(bounds.minX, point.x),\n maxX: Math.max(bounds.maxX, point.x),\n minY: Math.min(bounds.minY, point.y),\n maxY: Math.max(bounds.maxY, point.y),\n }),\n { minX: Infinity, maxX: -Infinity, minY: Infinity, maxY: -Infinity },\n )\n}\n\nfunction getProjectionMatrix(\n bounds: Bounds,\n coordinateSystem: GraphicsObject[\"coordinateSystem\"],\n) {\n const width = bounds.maxX - bounds.minX\n const height = bounds.maxY - bounds.minY\n\n const scale_factor = Math.min(\n (DEFAULT_SVG_SIZE - 2 * PADDING) / width,\n (DEFAULT_SVG_SIZE - 2 * PADDING) / height,\n )\n\n const yFlip = coordinateSystem === \"screen\" ? 1 : -1\n\n return compose(\n translate(DEFAULT_SVG_SIZE / 2, DEFAULT_SVG_SIZE / 2),\n scale(scale_factor, yFlip * scale_factor),\n translate(-(bounds.minX + width / 2), -(bounds.minY + height / 2)),\n )\n}\n\nfunction projectPoint(point: Point, matrix: Matrix) {\n const projected = applyToPoint(matrix, { x: point.x, y: point.y })\n return { ...point, ...projected }\n}\n\nexport function getSvgFromGraphicsObject(\n graphics: GraphicsObject,\n {\n includeTextLabels = false,\n }: {\n includeTextLabels?: boolean\n } = {},\n): string {\n const bounds = getBounds(graphics)\n const matrix = getProjectionMatrix(bounds, graphics.coordinateSystem)\n\n const svgObject = {\n name: \"svg\",\n type: \"element\",\n attributes: {\n width: DEFAULT_SVG_SIZE.toString(),\n height: DEFAULT_SVG_SIZE.toString(),\n viewBox: `0 0 ${DEFAULT_SVG_SIZE} ${DEFAULT_SVG_SIZE}`,\n xmlns: \"http://www.w3.org/2000/svg\",\n },\n children: [\n // Points\n ...(graphics.points || []).map((point) => {\n const projected = projectPoint(point, matrix)\n return {\n name: \"g\",\n type: \"element\",\n attributes: {},\n children: [\n {\n name: \"circle\",\n type: \"element\",\n attributes: {\n \"data-type\": \"point\",\n \"data-label\": point.label || \"\",\n \"data-x\": point.x.toString(),\n \"data-y\": point.y.toString(),\n cx: projected.x.toString(),\n cy: projected.y.toString(),\n r: \"3\",\n fill: point.color || \"black\",\n },\n },\n ...(includeTextLabels && point.label\n ? [\n {\n name: \"text\",\n type: \"element\",\n attributes: {\n x: (projected.x + 5).toString(),\n y: (projected.y - 5).toString(),\n \"font-family\": \"sans-serif\",\n \"font-size\": \"12\",\n },\n children: [{ type: \"text\", value: point.label }],\n },\n ]\n : []),\n ],\n }\n }),\n // Lines\n ...(graphics.lines || []).map((line) => ({\n name: \"polyline\",\n type: \"element\",\n attributes: {\n \"data-points\": line.points.map((p) => `${p.x},${p.y}`).join(\" \"),\n \"data-type\": \"line\",\n points: line.points\n .map((p) => projectPoint(p, matrix))\n .map((p) => `${p.x},${p.y}`)\n .join(\" \"),\n fill: \"none\",\n stroke: line.strokeColor || \"black\",\n \"stroke-width\": (line.strokeWidth\n ? line.strokeWidth * matrix.a\n : 1\n ).toString(),\n },\n })),\n // Rectangles\n ...(graphics.rects || []).map((rect) => {\n const corner1 = {\n x: rect.center.x - rect.width / 2,\n y: rect.center.y - rect.height / 2,\n }\n const projectedCorner1 = projectPoint(corner1, matrix)\n const corner2 = {\n x: rect.center.x + rect.width / 2,\n y: rect.center.y + rect.height / 2,\n }\n const projectedCorner2 = projectPoint(corner2, matrix)\n const scaledWidth = Math.abs(projectedCorner2.x - projectedCorner1.x)\n const scaledHeight = Math.abs(projectedCorner2.y - projectedCorner1.y)\n return {\n name: \"rect\",\n type: \"element\",\n attributes: {\n \"data-type\": \"rect\",\n \"data-label\": \"\",\n \"data-x\": rect.center.x.toString(),\n \"data-y\": rect.center.y.toString(),\n x: Math.min(projectedCorner1.x, projectedCorner2.x).toString(),\n y: Math.min(projectedCorner1.y, projectedCorner2.y).toString(),\n width: scaledWidth.toString(),\n height: scaledHeight.toString(),\n fill: rect.fill || \"none\",\n stroke: rect.stroke || \"black\",\n \"stroke-width\": Math.abs(1 / matrix.a).toString(),\n },\n }\n }),\n // Circles\n ...(graphics.circles || []).map((circle) => {\n const projected = projectPoint(circle.center, matrix)\n const scaledRadius = circle.radius * Math.abs(matrix.a)\n return {\n name: \"circle\",\n type: \"element\",\n attributes: {\n \"data-type\": \"circle\",\n \"data-label\": \"\",\n \"data-x\": circle.center.x.toString(),\n \"data-y\": circle.center.y.toString(),\n cx: projected.x.toString(),\n cy: projected.y.toString(),\n r: scaledRadius.toString(),\n fill: circle.fill || \"none\",\n stroke: circle.stroke || \"black\",\n \"stroke-width\": Math.abs(1 / matrix.a).toString(),\n },\n }\n }),\n // Crosshair lines and coordinates (initially hidden)\n {\n name: \"g\",\n type: \"element\",\n attributes: {\n id: \"crosshair\",\n style: \"display: none\",\n },\n children: [\n {\n name: \"line\",\n type: \"element\",\n attributes: {\n id: \"crosshair-h\",\n y1: \"0\",\n y2: DEFAULT_SVG_SIZE.toString(),\n stroke: \"#666\",\n \"stroke-width\": \"0.5\",\n },\n },\n {\n name: \"line\",\n type: \"element\",\n attributes: {\n id: \"crosshair-v\",\n x1: \"0\",\n x2: DEFAULT_SVG_SIZE.toString(),\n stroke: \"#666\",\n \"stroke-width\": \"0.5\",\n },\n },\n {\n name: \"text\",\n type: \"element\",\n attributes: {\n id: \"coordinates\",\n \"font-family\": \"monospace\",\n \"font-size\": \"12\",\n fill: \"#666\",\n },\n children: [{ type: \"text\", value: \"\" }],\n },\n ],\n },\n // Mouse tracking script\n {\n name: \"script\",\n type: \"element\",\n children: [\n {\n type: \"text\",\n value: `\n document.currentScript.parentElement.addEventListener('mousemove', (e) => {\n const svg = e.currentTarget;\n const rect = svg.getBoundingClientRect();\n const x = e.clientX - rect.left;\n const y = e.clientY - rect.top;\n const crosshair = svg.getElementById('crosshair');\n const h = svg.getElementById('crosshair-h');\n const v = svg.getElementById('crosshair-v');\n const coords = svg.getElementById('coordinates');\n \n crosshair.style.display = 'block';\n h.setAttribute('x1', '0');\n h.setAttribute('x2', '${DEFAULT_SVG_SIZE}');\n h.setAttribute('y1', y);\n h.setAttribute('y2', y);\n v.setAttribute('x1', x);\n v.setAttribute('x2', x);\n v.setAttribute('y1', '0');\n v.setAttribute('y2', '${DEFAULT_SVG_SIZE}');\n\n // Calculate real coordinates using inverse transformation\n const matrix = ${JSON.stringify(matrix)};\n // Manually invert and apply the affine transform\n // Since we only use translate and scale, we can directly compute:\n // x' = (x - tx) / sx\n // y' = (y - ty) / sy\n const sx = matrix.a;\n const sy = matrix.d;\n const tx = matrix.e; \n const ty = matrix.f;\n const realPoint = {\n x: (x - tx) / sx,\n y: (y - ty) / sy // Flip y back since we used negative scale\n }\n \n coords.textContent = \\`(\\${realPoint.x.toFixed(2)}, \\${realPoint.y.toFixed(2)})\\`;\n coords.setAttribute('x', (x + 5).toString());\n coords.setAttribute('y', (y - 5).toString());\n });\n document.currentScript.parentElement.addEventListener('mouseleave', () => {\n document.currentScript.parentElement.getElementById('crosshair').style.display = 'none';\n });\n `,\n },\n ],\n },\n ],\n }\n\n // biome-ignore lint/suspicious/noExplicitAny: TODO\n return pretty(stringify(svgObject as any))\n}\n"],"mappings":"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","names":[]}
|
|
@@ -159,7 +159,12 @@ function drawGraphicsToCanvas(graphics, target, options = {}) {
|
|
|
159
159
|
ctx.lineTo(projected.x, projected.y);
|
|
160
160
|
}
|
|
161
161
|
ctx.strokeStyle = line.strokeColor || "black";
|
|
162
|
-
|
|
162
|
+
if (line.strokeWidth) {
|
|
163
|
+
ctx.lineWidth = line.strokeWidth * matrix.a;
|
|
164
|
+
} else {
|
|
165
|
+
ctx.lineWidth = 2;
|
|
166
|
+
}
|
|
167
|
+
ctx.lineCap = "round";
|
|
163
168
|
if (line.strokeDash) {
|
|
164
169
|
if (typeof line.strokeDash === "string") {
|
|
165
170
|
ctx.setLineDash(
|
|
@@ -196,4 +201,4 @@ export {
|
|
|
196
201
|
getBounds,
|
|
197
202
|
drawGraphicsToCanvas
|
|
198
203
|
};
|
|
199
|
-
//# sourceMappingURL=chunk-
|
|
204
|
+
//# sourceMappingURL=chunk-CZLSXU7Y.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../lib/drawGraphicsToCanvas.ts"],"sourcesContent":["import {\n compose,\n scale,\n translate,\n applyToPoint,\n type Matrix,\n} from \"transformation-matrix\"\nimport type {\n GraphicsObject,\n Viewbox,\n CenterViewbox,\n TransformOptions,\n} from \"./types\"\n\n/**\n * Computes a transformation matrix based on a provided viewbox\n * Handles both min/max style viewboxes and center/width/height style viewboxes\n */\nexport function computeTransformFromViewbox(\n viewbox: Viewbox | CenterViewbox,\n canvasWidth: number,\n canvasHeight: number,\n options: { padding?: number; yFlip?: boolean } = {},\n): Matrix {\n const padding = options.padding ?? 40\n const yFlip = options.yFlip ?? false\n\n // Convert CenterViewbox to Viewbox if needed\n let bounds: Viewbox\n if (\"center\" in viewbox) {\n const halfWidth = viewbox.width / 2\n const halfHeight = viewbox.height / 2\n bounds = {\n minX: viewbox.center.x - halfWidth,\n maxX: viewbox.center.x + halfWidth,\n minY: viewbox.center.y - halfHeight,\n maxY: viewbox.center.y + halfHeight,\n }\n } else {\n bounds = viewbox\n }\n\n const width = bounds.maxX - bounds.minX\n const height = bounds.maxY - bounds.minY\n\n const scale_factor = Math.min(\n (canvasWidth - 2 * padding) / width,\n (canvasHeight - 2 * padding) / height,\n )\n\n return compose(\n translate(canvasWidth / 2, canvasHeight / 2),\n scale(scale_factor, yFlip ? -scale_factor : scale_factor),\n translate(-(bounds.minX + width / 2), -(bounds.minY + height / 2)),\n )\n}\n\n/**\n * Computes bounds for a graphics object\n */\nexport function getBounds(graphics: GraphicsObject): Viewbox {\n const points = [\n ...(graphics.points || []),\n ...(graphics.lines || []).flatMap((line) => line.points),\n ...(graphics.rects || []).flatMap((rect) => {\n const halfWidth = rect.width / 2\n const halfHeight = rect.height / 2\n return [\n { x: rect.center.x - halfWidth, y: rect.center.y - halfHeight },\n { x: rect.center.x + halfWidth, y: rect.center.y - halfHeight },\n { x: rect.center.x - halfWidth, y: rect.center.y + halfHeight },\n { x: rect.center.x + halfWidth, y: rect.center.y + halfHeight },\n ]\n }),\n ...(graphics.circles || []).flatMap((circle) => [\n { x: circle.center.x - circle.radius, y: circle.center.y }, // left\n { x: circle.center.x + circle.radius, y: circle.center.y }, // right\n { x: circle.center.x, y: circle.center.y - circle.radius }, // top\n { x: circle.center.x, y: circle.center.y + circle.radius }, // bottom\n ]),\n ]\n\n if (points.length === 0) {\n return { minX: -1, maxX: 1, minY: -1, maxY: 1 }\n }\n\n return points.reduce(\n (bounds, point) => ({\n minX: Math.min(bounds.minX, point.x),\n maxX: Math.max(bounds.maxX, point.x),\n minY: Math.min(bounds.minY, point.y),\n maxY: Math.max(bounds.maxY, point.y),\n }),\n { minX: Infinity, maxX: -Infinity, minY: Infinity, maxY: -Infinity },\n )\n}\n\n/**\n * Draws a graphics object onto a canvas or context\n * @param graphics - The graphics object to draw\n * @param target - The canvas element or 2D context to draw on\n * @param options - Options for controlling the transform and rendering\n */\nexport function drawGraphicsToCanvas(\n graphics: GraphicsObject,\n target: HTMLCanvasElement | CanvasRenderingContext2D,\n options: TransformOptions = {},\n): void {\n // Get the context\n const ctx =\n target instanceof HTMLCanvasElement ? target.getContext(\"2d\") : target\n\n if (!ctx) {\n throw new Error(\"Could not get 2D context from canvas\")\n }\n\n // Get canvas dimensions\n const canvasWidth =\n target instanceof HTMLCanvasElement ? target.width : target.canvas.width\n\n const canvasHeight =\n target instanceof HTMLCanvasElement ? target.height : target.canvas.height\n\n // Get or compute the transform matrix\n let matrix: Matrix\n\n if (options.transform) {\n matrix = options.transform\n } else if (options.viewbox) {\n matrix = computeTransformFromViewbox(\n options.viewbox,\n canvasWidth,\n canvasHeight,\n {\n padding: options.padding,\n yFlip: options.yFlip,\n },\n )\n } else {\n // Auto-compute bounds and transform if not provided\n const bounds = getBounds(graphics)\n const yFlip = graphics.coordinateSystem === \"cartesian\"\n matrix = computeTransformFromViewbox(bounds, canvasWidth, canvasHeight, {\n padding: options.padding ?? 40,\n yFlip,\n })\n }\n\n // Clear the canvas\n ctx.clearRect(0, 0, canvasWidth, canvasHeight)\n\n // Save the current transform state\n ctx.save()\n\n // Draw the graphics elements\n // Draw rectangles\n if (graphics.rects && graphics.rects.length > 0) {\n graphics.rects.forEach((rect) => {\n const halfWidth = rect.width / 2\n const halfHeight = rect.height / 2\n\n const topLeft = applyToPoint(matrix, {\n x: rect.center.x - halfWidth,\n y: rect.center.y - halfHeight,\n })\n\n const bottomRight = applyToPoint(matrix, {\n x: rect.center.x + halfWidth,\n y: rect.center.y + halfHeight,\n })\n\n const width = Math.abs(bottomRight.x - topLeft.x)\n const height = Math.abs(bottomRight.y - topLeft.y)\n\n ctx.beginPath()\n ctx.rect(\n Math.min(topLeft.x, bottomRight.x),\n Math.min(topLeft.y, bottomRight.y),\n width,\n height,\n )\n\n if (rect.fill) {\n ctx.fillStyle = rect.fill\n ctx.fill()\n }\n\n if (rect.stroke) {\n ctx.strokeStyle = rect.stroke\n ctx.stroke()\n }\n })\n }\n\n // Draw circles\n if (graphics.circles && graphics.circles.length > 0) {\n graphics.circles.forEach((circle) => {\n const projected = applyToPoint(matrix, circle.center)\n const scaledRadius = circle.radius * Math.abs(matrix.a) // Use matrix scale factor\n\n ctx.beginPath()\n ctx.arc(projected.x, projected.y, scaledRadius, 0, 2 * Math.PI)\n\n if (circle.fill) {\n ctx.fillStyle = circle.fill\n ctx.fill()\n }\n\n if (circle.stroke) {\n ctx.strokeStyle = circle.stroke\n ctx.stroke()\n }\n })\n }\n\n // Draw lines\n if (graphics.lines && graphics.lines.length > 0) {\n graphics.lines.forEach((line) => {\n if (line.points.length === 0) return\n\n ctx.beginPath()\n\n const firstPoint = applyToPoint(matrix, line.points[0])\n ctx.moveTo(firstPoint.x, firstPoint.y)\n\n for (let i = 1; i < line.points.length; i++) {\n const projected = applyToPoint(matrix, line.points[i])\n ctx.lineTo(projected.x, projected.y)\n }\n\n ctx.strokeStyle = line.strokeColor || \"black\"\n ctx.lineWidth = line.strokeWidth || 1\n\n if (line.strokeDash) {\n if (typeof line.strokeDash === \"string\") {\n ctx.setLineDash(\n line.strokeDash\n .split(\",\")\n .map(Number)\n .map((n) => n * Math.abs(matrix.a)),\n )\n } else {\n ctx.setLineDash(line.strokeDash.map((n) => n * Math.abs(matrix.a)))\n }\n } else {\n ctx.setLineDash([])\n }\n\n ctx.stroke()\n })\n }\n\n // Draw points\n if (graphics.points && graphics.points.length > 0) {\n graphics.points.forEach((point) => {\n const projected = applyToPoint(matrix, point)\n\n // Draw point as a small circle\n ctx.beginPath()\n ctx.arc(projected.x, projected.y, 3, 0, 2 * Math.PI)\n ctx.fillStyle = point.color || \"black\"\n ctx.fill()\n\n // Draw label if present and labels aren't disabled\n if (point.label && !options.disableLabels) {\n ctx.fillStyle = point.color || \"black\"\n ctx.font = \"12px sans-serif\"\n ctx.fillText(point.label, projected.x + 5, projected.y - 5)\n }\n })\n }\n\n // Restore the original transform\n ctx.restore()\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../lib/drawGraphicsToCanvas.ts"],"sourcesContent":["import {\n compose,\n scale,\n translate,\n applyToPoint,\n type Matrix,\n} from \"transformation-matrix\"\nimport type {\n GraphicsObject,\n Viewbox,\n CenterViewbox,\n TransformOptions,\n} from \"./types\"\n\n/**\n * Computes a transformation matrix based on a provided viewbox\n * Handles both min/max style viewboxes and center/width/height style viewboxes\n */\nexport function computeTransformFromViewbox(\n viewbox: Viewbox | CenterViewbox,\n canvasWidth: number,\n canvasHeight: number,\n options: { padding?: number; yFlip?: boolean } = {},\n): Matrix {\n const padding = options.padding ?? 40\n const yFlip = options.yFlip ?? false\n\n // Convert CenterViewbox to Viewbox if needed\n let bounds: Viewbox\n if (\"center\" in viewbox) {\n const halfWidth = viewbox.width / 2\n const halfHeight = viewbox.height / 2\n bounds = {\n minX: viewbox.center.x - halfWidth,\n maxX: viewbox.center.x + halfWidth,\n minY: viewbox.center.y - halfHeight,\n maxY: viewbox.center.y + halfHeight,\n }\n } else {\n bounds = viewbox\n }\n\n const width = bounds.maxX - bounds.minX\n const height = bounds.maxY - bounds.minY\n\n const scale_factor = Math.min(\n (canvasWidth - 2 * padding) / width,\n (canvasHeight - 2 * padding) / height,\n )\n\n return compose(\n translate(canvasWidth / 2, canvasHeight / 2),\n scale(scale_factor, yFlip ? -scale_factor : scale_factor),\n translate(-(bounds.minX + width / 2), -(bounds.minY + height / 2)),\n )\n}\n\n/**\n * Computes bounds for a graphics object\n */\nexport function getBounds(graphics: GraphicsObject): Viewbox {\n const points = [\n ...(graphics.points || []),\n ...(graphics.lines || []).flatMap((line) => line.points),\n ...(graphics.rects || []).flatMap((rect) => {\n const halfWidth = rect.width / 2\n const halfHeight = rect.height / 2\n return [\n { x: rect.center.x - halfWidth, y: rect.center.y - halfHeight },\n { x: rect.center.x + halfWidth, y: rect.center.y - halfHeight },\n { x: rect.center.x - halfWidth, y: rect.center.y + halfHeight },\n { x: rect.center.x + halfWidth, y: rect.center.y + halfHeight },\n ]\n }),\n ...(graphics.circles || []).flatMap((circle) => [\n { x: circle.center.x - circle.radius, y: circle.center.y }, // left\n { x: circle.center.x + circle.radius, y: circle.center.y }, // right\n { x: circle.center.x, y: circle.center.y - circle.radius }, // top\n { x: circle.center.x, y: circle.center.y + circle.radius }, // bottom\n ]),\n ]\n\n if (points.length === 0) {\n return { minX: -1, maxX: 1, minY: -1, maxY: 1 }\n }\n\n return points.reduce(\n (bounds, point) => ({\n minX: Math.min(bounds.minX, point.x),\n maxX: Math.max(bounds.maxX, point.x),\n minY: Math.min(bounds.minY, point.y),\n maxY: Math.max(bounds.maxY, point.y),\n }),\n { minX: Infinity, maxX: -Infinity, minY: Infinity, maxY: -Infinity },\n )\n}\n\n/**\n * Draws a graphics object onto a canvas or context\n * @param graphics - The graphics object to draw\n * @param target - The canvas element or 2D context to draw on\n * @param options - Options for controlling the transform and rendering\n */\nexport function drawGraphicsToCanvas(\n graphics: GraphicsObject,\n target: HTMLCanvasElement | CanvasRenderingContext2D,\n options: TransformOptions = {},\n): void {\n // Get the context\n const ctx =\n target instanceof HTMLCanvasElement ? target.getContext(\"2d\") : target\n\n if (!ctx) {\n throw new Error(\"Could not get 2D context from canvas\")\n }\n\n // Get canvas dimensions\n const canvasWidth =\n target instanceof HTMLCanvasElement ? target.width : target.canvas.width\n\n const canvasHeight =\n target instanceof HTMLCanvasElement ? target.height : target.canvas.height\n\n // Get or compute the transform matrix\n let matrix: Matrix\n\n if (options.transform) {\n matrix = options.transform\n } else if (options.viewbox) {\n matrix = computeTransformFromViewbox(\n options.viewbox,\n canvasWidth,\n canvasHeight,\n {\n padding: options.padding,\n yFlip: options.yFlip,\n },\n )\n } else {\n // Auto-compute bounds and transform if not provided\n const bounds = getBounds(graphics)\n const yFlip = graphics.coordinateSystem === \"cartesian\"\n matrix = computeTransformFromViewbox(bounds, canvasWidth, canvasHeight, {\n padding: options.padding ?? 40,\n yFlip,\n })\n }\n\n // Clear the canvas\n ctx.clearRect(0, 0, canvasWidth, canvasHeight)\n\n // Save the current transform state\n ctx.save()\n\n // Draw the graphics elements\n // Draw rectangles\n if (graphics.rects && graphics.rects.length > 0) {\n graphics.rects.forEach((rect) => {\n const halfWidth = rect.width / 2\n const halfHeight = rect.height / 2\n\n const topLeft = applyToPoint(matrix, {\n x: rect.center.x - halfWidth,\n y: rect.center.y - halfHeight,\n })\n\n const bottomRight = applyToPoint(matrix, {\n x: rect.center.x + halfWidth,\n y: rect.center.y + halfHeight,\n })\n\n const width = Math.abs(bottomRight.x - topLeft.x)\n const height = Math.abs(bottomRight.y - topLeft.y)\n\n ctx.beginPath()\n ctx.rect(\n Math.min(topLeft.x, bottomRight.x),\n Math.min(topLeft.y, bottomRight.y),\n width,\n height,\n )\n\n if (rect.fill) {\n ctx.fillStyle = rect.fill\n ctx.fill()\n }\n\n if (rect.stroke) {\n ctx.strokeStyle = rect.stroke\n ctx.stroke()\n }\n })\n }\n\n // Draw circles\n if (graphics.circles && graphics.circles.length > 0) {\n graphics.circles.forEach((circle) => {\n const projected = applyToPoint(matrix, circle.center)\n const scaledRadius = circle.radius * Math.abs(matrix.a) // Use matrix scale factor\n\n ctx.beginPath()\n ctx.arc(projected.x, projected.y, scaledRadius, 0, 2 * Math.PI)\n\n if (circle.fill) {\n ctx.fillStyle = circle.fill\n ctx.fill()\n }\n\n if (circle.stroke) {\n ctx.strokeStyle = circle.stroke\n ctx.stroke()\n }\n })\n }\n\n // Draw lines\n if (graphics.lines && graphics.lines.length > 0) {\n graphics.lines.forEach((line) => {\n if (line.points.length === 0) return\n\n ctx.beginPath()\n\n const firstPoint = applyToPoint(matrix, line.points[0])\n ctx.moveTo(firstPoint.x, firstPoint.y)\n\n for (let i = 1; i < line.points.length; i++) {\n const projected = applyToPoint(matrix, line.points[i])\n ctx.lineTo(projected.x, projected.y)\n }\n\n ctx.strokeStyle = line.strokeColor || \"black\"\n if (line.strokeWidth) {\n ctx.lineWidth = line.strokeWidth * matrix.a\n } else {\n ctx.lineWidth = 2\n }\n ctx.lineCap = \"round\"\n\n if (line.strokeDash) {\n if (typeof line.strokeDash === \"string\") {\n ctx.setLineDash(\n line.strokeDash\n .split(\",\")\n .map(Number)\n .map((n) => n * Math.abs(matrix.a)),\n )\n } else {\n ctx.setLineDash(line.strokeDash.map((n) => n * Math.abs(matrix.a)))\n }\n } else {\n ctx.setLineDash([])\n }\n\n ctx.stroke()\n })\n }\n\n // Draw points\n if (graphics.points && graphics.points.length > 0) {\n graphics.points.forEach((point) => {\n const projected = applyToPoint(matrix, point)\n\n // Draw point as a small circle\n ctx.beginPath()\n ctx.arc(projected.x, projected.y, 3, 0, 2 * Math.PI)\n ctx.fillStyle = point.color || \"black\"\n ctx.fill()\n\n // Draw label if present and labels aren't disabled\n if (point.label && !options.disableLabels) {\n ctx.fillStyle = point.color || \"black\"\n ctx.font = \"12px sans-serif\"\n ctx.fillText(point.label, projected.x + 5, projected.y - 5)\n }\n })\n }\n\n // Restore the original transform\n ctx.restore()\n}\n"],"mappings":"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","names":[]}
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
} from "./chunk-NG6H63SM.js";
|
|
4
4
|
import {
|
|
5
5
|
getSvgFromGraphicsObject
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-A4VFIZRQ.js";
|
|
7
7
|
|
|
8
8
|
// lib/index.ts
|
|
9
9
|
function getSvgFromLogString(logString) {
|
|
@@ -53,4 +53,4 @@ export {
|
|
|
53
53
|
getHtmlFromLogString,
|
|
54
54
|
getSvgsFromLogString
|
|
55
55
|
};
|
|
56
|
-
//# sourceMappingURL=chunk-
|
|
56
|
+
//# sourceMappingURL=chunk-KXJRUEMA.js.map
|
package/dist/cli/cli.js
CHANGED
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
import {
|
|
3
3
|
getHtmlFromLogString,
|
|
4
4
|
getSvgsFromLogString
|
|
5
|
-
} from "../chunk-
|
|
6
|
-
import "../chunk-
|
|
5
|
+
} from "../chunk-KXJRUEMA.js";
|
|
6
|
+
import "../chunk-CZLSXU7Y.js";
|
|
7
7
|
import {
|
|
8
8
|
getGraphicsObjectsFromLogString
|
|
9
9
|
} from "../chunk-NG6H63SM.js";
|
|
10
|
-
import "../chunk-
|
|
10
|
+
import "../chunk-A4VFIZRQ.js";
|
|
11
11
|
|
|
12
12
|
// cli/cli.ts
|
|
13
13
|
import { parseArgs } from "node:util";
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { GraphicsObject } from './types.js';
|
|
2
2
|
import 'transformation-matrix';
|
|
3
3
|
|
|
4
|
-
declare function getSvgFromGraphicsObject(graphics: GraphicsObject
|
|
4
|
+
declare function getSvgFromGraphicsObject(graphics: GraphicsObject, { includeTextLabels, }?: {
|
|
5
|
+
includeTextLabels?: boolean;
|
|
6
|
+
}): string;
|
|
5
7
|
|
|
6
8
|
export { getSvgFromGraphicsObject };
|
package/dist/lib/index.js
CHANGED
|
@@ -2,18 +2,18 @@ import {
|
|
|
2
2
|
getHtmlFromLogString,
|
|
3
3
|
getSvgFromLogString,
|
|
4
4
|
getSvgsFromLogString
|
|
5
|
-
} from "../chunk-
|
|
5
|
+
} from "../chunk-KXJRUEMA.js";
|
|
6
6
|
import {
|
|
7
7
|
computeTransformFromViewbox,
|
|
8
8
|
drawGraphicsToCanvas,
|
|
9
9
|
getBounds
|
|
10
|
-
} from "../chunk-
|
|
10
|
+
} from "../chunk-CZLSXU7Y.js";
|
|
11
11
|
import {
|
|
12
12
|
getGraphicsObjectsFromLogString
|
|
13
13
|
} from "../chunk-NG6H63SM.js";
|
|
14
14
|
import {
|
|
15
15
|
getSvgFromGraphicsObject
|
|
16
|
-
} from "../chunk-
|
|
16
|
+
} from "../chunk-A4VFIZRQ.js";
|
|
17
17
|
export {
|
|
18
18
|
computeTransformFromViewbox,
|
|
19
19
|
drawGraphicsToCanvas,
|
package/dist/lib/matcher.js
CHANGED
package/dist/lib/react.d.ts
CHANGED
|
@@ -7,9 +7,10 @@ type GraphicsObjectClickEvent = {
|
|
|
7
7
|
index: number;
|
|
8
8
|
object: any;
|
|
9
9
|
};
|
|
10
|
-
declare const InteractiveGraphics: ({ graphics, onObjectClicked, }: {
|
|
10
|
+
declare const InteractiveGraphics: ({ graphics, onObjectClicked, objectLimit, }: {
|
|
11
11
|
graphics: GraphicsObject;
|
|
12
12
|
onObjectClicked?: (event: GraphicsObjectClickEvent) => void;
|
|
13
|
+
objectLimit?: number;
|
|
13
14
|
}) => react_jsx_runtime.JSX.Element;
|
|
14
15
|
|
|
15
16
|
interface InteractiveGraphicsCanvasProps {
|
package/dist/lib/react.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import "../chunk-
|
|
1
|
+
import "../chunk-KXJRUEMA.js";
|
|
2
2
|
import {
|
|
3
3
|
drawGraphicsToCanvas,
|
|
4
4
|
getBounds
|
|
5
|
-
} from "../chunk-
|
|
5
|
+
} from "../chunk-CZLSXU7Y.js";
|
|
6
6
|
import "../chunk-NG6H63SM.js";
|
|
7
|
-
import "../chunk-
|
|
7
|
+
import "../chunk-A4VFIZRQ.js";
|
|
8
8
|
|
|
9
9
|
// site/components/InteractiveGraphics/InteractiveGraphics.tsx
|
|
10
10
|
import { compose, scale, translate } from "transformation-matrix";
|
|
@@ -827,7 +827,8 @@ var DimensionOverlay = ({ children, transform }) => {
|
|
|
827
827
|
import { jsx as jsx7, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
828
828
|
var InteractiveGraphics = ({
|
|
829
829
|
graphics,
|
|
830
|
-
onObjectClicked
|
|
830
|
+
onObjectClicked,
|
|
831
|
+
objectLimit
|
|
831
832
|
}) => {
|
|
832
833
|
const [activeLayers, setActiveLayers] = useState6(null);
|
|
833
834
|
const [activeStep, setActiveStep] = useState6(null);
|
|
@@ -917,6 +918,29 @@ var InteractiveGraphics = ({
|
|
|
917
918
|
realToScreen,
|
|
918
919
|
size
|
|
919
920
|
);
|
|
921
|
+
const filterAndLimit = (objects, filterFn) => {
|
|
922
|
+
if (!objects) return [];
|
|
923
|
+
const filtered = objects.map((obj, index) => ({ ...obj, originalIndex: index })).filter(filterFn);
|
|
924
|
+
return objectLimit ? filtered.slice(-objectLimit) : filtered;
|
|
925
|
+
};
|
|
926
|
+
const filteredLines = useMemo7(
|
|
927
|
+
() => filterAndLimit(graphics.lines, filterLines),
|
|
928
|
+
[graphics.lines, filterLines, objectLimit]
|
|
929
|
+
);
|
|
930
|
+
const filteredRects = useMemo7(
|
|
931
|
+
() => filterAndLimit(graphics.rects, filterRects),
|
|
932
|
+
[graphics.rects, filterRects, objectLimit]
|
|
933
|
+
);
|
|
934
|
+
const filteredPoints = useMemo7(
|
|
935
|
+
() => filterAndLimit(graphics.points, filterPoints),
|
|
936
|
+
[graphics.points, filterPoints, objectLimit]
|
|
937
|
+
);
|
|
938
|
+
const filteredCircles = useMemo7(
|
|
939
|
+
() => filterAndLimit(graphics.circles, filterCircles),
|
|
940
|
+
[graphics.circles, filterCircles, objectLimit]
|
|
941
|
+
);
|
|
942
|
+
const totalFilteredObjects = filteredLines.length + filteredRects.length + filteredPoints.length + filteredCircles.length;
|
|
943
|
+
const isLimitReached = objectLimit && totalFilteredObjects > objectLimit;
|
|
920
944
|
return /* @__PURE__ */ jsxs3("div", { children: [
|
|
921
945
|
showToolbar && /* @__PURE__ */ jsxs3("div", { style: { margin: 8 }, children: [
|
|
922
946
|
availableLayers.length > 1 && /* @__PURE__ */ jsxs3(
|
|
@@ -967,6 +991,14 @@ var InteractiveGraphics = ({
|
|
|
967
991
|
}
|
|
968
992
|
),
|
|
969
993
|
"Filter by step"
|
|
994
|
+
] }),
|
|
995
|
+
isLimitReached && /* @__PURE__ */ jsxs3("span", { style: { color: "red", fontSize: "12px" }, children: [
|
|
996
|
+
"Display limited to ",
|
|
997
|
+
objectLimit,
|
|
998
|
+
" objects. Received:",
|
|
999
|
+
" ",
|
|
1000
|
+
totalFilteredObjects,
|
|
1001
|
+
"."
|
|
970
1002
|
] })
|
|
971
1003
|
]
|
|
972
1004
|
}
|
|
@@ -982,50 +1014,42 @@ var InteractiveGraphics = ({
|
|
|
982
1014
|
overflow: "hidden"
|
|
983
1015
|
},
|
|
984
1016
|
children: /* @__PURE__ */ jsxs3(DimensionOverlay, { transform: realToScreen, children: [
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
{
|
|
1022
|
-
circle: c,
|
|
1023
|
-
index: originalIndex,
|
|
1024
|
-
interactiveState
|
|
1025
|
-
},
|
|
1026
|
-
originalIndex
|
|
1027
|
-
) : null
|
|
1028
|
-
),
|
|
1017
|
+
filteredLines.map((line) => /* @__PURE__ */ jsx7(
|
|
1018
|
+
Line,
|
|
1019
|
+
{
|
|
1020
|
+
line,
|
|
1021
|
+
index: line.originalIndex,
|
|
1022
|
+
interactiveState
|
|
1023
|
+
},
|
|
1024
|
+
line.originalIndex
|
|
1025
|
+
)),
|
|
1026
|
+
filteredRects.map((rect) => /* @__PURE__ */ jsx7(
|
|
1027
|
+
Rect,
|
|
1028
|
+
{
|
|
1029
|
+
rect,
|
|
1030
|
+
index: rect.originalIndex,
|
|
1031
|
+
interactiveState
|
|
1032
|
+
},
|
|
1033
|
+
rect.originalIndex
|
|
1034
|
+
)),
|
|
1035
|
+
filteredPoints.map((point) => /* @__PURE__ */ jsx7(
|
|
1036
|
+
Point,
|
|
1037
|
+
{
|
|
1038
|
+
point,
|
|
1039
|
+
index: point.originalIndex,
|
|
1040
|
+
interactiveState
|
|
1041
|
+
},
|
|
1042
|
+
point.originalIndex
|
|
1043
|
+
)),
|
|
1044
|
+
filteredCircles.map((circle) => /* @__PURE__ */ jsx7(
|
|
1045
|
+
Circle,
|
|
1046
|
+
{
|
|
1047
|
+
circle,
|
|
1048
|
+
index: circle.originalIndex,
|
|
1049
|
+
interactiveState
|
|
1050
|
+
},
|
|
1051
|
+
circle.originalIndex
|
|
1052
|
+
)),
|
|
1029
1053
|
/* @__PURE__ */ jsx7(
|
|
1030
1054
|
SuperGrid,
|
|
1031
1055
|
{
|
package/dist/lib/react.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../site/components/InteractiveGraphics/InteractiveGraphics.tsx","../../site/components/InteractiveGraphics/Line.tsx","../../site/components/InteractiveGraphics/Tooltip.tsx","../../site/utils/distToLineSegment.ts","../../site/components/InteractiveGraphics/defaultColors.ts","../../site/utils/safeLighten.ts","../../site/components/InteractiveGraphics/Point.tsx","../../site/components/InteractiveGraphics/Rect.tsx","../../site/components/InteractiveGraphics/Circle.tsx","../../site/utils/getGraphicsBounds.ts","../../site/components/InteractiveGraphics/hooks/useIsPointOnScreen.ts","../../site/components/InteractiveGraphics/hooks/useDoesLineIntersectViewport.ts","../../site/components/InteractiveGraphics/hooks/useFilterLines.ts","../../site/components/InteractiveGraphics/hooks/useFilterPoints.ts","../../site/components/InteractiveGraphics/hooks/useFilterRects.ts","../../site/components/InteractiveGraphics/hooks/useFilterCircles.ts","../../site/components/DimensionOverlay.tsx","../../site/components/InteractiveGraphicsCanvas.tsx","../../site/components/CanvasGraphics/CanvasGraphics.tsx"],"sourcesContent":["import { compose, scale, translate } from \"transformation-matrix\"\nimport { GraphicsObject } from \"../../../lib\"\nimport { useMemo, useState } from \"react\"\nimport useMouseMatrixTransform from \"use-mouse-matrix-transform\"\nimport { InteractiveState } from \"./InteractiveState\"\nimport { SuperGrid } from \"react-supergrid\"\nimport useResizeObserver from \"@react-hook/resize-observer\"\nimport { Line } from \"./Line\"\nimport { Point } from \"./Point\"\nimport { Rect } from \"./Rect\"\nimport { Circle } from \"./Circle\"\nimport { getGraphicsBounds } from \"site/utils/getGraphicsBounds\"\nimport {\n useIsPointOnScreen,\n useDoesLineIntersectViewport,\n useFilterLines,\n useFilterPoints,\n useFilterRects,\n useFilterCircles,\n} from \"./hooks\"\nimport { DimensionOverlay } from \"../DimensionOverlay\"\n\nexport type GraphicsObjectClickEvent = {\n type: \"point\" | \"line\" | \"rect\" | \"circle\"\n index: number\n object: any\n}\n\nexport const InteractiveGraphics = ({\n graphics,\n onObjectClicked,\n}: {\n graphics: GraphicsObject\n onObjectClicked?: (event: GraphicsObjectClickEvent) => void\n}) => {\n const [activeLayers, setActiveLayers] = useState<string[] | null>(null)\n const [activeStep, setActiveStep] = useState<number | null>(null)\n const [size, setSize] = useState({ width: 600, height: 600 })\n const availableLayers: string[] = Array.from(\n new Set([\n ...(graphics.lines?.map((l) => l.layer!).filter(Boolean) ?? []),\n ...(graphics.rects?.map((r) => r.layer!).filter(Boolean) ?? []),\n ...(graphics.points?.map((p) => p.layer!).filter(Boolean) ?? []),\n ]),\n )\n const maxStep = Math.max(\n 0,\n ...(graphics.lines?.map((l) => l.step!).filter(Boolean) ?? []),\n ...(graphics.rects?.map((r) => r.step!).filter(Boolean) ?? []),\n ...(graphics.points?.map((p) => p.step!).filter(Boolean) ?? []),\n )\n\n const graphicsBoundsWithPadding = useMemo(() => {\n const actualBounds = getGraphicsBounds(graphics)\n const width = actualBounds.maxX - actualBounds.minX\n const height = actualBounds.maxY - actualBounds.minY\n return {\n minX: actualBounds.minX - width / 10,\n minY: actualBounds.minY - height / 10,\n maxX: actualBounds.maxX + width / 10,\n maxY: actualBounds.maxY + height / 10,\n }\n }, [graphics])\n\n const { transform: realToScreen, ref } = useMouseMatrixTransform({\n initialTransform: compose(\n translate(size.width / 2, size.height / 2),\n scale(\n Math.min(\n size.width /\n (graphicsBoundsWithPadding.maxX - graphicsBoundsWithPadding.minX),\n size.height /\n (graphicsBoundsWithPadding.maxY - graphicsBoundsWithPadding.minY),\n ),\n -Math.min(\n size.width /\n (graphicsBoundsWithPadding.maxX - graphicsBoundsWithPadding.minX),\n size.height /\n (graphicsBoundsWithPadding.maxY - graphicsBoundsWithPadding.minY),\n ),\n ),\n translate(\n -(graphicsBoundsWithPadding.maxX + graphicsBoundsWithPadding.minX) / 2,\n -(graphicsBoundsWithPadding.maxY + graphicsBoundsWithPadding.minY) / 2,\n ),\n ),\n })\n\n useResizeObserver(ref, (entry: ResizeObserverEntry) => {\n setSize({\n width: entry.contentRect.width,\n height: entry.contentRect.height,\n })\n })\n\n const interactiveState: InteractiveState = {\n activeLayers: activeLayers,\n activeStep: activeStep,\n realToScreen: realToScreen,\n onObjectClicked: onObjectClicked,\n }\n\n const showToolbar = availableLayers.length > 1 || maxStep > 0\n\n // Use custom hooks for visibility checks and filtering\n const isPointOnScreen = useIsPointOnScreen(realToScreen, size)\n\n const doesLineIntersectViewport = useDoesLineIntersectViewport(\n realToScreen,\n size,\n )\n\n // Filter by layer and step\n const filterLayerAndStep = (obj: { layer?: string; step?: number }) => {\n if (activeLayers && obj.layer && !activeLayers.includes(obj.layer))\n return false\n if (\n activeStep !== null &&\n obj.step !== undefined &&\n obj.step !== activeStep\n )\n return false\n return true\n }\n\n const filterLines = useFilterLines(\n isPointOnScreen,\n doesLineIntersectViewport,\n filterLayerAndStep,\n )\n\n const filterPoints = useFilterPoints(isPointOnScreen, filterLayerAndStep)\n\n const filterRects = useFilterRects(\n isPointOnScreen,\n doesLineIntersectViewport,\n filterLayerAndStep,\n )\n\n const filterCircles = useFilterCircles(\n isPointOnScreen,\n filterLayerAndStep,\n realToScreen,\n size,\n )\n\n return (\n <div>\n {showToolbar && (\n <div style={{ margin: 8 }}>\n {availableLayers.length > 1 && (\n <select\n value={activeLayers ? activeLayers[0] : \"\"}\n onChange={(e) => {\n const value = e.target.value\n setActiveLayers(value === \"\" ? null : [value])\n }}\n style={{ marginRight: 8 }}\n >\n <option value=\"\">All Layers</option>\n {availableLayers.map((layer) => (\n <option key={layer} value={layer}>\n {layer}\n </option>\n ))}\n </select>\n )}\n\n {maxStep > 0 && (\n <div\n style={{ display: \"inline-flex\", alignItems: \"center\", gap: 8 }}\n >\n Step:\n <input\n type=\"number\"\n min={0}\n max={maxStep}\n value={activeStep ?? 0}\n onChange={(e) => {\n const value = parseInt(e.target.value)\n setActiveStep(Number.isNaN(value) ? null : value)\n }}\n disabled={activeStep === null}\n />\n <label>\n <input\n type=\"checkbox\"\n style={{ marginRight: 4 }}\n checked={activeStep !== null}\n onChange={(e) => {\n setActiveStep(e.target.checked ? 0 : null)\n }}\n />\n Filter by step\n </label>\n </div>\n )}\n </div>\n )}\n\n <div\n ref={ref}\n style={{\n position: \"relative\",\n height: 600,\n overflow: \"hidden\",\n }}\n >\n <DimensionOverlay transform={realToScreen}>\n {graphics.lines?.map((l, originalIndex) =>\n filterLines(l) ? (\n <Line\n key={originalIndex}\n line={l}\n index={originalIndex}\n interactiveState={interactiveState}\n />\n ) : null,\n )}\n {graphics.rects?.map((r, originalIndex) =>\n filterRects(r) ? (\n <Rect\n key={originalIndex}\n rect={r}\n index={originalIndex}\n interactiveState={interactiveState}\n />\n ) : null,\n )}\n {graphics.points?.map((p, originalIndex) =>\n filterPoints(p) ? (\n <Point\n key={originalIndex}\n point={p}\n index={originalIndex}\n interactiveState={interactiveState}\n />\n ) : null,\n )}\n {graphics.circles?.map((c, originalIndex) =>\n filterCircles(c) ? (\n <Circle\n key={originalIndex}\n circle={c}\n index={originalIndex}\n interactiveState={interactiveState}\n />\n ) : null,\n )}\n <SuperGrid\n stringifyCoord={(x, y) => `${x.toFixed(2)}, ${y.toFixed(2)}`}\n width={size.width}\n height={size.height}\n transform={realToScreen}\n />\n </DimensionOverlay>\n </div>\n </div>\n )\n}\n","import type * as Types from \"lib/types\"\nimport { applyToPoint } from \"transformation-matrix\"\nimport type { InteractiveState } from \"./InteractiveState\"\nimport { lighten } from \"polished\"\nimport { useState } from \"react\"\nimport { Tooltip } from \"./Tooltip\"\nimport { distToLineSegment } from \"site/utils/distToLineSegment\"\nimport { defaultColors } from \"./defaultColors\"\nimport { safeLighten } from \"site/utils/safeLighten\"\n\nexport const Line = ({\n line,\n index,\n interactiveState,\n}: { line: Types.Line; index: number; interactiveState: InteractiveState }) => {\n const { activeLayers, activeStep, realToScreen, onObjectClicked } =\n interactiveState\n const {\n points,\n layer,\n step,\n strokeColor,\n strokeWidth = 1 / realToScreen.a,\n strokeDash,\n } = line\n const [isHovered, setIsHovered] = useState(false)\n const [mousePos, setMousePos] = useState({ x: 0, y: 0 })\n\n const screenPoints = points.map((p) => applyToPoint(realToScreen, p))\n\n const handleMouseMove = (e: React.MouseEvent) => {\n const rect = e.currentTarget.getBoundingClientRect()\n const mouseX = e.clientX - rect.left\n const mouseY = e.clientY - rect.top\n const hoverThreshold = 10 // pixels\n\n setMousePos({ x: mouseX, y: mouseY })\n\n // Check distance to each line segment\n let isNearLine = false\n for (let i = 0; i < screenPoints.length - 1; i++) {\n const dist = distToLineSegment(\n mouseX,\n mouseY,\n screenPoints[i].x,\n screenPoints[i].y,\n screenPoints[i + 1].x,\n screenPoints[i + 1].y,\n )\n if (dist < hoverThreshold) {\n isNearLine = true\n break\n }\n }\n\n setIsHovered(isNearLine)\n }\n\n const baseColor = strokeColor ?? defaultColors[index % defaultColors.length]\n\n return (\n <svg\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n width: \"100%\",\n height: \"100%\",\n }}\n onMouseMove={handleMouseMove}\n onMouseLeave={() => setIsHovered(false)}\n onClick={\n isHovered\n ? () =>\n onObjectClicked?.({\n type: \"line\",\n index,\n object: line,\n })\n : undefined\n }\n >\n <polyline\n points={screenPoints.map((p) => `${p.x},${p.y}`).join(\" \")}\n stroke={isHovered ? safeLighten(0.2, baseColor) : baseColor}\n fill=\"none\"\n strokeWidth={strokeWidth * realToScreen.a}\n strokeDasharray={\n !strokeDash\n ? undefined\n : typeof strokeDash === \"string\"\n ? strokeDash\n : `${strokeDash[0] * realToScreen.a}, ${strokeDash[1] * realToScreen.a}`\n }\n strokeLinecap=\"round\"\n />\n {isHovered && line.label && (\n <foreignObject\n x={mousePos.x}\n y={mousePos.y - 40}\n width={300}\n height={40}\n >\n <Tooltip text={line.label} />\n </foreignObject>\n )}\n </svg>\n )\n}\n","export const Tooltip = ({ text }: { text: string }) => {\n return (\n <div\n style={{\n background: \"white\",\n border: \"1px solid #ccc\",\n boxShadow: \"0 0 10px 0 rgba(0, 0, 0, 0.1)\",\n borderRadius: \"4px\",\n padding: \"4px 8px\",\n fontSize: \"12px\",\n minWidth: \"150px\",\n maxWidth: \"300px\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"pre-wrap\",\n zIndex: 100,\n }}\n >\n {text}\n </div>\n )\n}\n","// Calculate distance from point to line segment\nexport const distToLineSegment = (\n px: number,\n py: number,\n x1: number,\n y1: number,\n x2: number,\n y2: number,\n) => {\n const A = px - x1\n const B = py - y1\n const C = x2 - x1\n const D = y2 - y1\n\n const dot = A * C + B * D\n const lenSq = C * C + D * D\n let param = -1\n\n if (lenSq !== 0) param = dot / lenSq\n\n let xx = 0\n let yy = 0\n\n if (param < 0) {\n xx = x1\n yy = y1\n } else if (param > 1) {\n xx = x2\n yy = y2\n } else {\n xx = x1 + param * C\n yy = y1 + param * D\n }\n\n const dx = px - xx\n const dy = py - yy\n return Math.sqrt(dx * dx + dy * dy)\n}\n","// These are default colors if no color is provided\n// colors are made based on the index of the item in the array\n\nexport const defaultColors = [\n \"rgba(239, 68, 68, 0.8)\", // red-300\n \"rgba(249, 115, 22, 0.8)\", // orange-300\n \"rgba(245, 158, 11, 0.8)\", // amber-300\n \"rgba(234, 179, 8, 0.8)\", // yellow-300\n \"rgba(132, 204, 22, 0.8)\", // lime-300\n \"rgba(34, 197, 94, 0.8)\", // green-300\n \"rgba(16, 185, 129, 0.8)\", // emerald-300\n \"rgba(20, 184, 166, 0.8)\", // teal-300\n \"rgba(6, 182, 212, 0.8)\", // cyan-300\n \"rgba(14, 165, 233, 0.8)\", // sky-300\n \"rgba(59, 130, 246, 0.8)\", // blue-300\n \"rgba(99, 102, 241, 0.8)\", // indigo-300\n \"rgba(139, 92, 246, 0.8)\", // violet-300\n \"rgba(168, 85, 247, 0.8)\", // purple-300\n \"rgba(217, 70, 239, 0.8)\", // fuchsia-300\n \"rgba(236, 72, 153, 0.8)\", // pink-300\n \"rgba(249, 168, 212, 0.8)\", // rose-300\n \"rgba(161, 161, 170, 0.8)\", // zinc-300\n]\n","import { lighten } from \"polished\"\n\nexport const safeLighten = (amount: number, color: string) => {\n try {\n return lighten(amount, color)\n } catch (e) {\n return color\n }\n}\n","import type * as Types from \"lib/types\"\nimport { applyToPoint } from \"transformation-matrix\"\nimport type { InteractiveState } from \"./InteractiveState\"\nimport { useState } from \"react\"\nimport { Tooltip } from \"./Tooltip\"\nimport { defaultColors } from \"./defaultColors\"\nimport { safeLighten } from \"site/utils/safeLighten\"\n\nexport const Point = ({\n point,\n interactiveState,\n index,\n}: {\n point: Types.Point\n interactiveState: InteractiveState\n index: number\n}) => {\n const { color, label, layer, step } = point\n const { activeLayers, activeStep, realToScreen, onObjectClicked } =\n interactiveState\n const [isHovered, setIsHovered] = useState(false)\n\n const screenPoint = applyToPoint(realToScreen, point)\n const size = 10\n\n return (\n <div\n style={{\n position: \"absolute\",\n left: screenPoint.x - size / 2,\n top: screenPoint.y - size / 2,\n width: size,\n height: size,\n borderRadius: \"50%\",\n border: `2px solid ${\n isHovered\n ? safeLighten(\n 0.2,\n color ?? defaultColors[index % defaultColors.length],\n )\n : (color ?? defaultColors[index % defaultColors.length])\n }`,\n cursor: \"pointer\",\n transition: \"border-color 0.2s\",\n }}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n onClick={() =>\n onObjectClicked?.({\n type: \"point\",\n index,\n object: point,\n })\n }\n >\n {isHovered && (\n <div\n style={{\n position: \"absolute\",\n bottom: \"100%\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n marginBottom: 8,\n }}\n >\n <Tooltip\n text={`${label ? `${label}\\n` : \"\"}x: ${point.x.toFixed(2)}, y: ${point.y.toFixed(2)}`}\n />\n </div>\n )}\n </div>\n )\n}\n","import type * as Types from \"lib/types\"\nimport { applyToPoint } from \"transformation-matrix\"\nimport type { InteractiveState } from \"./InteractiveState\"\nimport { lighten } from \"polished\"\nimport { useState } from \"react\"\nimport { Tooltip } from \"./Tooltip\"\nimport { defaultColors } from \"./defaultColors\"\nimport { safeLighten } from \"site/utils/safeLighten\"\n\nexport const Rect = ({\n rect,\n interactiveState,\n index,\n}: {\n rect: Types.Rect\n interactiveState: InteractiveState\n index: number\n}) => {\n const defaultColor = defaultColors[index % defaultColors.length]\n let { center, width, height, fill, stroke, layer, step } = rect\n const { activeLayers, activeStep, realToScreen, onObjectClicked } =\n interactiveState\n const [isHovered, setIsHovered] = useState(false)\n\n const screenCenter = applyToPoint(realToScreen, center)\n const screenWidth = width * realToScreen.a\n const screenHeight = height * Math.abs(realToScreen.d)\n\n // Default style when neither fill nor stroke is specified\n const hasStrokeOrFill = fill !== undefined || stroke !== undefined\n\n let backgroundColor = hasStrokeOrFill ? fill || \"transparent\" : defaultColor\n if (isHovered) {\n backgroundColor = safeLighten(0.2, backgroundColor)\n stroke = safeLighten(0.2, stroke!)\n }\n\n return (\n <div\n style={{\n position: \"absolute\",\n left: screenCenter.x - screenWidth / 2,\n top: screenCenter.y - screenHeight / 2,\n width: screenWidth,\n height: screenHeight,\n backgroundColor,\n border: stroke\n ? `2px solid ${isHovered ? safeLighten(0.2, stroke) : stroke}`\n : \"none\",\n cursor: \"pointer\",\n transition: \"border-color 0.2s\",\n }}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n onClick={() =>\n onObjectClicked?.({\n type: \"rect\",\n index,\n object: rect,\n })\n }\n >\n {isHovered && rect.label && (\n <div\n style={{\n position: \"absolute\",\n bottom: \"100%\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n marginBottom: 8,\n }}\n >\n <Tooltip text={rect.label} />\n </div>\n )}\n </div>\n )\n}\n","import type * as Types from \"lib/types\"\nimport { applyToPoint } from \"transformation-matrix\"\nimport type { InteractiveState } from \"./InteractiveState\"\nimport { useState } from \"react\"\nimport { Tooltip } from \"./Tooltip\"\nimport { defaultColors } from \"./defaultColors\"\nimport { safeLighten } from \"site/utils/safeLighten\"\n\nexport const Circle = ({\n circle,\n interactiveState,\n index,\n}: {\n circle: Types.Circle\n interactiveState: InteractiveState\n index: number\n}) => {\n const defaultColor = defaultColors[index % defaultColors.length]\n let { center, radius, fill, stroke, layer, step, label } = circle\n const { activeLayers, activeStep, realToScreen, onObjectClicked } =\n interactiveState\n const [isHovered, setIsHovered] = useState(false)\n const screenCenter = applyToPoint(realToScreen, center)\n const screenRadius = radius * realToScreen.a\n let backgroundColor = fill || defaultColor\n if (isHovered) {\n backgroundColor = safeLighten(0.2, backgroundColor)\n stroke = stroke ? safeLighten(0.2, stroke) : stroke\n }\n return (\n <div\n style={{\n position: \"absolute\",\n left: screenCenter.x - screenRadius,\n top: screenCenter.y - screenRadius,\n width: screenRadius * 2,\n height: screenRadius * 2,\n borderRadius: \"50%\",\n backgroundColor,\n border: stroke ? `2px solid ${stroke}` : \"none\",\n cursor: \"pointer\",\n transition: \"border-color 0.2s\",\n }}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n onClick={() =>\n onObjectClicked?.({\n type: \"circle\",\n index,\n object: circle,\n })\n }\n >\n {isHovered && label && (\n <div\n style={{\n position: \"absolute\",\n bottom: \"100%\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n marginBottom: 8,\n }}\n >\n <Tooltip text={label} />\n </div>\n )}\n </div>\n )\n}\n","import { GraphicsObject } from \"lib/types\"\n\nexport const getGraphicsBounds = (graphics: GraphicsObject) => {\n const bounds = {\n minX: Infinity,\n minY: Infinity,\n maxX: -Infinity,\n maxY: -Infinity,\n }\n for (const line of graphics.lines ?? []) {\n for (const point of line.points ?? []) {\n bounds.minX = Math.min(bounds.minX, point.x)\n bounds.minY = Math.min(bounds.minY, point.y)\n bounds.maxX = Math.max(bounds.maxX, point.x)\n bounds.maxY = Math.max(bounds.maxY, point.y)\n }\n }\n for (const rect of graphics.rects ?? []) {\n const { center, width, height } = rect\n const halfWidth = width / 2\n const halfHeight = height / 2\n bounds.minX = Math.min(bounds.minX, center.x - halfWidth)\n bounds.minY = Math.min(bounds.minY, center.y - halfHeight)\n bounds.maxX = Math.max(bounds.maxX, center.x + halfWidth)\n bounds.maxY = Math.max(bounds.maxY, center.y + halfHeight)\n }\n for (const point of graphics.points ?? []) {\n bounds.minX = Math.min(bounds.minX, point.x)\n bounds.minY = Math.min(bounds.minY, point.y)\n bounds.maxX = Math.max(bounds.maxX, point.x)\n bounds.maxY = Math.max(bounds.maxY, point.y)\n }\n return bounds\n}\n","import { applyToPoint, type Matrix } from \"transformation-matrix\"\nimport { useMemo } from \"react\"\nimport { OFFSCREEN_MARGIN } from \"./useDoesLineIntersectViewport\"\n\nexport const useIsPointOnScreen = (\n realToScreen: Matrix,\n size: { width: number; height: number },\n) => {\n return useMemo(() => {\n return (point: { x: number; y: number }) => {\n const screenPoint = applyToPoint(realToScreen, point)\n return (\n screenPoint.x >= -OFFSCREEN_MARGIN &&\n screenPoint.x <= size.width + OFFSCREEN_MARGIN &&\n screenPoint.y >= -OFFSCREEN_MARGIN &&\n screenPoint.y <= size.height + OFFSCREEN_MARGIN\n )\n }\n }, [realToScreen, size])\n}\n","import { applyToPoint, type Matrix } from \"transformation-matrix\"\nimport { useMemo } from \"react\"\n\n// Margin in pixels for determining if elements are off-screen\nexport const OFFSCREEN_MARGIN = 5\n\nexport const useDoesLineIntersectViewport = (\n realToScreen: Matrix,\n size: { width: number; height: number },\n) => {\n return useMemo(() => {\n return (p1: { x: number; y: number }, p2: { x: number; y: number }) => {\n // Convert real-world points to screen coordinates\n const sp1 = applyToPoint(realToScreen, p1)\n const sp2 = applyToPoint(realToScreen, p2)\n\n // Viewport boundaries with margin\n const left = -OFFSCREEN_MARGIN\n const right = size.width + OFFSCREEN_MARGIN\n const top = -OFFSCREEN_MARGIN\n const bottom = size.height + OFFSCREEN_MARGIN\n\n // If either point is inside the viewport, the line intersects\n if (\n (sp1.x >= left && sp1.x <= right && sp1.y >= top && sp1.y <= bottom) ||\n (sp2.x >= left && sp2.x <= right && sp2.y >= top && sp2.y <= bottom)\n ) {\n return true\n }\n\n // Helper function to check if a line intersects with a line segment\n const intersects = (\n a1: { x: number; y: number },\n a2: { x: number; y: number },\n b1: { x: number; y: number },\n b2: { x: number; y: number },\n ) => {\n // Line segment A is (a1, a2), line segment B is (b1, b2)\n const det =\n (a2.x - a1.x) * (b2.y - b1.y) - (a2.y - a1.y) * (b2.x - b1.x)\n\n // If lines are parallel or coincident, they don't intersect in a unique point\n if (det === 0) return false\n\n const lambda =\n ((b2.y - b1.y) * (b2.x - a1.x) + (b1.x - b2.x) * (b2.y - a1.y)) / det\n const gamma =\n ((a1.y - a2.y) * (b2.x - a1.x) + (a2.x - a1.x) * (b2.y - a1.y)) / det\n\n // Check if the intersection point is within both line segments\n return lambda >= 0 && lambda <= 1 && gamma >= 0 && gamma <= 1\n }\n\n // Check intersection with each edge of the viewport\n return (\n // Top edge\n intersects(sp1, sp2, { x: left, y: top }, { x: right, y: top }) ||\n // Right edge\n intersects(sp1, sp2, { x: right, y: top }, { x: right, y: bottom }) ||\n // Bottom edge\n intersects(sp1, sp2, { x: left, y: bottom }, { x: right, y: bottom }) ||\n // Left edge\n intersects(sp1, sp2, { x: left, y: top }, { x: left, y: bottom })\n )\n }\n }, [realToScreen, size])\n}\n","import { useMemo } from \"react\"\n\ntype Line = {\n points: Array<{ x: number; y: number }>\n layer?: string\n step?: number\n closed?: boolean\n}\n\nexport const useFilterLines = (\n isPointOnScreen: (point: { x: number; y: number }) => boolean,\n doesLineIntersectViewport: (\n p1: { x: number; y: number },\n p2: { x: number; y: number },\n ) => boolean,\n filterLayerAndStep: (obj: { layer?: string; step?: number }) => boolean,\n) => {\n return useMemo(() => {\n return (line: Line) => {\n // First apply layer and step filters\n if (!filterLayerAndStep(line)) return false\n\n // Then check if any point of the line is visible\n if (line.points.some((p) => isPointOnScreen(p))) {\n return true\n }\n\n // If no points are visible, check if any line segment intersects the viewport\n for (let i = 0; i < line.points.length - 1; i++) {\n if (doesLineIntersectViewport(line.points[i], line.points[i + 1])) {\n return true\n }\n }\n\n // If it's a closed shape (polyline), check the last segment too\n if (line.points.length > 2 && line.closed) {\n if (\n doesLineIntersectViewport(\n line.points[line.points.length - 1],\n line.points[0],\n )\n ) {\n return true\n }\n }\n\n return false\n }\n }, [isPointOnScreen, doesLineIntersectViewport, filterLayerAndStep])\n}\n","import { useMemo } from \"react\"\n\ntype Point = {\n x: number\n y: number\n layer?: string\n step?: number\n}\n\nexport const useFilterPoints = (\n isPointOnScreen: (point: { x: number; y: number }) => boolean,\n filterLayerAndStep: (obj: { layer?: string; step?: number }) => boolean,\n) => {\n return useMemo(() => {\n return (point: Point) => {\n // First apply layer and step filters\n if (!filterLayerAndStep(point)) return false\n\n // Then check if the point is visible\n return isPointOnScreen(point)\n }\n }, [isPointOnScreen, filterLayerAndStep])\n}\n","import { useMemo } from \"react\"\n\ntype Rect = {\n center: { x: number; y: number }\n width: number\n height: number\n layer?: string\n step?: number\n}\n\nexport const useFilterRects = (\n isPointOnScreen: (point: { x: number; y: number }) => boolean,\n doesLineIntersectViewport: (\n p1: { x: number; y: number },\n p2: { x: number; y: number },\n ) => boolean,\n filterLayerAndStep: (obj: { layer?: string; step?: number }) => boolean,\n) => {\n return useMemo(() => {\n return (rect: Rect) => {\n // First apply layer and step filters\n if (!filterLayerAndStep(rect)) return false\n\n // For rectangles, check if any corner or the center is visible\n const { center, width, height } = rect\n const halfWidth = width / 2\n const halfHeight = height / 2\n\n const topLeft = { x: center.x - halfWidth, y: center.y - halfHeight }\n const topRight = { x: center.x + halfWidth, y: center.y - halfHeight }\n const bottomLeft = { x: center.x - halfWidth, y: center.y + halfHeight }\n const bottomRight = { x: center.x + halfWidth, y: center.y + halfHeight }\n\n // Check if any corner or center is visible\n if (\n isPointOnScreen(center) ||\n isPointOnScreen(topLeft) ||\n isPointOnScreen(topRight) ||\n isPointOnScreen(bottomLeft) ||\n isPointOnScreen(bottomRight)\n ) {\n return true\n }\n\n // Check if any edge of the rectangle intersects the viewport\n return (\n doesLineIntersectViewport(topLeft, topRight) ||\n doesLineIntersectViewport(topRight, bottomRight) ||\n doesLineIntersectViewport(bottomRight, bottomLeft) ||\n doesLineIntersectViewport(bottomLeft, topLeft)\n )\n }\n }, [isPointOnScreen, doesLineIntersectViewport, filterLayerAndStep])\n}\n","import { applyToPoint, type Matrix } from \"transformation-matrix\"\nimport { useMemo } from \"react\"\nimport { OFFSCREEN_MARGIN } from \"./useDoesLineIntersectViewport\"\n\ntype Circle = {\n center: { x: number; y: number }\n radius: number\n layer?: string\n step?: number\n}\n\nexport const useFilterCircles = (\n isPointOnScreen: (point: { x: number; y: number }) => boolean,\n filterLayerAndStep: (obj: { layer?: string; step?: number }) => boolean,\n realToScreen: Matrix,\n size: { width: number; height: number },\n) => {\n return useMemo(() => {\n return (circle: Circle) => {\n // First apply layer and step filters\n if (!filterLayerAndStep(circle)) return false\n\n // For circles, check if center is visible or if any cardinal point is visible\n const { center, radius } = circle\n\n // Check if center or cardinal points on the circle are visible\n if (\n isPointOnScreen(center) ||\n isPointOnScreen({ x: center.x + radius, y: center.y }) ||\n isPointOnScreen({ x: center.x - radius, y: center.y }) ||\n isPointOnScreen({ x: center.x, y: center.y + radius }) ||\n isPointOnScreen({ x: center.x, y: center.y - radius })\n ) {\n return true\n }\n\n // Check if the circle intersects the viewport\n // Convert to screen coordinates for viewport intersection test\n const screenCenter = applyToPoint(realToScreen, center)\n const scale = Math.abs(realToScreen.a) // Get the scale factor\n const screenRadius = radius * scale\n\n // Viewport boundaries\n const left = -OFFSCREEN_MARGIN\n const right = size.width + OFFSCREEN_MARGIN\n const top = -OFFSCREEN_MARGIN\n const bottom = size.height + OFFSCREEN_MARGIN\n\n // Check if the circle intersects with the viewport\n // Case 1: Circle center is inside the viewport horizontally but outside vertically\n if (screenCenter.x >= left && screenCenter.x <= right) {\n if (\n Math.abs(screenCenter.y - top) <= screenRadius ||\n Math.abs(screenCenter.y - bottom) <= screenRadius\n ) {\n return true\n }\n }\n\n // Case 2: Circle center is inside the viewport vertically but outside horizontally\n if (screenCenter.y >= top && screenCenter.y <= bottom) {\n if (\n Math.abs(screenCenter.x - left) <= screenRadius ||\n Math.abs(screenCenter.x - right) <= screenRadius\n ) {\n return true\n }\n }\n\n // Case 3: Circle center is outside the viewport, check corners\n const cornerDistanceSquared = (cornerX: number, cornerY: number) => {\n const dx = screenCenter.x - cornerX\n const dy = screenCenter.y - cornerY\n return dx * dx + dy * dy\n }\n\n const radiusSquared = screenRadius * screenRadius\n\n return (\n cornerDistanceSquared(left, top) <= radiusSquared ||\n cornerDistanceSquared(right, top) <= radiusSquared ||\n cornerDistanceSquared(left, bottom) <= radiusSquared ||\n cornerDistanceSquared(right, bottom) <= radiusSquared\n )\n }\n }, [isPointOnScreen, filterLayerAndStep, realToScreen, size])\n}\n","import React, { useEffect, useRef, useState } from \"react\"\nimport { applyToPoint, identity, inverse } from \"transformation-matrix\"\nimport type { Matrix } from \"transformation-matrix\"\n\ninterface Props {\n transform?: Matrix\n children: React.ReactNode\n}\n\nexport const DimensionOverlay: React.FC<Props> = ({ children, transform }) => {\n if (!transform) transform = identity()\n const [dimensionToolVisible, setDimensionToolVisible] = useState(false)\n const [dimensionToolStretching, setDimensionToolStretching] = useState(false)\n // Start of dimension tool line in real-world coordinates (not screen)\n const [dStart, setDStart] = useState({ x: 0, y: 0 })\n // End of dimension tool line in real-world coordinates (not screen)\n const [dEnd, setDEnd] = useState({ x: 0, y: 0 })\n const mousePosRef = useRef({ x: 0, y: 0 })\n const containerRef = useRef<HTMLDivElement | null>(null)\n const container = containerRef.current!\n const containerBounds = container?.getBoundingClientRect()\n\n const bindKeys = () => {\n const container = containerRef.current\n\n const down = (e: KeyboardEvent) => {\n if (e.key === \"d\") {\n setDStart({ x: mousePosRef.current.x, y: mousePosRef.current.y })\n setDEnd({ x: mousePosRef.current.x, y: mousePosRef.current.y })\n setDimensionToolVisible((visible: boolean) => !visible)\n setDimensionToolStretching(true)\n }\n if (e.key === \"Escape\") {\n setDimensionToolVisible(false)\n setDimensionToolStretching(false)\n }\n }\n\n const addKeyListener = () => {\n if (container) {\n window.addEventListener(\"keydown\", down)\n }\n }\n\n const removeKeyListener = () => {\n if (container) {\n window.removeEventListener(\"keydown\", down)\n }\n }\n\n if (container) {\n container.addEventListener(\"focus\", addKeyListener)\n container.addEventListener(\"blur\", removeKeyListener)\n container.addEventListener(\"mouseenter\", addKeyListener)\n container.addEventListener(\"mouseleave\", removeKeyListener)\n }\n return () => {\n if (container) {\n container.removeEventListener(\"focus\", addKeyListener)\n container.removeEventListener(\"blur\", removeKeyListener)\n container.removeEventListener(\"mouseenter\", addKeyListener)\n container.removeEventListener(\"mouseleave\", removeKeyListener)\n }\n }\n }\n\n useEffect(bindKeys, [containerBounds?.width, containerBounds?.height])\n\n const screenDStart = applyToPoint(transform, dStart)\n const screenDEnd = applyToPoint(transform, dEnd)\n\n const arrowScreenBounds = {\n left: Math.min(screenDStart.x, screenDEnd.x),\n right: Math.max(screenDStart.x, screenDEnd.x),\n top: Math.min(screenDStart.y, screenDEnd.y),\n bottom: Math.max(screenDStart.y, screenDEnd.y),\n flipX: screenDStart.x > screenDEnd.x,\n flipY: screenDStart.y > screenDEnd.y,\n width: 0,\n height: 0,\n }\n arrowScreenBounds.width = arrowScreenBounds.right - arrowScreenBounds.left\n arrowScreenBounds.height = arrowScreenBounds.bottom - arrowScreenBounds.top\n\n return (\n <div\n ref={containerRef}\n tabIndex={0}\n style={{ position: \"relative\" }}\n onMouseMove={(e: React.MouseEvent<HTMLDivElement>) => {\n const rect = e.currentTarget.getBoundingClientRect()\n const x = e.clientX - rect.left\n const y = e.clientY - rect.top\n const rwPoint = applyToPoint(inverse(transform!), { x, y })\n mousePosRef.current.x = rwPoint.x\n mousePosRef.current.y = rwPoint.y\n\n if (dimensionToolStretching) {\n setDEnd({ x: rwPoint.x, y: rwPoint.y })\n }\n }}\n onMouseDown={() => {\n if (dimensionToolStretching) {\n setDimensionToolStretching(false)\n } else if (dimensionToolVisible) {\n setDimensionToolVisible(false)\n }\n }}\n onMouseEnter={() => {\n if (containerRef.current) {\n bindKeys()\n }\n }}\n >\n {children}\n {dimensionToolVisible && (\n <>\n <div\n style={{\n position: \"absolute\",\n left: arrowScreenBounds.left,\n width: arrowScreenBounds.width,\n textAlign: \"center\",\n top: screenDStart.y + 2,\n color: \"red\",\n mixBlendMode: \"difference\",\n pointerEvents: \"none\",\n marginTop: arrowScreenBounds.flipY ? 0 : -20,\n fontSize: 12,\n fontFamily: \"sans-serif\",\n zIndex: 30,\n }}\n >\n {Math.abs(dStart.x - dEnd.x).toFixed(2)}\n </div>\n <div\n style={{\n position: \"absolute\",\n left: screenDEnd.x,\n height: arrowScreenBounds.height,\n display: \"flex\",\n flexDirection: \"column\",\n justifyContent: \"center\",\n top: arrowScreenBounds.top,\n color: \"red\",\n pointerEvents: \"none\",\n mixBlendMode: \"difference\",\n fontSize: 12,\n fontFamily: \"sans-serif\",\n zIndex: 30,\n }}\n >\n <div\n style={{\n marginLeft: arrowScreenBounds.flipX ? \"-100%\" : 4,\n paddingRight: 4,\n }}\n >\n {Math.abs(dStart.y - dEnd.y).toFixed(2)}\n </div>\n </div>\n <svg\n style={{\n position: \"absolute\",\n left: 0,\n top: 0,\n pointerEvents: \"none\",\n mixBlendMode: \"difference\",\n zIndex: 30,\n }}\n width={containerBounds?.width || \"100%\"}\n height={containerBounds?.height || \"100%\"}\n >\n <defs>\n <marker\n id=\"head\"\n orient=\"auto\"\n markerWidth=\"3\"\n markerHeight=\"4\"\n refX=\"2\"\n refY=\"2\"\n >\n <path d=\"M0,0 V4 L2,2 Z\" fill=\"red\" />\n </marker>\n </defs>\n <line\n x1={screenDStart.x}\n y1={screenDStart.y}\n x2={screenDEnd.x}\n y2={screenDEnd.y}\n markerEnd=\"url(#head)\"\n strokeWidth={1.5}\n fill=\"none\"\n stroke=\"red\"\n />\n <line\n x1={screenDStart.x}\n y1={screenDStart.y}\n x2={screenDEnd.x}\n y2={screenDStart.y}\n strokeWidth={1.5}\n fill=\"none\"\n strokeDasharray={\"2,2\"}\n stroke=\"red\"\n />\n <line\n x1={screenDEnd.x}\n y1={screenDStart.y}\n x2={screenDEnd.x}\n y2={screenDEnd.y}\n strokeWidth={1.5}\n fill=\"none\"\n strokeDasharray={\"2,2\"}\n stroke=\"red\"\n />\n </svg>\n <div\n style={{\n right: 0,\n bottom: 0,\n position: \"absolute\",\n color: \"red\",\n fontFamily: \"sans-serif\",\n fontSize: 12,\n margin: 4,\n }}\n >\n ({dStart.x.toFixed(2)},{dStart.y.toFixed(2)})<br />(\n {dEnd.x.toFixed(2)},{dEnd.y.toFixed(2)})<br />\n dist:{\" \"}\n {Math.sqrt(\n (dEnd.x - dStart.x) ** 2 + (dEnd.y - dStart.y) ** 2,\n ).toFixed(2)}\n </div>\n </>\n )}\n </div>\n )\n}\n","import React, { useRef, useEffect, useState, useMemo } from \"react\"\nimport { drawGraphicsToCanvas, getBounds, type GraphicsObject } from \"../../lib\"\nimport useMouseMatrixTransform from \"use-mouse-matrix-transform\"\nimport { compose, scale, translate } from \"transformation-matrix\"\nimport useResizeObserver from \"@react-hook/resize-observer\"\nimport { DimensionOverlay } from \"./DimensionOverlay\"\n\ninterface InteractiveGraphicsCanvasProps {\n graphics: GraphicsObject\n showLabelsByDefault?: boolean\n showGrid?: boolean\n height?: number | string\n width?: number | string\n}\n\nexport function InteractiveGraphicsCanvas({\n graphics,\n showLabelsByDefault = true,\n showGrid = true,\n height = 500,\n width = \"100%\",\n}: InteractiveGraphicsCanvasProps) {\n const canvasRef = useRef<HTMLCanvasElement>(null)\n const containerRef = useRef<HTMLDivElement | null>(null)\n const [size, setSize] = useState({ width: 600, height: 600 })\n const [activeStep, setActiveStep] = useState<number | null>(null)\n const [showLabels, setShowLabels] = useState(showLabelsByDefault)\n const [showLastStep, setShowLastStep] = useState(true)\n\n // Calculate the maximum step value from all graphics objects\n const maxStep = useMemo(() => {\n return Math.max(\n 0,\n ...(graphics.points?.map((p) => p.step ?? 0) ?? []),\n ...(graphics.lines?.map((l) => l.step ?? 0) ?? []),\n ...(graphics.rects?.map((r) => r.step ?? 0) ?? []),\n ...(graphics.circles?.map((c) => c.step ?? 0) ?? []),\n )\n }, [graphics])\n\n // Filter graphics objects based on step\n const filteredGraphics = useMemo(() => {\n if (activeStep === null) {\n return graphics\n }\n\n // If showLastStep is enabled and we're filtering by step, show everything up to and including the current step\n const maxStep = Math.max(\n ...(graphics.points?.map((p) => p.step ?? 0) ?? []),\n ...(graphics.lines?.map((l) => l.step ?? 0) ?? []),\n ...(graphics.rects?.map((r) => r.step ?? 0) ?? []),\n ...(graphics.circles?.map((c) => c.step ?? 0) ?? []),\n )\n const filterByStep = showLastStep\n ? (objStep?: number) => objStep === undefined || objStep === maxStep\n : activeStep\n ? (objStep?: number) => objStep === undefined || objStep === activeStep\n : () => true\n\n return {\n ...graphics,\n points: graphics.points?.filter((p) => filterByStep(p.step)),\n lines: graphics.lines?.filter((l) => filterByStep(l.step)),\n rects: graphics.rects?.filter((r) => filterByStep(r.step)),\n circles: graphics.circles?.filter((c) => filterByStep(c.step)),\n }\n }, [graphics, activeStep, showLastStep])\n\n // Get bounds of the graphics with padding\n const graphicsBoundsWithPadding = useMemo(() => {\n const bounds = getBounds(graphics)\n const width = bounds.maxX - bounds.minX\n const height = bounds.maxY - bounds.minY\n return {\n minX: bounds.minX - width / 10,\n minY: bounds.minY - height / 10,\n maxX: bounds.maxX + width / 10,\n maxY: bounds.maxY + height / 10,\n }\n }, [graphics])\n\n // Use mouse transform hook for panning/zooming\n const { transform, ref: mouseTransformRef } = useMouseMatrixTransform({\n initialTransform: compose(\n translate(size.width / 2, size.height / 2),\n scale(\n Math.min(\n size.width /\n (graphicsBoundsWithPadding.maxX - graphicsBoundsWithPadding.minX),\n size.height /\n (graphicsBoundsWithPadding.maxY - graphicsBoundsWithPadding.minY),\n ),\n -Math.min(\n size.width /\n (graphicsBoundsWithPadding.maxX - graphicsBoundsWithPadding.minX),\n size.height /\n (graphicsBoundsWithPadding.maxY - graphicsBoundsWithPadding.minY),\n ),\n ),\n translate(\n -(graphicsBoundsWithPadding.maxX + graphicsBoundsWithPadding.minX) / 2,\n -(graphicsBoundsWithPadding.maxY + graphicsBoundsWithPadding.minY) / 2,\n ),\n ),\n })\n\n // Monitor container size\n useResizeObserver(containerRef, (entry) => {\n setSize({\n width: entry.contentRect.width,\n height: entry.contentRect.height,\n })\n })\n\n // Draw function that uses our canvas renderer\n const drawCanvas = () => {\n if (!canvasRef.current) return\n\n // Make sure canvas dimensions match container\n canvasRef.current.width = size.width\n canvasRef.current.height = size.height\n\n // Draw the graphics with the current transform\n drawGraphicsToCanvas(filteredGraphics, canvasRef.current, {\n transform: transform,\n disableLabels: !showLabels,\n })\n\n // Draw a grid for reference if requested\n if (showGrid) {\n drawGrid(canvasRef.current, transform)\n }\n }\n\n // Draw a grid to help with visualization\n const drawGrid = (canvas: HTMLCanvasElement, transform: any) => {\n const ctx = canvas.getContext(\"2d\")\n if (!ctx) return\n\n ctx.save()\n\n // Draw coordinate axes\n ctx.beginPath()\n\n // X-axis\n const xAxisStart = { x: -1000, y: 0 }\n const xAxisEnd = { x: 1000, y: 0 }\n const xAxisStartTransformed = transformPoint(xAxisStart, transform)\n const xAxisEndTransformed = transformPoint(xAxisEnd, transform)\n\n ctx.moveTo(xAxisStartTransformed.x, xAxisStartTransformed.y)\n ctx.lineTo(xAxisEndTransformed.x, xAxisEndTransformed.y)\n\n // Y-axis\n const yAxisStart = { x: 0, y: -1000 }\n const yAxisEnd = { x: 0, y: 1000 }\n const yAxisStartTransformed = transformPoint(yAxisStart, transform)\n const yAxisEndTransformed = transformPoint(yAxisEnd, transform)\n\n ctx.moveTo(yAxisStartTransformed.x, yAxisStartTransformed.y)\n ctx.lineTo(yAxisEndTransformed.x, yAxisEndTransformed.y)\n\n ctx.strokeStyle = \"#aaa\"\n ctx.lineWidth = 1\n ctx.stroke()\n\n // Draw grid lines\n ctx.beginPath()\n ctx.setLineDash([2, 2])\n\n // Determine grid spacing based on zoom level\n const gridSize = 10\n\n // Draw vertical grid lines\n for (let x = -100; x <= 100; x += gridSize) {\n if (x === 0) continue // Skip the axis\n\n const start = transformPoint({ x, y: -100 }, transform)\n const end = transformPoint({ x, y: 100 }, transform)\n\n ctx.moveTo(start.x, start.y)\n ctx.lineTo(end.x, end.y)\n }\n\n // Draw horizontal grid lines\n for (let y = -100; y <= 100; y += gridSize) {\n if (y === 0) continue // Skip the axis\n\n const start = transformPoint({ x: -100, y }, transform)\n const end = transformPoint({ x: 100, y }, transform)\n\n ctx.moveTo(start.x, start.y)\n ctx.lineTo(end.x, end.y)\n }\n\n ctx.strokeStyle = \"#ddd\"\n ctx.stroke()\n ctx.restore()\n }\n\n // Helper to transform a point through the matrix\n const transformPoint = (point: { x: number; y: number }, matrix: any) => {\n return {\n x: matrix.a * point.x + matrix.c * point.y + matrix.e,\n y: matrix.b * point.x + matrix.d * point.y + matrix.f,\n }\n }\n\n // Apply the drawing when transform changes\n useEffect(() => {\n drawCanvas()\n }, [transform, size, filteredGraphics, showGrid, showLabels])\n\n return (\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: \"10px\" }}>\n {maxStep > 0 && (\n <div style={{ display: \"flex\", gap: \"12px\", alignItems: \"center\" }}>\n <div style={{ display: \"flex\", alignItems: \"center\", gap: \"8px\" }}>\n <label>\n <input\n type=\"checkbox\"\n style={{ marginRight: 4 }}\n checked={activeStep !== null}\n onChange={(e) => {\n setActiveStep(e.target.checked ? 0 : null)\n }}\n />\n Filter by step\n </label>\n\n <input\n type=\"number\"\n min={0}\n max={maxStep}\n value={activeStep ?? 0}\n onChange={(e) => {\n const value = parseInt(e.target.value)\n setShowLastStep(false)\n setActiveStep(\n Number.isNaN(value) ? 0 : Math.min(value, maxStep),\n )\n }}\n disabled={activeStep === null}\n style={{ width: \"60px\" }}\n />\n\n <label>\n <input\n type=\"checkbox\"\n style={{ marginRight: 4 }}\n checked={showLastStep}\n onChange={(e) => {\n setShowLastStep(e.target.checked)\n setActiveStep(null)\n }}\n />\n Show last step\n </label>\n </div>\n\n <div style={{ display: \"flex\", alignItems: \"center\", gap: \"8px\" }}>\n <label>\n <input\n type=\"checkbox\"\n style={{ marginRight: 4 }}\n checked={showLabels}\n onChange={(e) => {\n setShowLabels(e.target.checked)\n }}\n />\n Show labels\n </label>\n </div>\n </div>\n )}\n\n <div\n ref={(node) => {\n // Using a callback ref approach\n containerRef.current = node\n // Apply the mouse transform ref if available\n if (mouseTransformRef && node) {\n mouseTransformRef.current = node\n }\n }}\n style={{\n position: \"relative\",\n width: width,\n height: height,\n border: \"1px solid #ccc\",\n overflow: \"hidden\",\n }}\n >\n <canvas\n ref={canvasRef}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n width,\n height,\n }}\n />\n </div>\n </div>\n )\n}\n\nexport default InteractiveGraphicsCanvas\n","import React, { useRef, useEffect, useState } from \"react\"\nimport { GraphicsObject } from \"../../../lib/types\"\nimport {\n drawGraphicsToCanvas,\n getBounds,\n} from \"../../../lib/drawGraphicsToCanvas\"\nimport useMouseMatrixTransform from \"use-mouse-matrix-transform\"\nimport { compose, scale, translate, type Matrix } from \"transformation-matrix\"\nimport useResizeObserver from \"@react-hook/resize-observer\"\nimport { DimensionOverlay } from \"../DimensionOverlay\"\n\ninterface CanvasGraphicsProps {\n graphics: GraphicsObject\n width?: number\n height?: number\n withGrid?: boolean\n initialTransform?: Matrix\n disableLabels?: boolean\n}\n\n// Create a container component that handles the mouse matrix transform\nfunction TransformContainer({\n initialTransform,\n children,\n onTransformChange,\n}: {\n initialTransform: Matrix\n children: React.ReactNode\n onTransformChange: (transform: Matrix) => void\n}) {\n const { transform, ref } = useMouseMatrixTransform({\n initialTransform,\n })\n\n // Update parent with transform changes\n useEffect(() => {\n onTransformChange(transform)\n }, [transform, onTransformChange])\n\n return (\n <div\n ref={ref}\n style={{\n position: \"relative\",\n width: \"100%\",\n height: \"100%\",\n }}\n >\n {children}\n </div>\n )\n}\n\nexport const CanvasGraphics = ({\n graphics,\n width = 600,\n height = 600,\n withGrid = true,\n disableLabels = false,\n initialTransform,\n}: CanvasGraphicsProps) => {\n const canvasRef = useRef<HTMLCanvasElement>(null)\n const containerRef = useRef<HTMLDivElement>(null)\n const [size, setSize] = useState({ width, height })\n const [currentTransform, setCurrentTransform] = useState<Matrix | null>(null)\n\n // Get bounds of the graphics with padding\n const graphicsBoundsWithPadding = React.useMemo(() => {\n const bounds = getBounds(graphics)\n const bWidth = bounds.maxX - bounds.minX\n const bHeight = bounds.maxY - bounds.minY\n return {\n minX: bounds.minX - bWidth / 10,\n minY: bounds.minY - bHeight / 10,\n maxX: bounds.maxX + bWidth / 10,\n maxY: bounds.maxY + bHeight / 10,\n }\n }, [graphics])\n\n // Compute initial transform if not provided\n const computedInitialTransform = React.useMemo(() => {\n if (initialTransform) return initialTransform\n\n const yFlip = graphics.coordinateSystem === \"cartesian\"\n return compose(\n translate(size.width / 2, size.height / 2),\n scale(\n Math.min(\n size.width /\n (graphicsBoundsWithPadding.maxX - graphicsBoundsWithPadding.minX),\n size.height /\n (graphicsBoundsWithPadding.maxY - graphicsBoundsWithPadding.minY),\n ),\n yFlip\n ? -Math.min(\n size.width /\n (graphicsBoundsWithPadding.maxX -\n graphicsBoundsWithPadding.minX),\n size.height /\n (graphicsBoundsWithPadding.maxY -\n graphicsBoundsWithPadding.minY),\n )\n : Math.min(\n size.width /\n (graphicsBoundsWithPadding.maxX -\n graphicsBoundsWithPadding.minX),\n size.height /\n (graphicsBoundsWithPadding.maxY -\n graphicsBoundsWithPadding.minY),\n ),\n ),\n translate(\n -(graphicsBoundsWithPadding.maxX + graphicsBoundsWithPadding.minX) / 2,\n -(graphicsBoundsWithPadding.maxY + graphicsBoundsWithPadding.minY) / 2,\n ),\n )\n }, [graphics, graphicsBoundsWithPadding, initialTransform, size])\n\n // Track transform changes from the mouse transform hook\n const handleTransformChange = React.useCallback((transform: Matrix) => {\n setCurrentTransform(transform)\n }, [])\n\n // Monitor container size\n useResizeObserver(containerRef, (entry) => {\n setSize({\n width: entry.contentRect.width,\n height: entry.contentRect.height,\n })\n })\n\n // Draw function that uses our canvas renderer\n const drawCanvas = React.useCallback(() => {\n if (!canvasRef.current || !currentTransform) return\n\n // Make sure canvas dimensions match container\n canvasRef.current.width = size.width\n canvasRef.current.height = size.height\n\n // Draw the graphics with the current transform\n drawGraphicsToCanvas(graphics, canvasRef.current, {\n transform: currentTransform,\n disableLabels,\n })\n\n // Draw a grid for reference if enabled\n if (withGrid) {\n drawGrid(canvasRef.current, currentTransform)\n }\n }, [canvasRef, currentTransform, graphics, size, withGrid])\n\n // Draw a grid to help with visualization\n const drawGrid = (canvas: HTMLCanvasElement, transform: Matrix) => {\n const ctx = canvas.getContext(\"2d\")\n if (!ctx) return\n\n ctx.save()\n\n // Draw coordinate axes\n ctx.beginPath()\n\n // X-axis\n const xAxisStart = { x: -1000, y: 0 }\n const xAxisEnd = { x: 1000, y: 0 }\n const xAxisStartTransformed = transformPoint(xAxisStart, transform)\n const xAxisEndTransformed = transformPoint(xAxisEnd, transform)\n\n ctx.moveTo(xAxisStartTransformed.x, xAxisStartTransformed.y)\n ctx.lineTo(xAxisEndTransformed.x, xAxisEndTransformed.y)\n\n // Y-axis\n const yAxisStart = { x: 0, y: -1000 }\n const yAxisEnd = { x: 0, y: 1000 }\n const yAxisStartTransformed = transformPoint(yAxisStart, transform)\n const yAxisEndTransformed = transformPoint(yAxisEnd, transform)\n\n ctx.moveTo(yAxisStartTransformed.x, yAxisStartTransformed.y)\n ctx.lineTo(yAxisEndTransformed.x, yAxisEndTransformed.y)\n\n ctx.strokeStyle = \"#aaa\"\n ctx.lineWidth = 1\n ctx.stroke()\n\n // Draw grid lines\n ctx.beginPath()\n ctx.setLineDash([2, 2])\n\n // Calculate a good grid size based on zoom level\n // This is an approximate calculation\n const zoomLevel = Math.abs(transform.a) // Scale factor\n const gridSize = Math.pow(10, Math.floor(Math.log10(100 / zoomLevel)))\n\n const gridRange = Math.ceil(1000 / gridSize) * gridSize\n\n // Draw vertical grid lines\n for (let x = -gridRange; x <= gridRange; x += gridSize) {\n if (x === 0) continue // Skip the axis\n\n const start = transformPoint({ x, y: -gridRange }, transform)\n const end = transformPoint({ x, y: gridRange }, transform)\n\n ctx.moveTo(start.x, start.y)\n ctx.lineTo(end.x, end.y)\n }\n\n // Draw horizontal grid lines\n for (let y = -gridRange; y <= gridRange; y += gridSize) {\n if (y === 0) continue // Skip the axis\n\n const start = transformPoint({ x: -gridRange, y }, transform)\n const end = transformPoint({ x: gridRange, y }, transform)\n\n ctx.moveTo(start.x, start.y)\n ctx.lineTo(end.x, end.y)\n }\n\n ctx.strokeStyle = \"#ddd\"\n ctx.stroke()\n ctx.restore()\n }\n\n // Helper to transform a point through the matrix\n const transformPoint = (point: { x: number; y: number }, matrix: Matrix) => {\n return {\n x: matrix.a * point.x + matrix.c * point.y + matrix.e,\n y: matrix.b * point.x + matrix.d * point.y + matrix.f,\n }\n }\n\n // Apply the drawing when transform changes\n useEffect(() => {\n drawCanvas()\n }, [drawCanvas])\n\n // Initialize transform\n useEffect(() => {\n setCurrentTransform(computedInitialTransform)\n }, [computedInitialTransform])\n\n return (\n <div\n ref={containerRef}\n style={{\n position: \"relative\",\n width: \"100%\",\n height: `${height}px`,\n border: \"1px solid #eee\",\n overflow: \"hidden\",\n }}\n >\n <TransformContainer\n initialTransform={computedInitialTransform}\n onTransformChange={handleTransformChange}\n >\n <DimensionOverlay\n transform={currentTransform || computedInitialTransform}\n >\n <canvas\n ref={canvasRef}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n width: \"100%\",\n height: \"100%\",\n }}\n />\n </DimensionOverlay>\n </TransformContainer>\n </div>\n )\n}\n"],"mappings":"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","names":["useMemo","useState","jsx","applyToPoint","useState","jsx","useState","applyToPoint","applyToPoint","useState","jsx","useState","applyToPoint","applyToPoint","useState","jsx","useState","applyToPoint","applyToPoint","useMemo","applyToPoint","useMemo","applyToPoint","useMemo","useMemo","useMemo","applyToPoint","useMemo","useMemo","applyToPoint","scale","useState","applyToPoint","jsx","jsxs","container","jsx","jsxs","useState","useMemo","useRef","useEffect","useState","useMemo","useMouseMatrixTransform","compose","scale","translate","useResizeObserver","jsx","jsxs","useRef","useState","useMemo","maxStep","width","height","transform","useEffect","React","useRef","useEffect","useState","useMouseMatrixTransform","compose","scale","translate","useResizeObserver","jsx","useMouseMatrixTransform","useEffect","useRef","useState","React","compose","translate","scale","useResizeObserver"]}
|
|
1
|
+
{"version":3,"sources":["../../site/components/InteractiveGraphics/InteractiveGraphics.tsx","../../site/components/InteractiveGraphics/Line.tsx","../../site/components/InteractiveGraphics/Tooltip.tsx","../../site/utils/distToLineSegment.ts","../../site/components/InteractiveGraphics/defaultColors.ts","../../site/utils/safeLighten.ts","../../site/components/InteractiveGraphics/Point.tsx","../../site/components/InteractiveGraphics/Rect.tsx","../../site/components/InteractiveGraphics/Circle.tsx","../../site/utils/getGraphicsBounds.ts","../../site/components/InteractiveGraphics/hooks/useIsPointOnScreen.ts","../../site/components/InteractiveGraphics/hooks/useDoesLineIntersectViewport.ts","../../site/components/InteractiveGraphics/hooks/useFilterLines.ts","../../site/components/InteractiveGraphics/hooks/useFilterPoints.ts","../../site/components/InteractiveGraphics/hooks/useFilterRects.ts","../../site/components/InteractiveGraphics/hooks/useFilterCircles.ts","../../site/components/DimensionOverlay.tsx","../../site/components/InteractiveGraphicsCanvas.tsx","../../site/components/CanvasGraphics/CanvasGraphics.tsx"],"sourcesContent":["import { compose, scale, translate } from \"transformation-matrix\"\nimport { GraphicsObject } from \"../../../lib\"\nimport { useMemo, useState } from \"react\"\nimport useMouseMatrixTransform from \"use-mouse-matrix-transform\"\nimport { InteractiveState } from \"./InteractiveState\"\nimport { SuperGrid } from \"react-supergrid\"\nimport useResizeObserver from \"@react-hook/resize-observer\"\nimport { Line } from \"./Line\"\nimport { Point } from \"./Point\"\nimport { Rect } from \"./Rect\"\nimport { Circle } from \"./Circle\"\nimport { getGraphicsBounds } from \"site/utils/getGraphicsBounds\"\nimport {\n useIsPointOnScreen,\n useDoesLineIntersectViewport,\n useFilterLines,\n useFilterPoints,\n useFilterRects,\n useFilterCircles,\n} from \"./hooks\"\nimport { DimensionOverlay } from \"../DimensionOverlay\"\n\nexport type GraphicsObjectClickEvent = {\n type: \"point\" | \"line\" | \"rect\" | \"circle\"\n index: number\n object: any\n}\n\nexport const InteractiveGraphics = ({\n graphics,\n onObjectClicked,\n objectLimit,\n}: {\n graphics: GraphicsObject\n onObjectClicked?: (event: GraphicsObjectClickEvent) => void\n objectLimit?: number\n}) => {\n const [activeLayers, setActiveLayers] = useState<string[] | null>(null)\n const [activeStep, setActiveStep] = useState<number | null>(null)\n const [size, setSize] = useState({ width: 600, height: 600 })\n const availableLayers: string[] = Array.from(\n new Set([\n ...(graphics.lines?.map((l) => l.layer!).filter(Boolean) ?? []),\n ...(graphics.rects?.map((r) => r.layer!).filter(Boolean) ?? []),\n ...(graphics.points?.map((p) => p.layer!).filter(Boolean) ?? []),\n ]),\n )\n const maxStep = Math.max(\n 0,\n ...(graphics.lines?.map((l) => l.step!).filter(Boolean) ?? []),\n ...(graphics.rects?.map((r) => r.step!).filter(Boolean) ?? []),\n ...(graphics.points?.map((p) => p.step!).filter(Boolean) ?? []),\n )\n\n const graphicsBoundsWithPadding = useMemo(() => {\n const actualBounds = getGraphicsBounds(graphics)\n const width = actualBounds.maxX - actualBounds.minX\n const height = actualBounds.maxY - actualBounds.minY\n return {\n minX: actualBounds.minX - width / 10,\n minY: actualBounds.minY - height / 10,\n maxX: actualBounds.maxX + width / 10,\n maxY: actualBounds.maxY + height / 10,\n }\n }, [graphics])\n\n const { transform: realToScreen, ref } = useMouseMatrixTransform({\n initialTransform: compose(\n translate(size.width / 2, size.height / 2),\n scale(\n Math.min(\n size.width /\n (graphicsBoundsWithPadding.maxX - graphicsBoundsWithPadding.minX),\n size.height /\n (graphicsBoundsWithPadding.maxY - graphicsBoundsWithPadding.minY),\n ),\n -Math.min(\n size.width /\n (graphicsBoundsWithPadding.maxX - graphicsBoundsWithPadding.minX),\n size.height /\n (graphicsBoundsWithPadding.maxY - graphicsBoundsWithPadding.minY),\n ),\n ),\n translate(\n -(graphicsBoundsWithPadding.maxX + graphicsBoundsWithPadding.minX) / 2,\n -(graphicsBoundsWithPadding.maxY + graphicsBoundsWithPadding.minY) / 2,\n ),\n ),\n })\n\n useResizeObserver(ref, (entry: ResizeObserverEntry) => {\n setSize({\n width: entry.contentRect.width,\n height: entry.contentRect.height,\n })\n })\n\n const interactiveState: InteractiveState = {\n activeLayers: activeLayers,\n activeStep: activeStep,\n realToScreen: realToScreen,\n onObjectClicked: onObjectClicked,\n }\n\n const showToolbar = availableLayers.length > 1 || maxStep > 0\n\n // Use custom hooks for visibility checks and filtering\n const isPointOnScreen = useIsPointOnScreen(realToScreen, size)\n\n const doesLineIntersectViewport = useDoesLineIntersectViewport(\n realToScreen,\n size,\n )\n\n // Filter by layer and step\n const filterLayerAndStep = (obj: { layer?: string; step?: number }) => {\n if (activeLayers && obj.layer && !activeLayers.includes(obj.layer))\n return false\n if (\n activeStep !== null &&\n obj.step !== undefined &&\n obj.step !== activeStep\n )\n return false\n return true\n }\n\n const filterLines = useFilterLines(\n isPointOnScreen,\n doesLineIntersectViewport,\n filterLayerAndStep,\n )\n\n const filterPoints = useFilterPoints(isPointOnScreen, filterLayerAndStep)\n\n const filterRects = useFilterRects(\n isPointOnScreen,\n doesLineIntersectViewport,\n filterLayerAndStep,\n )\n\n const filterCircles = useFilterCircles(\n isPointOnScreen,\n filterLayerAndStep,\n realToScreen,\n size,\n )\n\n const filterAndLimit = <T,>(\n objects: T[] | undefined,\n filterFn: (obj: T) => boolean,\n ): (T & { originalIndex: number })[] => {\n if (!objects) return []\n const filtered = objects\n .map((obj, index) => ({ ...obj, originalIndex: index }))\n .filter(filterFn)\n return objectLimit ? filtered.slice(-objectLimit) : filtered\n }\n\n const filteredLines = useMemo(\n () => filterAndLimit(graphics.lines, filterLines),\n [graphics.lines, filterLines, objectLimit],\n )\n const filteredRects = useMemo(\n () => filterAndLimit(graphics.rects, filterRects),\n [graphics.rects, filterRects, objectLimit],\n )\n const filteredPoints = useMemo(\n () => filterAndLimit(graphics.points, filterPoints),\n [graphics.points, filterPoints, objectLimit],\n )\n const filteredCircles = useMemo(\n () => filterAndLimit(graphics.circles, filterCircles),\n [graphics.circles, filterCircles, objectLimit],\n )\n\n const totalFilteredObjects =\n filteredLines.length +\n filteredRects.length +\n filteredPoints.length +\n filteredCircles.length\n const isLimitReached = objectLimit && totalFilteredObjects > objectLimit\n\n return (\n <div>\n {showToolbar && (\n <div style={{ margin: 8 }}>\n {availableLayers.length > 1 && (\n <select\n value={activeLayers ? activeLayers[0] : \"\"}\n onChange={(e) => {\n const value = e.target.value\n setActiveLayers(value === \"\" ? null : [value])\n }}\n style={{ marginRight: 8 }}\n >\n <option value=\"\">All Layers</option>\n {availableLayers.map((layer) => (\n <option key={layer} value={layer}>\n {layer}\n </option>\n ))}\n </select>\n )}\n\n {maxStep > 0 && (\n <div\n style={{ display: \"inline-flex\", alignItems: \"center\", gap: 8 }}\n >\n Step:\n <input\n type=\"number\"\n min={0}\n max={maxStep}\n value={activeStep ?? 0}\n onChange={(e) => {\n const value = parseInt(e.target.value)\n setActiveStep(Number.isNaN(value) ? null : value)\n }}\n disabled={activeStep === null}\n />\n <label>\n <input\n type=\"checkbox\"\n style={{ marginRight: 4 }}\n checked={activeStep !== null}\n onChange={(e) => {\n setActiveStep(e.target.checked ? 0 : null)\n }}\n />\n Filter by step\n </label>\n {isLimitReached && (\n <span style={{ color: \"red\", fontSize: \"12px\" }}>\n Display limited to {objectLimit} objects. Received:{\" \"}\n {totalFilteredObjects}.\n </span>\n )}\n </div>\n )}\n </div>\n )}\n\n <div\n ref={ref}\n style={{\n position: \"relative\",\n height: 600,\n overflow: \"hidden\",\n }}\n >\n <DimensionOverlay transform={realToScreen}>\n {filteredLines.map((line) => (\n <Line\n key={line.originalIndex}\n line={line}\n index={line.originalIndex}\n interactiveState={interactiveState}\n />\n ))}\n {filteredRects.map((rect) => (\n <Rect\n key={rect.originalIndex}\n rect={rect}\n index={rect.originalIndex}\n interactiveState={interactiveState}\n />\n ))}\n {filteredPoints.map((point) => (\n <Point\n key={point.originalIndex}\n point={point}\n index={point.originalIndex}\n interactiveState={interactiveState}\n />\n ))}\n {filteredCircles.map((circle) => (\n <Circle\n key={circle.originalIndex}\n circle={circle}\n index={circle.originalIndex}\n interactiveState={interactiveState}\n />\n ))}\n <SuperGrid\n stringifyCoord={(x, y) => `${x.toFixed(2)}, ${y.toFixed(2)}`}\n width={size.width}\n height={size.height}\n transform={realToScreen}\n />\n </DimensionOverlay>\n </div>\n </div>\n )\n}\n","import type * as Types from \"lib/types\"\nimport { applyToPoint } from \"transformation-matrix\"\nimport type { InteractiveState } from \"./InteractiveState\"\nimport { lighten } from \"polished\"\nimport { useState } from \"react\"\nimport { Tooltip } from \"./Tooltip\"\nimport { distToLineSegment } from \"site/utils/distToLineSegment\"\nimport { defaultColors } from \"./defaultColors\"\nimport { safeLighten } from \"site/utils/safeLighten\"\n\nexport const Line = ({\n line,\n index,\n interactiveState,\n}: { line: Types.Line; index: number; interactiveState: InteractiveState }) => {\n const { activeLayers, activeStep, realToScreen, onObjectClicked } =\n interactiveState\n const {\n points,\n layer,\n step,\n strokeColor,\n strokeWidth = 1 / realToScreen.a,\n strokeDash,\n } = line\n const [isHovered, setIsHovered] = useState(false)\n const [mousePos, setMousePos] = useState({ x: 0, y: 0 })\n\n const screenPoints = points.map((p) => applyToPoint(realToScreen, p))\n\n const handleMouseMove = (e: React.MouseEvent) => {\n const rect = e.currentTarget.getBoundingClientRect()\n const mouseX = e.clientX - rect.left\n const mouseY = e.clientY - rect.top\n const hoverThreshold = 10 // pixels\n\n setMousePos({ x: mouseX, y: mouseY })\n\n // Check distance to each line segment\n let isNearLine = false\n for (let i = 0; i < screenPoints.length - 1; i++) {\n const dist = distToLineSegment(\n mouseX,\n mouseY,\n screenPoints[i].x,\n screenPoints[i].y,\n screenPoints[i + 1].x,\n screenPoints[i + 1].y,\n )\n if (dist < hoverThreshold) {\n isNearLine = true\n break\n }\n }\n\n setIsHovered(isNearLine)\n }\n\n const baseColor = strokeColor ?? defaultColors[index % defaultColors.length]\n\n return (\n <svg\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n width: \"100%\",\n height: \"100%\",\n }}\n onMouseMove={handleMouseMove}\n onMouseLeave={() => setIsHovered(false)}\n onClick={\n isHovered\n ? () =>\n onObjectClicked?.({\n type: \"line\",\n index,\n object: line,\n })\n : undefined\n }\n >\n <polyline\n points={screenPoints.map((p) => `${p.x},${p.y}`).join(\" \")}\n stroke={isHovered ? safeLighten(0.2, baseColor) : baseColor}\n fill=\"none\"\n strokeWidth={strokeWidth * realToScreen.a}\n strokeDasharray={\n !strokeDash\n ? undefined\n : typeof strokeDash === \"string\"\n ? strokeDash\n : `${strokeDash[0] * realToScreen.a}, ${strokeDash[1] * realToScreen.a}`\n }\n strokeLinecap=\"round\"\n />\n {isHovered && line.label && (\n <foreignObject\n x={mousePos.x}\n y={mousePos.y - 40}\n width={300}\n height={40}\n >\n <Tooltip text={line.label} />\n </foreignObject>\n )}\n </svg>\n )\n}\n","export const Tooltip = ({ text }: { text: string }) => {\n return (\n <div\n style={{\n background: \"white\",\n border: \"1px solid #ccc\",\n boxShadow: \"0 0 10px 0 rgba(0, 0, 0, 0.1)\",\n borderRadius: \"4px\",\n padding: \"4px 8px\",\n fontSize: \"12px\",\n minWidth: \"150px\",\n maxWidth: \"300px\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"pre-wrap\",\n zIndex: 100,\n }}\n >\n {text}\n </div>\n )\n}\n","// Calculate distance from point to line segment\nexport const distToLineSegment = (\n px: number,\n py: number,\n x1: number,\n y1: number,\n x2: number,\n y2: number,\n) => {\n const A = px - x1\n const B = py - y1\n const C = x2 - x1\n const D = y2 - y1\n\n const dot = A * C + B * D\n const lenSq = C * C + D * D\n let param = -1\n\n if (lenSq !== 0) param = dot / lenSq\n\n let xx = 0\n let yy = 0\n\n if (param < 0) {\n xx = x1\n yy = y1\n } else if (param > 1) {\n xx = x2\n yy = y2\n } else {\n xx = x1 + param * C\n yy = y1 + param * D\n }\n\n const dx = px - xx\n const dy = py - yy\n return Math.sqrt(dx * dx + dy * dy)\n}\n","// These are default colors if no color is provided\n// colors are made based on the index of the item in the array\n\nexport const defaultColors = [\n \"rgba(239, 68, 68, 0.8)\", // red-300\n \"rgba(249, 115, 22, 0.8)\", // orange-300\n \"rgba(245, 158, 11, 0.8)\", // amber-300\n \"rgba(234, 179, 8, 0.8)\", // yellow-300\n \"rgba(132, 204, 22, 0.8)\", // lime-300\n \"rgba(34, 197, 94, 0.8)\", // green-300\n \"rgba(16, 185, 129, 0.8)\", // emerald-300\n \"rgba(20, 184, 166, 0.8)\", // teal-300\n \"rgba(6, 182, 212, 0.8)\", // cyan-300\n \"rgba(14, 165, 233, 0.8)\", // sky-300\n \"rgba(59, 130, 246, 0.8)\", // blue-300\n \"rgba(99, 102, 241, 0.8)\", // indigo-300\n \"rgba(139, 92, 246, 0.8)\", // violet-300\n \"rgba(168, 85, 247, 0.8)\", // purple-300\n \"rgba(217, 70, 239, 0.8)\", // fuchsia-300\n \"rgba(236, 72, 153, 0.8)\", // pink-300\n \"rgba(249, 168, 212, 0.8)\", // rose-300\n \"rgba(161, 161, 170, 0.8)\", // zinc-300\n]\n","import { lighten } from \"polished\"\n\nexport const safeLighten = (amount: number, color: string) => {\n try {\n return lighten(amount, color)\n } catch (e) {\n return color\n }\n}\n","import type * as Types from \"lib/types\"\nimport { applyToPoint } from \"transformation-matrix\"\nimport type { InteractiveState } from \"./InteractiveState\"\nimport { useState } from \"react\"\nimport { Tooltip } from \"./Tooltip\"\nimport { defaultColors } from \"./defaultColors\"\nimport { safeLighten } from \"site/utils/safeLighten\"\n\nexport const Point = ({\n point,\n interactiveState,\n index,\n}: {\n point: Types.Point\n interactiveState: InteractiveState\n index: number\n}) => {\n const { color, label, layer, step } = point\n const { activeLayers, activeStep, realToScreen, onObjectClicked } =\n interactiveState\n const [isHovered, setIsHovered] = useState(false)\n\n const screenPoint = applyToPoint(realToScreen, point)\n const size = 10\n\n return (\n <div\n style={{\n position: \"absolute\",\n left: screenPoint.x - size / 2,\n top: screenPoint.y - size / 2,\n width: size,\n height: size,\n borderRadius: \"50%\",\n border: `2px solid ${\n isHovered\n ? safeLighten(\n 0.2,\n color ?? defaultColors[index % defaultColors.length],\n )\n : (color ?? defaultColors[index % defaultColors.length])\n }`,\n cursor: \"pointer\",\n transition: \"border-color 0.2s\",\n }}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n onClick={() =>\n onObjectClicked?.({\n type: \"point\",\n index,\n object: point,\n })\n }\n >\n {isHovered && (\n <div\n style={{\n position: \"absolute\",\n bottom: \"100%\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n marginBottom: 8,\n }}\n >\n <Tooltip\n text={`${label ? `${label}\\n` : \"\"}x: ${point.x.toFixed(2)}, y: ${point.y.toFixed(2)}`}\n />\n </div>\n )}\n </div>\n )\n}\n","import type * as Types from \"lib/types\"\nimport { applyToPoint } from \"transformation-matrix\"\nimport type { InteractiveState } from \"./InteractiveState\"\nimport { lighten } from \"polished\"\nimport { useState } from \"react\"\nimport { Tooltip } from \"./Tooltip\"\nimport { defaultColors } from \"./defaultColors\"\nimport { safeLighten } from \"site/utils/safeLighten\"\n\nexport const Rect = ({\n rect,\n interactiveState,\n index,\n}: {\n rect: Types.Rect\n interactiveState: InteractiveState\n index: number\n}) => {\n const defaultColor = defaultColors[index % defaultColors.length]\n let { center, width, height, fill, stroke, layer, step } = rect\n const { activeLayers, activeStep, realToScreen, onObjectClicked } =\n interactiveState\n const [isHovered, setIsHovered] = useState(false)\n\n const screenCenter = applyToPoint(realToScreen, center)\n const screenWidth = width * realToScreen.a\n const screenHeight = height * Math.abs(realToScreen.d)\n\n // Default style when neither fill nor stroke is specified\n const hasStrokeOrFill = fill !== undefined || stroke !== undefined\n\n let backgroundColor = hasStrokeOrFill ? fill || \"transparent\" : defaultColor\n if (isHovered) {\n backgroundColor = safeLighten(0.2, backgroundColor)\n stroke = safeLighten(0.2, stroke!)\n }\n\n return (\n <div\n style={{\n position: \"absolute\",\n left: screenCenter.x - screenWidth / 2,\n top: screenCenter.y - screenHeight / 2,\n width: screenWidth,\n height: screenHeight,\n backgroundColor,\n border: stroke\n ? `2px solid ${isHovered ? safeLighten(0.2, stroke) : stroke}`\n : \"none\",\n cursor: \"pointer\",\n transition: \"border-color 0.2s\",\n }}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n onClick={() =>\n onObjectClicked?.({\n type: \"rect\",\n index,\n object: rect,\n })\n }\n >\n {isHovered && rect.label && (\n <div\n style={{\n position: \"absolute\",\n bottom: \"100%\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n marginBottom: 8,\n }}\n >\n <Tooltip text={rect.label} />\n </div>\n )}\n </div>\n )\n}\n","import type * as Types from \"lib/types\"\nimport { applyToPoint } from \"transformation-matrix\"\nimport type { InteractiveState } from \"./InteractiveState\"\nimport { useState } from \"react\"\nimport { Tooltip } from \"./Tooltip\"\nimport { defaultColors } from \"./defaultColors\"\nimport { safeLighten } from \"site/utils/safeLighten\"\n\nexport const Circle = ({\n circle,\n interactiveState,\n index,\n}: {\n circle: Types.Circle\n interactiveState: InteractiveState\n index: number\n}) => {\n const defaultColor = defaultColors[index % defaultColors.length]\n let { center, radius, fill, stroke, layer, step, label } = circle\n const { activeLayers, activeStep, realToScreen, onObjectClicked } =\n interactiveState\n const [isHovered, setIsHovered] = useState(false)\n const screenCenter = applyToPoint(realToScreen, center)\n const screenRadius = radius * realToScreen.a\n let backgroundColor = fill || defaultColor\n if (isHovered) {\n backgroundColor = safeLighten(0.2, backgroundColor)\n stroke = stroke ? safeLighten(0.2, stroke) : stroke\n }\n return (\n <div\n style={{\n position: \"absolute\",\n left: screenCenter.x - screenRadius,\n top: screenCenter.y - screenRadius,\n width: screenRadius * 2,\n height: screenRadius * 2,\n borderRadius: \"50%\",\n backgroundColor,\n border: stroke ? `2px solid ${stroke}` : \"none\",\n cursor: \"pointer\",\n transition: \"border-color 0.2s\",\n }}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n onClick={() =>\n onObjectClicked?.({\n type: \"circle\",\n index,\n object: circle,\n })\n }\n >\n {isHovered && label && (\n <div\n style={{\n position: \"absolute\",\n bottom: \"100%\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n marginBottom: 8,\n }}\n >\n <Tooltip text={label} />\n </div>\n )}\n </div>\n )\n}\n","import { GraphicsObject } from \"lib/types\"\n\nexport const getGraphicsBounds = (graphics: GraphicsObject) => {\n const bounds = {\n minX: Infinity,\n minY: Infinity,\n maxX: -Infinity,\n maxY: -Infinity,\n }\n for (const line of graphics.lines ?? []) {\n for (const point of line.points ?? []) {\n bounds.minX = Math.min(bounds.minX, point.x)\n bounds.minY = Math.min(bounds.minY, point.y)\n bounds.maxX = Math.max(bounds.maxX, point.x)\n bounds.maxY = Math.max(bounds.maxY, point.y)\n }\n }\n for (const rect of graphics.rects ?? []) {\n const { center, width, height } = rect\n const halfWidth = width / 2\n const halfHeight = height / 2\n bounds.minX = Math.min(bounds.minX, center.x - halfWidth)\n bounds.minY = Math.min(bounds.minY, center.y - halfHeight)\n bounds.maxX = Math.max(bounds.maxX, center.x + halfWidth)\n bounds.maxY = Math.max(bounds.maxY, center.y + halfHeight)\n }\n for (const point of graphics.points ?? []) {\n bounds.minX = Math.min(bounds.minX, point.x)\n bounds.minY = Math.min(bounds.minY, point.y)\n bounds.maxX = Math.max(bounds.maxX, point.x)\n bounds.maxY = Math.max(bounds.maxY, point.y)\n }\n return bounds\n}\n","import { applyToPoint, type Matrix } from \"transformation-matrix\"\nimport { useMemo } from \"react\"\nimport { OFFSCREEN_MARGIN } from \"./useDoesLineIntersectViewport\"\n\nexport const useIsPointOnScreen = (\n realToScreen: Matrix,\n size: { width: number; height: number },\n) => {\n return useMemo(() => {\n return (point: { x: number; y: number }) => {\n const screenPoint = applyToPoint(realToScreen, point)\n return (\n screenPoint.x >= -OFFSCREEN_MARGIN &&\n screenPoint.x <= size.width + OFFSCREEN_MARGIN &&\n screenPoint.y >= -OFFSCREEN_MARGIN &&\n screenPoint.y <= size.height + OFFSCREEN_MARGIN\n )\n }\n }, [realToScreen, size])\n}\n","import { applyToPoint, type Matrix } from \"transformation-matrix\"\nimport { useMemo } from \"react\"\n\n// Margin in pixels for determining if elements are off-screen\nexport const OFFSCREEN_MARGIN = 5\n\nexport const useDoesLineIntersectViewport = (\n realToScreen: Matrix,\n size: { width: number; height: number },\n) => {\n return useMemo(() => {\n return (p1: { x: number; y: number }, p2: { x: number; y: number }) => {\n // Convert real-world points to screen coordinates\n const sp1 = applyToPoint(realToScreen, p1)\n const sp2 = applyToPoint(realToScreen, p2)\n\n // Viewport boundaries with margin\n const left = -OFFSCREEN_MARGIN\n const right = size.width + OFFSCREEN_MARGIN\n const top = -OFFSCREEN_MARGIN\n const bottom = size.height + OFFSCREEN_MARGIN\n\n // If either point is inside the viewport, the line intersects\n if (\n (sp1.x >= left && sp1.x <= right && sp1.y >= top && sp1.y <= bottom) ||\n (sp2.x >= left && sp2.x <= right && sp2.y >= top && sp2.y <= bottom)\n ) {\n return true\n }\n\n // Helper function to check if a line intersects with a line segment\n const intersects = (\n a1: { x: number; y: number },\n a2: { x: number; y: number },\n b1: { x: number; y: number },\n b2: { x: number; y: number },\n ) => {\n // Line segment A is (a1, a2), line segment B is (b1, b2)\n const det =\n (a2.x - a1.x) * (b2.y - b1.y) - (a2.y - a1.y) * (b2.x - b1.x)\n\n // If lines are parallel or coincident, they don't intersect in a unique point\n if (det === 0) return false\n\n const lambda =\n ((b2.y - b1.y) * (b2.x - a1.x) + (b1.x - b2.x) * (b2.y - a1.y)) / det\n const gamma =\n ((a1.y - a2.y) * (b2.x - a1.x) + (a2.x - a1.x) * (b2.y - a1.y)) / det\n\n // Check if the intersection point is within both line segments\n return lambda >= 0 && lambda <= 1 && gamma >= 0 && gamma <= 1\n }\n\n // Check intersection with each edge of the viewport\n return (\n // Top edge\n intersects(sp1, sp2, { x: left, y: top }, { x: right, y: top }) ||\n // Right edge\n intersects(sp1, sp2, { x: right, y: top }, { x: right, y: bottom }) ||\n // Bottom edge\n intersects(sp1, sp2, { x: left, y: bottom }, { x: right, y: bottom }) ||\n // Left edge\n intersects(sp1, sp2, { x: left, y: top }, { x: left, y: bottom })\n )\n }\n }, [realToScreen, size])\n}\n","import { useMemo } from \"react\"\n\ntype Line = {\n points: Array<{ x: number; y: number }>\n layer?: string\n step?: number\n closed?: boolean\n}\n\nexport const useFilterLines = (\n isPointOnScreen: (point: { x: number; y: number }) => boolean,\n doesLineIntersectViewport: (\n p1: { x: number; y: number },\n p2: { x: number; y: number },\n ) => boolean,\n filterLayerAndStep: (obj: { layer?: string; step?: number }) => boolean,\n) => {\n return useMemo(() => {\n return (line: Line) => {\n // First apply layer and step filters\n if (!filterLayerAndStep(line)) return false\n\n // Then check if any point of the line is visible\n if (line.points.some((p) => isPointOnScreen(p))) {\n return true\n }\n\n // If no points are visible, check if any line segment intersects the viewport\n for (let i = 0; i < line.points.length - 1; i++) {\n if (doesLineIntersectViewport(line.points[i], line.points[i + 1])) {\n return true\n }\n }\n\n // If it's a closed shape (polyline), check the last segment too\n if (line.points.length > 2 && line.closed) {\n if (\n doesLineIntersectViewport(\n line.points[line.points.length - 1],\n line.points[0],\n )\n ) {\n return true\n }\n }\n\n return false\n }\n }, [isPointOnScreen, doesLineIntersectViewport, filterLayerAndStep])\n}\n","import { useMemo } from \"react\"\n\ntype Point = {\n x: number\n y: number\n layer?: string\n step?: number\n}\n\nexport const useFilterPoints = (\n isPointOnScreen: (point: { x: number; y: number }) => boolean,\n filterLayerAndStep: (obj: { layer?: string; step?: number }) => boolean,\n) => {\n return useMemo(() => {\n return (point: Point) => {\n // First apply layer and step filters\n if (!filterLayerAndStep(point)) return false\n\n // Then check if the point is visible\n return isPointOnScreen(point)\n }\n }, [isPointOnScreen, filterLayerAndStep])\n}\n","import { useMemo } from \"react\"\n\ntype Rect = {\n center: { x: number; y: number }\n width: number\n height: number\n layer?: string\n step?: number\n}\n\nexport const useFilterRects = (\n isPointOnScreen: (point: { x: number; y: number }) => boolean,\n doesLineIntersectViewport: (\n p1: { x: number; y: number },\n p2: { x: number; y: number },\n ) => boolean,\n filterLayerAndStep: (obj: { layer?: string; step?: number }) => boolean,\n) => {\n return useMemo(() => {\n return (rect: Rect) => {\n // First apply layer and step filters\n if (!filterLayerAndStep(rect)) return false\n\n // For rectangles, check if any corner or the center is visible\n const { center, width, height } = rect\n const halfWidth = width / 2\n const halfHeight = height / 2\n\n const topLeft = { x: center.x - halfWidth, y: center.y - halfHeight }\n const topRight = { x: center.x + halfWidth, y: center.y - halfHeight }\n const bottomLeft = { x: center.x - halfWidth, y: center.y + halfHeight }\n const bottomRight = { x: center.x + halfWidth, y: center.y + halfHeight }\n\n // Check if any corner or center is visible\n if (\n isPointOnScreen(center) ||\n isPointOnScreen(topLeft) ||\n isPointOnScreen(topRight) ||\n isPointOnScreen(bottomLeft) ||\n isPointOnScreen(bottomRight)\n ) {\n return true\n }\n\n // Check if any edge of the rectangle intersects the viewport\n return (\n doesLineIntersectViewport(topLeft, topRight) ||\n doesLineIntersectViewport(topRight, bottomRight) ||\n doesLineIntersectViewport(bottomRight, bottomLeft) ||\n doesLineIntersectViewport(bottomLeft, topLeft)\n )\n }\n }, [isPointOnScreen, doesLineIntersectViewport, filterLayerAndStep])\n}\n","import { applyToPoint, type Matrix } from \"transformation-matrix\"\nimport { useMemo } from \"react\"\nimport { OFFSCREEN_MARGIN } from \"./useDoesLineIntersectViewport\"\n\ntype Circle = {\n center: { x: number; y: number }\n radius: number\n layer?: string\n step?: number\n}\n\nexport const useFilterCircles = (\n isPointOnScreen: (point: { x: number; y: number }) => boolean,\n filterLayerAndStep: (obj: { layer?: string; step?: number }) => boolean,\n realToScreen: Matrix,\n size: { width: number; height: number },\n) => {\n return useMemo(() => {\n return (circle: Circle) => {\n // First apply layer and step filters\n if (!filterLayerAndStep(circle)) return false\n\n // For circles, check if center is visible or if any cardinal point is visible\n const { center, radius } = circle\n\n // Check if center or cardinal points on the circle are visible\n if (\n isPointOnScreen(center) ||\n isPointOnScreen({ x: center.x + radius, y: center.y }) ||\n isPointOnScreen({ x: center.x - radius, y: center.y }) ||\n isPointOnScreen({ x: center.x, y: center.y + radius }) ||\n isPointOnScreen({ x: center.x, y: center.y - radius })\n ) {\n return true\n }\n\n // Check if the circle intersects the viewport\n // Convert to screen coordinates for viewport intersection test\n const screenCenter = applyToPoint(realToScreen, center)\n const scale = Math.abs(realToScreen.a) // Get the scale factor\n const screenRadius = radius * scale\n\n // Viewport boundaries\n const left = -OFFSCREEN_MARGIN\n const right = size.width + OFFSCREEN_MARGIN\n const top = -OFFSCREEN_MARGIN\n const bottom = size.height + OFFSCREEN_MARGIN\n\n // Check if the circle intersects with the viewport\n // Case 1: Circle center is inside the viewport horizontally but outside vertically\n if (screenCenter.x >= left && screenCenter.x <= right) {\n if (\n Math.abs(screenCenter.y - top) <= screenRadius ||\n Math.abs(screenCenter.y - bottom) <= screenRadius\n ) {\n return true\n }\n }\n\n // Case 2: Circle center is inside the viewport vertically but outside horizontally\n if (screenCenter.y >= top && screenCenter.y <= bottom) {\n if (\n Math.abs(screenCenter.x - left) <= screenRadius ||\n Math.abs(screenCenter.x - right) <= screenRadius\n ) {\n return true\n }\n }\n\n // Case 3: Circle center is outside the viewport, check corners\n const cornerDistanceSquared = (cornerX: number, cornerY: number) => {\n const dx = screenCenter.x - cornerX\n const dy = screenCenter.y - cornerY\n return dx * dx + dy * dy\n }\n\n const radiusSquared = screenRadius * screenRadius\n\n return (\n cornerDistanceSquared(left, top) <= radiusSquared ||\n cornerDistanceSquared(right, top) <= radiusSquared ||\n cornerDistanceSquared(left, bottom) <= radiusSquared ||\n cornerDistanceSquared(right, bottom) <= radiusSquared\n )\n }\n }, [isPointOnScreen, filterLayerAndStep, realToScreen, size])\n}\n","import React, { useEffect, useRef, useState } from \"react\"\nimport { applyToPoint, identity, inverse } from \"transformation-matrix\"\nimport type { Matrix } from \"transformation-matrix\"\n\ninterface Props {\n transform?: Matrix\n children: React.ReactNode\n}\n\nexport const DimensionOverlay: React.FC<Props> = ({ children, transform }) => {\n if (!transform) transform = identity()\n const [dimensionToolVisible, setDimensionToolVisible] = useState(false)\n const [dimensionToolStretching, setDimensionToolStretching] = useState(false)\n // Start of dimension tool line in real-world coordinates (not screen)\n const [dStart, setDStart] = useState({ x: 0, y: 0 })\n // End of dimension tool line in real-world coordinates (not screen)\n const [dEnd, setDEnd] = useState({ x: 0, y: 0 })\n const mousePosRef = useRef({ x: 0, y: 0 })\n const containerRef = useRef<HTMLDivElement | null>(null)\n const container = containerRef.current!\n const containerBounds = container?.getBoundingClientRect()\n\n const bindKeys = () => {\n const container = containerRef.current\n\n const down = (e: KeyboardEvent) => {\n if (e.key === \"d\") {\n setDStart({ x: mousePosRef.current.x, y: mousePosRef.current.y })\n setDEnd({ x: mousePosRef.current.x, y: mousePosRef.current.y })\n setDimensionToolVisible((visible: boolean) => !visible)\n setDimensionToolStretching(true)\n }\n if (e.key === \"Escape\") {\n setDimensionToolVisible(false)\n setDimensionToolStretching(false)\n }\n }\n\n const addKeyListener = () => {\n if (container) {\n window.addEventListener(\"keydown\", down)\n }\n }\n\n const removeKeyListener = () => {\n if (container) {\n window.removeEventListener(\"keydown\", down)\n }\n }\n\n if (container) {\n container.addEventListener(\"focus\", addKeyListener)\n container.addEventListener(\"blur\", removeKeyListener)\n container.addEventListener(\"mouseenter\", addKeyListener)\n container.addEventListener(\"mouseleave\", removeKeyListener)\n }\n return () => {\n if (container) {\n container.removeEventListener(\"focus\", addKeyListener)\n container.removeEventListener(\"blur\", removeKeyListener)\n container.removeEventListener(\"mouseenter\", addKeyListener)\n container.removeEventListener(\"mouseleave\", removeKeyListener)\n }\n }\n }\n\n useEffect(bindKeys, [containerBounds?.width, containerBounds?.height])\n\n const screenDStart = applyToPoint(transform, dStart)\n const screenDEnd = applyToPoint(transform, dEnd)\n\n const arrowScreenBounds = {\n left: Math.min(screenDStart.x, screenDEnd.x),\n right: Math.max(screenDStart.x, screenDEnd.x),\n top: Math.min(screenDStart.y, screenDEnd.y),\n bottom: Math.max(screenDStart.y, screenDEnd.y),\n flipX: screenDStart.x > screenDEnd.x,\n flipY: screenDStart.y > screenDEnd.y,\n width: 0,\n height: 0,\n }\n arrowScreenBounds.width = arrowScreenBounds.right - arrowScreenBounds.left\n arrowScreenBounds.height = arrowScreenBounds.bottom - arrowScreenBounds.top\n\n return (\n <div\n ref={containerRef}\n tabIndex={0}\n style={{ position: \"relative\" }}\n onMouseMove={(e: React.MouseEvent<HTMLDivElement>) => {\n const rect = e.currentTarget.getBoundingClientRect()\n const x = e.clientX - rect.left\n const y = e.clientY - rect.top\n const rwPoint = applyToPoint(inverse(transform!), { x, y })\n mousePosRef.current.x = rwPoint.x\n mousePosRef.current.y = rwPoint.y\n\n if (dimensionToolStretching) {\n setDEnd({ x: rwPoint.x, y: rwPoint.y })\n }\n }}\n onMouseDown={() => {\n if (dimensionToolStretching) {\n setDimensionToolStretching(false)\n } else if (dimensionToolVisible) {\n setDimensionToolVisible(false)\n }\n }}\n onMouseEnter={() => {\n if (containerRef.current) {\n bindKeys()\n }\n }}\n >\n {children}\n {dimensionToolVisible && (\n <>\n <div\n style={{\n position: \"absolute\",\n left: arrowScreenBounds.left,\n width: arrowScreenBounds.width,\n textAlign: \"center\",\n top: screenDStart.y + 2,\n color: \"red\",\n mixBlendMode: \"difference\",\n pointerEvents: \"none\",\n marginTop: arrowScreenBounds.flipY ? 0 : -20,\n fontSize: 12,\n fontFamily: \"sans-serif\",\n zIndex: 30,\n }}\n >\n {Math.abs(dStart.x - dEnd.x).toFixed(2)}\n </div>\n <div\n style={{\n position: \"absolute\",\n left: screenDEnd.x,\n height: arrowScreenBounds.height,\n display: \"flex\",\n flexDirection: \"column\",\n justifyContent: \"center\",\n top: arrowScreenBounds.top,\n color: \"red\",\n pointerEvents: \"none\",\n mixBlendMode: \"difference\",\n fontSize: 12,\n fontFamily: \"sans-serif\",\n zIndex: 30,\n }}\n >\n <div\n style={{\n marginLeft: arrowScreenBounds.flipX ? \"-100%\" : 4,\n paddingRight: 4,\n }}\n >\n {Math.abs(dStart.y - dEnd.y).toFixed(2)}\n </div>\n </div>\n <svg\n style={{\n position: \"absolute\",\n left: 0,\n top: 0,\n pointerEvents: \"none\",\n mixBlendMode: \"difference\",\n zIndex: 30,\n }}\n width={containerBounds?.width || \"100%\"}\n height={containerBounds?.height || \"100%\"}\n >\n <defs>\n <marker\n id=\"head\"\n orient=\"auto\"\n markerWidth=\"3\"\n markerHeight=\"4\"\n refX=\"2\"\n refY=\"2\"\n >\n <path d=\"M0,0 V4 L2,2 Z\" fill=\"red\" />\n </marker>\n </defs>\n <line\n x1={screenDStart.x}\n y1={screenDStart.y}\n x2={screenDEnd.x}\n y2={screenDEnd.y}\n markerEnd=\"url(#head)\"\n strokeWidth={1.5}\n fill=\"none\"\n stroke=\"red\"\n />\n <line\n x1={screenDStart.x}\n y1={screenDStart.y}\n x2={screenDEnd.x}\n y2={screenDStart.y}\n strokeWidth={1.5}\n fill=\"none\"\n strokeDasharray={\"2,2\"}\n stroke=\"red\"\n />\n <line\n x1={screenDEnd.x}\n y1={screenDStart.y}\n x2={screenDEnd.x}\n y2={screenDEnd.y}\n strokeWidth={1.5}\n fill=\"none\"\n strokeDasharray={\"2,2\"}\n stroke=\"red\"\n />\n </svg>\n <div\n style={{\n right: 0,\n bottom: 0,\n position: \"absolute\",\n color: \"red\",\n fontFamily: \"sans-serif\",\n fontSize: 12,\n margin: 4,\n }}\n >\n ({dStart.x.toFixed(2)},{dStart.y.toFixed(2)})<br />(\n {dEnd.x.toFixed(2)},{dEnd.y.toFixed(2)})<br />\n dist:{\" \"}\n {Math.sqrt(\n (dEnd.x - dStart.x) ** 2 + (dEnd.y - dStart.y) ** 2,\n ).toFixed(2)}\n </div>\n </>\n )}\n </div>\n )\n}\n","import React, { useRef, useEffect, useState, useMemo } from \"react\"\nimport { drawGraphicsToCanvas, getBounds, type GraphicsObject } from \"../../lib\"\nimport useMouseMatrixTransform from \"use-mouse-matrix-transform\"\nimport { compose, scale, translate } from \"transformation-matrix\"\nimport useResizeObserver from \"@react-hook/resize-observer\"\nimport { DimensionOverlay } from \"./DimensionOverlay\"\n\ninterface InteractiveGraphicsCanvasProps {\n graphics: GraphicsObject\n showLabelsByDefault?: boolean\n showGrid?: boolean\n height?: number | string\n width?: number | string\n}\n\nexport function InteractiveGraphicsCanvas({\n graphics,\n showLabelsByDefault = true,\n showGrid = true,\n height = 500,\n width = \"100%\",\n}: InteractiveGraphicsCanvasProps) {\n const canvasRef = useRef<HTMLCanvasElement>(null)\n const containerRef = useRef<HTMLDivElement | null>(null)\n const [size, setSize] = useState({ width: 600, height: 600 })\n const [activeStep, setActiveStep] = useState<number | null>(null)\n const [showLabels, setShowLabels] = useState(showLabelsByDefault)\n const [showLastStep, setShowLastStep] = useState(true)\n\n // Calculate the maximum step value from all graphics objects\n const maxStep = useMemo(() => {\n return Math.max(\n 0,\n ...(graphics.points?.map((p) => p.step ?? 0) ?? []),\n ...(graphics.lines?.map((l) => l.step ?? 0) ?? []),\n ...(graphics.rects?.map((r) => r.step ?? 0) ?? []),\n ...(graphics.circles?.map((c) => c.step ?? 0) ?? []),\n )\n }, [graphics])\n\n // Filter graphics objects based on step\n const filteredGraphics = useMemo(() => {\n if (activeStep === null) {\n return graphics\n }\n\n // If showLastStep is enabled and we're filtering by step, show everything up to and including the current step\n const maxStep = Math.max(\n ...(graphics.points?.map((p) => p.step ?? 0) ?? []),\n ...(graphics.lines?.map((l) => l.step ?? 0) ?? []),\n ...(graphics.rects?.map((r) => r.step ?? 0) ?? []),\n ...(graphics.circles?.map((c) => c.step ?? 0) ?? []),\n )\n const filterByStep = showLastStep\n ? (objStep?: number) => objStep === undefined || objStep === maxStep\n : activeStep\n ? (objStep?: number) => objStep === undefined || objStep === activeStep\n : () => true\n\n return {\n ...graphics,\n points: graphics.points?.filter((p) => filterByStep(p.step)),\n lines: graphics.lines?.filter((l) => filterByStep(l.step)),\n rects: graphics.rects?.filter((r) => filterByStep(r.step)),\n circles: graphics.circles?.filter((c) => filterByStep(c.step)),\n }\n }, [graphics, activeStep, showLastStep])\n\n // Get bounds of the graphics with padding\n const graphicsBoundsWithPadding = useMemo(() => {\n const bounds = getBounds(graphics)\n const width = bounds.maxX - bounds.minX\n const height = bounds.maxY - bounds.minY\n return {\n minX: bounds.minX - width / 10,\n minY: bounds.minY - height / 10,\n maxX: bounds.maxX + width / 10,\n maxY: bounds.maxY + height / 10,\n }\n }, [graphics])\n\n // Use mouse transform hook for panning/zooming\n const { transform, ref: mouseTransformRef } = useMouseMatrixTransform({\n initialTransform: compose(\n translate(size.width / 2, size.height / 2),\n scale(\n Math.min(\n size.width /\n (graphicsBoundsWithPadding.maxX - graphicsBoundsWithPadding.minX),\n size.height /\n (graphicsBoundsWithPadding.maxY - graphicsBoundsWithPadding.minY),\n ),\n -Math.min(\n size.width /\n (graphicsBoundsWithPadding.maxX - graphicsBoundsWithPadding.minX),\n size.height /\n (graphicsBoundsWithPadding.maxY - graphicsBoundsWithPadding.minY),\n ),\n ),\n translate(\n -(graphicsBoundsWithPadding.maxX + graphicsBoundsWithPadding.minX) / 2,\n -(graphicsBoundsWithPadding.maxY + graphicsBoundsWithPadding.minY) / 2,\n ),\n ),\n })\n\n // Monitor container size\n useResizeObserver(containerRef, (entry) => {\n setSize({\n width: entry.contentRect.width,\n height: entry.contentRect.height,\n })\n })\n\n // Draw function that uses our canvas renderer\n const drawCanvas = () => {\n if (!canvasRef.current) return\n\n // Make sure canvas dimensions match container\n canvasRef.current.width = size.width\n canvasRef.current.height = size.height\n\n // Draw the graphics with the current transform\n drawGraphicsToCanvas(filteredGraphics, canvasRef.current, {\n transform: transform,\n disableLabels: !showLabels,\n })\n\n // Draw a grid for reference if requested\n if (showGrid) {\n drawGrid(canvasRef.current, transform)\n }\n }\n\n // Draw a grid to help with visualization\n const drawGrid = (canvas: HTMLCanvasElement, transform: any) => {\n const ctx = canvas.getContext(\"2d\")\n if (!ctx) return\n\n ctx.save()\n\n // Draw coordinate axes\n ctx.beginPath()\n\n // X-axis\n const xAxisStart = { x: -1000, y: 0 }\n const xAxisEnd = { x: 1000, y: 0 }\n const xAxisStartTransformed = transformPoint(xAxisStart, transform)\n const xAxisEndTransformed = transformPoint(xAxisEnd, transform)\n\n ctx.moveTo(xAxisStartTransformed.x, xAxisStartTransformed.y)\n ctx.lineTo(xAxisEndTransformed.x, xAxisEndTransformed.y)\n\n // Y-axis\n const yAxisStart = { x: 0, y: -1000 }\n const yAxisEnd = { x: 0, y: 1000 }\n const yAxisStartTransformed = transformPoint(yAxisStart, transform)\n const yAxisEndTransformed = transformPoint(yAxisEnd, transform)\n\n ctx.moveTo(yAxisStartTransformed.x, yAxisStartTransformed.y)\n ctx.lineTo(yAxisEndTransformed.x, yAxisEndTransformed.y)\n\n ctx.strokeStyle = \"#aaa\"\n ctx.lineWidth = 1\n ctx.stroke()\n\n // Draw grid lines\n ctx.beginPath()\n ctx.setLineDash([2, 2])\n\n // Determine grid spacing based on zoom level\n const gridSize = 10\n\n // Draw vertical grid lines\n for (let x = -100; x <= 100; x += gridSize) {\n if (x === 0) continue // Skip the axis\n\n const start = transformPoint({ x, y: -100 }, transform)\n const end = transformPoint({ x, y: 100 }, transform)\n\n ctx.moveTo(start.x, start.y)\n ctx.lineTo(end.x, end.y)\n }\n\n // Draw horizontal grid lines\n for (let y = -100; y <= 100; y += gridSize) {\n if (y === 0) continue // Skip the axis\n\n const start = transformPoint({ x: -100, y }, transform)\n const end = transformPoint({ x: 100, y }, transform)\n\n ctx.moveTo(start.x, start.y)\n ctx.lineTo(end.x, end.y)\n }\n\n ctx.strokeStyle = \"#ddd\"\n ctx.stroke()\n ctx.restore()\n }\n\n // Helper to transform a point through the matrix\n const transformPoint = (point: { x: number; y: number }, matrix: any) => {\n return {\n x: matrix.a * point.x + matrix.c * point.y + matrix.e,\n y: matrix.b * point.x + matrix.d * point.y + matrix.f,\n }\n }\n\n // Apply the drawing when transform changes\n useEffect(() => {\n drawCanvas()\n }, [transform, size, filteredGraphics, showGrid, showLabels])\n\n return (\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: \"10px\" }}>\n {maxStep > 0 && (\n <div style={{ display: \"flex\", gap: \"12px\", alignItems: \"center\" }}>\n <div style={{ display: \"flex\", alignItems: \"center\", gap: \"8px\" }}>\n <label>\n <input\n type=\"checkbox\"\n style={{ marginRight: 4 }}\n checked={activeStep !== null}\n onChange={(e) => {\n setActiveStep(e.target.checked ? 0 : null)\n }}\n />\n Filter by step\n </label>\n\n <input\n type=\"number\"\n min={0}\n max={maxStep}\n value={activeStep ?? 0}\n onChange={(e) => {\n const value = parseInt(e.target.value)\n setShowLastStep(false)\n setActiveStep(\n Number.isNaN(value) ? 0 : Math.min(value, maxStep),\n )\n }}\n disabled={activeStep === null}\n style={{ width: \"60px\" }}\n />\n\n <label>\n <input\n type=\"checkbox\"\n style={{ marginRight: 4 }}\n checked={showLastStep}\n onChange={(e) => {\n setShowLastStep(e.target.checked)\n setActiveStep(null)\n }}\n />\n Show last step\n </label>\n </div>\n\n <div style={{ display: \"flex\", alignItems: \"center\", gap: \"8px\" }}>\n <label>\n <input\n type=\"checkbox\"\n style={{ marginRight: 4 }}\n checked={showLabels}\n onChange={(e) => {\n setShowLabels(e.target.checked)\n }}\n />\n Show labels\n </label>\n </div>\n </div>\n )}\n\n <div\n ref={(node) => {\n // Using a callback ref approach\n containerRef.current = node\n // Apply the mouse transform ref if available\n if (mouseTransformRef && node) {\n mouseTransformRef.current = node\n }\n }}\n style={{\n position: \"relative\",\n width: width,\n height: height,\n border: \"1px solid #ccc\",\n overflow: \"hidden\",\n }}\n >\n <canvas\n ref={canvasRef}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n width,\n height,\n }}\n />\n </div>\n </div>\n )\n}\n\nexport default InteractiveGraphicsCanvas\n","import React, { useRef, useEffect, useState } from \"react\"\nimport { GraphicsObject } from \"../../../lib/types\"\nimport {\n drawGraphicsToCanvas,\n getBounds,\n} from \"../../../lib/drawGraphicsToCanvas\"\nimport useMouseMatrixTransform from \"use-mouse-matrix-transform\"\nimport { compose, scale, translate, type Matrix } from \"transformation-matrix\"\nimport useResizeObserver from \"@react-hook/resize-observer\"\nimport { DimensionOverlay } from \"../DimensionOverlay\"\n\ninterface CanvasGraphicsProps {\n graphics: GraphicsObject\n width?: number\n height?: number\n withGrid?: boolean\n initialTransform?: Matrix\n disableLabels?: boolean\n}\n\n// Create a container component that handles the mouse matrix transform\nfunction TransformContainer({\n initialTransform,\n children,\n onTransformChange,\n}: {\n initialTransform: Matrix\n children: React.ReactNode\n onTransformChange: (transform: Matrix) => void\n}) {\n const { transform, ref } = useMouseMatrixTransform({\n initialTransform,\n })\n\n // Update parent with transform changes\n useEffect(() => {\n onTransformChange(transform)\n }, [transform, onTransformChange])\n\n return (\n <div\n ref={ref}\n style={{\n position: \"relative\",\n width: \"100%\",\n height: \"100%\",\n }}\n >\n {children}\n </div>\n )\n}\n\nexport const CanvasGraphics = ({\n graphics,\n width = 600,\n height = 600,\n withGrid = true,\n disableLabels = false,\n initialTransform,\n}: CanvasGraphicsProps) => {\n const canvasRef = useRef<HTMLCanvasElement>(null)\n const containerRef = useRef<HTMLDivElement>(null)\n const [size, setSize] = useState({ width, height })\n const [currentTransform, setCurrentTransform] = useState<Matrix | null>(null)\n\n // Get bounds of the graphics with padding\n const graphicsBoundsWithPadding = React.useMemo(() => {\n const bounds = getBounds(graphics)\n const bWidth = bounds.maxX - bounds.minX\n const bHeight = bounds.maxY - bounds.minY\n return {\n minX: bounds.minX - bWidth / 10,\n minY: bounds.minY - bHeight / 10,\n maxX: bounds.maxX + bWidth / 10,\n maxY: bounds.maxY + bHeight / 10,\n }\n }, [graphics])\n\n // Compute initial transform if not provided\n const computedInitialTransform = React.useMemo(() => {\n if (initialTransform) return initialTransform\n\n const yFlip = graphics.coordinateSystem === \"cartesian\"\n return compose(\n translate(size.width / 2, size.height / 2),\n scale(\n Math.min(\n size.width /\n (graphicsBoundsWithPadding.maxX - graphicsBoundsWithPadding.minX),\n size.height /\n (graphicsBoundsWithPadding.maxY - graphicsBoundsWithPadding.minY),\n ),\n yFlip\n ? -Math.min(\n size.width /\n (graphicsBoundsWithPadding.maxX -\n graphicsBoundsWithPadding.minX),\n size.height /\n (graphicsBoundsWithPadding.maxY -\n graphicsBoundsWithPadding.minY),\n )\n : Math.min(\n size.width /\n (graphicsBoundsWithPadding.maxX -\n graphicsBoundsWithPadding.minX),\n size.height /\n (graphicsBoundsWithPadding.maxY -\n graphicsBoundsWithPadding.minY),\n ),\n ),\n translate(\n -(graphicsBoundsWithPadding.maxX + graphicsBoundsWithPadding.minX) / 2,\n -(graphicsBoundsWithPadding.maxY + graphicsBoundsWithPadding.minY) / 2,\n ),\n )\n }, [graphics, graphicsBoundsWithPadding, initialTransform, size])\n\n // Track transform changes from the mouse transform hook\n const handleTransformChange = React.useCallback((transform: Matrix) => {\n setCurrentTransform(transform)\n }, [])\n\n // Monitor container size\n useResizeObserver(containerRef, (entry) => {\n setSize({\n width: entry.contentRect.width,\n height: entry.contentRect.height,\n })\n })\n\n // Draw function that uses our canvas renderer\n const drawCanvas = React.useCallback(() => {\n if (!canvasRef.current || !currentTransform) return\n\n // Make sure canvas dimensions match container\n canvasRef.current.width = size.width\n canvasRef.current.height = size.height\n\n // Draw the graphics with the current transform\n drawGraphicsToCanvas(graphics, canvasRef.current, {\n transform: currentTransform,\n disableLabels,\n })\n\n // Draw a grid for reference if enabled\n if (withGrid) {\n drawGrid(canvasRef.current, currentTransform)\n }\n }, [canvasRef, currentTransform, graphics, size, withGrid])\n\n // Draw a grid to help with visualization\n const drawGrid = (canvas: HTMLCanvasElement, transform: Matrix) => {\n const ctx = canvas.getContext(\"2d\")\n if (!ctx) return\n\n ctx.save()\n\n // Draw coordinate axes\n ctx.beginPath()\n\n // X-axis\n const xAxisStart = { x: -1000, y: 0 }\n const xAxisEnd = { x: 1000, y: 0 }\n const xAxisStartTransformed = transformPoint(xAxisStart, transform)\n const xAxisEndTransformed = transformPoint(xAxisEnd, transform)\n\n ctx.moveTo(xAxisStartTransformed.x, xAxisStartTransformed.y)\n ctx.lineTo(xAxisEndTransformed.x, xAxisEndTransformed.y)\n\n // Y-axis\n const yAxisStart = { x: 0, y: -1000 }\n const yAxisEnd = { x: 0, y: 1000 }\n const yAxisStartTransformed = transformPoint(yAxisStart, transform)\n const yAxisEndTransformed = transformPoint(yAxisEnd, transform)\n\n ctx.moveTo(yAxisStartTransformed.x, yAxisStartTransformed.y)\n ctx.lineTo(yAxisEndTransformed.x, yAxisEndTransformed.y)\n\n ctx.strokeStyle = \"#aaa\"\n ctx.lineWidth = 1\n ctx.stroke()\n\n // Draw grid lines\n ctx.beginPath()\n ctx.setLineDash([2, 2])\n\n // Calculate a good grid size based on zoom level\n // This is an approximate calculation\n const zoomLevel = Math.abs(transform.a) // Scale factor\n const gridSize = Math.pow(10, Math.floor(Math.log10(100 / zoomLevel)))\n\n const gridRange = Math.ceil(1000 / gridSize) * gridSize\n\n // Draw vertical grid lines\n for (let x = -gridRange; x <= gridRange; x += gridSize) {\n if (x === 0) continue // Skip the axis\n\n const start = transformPoint({ x, y: -gridRange }, transform)\n const end = transformPoint({ x, y: gridRange }, transform)\n\n ctx.moveTo(start.x, start.y)\n ctx.lineTo(end.x, end.y)\n }\n\n // Draw horizontal grid lines\n for (let y = -gridRange; y <= gridRange; y += gridSize) {\n if (y === 0) continue // Skip the axis\n\n const start = transformPoint({ x: -gridRange, y }, transform)\n const end = transformPoint({ x: gridRange, y }, transform)\n\n ctx.moveTo(start.x, start.y)\n ctx.lineTo(end.x, end.y)\n }\n\n ctx.strokeStyle = \"#ddd\"\n ctx.stroke()\n ctx.restore()\n }\n\n // Helper to transform a point through the matrix\n const transformPoint = (point: { x: number; y: number }, matrix: Matrix) => {\n return {\n x: matrix.a * point.x + matrix.c * point.y + matrix.e,\n y: matrix.b * point.x + matrix.d * point.y + matrix.f,\n }\n }\n\n // Apply the drawing when transform changes\n useEffect(() => {\n drawCanvas()\n }, [drawCanvas])\n\n // Initialize transform\n useEffect(() => {\n setCurrentTransform(computedInitialTransform)\n }, [computedInitialTransform])\n\n return (\n <div\n ref={containerRef}\n style={{\n position: \"relative\",\n width: \"100%\",\n height: `${height}px`,\n border: \"1px solid #eee\",\n overflow: \"hidden\",\n }}\n >\n <TransformContainer\n initialTransform={computedInitialTransform}\n onTransformChange={handleTransformChange}\n >\n <DimensionOverlay\n transform={currentTransform || computedInitialTransform}\n >\n <canvas\n ref={canvasRef}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n width: \"100%\",\n height: \"100%\",\n }}\n />\n </DimensionOverlay>\n </TransformContainer>\n </div>\n )\n}\n"],"mappings":"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","names":["useMemo","useState","jsx","applyToPoint","useState","jsx","useState","applyToPoint","applyToPoint","useState","jsx","useState","applyToPoint","applyToPoint","useState","jsx","useState","applyToPoint","applyToPoint","useMemo","applyToPoint","useMemo","applyToPoint","useMemo","useMemo","useMemo","applyToPoint","useMemo","useMemo","applyToPoint","scale","useState","applyToPoint","jsx","jsxs","container","jsx","jsxs","useState","useMemo","useRef","useEffect","useState","useMemo","useMouseMatrixTransform","compose","scale","translate","useResizeObserver","jsx","jsxs","useRef","useState","useMemo","maxStep","width","height","transform","useEffect","React","useRef","useEffect","useState","useMouseMatrixTransform","compose","scale","translate","useResizeObserver","jsx","useMouseMatrixTransform","useEffect","useRef","useState","React","compose","translate","scale","useResizeObserver"]}
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../lib/getSvgFromGraphicsObject.ts"],"sourcesContent":["import {\n transform,\n compose,\n translate,\n scale,\n applyToPoint,\n identity,\n type Matrix,\n} from \"transformation-matrix\"\nimport type { GraphicsObject, Point } from \"./types\"\nimport { stringify } from \"svgson\"\nimport pretty from \"pretty\"\n\nconst DEFAULT_SVG_SIZE = 640\nconst PADDING = 40\n\ninterface Bounds {\n minX: number\n maxX: number\n minY: number\n maxY: number\n}\n\nfunction getBounds(graphics: GraphicsObject): Bounds {\n const points: Point[] = [\n ...(graphics.points || []),\n ...(graphics.lines || []).flatMap((line) => line.points),\n ...(graphics.rects || []).flatMap((rect) => {\n const halfWidth = rect.width / 2\n const halfHeight = rect.height / 2\n return [\n { x: rect.center.x - halfWidth, y: rect.center.y - halfHeight },\n { x: rect.center.x + halfWidth, y: rect.center.y - halfHeight },\n { x: rect.center.x - halfWidth, y: rect.center.y + halfHeight },\n { x: rect.center.x + halfWidth, y: rect.center.y + halfHeight },\n ]\n }),\n ...(graphics.circles || []).flatMap((circle) => [\n { x: circle.center.x - circle.radius, y: circle.center.y }, // left\n { x: circle.center.x + circle.radius, y: circle.center.y }, // right\n { x: circle.center.x, y: circle.center.y - circle.radius }, // top\n { x: circle.center.x, y: circle.center.y + circle.radius }, // bottom\n ]),\n ]\n\n if (points.length === 0) {\n return { minX: -1, maxX: 1, minY: -1, maxY: 1 }\n }\n\n return points.reduce(\n (bounds, point) => ({\n minX: Math.min(bounds.minX, point.x),\n maxX: Math.max(bounds.maxX, point.x),\n minY: Math.min(bounds.minY, point.y),\n maxY: Math.max(bounds.maxY, point.y),\n }),\n { minX: Infinity, maxX: -Infinity, minY: Infinity, maxY: -Infinity },\n )\n}\n\nfunction getProjectionMatrix(\n bounds: Bounds,\n coordinateSystem: GraphicsObject[\"coordinateSystem\"],\n) {\n const width = bounds.maxX - bounds.minX\n const height = bounds.maxY - bounds.minY\n\n const scale_factor = Math.min(\n (DEFAULT_SVG_SIZE - 2 * PADDING) / width,\n (DEFAULT_SVG_SIZE - 2 * PADDING) / height,\n )\n\n const yFlip = coordinateSystem === \"screen\" ? 1 : -1\n\n return compose(\n translate(DEFAULT_SVG_SIZE / 2, DEFAULT_SVG_SIZE / 2),\n scale(scale_factor, yFlip * scale_factor),\n translate(-(bounds.minX + width / 2), -(bounds.minY + height / 2)),\n )\n}\n\nfunction projectPoint(point: Point, matrix: Matrix) {\n const projected = applyToPoint(matrix, { x: point.x, y: point.y })\n return { ...point, ...projected }\n}\n\nexport function getSvgFromGraphicsObject(graphics: GraphicsObject): string {\n const bounds = getBounds(graphics)\n const matrix = getProjectionMatrix(bounds, graphics.coordinateSystem)\n\n const svgObject = {\n name: \"svg\",\n type: \"element\",\n attributes: {\n width: DEFAULT_SVG_SIZE.toString(),\n height: DEFAULT_SVG_SIZE.toString(),\n viewBox: `0 0 ${DEFAULT_SVG_SIZE} ${DEFAULT_SVG_SIZE}`,\n xmlns: \"http://www.w3.org/2000/svg\",\n },\n children: [\n // Points\n ...(graphics.points || []).map((point) => {\n const projected = projectPoint(point, matrix)\n return {\n name: \"g\",\n type: \"element\",\n attributes: {},\n children: [\n {\n name: \"circle\",\n type: \"element\",\n attributes: {\n \"data-type\": \"point\",\n \"data-label\": point.label || \"\",\n \"data-x\": point.x.toString(),\n \"data-y\": point.y.toString(),\n cx: projected.x.toString(),\n cy: projected.y.toString(),\n r: \"3\",\n fill: point.color || \"black\",\n },\n },\n ...(point.label\n ? [\n {\n name: \"text\",\n type: \"element\",\n attributes: {\n x: (projected.x + 5).toString(),\n y: (projected.y - 5).toString(),\n \"font-family\": \"sans-serif\",\n \"font-size\": \"12\",\n },\n children: [{ type: \"text\", value: point.label }],\n },\n ]\n : []),\n ],\n }\n }),\n // Lines\n ...(graphics.lines || []).map((line) => ({\n name: \"polyline\",\n type: \"element\",\n attributes: {\n \"data-points\": line.points.map((p) => `${p.x},${p.y}`).join(\" \"),\n \"data-type\": \"line\",\n points: line.points\n .map((p) => projectPoint(p, matrix))\n .map((p) => `${p.x},${p.y}`)\n .join(\" \"),\n fill: \"none\",\n stroke: line.strokeColor || \"black\",\n \"stroke-width\": (line.strokeWidth || 1).toString(),\n },\n })),\n // Rectangles\n ...(graphics.rects || []).map((rect) => {\n const corner1 = {\n x: rect.center.x - rect.width / 2,\n y: rect.center.y - rect.height / 2,\n }\n const projectedCorner1 = projectPoint(corner1, matrix)\n const corner2 = {\n x: rect.center.x + rect.width / 2,\n y: rect.center.y + rect.height / 2,\n }\n const projectedCorner2 = projectPoint(corner2, matrix)\n const scaledWidth = Math.abs(projectedCorner2.x - projectedCorner1.x)\n const scaledHeight = Math.abs(projectedCorner2.y - projectedCorner1.y)\n return {\n name: \"rect\",\n type: \"element\",\n attributes: {\n \"data-type\": \"rect\",\n \"data-label\": \"\",\n \"data-x\": rect.center.x.toString(),\n \"data-y\": rect.center.y.toString(),\n x: Math.min(projectedCorner1.x, projectedCorner2.x).toString(),\n y: Math.min(projectedCorner1.y, projectedCorner2.y).toString(),\n width: scaledWidth.toString(),\n height: scaledHeight.toString(),\n fill: rect.fill || \"none\",\n stroke: rect.stroke || \"black\",\n \"stroke-width\": Math.abs(1 / matrix.a).toString(),\n },\n }\n }),\n // Circles\n ...(graphics.circles || []).map((circle) => {\n const projected = projectPoint(circle.center, matrix)\n const scaledRadius = circle.radius * Math.abs(matrix.a)\n return {\n name: \"circle\",\n type: \"element\",\n attributes: {\n \"data-type\": \"circle\",\n \"data-label\": \"\",\n \"data-x\": circle.center.x.toString(),\n \"data-y\": circle.center.y.toString(),\n cx: projected.x.toString(),\n cy: projected.y.toString(),\n r: scaledRadius.toString(),\n fill: circle.fill || \"none\",\n stroke: circle.stroke || \"black\",\n \"stroke-width\": Math.abs(1 / matrix.a).toString(),\n },\n }\n }),\n // Crosshair lines and coordinates (initially hidden)\n {\n name: \"g\",\n type: \"element\",\n attributes: {\n id: \"crosshair\",\n style: \"display: none\",\n },\n children: [\n {\n name: \"line\",\n type: \"element\",\n attributes: {\n id: \"crosshair-h\",\n y1: \"0\",\n y2: DEFAULT_SVG_SIZE.toString(),\n stroke: \"#666\",\n \"stroke-width\": \"0.5\",\n },\n },\n {\n name: \"line\",\n type: \"element\",\n attributes: {\n id: \"crosshair-v\",\n x1: \"0\",\n x2: DEFAULT_SVG_SIZE.toString(),\n stroke: \"#666\",\n \"stroke-width\": \"0.5\",\n },\n },\n {\n name: \"text\",\n type: \"element\",\n attributes: {\n id: \"coordinates\",\n \"font-family\": \"monospace\",\n \"font-size\": \"12\",\n fill: \"#666\",\n },\n children: [{ type: \"text\", value: \"\" }],\n },\n ],\n },\n // Mouse tracking script\n {\n name: \"script\",\n type: \"element\",\n children: [\n {\n type: \"text\",\n value: `\n document.currentScript.parentElement.addEventListener('mousemove', (e) => {\n const svg = e.currentTarget;\n const rect = svg.getBoundingClientRect();\n const x = e.clientX - rect.left;\n const y = e.clientY - rect.top;\n const crosshair = svg.getElementById('crosshair');\n const h = svg.getElementById('crosshair-h');\n const v = svg.getElementById('crosshair-v');\n const coords = svg.getElementById('coordinates');\n \n crosshair.style.display = 'block';\n h.setAttribute('x1', '0');\n h.setAttribute('x2', '${DEFAULT_SVG_SIZE}');\n h.setAttribute('y1', y);\n h.setAttribute('y2', y);\n v.setAttribute('x1', x);\n v.setAttribute('x2', x);\n v.setAttribute('y1', '0');\n v.setAttribute('y2', '${DEFAULT_SVG_SIZE}');\n\n // Calculate real coordinates using inverse transformation\n const matrix = ${JSON.stringify(matrix)};\n // Manually invert and apply the affine transform\n // Since we only use translate and scale, we can directly compute:\n // x' = (x - tx) / sx\n // y' = (y - ty) / sy\n const sx = matrix.a;\n const sy = matrix.d;\n const tx = matrix.e; \n const ty = matrix.f;\n const realPoint = {\n x: (x - tx) / sx,\n y: (y - ty) / sy // Flip y back since we used negative scale\n }\n \n coords.textContent = \\`(\\${realPoint.x.toFixed(2)}, \\${realPoint.y.toFixed(2)})\\`;\n coords.setAttribute('x', (x + 5).toString());\n coords.setAttribute('y', (y - 5).toString());\n });\n document.currentScript.parentElement.addEventListener('mouseleave', () => {\n document.currentScript.parentElement.getElementById('crosshair').style.display = 'none';\n });\n `,\n },\n ],\n },\n ],\n }\n\n // biome-ignore lint/suspicious/noExplicitAny: TODO\n return pretty(stringify(svgObject as any))\n}\n"],"mappings":"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","names":[]}
|
|
File without changes
|