I would like to create an animated Mandelbrot visualization using JavaScript on an HTML5 <canvas> element. The Mandelbrot set, popularized by BenoĆ®t Mandelbrot, is the set of complex numbers that remain bounded under the function zn+1 = zn2 + c. This is known as an escape function; that is, regardless of the size of n, zn never “escapes”. Computing the Mandelbrot set can be as computationally complex as desired for a given visualization.
In JavaScript, the escape function can be written as follows:
Mandelbrot.prototype.escapeFunc = function(x, y) {
r = 0.0; i = 0.0; m = 0.0;
j = 0;
while ((j < this.max) && (m < 4.0)) {
j++;
m = r * r - i * i;
i = 2.0 * r * i + y;
r = m + x;
}
return j;
}
For a given HTML5 canvas element, such as
<canvas id="mandelbrot" width="512" height="512">
A Manelbrot set over the complex plane can be represented with the follow object
function Mandelbrot(m) {
this.m = m;
this.c = m.getContext("2d");
this.width = m.width;
this.height = m.height;
this.SX = -1.75; // start value real
this.EX = 0.6; // end value real
this.SY = -1.125; // start value imaginary
this.EY = 1.125; // end value imaginary
this.xzoom = (this.EX - this.SX) / (this.width*1.0);
this.yzoom = (this.EY - this.SY) / (this.height*1.0);
}
Given these functions, rendering a Mandelbrot set on an HTML5 canvas element is as simple as looping through each of the pixels of the canvas, calculating the escape value, and drawing the pixel. Here is a simple render function:
Mandelbrot.prototype.render = function() {
var prev_h = 0;
for (var x = 0; x < this.width; x=x+1) {
for (var y = 0; y < this.height; y=y+1) {
esc = this.escapeFunc(this.SX + x*this.xzoom, this.SY + y*this.yzoom);
h = 360 * (esc/this.max)
if (h != prev_h) {
perc = Math.floor(100*(h/360))
this.c.fillStyle='hsla('+ h + ','+ (perc+100) +'%,'+ (60-perc) +'%,'+ this.opacity +')';
prev_h = h;
}
this.c.fillRect(x,y,1,1);
}
}
}
If you have an HTML5 compatible browser you should see an animated example below: