This week I was intrigued by my co worker Andor Salga trying to make a webgl page that was just an empty black canvas, but was still technically a webgl empty black canvas in as few characters as possible. It doesn’t HAVE to be black, though, just some colour of some sort.
Anyway, it ended up on twitter, and was passed around by a couple people and this is what we now have:
<canvas onclick=with(getContext('experimental-webgl'))clearColor(0,0,0,1),clear(16640)>
Please forgive the use of with
It is currently at 88 characters.
I challenge someone to reduce the character count.
I also figure this is a good chance to explain WebGL, how to set it up, and some of the dirty JavaScript tricks used here.
What you need to setup a WebGL context is a canvas, access to a reference of that canvas, three function calls, and a buffer bit seen as 16640 in the current version.
The function calls are getContext, clearColor, and clear.
getContext returns the object that clearColor and clear must be used on.
The buffer bit is actually a constant variable defined as COLOR_BUFFER_BIT, or 16384, or 0×4000, or 0100000000000000, or the bitwise operation 8<<11. With the decimal version being the smallest number of characters at 5. It is that one singular bit in the binary representation we are interested in, but I also found out that the DEPTH_BUFFER_BIT can also be turned on, usually written as COLOR_BUFFER_BIT | DEPTH_BUFFER_BIT giving us the decimal of 16640… still only 5 characters, but I am currently using… just because.
The practical and readable way to do what we need setup would be something like this:
<canvas id="canvas"></canvas> <script> var canvas = document.getElementById( "canvas" ); var graphics = canvas.getContext( 'experimental-webgl' ); graphics.clearColor( 0,0,0,1 ); graphics.clear( graphics.COLOR_BUFFER_BIT | graphics.DEPTH_BUFFER_BIT ); </script>
So how do we go from the above to 88 characters?
First if we drop the script in an event on the canvas element itself so we don't need to create a script element, and we no longer need to search for the element by id as it exists as the keyword "this". The only event I could get to respond in this context was onclick… so onclick it is.
Next is to drop the buffer bit and just use the pure value explained above.
If the string in the onclick event doesn't have any spaces, we don't need to put it in quotes. Good for us as we don't want to use spaces anyway.
Drop the . Valid HTML is far too long
The this word in this.getContext isn’t needed inside the onclick… the browser will find it.
Using with allows us to not have to attach clear and clearColour to an object, just so long as the object returned from getContext is inside the with parameters.
What with does is allows you to take an object as a parameter, and anything inside the following block of code that does not exist within that scope, the browser will then check if it exists inside the object supplied as a parameter. This function is dangerous and there is only ONE time to use this function, and that is when you are trying to make a WebGL page 88 characters
We should now have something that looks like this…
<canvas onclick=with(getContext(‘experimental-webgl’)){clearColor(0,0,0,1);clear(16640)}>
We are at 90 characters now.
To drop those extra two characters we need to make clearColor(0,0,0,1); clear(16640) one command, because just like any operation, if with has no curly braces, it will execute the next line, and end.
We are now going to pervert the ability to define multiple variables using a comma like “var i = 0, a = 1;” so if we drop our function calls in between the comma, it should work… in all the wrong ways… just drop the curly braces and turn the semi-colon into a comma like this “clearColor(0,0,0,1),clear(16640)” That is technically runnable JavaScript.
We now have 88 characters with this:
<canvas onclick=with(getContext('experimental-webgl'))clearColor(0,0,0,1),clear(16640)>
Again, I am challenging someone to make it less than 88 characters.