A space probe warp jumps from star system to star system, in a quest for a planet that could harbor life.
for(_='25~75Z2~,Z,Ys&3],X*iW&~5VW)VUMath.TTPILin(K00JJ)H*(GtaF]=E15DD0B12AV)@++;d[qE](c[c.fc-n,n=~6;)fyEs%0,+=[1,-1][A8Tcos(*TsKf)+f)*=Tsqrt(Z*Z-y*y);n.addColorStop(a.width,a.heightTmax( for(2*n,2*nc.drawImage(a,nGi<0?i=0;i-DB3H)*L/3H* TmKt-if(!t){a=a.cloneNode(p=[s=5]i in cc=a.getContext("2d"))c[i[0]+[i[6]]Ei;e=cggd=e.daF}if(t%AZ<1){cccRY~,Y60x=y=f="rgb("+[531+DV,D+32V]1,"#J0"cD;f<*p[fETmK3*(f@/20)-3*f/H-7+23e5;--n;s*=(-s)/65)xXy3-Xt=-6;t6p[Gy+t@+(x+i@]+=.01}f=t/2Jy=-Z;y<Zx=-(C)@,q=4G(y+Z)*B+Z-Cx<C{w-x*xi=p[((*TaFn2(yw,x)+t)/L@+GTacos((-wy)/Z)*/L@];.1+.J8* n-x)-:+~U-7W:Z+50U:ZU~5}cpge,0"hsl(,~%,"+ 1J-t)+"%";c.save("#fff"F.5*/2c.roFte(-.2-.210FC=8J9-405J-5J1JZJiW%Z~-Bi%~~-B i%D/7,t-AH, 1,t-11H~0-Z35-B1J;,AJs|40;gCE"lighter";AD,-~Z~Gi&6),D,-CW~Wre)';g=/[^ -?CIM-S[-}]/.exec(_);)with(_.split(g))_=join(shift(t=0));setInterval(_,33)
Zm9yKF89JzI1fjc1WjJ+LFosWXMmM10sWCppVyZ+NVZXKVZVTWF0aC5UVFBJTGluKEswMEpKKUgqKEd0YUZdPUUxNUREMEIxMkFWKUArKx87ZFtxH0UeXSgdY1tjLhwcZmMdGy1uLBpuPRl+Nhg7KRccZnlFFnMlFTAsFCs9WxQxLBQtMV1bE0E4ElRjb3MoESpUc0tmKSsRZikqED1Uc3FydChaKloteSp5Dyk7Dg5uLmFkZENvbG9yU3RvcCgMYS53aWR0aCxhLmhlaWdodAtUbWF4KAlmb3IoCBoyKm4sMipuDgdjLmRyYXdJbWFnZShhLAYebkdpPDA/BQhpPTA7H2ktBBQURBRCAxQzSCkqTC8zSAIqEQkUVG1LdC0BaWYoIXQpe2E9YS5jbG9uZU5vZGUocD1bcz01XQ4IaSBpbiBjYz1hLmdldENvbnRleHQoIjJkIikpY1tpWzBdK1tpWzZdXUVpO2U9YxxnZx0DDmQ9ZS5kYUZ9aWYodCVBWjwxKXtjFhljHGNSHVl+LFk2MAx4PXk9Zj0UInJnYigiK1s1FDMxKxVEVixEKxUzMlZdDDEsIiNKMCIOYxtEAw4IO2Y8GCoYF3BbZh9FVG1LFDMqEShmQC8yMCktMyoRZi8SSC0VNysyDggZM2U1Oy0tbjtzKj0oGC1zKS82NSkIeBNYeRMzLVh0PS02Ox90FwQ2F3BbGEd5K3RAKyh4K2lAXSs9LjAxfWY9ER90LzJKDgh5PS1aOx95PFoXCHg9LShDDylALHE9NEcoeStaKSpCK1otQw4feDxDF3t3Dy14KngOaT1wWygoEipUYUZuMigZeRB3LHgpK3QpL0xAKxhHVGFjb3MoKC13EHkpL1opKhgvTEBdOxkuMSsuSjgqCRRuLXgpBRItFRI6FRIrFX5VBS03VzpaKxU1MFUFFRI6FVpVHn41fWMccGcdZSwUMA4WImhzbCgYLH4lLCIrCRQxSi10KSsiJSI7GxQUCw5jLnNhdmUoFiIjZmZmIg4cRh0uNSoLLzIOYy5yb0Z0ZSgtLjItLjIBMTACDhxGHUM9OEoBOQItNDAUNUotNUoBMUoCDgRaShcbaVclWn4tQhRpJX5+LUIUCWklRC83LHQtQUgsCTEsdC0xMUgOGX4wLVoBMzUCLUIBMUoCOwYDLEFKGgcZc3w0MDscZ0NFImxpZ2h0ZXIiOwRBFwZEAywaLX4HBFoXGX5HaSY2KSwGRAMsLUNXGn5XBxxyZR0pJztnPS9bXiAtP0NJTS1TWy19XS8uZXhlYyhfKTspd2l0aChfLnNwbGl0KGcpKV89am9pbihzaGlmdCh0PTApKTtzZXRJbnRlcnZhbChfLDMzKQ==
/*
* global variables
*
* p (land) : planet heightmap
* t (time) : animation timer
* a (a2) : secondary canvas (cache)
* cc(c2) : secondary canvas 2D context
* n (rGradient) : (beginning only, can be reused) : star gradient cache
* e (i2) : secondary canvas image buffer
* d (d2) : secondary canvas image buffer data
* f (rx) : planet tilt angle
* x y w (x)(y)(z) : cartesian coordinates of screen projection onto planet
* x - n (xp)(yp)(zp) : cartesian coordinates of ray hit onto rotated planet
* i (l) altitude of land at given pixel
* n (light) : light received by pixel while drawing planet
* q (k) : drawn pixel offset into secondary canvas image buffer data
* u (sunX) : coordinates to draw sun on screen
* n (planetSize) : radius of planet in pixels
* n (halfSize) : radius of sun in pixels
* i (i) loop index
* i t n s x y f (i)(j)(t)(n)(x)(y) : loop coordinates upon generating planet
* s : seed for pseudorandom, changed by planet generation
*
* parameters needed
* star radius
* star color
* planet ocean level
* planet colors
*/
// create a cache for the planet and the star
a = a.cloneNode(p=[s=5]);
cc = a.getContext("2d");
e = cc.getImageData(t=0,0,150,150); d=e.data;
setInterval( function () {
if (t%1275<1) {
// arriving to a new star system
// draw the star onto the cache
cc.fillStyle = n = cc.createRadialGradient(225, 75, 25, 225, 75, 60);
n.addColorStop(x=y=f=0, "rgb("+[50, 31+s%15&255, 15+s%32&255]);
n.addColorStop(1, "#000");
cc.fillRect(150,0,150,150);
// dig the oceans
for (; f<256*256; )
p[f++]=Math.min(0,3*Math.cos((f&255)/20)-3*Math.cos(f/12800)-s%7+2);
// then add the hills
for (n=3e5;--n;s*=(256-s)/65) // logistic map for pseudorandom
for (x+=[0,1,0,-1][s&3],
y+=[0,1,0,-1][3-s&3],
t=-6;++t;)
for (i=0;++i-6;)
p[256*(y+t&255)+(x+i&255)]+=.01;
}
// drawView()
// 0-100 : whiteout progressively vanishes, motions starts slowly
// 100-300 : pan on star
// 300-400 : bring planet to center
// 400-500 : move forward towards planet
// 500-700 : still, planet rotates
// 900-1100 : fly over planet
// 1100-1275 : initiate warp
// draw the rotated planet into the cache
f = Math.cos(++t/200);
for (y=-75; ++y<75;)
for(x=-(u=Math.sqrt(75*75-y*y)&255),
q = 4*((y+75)*150+75-u);
++x<u;)
{
w=Math.sqrt(75*75-y*y-x*x);
i = p[((128*Math.atan2(n = y*Math.sin(f)+Math.cos(f)*w,x) + t)/Math.PI&255)+256*(Math.acos((-w*Math.sin(f)+Math.cos(f)*y)/75)*256/Math.PI&255)];
n = .1+.008*Math.max(0, n-x);
d[q++]= n*(i<0?128-s%128:s%128+s%25*i)&255;
d[q++]= n*(i<0?-7*i:75+s%50*i)&255;
d[q++]= n*(i<0?s%128:s%75*i)&255;
d[q++]=255;
}
cc.putImageData(e,0,0);
// flash vanishes in the first 100 frames
c.fillStyle="hsl(256,25%,"+Math.max(0,100-t)+"%";
c.fillRect(0,0,a.width,a.height);
c.save(c.fillStyle = "#fff");
c.translate(.5*a.width, a.height/2);
c.rotate(-.2-.2*Math.cos(Math.max(0, Math.min(t-100, 300))*Math.PI/300));
// camera motion
c.translate(u = 800*Math.cos(Math.max(0, Math.min(t-90, 300))*Math.PI/300)-400,
500-500*Math.cos(Math.max(0, Math.min(t-1000, 300))*Math.PI/300));
// draw starfield, with trail (frame 1100+) then warp effect (frame 1200+)
for (i=0; ++i-7500;)
c.fillRect(i*i%7525-1500,i%2525-1500, Math.max(i%15/7, t-1200), Math.max(1, t-1100));
// copy scaled planet from cache
n = 250-75*Math.cos(Math.max(0, Math.min(t-350, 300))*Math.PI/300)
-150*Math.cos(Math.max(0, Math.min(t-1000, 300))*Math.PI/300);
c.drawImage(a, 0, 0, 150, 150, 1200-n, -n, 2*n, 2*n);
// draw star (multiple copies of the cache, with the appropriate compositing)
n=s|40; // star size, different in each system
c.globalCompositeOperation="lighter";
for (i=0;++i-12;)
c.drawImage(a, 150, 0, 150, 150, -n, -25-n, 2*n, 2*n);
// draw the lens flare
for (i=0;++i-75;)
n=25*(i&6),c.drawImage(a, 150, 0, 150, 150, -u*i-n, 25*i-n, 2*n, 2*n);
// reset camera aim, rotation, composite operation for next frame
c.restore();
}, 33);