05/19/2010 21:39 by buza ()
I finally got around to putting up a video of the Feedabot Viewer.
I finally got around to putting up a video of the Feedabot Viewer.
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.
Hooking up Tak’s outstanding PhotoViewer to Feedabot is clearly an excellent idea. Here’s proof.
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…
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!
Quick Look-like interaction in the browser! Read more here.
This morning I checked our site and was welcomed by this:

Hilarious, but it’s so true. Ask anyone who has a public drawing site what the most commonly drawn “thing” is. Better yet, take a look at what people draw on bathroom stalls next time you’re at a bar.
Like I mentioned earlier, Village 2.0 features the all new MudTyper Version 2. MudTyper 2 has two components: MudTyper Server, a light weight Cocoa HTTP server and MudTyper Renderer, the font renderer. On the Village website, MudTyper is integrated behind the rails application.
An overview of the architecture is shown below:

A POST request from the browser is sent to a Rails Metal URL periodically (as opposed to responding to keystroke events). The Rails Metal method verifies sessions, and request parameters and forwards them over to the MudTyper Server. The MudTyper Server then sends a request to MudTyper Renderer to create either a file that is saved to disk or a base64 encoded string depending on the user’s browser. The browser receives the image as a response and includes the rendered image into the page.
With this architecture, it is possible to scale for increased load. We can run multiple instances of MudTyper Server+Renderer, and use mod_proxy to get Apache to handle the load balancing.
The new Renderer adds a lot of new support, including support for OpenType fonts with full kerning support, as well as many OTF features. For instance, we can now render Galaxie Cassiopeia‘s contextual alternates, adding smooth transitions between letters.
It’s been a long project, but finally, Village Version 2.0 launches! We (Village and BuzaMoto) worked really hard on it and I think the site turned out great. I urge everyone to check it out. For the curious, the site was built with Rails, and runs an all new version of MudTyper, which supports OTF with kerning in addition to many OTF features (including contextual alternates). More about MudTyper in the future when I have time to write about the more interesting technical aspects of it.
Just before the end of 2009, we launched a new e-commerce website for ProjectNo8. The site was designed by my friend Christian Schmidt. For this website, we decided to build it using Spree, an e-commerce framework built on Rails. Spree was great to work with and really sped up the development time. It was still flexible enough to implement everything we needed to, and it was familiar since it’s built with Rails.