diff --git a/lib/react/SimpleGraphicsSVG.tsx b/lib/react/SimpleGraphicsSVG.tsx index 3a73f9f..4e3f3c8 100644 --- a/lib/react/SimpleGraphicsSVG.tsx +++ b/lib/react/SimpleGraphicsSVG.tsx @@ -30,16 +30,16 @@ export function SimpleGraphicsSVG({ graphics }: { graphics: GraphicsObject }) { for (const p of pts) consider(p.x, p.y) } for (const r of rects) { - const x = (r as any).x ?? 0 - const y = (r as any).y ?? 0 + const x = r.center.x - r.width / 2 + const y = r.center.y - r.height / 2 const w = (r as any).width ?? 0 const h = (r as any).height ?? 0 consider(x, y) consider(x + w, y + h) } for (const c of circles) { - const x = (c as any).x ?? 0 - const y = (c as any).y ?? 0 + const x = c.center.x + const y = c.center.y const rad = (c as any).radius ?? 1 consider(x - rad, y - rad) consider(x + rad, y + rad) @@ -74,12 +74,12 @@ export function SimpleGraphicsSVG({ graphics }: { graphics: GraphicsObject }) { {rects.map((r: any, i: number) => ( ))} @@ -97,11 +97,11 @@ export function SimpleGraphicsSVG({ graphics }: { graphics: GraphicsObject }) { {circles.map((c: any, i: number) => ( ))} diff --git a/tests/fallback-shapes.test.tsx b/tests/fallback-shapes.test.tsx new file mode 100644 index 0000000..04ed2f5 --- /dev/null +++ b/tests/fallback-shapes.test.tsx @@ -0,0 +1,69 @@ +import { expect, test } from "bun:test" +import type { GraphicsObject } from "graphics-debug" +import type { ReactElement } from "react" +import { SimpleGraphicsSVG } from "../lib/react/SimpleGraphicsSVG" + +const { + renderToStaticMarkup, +}: { + renderToStaticMarkup: (element: ReactElement) => string +} = require("react-dom/server") + +const render = (graphics: GraphicsObject) => + renderToStaticMarkup() + +test("fallback rectangles use their center and include their actual bounds", () => { + const svg = render({ + rects: [{ center: { x: 100, y: -50 }, width: 20, height: 10 }], + }) + + expect(svg).toContain('x="90" y="-55" width="20" height="10"') + expect(svg).toContain('viewBox="80 -65 40 30"') +}) + +test("fallback circles use their center and include their actual bounds", () => { + const svg = render({ + circles: [{ center: { x: -40, y: 70 }, radius: 5 }], + }) + + expect(svg).toContain('cx="-40" cy="70" r="5"') + expect(svg).toContain('viewBox="-55 55 30 30"') +}) + +test("the viewBox includes separated rectangles and circles", () => { + const svg = render({ + rects: [{ center: { x: 100, y: -50 }, width: 20, height: 10 }], + circles: [{ center: { x: -40, y: 70 }, radius: 5 }], + }) + + expect(svg).toContain('viewBox="-55 -65 175 150"') +}) + +test("fallback shapes use the fill and stroke fields from GraphicsObject", () => { + const svg = render({ + rects: [ + { + center: { x: 0, y: 0 }, + width: 20, + height: 10, + fill: "red", + stroke: "blue", + }, + ], + circles: [ + { center: { x: 40, y: 0 }, radius: 5, fill: "green", stroke: "purple" }, + ], + }) + + expect(svg).toContain('fill="red" stroke="blue"') + expect(svg).toContain('fill="green" stroke="purple"') +}) + +test("rectangles centered at the origin extend to both sides of it", () => { + const svg = render({ + rects: [{ center: { x: 0, y: 0 }, width: 20, height: 10 }], + }) + + expect(svg).toContain('x="-10" y="-5"') + expect(svg).toContain('viewBox="-20 -15 40 30"') +})