Main > Diary > Development

« Charminar Security | Main | Charminar Ceiling »

April 30, 2005

Intelligent Image Resizing in JavaScript

update 11-Mar-2006: added syntax highlighting to source-code.

It's been a little while since I've played around much with doing anything slightly less than the ordinary with JavaScript and the DOM. After seeing some colleagues of mine bring up my photoblog I noticed that it is somewhat annoying not to be able to view the entire image on your screen at once at lower screen resolutions.

I started playing around—inadvertently on the live site—with developing a solution that would scale the main image using the window.onresize event. I was quickly reminded by how much I hate the differences in implementation between IE and Firefox. I found the following articles useful:

  • Obtaining the browser window size
  • Quirksmode JavaScript - Browser detect
  • The whole thing is implemented as a JavaScript class that manipulates two ids in the DOM, "podImage" the image and "podImageViewOriginalLink" which creates the link test to return the image back to its original size.

    Here's the code:

    function podImageClass() {
    
       if ( !(this instanceof podImageClass) ) return new podImageClass();
    
       var browser;
    
       var podImage;
       var podImageHeight;
       var podImageWidth;
       var podImageAspect;
    
       var debounceResize = 0;
       var haveResized = 0;
    
       function __setViewOriginalLink(displayBool) {
           var voLink = document.getElementById("podImageViewOriginalLink");
           if (displayBool) {
              voLink.innerHTML = 
                  '<a href="javascript:podImage.setOriginalSize()">' +
                  "Scale to Original Size" + "</a>";
           } else {
              voLink.innerHTML = '&nbsp;';
           }
       }
    
       function _setText () {
           var podImageText = '"<$MTEntryTitle$>"' + " / " +
               "Click For Previous";
           podImage.alt = podImageText;
           podImage.title = podImageText;
       }
    
       function _setSize() {
          var myWidth = 0, myHeight = 0;
        
          if (debounceResize) {
             debounceResize = 0;
             return;
          }
    
          if( typeof( window.innerWidth ) == 'number' ) {
             //Non-IE
             myWidth = window.innerWidth;
             myHeight = window.innerHeight;
          } else if( document.documentElement &&
             ( document.documentElement.clientWidth ||  
                document.documentElement.clientHeight ) ) {
             //IE 6+ in 'standards compliant mode'
             myWidth = document.documentElement.clientWidth;
             myHeight = document.documentElement.clientHeight;
          } else if( document.body && ( document.body.clientWidth || 
                document.body.clientHeight ) ) {
             //IE 4 compatible
             myWidth = document.body.clientWidth;
             myHeight = document.body.clientHeight;
          }
    
          // Only do the resize if we've done this before or if our
          // image is greater than their window size 64px of top margin.
          if ( !( haveResized || ((podImageHeight + 64) > myHeight) ) ) {
             return;
          }
    
          // allow 128px margins on top and bottom:
          var newImageHeight = myHeight - ( 2 * 128 );
    
          if ( (podImageHeight + 64) < myHeight ) {
             // Just use original width and height;
             _setOriginalSize();
          } else {
             // Downscale:
             if (newImageHeight > 0) {
                var newImageWidth = newImageHeight * podImageAspect;
                podImage.width = newImageWidth;
                podImage.height = newImageHeight;
             }
    
             __setViewOriginalLink(true);
          }
    
          haveResized = 1;
       }
    
       function _setOriginalSize() {
          // We have to play with the onresize handler to work
          // around IE sending spurious events.
          window.onresize = null;
          podImage.width = podImageWidth;
          podImage.height = podImageHeight;
          __setViewOriginalLink(false);
          if (browser == "MSIE") {
             debounceResize = 1;
          }
          window.onresize = _setSize;
       }
    
       function _checkIt(string)
       {
          var detect = navigator.userAgent.toLowerCase();
          place = detect.indexOf(string) + 1;
          thestring = string;
          return place;
       }
    
       function _init() {
          if (_checkIt('msie')) browser = "MSIE"
          else browser = "Other";
    
          podImage = document.getElementById("podImage");
          podImageWidth = podImage.width;
          podImageHeight = podImage.height;
          podImageAspect = (podImageHeight > 0) ?
             (podImageWidth / podImageHeight) : 0;
       }
    
       this.init = _init;
       this.setText = _setText;
       this.setSize = _setSize;
       this.setOriginalSize = _setOriginalSize;
    
       _init();
    }
    
    <!-- setup podImage class: -->
    var podImage;
    addLoadEvent(function() {
            podImage = podImageClass();
            podImage.setText();
            podImage.setSize();
            window.onresize = podImage.setSize;
    });

    It's live on the site now; let me know if you run into any bugs or if you just find the whole thing annoying.

    I'm sure one day this entire exercise will be reduced to two lines of CSS.

    Posted by jordanh at April 30, 2005 1:47 PM

    Trackback Pings

    TrackBack URL for this entry:
    http://jordan.husney.com/mt/mt-tb.cgi/22.

    Comments

    Thanks...This is really useful for me :)

    Posted by: Thanh H. Nguyen at September 20, 2007 12:51 AM

    Post a comment




    Remember Me?