Ecco uno slideshow realizzato da me in jQuery che potete vedere in azione seguendo il link:
DEMO - Slideshow
ANALISI
Le immagini sono disposte una sopra l’altra grazie ad un diverso valore di “profondità” (z-index) e sono composte da colonne (invisibili se non durante l’animazione) divise in punti variabili e casuali. L’animazione ha il compito di allontanare le due parti “spezzate“ delle colonne in modo da mostrare l’immagine sottostante.
Lo script è quindi riassumibile in due punti:
- Organizzazione della struttura
- Animazione
I codici HTML e CSS non contengono definizioni importanti se non la struttura di base in cui alloggerà lo slideshow:
HTML
<div id="container">
<img id="img0" src="funnies/simpson.jpg" />
<img id="img1" src="funnies/futurama.jpg" />
<img id="img2" src="funnies/Mr. Bean.jpg" />
</div>
<div id="main_box"></div><a id="change" href="#">CHANGE</a>
CSS
.cols_rand,.cols_diff{
position: absolute;}
img{
display: none;}
#main_box
{
position: relative;margin:0 auto; /* per centrare */}
.imgbox
{
overflow: hidden;}
Veniamo al jQuery, parte essenziale per il funzionamento dello script.
jQUERY
$(window).load(function (){
$('#change').bind('click', anima_slideshow);// variabili per la griglia
var numero_immagini = $('img').length;var width = $('img#img0').width();var height = $('img#img0').height();var zindex = 0;var colonne = 6;var larghezza_colonna;
var numero_random;
var numero_diff;
var box='';var x,y;
var top,left;
var img,tmp,arraytmp = [];// variabili d'animazione
var img_corrente = numero_immagini -1;// modifico i valori del main_box per poterlo centrare
$('#main_box').width(width);$('#main_box').height(height);for (x = 0; x < numero_immagini; x++){
// calcolo valori randoms
randoms = [];randoms = array_random(randoms,height,6); // creo array casualeimg = $('#img'+x).attr('src');/* CREO GRIGLIA */
// apro il box che conterra tutte le colonne
box += '<div class="imgbox b'+x+'" style="position:absolute; z-index:'+x+';width:'+width+'px;height:'+height+'px;">';// ciclo le colonne
for (y = 0; y<colonne; y++){
// calcolo random
numero_random = randoms[y];// calcolo differenza
numero_diff = height - numero_random;larghezza_colonna = Math.floor(width/colonne);top = numero_random; // il top della cols_diff corrisponde all'altezza della cols_random
left = y*larghezza_colonna;// stampo applicandoci su l'immagine..
box += '<div class="cols_rand n'+y+'" style="width:'+larghezza_colonna+'px;'+'height:'+numero_random+'px;'+'left:'+(left)+'px; top:0px; '+'background-image:url(\''+img+'\'); '+'background-position:'+(width - y*larghezza_colonna)+'px 0px;" ></div>'+'<div class="cols_diff n'+y+'" style="width:'+larghezza_colonna+'px;'+'height:'+numero_diff+'px;'+'top:'+top+'px; '+'left:'+(left)+'; '+'background-image:url(\''+img+'\'); '+'background-position:'+(width - y*larghezza_colonna)+'px '+(-top)+'px; "></div>';}
//chiudo il box
box += '</div>';
}
//output
$('#main_box').html(box);function anima_slideshow(){
event.preventDefault();$('#change').unbind();// salgono le cols_random
$('.imgbox.b'+img_corrente).children('.cols_rand').each(function(){
height_tmp = $(this).height();$(this).animate({'marginTop': -height_tmp+'px'},2000,'easeOutCubic');});// salgono le cols_diff
$('.imgbox.b'+img_corrente).children('.cols_diff').each(function(){
height_tmp = $(this).height();$(this).animate({'marginTop': +height_tmp+'px'},2000,'easeOutCubic');});// cambio l'opacità
$('.imgbox.b'+img_corrente).animate({'opacity':'0.6'},2000,function(){
// cambio gli z-index
$('.imgbox').each(function(){
// ottengo l'id
id = $(this).attr('class').substring(8,$(this).attr('class').length);// se non è uguale all'id dell'img_corrente incremento lo z-index
if (id != img_corrente){
zindex_tmp = parseInt($(this).css("zIndex"));$(this).css('zIndex',++zindex_tmp);if (zindex_tmp == (x-1)){
tmp = id;}
}
else
{
$(this).css('zIndex',0);}
$('.imgbox.b'+img_corrente).css('opacity','1');});// scendono le cols_random
$('.imgbox.b'+img_corrente).children('.cols_rand').each(function(){
height_tmp = $(this).height();$(this).css('marginTop','0px');});// scendono le cols_diff
$('.imgbox.b'+img_corrente).children('.cols_diff').each(function(){
height_tmp = $(this).height();$(this).css('marginTop','0px');});// aggiorno immagine corrente
img_corrente = tmp;$('#change').bind('click', anima_slideshow);});}
});// funzione che genera i numeri casuali
function array_random(array,max,size){
while (array.length < size){
cas = Math.round(Math.random()*max);if ($.inArray(cas,array) == -1 & cas != 0){
array.push(cas);}
}
return array;
}
NEL DETTAGLIO..
Mi soffermo sull’organizzazione delle immagini in quanto lo script ha il compito di provvedere ad una vera e propria costruzione delle immagini: l’algoritmo crea una griglia composta da colonne superiori, di altezza casuale, e da colonne inferiori che assumeranno l’altezza restante. Su ogni semi-colonna sarà applicata l’immagine di sfondo, posizionata secondo le coordinate calcolate.
L’animazione, come già anticipato, allontana le due parti delle colonne e poi modifica i valori di z-index in modo tale da permettere alle colonne di scendere, solo successivamente, dietro le altre immagini. Questa si occupa anche di gestire una lieve variazione di opacità e dell’aggiunta di un effetto di easing. Vi faccio notare l'uso delle funzioni bind() e unbind() che servono per "disattivare" il pulsante change durante la transizione in modo tale da evitare che click multipli blocchino lo slideshow.
DEMO - Slideshow