Mercurial > mozilla-the-big-picture
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 }); |