changeset 37:ddab6ae20001

The best image for display is now chosen dynamically based on display resolution, rather than depending on the large/small CSS class metadata.
author Atul Varma <varmaa@toolness.com>
date Fri, 11 Dec 2009 16:18:38 -0800
parents 2c5d734e1d2c
children 496e8bb45290
files mbp.css mbp.html mbp.js
diffstat 3 files changed, 75 insertions(+), 43 deletions(-) [+]
line wrap: on
line diff
--- a/mbp.css	Fri Dec 11 15:14:23 2009 -0800
+++ b/mbp.css	Fri Dec 11 16:18:38 2009 -0800
@@ -56,23 +56,15 @@
     font-size: 8pt;
 }
 
-.mbp-entry .large {
-    display: none;
-}
-
-.mbp-entry .small {
-    display: inline;
-}
-
 br {
     clear: left;
 }
 
-#images {
+#big-picture {
     padding-top: 4pt;
     text-align: center;
 }
 
-#images img {
+#big-picture img {
     max-width: 560pt;
 }
--- a/mbp.html	Fri Dec 11 15:14:23 2009 -0800
+++ b/mbp.html	Fri Dec 11 16:18:38 2009 -0800
@@ -15,8 +15,7 @@
 <div class="mbp-entry">
   <a class="link"
      href="http://blog.mozilla.com/blog/2009/11/06/firefox-goes-mobile-winner-announced-plus-a-new-design-challenge/">
-    <img class="small large"
-         width="580" height="647"
+    <img width="580" height="647"
          src="http://creative.mozilla.org/images/designs/0/346/346_lg.jpg"
          style="clip: rect(136, 375, 261, 250);"/>
   </a>
@@ -30,11 +29,9 @@
 <div class="mbp-entry">
   <a class="link"
      href="http://www.flickr.com/photos/nois3lab/4088072729/in/set-72157622640597827/">
-    <img class="large"
-         width="3720" height="2480"
+    <img width="3720" height="2480"
          src="http://farm3.static.flickr.com/2567/4088072729_0286a1611c_o.jpg"/>
-    <img class="small"
-         width="500" height="333"
+    <img width="500" height="333"
          src="http://farm3.static.flickr.com/2567/4088072729_57e0e4c513.jpg"
          style="clip: rect(36, 293, 160, 169);"/>
   </a>
@@ -47,11 +44,9 @@
 <div class="mbp-entry">
   <a class="link"
      href="http://www.flickr.com/photos/rogeliocalamaya/4090865406/">
-    <img class="large"
-         width="663" height="848"
+    <img width="663" height="848"
          src="http://farm3.static.flickr.com/2778/4090865406_2cc961098e_o.jpg"/>
-    <img class="small"
-         width="391" height="500"
+    <img width="391" height="500"
          src="http://farm3.static.flickr.com/2778/4090865406_76ed2868d9.jpg"
          style="clip: rect(163, 240, 290, 113);"/>
   </a>
@@ -63,8 +58,7 @@
 <div class="mbp-entry">
   <a class="link"
      href="http://antennasoft.net/robcee/2009/11/12/firebug-1-5-new-features-revealed/">
-    <img class="large small"
-         width="749" height="401"
+    <img width="749" height="401"
          src="http://farm3.static.flickr.com/2527/4098694166_44025231d6_o.png"
          style="clip: rect(141, 133, 270, 4);"/>
   </a>
@@ -77,8 +71,7 @@
 <div class="mbp-entry">
   <a class="link"
      href="http://www.womoz.org/blog/?p=142">
-    <img class="large small"
-         width="420" height="300"
+    <img width="420" height="300"
          src="http://womoz.org/wiki/lib/exe/fetch.php?cache=&media=logos:logo9.jpg"
          style="clip: rect(48, 255, 250, 53);"/>
   </a>
@@ -90,11 +83,9 @@
 <div class="mbp-entry">
   <a class="link"
      href="http://blog.stephenhorlander.com/2009/11/20/sketch-day/">
-    <img class="large"
-         width="1172" height="906"
+    <img width="1172" height="906"
          src="http://www.stephenhorlander.com/images/blog-posts/sketches/menu-sketch-large.jpg"/>
-    <img class="small"
-         width="490" height="375"
+    <img width="490" height="375"
          src="http://www.stephenhorlander.com/images/blog-posts/sketches/menu-sketch-small.jpg"
          style="clip: rect(16, 206, 197, 25);"/>
   </a>
@@ -107,8 +98,7 @@
 <div class="mbp-entry">
   <a class="link"
      href="http://www.azarask.in/blog/post/identity-in-the-browser-firefox/">
-    <img class="large small"
-         width="1000" height="1500"
+    <img width="1000" height="1500"
          src="http://farm3.static.flickr.com/2552/4128966575_9876fdb834_o.png"
          style="clip: rect(411, 720, 573, 558);"/>
   </a>
@@ -120,6 +110,6 @@
 </div>
 </div>
 <br/>
-<div id="images"></div>
+<div id="big-picture"></div>
 </body>
 </html>
--- a/mbp.js	Fri Dec 11 15:14:23 2009 -0800
+++ b/mbp.js	Fri Dec 11 16:18:38 2009 -0800
@@ -1,18 +1,59 @@
 $(window).ready(
   function() {
+    var containerWidth = $("#container").width();
     var rectRegexp = /rect\((\d+)px,? (\d+)px,? (\d+)px,? (\d+)px\)/;
-    var smallImages = $(".mbp-entry img.small");
-    var loadsLeft = smallImages.length;
-    $("h1").mouseover(
+
+    // Each entry may have multiple resolutions of the same image;
+    // choose the one that's best for our display device, and
+    // make sure we have a clipping area for its thumbnail.
+    $(".mbp-entry").each(
       function() {
-        $("#images").empty();
+        var images = $(this).find("img");
+        var lastClip = null;
+        var best = null;
+        images.each(
+          function() {
+            var clip = $(this).css("clip");
+            if (clip != "auto")
+              lastClip = this;
+            if (best) {
+              // The "best" image is the lowest-resolution image
+              // that's still bigger than the width of our container:
+              // this way we never upscale, but we also don't waste
+              // bandwidth getting a massive image that we won't
+              // see.
+              if (this.width < best.width &&
+                  this.width >= containerWidth) {
+                best = this;
+              }
+            } else
+              best = this;
+          });
+
+        // If our best image doesn't have a CSS clipping rect associated
+        // with it, we'll use the scaled clipping rect of another
+        // resolution.
+        if ($(best).css("clip") == "auto" && lastClip) {
+          var scaling = best.width / lastClip.width;
+          var parts = $(lastClip).css("clip").match(rectRegexp);
+          if (!parts)
+            throw new Error("Invalid 'clip' CSS for " + lastClip.src);
+
+          var newParts = [];
+          for (var i = 1; i <= 4; i++)
+            newParts.push(Math.floor(parts[i] * scaling) + "px");
+          $(best).css({clip: "rect(" + newParts.join(", ") + ")"});
+        }
+
+        // Remove all the non-ideal images we don't need.
+        images.each(function() { if (this != best) $(this).remove(); });
       });
-    $(".mbp-entry img.large").each(
-      function() {
-        if (!$(this).hasClass("small"))
-          $(this).remove();
-      });
-    smallImages.each(
+
+    var images = $(".mbp-entry img");
+    var loadsLeft = images.length;
+
+    // Create the thumbnails and attach event handlers to them.
+    images.each(
       function() {
         function onLoaded() {
           $("#countdown").text(--loadsLeft);
@@ -26,6 +67,9 @@
 
           var clip = $(this).css("clip");
           var parts = clip.match(rectRegexp);
+          if (!parts)
+            throw new Error("Invalid 'clip' CSS for " + this.src);
+
           var crop = {top: parts[1],
                       right: parts[2],
                       bottom: parts[3],
@@ -40,8 +84,8 @@
 
           $(canvas).mouseenter(
             function() {
-              $("#images").empty();
-              $("#images").append(self);
+              $("#big-picture").empty();
+              $("#big-picture").append(self);
             });
           $(canvas).addClass("thumbnail");
           $(this).before(canvas);
@@ -67,5 +111,11 @@
         else
           this.addEventListener("load", onLoaded, false);
       });
+
+    $("h1").mouseover(
+      function() {
+        $("#big-picture").empty();
+      });
+
     $("#countdown").text(loadsLeft);
   });