Clicking anywhere on the canvas spawns a generation of elemental "worms" which compete to paint the canvas by squirming around randomly, affecting the canvas pixels which they pass over according to w…
for(_=');z]=y){xreturnvxv `=0;__w<^[k]Z])}W,1V],U[0]TT,S,0V)Rfunction(bQQ`g(b,[Pf(b)OW,POSN.05RNL50KMath.random()JK*J)+H[1]Go[i]E[ESEGD1,EGUCfor(BBk_k<@b[4UO$,51U[#b%1*d>e?e:};,eBi_++);w~~(.length/rR,Y(q,h)*F+M(;iBw([w,i=Q,d255%6U*d[(b|l.data[4*(yuZb.clientt[X/K)=[ +=3*J)-1;E];+=f(rZ)[2]o[o] X,Y,1HK,XH1M(bGbSF)M(iw,F))Bi in c)c[iT+i[6]yc[iF=a.width;h=a.height;l=c.cI(F,hzI o t 1VVVX P$G,ONOSY(O+LOG,Y(O-L$Wn J,J,Ju [79V49#212,223,230U[V00#51V53,]Axb*=6;d e+=d*=.51-e-*2-=d*=2++dv[*d[~~b16)8)%6U]MxB;0>b;)b+=d;v b%dY`b<d?d:bbf=Q`I[]gxI[yd;Bm_m<t;m)+myY(A(dSdG,d)[mU0,)i<h^FgUnzs=Qxi<o^E{ETG[3](Ezr D-1U[ET-CE,E,[ET+CD+1]q 0,0,0@r;kqTSqGG,q;g(E,[Y(qTG/rRW@u;kK>i=K*k;w<K*k+KtZ?(S+1G,+2):gUf])zc.pg(l,0,0zrequestAnimationFrame(s)a.onclick=Qxif(200>X&&K>Y)y!else{o p ,,,Bw^tt[w]&&i<p[wi[wUJSnT]}s(0)';g=/[^ !%-?AFIMXY[\]a-uw{-~]/.exec(_);)with(_.split(g))_=join(shift());eval(_)
Zm9yKF89Jyk7el09eSl7eHJldHVybnZ4diBgPTA7X193PF5ba11aXSl9VywxVl0sVVswXVRULFMsMFYpUmZ1bmN0aW9uKGJRUWBnKGIsW1BmKGIpT1csUE9TTi4wNVJOTDUwS01hdGgucmFuZG9tKClKSypKKStIWzFdR29baV1FW0VTRUdEMSxFR1VDZm9yKEJCa19rPEBiWzRVTyQsNTFVWyNiJTEqZB8+ZT9lOh59Ox0sZRxCaV8bKyspGjt3Ghl+figYLmxlbmd0aBcvchdSLFkocRYsaCkqRitNKBU7aRpCdxQoW3csaRM9USxkEjI1NRElNlURKmRbKGJ8EGwuZGF0YVs0KigPeXVaDmIuY2xpZW50DHRbGAxYL0spCz1bCSs9GDMqSiktMTtFCF07Bys9ZihyWikGWzJdBW9bbxddCQxYLAxZLBgxSEssWAQYSDEDTShiRxViU0YpAg9NKGkVdyxGKSkBQmkgaW4gYyljW2lUK2lbNl15Y1tpB0Y9YS53aWR0aDtoPWEuaGVpZ2h0O2w9Yy5jSShGLGh6SQkHbwkHdAkxVlZWB1gJUCRHLE8FTk9TWShPBStMT0csWShPBS1MJAVXB24JSixKLEoHdQlbNzlWNDkjMjEyLDIyMywyMzBVWxFWMDAjNTFWNTMsEV0HQRIceGIqPTY7ZAllKz1kKj0uNR4xLWUcLR8qMhwtPWQqPTIcHCsfHCtkB3ZbESpkW35+YhAxNikQOCklNlURXR1NEnhCOzA+YjspYis9ZDt2IGIlZB1ZEhxgYjxkP2Q6Yh5iHWY9UWBJWwJdHWcSeElbAnlkO0JtX208dBc7bRoPAikrbXlZKEEoZFNkRyxkBSlbbVUwLBEpHRtpPGgUXkYZZxNVbnpzPVF4G2k8bxcUXkUFGXtFVAhHCFszXShFenIJRC0xVVtFVC1DRSxFLFtFVCtDRCsxXQdxCTAsMCwwB0ByFztrGnFUBlNxRwZHLHEFBgU7ZyhFLFtZKHFUFkcWBS9yF1JXQHUXO2saG0s+aRQ9SyprO3c8SyprK0sZdFo/KAEOUwErMQ5HLAErMg4FKTpnE1VmE10pemMucGcobCwwLDB6cmVxdWVzdEFuaW1hdGlvbkZyYW1lKHMpHWEub25jbGljaz1ReGlmKDIwMD4MWCYmSz4MWSkLeSELB2Vsc2V7bwkHcAkDLAMsAywDB0J3XnQXGRt0W3ddJiZpPHBbdwdpGgRbd1VKBwRTblRdfR1zKDApJztnPS9bXiAhJS0/QUZJTVhZW1xdYS11d3stfl0vLmV4ZWMoXyk7KXdpdGgoXy5zcGxpdChnKSlfPWpvaW4oc2hpZnQoKSk7ZXZhbChfKQ==
(function(){
//width
F = a.width
//height
G = a.height
//imageData
H = c.createImageData( F, G )
//hslData
I = []
//worms
K = []
//element painting enabled? earth/air/fire/water
U = [ 1, 1, 1 ,1 ]
//element actions (hsl)
X = [
//earth modifies hue channel
worm =>
E( worm, [
worm[ 4 ],
D( worm )[ 1 ],
D( worm )[ 2 ]
]),
//air increments lightness channel
worm =>
E( worm, [
D( worm )[ 0 ],
D( worm )[ 0 ],
C( D( worm )[ 2 ] + 0.05, 0, 1 )
]),
//fire decrements lightness channel
worm =>
E( worm, [
D( worm )[ 0 ],
D( worm )[ 1 ],
C( D( worm )[ 2 ] - 0.05, 0, 1 )
]),
//water modifies saturation channel
worm =>
E( worm, [
D( worm )[ 0 ],
worm[ 4 ],
D( worm )[ 2 ]
])
]
//initial fill color (HSL)
J = [
Math.random(),
Math.random(),
Math.random()
]
//element button colors (RGB)
W = [
//earth
[ 79, 149, 51 ],
//air
[ 212, 223, 230 ],
//fire
[ 255, 100, 51 ],
//water
[ 51, 153, 255 ]
]
//hslToRgb
A = ( b, d, e ) => {
b *= 6
d = [
e += d *= .5 > e ? e : 1 - e,
e - b % 1 * d * 2,
e -= d *= 2,
e,
e + b % 1 * d,
e + d
]
return [
255 * d[ ~~b % 6 ],
255 * d[ ( b | 16 ) % 6 ],
255 * d[ ( b | 8 ) % 6 ],
255
]
}
//wrap
B = ( b, d ) => {
for( ; 0 > b; )
b += d
return b % d
}
//clamp
C = ( n, min, max ) => n < min ? min : n > max ? max : n
//get (hsl)
D = point =>
I[ B( point[ 1 ], G ) * F + B( point[ 0 ], F ) ]
//set (hsl)
E = ( point, hsl ) => {
//save to hueData
I[ B( point[ 1 ], G ) * F + B( point[ 0 ], F ) ] = hsl
//set imageData channels (rgb)
for( m = 0; m < U.length; m++ )
H.data[(
B( point[ 1 ], G ) *
F +
B( point[ 0 ], F )
) * 4 + m ] = C( A( hsl[ 0 ], hsl[ 1 ], hsl[ 2 ] )[ m ], 0, 255 )
}
//fill canvas
for( i = 0; i < G; i++ )
for( j = 0; j < F; j++ )
E( [ j, i ], J )
//tick
T = elapsed => {
//each worm
for( i = 0; i < K.length; i++ )
//worm movements per tick
for( j = 0; j < K[ i ][ 2 ]; j++ ){
//move 0-1 pixels on each axis
K[ i ][ 0 ] += ~~( Math.random() * 3 ) - 1
K[ i ][ 1 ] += ~~( Math.random() * 3 ) - 1
//action
K[ i ][ 3 ]( K[ i ] )
//blur
//find neighbours
S = [
[ K[ i ][ 0 ], K[ i ][ 1 ] - 1 ],
[ K[ i ][ 0 ] - 1, K[ i ][ 1 ] ],
K[ i ],
//extra copy of current point to bias result
K[ i ],
[ K[ i ][ 0 ] + 1, K[ i ][ 1 ] ],
[ K[ i ][ 0 ], K[ i ][ 1 ] + 1 ]
]
//sum channels with neighbours (HSL)
R = [ 0, 0, 0 ]
for( k = 0; k < S.length; k++ ){
R[ 0 ] += D( S[ k ] )[ 0 ]
R[ 1 ] += D( S[ k ] )[ 1 ]
R[ 2 ] += D( S[ k ] )[ 2 ]
}
//normalize channels and paint (HSL)
E( K[ i ], [
C( R[ 0 ] / S.length, 0, 1 ),
C( R[ 1 ] / S.length, 0, 1 ),
C( R[ 2 ] / S.length, 0, 1 )
])
//end blur
}
//element select buttons
for( k = 0; k < W.length; k++ ){
for( i = 0; i < 50; i++ )
for( j = k * 50; j < k * 50 + 50; j++ ){
//if element enabled draw button
if( U[ k ] ){
//red channel
H.data[(
B( i, G ) *
F +
B( j, F )
) * 4 ] = W[ k ][ 0 ]
//green channel
H.data[(
B( i, G ) *
F +
B( j, F )
) * 4 + 1 ] = W[ k ][ 1 ]
//blue channel
H.data[(
B( i, G ) *
F +
B( j, F )
) * 4 + 2 ] = W[ k ][ 2 ]
}
//draw background
else {
E( [ j, i ], D( [ j, i ] ) )
}
}
}
//blit
c.putImageData( H, 0, 0 )
requestAnimationFrame( T )
}
a.onclick = event => {
//toggle buttons?
if( event.clientX < 200 && event.clientY < 50 ){
U[ ~~( event.clientX / 50 ) ] = !U[ ~~( event.clientX / 50 ) ]
}
//new worm generation at click point
else {
//clear current worms
K = []
//number of worms per element
N = [
//earth count
~~( Math.random() * 50 ) + 1,
//air count
~~( Math.random() * 50 ) + 1,
//fire count
~~( Math.random() * 50 ) + 1,
//water count
~~( Math.random() * 50 ) + 1
]
//add worms for each element
for( j = 0; j < U.length; j++ ){
//add count for this element
for( i = 0; U[ j ] && i < N[ j ]; i++ ){
//add worm
K[ K.length ] = [
//initial position
event.clientX,
event.clientY,
//turns per tick
~~( Math.random() * 150 ) + 50,
//draw action
X[ j ],
//value
Math.random()
]
}
}
//always add one extra worm that paints with the fill color
K[ K.length ] = [
//initial position
event.clientX,
event.clientY,
//turns per tick
~~( Math.random() * 150 ) + 50,
//colorise
X[ 0 ],
//current fill hue
J[ 0 ]
]
}
}
//start
T( 0 )
})()