Slideshow
Use Arrow keys or click to navigate
Principles
Opinionated, agile (code is easy to change) framework for algorithmic art. See my essays for research/plans that went into this.
- Leverage TypeScript: you shouldn't need to learn much, autocomplete and type checking should have your back.
- Not for beginners.
- Control flow at level of drawing (tiling, partitions etc).
- Performance is not the goal.
- Common algorithmic art things (e.g. randomness) should be easy.
- Should feel fun/powerful.
- Life is too short to compile things.
- Rethink standard APIs
- Declarative when possible (especially anything configuration-y), procedural when pragmatic; make it easy to explore/change your mind.
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).
- Novel curve drawing API, as standard bezier curve APIs make absolutely no sense for humans to think about.
Tutorial
Let's make the animated logo thing above to learn about how to use Solandra. Let's start with the background. The only way to do colours in Solandra is via HSL(A). Hue (0-360), Saturation (0-100) and Brightness (0-100). Oh and alpha (0-1). RGB is for computers not for you.
Every sketch is just a function on the main Solandra object (here called p). So we get friendly autocompletion.
p.background(220, 26, 14)
That's a bit boring. Let's draw something. First we set a fill colour. Then we use a fill call (to draw lines use draw instead). Solandra comes with loads of standard built in shapes, with clear, declarative APIs (you describe the shape).
p.setFillColor(220, 54, 50)
p.fill(new Rect({ at: [0.2, 0.2], w: 0.6, h: 0.4 }))
What did we learn? Points are always of the form: [x,y]. We use short names for common things (like width, w).
Let's draw many shapes. But we'll make the computer do the hard bit. What if we could just ask it to tile our canvas? We can.
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 }))
})
First we configure out tiling: 10 tiles across, square shape. Let's add a margin (that would be really tedious by hand).
Now let's use our tiling. That's a lot of arguments. But it doesn't matter. TypeScript keeps track of them. They are the position, tile size, tile centre and iteration count. We'll use the last one to pick a colour.
Let's draw polygons instead. Instead of tiling, let's move across our canvas. The API is basically the same. Configuration goes first (we can then easily tweak it).
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 }))
})
We need one more thing before we can finish our drawing: time. But it is really easy, usually just p.t gives the time in seconds. We throw in some trigonometric stuff to make look more organic and:
new RegularPolygon({
at: [c[0], c[1] + Math.cos(p.t + (i * Math.PI) / 8) * 0.2],
r: w / 3,
n: i + 3,
})
Okay so let's put everything together and draw our 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
This website has loads of examples of using Solandra, all with 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