Solandra
A human friendly framework for creative coding with TypeScript
Start here
- Browse the examples. Each sketch includes its source code.
- Follow the getting started guide
- For coding assistants, add the API reference to your project.
- Or follow the tutorial below to build an animated sketch.
Slideshow
Use the arrow keys or click to change sketches.
Principles
I built Solandra to make sketches easy to change and experiment with. My essays describe the ideas behind it.
- Use TypeScript for autocomplete and type checking.
- Assume some JavaScript or TypeScript experience.
- Work with tiles, rows and shapes in drawing loops.
- Prioritise quick experimentation over rendering speed.
- Provide helpers for common tasks such as seeded randomness.
- Describe shapes with configuration objects and draw them with ordinary functions and loops.
Practice
Some of the practical implications:
- Sketches always have width 1, height depends on aspect ratio.
- Angles in radians.
- Points are [number, number].
- Colours in hsl(a).
- Describe curves by their size, direction and shape.
Tutorial
Build the animated logo above, starting with its background. Colours use HSL: hue (0–360), saturation (0–100) and lightness (0–100), with optional alpha (0–1) for opacity.
A sketch is a function that takes an SCanvas, called p in these examples.
p.background(220, 26, 14)Set a fill colour, then pass a shape to fill. To stroke its outline, use draw instead.
p.setFillColor(220, 54, 50)
p.fill(new Rect({ at: [0.2, 0.2], w: 0.6, h: 0.4 }))Points use [x, y] coordinates. Common options have short names, such as w for width.
Use forTiling to repeat the shape across a grid:
p.forTiling({ n: 10, type: "square", margin: 0.1 },
(at, [w, h], c, i) => {
p.setFillColor(150 + i * 5, 54, 50)
p.fill(new Rect({ at, w, h }))
})The configuration sets ten square tiles across, with a margin around the canvas.
The callback receives each tile's position, size, centre and index. Here, the index determines its colour.
Next, use forHorizontal to draw a row of polygons. It takes the same callback arguments as forTiling:
p.forHorizontal({ n: 8, margin: 0.1 }, (at, [w, h], c, i) => {
p.setFillColor(150 + i * 5, 54, 50)
p.fill(new RegularPolygon({ at: c, r: w / 3, n: i + 3 }))
})Use p.t, the time in seconds, to animate the polygons. Sine and cosine make their properties vary smoothly:
new RegularPolygon({
at: [c[0], c[1] + Math.cos(p.t + (i * Math.PI) / 8) * 0.2],
r: w / 3,
n: i + 3,
})Combine these steps to draw the animated logo:
p.background(220, 26, 14)
const { bottom, right, center } = p.meta
const d = Math.min(bottom, right) / 2.8
p.times(5, n => {
const sides = 10 - n
const r = d - n * 0.16 * d + (1 + Math.cos(p.t)) / 40
p.setFillColor(220, 70, 10 + n * 12)
p.fill(new RegularPolygon({
at: center,
n: sides,
r,
}))
})Examples
Explore more sketches and their source code:
Other Platforms
Versions of Solandra are available on other platformsSolandra was made by James Porter.
Check out the GitHub page or install with npm i solandra