Commits

Trey Hunner committed c9d9cd8

Fix getOriginalImageSize in Chrome

Changes:
- Add imagesLoaded jQuery function as a $.load() alternative
- Change getOriginalImgSize to use imagesLoaded and accept callback
- Call scale through getOriginalImgSize callback, passing imgage size

Comments (0)

Files changed (1)

src/jquery.myimgscale.js

             $parent.css({opacity: 0, overflow: 'hidden'}); // keep the img inside boundaries
             
             if ($parent.length > 0) {
-                $img.removeAttr('height').removeAttr('width');
-                if (this.complete) { // img already loaded/cached
-                    scale($img, $parent);
-                } else {
-                    $img.load(function() {
-                        scale($img, $parent);
-                    });
-                }
+                getOriginalImgSize($img, function(imgSize) {
+                    scale($img, $parent, imgSize);
+                });
             }
         });
         
-        function scale($img, $parent) {
-            var imgSize = getOriginalImgSize($img),
-                imgW = imgSize.width,
+        function scale($img, $parent, imgSize) {
+            var imgW = imgSize.width,
                 imgH = imgSize.height,
                 destW = $parent.width(),
                 destH = $parent.height(),
         /**
          * To calculate the correct scale ratio, we need the image's original size rather than some preset values,
          * which were set either manually in code or automatically by browser.
-         * Thanks FDisk for the solution:
+         * Thanks Xavi, FDisk, and RobW for the solution:
          * http://stackoverflow.com/questions/318630/get-real-image-width-and-height-with-javascript-in-safari-chrome
          */
-        function getOriginalImgSize($img) {
-            var t = new Image();
-            t.src = $img.attr("src");
-            return {width: t.width, height: t.height};
+        function getOriginalImgSize($img, callback) {
+            $img.imagesLoaded(function() {
+                $("<img>").attr("src", $img.attr("src"))
+                    .imagesLoaded(function() {
+                        callback({width: this[0].width, height: this[0].height});
+                    });
+            });
         }
         
         /**
             return size;
         }
     };
-})(jQuery);
+
+    /*!
+     * imagesLoaded function from jQuery imagesLoaded plugin v1.0.4
+     * https://github.com/desandro/imagesloaded
+     *
+     * MIT License. by Paul Irish et al.
+     *
+     * Full list of contributors to imagesLoaded listed here:
+     * https://github.com/desandro/imagesloaded/contributors
+     *
+     * execute a callback when all images have loaded.
+     * needed because .load() doesn't work on cached images
+     *
+     * callback function gets image collection as argument
+     *  `this` is the container
+     */
+    $.fn.imagesLoaded = function( callback ) {
+        var $this = this,
+            $images = $this.find('img').add( $this.filter('img') ),
+            len = $images.length,
+            blank = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==';
+
+        function triggerCallback() {
+            callback.call( $this, $images );
+        }
+
+        function imgLoaded( event ) {
+            if ( --len <= 0 && event.target.src !== blank ){
+                setTimeout( triggerCallback );
+                $images.unbind( 'load error', imgLoaded );
+            }
+        }
+
+        if ( !len ) {
+            triggerCallback();
+        }
+
+        $images.bind( 'load error',    imgLoaded ).each( function() {
+            // cached images don't fire load sometimes, so we reset src.
+            if (this.complete || typeof this.complete === "undefined") {
+                var src = this.src;
+                // webkit hack from http://groups.google.com/group/jquery-dev/browse_thread/thread/eee6ab7b2da50e1f
+                // data uri bypasses webkit log warning (thx doug jones)
+                this.src = blank;
+                this.src = src;
+            }
+        });
+
+        return $this;
+    };
+})(jQuery);