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: