Grow your CSS skills. Land your dream job.

Building an Animated Cartoon Robot with jQuery

Published by Chris Coyier

Why?

Aside from being a fun exercise, what purpose does something like this have? None that's plainly obvious. Its about as useful as a miniature ship in a bottle. Yet it does have an underlying purpose. It could inspire someone to look beyond the perceived constraints of web designers and developers.

View Demo

 

Overview

This project was created by layering several empty divs over each other with transparent PNGs as background images.

The backgrounds were animated at different speeds using a jQuery plug-in by Alexander Farkas. This effect simulates a faux 3-D animated background dubbed the “parallax effect” originating from old-school side scrolling video games.

The robot is comprised similarly to the background animation scene by layering several DIVs together to create the different robot pieces. The final step, was animating the robot with some jQuery.

The Markup

<div id="wrapper">
	
  <div id="cloud-01">
  <div id="cloud-02">
  <div id="mountains-03">	
  <div id="ground">
	
  <div id="full-robot">
    <div id="branding"><h1>Robot Head.</h1></div> 
    <div id="content"><p> Robot Chest.</p></div> 
    <div id="sec-content"><p> Robot Pelvis.</p></div> 
    <div id="footer"><p> Robot Legs.</p></div>
  </div>

  </div>
  </div>
  </div>
  </div>

</div>

The structure of the divs closely resembles our diagram. None of the DIVs has the width attribute specified so they will expand to fill the size of any browser window they are displayed on. NOTE: All the images that make the background scenery parallax effect are 9999px wide. Well beyond the width of any computer display or television in common use. We’ll use CSS to place the background images exactly where we want within each particular div.

The Style

The CSS for this project is just as simple as the markup.

h1, p { position: absolute; left: -9999px; }

div {position: relative;}

#wrapper { background: #bedfe4 url(../images/sun.png) no-repeat left -30px; border: 5px solid #402309;}

#cloud-01 { background: url(../images/clouds-01.png) no-repeat left -100px; }                                                         
                                                          
#cloud-02 {	background: url(../images/clouds-02.png) no-repeat left top; }

#mountains-03 { background: url(../images/mountain-03.png) no-repeat left bottom; }

#ground { background: url(../images/ground-05.png) no-repeat left bottom; }

#full-robot { width: 271px; }

#branding { 
	background: url(../images/robot-head.png) no-repeat center top;
	width: 271px;
	height: 253px;
	z-index: 4; 
	}

#content {
	background: url(../images/robot-torso.png) no-repeat center top;
	width: 271px;
	height: 164px;
	z-index: 3;
	margin-top: -65px;
	}

#sec-content {
	background: url(../images/robot-hips.png) no-repeat center top;
	width: 271px;
	height: 124px;
	z-index: 2;
	margin-top: -90px;
	}

#footer {
	background: url('../images/robot-legs.png') no-repeat center top;
	width: 271px;
	height: 244px;
	z-index: 1;
	margin-top: -90px;
	}

Absolute positioning is used to pull any header or paragraph text 9999px to the left of the screen. Then we declare every DIV in the page position: relative. By making all the DIVs position: relative;, we now have the ability to the use the z-index property to reverse the natural stacking order of the robot DIVs.

The jQuery JavaScript

Disclaimer: The original script to animate the robot was horrid. The good folks at coding cyborg were kind enough to clean it up and re-write it.

$(document).ready(function(){ 
$('#cloud-01').css({backgroundPosition: '0 -80px'});
$('#cloud-02').css({backgroundPosition: '0 -30px'});
$('#mountains-03').css({backgroundPosition: '0 50px'});
$('#trees-04').css({backgroundPosition: '0 50px'});
$('#ground').css({backgroundPosition: 'left bottom'});
$('#branding').css({backgroundPosition: 'center 0'});
$('#content').css({backgroundPosition: 'center 0'});
$('#sec-content').css({backgroundPosition: 'center 0'});
$('#footer').css({backgroundPosition: 'center 0'});
$('#wrapper').css({overflow: "hidden"});

	$('#klicker').click(function(){
		$('#cloud-01').animate({backgroundPosition: '(-500px -80px)'}, 20000);
		$('#cloud-02').animate({backgroundPosition: '(-625px -30px)'}, 20000);
		$('#mountains-03').animate({backgroundPosition: '(-2500px 50px)'}, 20000);
		$('#ground').animate({backgroundPosition: '(-5000px bottom)'}, 20000);
	
	startHim();
	
	$("#full-robot").animate({left:"50%",marginLeft:"-150px"}, 2000);
	setTimeout("leaveScreen()",15000);
	});
		
});

var num = 1;

function startHim(){
	num++;
	$("#sec-content").animate({top:"-=5px"},150).animate({top:"+=5px"},150);
	$("#content,#branding").animate({top:"-="+num+"px"},150).animate({top:"+="+num+"px"},150);
	if(num<4){
		setTimeout("startHim()",300);
	} else {
		setTimeout("bounceHim()",300);
	}
}
	
function bounceHim(){
	$("#sec-content,#branding").animate({top:"-=4px"},150).animate({top:"+=4px"},150);
		$("#content").animate({top:"-=8px"},150).animate({top:"+=8px"},150);
	setTimeout("bounceHim()",300);
}
	
function leaveScreen(){
	$("#full-robot").animate({left:"100%",marginLeft:"0px"}, 2000);
}

We begin by re-affirming the original background position of all the images.

Upon clicking the ‘#klicker’ div, a function tells jQuery to animate the backgrounds from their current position all the way to the coordinates specified for each div. By separating all the different image layers into different DIVs we can animate the background elements at different speeds. Moving the elements at different speeds gives an illusion of a 3rd dimension. We move the elements in the background at a much slower rate than the elements in the foreground. Notice on this animation that the speed of the clouds in the background is slower than the speed of the mountains. And the mountains are slower than the ground which is the fastest of all. Finally after firing off all these commands to get the background moving the ‘#klicker’ function calls on the ‘startHim()’ function.

The ‘startHim()’ function, you guessed it right, starts our robot. It begins his little bounce and gets him moving to the center of the #wrapper div. The ‘startHim()’ function calls on the ‘bounceHim()’ function. And then it keeps looping.

We need to make the robot seem like it was bouncing on a rough desert rode. To achieve that bouncy irregular effect we’ll use the ‘bounceHim()’ function. It targets the separate robot DIVs and ‘bounces’ them 5px up and then 5px down. That wont be enough though, all the different pieces of the robot bouncing at the same rate looks too stiff. We need to make it look a bit more random and interesting. So we’ll take the div that makes the chest portion of the robot and move it at a different rate than the head and pelvis pieces. We’ll ‘bounce’ the chest part at 8px up and 8px down. This gives the robot a nice off-beat bouncy effect.

The ‘leaveScreen()’ function is the last function called. After 15 seconds (15000) it moves the robot 100% percent to the left of the screen which consequently moves the robot off to the right of the screen.

Anthony Calzadilla is an independent web designer based out of Miami, FL. USA.

Note from Chris

I think this is an extremely cool experiment. I'd say for most users, the end result is indistinguishable from Flash. Yet, the advantages over Flash are enormous. Each piece of the animation is separate and can be altered/replaced easily. Tweaks to the animation style can be done with numbers within the JavaScript file itself as opposed to having to alter an original Flash document and re-export/upload an entire new version.

Comments

  1. Really nicely done! I would recommend caching some of those selectors, but a really nice concept.

  2. Permalink to comment#

    Wow, I agree… very nice! It's interesting to see how far we try to push web design sometimes. I like this a lot!!!
    Greg

  3. This is very cool. I had NO idea that jQuery was able to do animations of that scale.

  4. Permalink to comment#

    I have seen this before it is a very nice effect but way over my head

  5. Tobi
    Permalink to comment#

    sick shit..

  6. 9swords
    Permalink to comment#

    :::::::: i like this part :::::::::::;;; ({top:"+="+num+"px"} :::::::: cool

  7. AR2RO
    Permalink to comment#

    Hey men!

    This is great my partners thought that this is Flash animation! :D

    Great job!

  8. Permalink to comment#

    Very cool! I love this type of jQuery stuff! Nice job!

  9. Very cool! I love things that take functionality away from flash!

  10. Very impressive that jquery that handle such "animation" tendencies. I kept right clicking waiting to see the Flash Player pop up, but nope! AMAZING!

  11. Permalink to comment#

    Although it wasn’t really useful, it still is really, REALLY awesome to see something like this. This absolutely shows that the line between Flash & JavaScript / xHTML is fading: Well done and my compliments.

  12. Michał Czernow
    Permalink to comment#

    Not very semantic though ;).

  13. Permalink to comment#

    hell yeah!

  14. Permalink to comment#

    Tweaks to the animation style can be done with numbers within the JavaScript file itself as opposed to having to alter an original Flash document and re-export/upload an entire new version.

    That sums it up perfectly. It’s absolutely annoying having to go back and rework animation.

    Thanks for sharing!

  15. Flash is the Bane of my existence… so this is quite welcomed haha

    CHEERS

  16. Aside from being a fun exercise, what purpose does something like this have? None that’s plainly obvious. Its about as useful as a miniature ship in a bottle. Yet it does have an underlying purpose. It could inspire someone to look beyond the perceived constraints of web designers and developers.

    I don’t necessarily agree with this statement.

    Using JavaScript animation is a great way to create interactive applications that degrade gracefully (i.e. you never see the “You need to upgrade to the latest version of Flash to see this content” message).

    Using techniques like this means your information is still easily accessible by screen readers, search engines, and the like. And you still get sweet animation.

    Simply put, mastering this technique is having your cake and eating it, too.

    -Jason

  17. Permalink to comment#

    Inspiring! This have given me a great idea for a very useful / educational “app”.
    Thanks again.

  18. nice tut thanks..

  19. Permalink to comment#

    Great piece of lateral thinking, nice to see folks pushing boundaries

  20. Permalink to comment#

    very cool~

  21. Roderick
    Permalink to comment#

    Didn’t I see this exactly same thing before? I can swear that I did. Did you write this for another website and publish it before?

  22. Permalink to comment#

    Very nice stuff, like it! But the bots midsection wont stay in its position, when i start the animation – i’m using Opera 9.6

  23. Permalink to comment#

    i like it :) it’s so pretty

  24. jQuery is a powerful library that continues to impress me…this is a very cool experiment and extremely useful for the non-flash folks out there.

  25. Nicely done! Very similar to my own jQuery Paralax plugin

  26. Great tutorial, but wouldn’t it be easier to do this in flash. I mean it might be more accessible but it seems an awful lot of effort for something so simple.

  27. jon
    Permalink to comment#

    brilliant boundary pushing. inspirational. you rock my socks!

  28. Very nice. Good job.

  29. Cody
    Permalink to comment#

    This is so web 1.0! Anybody on the cutting edge of design would know well enough to use an energy saving light bulb for the robot’s nose! jk =P

  30. Permalink to comment#

    P-town represent! You should have made it a hipster robot.

  31. Permalink to comment#

    I am totally impressed.. way to go developers! Way to go jQuery!

  32. jQuery forever!!

  33. Hi all, I’m glad you guys liked the tut. Big thanks to Chris for posting it here!

  34. This is one of the most impressive things I have seen online for a while. I am quite new to jQuery and originated in flash. I have since left flash behind to create, user friendly, search engine friendly websites:www.punklogic.com It seems to me like there is a little javascript revolution going on behind the scenes? Do you think that it could replace flash?

    • matt
      Permalink to comment#

      Do you think that it could replace
      flash?

      Does it sound, does it scale ?

      Never ever this will replace flash…why should it, btw ??

    • James
      Permalink to comment#

      Since most of the functionality is on the client, I’d say it scales as well as any webage. As for replacing Flash, I will give you the benefit of the doubt and presume you are not trolling. Flash is a binary, proprietary closed-source plugin with a limited number of working platforms, much fewer than HTML/Javascript. Replacing Flash with javascrpt/html/canvas/svg/smil is a very good thing.

  35. Covienam
    Permalink to comment#

    Very impressive

  36. Hi, all these JavaScript libraries are cool, I could see them replacing flash on the UI/Interface front one day… but not for animation. Especially Flash CS4, its like a mini AfterEffects for vectors.

  37. Permalink to comment#

    Very nice tutorial. I always planned to add some little animation my website, but didn’t feel like going the Flash way. Now I see I don’t have to.

  38. This is something different.. and It is one of the most impressive things I have seen so far …

  39. BialyGryf
    Permalink to comment#

    hm… test in Opera please…

  40. Permalink to comment#

    Very cool, will I every need this?

This comment thread is closed. If you have important information to share, you can always contact me.

*May or may not contain any actual "CSS" or "Tricks".