Final version of this wave/rubber fx : added 'elastic' like fx and better lightning. However, I had to simplify a bit the waves fx to match the 1024 bytes limit...
a=document.getElementById("c"),b=a.width=innerWidth>>1,c=a.height=128,d=[],e=[],f=[],g=0;nc=1;for(i=0;i<4096;i++){d[i]=16*Math.sin(i*3.14/128);oc=nc;nc=Math.cos(i*3.14/2048);nc*=nc*nc*nc*nc;e[i]=4*c*(1+nc);f[i]=Math.abs(1E4*(nc-oc))}h=a.getContext("2d");h.fillRect(0,0,b,c);j=h.getImageData(0,0,b,c),k=j.data;setInterval(function(){for(x=1;x<b;x++){y1=~~e[g-e[g-x&4095]&4095];dy=~~f[g-e[g-x&4095]&4095];yR=~~(d[g+x*5&511]+d[g-x*2&511]+48);z=x*4;for(y=c;y--;z+=b*4,k[z]=k[z+1]=0)k[z+2]=(z+y>>5&7)*15;for(z=(x+(c-yR>>1)*b)*4;yR--;z+=b*4)k[z]=255;y1=~~(y1%c*(c-dy*2)/c);y2=c-dy*2-y1;w=x-1<<2;for(y=c;y--;w+=b*4)k[w]=k[w+1]=k[w+2]=255;w=x-1+dy*b<<2;y=y1;oi=c*256/y1;for(oy=0;y-- >1;w+=b*4){oy+=oi;z=x+(oy>>8)*b<<2;k[w]=k[z]+y2*3<255?k[z]+y2*3:255;k[w+1]=k[z+1]+y2*3<255?k[z+1]+y2*3:255;k[w+2]=k[z+2]+y2*3<255?k[z+2]+y2*3:255}oi=c*256/y2;for(oy=0;y2-- >1;w+=b*4){oy+=oi;z=x+(oy>>8)*b<<2;k[w]=k[z]-y1*4>0?k[z]-y1*4:0;k[w+1]=k[z+1]-y1*4>0?k[z+1]-y1*4:0;k[w+2]=k[z+2]-y1*4>0?k[z+2]-y1*4:0}}g+=8;h.putImageData(j,0,0)},30);
YT1kb2N1bWVudC5nZXRFbGVtZW50QnlJZCgiYyIpLGI9YS53aWR0aD1pbm5lcldpZHRoPj4xLGM9YS5oZWlnaHQ9MTI4LGQ9W10sZT1bXSxmPVtdLGc9MDtuYz0xO2ZvcihpPTA7aTw0MDk2O2krKyl7ZFtpXT0xNipNYXRoLnNpbihpKjMuMTQvMTI4KTtvYz1uYztuYz1NYXRoLmNvcyhpKjMuMTQvMjA0OCk7bmMqPW5jKm5jKm5jKm5jO2VbaV09NCpjKigxK25jKTtmW2ldPU1hdGguYWJzKDFFNCoobmMtb2MpKX1oPWEuZ2V0Q29udGV4dCgiMmQiKTtoLmZpbGxSZWN0KDAsMCxiLGMpO2o9aC5nZXRJbWFnZURhdGEoMCwwLGIsYyksaz1qLmRhdGE7c2V0SW50ZXJ2YWwoZnVuY3Rpb24oKXtmb3IoeD0xO3g8Yjt4Kyspe3kxPX5+ZVtnLWVbZy14JjQwOTVdJjQwOTVdO2R5PX5+ZltnLWVbZy14JjQwOTVdJjQwOTVdO3lSPX5+KGRbZyt4KjUmNTExXStkW2cteCoyJjUxMV0rNDgpO3o9eCo0O2Zvcih5PWM7eS0tO3orPWIqNCxrW3pdPWtbeisxXT0wKWtbeisyXT0oeit5Pj41JjcpKjE1O2Zvcih6PSh4KyhjLXlSPj4xKSpiKSo0O3lSLS07eis9Yio0KWtbel09MjU1O3kxPX5+KHkxJWMqKGMtZHkqMikvYyk7eTI9Yy1keSoyLXkxO3c9eC0xPDwyO2Zvcih5PWM7eS0tO3crPWIqNClrW3ddPWtbdysxXT1rW3crMl09MjU1O3c9eC0xK2R5KmI8PDI7eT15MTtvaT1jKjI1Ni95MTtmb3Iob3k9MDt5LS0gPjE7dys9Yio0KXtveSs9b2k7ej14KyhveT4+OCkqYjw8MjtrW3ddPWtbel0reTIqMzwyNTU/a1t6XSt5MiozOjI1NTtrW3crMV09a1t6KzFdK3kyKjM8MjU1P2tbeisxXSt5MiozOjI1NTtrW3crMl09a1t6KzJdK3kyKjM8MjU1P2tbeisyXSt5MiozOjI1NX1vaT1jKjI1Ni95Mjtmb3Iob3k9MDt5Mi0tID4xO3crPWIqNCl7b3krPW9pO3o9eCsob3k+PjgpKmI8PDI7a1t3XT1rW3pdLXkxKjQ+MD9rW3pdLXkxKjQ6MDtrW3crMV09a1t6KzFdLXkxKjQ+MD9rW3orMV0teTEqNDowO2tbdysyXT1rW3orMl0teTEqND4wP2tbeisyXS15MSo0OjB9fWcrPTg7aC5wdXRJbWFnZURhdGEoaiwwLDApfSwzMCk7
var doc = document;
var canvas = doc.getElementById("c");
var width = canvas.width = innerWidth>>1;
var height = canvas.height = 128;//innerHeight;
var mySinR=[],mySin=[],myCos=[];
var cpt=0;
for (nc=1,i=0;i<4096;i++) {
mySinR[i]=16*Math.sin(i*3.14/128);
oc=nc;
nc=Math.cos(i*3.14/2048);
nc*=nc*nc*nc*nc;
mySin[i]=4*height*(1+nc);
myCos[i]=Math.abs(10000*(nc-oc));
}
// Paint the canvas opaque black (fillStyle should be "black" by default).
var ctx = canvas.getContext("2d");
ctx.fillRect(0, 0, width, height);
var image = ctx.getImageData(0, 0, width, height);
var data = image.data;
function renderRub() {
for (x = 1; x < width; x++) {
y1=~~mySin[(cpt-mySin[(cpt - x)&4095])&4095];
dy=~~myCos[(cpt-mySin[(cpt - x)&4095])&4095];
yR=~~(mySinR[(cpt+x*5)& 511]+mySinR[(cpt-x*2)&511]+48);
os=x*4;
for (y=height;y--;os+=width*4,data[os]=data[os+1]=0) data[os+2] = ((os+y>>5)&7)*15;
os=(x+(height-yR>>1)*width)*4;
for (;yR--;os += width*4) data[os]=255;
y1=~~(y1%height*(height-dy*2)/height);
y2=height-dy*2-y1;
od=x-1<<2;
for (y=height;y--;od+=width*4) data[od]=data[od+1]=data[od+2]=255;
od=x-1+ dy*width<<2;
for (y=y1,oi=height*256/y1,oy=0;y-->1;od+=width*4) {
oy+=oi;
os=(x + (oy>>8)*width)<<2;
data[od] = (data[os]+y2*3<255?data[os]+y2*3:255);
data[od+1] = (data[os+1]+y2*3<255?data[os+1]+y2*3:255);
data[od+2] = (data[os+2]+y2*3<255?data[os+2]+y2*3:255);
}
for (oi=height*256/y2,oy=0;y2-->1;od+=width*4) {
oy+=oi;
os=(x + (oy>>8)*width)<<2;
data[od] = (data[os]-y1*4>0?data[os]-y1*4:0);
data[od+1] = (data[os+1]-y1*4>0?data[os+1]-y1*4:0);
data[od+2] = (data[os+2]-y1*4>0?data[os+2]-y1*4:0);
}
}
cpt+=8;
ctx.putImageData(image, 0, 0);
}
setInterval(renderRub,30);