Cara’s Site
08/03/2010 15:53 by mud ()

A quick weekend project, building a site for my friend Cara using Indexhibit. It was easy enough to get started although while writing the plugin, I did have to add some extra stuff to the core. It did make me feel a little sad having to write PHP, but maybe this will inspire me to port it as a Rails/Sinatra app?

PS Cara is awesome if any one is looking for a production designer.

When ripoffs go wrong
07/01/2010 13:30 by mud ()

I just saw this in a flash ad:

which is clearly a rip off of the classic eye bee m poster by Paul Rand:

The rule to ripping something off is to make it better. In this case, a massive failure. If I ever get old and need grandpa reading glasses, I will not go to Lens Crafters!

Site Launch: Knoll Antenna Workspaces Teaser
06/15/2010 12:55 by mud ()

Just in time for the launch of Antenna Workspaces by Knoll at NeoCon 2010, the Teaser website goes live.

We worked on this site in a really short time, but are happy with the outcome. Thanks to tips from Apple engineers last week at WWDC, the site runs fast on the iPad and iPhone, and enhances the experience with support for multi-touch. Move four objects at once if you want!

The source of this website runs inside Knoll’s NeoCon page using Shadowbox, and what’s notable about this site is that users can share links to any image, which will open the page in Shadowbox and open up the specific image that was linked.

Now I deserve a vacation, but it probably won’t happen.

Nerding Out At WWDC 2010
06/07/2010 21:18 by mud ()

Nerding out at WWDC. If you’re here, I’ll see you around. Lets meet at the Thurs Beer Bash!

Feedabot Viewer : A Video
05/19/2010 21:39 by buza ()

I finally got around to putting up a video of the Feedabot Viewer.

Navigating the Feedabot Archive
05/11/2010 19:55 by buza ()

Every day, the collection of pages rendered by feedabot grows larger. In fact, there are approximately 250,000 pages in the feedabot archive as of a few days ago. Using the current web-based interface to navigate through this collection (one mouse click loads six new images), it would take approximately 35 hours of nonstop clicking to view all of those pages. A choice of layout similar to the Tumblr Mosaic Viewer would certainly help matters, but only slightly. It was only a matter of time before coming to the realization that there must be a better way to navigate (and further explore) such a large collection of web pages.

At this point, we must leave the browser and head back to the desktop. Even with rich media technologies such as Flash, the browser really isn’t the best place to experiment with interfaces for quickly navigating large data sets. The desktop viewer for the feedabot archive, tentatively called the ‘feedabot viewer’, was designed to be clean, fun, and aesthetically pleasing.

Interaction with the viewer is purely mouse-based, containing no popup menus or dialog boxes. A day’s worth of feedabot-rendered pages is loaded with a flick of the horizontal scroll wheel. Navigation through the resulting set occurs through the use of the vertical scroll wheel, and the mouse cursor position is used to reveal the tweet that contained the link of the rendered page. At this point, the user may ’select’ the page with a mouse click to extract the image resources from the page itself. The resulting images are placed on a layer in front of the view, with navigation possible through the use of the horizontal scroll wheel. When the mouse cursor position moves beyond the currently selected page, these images disappear. One can only hope that navigating the web will be this pleasant in the future.

A few more images of the viewer in action can be found on my blog, and in this Flickr set.

PhotoViewer + Feedabot
04/23/2010 02:49 by buza ()

Hooking up Tak’s outstanding PhotoViewer to Feedabot is clearly an excellent idea. Here’s proof.

PhotoViewer with CSS Transition Goodies
04/14/2010 18:46 by mud ()

I wanted to play with the new CSS transition stuff, to see what all the fuss was about. At the same time I wanted to make something useful, so I thought why not make a little site for my friend Dave, who is one bad ass photographer. I have a rough demo up and it works pretty well. It only works with Safari 4, but the good news is that it also works with Mobile Safari.

It’s really nice that the animation is defined in the CSS and you don’t need any JavaScript to move objects. It was also really simple to implement, most of the work was done in about an hour. The interaction is simple. Click a picture to zoom into it, then a full version loads, click on it and you zoom back out. You can also move the thumbnails around.

I had to violate some ui for the iPad because of the way mobile safari handles events, or more precisely, doesn’t handle events. I wanted to maintain the native gestures of but weirdly enough safari does fire any events when double tapping to zoom in, as stated in their documentation. Why?

I decided implementing my own photo uploading/managing would be too much of a pain in the ass, after all Dave isn’t paying me for this. Yes, this may come as a shock, but I’m not a total asshole. So I decided to use Flickr as a CMS. Since the API allows for a JavaScript callback, there’s no backend proxy work required.

Anyway, here’s a little taste of how it works. You need Safari 4 or iPhone OS 3. Currently, there are three different ways to load photos.

1) Load from a JSON file

Loading a JSON file, don’t pass any query terms: http://mud.mitplw.com/PhotoViewer/

The actual JSON file is: http://mud.mitplw.com/PhotoViewer/index.json

2) Load Photosets from a Flickr user

Pass a photoset=flickr_user_id query, like this (using Luis’s Flickr account)

http://mud.mitplw.com/PhotoViewer/?photoset=75903973@N00

HINT: you can look up user_ids with idGettr.

3) Load Photos from Flickr using tag search

Pass any comma delimited tags like ?drunk,punks

http://mud.mitplw.com/PhotoViewer/?drunk,punks

Finally, I’ll post the source on github when I finally finish Dave’s site. Also, maybe in the near future I’ll add some local storage and HTML5 video support…

Private Members and Prototype
03/20/2010 21:26 by mud ()

When writing JavaScript, most people don’t think about member access. Every member in an object is essentially a public variable. This is because there isn’t support for declaring variable modifiers (ie. public, protected, private) in the language. For most simple developments, this shouldn’t be a problem, and I never really thought too hard about it. But now that I’m knee deep in a big JavaScript project (and interesting new JS projects popping up like node.js) putting more consideration into encapsulation is a good idea.

According to Douglas Crockford it’s possible to create private variables and methods, and privileged methods (public methods with access to private variables and methods). Crockford’s article also gives us some patterns to follow which we can easily follow.

I was curious to see how this might look like in my preferred JS framework, Prototype.js. It didn’t take long before I concluded that you can’t use private variables with Class.create().

Here’s a rather useless class:

var AssetRequest = Class.create({
  initialize: function(_id, _url) {
    this.id      = _id;
    this.url     = _url;
    this.loaded  = false;
    this.content = null;
    this.request = null;
  },
  load: function() {
    if (!this.loaded) {
      this.request = new Ajax.Request(this.url, {
        onSuccess: function(transport) {
          this.loaded = true;
          this.content = transport.responseText;
          Event.fire(document, 'assetrequest:loaded', this);
        },
        onFailure: function() {
          Event.fire(document, 'assetrequest:failed', this);
        }
      });
    }
  }
});

The idea here is that you will create an AssetRequest object for an asset, say a JSON file. As you can imagine, all the members are editable. You can do something really dumb like this:

var request = new AssetRequest('req1', '/assets/asset-1.js');
request.loaded = true;
if (request.loaded) {
  alert(request.id + ' is loaded');
}

If you count on request.loaded to tell you if an asset has been loaded, it’s not reliable. So obviously we want to make this a private variable set it’s value internally, and create a privileged method that will provide access to its value. But you’ll see that this is actually not possible if we construct AssetRequest with Prototype’s Class.create.

It’s tempting to write:

var AssetRequest = Class.create((function() {
  var id,
      url,
      loaded  = false,
      content = null,
      request = null;

  return {
    initialize: function(_id, _url) {
      id  = _id;
      url = _url;
    },
    load: function() {
      if (!loaded) {
        request = new Ajax.Request(url, {
          onSuccess: function(transport) {
            loaded = true;
            content = transport.responseText;
            Event.fire(document, 'assetrequest:loaded', this);
          },
          onFailure: function() {
            Event.fire(document, 'assetrequest:failed', this);
          }
        });
      }
    },
    getURL:   function() { return url; },
    isLoaded: function() { return loaded; }
  }
})());

If you try this out, you’ll soon realize something is wrong:

var req = new AbstractRequest('1', '/request1');
alert(req.getURL());
//-> '/request'
var req2 = new AbstractRequest('2', '/request2');
alert(req2.getURL());
//-> '/request2'
alert(req.getURL());
//-> '/request2' ... this isn't good!

It seems the “private” variables that are created are not instance variables, instead they are “static” variables. I then thought the only way to create private variables would be defining the variables and all private/privileged methods inside the initialize method. But that’s where I gave up since that would be just so dirty looking.

I decided to not use Class.create and instead create my own constructor, just like the Crock style. So now our example will look like:

var AssetRequest = function(_id, _url) {
  var that    = this,
      id      = _id,
      url     = _url,
      loaded  = false,
      content = null,
      request = null;

  this.load = function() {
    if (!loaded) {
      request = new Ajax.Request(url, {
        onSuccess: function(transport) {
          loaded = true;
          content = transport.responseText;
          Event.fire(document, 'assetrequest:loaded', that);
        },
        onFailure: function() {
          Event.fire(document, 'assetrequest:failed', that);
        }
      });
    }
  };
  this.getURL   = function() { return url; };
  this.isLoaded = function() { return loaded; };
};

The problem now is that this new class can’t be extended as if it were created with Class.create. For now I only use this method for classes that don’t need to be subclassed, but hopefully in the near future, there will be an update to Prototype that will allow private variables!

Resource Peeking in Feedabot
02/23/2010 17:06 by buza ()

Quick Look-like interaction in the browser! Read more here.