Treehouse

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!

ydkjs-2.png

Recent Features

  • CSS 3D Folding&nbsp;Animation

    Google Plus provides loads of inspiration for front-end developers, especially when it comes to the CSS and JavaScript wonders they create. Last year I duplicated their incredible PhotoStack effect with both MooTools and pure CSS; this time I'm going to duplicate...

  • 5 HTML5 APIs You Didn&#8217;t Know&nbsp;Existed

    When you say or read "HTML5", you half expect exotic dancers and unicorns to walk into the room to the tune of "I'm Sexy and I Know It."  Can you blame us though?  We watched the fundamental APIs stagnate for so long that a basic feature...

Incredible Demos

  • Pure CSS Slide Up and Slide&nbsp;Down

    If I can avoid using JavaScript for element animations, I'm incredibly happy and driven to do so.  They're more efficient, don't require a JavaScript framework to manage steps, and they're more elegant.  One effect that is difficult to nail down with pure CSS is sliding up...

  • Element Position Swapping Using MooTools&nbsp;1.2

    We all know that MooTools 1.2 can do some pretty awesome animations. What if we want to quickly make two element swap positions without a lot of fuss? Now you can by implementing a MooTools swap() method. MooTools 1.2 Implementation MooTools 1.2 Usage To call the swap...

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!