Kilian Valkhof

Front-end & user experience developer, Jedi.

Fancyzoom image gallery functionality

Javascript, 16 March 2009

Fancyzoom is pretty cool in a lot of ways, like it’s amazing zoom functionality modelled after OS X. The only thing missing was next and previous links for gallery functionality, so I implemented those.

How it works

This version is an edit of the original Fancyzoom, available at

I’m used to writing JavaScript with a library like jQuery or Prototype, but since Fancyzoom was library-free, I decided not to add additional dependencies. Turns out, regular JavaScript makes you type a whole lot more. Here’s what I did:

For next and previous links to work we need to know which images are next and previous, and even if there is a next or previous image. So on initialisation I compose an array of ‘candidate images’. When you then open an image, it checks the position of the current image in the array, and adds or hides the previous/next links accordingly. The first image doesn’t get a previous, the last image doesn’t get a next, everything in between gets both links.

When displaying the links, I add the corresponding image number to the previous and next links (current image number minus one for previous, and plus one for next). When you click either of the links, it finds the image in the array, sets up an onload event, and displays the loading spinner. Once the image is loaded, I remove the spinner and update the previous and next links.


Now, one of the cool things of Fancyzoom is it’s keystrokes. esc closes the image overlay, ctrl and alt are click-throughs (no overlay, just open the image). Like in OSX you can press shift while clicking to make the zoom effect go really slow. Since I was adding next and previous links, I wanted the arrow keys to work as well.

I started with PPK’s key reference page to see which charcode I had to use. PPK then gave me a smart tip: “Use keydown, not keypress. Saves you a lot of hassle.”. Fancyzoom used keypress, which indeed make things more annoying to do cross-browser. I changed it to keydown, and it worked without having to change any of the other code. In the end it worked so well that for kicks I also added the spacebar as a way to go to the next image.

The above is of course only a cursory view of the changes made, but the fancyzoom.js and fancyzoomhtml.js files themselves are well documented so with minimal JavaScript knowledge you should be able to follow what’s happening. (and if not, don’t hesitate to ask!)


Fancyzoom exists out of two files, and I added a third CSS file to it (which you can just copy/paste into your own css file)

License: this is free for personal use. For all other uses, refer to the full license in the fancyzoom.js file.

You can see it in action on the numerous software pages on Wakoopa, for example the Safari page or the Openoffice page.

Let me know what you think, and if you have improvements I’d love to hear them!

Thanks for Reading!

I am Kilian Valkhof, a front-end and user experience developer from the Netherlands.
Contact me or ping me on twitter.

  1. Sweet! nice job with the script.

    I was searching for the way to achieve the results of a “gallery” with FancyZoom.
    But there’s one thing that refrain me from using your modified script:

    1- There is no resizing from “next previous”
    (since my attached images are different a resizing is mandatory ; / )

    FancyBox achieves this but it conflicts with some other necessary script.
    Let me know if you eventually integrate the resizing script.

    Keep up the great job :)

  2. Hey Brian, that’s on my list of things to solve. Fancyzoom itself actually calculates the dimensions of the first clicked image, and applies that to each clicked image, and it’s quite hard for me to change that code without changing major parts of fancyzoom (which I’d rather not do)

  3. Hi Kilian,
    I just wanted to update this comment with the fact that fancybox actually works now with gallery view and is 99% similar to fancyzoom.

  4. Hi! Next and previous image wraps around the first 10 images. Tried to fix it, but found new bugs. The problem is this (times three):

    var imageNo = parseInt(imagenumber[imagenumber.length-1]);

    …which only selects the last digit of imagenumber.

  5. Hi!
    This sounds great! Do you have a demo for testing the UX before trying it out on my own server? Thanks!