Submit your widget

Image Highlighting and Preview with jQuery

Created 14 years ago   Views 10111   downloads 1735    Author n/a
Image Highlighting and Preview with jQuery
View DemoDownload
113
Share |

We will highlight images on a delayed hover and offer a preview mode which will enlarge and center the bigger version of the image on the screen.

The Markup

 

For the HTML structure we simply need to consider the image and its class. The image can be placed anywhere in your website:

<img src="images/thumbs/1.jpg" alt="images/1.jpg" class="ih_image"/>

 

 

We use the alt attribute to add the reference to the bigger image.

We will also add an overlay element before the body ends:

 

<div id="ih_overlay" class="ih_overlay" style="display:none;"></div>

 

 

The structure that we will be creating with the JavaScript will look as follows:

<div id="ih_clone" class="ih_image_clone_wrap">
 <span class="ih_close"></span>
 <img class="preview" src="images/1.jpg">
</div>

 

 

This structure will not be placed in our HTML – it will be created dynamically.

Now, let’s take a look at the style.

The CSS

First, we will define the style for the overlay:

.ih_overlay{
 position:fixed;
 top:0px;
 left:0px;
 right:0px;
 bottom:0px;
 background:#000;
 z-index:10;
 opacity:0.9;
 filter:progid:DXImageTransform.Microsoft.Alpha(opacity=90);
}

 

 

The filter property is used for applying transparency in IE. We make the overlay fixed in order to always be shown, even if we scroll the page.

The image that we want to apply our effect to will have the following style:

 

img.ih_image{
 margin:10px 0px;
 position:relative;
 -moz-box-shadow:1px 1px 4px #000;
 -webkit-box-shadow:1px 1px 4px #000;
 box-shadow:1px 1px 4px #000;
 opacity:0.7;
 filter:progid:DXImageTransform.Microsoft.Alpha(opacity=70);
}

 

 

It’s pretty plain, we just add some box shadow to it.

In our JavaScript we will create a wrapper that contains a clone of the image that we are hovering. It will get the same positions as the current image. That’s why we do not define the top and left here, but dynamically in the JS.

 

.ih_image_clone_wrap{
 position:absolute;
 z-index:11;
}

 

 

We will also add some spans with icons that will either show a magnifying glass, a loading image or a cross. We define all common properties as follows:

 

.ih_image_clone_wrap span.ih_zoom,
.ih_image_clone_wrap span.ih_loading,
.ih_image_clone_wrap span.ih_close{
 position:absolute;
 top:10px;
 right:10px;
 width:24px;
 height:24px;
 -moz-border-radius:6px;
 -webkit-border-radius:6px;
 border-radius:6px;
 opacity:0.8;
 cursor:pointer;
 -moz-box-shadow:1px 1px 2px #000;
 -webkit-box-shadow:1px 1px 2px #000;
 box-shadow:1px 1px 2px #000;
 z-index:999;
 filter:progid:DXImageTransform.Microsoft.Alpha(opacity=80);
}

 

 

The specific properties for each class, like the background, will be defined as follows:

 

.ih_image_clone_wrap span.ih_zoom{
 background:#000 url(../icons/zoom.png) no-repeat center center;
}
.ih_image_clone_wrap span.ih_loading{
 background:#000 url(../icons/loader.gif) no-repeat center center;
}
.ih_image_clone_wrap span.ih_close{
 background:#000 url(../icons/close.png) no-repeat center center;
}
.ih_image_clone_wrap img{
 opacity:0.7;
 -moz-box-shadow:1px 1px 10px #000;
 -webkit-box-shadow:1px 1px 10px #000;
 box-shadow:1px 1px 10px #000;
 filter:progid:DXImageTransform.Microsoft.Alpha(opacity=70);
}

 

 

The full sized image that we will load on top of the thumbnail, will have the following style:

 

.ih_image_clone_wrap img.preview{
 opacity:1;
 position:absolute;
 top:0px;
 left:0px;
}

 

 

And now, let’s add some magic!

The JavaScript

In our jQuery function we will start by defining a variable to control the timing of the highlight effect.
When we hover over an image with the specific class we create our div with the class ih_image_clone_wrap and define its position by getting the position of the current image.

 

/**
* timeout to control the display of the overlay/highlight
*/
var highlight_timeout;

/**
* user hovers one image:
* create a absolute div with the same image inside,
* and append it to the body
*/
$('img.ih_image').bind('mouseenter',function () {
  var $thumb = $(this);

  var $clone = $('<div />',{
   'id'  : 'ih_clone',
   'className' : 'ih_image_clone_wrap',
   'html'      : '<img src="' + $thumb.attr('src') + '" alt="' + $thumb.attr('alt') + '"/><span class="ih_zoom"></span>',
   'style'  : 'top:' + $thumb.offset().top + 'px;left:' + $thumb.offset().left + 'px;'
  });

  var highlight = function (){
   $('#ih_overlay').show();
   $('BODY').append($clone);
  }
  //show it after some time ...
  highlight_timeout = setTimeout(highlight,700);

  /**
  * when we click on the zoom,
  * we display the image in the center of the window,
  * and enlarge it to the size of the real image,
  * fading this one in, after the animation is over.
  */
  $clone.find('.ih_zoom').bind('click',function(){
   var $zoom = $(this);
   $zoom.addClass('ih_loading').removeClass('ih_zoom');
   var imgL_source = $thumb.attr('alt');

   $('<img class="ih_preview" style="display:none;"/>').load(function(){
    var $imgL = $(this);
    $zoom.hide();
    var windowW = $(window).width();
    var windowH = $(window).height();
    var windowS = $(window).scrollTop();

    $clone.append($imgL).animate({
     'top'   : windowH/2 + windowS + 'px',
     'left'   : windowW/2  + 'px',
     'margin-left' : -$thumb.width()/2 + 'px',
     'margin-top' : -$thumb.height()/2 + 'px'
    },400,function(){
     var $clone = $(this);
     var largeW = $imgL.width();
     var largeH = $imgL.height();
     $clone.animate({
      'top'   : windowH/2 + windowS + 'px',
      'left'   : windowW/2  + 'px',
      'margin-left' : -largeW/2 + 'px',
      'margin-top' : -largeH/2 + 'px',
      'width'   : largeW + 'px',
      'height'  : largeH + 'px'
     },400).find('img:first').animate({
      'width'   : largeW + 'px',
      'height'  : largeH + 'px'
     },400,function(){
      var $thumb = $(this);
      /**
      * fade in the large image and
      * replace the zoom with a cross,
      * so the user can close the preview mode
      */
      $imgL.fadeIn(function(){
       $zoom.addClass('ih_close')
         .removeClass('ih_loading')
         .fadeIn(function(){
         $(this).bind('click',function(){
          $clone.remove();
          clearTimeout(highlight_timeout);
          $('#ih_overlay').hide();
         });
        $(this).bind('click',function(){
         $clone.remove();
         clearTimeout(highlight_timeout);
         $('#ih_overlay').hide();
        });
       });
       $thumb.remove();
      });
     });
    });
   }).error(function(){
    /**
    * error loading image
    * maybe show a message like
    * 'no preview available'?
    */
    $zoom.fadeOut();
   }).attr('src',imgL_source);
  });
}).bind('mouseleave',function(){
 /**
 * the user moves the mouse out of an image.
 * if there's no clone yet, clear the timeout
 * (user was probably scolling through the article, and
 * doesn't want to view the image)
 */
 if($('#ih_clone').length) return;
 clearTimeout(highlight_timeout);
});

/**
* the user moves the mouse out of the clone.
* if we don't have yet the cross option to close the preview, then
* clear the timeout
*/
$('#ih_clone').live('mouseleave',function() {
 var $clone = $('#ih_clone');
 if(!$clone.find('.ih_preview').length){
  $clone.remove();
  clearTimeout(highlight_timeout);
  $('#ih_overlay').hide();
 }
});