Building an Animated Cartoon Robot with jQuery

Avatar of Chris Coyier
Chris Coyier on (Updated on )

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.