view mbp.js @ 42:831e6516b5d2

Added tag rough-draft for changeset f051531224a4
author Atul Varma <varmaa@toolness.com>
date Fri, 11 Dec 2009 17:35:45 -0800
parents f051531224a4
children 1909896414d8
line wrap: on
line source

$(window).ready(
  function() {
    var containerWidth = $("#container").width();
    var rectRegexp = /rect\((\d+)px,? (\d+)px,? (\d+)px,? (\d+)px\)/;

    // 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() {
        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(); });
      });

    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);

          while (this.previousSibling &&
                 this.previousSibling.isElementContentWhitespace)
            $(this.previousSibling).remove();
          while (this.nextSibling &&
                 this.nextSibling.isElementContentWhitespace)
            $(this.nextSibling).remove();

          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],
                      left: parts[4]};
          crop.width = crop.right - crop.left;
          crop.height = crop.bottom - crop.top;
          var canvas = document.createElement("canvas");
          var self = $(this.parentNode).clone();
          var maxWidth = Math.max($(document.body).width(), containerWidth);
          self.find("img").removeAttr("width")
                          .removeAttr("height")
                          .css({maxWidth: maxWidth});
          $(canvas).mouseenter(
            function() {
              $("#big-picture").empty();
              $("#big-picture").append(self);
            });
          $(canvas).addClass("thumbnail");
          $(this).before(canvas);
          var ctx = canvas.getContext("2d");
          ctx.drawImage(this,
                        crop.left,
                        crop.top,
                        crop.width,
                        crop.height,
                        0,
                        0,
                        canvas.width,
                        canvas.height);
          $(this).remove();
          if (loadsLeft == 0) {
            $("#countdown").remove();
            $("#container").fadeIn();
          }
        }

        if (this.complete)
          onLoaded.call(this);
        else
          this.addEventListener("load", onLoaded, false);
      });

    $("h1").mouseover(
      function() {
        $("#big-picture").empty();
      });

    $("#countdown").text(loadsLeft);
  });