I’ve been fooling with a favorite-color app as an Identity-tech testbed, and I wanted to reward people just a little for making the effort to pick and save and maybe share their own faves. I’d seen some of the flashy stuff that the cool kids are doing with HTML5 and even though I’m really a server-side guy it looked like fun, so I poked around.
What I discovered is that the HTML5 Canvas is easy to learn and easy to program, so I’m going to show you a little hack I did, not because there’s anything particularly wonderful about it, but just to try help convince anyone who hasn’t dived in that maybe they should.
Color basics · I’m sure most of you know this stuff, but bear with me for one paragraph for the sake of the rest. On computers colors are made up of three numbers, giving red, green, and blue values typically in a range from 0-255. So (0, 0, 0) is black, (255, 255, 255) is white, (255, 0, 0) is a harsh unforgiving red, and so on. [Actually they’re given as four values with the other one being the transparency, but let’s ignore that for now.]
The field just below is an instance of the nice JSColor chooser; so click on the “EEEEEE” and choose away.
The three squares over on the right represent Red, Blue, and Green, top to botton, and when you picked a color, they painted in its pure R, G, and B components. Which is sort of boring for most colors.
Click and we’ll repaint the RGB squares with pretty color maps. The top one shows all the colors that can be made with your color’s Red value, the second all the colors with its Blue value, and the last all the colors with its Green value.
But wait, didn’t you choose a color? Go ahead, give it a try.
How it works · The code is in a JavaScript file called rgb.js (hey, I suck at naming things). If you’re the kind of person who looks at code, go do that. It’s not rocket science! The only even-slightly-hairy bit is the color-morphing code, which is as it should be.
There are only a handful of APIs that you need for this sort of
thing Gradient#addColorStop
, Context#setFillStyle
and Context#fillRect
.
I’m not claiming that this JavaScript code is either idiomatic or good; I’m well out of my comfort zone. But that’s sort of the point; N00b.js ftw!
There’s an interesting technical point: I had three canvases to render and
I wanted to do it in parallel so I checked out Web Workers which have a nice
API but you can’t touch the DOM which makes them much less interesting. But in
one of the rare pleasant surprises in my decades of computer
programming, I noticed that firing off three different
setInterval
calls, one for each Canvas, pretty well achieves the
same effect. Because callbacks.
Pleasing · First of all, the performance. While I always try for efficiency, I had no insight, going in, as to what are considered JavaScript best practices for graphics performance. A little measurement revealed that each step of the morphing loop took 50ms or so, so I told it to run 50-ish times at 55ms intervals and the result is smooth on modern browsers (a bit less so on Firefox). Gotta like that.
Also, as a dynamic-typing guy, I was pleased when I refactored everything from a hash indexed by “R”, “G”, and “B” to an array indexed by 0, 1, and 2... and most of the code didn’t have to change, because in dynamically-typed languages it’s obvious what you mean. As a side effect, it got faster.
Gripes · Mind you, not everything’s perfect: The state of searchable online documentation is execrable. Many searches lead to W3Schools or HTMLCanvasTutorials or whatever. Eventually I discovered that while Mark Pilgrim has retired from the Net, someone has unretired his Dive Into HTML5, and it’s really quite good.
Also, anything you find in the Mozilla Developer Network or HTML5 Rocks is going to be useful.
Heresy · OK, at some point it has to be said: JavaScript sort of sucks. On the other hand, it’s the only language, sucky or not, that is embedded in the world’s most popular app-delivery platform, and the world’s most popular declarative-user-interface language. So it can afford to suck a lot while it laughs at peasants like me dissing it.
Who knows, maybe you’ll like coding in it. And even if you don’t, maybe you should try it anyhow.
[Prediction: I’m gonna get dozens of comments demonstrating that my JavaScript is stupid, ugly, and slow. Somehow, this is not disturbing my peace of mind.]