changeset 0:126e9241488c

Origination.
author Atul Varma <varmaa@toolness.com>
date Fri, 27 Nov 2009 11:43:36 -0500
parents
children af52e3302662
files mozilla-the-big-picture.css mozilla-the-big-picture.html mozilla-the-big-picture.js
diffstat 3 files changed, 258 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mozilla-the-big-picture.css	Fri Nov 27 11:43:36 2009 -0500
@@ -0,0 +1,7 @@
+#thumbnails canvas {
+    padding: 12px;
+}
+
+.pic-container {
+    padding: 12px;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mozilla-the-big-picture.html	Fri Nov 27 11:43:36 2009 -0500
@@ -0,0 +1,14 @@
+<html>
+<head>
+  <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
+  <link rel="stylesheet" type="text/css" media="all"
+        href="mozilla-the-big-picture.css" />
+  <title>Mozilla: The Big Picture</title>
+</head>
+<body>
+<div id="thumbnails"></div>
+<div id="pics"></div>
+</body>
+<script src="jquery.js"></script>
+<script src="mozilla-the-big-picture.js"></script>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mozilla-the-big-picture.js	Fri Nov 27 11:43:36 2009 -0500
@@ -0,0 +1,237 @@
+var __entries = [
+  {
+    'title': 'pocketfox',
+    'caption': 'no u',
+    'date': '',
+    'post': 'http://blog.mozilla.com/blog/2009/11/06/firefox-goes-mobile-winner-announced-plus-a-new-design-challenge/',
+    'large': 'http://creative.mozilla.org/images/designs/0/346/346_lg.jpg'
+  },
+  {
+    'title': 'colosseo',
+    'caption': '',
+    'date': '',
+    'post': 'http://www.flickr.com/photos/nois3lab/4088072729/in/set-72157622640597827/',
+    'large': 'http://farm3.static.flickr.com/2567/4088072729_0286a1611c_o.jpg',
+    'small': 'http://farm3.static.flickr.com/2567/4088072729_57e0e4c513.jpg'
+  },
+  {
+    'title': 'happy b-day firefox',
+    'caption': '',
+    'date': '',
+    'post': 'http://www.flickr.com/photos/rogeliocalamaya/4090865406/',
+    'large': 'http://farm3.static.flickr.com/2778/4090865406_2cc961098e_o.jpg',
+    'small': 'http://farm3.static.flickr.com/2778/4090865406_76ed2868d9.jpg'
+  },
+  {
+    'title': 'sketch day',
+    'caption': '',
+    'date': '',
+    'post': 'http://blog.stephenhorlander.com/2009/11/20/sketch-day/',
+    'large': 'http://www.stephenhorlander.com/images/blog-posts/sketches/menu-sketch-large.jpg',
+    'small': 'http://www.stephenhorlander.com/images/blog-posts/sketches/menu-sketch-small.jpg'
+  }
+];
+
+function ObserverManager(subject) {
+  this.subject = subject;
+  this.observers = {};
+
+  var self = this;
+  this.subject.addObserver = function() {
+    self.add.apply(self, arguments);
+  };
+}
+
+ObserverManager.prototype = {
+  add: function add(topic, observer) {
+    if (!(topic in this.observers))
+      this.observers[topic] = [];
+    this.observers[topic].push(observer);
+  },
+
+  notify: function notify(topic) {
+    if (!(topic in this.observers))
+      this.observers[topic] = [];
+    for (var i = 0; i < this.observers[topic].length; i++)
+      this.observers[topic][i].observe(this.subject, topic);
+  }
+};
+
+function Thumbnail(selectableImage, canvas, size) {
+  canvas.width = size;
+  canvas.height = size;
+
+  this.selectableImage = selectableImage;
+  this.canvas = canvas;
+  this.size = size;
+  this.selectableImage.addObserver("selection-changed", this);
+}
+
+Thumbnail.prototype = {
+  observe: function observe(subject, topic) {
+    var selection = this.selectableImage.getNormalizedSelection();
+    var ctx = this.canvas.getContext("2d");
+    ctx.drawImage(
+      this.selectableImage.img,
+      selection.anchor.x,
+      selection.anchor.y,
+      selection.width,
+      selection.height,
+      0,
+      0,
+      this.size,
+      this.size
+    );
+  }
+};
+
+function SelectableImage(url, canvas) {
+  var img = new Image();
+  var ctx = canvas.getContext("2d");
+
+  img._parent = this;
+  img.onload = this.onImgLoad;
+  img.src = url;
+
+  canvas._parent = this;
+
+  $(canvas).mousedown(this.onDragStart);
+  $(canvas).mouseup(this.onDragStop);
+
+  this.isDirty = false;
+  this.ctx = ctx;
+  this.canvas = canvas;
+  this.img = img;
+  this.selection = {anchor: {x: 0, y: 0},
+                    width: 0,
+                    height: 0};
+  this._observers = new ObserverManager(this);
+}
+
+SelectableImage.prototype = {
+  onImgLoad: function onImgLoad(evt) {
+    var self = evt.target._parent;
+
+    self.canvas.width = self.img.width;
+    self.canvas.height = self.img.height;
+    self._markDirty();
+  },
+
+  onDragStart: function onDragStart(evt) {
+    var self = evt.target._parent;
+    var point = self._getCanvasPoint(evt);
+
+    self.selection = {anchor: point,
+                      width: 0,
+                      height: 0};
+    $(self.canvas).bind("mousemove", self.onDragging);
+  },
+
+  onDragging: function onDragging(evt) {
+    var self = evt.target._parent;
+    var point = self._getCanvasPoint(evt);
+
+    var width = point.x - self.selection.anchor.x;
+    var height = point.y - self.selection.anchor.y;
+
+    if (evt.shiftKey) {
+      // Constrain dimensions to square.
+      var maxDiff = Math.max(Math.abs(width),
+                             Math.abs(height));
+      if (width > 0)
+        width = maxDiff;
+      else
+        width = -maxDiff;
+
+      if (height > 0)
+        height = maxDiff;
+      else
+        height = -maxDiff;
+    }
+
+    self.selection.width = width;
+    self.selection.height = height;
+    self._markDirty();
+  },
+
+  onDragStop: function onDragStop(evt) {
+    var self = evt.target._parent;
+
+    $(self.canvas).unbind("mousemove", self.onDragging);
+    self._markDirty();
+    self._observers.notify("selection-changed");
+  },
+
+  getNormalizedSelection: function getNormalizedSelection() {
+    var x = this.selection.anchor.x;
+    var y = this.selection.anchor.y;
+    var width = this.selection.width;
+    var height = this.selection.height;
+
+    if (width < 0) {
+      x = x + width;
+      width = -width;
+    }
+    if (height < 0) {
+      y = y + height;
+      height = -height;
+    }
+
+    return {anchor: {x: x, y: y},
+            width: width,
+            height: height};
+  },
+
+  _getCanvasPoint: function _getCanvasPoint(evt) {
+    var ofs = $(this.canvas).offset();
+    return {x: evt.pageX - ofs.left,
+            y: evt.pageY - ofs.top};
+  },
+
+  _markDirty: function _markDirty() {
+    var self = this;
+
+    if (!this._isDirty) {
+      this._isDirty = true;
+      window.setTimeout(function() { self._render(); }, 0);
+    }
+  },
+
+  _render: function _render() {
+    this._isDirty = false;
+    this.ctx.drawImage(this.img, 0, 0);
+
+    var norm = this.getNormalizedSelection();
+
+    this.ctx.fillStyle = "rgba(0,0,0,0.75)";
+    this.ctx.strokeStyle = "rgb(255,255,255)";
+    this.ctx.lineWidth = 1.0;
+    this.ctx.lineJoin = "bevel";
+    this.ctx.fillRect(norm.anchor.x, norm.anchor.y,
+                      norm.width, norm.height);
+    this.ctx.strokeRect(norm.anchor.x, norm.anchor.y,
+                        norm.width, norm.height);
+  }
+};
+
+function processEntries(entries) {
+  var THUMBNAIL_SIZE = 100;
+
+  for (var i = 0; i < entries.length; i++) {
+    var entry = entries[i];
+    entry.small = entry.small || entry.large;
+
+    var container = $('<div class="pic-container"></div>');
+    var canvas = document.createElement("canvas");
+    container.append(canvas);
+    $("#pics").append(container);
+    var selImg = new SelectableImage(entry.small, canvas);
+
+    var thumbnailCanvas = document.createElement("canvas");
+    $("#thumbnails").append(thumbnailCanvas);
+    var thumbnail = new Thumbnail(selImg, thumbnailCanvas,
+                                  THUMBNAIL_SIZE);
+  }
+}
+
+$(window).ready(function() { processEntries(__entries); });