O'Reilly

Instagram For MooTools

By on  

Instagram MooTools

If you're still rocking an iPhone and fancy taking a photo every now and then, you'd be crazy not to be using an app called Instagram.  With Instagram you take the photos just as you would with your native iPhone camera app, but Instagram provides a number of image filters to enhance the appearance of the image you've taken.  You can make your photo look brighter, darker, "older", and much more.  The photo is saved both on Instagram's service and your local phone.

Like any other service, Instagram also provides an API which allows you to get image, user, tag, and other account information. Christopher Beloch has taken the time to provide a simple set of MooTools classes which act as a wrapper for Instagram's web API.  This post will show you how to use Instagram's API, Instagram for MooTools, and some simple CSS and JavaScript to create a very simple photo gallery with which you can view all of your photos at once.

You must have an Instagram account to view the demo;  there's currently no way for me to open my account for viewing only.  Also note that Instagram provides a server-side implementation for OpenAuth;  this post will focus on client side only.  Lastly, this post's focus is using Instagram for MooTools (authentication, pulling photos, etc.); not creating the most shocking photo gallery ever.

OpenAuth and Creating "Apps"

Instagram subscribes to the OpenAuth method of verification that applications like Facebook and Twitter use.  To create an Instagram usage client, click here.  There are two important piece of information which you'll need to remember from this page:  a ClientID which will be used to log into your OpenAuth account, and a RedirectURI which the user will be redirected to once they log in.  Creating the app is very simple and you should be through it in a minute -- just remember to save the generated ClientID and RedirectURI you chose.

Including Instagram for MooTools and Dependencies

MooTools for Instagram

Instagram for MooTools is available on the JavaScript treasure chest MooTools Forge.  This set of classes requires MooTools Core and More's Request.JSONP.  The basic photo gallery I create will use More's Element.Delegation, but this class isn't required to use Instagram for MooTools.  There are multiple classes available with Instagram For MooTools, but the quick photo gallery will only use Base (required for all subclasses) and User (which allows for retrieval of user media).

Logging In

My page which will host the photo gallery will require authentication to request images.  To make sure the user has proper authorization, we'll use this snippet of JavaScript:

// Basic settings
var clientId = "YOUR_CLIENT_ID";
var redirectUrl = "http://test.local/instagram.html";

// Create an instance of Instagram with user capabilities
var user = new Instagram({
	client_id: clientId,
	redirect_uri: redirectUrl
});

// If there's no hash, they aren't logged in
if(!window.location.hash) {
	window.location = user.getAuthURL();
}

The code above defines the ClientID and RedirectURI which were provided by Instagram, creates and instance of Instagram, and checks the window.location.hash to make sure an access token is present.  If not, the user is sent to Instagram's sign-in page for this app.  When the user signs in, they will be redirected to your RedirectURI with an access_token properties in the hash.

Simple Photo Gallery Layout

The photo gallery layout will be two columns:  the first column containing the caption and large version of the image retrieved from the service, the second containing clickable thumbnails.  The large image will be fixed to the top left, the thumbnails will scroll during page scroll.  Here's our basic CSS:

#mediaHolderLoading {
	border-radius: 8px;
	background: #222;
	color: #fff;
	padding: 5px 10px;
	font-family: Monaco, Courier, Monospace;
	font-size: 12px;
	z-index:200;
}
#mediaHolder.noPhotos #mediaHolderLoading {
	background: inherit;
	color: #f00;
}

#mediaHolder.noPhotos #largeImageHolder {
	display:none;
}

#largeImageHolder {
	width: 612px;
	height: 612px;
	position: fixed;
	top: 24px;
	left: 27px;
	padding:10px;
	background: #eee;
}

#caption {
	font-size:18px;
	color:#444;
}

#thumbHolder {
	margin-left: 650px;
	margin-top: -5px;
	opacity: 0;
	padding:10px;
	background: #eee;
}

#thumbHolder a {
	width: 150px;
	height: 150px;
	padding: 0 20px 20px 0;
	display: inline-block;
}

#thumbHolder img {
	display:block;
}

#thumbHolder img:hover {
	display:block;
	-webkit-transform: rotate(-3deg) scale(1.1);
	-moz-transform: rotate(-3deg) scale(1.1);
	-o-transform: rotate(-3deg) scale(1.1);
	-ms-transform: rotate(-3deg) scale(1.1);
	transform: rotate(-3deg) scale(1.1);
}

And the HTML it will style:

<div id="mediaHolder">
	<span id="mediaHolderLoading">Loading your photos...</span>
	<div id="largeImageHolder">
		<img src="" id="largeImage" />
		<span id="caption"></span>
	</div>
	<div id="thumbHolder"></div>
</div>

Nothing groundbreaking or overly complex.  Again, this is going to be  a very simple gallery.

Using Instagram For MooTools to Retrieve Images

Assuming we're now logged in and authenticated, we can make our move to retrieve images.  The getMedia method of our Instagram instance will send a JSONP request to Instagram to retrieve all of the authenticated user's photos:

// Makes a JSONP request to go get media
user.getUserMedia();

Before we send that request for images, however, we need to set up a listener for when those images are returned.  After the browsing the Instagram.User and Instagram.Base source, I discovered the event to listen for is the mediaData event.

// Add listener for instagram data reception
user.addEvent("mediaData", function(userPhotos) {
	
	// If there are items received
	if(userPhotos.data.length) {
		 // Do something
	}
	else {
		// Show "no images" message
	}
});

The userPhotos var will provide an array with or without images based on the contents of your account.  Iterate through the array to work with the result.  The addEvent pattern is used throughout the Instagram classes;  be sure to look around to find the proper event to listen to though, as it's not always apparent.

Gallery Creation

Now that we can receive and managed the result, it's time to use basic MooTools JavaScript code to build the thumbnails and delegate clicks to show the larger image:

// Add listener for instagram data reception
user.addEvent("mediaData", function(userPhotos) {
	
	// Get the media holder text
	var mediaHolderLoading = document.id("mediaHolderLoading"),
		mediaHolder = document.id("mediaHolder");
	
	// If there are items received
	if(userPhotos.data.length) {
		// Axe the message
		mediaHolderLoading.destroy();
		
		// Get a few elements
		var thumbHolder = document.id("thumbHolder"),
			largeImage = document.id("largeImage"),
			caption = document.id("caption");
		
		// Create the HTML string
		var html = "",
			template = '<a href="{largeImage}" target="_blank" data-index={index}><img src="{thumbnailImage}" alt="{caption}" /></a>';
		// For every photo received
		userPhotos.data.each(function(photo, index) {
			// Place caption text right on obj for easier access
			photo.captionText = (photo.caption ? photo.caption.text : "");
			// Append to html
			html += template.substitute({
				largeImage: photo.images.standard_resolution.url,
				thumbnailImage: photo.images.thumbnail.url,
				caption: photo.captionText,
				index: index
			});
		});
		// Set the large image and caption
		largeImage.set("src", userPhotos.data[0].images.standard_resolution.url);
		caption.set("html", userPhotos.data[0].captionText);
		
		// Get the thumb holder
		thumbHolder.set("html", html).fade(1);
		
		// Add event delgation to listen for clicks
		thumbHolder.addEvent("click:relay(a)", function(e, a) {
			e.stop();
			// Set the image
			largeImage.set("src",a.get("href"));
			// Get the caption
			caption.set("html", userPhotos.data[a.get("data-index")].captionText);
		});
		
	}
	else {
		mediaHolder.addClass("noPhotos");
		mediaHolderLoading.set("html", "No photos were found.");
	}
});

You'll note that instead of programmatically create and inject nodes into the thumbnail holder, I use string concatenation to generate the HTML.  Doing so is faster than node injection.  I've also used event delegation to avoid numerous event connections.

And there you have it:  a quick overview of Instagram for  MooTools.  Christopher Beloch's work provides a great interface to Instagram's API.  I look forward to seeing what you create with it!

O'Reilly Velocity Conference
Save 20% with discount code AFF20

Recent Features

  • Convert XML to JSON with JavaScript

    If you follow me on Twitter, you know that I've been working on a super top secret mobile application using Appcelerator Titanium.  The experience has been great:  using JavaScript to create easy to write, easy to test, native mobile apps has been fun.  My...

  • Send Text Messages with PHP

    Kids these days, I tell ya.  All they care about is the technology.  The video games.  The bottled water.  Oh, and the texting, always the texting.  Back in my day, all we had was...OK, I had all of these things too.  But I still don't get...

Incredible Demos

  • Input Incrementer and Decrementer with MooTools

    Chris Coyier's CSS-Tricks blog is everything mine isn't. Chris' blog is rock star popular, mine is not. Chris prefers jQuery, I prefer MooTools. Chris does posts with practical solutions, I do posts about stupid video-game like effects. If I...

  • Introducing MooTools ScrollSidebar

    How many times are you putting together a HTML navigation block or utility block of elements that you wish could be seen everywhere on a page? I've created a solution that will seamlessly allow you to do so: ScrollSidebar. ScrollSidebar allows you...

Discussion

  1. Alpha Chung

    Well, I followed you on Instagram. :)

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!

Recently on David Walsh Blog

  • Open Files from Command Line on OS X

    I'm as much of a fan of application UIs as anyone else but I'm finding myself working more and more from the command line lately.  Much of that is becoming obsessed with media manipulation but I'm forcing myself to use less UIs so that I...

  • Get Stock Quotes From Command Line

    When I conned my way into my first professional programming gig, I didn't really think much about money -- just that I was getting my foot in the door.  But as my career has gone on, I've been more aware of money, investing, and retirement.  I've recently...

  • Geolocation API

    One interesting aspect of web development is geolocation; where is your user viewing your website from? You can base your language locale on that data or show certain products in your store based on the user's location. Let's examine how you can...

  • Create an Image Preview from a Video

    Visuals are everything when it comes to media.  When I'm trying to decide whether to watch a video on Netflix, it would be awesome to see a trailer of some kind, but alas that isn't available.  When I'm looking to download a video on my computer,...

  • New:  Webdesigner News!

    A new and exciting website has recently been launched for web designers and developers. You likely spend hours every morning browsing through hundreds of posts on your RSS feeds, hoping to stumble across relevant stories. Webdesigner News was built to provide web designers and developers with...