Building a data-driven image carousel with Sencha Touch 2
February 11, 2012 35 Comments
This evening I embarked on a little stellar voyage that I’d like to share with you all. Most people with great taste love astronomy and Sencha Touch 2, so why not combine them in a fun evening’s web app building?
NASA has been running a small site called APOD (Astronomy Picture Of the Day) for a long time now, as you can probably tell by the awesome web design of that page. Despite its 1998-era styling, this site incorporates some pretty stunning images of the universe and is begging for a mobile app interpretation.
We’re not going to go crazy, in fact this whole thing only took about an hour to create, but hopefully it’s a useful look at how to put something like this together. In this case, we’re just going to write a quick app that pulls down the last 20 pictures and shows them in a carousel with an optional title.
Here’s what it looks like live. You’ll need a webkit browser (Chrome or Safari) to see this, alternatively load up http://code.edspencer.net/apod on a phone or tablet device:
The full source code for the app is up on github, and we’ll go through it bit by bit below.
Our app consists of 5 files:
app.js, which boots our application up
app/model/Picture.js, which represents a single APOD picture
app/view/Picture.js, which shows a picture on the page
app/store/Pictures.js, which fetches the pictures from the APOD RSS feed
The whole thing is up on github and you can see a live demo at http://code.edspencer.net/apod. To see what it’s doing tap that link on your phone or tablet, and to really feel it add it to your homescreen to get rid of that browser chrome.
Most of the action happens in app.js, which for your enjoyment is more documentation than code. Here’s the gist of it:
This is pretty simple stuff and you can probably just follow the comments to see what’s going on. Basically though the app.js is responsible for launching our application, creating the Carousel and info Components, and setting up a couple of convenient event listeners.
We also had a few other files:
Found in app/model/Picture.js, our model is mostly just a list of fields sent back in the RSS feed. There is one that’s somewhat more complicated than the rest though – the ‘image’ field. Ideally, the RSS feed would have sent back the url of the image in a separate field and we could just pull it out like any other, but alas it is embedded inside the main content.
To get around this, we just specify a convert function that grabs the content field, finds the first image url inside of it and pulls it out. To make sure it looks good on any device we also pass it through Sencha IO src, which resizes the image to fit the screen size of whatever device we happen to be viewing it on:
Our Store is even simpler than our Model. All it does is load the APOD RSS feed over JSON-P (via Google’s RSS Feed API) and decode the data with a very simple JSON Reader. This automatically pulls down the images and runs them through our Model’s convert function:
Tying it all together
Our app.js loads our Model and Store, plus a really simple Picture view that is basically just an Ext.Img. All it does then is render the Carousel and Info Component to the screen and tie up a couple of listeners.
In case you weren’t paying attention before, the info component is just an Ext.Component that we rendered up in app.js as a place to render the title of the image you’re currently looking at. When you swipe between items in the carousel the activeitemchange event is fired, which we listen to near the top of app.js. All our activeitemchange listener does is update the HTML of the info component to the title of the image we just swiped to.
But what about the info component itself? Well at the bottom of app.js we added a tap listener on Ext.Viewport that hides or shows the info Component whenever you tap anywhere on the screen (except if you tap on the Carousel indicator icons). With a little CSS transition loveliness we get a nice fade in/out transition when we tap the screen to reveal the image title. Here’s that tap listener again:
The End of the Beginning
This was a really simple app that shows how easy it is to put these things together with Sencha Touch 2. Like with most stories though there’s more to come so keep an eye out for parts 2 and 3 of this intergalactic adventure.