cetz
cetz copied to clipboard
Function for scaling children to a fixed bounding box
It would be nice to have something like set-viewport
, which scales its children to a fixed AABB by measuring their bounding box and scaling their coordinates afterward (what plot.plot des, but for normal elements).
CeTZ 0.1.2 POC:
#let scale-up(body, size: (10, 10, 1)) = {
((
children: body,
finalize-children: (ctx, children) => {
let low = none
let high = none
for c in children {
for b in c.bounds {
if low == none {
low = b
} else {
low = (
calc.min(low.at(0), b.at(0)),
calc.min(low.at(1), b.at(1)),
calc.min(low.at(1), b.at(1)), 1)
}
if high == none {
high = b
} else {
high = (
calc.max(high.at(0), b.at(0)),
calc.max(high.at(1), b.at(1)),
calc.max(high.at(1), b.at(1)), 1)
}
}
}
let m = cetz.matrix.transform-scale((x: size.at(0) / (high.at(0) - low.at(0)),
y: -size.at(1) / (high.at(1) - low.at(1))))
children = children.map(c => {
c.segments = c.segments.map(s => {
for i in range(1, s.len()) {
s.at(i) = cetz.matrix.mul-vec(m, cetz.vector.as-vec(s.at(i), init: (0,0,0,1)))
}
return s
})
return c
})
return children
}
),)
}
#cetz.canvas({
import cetz.draw: *
import cetz.plot
let sx = 13
let sy = 10
rect((0,0), (sx, sy), stroke: red)
scale-up({
circle((1,-1))
catmull((0,0), (2, -2), (4, 0))
}, size: (sx, sy, 1))
})