In this post, I’ll share a simple tutorial on how to create some basic generative art that looks like it could have been inspired by Damien Hirst. At the end, you’ll have a script that generates an SVG directly in your browser.
Because SVGs are vector graphics, they can easily be scaled up an down without any loss of resolution. So, the units we choose are for defining relative proportion. I chose 24x15 since it roughly approximates the golden ratio.
<svg xmlns="http://www.w3.org/2000/svg" version="1.1"
viewbox="0 0 2400 1500">
</svg>
The main thing to note here is that the viewbox defines the
coordinates of the top left corner of your image and the aspect ratio. In this
case, the top left corner is defined as (0,0)
and with 2400 points in the
x-direction and 1500 points in the y-direction.
Next, you need to decide roughly how many dots you’d like to create.
Conceptually, I broke the image down into 100x100
squares that can each be
filled with a dot of a different color. Then, to make the image feel less
rigid, I added a little noise to the location of center of each circle.
<circle cx="150" cy="250" r="50" fill="#000000"
stroke="white" stroke-width="1" fill-opacity="1" />
To define an svg circle, you need to define the center coordinates and the radius of the circle. In addition, we’ll want to define the fill and stroke colors.
const blockSize = 100;
const xBlocks = 24;
const yBlocks = 15;
const strokeWidth = 5;
let res = `<svg xmlns="http://www.w3.org/2000/svg" version="1.1"
viewbox="0 0 ${xBlocks * blockSize} ${yBlocks * blockSize}">`;
function addNoise(radius) {
const rand = Math.floor(Math.random() * Math.floor(2 * radius));
return rand - Math.floor(radius);
}
function randomFillColor() {
// 16777215 is equivalent to #FFFFFF
return '#' + Math.floor(Math.random() * 16777215).toString(16);
}
function createCircle(cx, cy, radius, fill){
const args = `cx="${cx}" cy="${cy}" r="${radius}" fill="${fill}"`;
const stroke = `stroke="white" stroke-width="${strokeWidth}"`;
return `<circle ${args} ${stroke} fill-opacity="1" />`;
}
for (let i = 0; i < xBlocks; i++) {
for (let j = 0; j < yBlocks; j++) {
const radius = blockSize / 2;
const cx = (i * blockSize) + radius + addNoise(radius / 2);
const cy = (j * blockSize) + radius + addNoise(radius / 2);
const fill = randomFillColor();
res += createCircle(cx, cy, radius, fill);
}
}
res += "</svg>";
Putting all of this together requires nesting all of these circles inside the
svg
described above and then either saving that string to disk as a file or
adding it to an HTML page. Click here to see the javascript used
to create the image at the top of this post.
When I first put this together, I was surprised by how much joy I got from something so simple. I hope you try experimenting with your own generative art. I can’t wait to see what you create.