CSS/DOM-based Draggable Magnifiers #

I'm currently working on a project where I need to display some images (specifically, photographs of book bindings) at various magnification levels, so that even the most expert user (presumably, a book geek) will be satisfied with the amount of detail visible. This is normally done by generating a few versions of the image, and allowing the user to click through them. However, this can get rather cumbersome due to multiple windows and scrolling.

I came up with a solution off the top of my head, but in retrospect I'm guessing I was subconsciously influenced by KTP 3.0's Lens f/x Photoshop filters of the mid 1990's (which were in turn based on Magic Lenses). A bit of Googling turned up a Flash version of the concept, but so far nothing in pure HTML. The basic idea is to have a draggable magnified portion, allowing the user to see a reasonable amount of detail without losing context or needing to scroll.

The end result is the magnifier, a collection of JavaScript bits that adds a lens widget to a regular image. This follows the separation of behavior and structure school of thought (not that this is a new concept; it was also used when enhancing our sidebar).

Implementation-wise, there isn't that much to it. The magnifier is an absolutely positioned (within its parent) <div> that has as its background image the zoomed in version of the binding. By changing its background-position CSS attribute within is onmousemove handler (along with its position of course), we can give the impression of showing only a slice of a larger image. Since we're being dynamic anyway, we can support different sizes (as well as turning it off altogether). Finally, we added a drop-shadow by having a separate <div> in a lower layer that follows it around. Shadows are done with three hand-made images, though presumably one could make them flexible-size wise, by separating them into corner and repeated areas, although this would require much more bookkeeping, code-wise. Another alternative to consider is to put the drop shadow image in front, and use it to provide a fancier border, or even a non-rectangular cut-out, like the in the KPT example.

Browser-wise, this appears to work in everything that I've thrown at it (MSIE, Firefox, Safari, and Mozilla). MSIE required a bit of hacking in order to get it to display PNG alpha channels properly (the usual story) and for extracting the coordinates out of the mouse events. Safari seems to be ignoring the background-repeat: no-repeat property of the magnifier, but that is only an issue when the magnifier is close to the edges, and is therefore forgivable.

Update: This follow-up may be worthwhile reading as well.


Beautiful work! Very nice job.
Looks very nice!
Wow, great implementation, for maps especially... compliments!
Cool. This is just exactly what our client wants.
Is there any way to make the magnifier stop at the boundaries of the image and not keep going?
Very good.

It's possible to use a client-side map for the zoomed image?
Get my congratulations for your well-done job.
It exactly suits my needs, except in that my three images in each page are 200px wide, and I would need to offer the details in a square of 100px as sides (no medium or large squares, I would only need a small enlargement square). So I'm wondering if there is a simplified version of your javascript code or at least a commented version upon which I could try myself to modify and simplify. Many thanks, anyway, M.
I agree, this really is great work... but can you tell us how to customise for different sized images?
Nice tool Mihai. It's similar to Magic Magnify which magnifies the image upon hover. http://magictoolbox.com/magicmagnify/

It's free for non-commercial websites or £15 for a commercial site.
is there a way to load magnifier on the "off" position?
Hi, great script. I was wondering... how can I have two different images on the same page and magnify them in the same way? Thanks.
This has an issue, at least in FF 3: left button is also interpreted as image drag. Fix is to add 'event.preventDefault()' to MagnifierMouseDown. Then it works like a charm.
Is there a download?
This is simply magical.

Post a Comment