Christmas JS1k
December 29, 2010
Gifted the benefit of R&D time at work, at the end of 2010 I submitted an entry to the Christmas JS1k contest along with my fellow POPsters. I got to geek out and spend work time creating something cutting-edge that I'm pretty proud of: a canvas drawing app!
My goals were to:
- Learn enough native JS to complete an entry(!)
- Use canvas
- Keep usability in mind since it tends to go out the window when shaving off bytes: cursors, tip text, etc.
To see what I ended up with (as well as a super fancy jQuery version that was my starting point), you can play with a demo here.
What is JS1k, you ask? From the source: "the object of this competition is to create a cool JavaScript "application" no larger than 1k. Starting out as a joke, the first version ended with a serious amount of submissions, prizes and quality."
View my uncompressed JS1k entry
<script type="text/javascript">
var c = document.getElementsByTagName('canvas')[0];
var b = document.body;
var a = c.getContext('2d');
</script>
<script type="text/javascript">
d=document;
h=d.createElement('h1');
h.innerHTML='Draw.';
b.insertBefore(h, c);
// context abbreviation loop
for($ in a){
a[$[0]+($[6]||$[2])]=a[$];
}
// commonly used integers
x=150;
y=120;
c.width=c.height=x*2;
k='background:#';
z=c.style;
z.cssText=k+"416012";
// pen color array
A=['000','0e943a','C0C0C0','C5B358'];
co = '#'+A[0];
//create color squares
for(i=0;i<4;i++){
sqr(A[i]);
}
// not overlapping circle
oLp = 0;
// not drawing
drw = 0;
onmousemove=function(e){
// get mouse/canvas properties
gTs(e,c)
// mouse intersects circle
if(dI(eX-oL, eY-oT)){
z.cursor='crosshair';
oLp = 1;
// if the mouse is down, leave a mark
if (drw == 1) {
with(a){
ln(eX-oL, eY-oT); // lineTo
strokeStyle = co;
sr() // stroke
}
}
}
// mouse off circle
else {
z.cursor='default';
oLp = 0;
drw = 0
}
};
onmouseup=function(){ drw = 0}
onmousedown=function(e){
// if overlapping
if(oLp) {
gTs(e,e.target)
drw = 1;
with(a){
ba(); // beginPath
lineWidth=3;
mv(eX-oL, eY-oT) // moveTo
}
}
}
// get target values
function gTs(e,t){
eX=e.pageX;
eY=e.pageY;
oL=t.offsetLeft;
oT=t.offsetTop;
}
// create square: k='background:#', v=color from array
function sqr(v){
n=d.createElement('a');
n.id=v;
n.style.cssText=k + v +';cursor:pointer;height:15px;float:left;margin:0 8px 0 0;width:15px';
n.onclick=function(e){co='#'+e.target.id}
b.appendChild(n)
}
// does intersect: a=pageX, b=pageY, x=circleX/circleY, y=circleRadius
function dI(a,b) {
f = a-x;
g = b-x;
return f*f+g*g <= y*y
}
// create sphere
with(a){
g=cR(x,y,0,x,y,200); // createRadialGradient
g.addColorStop(0,'#f00');
g.addColorStop(1,'#600');
ba(); // beginPath
fillStyle=g;
ac(x, x, y, 0, Math.PI*2,false); // arc
ca(); // closePath
fl() // fill
}
</script>