OSX Screensaver emulation with Canvas: That’s Bean

OS X has a pretty little screensaver which takes a bunch of images and ‘drops’ them, spinning, onto the screen. Think of it like scattering photographs onto a table, one at a time.

Naturally, there’s a desperate need for a JavaScript/Canvas port of this functionality, resulting in the following:

I had to limit the video capture framerate a bit so the video makes it look less smooth than it actually is. Check it out running in your own browser here.

For obvious reasons I have called the code behind this Bean, and it’s all available up on Github.

For the curious, here’s a little explanation about how it works. Bean starts off with a blank canvas and a list of image urls, which it preloads before getting started. It then drops one image at a time, rotating it as it goes. Each falling image is called a Plunger, because it plunges.

Each Plunger gets a random position and rotation to end up in, and takes care of drawing itself to the canvas on each frame by calculating its current size and rotation as it falls away from you.

Drawing each Plunger image on every frame quickly starts to kill the CPU, so we take a frame snapshot every time a Plunger has finished its descent. This just entails drawing the completed Plunges first and then using Canvas’ getImageData API to grab the pixel data for the image.

This gives us a snapshot of all of the fallen Plungers, meaning we can just draw a single background image and the currently falling Plunger on each frame. This approach ensures the performance remains constant, as we are only ever drawing a maximum of 2 images per frame. Each time a Plunger finishes its descent a new snapshot is taken.

Bean attempts to draw a new frame roughly 25 times per second and modern browsers seem to handle this pretty well. Safari pulls around 60% of one core on my MacBook Pro, with Firefox somewhat less performant. Needless to say, I didn’t even bother trying to make this work with IE.

Here’s the code to set the Bean in motion. This is using a few bundled APOD images:

var bean = new Bean({
  imageUrls: [
    'images/DoubleCluster_cs_fleming.jpg',
    'images/NGC660Hagar0_c900.jpg',
    'images/filaments_iac.jpg',
    'images/m78wide_tvdavis900.jpg',
    'images/sunearthpanel_sts129.jpg',
    'images/NGC253_SSRO_900.jpg',
    'images/Ophcloud_spitzer_c800.jpg'
  ],
  canvasId : 'main',
  fillBody : true
});

bean.onReady(function(bean) {
  bean.start();
});

8 Responses to OSX Screensaver emulation with Canvas: That’s Bean

  1. Tom says:

    You could then run your screensaver in this! http://github.com/tlrobinson/WebSaver

  2. Myles Becker says:

    This is VERY cool…I’ve been doing a lot of reading lately about JS libraries and with the new things coming down the pike. I’ve been excited to see the advancement in the use of JS, and this was a great example. One quick question, though. For some reason, in Chrome, it only does one picture, whereas in other compliant browsers, I get the whole show. Do you know if there is anything odd that might be going on with the way this works in Chrome? Great work and I can’t wait to dig through your site more!
    -m-

  3. Ed Spencer says:

    @Myles I’d noticed that with Chrome too, not sure why it’s doing it. Feel free to fork the code and investigate đŸ™‚

  4. Pingback: NFJS 2010 Java Agility Event Series « TechnoBuzz

  5. Pingback: 20 Amazing Implementations of HTML5 Canvas

  6. Pingback: 20 Amazing Implementations of HTML5 Canvas « CSS Tips

  7. Pingback: 20 Amazing Implementations of HTML5 Canvas | Fly mini

  8. Pingback: 20 Amazing Implementations of HTML5 Canvas

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: