JS1k 2015 Invitation
<!doctype html> | |
<html> | |
<head> | |
<title>JS1k 2015 Invitation by Mathieu 'p01' Henri</title> | |
<meta charset="utf-8" /> | |
<meta name="author" content="Mathieu 'p01' Henri, @p01"/> | |
<meta name="viewport" content="width=device-width,initial-scale=1"/> | |
<style> | |
html, body { margin: 0; padding: 0; border: 0; } | |
#c { display: block; } /* kill scrollbars from hell */ | |
</style> | |
</head> | |
<body> | |
<canvas id="c"></canvas> | |
<script> | |
var a = document.getElementsByTagName('canvas')[0]; | |
var b = document.body; | |
var d = function(e){ return function(){ e.parentNode.removeChild(e); }; }(a); | |
// unprefix some popular vendor prefixed things (but stick to their original name) | |
var AudioContext = | |
window.AudioContext || | |
window.webkitAudioContext; | |
var requestAnimationFrame = | |
window.requestAnimationFrame || | |
window.mozRequestAnimationFrame || | |
window.webkitRequestAnimationFrame || | |
window.msRequestAnimationFrame || | |
function(f){ setTimeout(f, 1000/30); }; | |
// fix bug in safari: http://qfox.nl/weblog/218 | |
document.body.clientWidth; | |
// auto resize (original) canvas. call `onresize(w,h) to limit the size of the canvas | |
(window.onorientationchange = window.onresize = function(a){ | |
var mw = Infinity; | |
var mh = Infinity; | |
var min = Math.min; | |
return function(w,h){ | |
if (arguments.length === 2) { | |
mw = w; | |
mh = h; | |
} | |
a.style.width = (a.width = min(mw, innerWidth)) + 'px'; | |
a.style.height = (a.height = min(mh, innerHeight)) + 'px'; | |
}; | |
}(a))(); | |
var c = a.getContext('2d'); | |
</script> | |
<script src="test.js"></script> | |
<script>onclick=function(){location.href='http://www.p01.org/releases/JS1K_2015_invit/';}</script> | |
</body> | |
</html> |
// Compresses down to ~1020 bytes with Uglify + RegPack | |
(u=function(){ | |
requestAnimationFrame(u); | |
a.width=x=1023; | |
a.height=h=x*innerHeight/innerWidth|1; | |
H=performance.now()/15|1; | |
c.textAlign='center'; | |
c.font='2em cursive'; | |
q=170; | |
c.fillStyle='hsl('+q+',20%,55%)'; | |
c.fillRect(0,0,1023,h); | |
w=555; | |
for(;x--;){ | |
s=x%3?H++&1||-1:0; | |
// exisiting || new portion of tracks + distance of the "particle" | |
c[H&1023]=x&&c[H&1023]||8+Math.random()*h/2; | |
// Y coordinate & parallax | |
Y=Math.sin(H/511-Math.sin(H/511*3)*3)*48+s*c[H&1023]+h/2; | |
X=1023-x+(511-x)*Y/h; | |
c.globalAlpha=1; | |
q=170; | |
// "particles" | |
if (s) { | |
// Adjust the color based on the Y coordinate | |
q+=Y&31; | |
c.fillStyle='hsl('+q+',55%,200%)'; | |
if (H%511) { | |
// GRASS "particle" | |
// Adjust the color based on the Y coordinate, again | |
if (Y&1) | |
c.fillStyle='hsl('+q+',55%,20%)'; | |
// vertical strands of grass | |
c.fillRect(X+Math.sin(q++)*3,Y+Math.sin(q++),1,5); | |
c.fillRect(X+Math.sin(q++)*3,Y+Math.sin(q++),1,5); | |
c.fillRect(X+Math.sin(q++)*3,Y+Math.sin(q++),1,5); | |
// little bits of grass | |
c.fillRect(X+Math.sin(q++)*48,Y+Math.sin(q++)*3,1,1); | |
c.fillRect(X+Math.sin(q++)*48,Y+Math.sin(q++)*3,1,1); | |
c.fillRect(X+Math.sin(q++)*48,Y+Math.sin(q++)*3,1,1); | |
// TREE "particle" | |
// wih varying intensity of the forest | |
if (!(H%(9+Math.sin(H/511/3)*3|1))) { | |
// Get the height of the tree | |
z=Y&15; | |
z+=6; | |
Y-=z*6; | |
c.globalAlpha=.3; | |
// Draw multiple triangles to make up a pine tree | |
for (;z--;) { | |
c.beginPath(); | |
c.lineTo(X,Y); | |
c.lineTo(X-2*z+Math.sin(q++)*3,Y+6*z+Math.sin(q++)*3); | |
c.lineTo(X+2*z+Math.sin(q++)*3,Y+6*z+Math.sin(q++)*3); | |
c.fill(); | |
} | |
} | |
} else { | |
// TEXT "particle" | |
c.fillText(['Cross browser','1kb demos','February 2015','JS1k 2015'][H/511&3],X,Y); | |
} | |
} else { | |
// tracks | |
c.fillStyle='hsl('+q+',55%,2%)'; | |
c.fillRect(X,Y,1,5); | |
c.fillRect(X,Y,5,1);Y+=2; | |
c.fillRect(X,Y,5,1); | |
// TRAIN | |
if(x==w){ | |
// wagons | |
X-=10; | |
c.fillRect(X,Y,20,-10); | |
// locomotive | |
if(x<511){ | |
c.fillRect(X,Y,10,-15);X+=15; | |
c.fillRect(X,Y,2,-15); | |
// steam | |
c.fillStyle='hsl('+q+',55%,200%)'; | |
c.globalAlpha=.3; | |
q=H; | |
z=9; | |
for(;z--;){ | |
c.fillRect(X+Math.sin(q++)*3,Y-6*z+Math.sin(q++)*3,z,z); | |
} | |
} else { | |
w-=15; | |
} | |
} | |
} | |
} | |
// Cut out JS1k typography | |
c.globalCompositeOperation='destination-in'; | |
H=Math.sin(H/511/2+10)*31+31; | |
H=H<3?9:H*H; | |
c.translate(511,h/2); | |
c.rotate(H/511+.1); | |
c.scale(H,H); | |
X=Y=-3; | |
c.beginPath(); | |
// J | |
c.moveTo(X,Y); | |
c.arc(X-2,Y+3,2,0,Math.PI/2,0); | |
// S | |
X+=2; | |
Y+=4; | |
c.moveTo(X,Y); | |
c.arc(X,Y-1,1,Math.PI/2,Math.PI/2*3,1); | |
c.arc(X,Y-3,1,Math.PI/2,Math.PI/2*3,0); | |
// 1 | |
X+=3; | |
c.moveTo(X,Y); | |
c.arc(X-2,Y-5,2,0,Math.PI/2,0); | |
// k | |
X+=2; | |
c.moveTo(X,Y); | |
c.lineTo(X,Y-6); | |
X+=3; | |
c.moveTo(X,Y); | |
c.arc(X-1,Y-2,1,Math.PI/2*3/2,Math.PI/2*3,0); | |
c.stroke(); | |
})() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment