jQuery: animazioni in sequenza e seriali con i deferred objects

Con i deferred objects, introdotti a partire da jQuery 1.5, possiamo creare animazioni in sequenza evitando di scrivere codice ridondante e prolisso. In particolare, jQuery 1.6 fornisce il metodo pipe() di un oggetto di tipo Deferred proprio per questo scopo. Vediamo insieme i dettagli.

Codice per le animazioni sequenziali

La struttura del codice per le animazioni sequenziali è la seguente:


$.Deferred(function(dfr) {

	dfr.pipe(function() {
	
		return animazione1;
	
	}).
	pipe(function() {
	
		return animazione2;
	
	}).
	pipe(function() {
	
		return animazioneN;
	
	});



}).resolve();

dfr è un riferimento all'oggetto Deferred corrente. pipe() viene concatenato per creare uno stack di animazioni sequenziali che verranno eseguite serialmente.

Esempio pratico

Abbiamo la seguente struttura HTML:


<body>
<div id="topleft"></div>
<div id="topright"></div>
<div id="bottomleft"></div>
<div id="bottomright"></div>

<div id="center"></div>
</body>

Con i seguenti stili CSS:


html, body {
	margin: 0;
	padding: 0;
	height: 100%;
	min-height: 100%;
}

body {
	position: relative;
}

#topleft, #topright,
#bottomleft, #bottomright,
#center {
	position: absolute;
}

#topleft, #topright,
#bottomleft, #bottomright {
	width: 100px;
	height: 100px;
	z-index: 2;
}

#center {
	top: 50%;
	left: 50%;
	margin: -100px 0 0 -100px;
	width: 200px;
	height: 200px;
	background: #ccc;
	z-index: 1;
}

#topleft {
	top: 0;
	left: 0;
	background: #00f;
}

#topright {
	top: 0;
	right: 0;
	background: #f00;
}

#bottomleft {
	bottom: 0;
	left: 0;
	background: #800;
}

#bottomright {
	bottom: 0;
	right: 0;
	background: #008;
}

Vogliamo che i quattro quadrati posti ai lati della pagina vadano ad unirsi uno dopo l'altro nel quadrato centrale. Dopo che ciò è avvenuto, il quadrato centrale deve espandersi fino a coprire l'intera pagina lasciando i quattro quadrati in primo piano al centro. Ecco il codice jQuery:


var Animation = new function() {

	var center = $('#center');
	var coordinates = {
	
		top: center.offset().top,
		left: center.offset().left
	
	};
		
	this.run = function() {
	
		setTimeout(function() {
	
	    	$.Deferred(function(dfr) {
	    	
	    		
	    		dfr.pipe(function() {
	    		
	    			return $('#topleft').animate({
	    				top: coordinates.top,
	    				left: coordinates.left
	    			}, 'slow');
	    		
	    		}).
	    		pipe(function() {
	    		
	    			return $('#topright').animate({
	    				top: coordinates.top,
	    				left: coordinates.left + 100
	    			}, 'slow');
	    		
	    		}).
	    		pipe(function() {
	    		
	    			return $('#bottomleft').animate({
	    				top: coordinates.top + 100,
	    				left: coordinates.left
	    			}, 'slow');
	    		
	    		}).
	    		pipe(function() {
	    		
	    			return $('#bottomright').animate({
	    				top: coordinates.top +100,
	    				left: coordinates.left + 100
	    			}, 'slow');
	    		
	    		}).
	    		pipe(function() {
	    		
	    			return center.animate({
	    				top: 0,
	    				left: 0,
	    				width: '100%',
	    				height: '100%',
	    				margin: 0
	    			}, 'slow');
	    		
	    		});
	    	
	    	
	    	}).resolve();
	    
	    }, 2000);
	
	};
	

}();

$(function() {

	Animation.run();

});

Come si può notare, le cinque animazioni vengono eseguite in sequenza senza bisogno di utilizzare la funzione di callback del metodo animate(). Potete visionare l'esempio finale in questa pagina.