Last friday
MIX Online and
An Event Apart launched an unusual Javascript contest.
10K Apart pushes the developer to reduce their code so it fits in 10,000 bytes. This sounds like a nice challenge, but strangely they allow specific external libraries, which, in my opinion, over complicate things.
However, just to see what could be done, I quickly checked the amount of bytes that I would need to have a simple and easy to use 3d engine. That turned out to be about 1,000 bytes. Which left me with 9,000 bytes. Now, this may sound great, but it's kind of discouraging. Now I understand why the 64 kbytes coders always say that 64 kbytes are way harder to do than 4 kbytes –
the number of possibilities is lower. Anyway, if I come up with a good idea I may try doing something with that for the contest.
Today I found out about
JS1k. Which seemed to be
Peter van der Zee's response to the former contest (no external libs, just 1,024 bytes of plain javascript) and it also had
a few submissions.
Once I got the 3d engine working I got a bit code-addicted and ended up doing a plasma in 3D in 1,464 bytes, it was nice looking already, so it was a matter of reducing those extra 440 bytes. After learning some tricks and testing things here and there,
it got reduced to 996 bytes. Here it's the result:

Looking forward to see what
p01 has to "say" of all this... :)
EDIT: After reading
Diego's post and finding interesting to see which tricks he used I thought I should also share the non-obfuscated code of my entry.
( function () {
var res = 25, res3 = res * res * res,
i = 0, x = 0, y = 0, z = 0, s, size, sizeHalf,
vx, vy, vz, rsx, rcx, rsy, rcy, rsz, rcz,
xy, xz, yx, yz, zx, zy,
cx = 0, cy = 0, cz = 1, rx = 1, ry = 1, rz = 0,
t, t1, t2, t3,
sin = Math.sin, cos = Math.cos, pi = Math.PI * 3,
mouseX = 0, mouseY = 0, color,
doc = document, body = doc.body,
canvas, context, mesh = [],
width = innerWidth,
height = innerHeight,
widthHalf = width / 2,
heightHalf = height / 2;
body.style.margin = '0px';
body.style.overflow = 'hidden';
canvas = doc.body.children[0];
canvas.width = width;
canvas.height = height;
context = canvas.getContext( '2d' );
context.translate( widthHalf, heightHalf );
doc.onmousemove = function ( event ) {
mouseX = ( event.clientX - widthHalf ) / 1000;
mouseY = ( event.clientY + heightHalf ) / 1000;
};
while ( i++ < res3 ) {
mesh.push( x / res - 0.5 );
mesh.push( y / res - 0.5 );
mesh.push( z / res - 0.5 );
z = i % res;
y = !z ? ++y %res : y;
x = !z && !y ? ++x : x;
}
setInterval( function () {
context.clearRect( - widthHalf, - heightHalf, width, height );
cx += ( mouseX - cx ) / 10;
cz += ( mouseY - cz ) / 10;
t = new Date().getTime();
t1 = sin( t / 20000 ) * pi;
t2 = sin( t / 10000 ) * pi;
t3 = sin( t / 15000 ) * pi;
rx = t / 10000;
rsx = sin( rx ); rcx = cos( rx );
rsy = sin( ry ); rcy = cos( ry );
rsz = sin( rz ); rcz = cos( rz );
i = 0;
while ( ( i += 3 ) < res3 * 3 ) {
x = mesh[ i ];
y = mesh[ i + 1 ];
z = mesh[ i + 2 ];
s = sin( t1 + x * t1 ) + sin( t2 + y * t2 ) + sin( t3 + z * t3 );
if ( s >= 0 ) {
xy = rcx * y - rsx * z;
xz = rsx * y + rcx * z;
yz = rcy * xz - rsy * x;
yx = rsy * xz + rcy * x;
zx = rcz * yx - rsz * xy;
zy = rsz * yx + rcz * xy;
vx = zx - cx;
vy = zy - cy;
vz = yz + cz;
if ( vz > 0 ) {
color = ( 64 / vz ) >> 0;
context.fillStyle = 'rgb('+ ( color - 16 ) + ','+ ( color * 2 - 128 ) + ','+ ( color + 64 ) + ')';
size = s * 30 / vz;
sizeHalf = size / 2;
context.fillRect( ( vx / vz ) * widthHalf - sizeHalf, ( vy / vz ) * widthHalf - sizeHalf, size, size );
}
}
}
}, 16 );
} )();
Which, after
compression ends up like this:
var O=24,d=O*O*O,X=0,U=0,T=0,S=0,W,j,L,o,m,k,b,q,ac,n,ab,l,K,I,r,p,Z,Y,C=0,A=0,w=1,G=1,F=1,E=0,V,P,N,M,u=Math.sin,f=Math.cos,v=Math.PI*3,R=0,Q=0,H,g=document,D=g.body,h,aa,B=[],a=innerWidth,e=innerHeight,J=a/2,c=e/2;D.style.margin="0px";D.style.overflow="hidden";h=g.body.children[0];h.width=a;h.height=e;aa=h.getContext("2d");aa.translate(J,c);g.onmousemove=function(i){R=(i.clientX-J)/1e3;Q=(i.clientY+c)/1e3};while(X++=0){K=q*T-b*S;I=b*T+q*S;p=n*I-ac*U;r=ac*I+n*U;Z=l*r-ab*K;Y=ab*r+l*K;o=Z-C;m=Y-A;k=p+w;if(k>0){H=(64/k)>>0;aa.fillStyle="rgb("+(H-16)+","+(H*2-128)+","+(H+64)+")";j=W*30/k;L=j/2;aa.fillRect((o/k)*J-L,(m/k)*J-L,j,j)}}}},16);
20 comments