Another Mandelbrot fractal stuff, but this time with 'realtime' zoom. A bit slow to start, but after having clicked on the spot you want to zoom, will zoom smoothly from x1 to x65536.
d=document,f=d.getElementById("c"),g=f.width=f.height=512,h=f.getContext("2d");h.fillRect(0,0,g,g);h.fillStyle="#FFF";d.onclick=function(e){if(st){clearInterval(tm);k()}else{st=1;mX=(e.layerX?e.layerX:e.offsetX)-f.offsetLeft;mY=(e.layerY?e.layerY:e.offsetY)-f.offsetTop;cx=2*mX/g-1.5;cy=2*mY/g-1;for(i=-1;++i<16;)m(1<<i,n[i]);tm=setInterval(p,30)}};n=[];for(i=-1;++i<16;)n[i]=h.getImageData(0,0,g,g).data;q=h.getImageData(0,0,g,g),r=q.data;function m(e,l){o=0;for(y=-1;++y<g;)for(x=-1;++x<g;){a=(2*x/g-1)/e+cx;b=(2*y/g-1)/e+cy;for(j=v=w=0;++j<256&&(z=v*v)+(u=w*w)<4;){w=2*v*w+b;v=z-u+a}j&=255;l[o]=j*7&255;l[o+2]=j*5&255;l[o+1]=j*3&255;o+=4}}function p(){t=256+c;b=a=(512-t)*128;o=0;for(y=g/2;--y;a+=t)for(w=2;w--;){x=g/2;for(v=b;x--;v+=t,o+=8){u=(a>>8)*g+(v>>8)<<2;r[o+4]=r[o]=cd[u];r[o+5]=r[o+1]=cd[u+1];r[o+6]=r[o+2]=cd[u+2]}}c-=4;h.putImageData(q,0,0);h.fillText(st?"CLICK>RESET/x"+(1<<(ir&15))*(2-c/256):"CLICK>ZOOM(&wait)",9,9);if(!c){c=256;cd=n[++ir&15]}}function k(){c=256;cy=st=ir=0;cx=-0.5;cd=n[0];m(1,cd);p()}k();
ZD1kb2N1bWVudCxmPWQuZ2V0RWxlbWVudEJ5SWQoImMiKSxnPWYud2lkdGg9Zi5oZWlnaHQ9NTEyLGg9Zi5nZXRDb250ZXh0KCIyZCIpO2guZmlsbFJlY3QoMCwwLGcsZyk7aC5maWxsU3R5bGU9IiNGRkYiO2Qub25jbGljaz1mdW5jdGlvbihlKXtpZihzdCl7Y2xlYXJJbnRlcnZhbCh0bSk7aygpfWVsc2V7c3Q9MTttWD0oZS5sYXllclg/ZS5sYXllclg6ZS5vZmZzZXRYKS1mLm9mZnNldExlZnQ7bVk9KGUubGF5ZXJZP2UubGF5ZXJZOmUub2Zmc2V0WSktZi5vZmZzZXRUb3A7Y3g9MiptWC9nLTEuNTtjeT0yKm1ZL2ctMTtmb3IoaT0tMTsrK2k8MTY7KW0oMTw8aSxuW2ldKTt0bT1zZXRJbnRlcnZhbChwLDMwKX19O249W107Zm9yKGk9LTE7KytpPDE2OyluW2ldPWguZ2V0SW1hZ2VEYXRhKDAsMCxnLGcpLmRhdGE7cT1oLmdldEltYWdlRGF0YSgwLDAsZyxnKSxyPXEuZGF0YTtmdW5jdGlvbiBtKGUsbCl7bz0wO2Zvcih5PS0xOysreTxnOylmb3IoeD0tMTsrK3g8Zzspe2E9KDIqeC9nLTEpL2UrY3g7Yj0oMip5L2ctMSkvZStjeTtmb3Ioaj12PXc9MDsrK2o8MjU2JiYoej12KnYpKyh1PXcqdyk8NDspe3c9Mip2KncrYjt2PXotdSthfWomPTI1NTtsW29dPWoqNyYyNTU7bFtvKzJdPWoqNSYyNTU7bFtvKzFdPWoqMyYyNTU7bys9NH19ZnVuY3Rpb24gcCgpe3Q9MjU2K2M7Yj1hPSg1MTItdCkqMTI4O289MDtmb3IoeT1nLzI7LS15O2ErPXQpZm9yKHc9Mjt3LS07KXt4PWcvMjtmb3Iodj1iO3gtLTt2Kz10LG8rPTgpe3U9KGE+PjgpKmcrKHY+PjgpPDwyO3Jbbys0XT1yW29dPWNkW3VdO3Jbbys1XT1yW28rMV09Y2RbdSsxXTtyW28rNl09cltvKzJdPWNkW3UrMl19fWMtPTQ7aC5wdXRJbWFnZURhdGEocSwwLDApO2guZmlsbFRleHQoc3Q/IkNMSUNLPlJFU0VUL3giKygxPDwoaXImMTUpKSooMi1jLzI1Nik6IkNMSUNLPlpPT00oJndhaXQpIiw5LDkpO2lmKCFjKXtjPTI1NjtjZD1uWysraXImMTVdfX1mdW5jdGlvbiBrKCl7Yz0yNTY7Y3k9c3Q9aXI9MDtjeD0tMC41O2NkPW5bMF07bSgxLGNkKTtwKCl9aygpOw==
var doc = document;
var canvas = doc.getElementById("c");
var fxsize = canvas.width = canvas.height = 512;//have to be square!!
// Paint the canvas opaque black (fillStyle should be "black" by default).
var ctx = canvas.getContext("2d");
ctx.fillRect(0, 0, fxsize, fxsize);
ctx.fillStyle = '#FFF';
function mafunc(e) {
if (st) {clearInterval(tm);startMsgMandel();}
else {
st=1;
mX=(e.layerX?e.layerX:e.offsetX)-canvas.offsetLeft;
mY=(e.layerY?e.layerY:e.offsetY)-canvas.offsetTop;
cx=2*mX/fxsize-1.5;
cy=2*mY/fxsize-1;
for (i=-1;++i<16;) computeFrac(1<<i,imageFrac[i]);
tm=setInterval(renderMandel,30);
//ctx.fillText("Plz Wait",8,8);
// setTimeout(computeStuff,99);
}
}
doc.onclick=mafunc;
var imageFrac=[];
for (i = -1; ++i < 16;) imageFrac[i]=ctx.getImageData(0,0,fxsize, fxsize).data;
var imageRend = ctx.getImageData(0,0,fxsize, fxsize);
var dataRend = imageRend.data;
//doc.body.style.background = "#000";
function computeFrac(zmfact,dt) {
o=0;
for (y = -1; ++y < fxsize;)
for (x = -1; ++x < fxsize;) {
a=(2*x/fxsize-1)/zmfact + cx;
b=(2*y/fxsize-1)/zmfact + cy;
j=v=w=0;
while ((++j<256)&&((z=v*v)+(u=w*w)<4)) {
w=2*v*w+b;
v=z-u+a;
}
j&=255;
dt[o]=(j*7)&255;
dt[o+2]=(j*5)&255;
dt[o+1]=(j*3)&255;
o+=4;
}
}
function renderMandel() {
//now do the zoom
t=256+c; //fixed point .8
// b=a=(512-t)*fxsize/4;
b=a=(512-t)*128;
o=0;
for (y=fxsize/2;--y;a+=t)
for(w=2;w--;)
for (x=fxsize/2,v=b;x--;v+=t,o+=8) {
u=(a>>8)*fxsize + (v>>8) <<2;
dataRend[o+4]=dataRend[o]=cd[u];
dataRend[o+5]=dataRend[o+1]=cd[u+1];
dataRend[o+6]=dataRend[o+2]=cd[u+2];
}
c-=4;
ctx.putImageData(imageRend, 0,0);
//ctx.fillText("MandelFun/Yoyofr- x"+(((1<<ir)*c+(1<<(ir+1))*(c^255))>>8), fxsize-150, fxsize-20);
// ctx.fillText(st?"CLICK to RESET":"CLICK to ZOOM (& wait...)",9,9);
ctx.fillText(st?"CLICK>RESET/x"+(1<<(ir&15))*(2-c/256):"CLICK>ZOOM (&wait)",9,9);
if (!c) {
c=256;
// if (++ir==9) ir=0;
cd=imageFrac[++ir&15];
}
}
//function computeStuff() {
// for (i=-1;++i<16;) computeFrac(1<<i,imageFrac[i]);
// tm=setInterval(renderMandel,30);
//}
function startMsgMandel() {
c=256;
cy=st=ir=0; cx=-0.5;
cd=imageFrac[0];
computeFrac(1,cd);
renderMandel();
//ctx.fillText("Click&wait for zoom",9,9);
}
startMsgMandel();