Animation via les équations de robert penner

Contenu du snippet

Cette source est une 'base' pour ceux et celles qui désirent créer leur moteur d'animations en Javascript.
Robert Penner, mathématicien en herbe plus connu dans l'univers du Flash, a mis au point il y a déjà quelques temps une serie d'équations permettant l'animation d'objets sous divers effets. On retrouve ces équations dans plusieurs librairies JS connues (mootools par exemple).

Mon exemple fournis 4 des effets les plus sympa et leur système d'utilisation. Vous trouverez l'ensemble des équations à l'adresse suivante :

http://www.robertpenner.com/easing/

Source / Exemple :


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>Effets</title>
<style type="text/css">
	body{ font: 11px/16px Arial, "Trebushet MS", Helvetica; color: #333; }
	h2{ font-weight: bold; font-size: 14px; }
	td.libelle{ width: 180px; }
	td.valeur{ width: 100px; }
	td.inputs, td.select{ width: 100%; }
	#animation{ height: 32px; width: 32px; background: #aaccf6;	margin: 22px; }
</style>
</head>
<body>
<table>
	<tr>
		<td class="libelle">Durée de l'animation (en ms)</td>
		<td class="valeur"><input type="text" id="duration" value="800"/></td>
	</tr>
	<tr>
		<td class="libelle">Nombre de pixels à animer</td>
		<td class="valeur"><input type="text" id="nbPix" value="180"/></td>
	</tr>
	<tr>
		<td class="libelle">Transition</td>
		<td class="valeur">
			<select id="transition">
				<option value="linear" selected="selected">Lineaire</option>
				<option value="elastic">Elastique</option>
				<option value="bounce">Bonds</option>
				<option value="skid">Liquide</option>
			</select>
		</td>
	</tr>
	<tr>
		<td class="libelle">Valeur à modifier</td>
		<td class="valeur">
			<select id="cssRule">
				<option value="height" selected="selected">Hauteur</option>
				<option value="width">Largeur</option>
				<option value="both">Hauteur et largeur</option>
			</select>
		</td>
	</tr>
</table>

<input type="button" value="GO" onclick="animate()"/> <input type="button" value="Reset" onclick="reset()"/>

<div id="animation"></div>

<script type="text/javascript">
	function $(idObj){
		return document.getElementById(idObj);
	};
	
	var transitions = {
		linear: function(t, b, c, d){ return c*t/d + b; },
		elastic: function (t,b,c,d,a,p){
			if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
			if (!a || a < Math.abs(c)) { a=c; var s=p/4; }
			else var s = p/(2*Math.PI) * Math.asin (c/a);
			return (a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b);
		},
		bounce: function(t,b,c,d){
			if((t/=d) < (1/2.75)) {
				return c*(7.5625*t*t) + b;
			}else if (t < (2/2.75)) {
				return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
			}else if (t < (2.5/2.75)) {
				return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
			}else{
				return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
			}
		},
		skid: function(t,b,c,d){
			var s = 1.70158;
			return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
		}
	};
	
	function reset(){
		$('animation').style.height = '32px';
		$('animation').style.width = '32px';
	};
	
	function animate(){
		var target = $('animation');
		var tmr = (1000/80); //assure une moyenne de 80 images par secondes
		var nbSteps = Math.round($('duration').value/tmr);
		var step = Math.abs(32 - $('nbPix').value)/nbSteps;
		var mapping = [];
		//On remplis un tableau contenant toutes les étapes de l'animation
		for(var i=1; i<=nbSteps; i++){
			mapping.push(transitions[$('transition').value](i*tmr, 32, $('nbPix').value - 32, $('duration').value));
		}
		var currentStep = 0;
		var timer = window.setInterval(function(){
			if(mapping[currentStep]){
				if($('cssRule').value=='both'){
					$('animation').style['height'] = mapping[currentStep]+'px';
					$('animation').style['width'] = mapping[currentStep]+'px';
				}else $('animation').style[$('cssRule').value] = mapping[currentStep]+'px';
				currentStep++;
			}else{
				window.clearInterval(timer);
				return;
			}
		}, tmr);
	};

</script>
</body>
</html>

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.