Wednesday, March 24, 2010

JavaScript and jQuery Image Magnifier

In an alternate version to the Image Magnification tool from my previous post, I have created another magnification tool which works exactly like a magnification glass moving over the picture. This tool is more concise and easy to use then the previous one where a separate popup with the same aspect ratio was used to display the image. Here the magnified image section keeps moving with the mouse providing an exact magnification glass effect. You also don’t need any separate CSS for the magnification window.

Why should you use this Image Magnification tool:

  1. Zero coding required.
  2. No CSS required at all.
  3. Can be triggered automatically or manually from the image.
  4. Works on images of any resolution or aspect ratio.

For testing I have used a very high resolution image of Taj Mahal (4300x2724 pixels).

This is how it looks in action:JavaScript Image MagnifierThe JavaScript code is very easy to understand and modify. The only thing you will need to modify for automatic magnification functionality is the $(document).ready() function where the jQuery Selectors needs to be modified to point to the images in your HTML document. You can also change the magnifier window size by changing the magnifier_size variable in the JavaScript Code.

Place the following JavaScript Code in the head section of your HTML page:
<script type="text/javascript"  src="http://code.jquery.com/jquery-latest.js"></script> 
<script type="text/javascript">
/* Developed by: Abhinay Rathore [web3o.blogspot.com] */
$(document).ready(function(){
      $(".magnify").mousemove(function(event){ moveMagnifier(this, event); });
      $(".magnify").mouseout(function(event){ hideMagnifier(); });
});

var magnifier_size = 200; //Change Magnifier size here.
var cursor_offset = 10; //Change Cursor Offset here.
var ratio, mHalf, pic_offset;
function showMagnifier(picId, e){ //Show Magnifier
      hideMagnifier();
      //Create and add magnified image to the body
      var magnifier = document.createElement("img");
      magnifier.id = "magnifier"
      magnifier.src = picId.src;
      magnifier.style.position = "absolute";
      document.body.appendChild(magnifier);
      //Calculate size ratio of original and magnified images
      ratio = magnifier.width / $(picId).width();
      mHalf = magnifier_size / 2;
      pic_offset = $(picId).offset(); //Picture offset
      //Get mouse position on the image
      var picX = e.pageX - pic_offset.left;
      var picY = e.pageY - pic_offset.top;
      clipImage(magnifier, picX, picY); //Clip the magnified image
      //Position the magnified image next to mouse cursor
      positionImage(magnifier, picX, picY, e.pageX, e.pageY)
}
function moveMagnifier(picId, e){ //Move Magnifier
      var magnifier = document.getElementById("magnifier");
      if(magnifier){ //If magnified image exists...
            //Get mouse position on the image
            var picX = e.pageX - pic_offset.left;
            var picY = e.pageY - pic_offset.top;
            clipImage(magnifier, picX, picY); //Clip the magnified image
            //Position the magnified image next to mouse cursor
            positionImage(magnifier, picX, picY, e.pageX, e.pageY)
      } else { //If magnified image does not exist...
            showMagnifier(picId, e);
      }
}
function clipImage(magnifier, picX, picY){ //Clip magnified image...
      var centerX = picX * ratio;
      var centerY = picY * ratio;
      $(magnifier).css("clip", "rect(" + Math.round(centerY - mHalf)  + "px," +
                                                   Math.round(centerX + mHalf) + "px," +
                                                   Math.round(centerY + mHalf) + "px," +
                                                   Math.round(centerX - mHalf) + "px)");
}
function positionImage(magnifier, picX, picY, pageX, pageY){  //Position magnified image...
      $(magnifier).css({'top': pageY - (picY * ratio) + mHalf + cursor_offset,
                         'left': pageX - (picX * ratio) + mHalf + cursor_offset});
}
function hideMagnifier(){ //Hide Magnifier
      $("#magnifier").remove(); //Remove the Magnifier Image
}
</script>

The CSS code I have used here is only to display the original images on the HTML page. You can use you own CSS styles and use the image class in the jQuery Selectors. You actually don’t need any CSS code to use this tool. You can use it directly by assigning mouse events to your images manually.
<style type="text/css">
.magnify{
      width: 500px;
      height: auto;
      cursor: crosshair;
}
</style>

The HTML Code for this image magnifier is very simple to use. If you are using CSS layout then you can use jQuery Selectors to select the images automatically.
<img class="magnify" src="taj.jpg" />

If you want to assign Magnification feature to your images manually, you can add mouse events to your images as shows below: 
<img src="taj.jpg" style="width:500px" onmousemove="moveMagnifier(this, event)" onmouseout="hideMagnifier()" />

Thursday, March 18, 2010

Dynamic Popup Image Zoom with Magnifying Glass Effect using jQuery

Lot of times on your webpage you might want to include an image of a very large resolution but the users then have to open that image in a new window to view its details in actual resolution. In situations like that, comes in handy some kind of image zoom tool which can display the actual image resolution/details just by hovering your mouse over that. These kind of image popup zoom boxes can be seen on some merchant websites where they don’t want the customers to navigate away from their product page.

      I have implemented a very easy to use image zoom tool where the popup appears just next to the image and the zoomed image pans based upon the mouse position on the original image giving the magnifying glass effect. This tool works with images of any resolution and aspect ratio. The zoom popup box width can be adjusted using the JavaScript and the height is automatically adjusted as per the aspect ratio of the original image.

Why should you use this image zoom tool:

  1. Zero coding required.
  2. No strict HTML layout/structure needed to place the images in the document.
  3. Works with images of any resolution and aspect ratio.
  4. Just by modifying the jQuery selectors in $(document).ready() function you can assign zoom property to the images on your page. For example: to assign zoom effect to all the images on your page, just use $("img").mouseover() selector.
  5. Zoom area width can be easily adjusted using the JavaScript zoom_width variable and the height is adjusted automatically based upon the image aspect ratio.
  6. There is not need to have a separate thumbnail for the images to be zoomed.

Here are a few examples of how the zooming looks like:Dynamic Popup Image Zoom with Magnifying Glass Effect Dynamic Popup Image Zoom with Magnifying Glass EffectDynamic Popup Image Zoom with Magnifying Glass Effect

The JavaScript code is very easy to incorporate and robust enough to handle any kind/size of images. You can use your own CSS/HTML to place the pictures in your document. When the page loads for the first time, the $(document).ready() function assigns mouse events to the pictures you want to zoom. You just need to change the jQuery selectors in the $(document).ready() function to select the images to zoom if you have a different CSS/HTML layout on your page.

      The showZoom() function is triggered when the user moves the mouse over the image. showZoom() creates the zoom box with the image of actual resolution inside it and calculates the margin ratios required for panning the zoomed image. The moveZoom() function is then used the keep track of the mouse position on the actual image and pan the image in zoom box based upon the mouse position on the actual image (Magnifying Glass Effect). hideZoom() removes the zoom box and its child elements when the user moves the mouse out of the image thumbnail.

JavaScript Code:
<script type="text/javascript"  src="http://code.jquery.com/jquery-latest.js"></script> 
<script type="text/javascript">
/* Developed by: Abhinay Rathore [web3o.blogspot.com] */
$(document).ready(function(){
      $(".pic_zoom > img").mouseover(function(){ showZoom(this); });
      $(".pic_zoom > img").mousemove(function(event){ moveZoom(this, event); });
      $(".pic_zoom > img").mouseout(function(){ hideZoom(); });
});
var zoom_width = 500; //Change zoom area width here
var zoom_left_ratio, zoom_top_ratio;
function showZoom(picId){ //Show Zoom window 
      hideZoom();

      //Create and add zoom div (with image) to the body
      var zoom = document.createElement("div");
      zoom.id = "zoom";
      var img = document.createElement("img");
      img.src = picId.src;
      zoom.appendChild(img);
      document.body.appendChild(zoom);
      //Set zoom div height proportionally to the width specified above.
      var offset = $(picId).offset();
      $(zoom).width(zoom_width);
      $(zoom).height(Math.round($(zoom).width() * $(picId).height() / $(picId).width()));
      $(zoom).css({'top': offset.top, 'left': offset.left + $(picId).width() + 10});
      //Calculate zoom ratio
      zoom_left_ratio = ($(img).width() - $(zoom).width()) / $(picId).width();
      zoom_top_ratio = ($(img).height() - $(zoom).height()) / $(picId).height();
}
function moveZoom(picId, e){ //Move Zoom image
    var zoomed_img = $("#zoom > img");
    var zoom = $("#zoom");
    var pic_offset = $(picId).offset();
    //Get mouse position on the image
    var picX = e.pageX - pic_offset.left;
    var picY = e.pageY - pic_offset.top;
    //Calculate margins for the zoomed image
    var leftMargin = -1 * Math.round(picX * zoom_left_ratio);
    var topMargin = -1 * Math.round(picY * zoom_top_ratio);
    //Ser margins for the zoomed image
    zoomed_img.css('left', (leftMargin > 0) ? 0 : leftMargin);
    zoomed_img.css('top', (topMargin > 0) ? 0 : topMargin);
}
function hideZoom(){ //Hide Zoom window
      //Remove the zoom div and its children from the body
      $("#zoom").children().remove();
      $("#zoom").remove();
}
</script>

A very minimal amount of CSS code is used to define the div tag holding the images and the properties for the zoom box. If you use your personalized CSS, then there is no need to modify the zoom box properties.

CSS Code:
<style type="text/css">
.pic_zoom {
      border: 1px solid #9CF;
      width: 210px;
}
.pic_zoom img{
      width: 200px;
      height: auto;
      margin: 5px;
      cursor: crosshair;
}
#zoom {
      position: absolute;
      border: 1px solid #9CF;
      overflow: hidden;
}
#zoom img{
      position: absolute;
}
</style>

The HTML code can be modified very easily based upon the layout and style of your HTML document. you can use your own containers or place the images directly on the document. For any modifications in the CSS/HTML layout, the jQuery selectors in the $(document).ready() function needs to be modified to assign the mouse events to the images for zooming them.

HTML Code:
<div class="pic_zoom">
    <img src="WaterLilies.jpg" />
    <img src="goldengate.jpg" />
    <img src="city.jpg" />
</div>

Tuesday, March 16, 2010

Dynamic Round Cornered Tab Menu without using images

Tab menus are one of the most common form of navigation buttons used in web design, the most common of which is usually a round cornered tab. To make round cornered tabs, you will usually have to use images for the corners/edges to get the effect. I have implemented a dynamic Tab menu using jQuery and CSS without using images. Taking the concept from my previous post on Round Cornered Div tags without using images, I have implemented this round cornered tab menu using the nifty power of jQuery which makes it dynamic in nature.

Why should you use this Tab Menu:

  1. VERY easy to use and modify.
  2. Easy to understand and modify the CSS.
  3. Faster to load because no images are used.
  4. The changeTab() function can change the tab selection dynamically.
  5. This Tab Menu can be used with Ajax like functionalities as well where the contents can be loaded dynamically based upon the click event.
  6. Can be used with your dynamic code just by setting the <li> class to ‘sel’ using your code.
  7. Scalable to any size by modifying the CSS only.

This is how the tabbed menu looks like:image

How does it work: The trick is pretty simple; The header for every tab is set dynamically by using jQuery. When a tab selection is made, the inactive tab header is replaced by the active tab header and vice versa.

The JavaScript/jQuery code:
The jQuery code is pretty simple to understand because only selectors are used to select the appropriate tab and change the CSS styles and colors. When the page loads for the first time, rounded corners and CSS is applied to the li tag with class ‘sel’ and a click event is assigned to all the p or a tags inside the Tab Menu.
    The changeTab() function is used to handle the tab click event for swapping the active and inactive tabs. Along with that any kind of Ajax calls or page redirects can be made based upon the tab button clicked. The TabRoundedCorners() function is used to populate the Tab header based upon active or inactive type.

Put the following code in the head section of your page:
/* Developed by: Abhinay Rathore [web3o.blogspot.com] */
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
<script type="text/javascript">
$(document).ready(function(){
      //Add Inactive tab round corners where class not equals to 'sel'
      $("#tabs > ul > li[class!='sel']").prepend(TabRoundedCorners('inactive'));
      //Add Active tab round corners where class equals to 'sel'
      $("#tabs > ul > li[class='sel']").prepend(TabRoundedCorners('active'));
      //Select tab where li class equal to 'sel'
      $("#tabs > ul > li[class='sel'] > p").addClass('sel');
      $("#tabs > ul > li[class='sel'] > a").addClass('sel');
      //Assign click event to all the tabs
      $("#tabs > ul > li > p").click(function(){ changeTab(this) });
      $("#tabs > ul > li > a").click(function(){ changeTab(this) });
     
});

function changeTab(tabId)
{
      //Remove Active tab round corners where class equals to 'sel'
      $("#tabs > ul > li[class='sel']").children(":first-child").remove();
      //Add Inactive tab round corners where class equals to 'sel'
      $("#tabs > ul > li[class='sel']").prepend(TabRoundedCorners('inactive'));
      //Remove 'sel' class for the currently selected tab
      $("#tabs > ul > li[class='sel']").children().removeClass('sel');
      $("#tabs > ul > li[class='sel']").removeClass('sel');
      //Remove Inactive rounded corners from clicked tab
      $(tabId).parent().children(":first-child").remove();
      //Add 'sel' class to p tag under clicked tab
      $(tabId).parent().children(":first-child").addClass('sel');
      //Add 'sel' class to the clicked tab li
      $(tabId).parent().addClass('sel');
      //Add Active tab round corners to the clicked tab
      $(tabId).parent().prepend(TabRoundedCorners('active'));
     
      // Perform Action based upon the selected tab button
      // if you are using Ajax to change your page content
      switch($(tabId).text())
      {
            case "Home": break;
            case "Work": break;
            case "Personal": break;
            case "Blog": break;
            case "About": break;
            case "Contact": break;
      }
}

function TabRoundedCorners(type){
      return "<div id=\'" + type + "_tab_rounder\'>" +
            "<div class=\'top_left\'><div class=\'top_left_inside\'>&#8226;</div></div>" +
            "<div class=\'top_right\'><div class=\'top_right_inside\'>&#8226;</div></div>" +
            "</div>";
}
</script>

CSS code:
The CSS code contains very minimal amount of CSS for the tabs and the round cornered tab headers. There are two sets of round cornered header CSS for active and inactive tabs. To make any modifications in the size of the tabs should be done to both these sets for consistency. To change the Tab colors, you only need to replace LightBlue and Gainsboro with your custom colors values in the whole CSS section.

Place the following CSS code in the head section of your page:
<style type="text/css">
<!--
#tabs {
      margin: 0px;
      padding: 0px;
}
#tabs ul
{
      margin: 0px;
      padding: 0px;
      list-style: none;
}
#tabs li
{
      margin: 0px 1px 0px 1px;
      float: left;
      padding: 0px;
      /*Set width to 'auto' for automatic width*/
      width: 80px;
}
#tabs p, #tabs a
{
      display: block;
      color: #069;
      font-family: Verdana, Geneva, sans-serif;
      font-size: small;
      text-decoration: none;
      background-color: Gainsboro;
      padding: 0px 8px 4px 8px;
      margin: 0px;
      cursor: pointer;
      text-align: center;
}
#tabs p:hover, #tabs a:hover
{
      color: #FFF;
}
#tabs p.sel, #tabs a.sel
{
      color: #FFF;
      background-color: LightBlue;
      font-weight: bold;
}

/* Active Tab rounded corners */

#active_tab_rounder { height: 5px; position: relative; background-color: LightBlue;}
#active_tab_rounder .top_left, #active_tab_rounder .top_right {
      height: 5px; width: 5px;
      position: relative; overflow: hidden;
        background-color: White;
}
#active_tab_rounder .top_left { float: left; }
#active_tab_rounder .top_right { float: right; }
#active_tab_rounder .top_left_inside, #active_tab_rounder .top_right_inside {
      height: 5px; width: 5px;
      font-family: Arial, Helvetica, sans-serif;
      font-size: 36px; color: LightBlue;
      position: relative; line-height: 10px;
}
#active_tab_rounder .top_left_inside { left: -2px; }
#active_tab_rounder .top_right_inside { left: -6px; }

/* Inactive Tab rounded corners */
#inactive_tab_rounder { height: 5px; position: relative; background-color: Gainsboro;}
#inactive_tab_rounder .top_left, #inactive_tab_rounder .top_right {
      height: 5px; width: 5px;
      position: relative; overflow: hidden;
        background-color: White;
}
#inactive_tab_rounder .top_left { float: left; }
#inactive_tab_rounder .top_right { float: right; }
#inactive_tab_rounder .top_left_inside, #inactive_tab_rounder .top_right_inside {
      height: 5px; width: 5px;
      font-family: Arial, Helvetica, sans-serif;
      font-size: 36px; color: Gainsboro;
      position: relative; line-height: 10px;
}
#inactive_tab_rounder .top_left_inside { left: -2px; }
#inactive_tab_rounder .top_right_inside { left: -6px; }
-->
</style>

HTML code:
The HTML code for the Tab Menu is very simple and easy to modify. The Tab Menu is represented by an unordered HTML list. The list elements can contain HTML links or Paragraph tags for tab heading. The default selected tab can be set by assigning the ‘sel’ class to the li tag.

Modify and place the following code inside the your HTML page body:
<div id="tabs">
<ul>
    <li><a href="javascript:void(0)">Home</a></li>
    <li><p>Work</p></li>
    <li class="sel"><p>Personal</p></li>
    <li><p>Blog</p></li>
    <li><p>About</p></li>
    <li><p>Contact</p></li>
</ul>
</div>

Friday, March 12, 2010

Animated Page Scrolling with jQuery

Many a times we use HTML links to link to some section on the same page and we link them using anchor tags. Using the nifty power of jQuery you can animate this effect by scrolling the page slowly when clicked on the anchor links. I have devised this easy to use function which can be used to scroll the HTML page/window to any HTML element on the page.

The ScrollTo function requires the id of the HTML element you want to scroll to and the duration for how long the animation should run. Durations are given in milliseconds; higher values indicate slower animations, not faster ones. The strings 'fast' and 'slow' can be supplied to indicate durations of 200 and 600 milliseconds, respectively. You can even call this function without the duration in which case the default duration is set to 400ms.

Just include the following JavaScript code in the head section of your HTML page:
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script type="text/javascript">
function ScrollTo(id, duration)
{
      if(!duration) duration = 400;
      var offset = $('#' + id).offset().top;
      $('html,body').animate({scrollTop: offset}, duration);
}
</script>

You can call this ScrollTo function from any DOM event like mouse clicks or key press. It can be used with any HTML element. Just make sure the id you pass to the function should be an unique id of any HTML element on the page.

HTML Examples:
<a href="javascript:void(0)" onclick="ScrollTo('placeToGo', 500)">Go To Link</a>
<a href="javascript:void(0)" onclick="ScrollTo('placeToGo')">Go To Link</a>
<img src="ClickButton.gif" onclick="ScrollTo('placetoGo') />