comparison mbp.js @ 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 124129f5c74a
comparison
equal deleted inserted replaced
36:2c5d734e1d2c 37:ddab6ae20001
1 $(window).ready( 1 $(window).ready(
2 function() { 2 function() {
3 var containerWidth = $("#container").width();
3 var rectRegexp = /rect\((\d+)px,? (\d+)px,? (\d+)px,? (\d+)px\)/; 4 var rectRegexp = /rect\((\d+)px,? (\d+)px,? (\d+)px,? (\d+)px\)/;
4 var smallImages = $(".mbp-entry img.small"); 5
5 var loadsLeft = smallImages.length; 6 // Each entry may have multiple resolutions of the same image;
6 $("h1").mouseover( 7 // choose the one that's best for our display device, and
8 // make sure we have a clipping area for its thumbnail.
9 $(".mbp-entry").each(
7 function() { 10 function() {
8 $("#images").empty(); 11 var images = $(this).find("img");
12 var lastClip = null;
13 var best = null;
14 images.each(
15 function() {
16 var clip = $(this).css("clip");
17 if (clip != "auto")
18 lastClip = this;
19 if (best) {
20 // The "best" image is the lowest-resolution image
21 // that's still bigger than the width of our container:
22 // this way we never upscale, but we also don't waste
23 // bandwidth getting a massive image that we won't
24 // see.
25 if (this.width < best.width &&
26 this.width >= containerWidth) {
27 best = this;
28 }
29 } else
30 best = this;
31 });
32
33 // If our best image doesn't have a CSS clipping rect associated
34 // with it, we'll use the scaled clipping rect of another
35 // resolution.
36 if ($(best).css("clip") == "auto" && lastClip) {
37 var scaling = best.width / lastClip.width;
38 var parts = $(lastClip).css("clip").match(rectRegexp);
39 if (!parts)
40 throw new Error("Invalid 'clip' CSS for " + lastClip.src);
41
42 var newParts = [];
43 for (var i = 1; i <= 4; i++)
44 newParts.push(Math.floor(parts[i] * scaling) + "px");
45 $(best).css({clip: "rect(" + newParts.join(", ") + ")"});
46 }
47
48 // Remove all the non-ideal images we don't need.
49 images.each(function() { if (this != best) $(this).remove(); });
9 }); 50 });
10 $(".mbp-entry img.large").each( 51
11 function() { 52 var images = $(".mbp-entry img");
12 if (!$(this).hasClass("small")) 53 var loadsLeft = images.length;
13 $(this).remove(); 54
14 }); 55 // Create the thumbnails and attach event handlers to them.
15 smallImages.each( 56 images.each(
16 function() { 57 function() {
17 function onLoaded() { 58 function onLoaded() {
18 $("#countdown").text(--loadsLeft); 59 $("#countdown").text(--loadsLeft);
19 60
20 var siblings = [this.previousSibling, 61 var siblings = [this.previousSibling,
24 siblings[i].isElementContentWhitespace) 65 siblings[i].isElementContentWhitespace)
25 $(siblings[i]).remove(); 66 $(siblings[i]).remove();
26 67
27 var clip = $(this).css("clip"); 68 var clip = $(this).css("clip");
28 var parts = clip.match(rectRegexp); 69 var parts = clip.match(rectRegexp);
70 if (!parts)
71 throw new Error("Invalid 'clip' CSS for " + this.src);
72
29 var crop = {top: parts[1], 73 var crop = {top: parts[1],
30 right: parts[2], 74 right: parts[2],
31 bottom: parts[3], 75 bottom: parts[3],
32 left: parts[4]}; 76 left: parts[4]};
33 crop.width = crop.right - crop.left; 77 crop.width = crop.right - crop.left;
38 // Allow max-width/max-height of CSS to propagate. 82 // Allow max-width/max-height of CSS to propagate.
39 self.find("img").removeAttr("width").removeAttr("height"); 83 self.find("img").removeAttr("width").removeAttr("height");
40 84
41 $(canvas).mouseenter( 85 $(canvas).mouseenter(
42 function() { 86 function() {
43 $("#images").empty(); 87 $("#big-picture").empty();
44 $("#images").append(self); 88 $("#big-picture").append(self);
45 }); 89 });
46 $(canvas).addClass("thumbnail"); 90 $(canvas).addClass("thumbnail");
47 $(this).before(canvas); 91 $(this).before(canvas);
48 var ctx = canvas.getContext("2d"); 92 var ctx = canvas.getContext("2d");
49 ctx.drawImage(this, 93 ctx.drawImage(this,
65 if (this.complete) 109 if (this.complete)
66 onLoaded.call(this); 110 onLoaded.call(this);
67 else 111 else
68 this.addEventListener("load", onLoaded, false); 112 this.addEventListener("load", onLoaded, false);
69 }); 113 });
114
115 $("h1").mouseover(
116 function() {
117 $("#big-picture").empty();
118 });
119
70 $("#countdown").text(loadsLeft); 120 $("#countdown").text(loadsLeft);
71 }); 121 });