A few years ago a bought a domain name for my sister for her birthday. Every year since, I’ve been making a sort of interactive birthday card there for her and in the process, teaching myself something new.
Last year, I made a little app that would display videos from a few of her favourite k-pop bands, using om.next (since that was something we’d been considering using at work).
This year, I decided to do something a little more interesting, both for me and her and make something actually interactive. I was thinking that it eventually could even be a game, time allowing (maybe next year?).
To start, I was thinking I’d have a picture of a baluchitherium1 on the page that one could move around with the arrow keys (and later, could be like, dodging obstacles or whatever). One of the things I’ve been trying to practice this year is being comfortable drawing stuff, so I used the fantastic pixel art tool aseprite to draw an animated gif of a baluch:
It’s simple enough to put this on the page, the use the arrow keys to move it around. This was probably good enough for a birthday card, but I wanted to do something more challenging…
I had read a great post by eevee about Perlin noise not too long ago and thought it was interesting, but I didn’t full get how the algorithm worked. The best way to understand an algorithm is to implement it, so I decided I’d make the background that the baluch was flying over be Perlin noise generated on-the-fly.
I started by trying to do a straightforward port of eevee’s python implementation to ClojureScript. It took me a while to get things working properly, but it was mostly a mechanical transformation of Python to ClojureScript (it was pretty fun to translate mutating loops into reduces and such though).
This obviously would not stand, so I had to find a way around this.
I didn’t feel like trying to optimize the algorithm (although that would definitely be a good thing to try to do), so I needed to somehow move the computation off the main thread.
I first thought I could just use
core.async (which is a great library), but realized quickly that that wasn’t the right approach –
Fortunately, there’s a solid ClojureScript library called servant that wraps WebWorker stuff and makes in fairly easy to have some ClojureScript code run in a background thread!
I remain slightly unclear about how data gets passed in and out of the
servant functions, but eventually I got things working by just passing in primitive data and encoding the return values of the functions using
The background updates fairly infrequently (depending on how fast your browser can render each frame), but it works!
Long story, but basically we have a family tradition of everyone having an animal, and for some reason my mum’s branch of the family has weird animals - my sister and one of my brothers are baluchitherium, these weird prehistoric creatures. I happen to be a pterodactyl. ↩
Probably don’t leave it open too long though - it will devour as much CPU as it can to push out the noise. ↩