The Mandelbrot fractal zoom in JavaScript



I had a lot of positive feedback after my previous tutorial and many requests for the zoom functionality.
Here it is - after clicking on the image, the area above and to the right of the cursor is magnified by the factor of 2.
It's not the most intuitive way to zoom, but I tried to reuse most of the code from the original version and still keep it relatively short and simple. Have fun exploring!

Click here to see it in action!

Here are the comments to the updates to the code:

<html>
<body>
<canvas id="myCanvas" width="800" height="800"></canvas><br>
<script>
var xmin=-2,ymin=-2,scale=50;
New variables that represent the bottom left corner of the plotted area and the scale

var x,y,i,xt;
var cx,cy;
var color;
var canvas = document.getElementById('myCanvas');
canvas.addEventListener("mousedown",zoom,false);
The function 'mousedown' will be triggered by clicking on the Canvas.

var context = canvas.getContext('2d');
mandel();
A call to the new function 'mandel()' to draw the first image.

function zoom(event)
        {
                xmin=xmin+Math.floor(event.pageX/4)/scale;
                ymin=-Math.floor(event.pageY/4)/scale+200/scale+ymin;
This is the heart and soul of the zoom functionality - we convert the mouse screen coordinates and to complex coordinates and set the bottom left corner of the area there.

                scale=scale*2;
                mandel();
        }
Now we increase the scale to zoom in and call the 'mandel()' function to redraw the image using updated coordinates and scale.

function mandel()
This is exactly the same code as previously, except now it's wrapped in a function, so that we can call it multiple times.

        {
                for(x=0;x<200;x++)
                {
                        for(y=0;y<200;y++)
                        {
                                i=0;
                                cx=xmin+x/scale;
                                cy=ymin+y/scale;
                                zx=0;
                                zy=0;                        

                                do
                                {
                                        xt=zx*zy;
                                        zx=zx*zx-zy*zy+cx;
                                        zy=2*xt+cy;
                                        i++;
                                }
                                while(i<255&&(zx*zx+zy*zy)<4);

                                color=i.toString(16);
                                context.beginPath();
                                context.rect(x*4, 800-y*4, 4, 4);
                                context.fillStyle ='#'+color+color+color;
                                context.fill();
                        }
                }
        }

</script>
</body>
</html>

And the full code (without comments) that you can copy and paste:

<html>
<body>
<canvas id="myCanvas" width="800" height="800"></canvas><br>
<script>
var xmin=-2,ymin=-2,scale=50;
var x,y,i,xt;
var cx,cy;
var color;
var canvas = document.getElementById('myCanvas');
canvas.addEventListener("mousedown",zoom,false);
var context = canvas.getContext('2d');
mandel();
function zoom(event)
        {
                xmin=xmin+Math.floor(event.pageX/4)/scale;
                ymin=-Math.floor(event.pageY/4)/scale+200/scale+ymin;
                scale=scale*2;
                mandel();
        }

function mandel()
        {
                for(x=0;x<200;x++)
                {
                        for(y=0;y<200;y++)
                        {
                                i=0;
                                cx=xmin+x/scale;
                                cy=ymin+y/scale;
                                zx=0;
                                zy=0;                        

                                do
                                {
                                        xt=zx*zy;
                                        zx=zx*zx-zy*zy+cx;
                                        zy=2*xt+cy;
                                        i++;
                                }
                                while(i<255&&(zx*zx+zy*zy)<4);

                                color=i.toString(16);
                                context.beginPath();
                                context.rect(x*4, 800-y*4, 4, 4);
                                context.fillStyle ='#'+color+color+color;
                                context.fill();
                        }
                }
        }

</script>
</body>
</html>

The Minesweeper game in 80 lines of Javascript

Your first program in JavaScript: you need 5 minutes and a notepad

Tutorial - interactive, animated sprites in JavaScript