Gaul is a generative art library. It was originally part of Sketchy, but I separated the non-gui parts and put them in gaul. The main reason for this is to make it easy to containerize generative art applications.
Gaul ships its own small 2D renderer in the render subpackage, with two
backends behind one drawing API:
- Raster — anti-aliased rasterizer (built on
freetype/raster) writing PNG - SVG — native vector output with true stroked paths and beziers, suitable for pen plotting
Coordinates are always pixels: origin top-left, x right, y down.
A render.Context fans out to any number of backends, so one drawing pass can
produce both a PNG and an SVG:
ras := render.NewRaster(800, 600)
svg := render.NewSVG(800, 600)
ctx := render.NewContext(ras, svg)
// ... draw ...
ras.SavePNG("out.png")
svg.Save("out.svg")Two more backends/features round this out: render.NewRecorder(w, h) records a
frame's draw operations and replays them later into any renderer
(rec.Replay(dst)), so a frame can be exported exactly as drawn without
re-running the drawing code. And Raster.SetScale(k) renders logical
coordinates into a k-times larger image — geometry, stroke widths, dashes, and
text all scale uniformly — for supersampled exports or fast low-resolution
previews.
Two drawing styles are supported and can be mixed freely.
Processing-style immediate mode, using the context's transform stack:
ctx.SetFillColor(color.White)
ctx.Push()
ctx.Translate(400, 300)
ctx.Rotate(gaul.Pi / 4)
ctx.DrawRectangle(-50, -50, 100, 100)
ctx.Fill()
ctx.Pop()Primitive-first, where geometry is constructed and transformed independently
(e.g. with Affine2D) and only drawn at the last minute:
tri := gaul.Triangle{A: a, B: b, C: c}
xform := gaul.Mult(
gaul.NewAffine2DWithTranslation(400, 300),
gaul.NewAffine2DWithRotation(gaul.Pi/4),
)
curve := xform.TransformCurve(tri.ToCurve())
curve.Draw(ctx)