I couldn't decide between doing wavy water or some cheap 3d terrain so I went with both. My attempt generates water and terrain in 3d, randomly switching between both.
var d=Math,e=d.sin,n=d.random,o,w=0,h=0,ps=[],u=0,q=!1;S=function(b,g,h){t=this;t.d=b;t.c=g;t.a=h;t.x=t.y=t.e=0;t.b=col;return t};A=function(b){~~(n()*100)>90&&(q?q=!1:q=!0);for(xx=0;xx<26;xx++){var g=-900+xx*80,h=-110+b*80,k=100;q==!0&&(k-=n()*40);q?col=[0,190,50]:col=[0,149,200];ps[b*26+xx]=new S(g,k,h)}};with(c){with(style)width=(w=innerWidth-9)+"px",height=(h=innerHeight-25)+"px";o=c.height}for(yy=0;yy<26;yy++)A(yy);for(p in a)a[p[0]+(p[6]||"")]=a[p];
setInterval(function(){with(a){fillStyle="rgba(190,250,250,.3)";fc(0,0,w,h);for(j=25;j>-1;j--)for(i=25;i>-1;i--){var b=ps[j*26+i],g=b.d,z=b.c,k=b.a,v=b.b;ps[j*26+i].b[1]!=190&&(u+=9.0E-6,ps[j*26+i].c+=e(u+i+j));b.a-=8;scl=o/(o+k);b.y=64+z*scl;b.x=128+g*scl;j<25&&i<25&&k>-110&&(l(~~ps[(j+1)*26+i].x,~~ps[(j+1)*26+i].y),l(~~ps[(j+1)*26+(i+1)].x,~~ps[(j+1)*26+(i+1)].y),l(~~ps[j*26+(i+1)].x,~~ps[j*26+(i+1)].y));l(~~b.x,~~b.y);fillStyle="rgb("+~~(100-b.a/25)+","+~~(v[1]-b.a/25)+","+~~(v[2]-b.a/25)+")";
f();ba()}ps[0].a<-110&&(ps.splice(0,26),A(25))}},10);
dmFyIGQ9TWF0aCxlPWQuc2luLG49ZC5yYW5kb20sbyx3PTAsaD0wLHBzPVtdLHU9MCxxPSExO1M9ZnVuY3Rpb24oYixnLGgpe3Q9dGhpczt0LmQ9Yjt0LmM9Zzt0LmE9aDt0Lng9dC55PXQuZT0wO3QuYj1jb2w7cmV0dXJuIHR9O0E9ZnVuY3Rpb24oYil7fn4obigpKjEwMCk+OTAmJihxP3E9ITE6cT0hMCk7Zm9yKHh4PTA7eHg8MjY7eHgrKyl7dmFyIGc9LTkwMCt4eCo4MCxoPS0xMTArYio4MCxrPTEwMDtxPT0hMCYmKGstPW4oKSo0MCk7cT9jb2w9WzAsMTkwLDUwXTpjb2w9WzAsMTQ5LDIwMF07cHNbYioyNit4eF09bmV3IFMoZyxrLGgpfX07d2l0aChjKXt3aXRoKHN0eWxlKXdpZHRoPSh3PWlubmVyV2lkdGgtOSkrInB4IixoZWlnaHQ9KGg9aW5uZXJIZWlnaHQtMjUpKyJweCI7bz1jLmhlaWdodH1mb3IoeXk9MDt5eTwyNjt5eSsrKUEoeXkpO2ZvcihwIGluIGEpYVtwWzBdKyhwWzZdfHwiIildPWFbcF07DQpzZXRJbnRlcnZhbChmdW5jdGlvbigpe3dpdGgoYSl7ZmlsbFN0eWxlPSJyZ2JhKDE5MCwyNTAsMjUwLC4zKSI7ZmMoMCwwLHcsaCk7Zm9yKGo9MjU7aj4tMTtqLS0pZm9yKGk9MjU7aT4tMTtpLS0pe3ZhciBiPXBzW2oqMjYraV0sZz1iLmQsej1iLmMsaz1iLmEsdj1iLmI7cHNbaioyNitpXS5iWzFdIT0xOTAmJih1Kz05LjBFLTYscHNbaioyNitpXS5jKz1lKHUraStqKSk7Yi5hLT04O3NjbD1vLyhvK2spO2IueT02NCt6KnNjbDtiLng9MTI4K2cqc2NsO2o8MjUmJmk8MjUmJms+LTExMCYmKGwofn5wc1soaisxKSoyNitpXS54LH5+cHNbKGorMSkqMjYraV0ueSksbCh+fnBzWyhqKzEpKjI2KyhpKzEpXS54LH5+cHNbKGorMSkqMjYrKGkrMSldLnkpLGwofn5wc1tqKjI2KyhpKzEpXS54LH5+cHNbaioyNisoaSsxKV0ueSkpO2wofn5iLngsfn5iLnkpO2ZpbGxTdHlsZT0icmdiKCIrfn4oMTAwLWIuYS8yNSkrIiwiK35+KHZbMV0tYi5hLzI1KSsiLCIrfn4odlsyXS1iLmEvMjUpKyIpIjsNCmYoKTtiYSgpfXBzWzBdLmE8LTExMCYmKHBzLnNwbGljZSgwLDI2KSxBKDI1KSl9fSwxMCk7
var ma = Math,
si = ma.sin,
ra = ma.random,
perspective,
size = 32,
W = 0,
H = 0,
points = [],
angle = 0,
ter = false;
setPoint = function(x,y,z,c){
t = this;
t.xp = x;
t.yp = y;
t.zp = z;
t.x = t.y = t.z = 0;
t.c = c;
return t;
},
addSection = function(yy){
if(~~(ra()*100)>90){(ter)?ter=false:ter=true;};
for (xx=0; xx <size; xx++){
var x = -1100 + xx * 80,
z = -110 + yy * 80,
y = 100;
(ter==true)?y-=ra()*40:y=y;
(ter)?col=[0,190,50]:col=[0,149,200];
points[yy * size +xx] = new setPoint(x,y,z,col);
}
}
with(c){
with(style)width=(W=innerWidth-9)+"px",height=(H=innerHeight-25)+"px";
perspective = c.height;
}
for (yy=0; yy <size; yy++) {
addSection(yy);
}
for(p in a){
a[p[0]+(p[6]||'')]=a[p];
}
// render loop
setInterval(function () {
with(a) {
fillStyle = "rgba(190,250,250,.3)"
fc(0, 0, W, H)
for (j=size-1; j >-1; j--) {
for (i=size-1; i >-1; i--) {
var point = points[j * size + i],
px = point.xp,
py = point.yp,
pz = point.zp,
color = point.c;
if(points[j * size + i].c[1]!=190){angle+=.000009; points[j * size + i].yp += si(angle+i+j)};
point.zp -=10;
scl = perspective / (perspective + pz);
point.y = 64 + py * scl;
point.x= 128 + px * scl;
m(~~point.x,~~point.y);
if(j<size-1&&i<size-1&&pz > -110){
l(~~points[((j+1) * size)+i].x,~~points[((j+1) * size)+i].y);
l(~~points[(j+1) * size+(i+1)].x,~~points[(j+1) * size+(i+1)].y);
l(~~points[(j * size)+(i+1)].x,~~points[(j * size)+(i+1)].y);
}
l(~~point.x,~~point.y);
fillStyle = 'rgb(' + ~~(100-point.zp/25) + ',' + ~~(color[1]-point.zp/25) + ',' + ~~(color[2] - point.zp/25) + ')';
f();
ba();
}
}
if(points[0].zp < -110){
points.splice(0,size);
addSection(size-1);
}
}
}, 10);