Reliable image load events with load_image

Wow! This takes me back! Please check the date this post was authored, as it may no longer be relevant in a modern context.

For several months I’ve been working with To Be, building a platform for creating and sharing creative work online. To Be’s fields are very visual, often incorporating animated GIFs, static images, canvas-rendered images, and iframes. Check out this field to see what kind of things people are creating and look here for more fields.

When images are loaded for a To Be field, we often need to react to the loaded state and perform some action. For instance if a given field element has a stencil description, we load the image to a canvas and process that canvas as a stencil. It turns out that image load events are notoriously un-reliable. For instance Chrome will not fire an onload callback when an image is fetched from the local cache [ticket here].

Last fall, I published a small library called after_image_load to GitHub. It handled CORs headers in addition to ensuring load events are always fired. We’ve been using that library in production for almost half a year now, and today I’ve finally incorporated the lessons from using it into an even slimmer jQuery library called load_image. Check it out on GitHub, and read on for some example usage.

Using load_image

load_image follows jQuery plugin conventions and returns a jQuery.Deferred promise [jQuery.Deferred docs]. Usage is simple:

$.loadImage("http://example.com/cat-photo.jpg").done(function(img){
  // `img` is a jQuery wrapped image element.
  img.appendTo('.wrapper');
});

We often use the image loader with CORs so images from other domains can be safely added to canvas elements. For this, the easiest thing to do is call loadImage on a new element you create:

$('<img crossOrigin="Anonymous" />').loadImage("http://example.com/cat-photo.jpg").done(function(img){
  // `img` has been loaded with CORs
});

Image elements cannot have their crossOrigin property changed, so you must create a new element if this value changes. Specifically you cannot un-set the crossOrigin value.

We also often need to fire CORs for an image URL, but not for a data-url:

// Assumes url... could be a data-url or a real URL.
imageElement = $(url.indexOf('data:') === 0 ? '<img />' : '<img crossOrigin="Anonymous" />');
imageElement.loadImage(url).done(function(img){
  // `img` has been loaded with CORs, only
  // if it was not a data-url.
});

We’ve found this to be a small but helpful tool for building To Be. Hope you find it useful!

Find load_image here on GitHub.