While working on my Canvas Bots project, I experimented a lot with Canvas generative art. There’s a lot of potential there, and each and every visualization has hundreds of variations. This canvas animation series will feature one visualization/variation per article, along with tips and tricks on how to modify it.
This article is part of the JavaScript Canvas series where I post experiments, JavaScript generative art, visualizations, Canvas animations, code snippets and how-to’s.
The first visualization is a Julia fractal animation. I won’t go into maths details or break down the code.
Here’s the JavaScript code:
document.addEventListener('DOMContentLoaded', () => {
let canvas = document.getElementById('canvas'),
ctx = canvas.getContext('2d'),
t = 0,
draw,
julia;
julia = function (d1, d2) {
let a,
b,
an,
bn,
r,
c,
i,
x,
y,
red = 0,
green = 0,
blue = 0,
width = canvas.width,
height = canvas.height,
left = -1,
right = 1,
up = (((right - left) / width) * height) / 2,
down = (((left - right) / width) * height) / 2,
stepX = (right - left) / width,
stepY = (up - down) / height,
index = 0,
imageData;
ctx.clearRect(0, 0, width, height);
ctx.transform(
width / (right - left),
0,
0,
-height / (up - down),
(width * left) / (left - right),
(height * down) / (down - up)
);
imageData = ctx.createImageData(width, height);
for (y = down, r = 0; y < up; y += stepY, r++) {
for (x = left, c = 0; x < right; x += stepX, c++) {
a = x;
b = y;
for (i = 0; i <= 100; i++) {
an = a * a - b * b + d1;
bn = 2 * a * b + d2;
a = an;
b = bn;
if (a >= 2 || b >= 2) {
red = (12 * i + i) % 128;
green = (16 * i + i) % 0;
blue = (20 * i + i) % 196;
break;
}
}
if (a < 2 && b < 2) {
red = 128;
green = 0;
blue = 196;
}
imageData.data[index++] = red;
imageData.data[index++] = green;
imageData.data[index++] = blue;
imageData.data[index++] = 255;
}
}
ctx.putImageData(imageData, 0, 0);
};
draw = function () {
t += 0.005;
julia(Math.cos(t) * 0.8, Math.sin(t) * 0.8);
};
setInterval(draw, 24);
});
In my case, I played with the colours to get a nice, purple tint. I have also played with the speed of the function, and settled to a value of 0.005
for a smooth transition.
Give it a whirl!