About the Technology

Picxr relies on a number of open source software libraries to help implement various features you see on the site. The three software components used most extensively throughout Picxr code are Ruby on Rails, jQuery, and Backbone.js. These three components help structure code in a maintainable way, and implement several useful design patterns that allow Picxr to more easily respond to user interactions.

Ruby on Rails

Ruby on Rails is a web framework favoring "convention over configuration," and is programmed in the Ruby programming language. Rails has a large and thriving community with a number of open source libraries. Rails was a good choice for Picxr because it made it very easy to get a basic website up and running. Rails is also well tested and scalable, as demonstrated by the many popular websites that use it.

Rails implements the Model View Controller design pattern to help organize the code in a maintainable way. Models are used to represent and query data. Views render the data in a user-readable form that is shown by the web browser. Controllers connect the Models and Views by taking user input, telling the appropriate Model(s) to fetch the data, and sending that data to the appropriate View.

Rails also uses the active record pattern to implement object-relational mapping. Picxr uses the PostgreSQL database to store information on pictures, and ActiveRecord in Rails provides an easy way to interact with this database. With ActiveRecord, you can easily insert, query, update, and delete data without having to write verbose SQL. Using ActiveRecord in Rails also helps protect against SQL injection attacks.

Backbone.js

Backbone.js is a client-side JavaScript library that provides structure to JavaScript-heavy applications. Picxr is primarily a client-side application, only making calls to the Ruby on Rails backend with necessary, so Backbone was a clear choice for implementing the client-side functionality.

Backbone code is organized in four components: Models, Views, Collections, and Routes. Models are used to interact with data retrieved from the server, while Collections hold a list of Models. Views present the data to the user, and can respond to user-interface events. Views can be associated with a collection of models or a single model, and can be set up to automatically update whenever that collection or model changes. The Router watches for changes in the URL and renders the appropriate View when the URL changes. The structure provided through these four components helps to reduce the amount of data transferred between the client and server, thus making responses to user interaction quicker.

Backbone also has a built in history module that supports pushState. This allows for Backbone to change the URL without refreshing the whole page. Furthermore, this new URL is pushed into the browser history, so the browser back button still works as expected. For browsers that don't yet support pushState, Backbone falls back on using JavaScript's window.location.hash property.

jQuery

jQuery is a JavaScript library for DOM traversal, manipulation, and event handling. jQuery is used extensively by Picxr to help provide consistent cross-browser functionality across many features. jQuery also helps respond to advanced events that are not supported by Backbone such as dragging. jQuery implements a number of design patterns to make DOM traversal and manipulation easier to deal with. jQuery is also easily extendable and has a number of useful plugins, such as the Spectrum, Chosen, and jQuery Hotkeys plugins that are used by Picxr.

Fabric.js

Fabric.js is a JavaScript library that provides an "interactive object model" on top of the HTML5 canvas element. Picxr uses Fabric.js to help process image modifications and handle user events on the canvas element. Fabric.js features a very useful set of functions for resizing, rotating, and moving objects around on the canvas, as well as functions for modifying object properties such as color and transparency. Fabric.js objects include text, Scalable Vector Graphics, basic shapes, and images.


Architecture Walkthrough

When a user first visits Picxr, the Thin web server responds to the user's request and uses the Rails routes file to determine which controller should respond to the request. The controller then executes code, which could involve anything from simply rendering a view to more complex code that uses the Rails models to query the database. When the HTML view is prepared, it is sent as a response to the user's browser. The user's browser will render the HTML and send any secondary requests for files embedded in the HTML file, such as CSS, JavaScript, and image files.

When the JavaScript finishes loading, all Backbone components are enabled and the Facebook JavaScript SDK starts loading asynchronously. Meanwhile, the Backbone router will render any appropriate Backbone views associated with the current URL. If the Facebook SDK hasn't finished loading yet and the Backbone views need data from Facebook, the router will specify a callback function to be called once the Facebook SDK is loaded. If the user is logged into Facebook and has already given Picxr permission to access photos from Facebook, Picxr will retrieve information on friends and photos using FQL. This data is placed into a Backbone model, which is then added to a collection. The Backbone view associated with this collection will re-render itself every time a new model is added.

Once the user selects a photo, the full photo will be loaded onto the photo modification page. Since the photo must abide by same-origin policy, it is loaded through a simple local image proxy that streams the image through Picxr's server. Picxr loads this proxied image onto Fabric.js as a Fabric image object and scales it down to fit within dimensions of the page. The sidebar "toolbox" is also loaded to enable users to select photo modification tools and configure tools.

Text uses the built in Fabric.js text object for manipulating text and Cufon for loading an SVG version of the font. Drawing listens for mouse events on the Fabric.js canvas and draws whenever the user clicks down on the canvas. Image effects use CamanJS and glfx.js to modify the Fabric.js canvas. This is accomplished by converting the Fabric.js canvas to an image, having CamanJS or glfx.js modify this image, and placing this modified image on the Fabric.js canvas.

Certain changes made on the photo manipulation page will trigger a call to save the current state of the image, enabling undoing and redoing. For example, when the user clicks down to draw and then clicks up, the state of the image will only be saved when the click up event is triggered. Image state is saved in JSON format which can easily be exported from and imported back into Fabric.js.

When the user is finished editing the photo, the photo metadata is saved as a record in the database, and the finalized photo is uploaded to Amazon S3. The permalink for the photo is a unique incrementing base64 hash, or in the case of a private photo, it is a longer random base64 hash.


Open Source Contributions

mousefu, a jQuery plugin for handling mouse and touch events/coordinates.


A full list of software components and external services used by Picxr are listed below:

Server-side

Client-side

  • jQuery for DOM manipulation and basic event handling
  • Backbone.js for pushState and providing MVC-like structure for JavaScript
  • Fabric.js for scaling, rotation, and moving on the <canvas> element
  • CamanJS for basic image filters and effects
  • glfx.js for more advanced image filters and effects with WebGL
  • Bootstrap for the CSS grid and some styling
  • jQuery UI for sliders used on the image manipulation page
  • Spectrum for the color picker
  • Chosen for user-friendly select boxes
  • jQuery Hotkeys to enable keyboard shortcuts
  • mousefu for handling mouse coordinates and events on image manipulation canvas

External services