Skip to content

Commit 6197e36

Browse files
committed
Add debug shapes to preview SVG
1 parent 7aa2062 commit 6197e36

1 file changed

Lines changed: 90 additions & 37 deletions

File tree

src/preview.tsx

Lines changed: 90 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,36 @@
1+
import React from 'react'
12
import { getBoundariesFromPattern } from './functions'
23
import { State } from './types'
34

4-
export const Preview: React.FC<{ state: State }> = ({ state }) => {
5-
const viewBox = (() => {
6-
let xMin = 0
7-
let xMax = 1
8-
let yMin = 0
9-
let yMax = 1
10-
11-
// Make sure that default viewBox contains entire pattern
12-
for (const p of state.patterns) {
13-
const b = getBoundariesFromPattern(p)
14-
15-
xMin = Math.min(xMin, b.xMin)
16-
xMax = Math.max(xMax, b.xMax)
17-
yMin = Math.min(yMin, b.yMin)
18-
yMax = Math.max(yMax, b.yMax)
19-
}
20-
21-
// Add some spacing around the bounding box
22-
xMin -= 0.1
23-
xMax += 0.1
24-
yMin -= 0.1
25-
yMax += 0.1
26-
27-
return `${xMin} ${yMin} ${xMax - xMin} ${yMax - yMin}`
28-
})()
5+
function getViewBox(state: State): string {
6+
let xMin = 0
7+
let xMax = 1
8+
let yMin = 0
9+
let yMax = 1
10+
11+
// Make sure that default viewBox contains entire pattern
12+
for (const p of state.patterns) {
13+
const b = getBoundariesFromPattern(p)
14+
15+
xMin = Math.min(xMin, b.xMin)
16+
xMax = Math.max(xMax, b.xMax)
17+
yMin = Math.min(yMin, b.yMin)
18+
yMax = Math.max(yMax, b.yMax)
19+
}
20+
21+
// Add some spacing around the bounding box
22+
xMin -= 0.1
23+
xMax += 0.1
24+
yMin -= 0.1
25+
yMax += 0.1
26+
27+
return `${xMin} ${yMin} ${xMax - xMin} ${yMax - yMin}`
28+
}
2929

30+
export const Preview: React.FC<{ state: State }> = ({ state }) => {
3031
return (
3132
<div className='border-1 border-amber-300 aspect-square'>
32-
<svg viewBox={viewBox} xmlns='http://www.w3.org/2000/svg' className='w-full aspect-square'>
33+
<svg viewBox={getViewBox(state)} xmlns='http://www.w3.org/2000/svg' className='w-full aspect-square'>
3334
<rect
3435
className='stroke-amber-100'
3536
vectorEffect='non-scaling-stroke'
@@ -43,18 +44,70 @@ export const Preview: React.FC<{ state: State }> = ({ state }) => {
4344
{state.patterns.map((p, i) => {
4445
const { xMin, xMax, yMin, yMax } = getBoundariesFromPattern(p)
4546

47+
const width = xMax - xMin
48+
const height = yMax - yMin
49+
4650
return (
47-
<rect
48-
key={i}
49-
className='stroke-amber-100'
50-
vectorEffect='non-scaling-stroke'
51-
fill='none'
52-
strokeWidth='1px'
53-
x={xMin.toFixed(3)}
54-
y={yMin.toFixed(3)}
55-
width={(xMax - xMin).toFixed(3)}
56-
height={(yMax - yMin).toFixed(3)}
57-
/>
51+
<React.Fragment key={i}>
52+
<rect
53+
className='stroke-amber-100'
54+
vectorEffect='non-scaling-stroke'
55+
fill='none'
56+
strokeWidth='1px'
57+
x={xMin.toFixed(3)}
58+
y={yMin.toFixed(3)}
59+
width={width.toFixed(3)}
60+
height={height.toFixed(3)}
61+
/>
62+
{/* Partial line from anchor to target in order to show the direction */}
63+
{(() => {
64+
const [anchorX, anchorY] = p.anchor
65+
const [targetX, targetY] = p.target
66+
67+
const x1 = anchorX
68+
const y1 = anchorY
69+
const x2 = targetX - (targetX - anchorX) * 0.5
70+
const y2 = targetY - (targetY - anchorY) * 0.5
71+
72+
return (
73+
<line
74+
className='stroke-amber-100'
75+
vectorEffect='non-scaling-stroke'
76+
strokeWidth='1px'
77+
x1={x1.toFixed(3)}
78+
y1={y1.toFixed(3)}
79+
x2={x2.toFixed(3)}
80+
y2={y2.toFixed(3)}
81+
/>
82+
)
83+
})()}
84+
{/* Click surfaces for rotation and resizing actions */}
85+
{[
86+
// top left
87+
{ x: xMin, y: yMin, rotation: 0 },
88+
// top right
89+
{ x: xMax, y: yMin, rotation: 90 },
90+
// bottom right
91+
{ x: xMax, y: yMax, rotation: 180 },
92+
// bottom left
93+
{ x: xMin, y: yMax, rotation: 270 },
94+
].map(({ x, y, rotation }, j) => {
95+
const r_handle = 0.05 // Radius of the handle
96+
97+
// Define the base handle shape (for top-left corner)
98+
// This creates a quarter-circle arc pointing outward from the corner
99+
const basePathD = `M 0 0 L -${r_handle} 0 A ${r_handle} ${r_handle} 0 0 1 0 -${r_handle} Z`
100+
101+
return (
102+
<g
103+
key={`corner-handle-${i}-${j}`}
104+
transform={`translate(${x.toFixed(3)}, ${y.toFixed(3)}) rotate(${rotation})`}
105+
>
106+
<path d={basePathD} className='fill-slate-400 hover:fill-blue-600 cursor-grab' />
107+
</g>
108+
)
109+
})}
110+
</React.Fragment>
58111
)
59112
})}
60113
</svg>

0 commit comments

Comments
 (0)