Crafting an Animated Postcard With jQuery

Nicely illustrated banners are…nice. But why not add a little pizazz by using animation like Flash websites do?

Through Javascript web pages are becoming increasingly less static and all sorts of creative possibilities are opening up.

In this tutorial we will learn the basics of setting up a continuous animation which can be applied pretty much anywhere. Take a peek below to see an outline of what we’ll be learning today.

What You’ll Learn

  • The art of looping animations using setTimeout()
  • How to take advantage of the Easing plugin
  • A new way to spice up your banner

The HTML

Laying down the groundwork is pretty simple, essentially we create a canvas (‘#content’) and center it with ‘#wrapper’ – pretty standard practice. The difference between this and the average layout lies in our use of ‘position:absolute’ to place each image, which is why there isn’t any real hierarchy to all the elements with images.

<div id="wrapper">
   <div id="content">
      <div id="sun"><img src="images/sun.gif"/></div>
      <div id="cloud1"><img src="images/cloud1.png"></div>
      <div id="cloud2"><img src="images/cloud2.png"></div>
      <div id="cloud3"><img src="images/cloud3.png"></div>
      <div id="raft"><img src="images/raft.png"></div>
      <div id="raftripple"><img src="images/raftripple.gif"></div>
      <div id="greetings"><img src="images/greetings.png"></div>
      <div id="stamp"><img src="images/stamp.png"></div>
   </div>
</div>

The CSS

Next up we will want to plug in all the CSS, I have included comments below to block out the importance of each style.

*{ margin:0; padding:0; }
body { text-align: center; background: #111; }

//Width should match that of the child element #content
#wrapper{ margin:0px auto; width:700px; }

//The canvas for our postcard, must be position:relative/overflow:hidden
#content{ position:relative; width:700px; height:300px; top:30px; overflow:hidden; border:5px solid #f5f5f5; background: url('images/scene_bg.jpg'); }

	#sun{ position:absolute; top:10px; left:30px; }

	//Note the negative left values that hide the clouds offscreen
	//The z-indexes define how the clouds with stack on top of each other
	#cloud1{ position:absolute; top:60px; left: -150px; z-index:5; }
	#cloud2{ position:absolute; top:40px; left: -250px; z-index:4; }
	#cloud3{ position:absolute; top:25px; left: -100px; z-index:3; }

	//Our raft/ripple under the raft, z-indexes stack them accordingly
	#raft{ position:absolute; top:220px; left: 312px; z-index:20; }
	#raftripple{ position:absolute; top:220px; left: 309px; z-index:19; }

	//The text and stamp both positioned off-screen and on top of everything
	#greetings{ position:absolute; top:-51px; left: 200px; z-index:21; }
	#stamp{ position:absolute; top:5px; left: 801px; z-index: 21; }

At this point in the game you should be looking at something pretty similar to this:

Get Your jQuery Ready

For those of you that aren’t as familiar with the whole jQuery scene we’re going to need to tag the following two lines into the <head> of the page:

<script type="text/javascript" src="http://jqueryjs.googlecode.com/files/jquery-1.3.2.js"></script>
<script src="jquery.easing.1.3.js" type="text/javascript"></script>

The first line calls jQuery, but the second calls the Easing Plugin, which might not be as familiar to you. We will be making use of it later in the tutorial, so for convenience sake, I have provided it in the downloadable files. If you’re one of those independent folks you could download it from the official site too, I won’t be offended.

The Basic Template for Looping an Animation

Below I have outlined the format for making a function that does a looped animation, in this case it is called the rather ambiguous name – ‘animate_element’.

function animate_element(){
 $("#element").animate({left:"+=100px"},1000).animate({left:"-=100px"}, 1000)
 setTimeout("element()",2000);
}

If we pay attention the the first line of code within the function, we can see that it runs two animations, one after the other.

$("#element").animate({left:"+=100px"},1000).animate({left:"-=100px"}, 1000)

The first of the two moves the element 100px from the left relative to it’s current location – as denoted by the ‘+=’. When that animation is complete the next will be triggered, which does the exact opposite and moves the element back to it’s starting location.

When the animations finish then we want to have the same function called again, so that they will be repeated. We do this via setTimeout(), which can trigger events based on a timer.

setTimeout("element()",2000);

The key point to notice is that the timer (2000 in this case) should be the sum of all the animation times in the previous line. This essentially will allow for each of the animations to complete (1000 + 1000), before restarting the function.

Creating Looped Animations for Our Postcard

After having just educated yourself in the setup for an animation, you should be be more than qualified to follow along in this next step, where we define a series of animation loops. Instead of doing a separate function for each individual animation, those that take the same amount of time to complete can be grouped together.

function sun_raft(){
	$("#sun").animate({opacity:".7"},1000).animate({opacity:"1"},1000);
	$("#raft").animate({top:"-=5px"},1000).animate({top:"+=5px"}, 1000);
	$("#raftripple").animate({opacity:".1"},1000).animate({opacity:"1"},1000);
	setTimeout("sun_raft()",2000);
}
function cloud1(){
	$("#cloud1").animate({left:"+=850px"},10000).animate({left:"-150px"}, 0)
	setTimeout("cloud1()",10000);
}
function cloud2(){
	$("#cloud2").animate({left:"+=950px"},9000).animate({left:"-250px"}, 0)
	setTimeout("cloud2()",9000);
}
function cloud3(){
	$("#cloud3").animate({left:"+=800px"},6000).animate({left:"-100px"}, 0)
	setTimeout("cloud3()",6000);
}

In the instance of the clouds, which will be constantly scrolling across the screen, after they travel the distance, they are reset to their initial location via an animation that takes 0 time (therefore instantaneous).

The raft portion of the postcard has two animations going side by side – The raft bobs up and down, while the ripple underneath fades in and out.

Putting It All Together (in a Function)

Now that we’ve defined the animations that will be looping let’s combine them all into a function that we can then call when the page loads.

function animation(){
	sun_raft();
	cloud1();
	cloud2();
	cloud3();
}

Wonderfully simple. Now instead of having to type out 4 different functions each time, we can simply call animation().

Adding One Time Animations & The Easing Plugin

Within our animated postcard we don’t necessarily want everything looping – in this example we only want the “Greetings from Build Internet!” and stamp to animate once. In order to accomplish this, we’re just going to tack the following two lines onto the end of the animation():

$("#greetings").animate({top: '125px' }, {queue:false, duration:600, easing:'easeOutBounce'});
$("#stamp").animate({left: '595px' }, {queue:false, duration:1200, easing:'easeOutBounce'});

You might have noticed the extra stuff built into animate(), don’t panic, that’s the Easing Plugin we talked about before doing it’s job. There are a number of options to play with, but for this example I’ve opted for a bounce effect when the text and stamp roll in, it adds some nice flair.

Time To Set It Off

We’ve got everything in order we need to actually have an event trigger animation(), I want it to begin as soon as the page loads, so this is what mine will look like:

$(document).ready(function() {
	setTimeout("animation()",300);
});

Special Note : You may have noticed I added a setTimeout() before calling animation() – This is so the visitor/browser have time to get situated before firing off the animations. If your animations are triggered by a click or something of that nature, you won’t need to encase animation() in a setTimeout().

Your Postcard Is Ready

Consider yourself armed with knowledge, obviously there are a fair share of creative applications for looped animations, so get cooking! For those of you craving more, check out the CSS-Tricks article called Building an Animated Cartoon Robot with jQuery.

  • Stumble It!
  • Bookmark It!
  • Tweet it!

About Sam Dunn

Sam is a designer and co-founder of One Mighty Roar from Massachusetts, USA. He takes particular interest in all things aesthetically pleasing. He can be found online at Vivalasam and Twitter.

 

Discussion

  1. Brian Klepper

    August 10th, 2009 at 12:04 AM

    Excellent work! I am currently working on a small project using similar functions. Thanks for the post
    .-= Brian Klepper´s last blog ..Steal Everything Excerpt =-.

  2. Robert Fisher

    August 10th, 2009 at 1:41 AM

    Great tutorial! I can imagine how this code can be used for other projects.
    .-= Robert Fisher´s last blog ..Math Resources Online =-.

  3. Hezi

    August 10th, 2009 at 1:50 AM

    rocknroll!
    .-= Hezi´s last blog ..HeziAbrass: Probably the most impressive animated gif ever http://bit.ly/PEUTs =-.

  4. mrvn

    August 10th, 2009 at 2:48 AM

    cool stuff. very useful for many other things too!!
    .-= mrvn´s last blog ..Artcore die Zweite =-.

  5. anil singh

    August 10th, 2009 at 2:55 AM

    Useful and intersting info

  6. Raja Sekharan

    August 10th, 2009 at 7:40 AM

    Great tutorial Sam. There is a similar implementation using mootools here:

    http://devthought.com/

    The clouds disappear when you click on them and can be dragged around. Really nice effect.
    .-= Raja Sekharan´s last blog ..How To Create Custom Forms Using Drupal In 4 Easy Steps =-.

  7. choen

    August 10th, 2009 at 1:14 PM

    ow. i liked. thanks… I want to try this tutorial
    .-= choen´s last blog ..Menggunakan sIFR 2.0 di ‘Blogger Template’ =-.

  8. tiff

    August 11th, 2009 at 11:00 AM

    Great tutorial!
    But where can I found (background-)images like this?

  9. webmasterdubai

    August 13th, 2009 at 12:59 AM

    wowo great work nice tutorial anybody can think its flash but is jquery.

  10. Jason

    August 14th, 2009 at 3:12 PM

    Awesome tutorial! I love how jQuery can be used in place of flash in many cases.
    .-= Jason´s last blog ..Creating Blind Accessible Web Sites and Applications =-.

  11. Sam Dunn

    August 16th, 2009 at 12:57 PM

    Thanks for the great feedback everyone.

    @tiff
    I created all of these background images specifically for this tutorial

  12. Scott

    August 17th, 2009 at 1:33 AM

    Would love to see how to do this on a div that is fluid and goes across the whole screen.

  13. Anthony Calzadilla

    August 31st, 2009 at 11:46 AM

    Excellent article Sam! You’ve inspired me to re-visit my jQuery robot and try to up the ante of jQuery animation.

    Thanks!
    Anthony
    .-= Anthony Calzadilla´s last blog ..Let’s Word Out Key Terms Like XHTML, jQuery and CSS =-.

  14. Luciano Santa Brígida

    August 31st, 2009 at 3:43 PM

    Hi, I loved this tutorial and easily built a banner like this one here. But when I published to the web I experienced a conflict with the jquery cycle plugin, which is also called by using jQuery(document).ready(function($) { $(“#rotator”).cycle({fx: ‘fade’, timeout: 6000, }); });
    When I remove those lines the banner animation goes ok. Any ideas on how to solve this?

  15. Luciano Santa Brígida

    August 31st, 2009 at 6:41 PM

    I figured a partial solution: I replaced $(document).ready(function() {} ) for $(window).load(function() {} )

    But unfortunately, it didn’t work on Chrome. IE and FF are OK, only tested in these 3 so far.

    Question: if I used setInterval instead of setTimeout, would I achieve the same loop effect? Could this fix the Chrome problem?
    .-= Luciano Santa Brígida´s last blog ..Dicionário Twitter =-.

  16. Amy

    September 1st, 2009 at 11:06 PM

    Awesome tutorial, now all we have to do is set the background color to change based on the time of day, and make the tube bob up and down in response to the user’s mouse movements, and we’re really cooking!

  17. bayXSonic

    November 29th, 2009 at 2:02 PM

    ooo ugly setTimeout!
    Im working on a project now and I came up with this:
    function pulse(selector){
    $(selector).animate({opacity:.7}, 500).animate({opacity:.9}, 500, function(){pulse(selector)});
    }

    But I’m sure that it can be improved much more.

  18. Vishal Modha

    December 18th, 2009 at 7:23 AM

    I’ve taken this a few steps further by adding an interactive Santa to the mix with the use of the sound plugin….

    Check it out here and tell me what you think:
    http://modasoft.co.uk/ecard.html

    Thanks for this article, it’s been a great stepping stone.

  19. Mike Croteau

    January 30th, 2010 at 5:11 PM

    Very cool… plan on playing around with this!

Join the Conversation!

Remember: Life's not all doom and gloom, so please keep it constructive. If we've made an error or missed something big, please let us know! Learning is revisions, after all.

CommentLuv is Enabled

 

Sponsors

Advertise on Build Internet!