27
Sep
2010

Magnifying Glass Effect With jQuery

I was playing around with neat little effect. Turned out to be pretty easy with jQuery. I don’t consider this a tutorial of how to do this effect, so much as a quick write-up.

First, click here for a demo (opens a new window).
The Magnifying Glass Effect

HTML

First here’s the HTML:

<img id="main_image" title="The Mona Lisa" src="monaLisaSmall.jpg" alt="The Mona Lisa" />
<div id="glass">
   <div id="glass-image"></div>
</div>

Basically, I have the image in your standard <img> tag.  Then I have two nested <div>’s.  The outer one (id=”glass”) will have the magnifying glass graphic, and the inner one (id=”glass-image”) will have the magnified image.  You’ll see later that these div’s don’t need to be placed in any particular spot on the page (they’ll have absolute positioning).

CSS

And the styles associated with this:

<style type="text/css">
#glass {
   background-image:url('magglass.png');
   background-repeat:no-repeat;
   background-position:top left;
   width:250px;
   height:170px;
   padding-top:10px;
   padding-left:92px;
   margin:0;
   position:absolute;
   display:none; /* we don't want this to display when the page loads */
}
#glass-image {
   background-image:url('monalisaLarge.jpg');
   width:150px;
   height:150px;
   background-repeat:no-repeat;
   margin:0;
   padding:0;
   cursor:none; /* only works in some browsers */
}
</style>

Taking this bit by bit:  For the div#glass, I added the magnifying glass graphic as a non-repeating background image.  Since this div has no real content, I also set its width and height to correspond to the magnifying glass image.  The paddings are there to position the inner div (i.e. the magnified image).  Position is absolute because we’re going to moving this thing around, and the display is “none” because when you first go to the page, no image should show.

For the div#glass-image, we set the background image (non-repeating) to the larger “magnified” image.  What’s nice, is since this is in the CSS, it loads when the page does to help reduce delays later.  The width and height I set to 150px each&emdash;the size of the magnified area.  Whatever you use (e.g. if you use a different magnifying glass graphic), take note of it because it will become important for positioning in the javascript.  Lastly, I set the cursor to “none.”  Now depending on which browser you use, this may or may not do anything.  If it works, when you see the magnifying glass, you won’t see the little cursor arrow.  Otherwise, it will be smack in the middle.

Javascript with jQuery

And finally, here’s the Javascript code:

<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
$(document).ready(function() {

   /* bind mouseover event to this anonymous function */
   $("#main_image").mouseover(function(e) {
      $(document).mousemove(myMM); /* bind function to the mousemove event */
      $("#glass").fadeIn('fast'); /* and quickly fadeIn the magnifying glass */
   });
});
function myMM(e) {
   /* set variables with the width and height of the
       large and small versions of the picture */
   var W = 743;
   var H = 1155;
   var w = 192;
   var h = 300;

   /* create a few jQuery objects */
   var monaImage = $("#monaimage");
   var glassImage = $("#glass-image");
   var glass  = $("#glass");

   /* position the glass div such that it is
       centered at the current location of the mouse */
   glass.css("left",e.pageX-75-92+"px").css("top",e.pageY-75-10+"px");

   /* calculate the position of the mouse on the small image */
   var xs = e.pageX - monaImage.offset().left;
   var ys = e.pageY - monaImage.offset().top;

   /* calculate the position of the glass "background" (magnified image)
       this is the distance to center minus the position on the large image */
   var bx = glassImage.width()/2 - xs*W/w;
   var by = glassImage.height()/2 - ys*H/h;

   /* set the magnified image position */
   glassImage.css("background-position",bx+"px "+by+"px");

   /* if mouse off the image far enough that big image no longer shows... */
   if (bx<-W || by<-H || bx>150 || by>150) {
      monaImage.unbind('mousemove',myMM); /* unbind mousemove event */
      glass.fadeOut('fast'); /* hide magnifying glass */
   }
}
</script>

Here’s how this breaks down.  First, we’re using the jQuery library, so we need to import it.  That’s the first <script> import.  All of the initialization code is then set in an anonymous function that is binded to the document’s “ready” event.  This is similar to an “onload” event, except it doesn’t wait for all the images to load.  It instead executes onces the pages DOM is populated.

The first thing I do is attach an anonymous “mouseover” event handler to the “#main_image” div (which is the smaller version of the picture, see the HTML). All the mouseover callback does is bind the “mousemove” event to the function myMM() and make the magnifying glass div appear using jQuery’s fadeIn() effect.

Then every time the mouse is moved, we need to adjust the magnified image. This is handled in the function myMM(). The input passed to myMM (I called it “e” for event) is a Javascript event object. This contains all sorts of information regarding the event that called the function (the mousemove). After setting some variables with the dimensions of the actual Mona Lisa image (enlarged and regular) I set the position of the magnifying glass to be centered over the mouse. The mouse position is obtained using the e.pageX and e.pageY properties.

Next we calculate the position of the mouse relative to the upper left corner of the image. Scaling these numbers using the relative dimension of the large image to the regular-sized image gives us the position the mouse should be over the magnified image! However, we need to position as the background to the “glass-image” div relative to the center of the glass.

Finally, if the mouse leaves the image area, we want the magnifying glass to go away. After doing that I decided to actually not have it go away until the the large image has left the view. The if-statement give this condition. If this happens, we make the magnifying glass fade away, and we unbind the myMM function from the “mousemove” event.

Rounded corners using CSS3

The magnifying glass is square because the shape of div’s must be rectangular. However, the new standard called CSS3 allows for rounded corners! This means we can make a circle! By changing just the image used for the magnifying glass, a few dimensional changes for our new graphic, and added some CSS3, we can have a normal looking round magnifying glass.

Here’s a demo with the rounded corners. It should work in Firefox, Chrome, Safari, and IE9.

And here’s the change to part of the CSS.

#glass-image {
	background-image:url('http://trent.marginallystable.com/wp-content/uploads/2010/09/monalisaLarge.jpg');
	width:150px;
	height:150px;
	border-radius: 75px; /* the new style, that's it! */
	-moz-border-radius: 75px; /* except you need to do this for mozilla */
	background-repeat:no-repeat;
	background-color:#fff;
	margin:0;
	padding:0;
	cursor:none;
}
  • Duderussi

    Is the image in the magnifying glass supposed to change? cause it doesn’t… not with chrome anyway.

  • http://trent.marginallystable.com Trent Russi

    Weird… it used to. Try refreshing the page.

  • Stereovaritone

    Hey thanks very much—this is great stuff! Is there a version with a round magnifying glass rather than a square one?

    • http://trent.marginallystable.com Trent Russi

      Yup!  Check out the section at the bottom called “Rounded corners using CSS3″.  It only works in newer browsers though.

Blog Archives

Recent Bookmarks

Books I’m Reading

Latest Tweets