Updated version of my mandelbrot zoomer : you can now specify the zoom depth (2^choice), the window size in pixels (square) & the zoom coordinates.
c=document.getElementById("c"),d=prompt,e=d("Zoom Depth(30 on fast cpu)","8"),f=c.width=c.height=2*d("Size(in pixels)","256"),g=c.getContext("2d");g.fillStyle="#FFF";g.fillRect(0,0,f,f);g.font="10px Arial";h=parseFloat(d("x","-1.768573656")),k=parseFloat(d("y","-0.000964296")),l=[];for(i=0;i<e;i++)l[i]=g.getImageData(0,0,f,f).data;m=g.getImageData(0,0,f,f),n=m.data,p=2,r=s=0,A=l[0];B(1,A);D();g.fillText("Computing",8,8);setTimeout(E,500);function E(){g.fillText(e-r,(r&7)*16+8,32+(r&248));B(1<<r,l[r]);if(++r<e)setTimeout(E,500);else tm=setInterval(D,30)}function B(C,q){for(y=o=0;y<f;y++)for(x=0;x<f;x++,o+=4){a=(2*x/f-1)/C+h;b=(2*y/f-1)/C+k;for(j=v=w=0;++j<512&&(z=v*v)+(u=w*w)<4;){w=2*v*w+b;v=z-u+a}j&=511;q[o]=j&255;q[o+2]=j*2&255;q[o+1]=j*2/3&255}}function D(){t=~~(p*256);a=v=w=(512-t)*f/4;o=0;for(y=f/2;--y;w+=t,o+=f*2){x=f/2;for(v=a;x--;v+=t,o+=4){u=(w>>8)*f+(v>>8)<<2;n[o]=A[u];n[o+1]=A[u+1];n[o+2]=A[u+2]}}g.putImageData(m,0,0);g.fillText("x"+(1<<s)*(3-p),8,f/2-16);p*=0.99;if(p<1){p++;if(++s==e)s=0;A=l[s]}};
Yz1kb2N1bWVudC5nZXRFbGVtZW50QnlJZCgiYyIpLGQ9cHJvbXB0LGU9ZCgiWm9vbSBEZXB0aCgzMCBvbiBmYXN0IGNwdSkiLCI4IiksZj1jLndpZHRoPWMuaGVpZ2h0PTIqZCgiU2l6ZShpbiBwaXhlbHMpIiwiMjU2IiksZz1jLmdldENvbnRleHQoIjJkIik7Zy5maWxsU3R5bGU9IiNGRkYiO2cuZmlsbFJlY3QoMCwwLGYsZik7Zy5mb250PSIxMHB4IEFyaWFsIjtoPXBhcnNlRmxvYXQoZCgieCIsIi0xLjc2ODU3MzY1NiIpKSxrPXBhcnNlRmxvYXQoZCgieSIsIi0wLjAwMDk2NDI5NiIpKSxsPVtdO2ZvcihpPTA7aTxlO2krKylsW2ldPWcuZ2V0SW1hZ2VEYXRhKDAsMCxmLGYpLmRhdGE7bT1nLmdldEltYWdlRGF0YSgwLDAsZixmKSxuPW0uZGF0YSxwPTIscj1zPTAsQT1sWzBdO0IoMSxBKTtEKCk7Zy5maWxsVGV4dCgiQ29tcHV0aW5nIiw4LDgpO3NldFRpbWVvdXQoRSw1MDApO2Z1bmN0aW9uIEUoKXtnLmZpbGxUZXh0KGUtciwociY3KSoxNis4LDMyKyhyJjI0OCkpO0IoMTw8cixsW3JdKTtpZigrK3I8ZSlzZXRUaW1lb3V0KEUsNTAwKTtlbHNlIHRtPXNldEludGVydmFsKEQsMzApfWZ1bmN0aW9uIEIoQyxxKXtmb3IoeT1vPTA7eTxmO3krKylmb3IoeD0wO3g8Zjt4Kyssbys9NCl7YT0oMip4L2YtMSkvQytoO2I9KDIqeS9mLTEpL0Mraztmb3Ioaj12PXc9MDsrK2o8NTEyJiYoej12KnYpKyh1PXcqdyk8NDspe3c9Mip2KncrYjt2PXotdSthfWomPTUxMTtxW29dPWomMjU1O3FbbysyXT1qKjImMjU1O3FbbysxXT1qKjIvMyYyNTV9fWZ1bmN0aW9uIEQoKXt0PX5+KHAqMjU2KTthPXY9dz0oNTEyLXQpKmYvNDtvPTA7Zm9yKHk9Zi8yOy0teTt3Kz10LG8rPWYqMil7eD1mLzI7Zm9yKHY9YTt4LS07dis9dCxvKz00KXt1PSh3Pj44KSpmKyh2Pj44KTw8MjtuW29dPUFbdV07bltvKzFdPUFbdSsxXTtuW28rMl09QVt1KzJdfX1nLnB1dEltYWdlRGF0YShtLDAsMCk7Zy5maWxsVGV4dCgieCIrKDE8PHMpKigzLXApLDgsZi8yLTE2KTtwKj0wLjk5O2lmKHA8MSl7cCsrO2lmKCsrcz09ZSlzPTA7QT1sW3NdfX07
//get canvas context
var canvasMandel = document.getElementById("c");
//get zoom param
var P=prompt;
var zoom_depth=P("Zoom Depth(30 on fast cpu)","8");
var fxsize = canvasMandel.width = canvasMandel.height = 2*P("Size(in pixels)","256");//have to be square!!
var ctxMand = canvasMandel.getContext("2d");
// clear canvas & set up font
ctxMand.fillStyle = '#FFF';
ctxMand.fillRect(0, 0, fxsize, fxsize);
ctxMand.font="10px Arial";
//get zoom param
var cx=parseFloat(P("x","-1.768573656"));
var cy=parseFloat(P("y","-0.000964296"));
//cx=-1.768573656;
//cy=-0.000964296;
// Init buffers
var imageFrac=[];
for (i = 0; i < zoom_depth;i++) imageFrac[i]=ctxMand.getImageData(0,0,fxsize, fxsize).data;
var imageRendMand = ctxMand.getImageData(0,0,fxsize, fxsize);
var dataRendMand = imageRendMand.data;
//init global var & start
var zoomf=2;
var zmf=0;
var ir=0;
var cd=imageFrac[0];
computeFrac(1,cd);
renderMandel();
ctxMand.fillText("Computing",8,8);
setTimeout(computeStuff,500);
// compute images used for the zoom
function computeStuff() {
ctxMand.fillText(zoom_depth-zmf,(zmf&7)*16 + 8,32+(zmf&248));
computeFrac(1<<zmf,imageFrac[zmf]);
if (++zmf<zoom_depth) setTimeout(computeStuff,500);
else tm=setInterval(renderMandel,30);
}
// draw a fractal at a given zoom factor
//
function computeFrac(zmfact,dt) {
o=0;
for (y = 0; y < fxsize;y++)
for (x = 0; x < fxsize;x++,o+=4) {
a=(2*x/fxsize-1)/zmfact + cx;
b=(2*y/fxsize-1)/zmfact + cy;
j=v=w=0;
while ((++j<512)&&((z=v*v)+(u=w*w)<4)) {
w=2*v*w+b;
v=z-u+a;
}
j&=511;
dt[o]=j&255;
dt[o+2]=(j*2)&255;
dt[o+1]=(j*2/3)&255;
}
}
// zoom between precomputed images
function renderMandel() {
//now do the zoom
t=~~(zoomf*256);
a=v=w=(512-t)*fxsize/4;
for (o=0,y=fxsize/2;--y;w+=t,o+=fxsize*2)
for (x=fxsize/2,v=a;x--;v+=t,o+=4) {
u=(w>>8)*fxsize + (v>>8) <<2;
dataRendMand[o]=cd[u];
dataRendMand[o+1]=cd[u+1];
dataRendMand[o+2]=cd[u+2];
}
ctxMand.putImageData(imageRendMand,0,0);
ctxMand.fillText("x"+(1<<(ir))*(3-zoomf),8,fxsize/2-16);
zoomf*=0.99;
if (zoomf<1) {
zoomf++;
if (++ir==zoom_depth) ir=0;
cd=imageFrac[ir];
}
}