Canvas: Julia Fractal Animation

on in Canvas
Last modified on

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.

JavaScript Canvas Logo

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!

Related posts