jQuery+Flickr: Realizziamo un semplice slideshow

Nel precendente articolo abbiamo visto come utilizzare jQuery per recuperare le immagini da un account di Flickr, in questo articolo andremo oltre, realizzando un semplice slideshow: a questa pagina puoi vedere una demo di quello che andremo a creare e qui invece puoi trovare i sorgenti.

Parte I: il markup

Il markup è la parte più semplice:

<div id="wrapper">
	<div id="galleryContainer">
		<div id="gallery">
			<!--
				Qui andranno le immagini
				recuperate dinamicamente
			-->
		</div> <!-- end gallery -->

	</div> <!-- end galleryContainer -->

	<a href="#" id="prevButton">Previous</a>
	<a href="#" id="nextButton">Next</a>

</div> <!-- end wrapper -->

Non abbiamo fatto altro che creare tre sezioni: wrapper è il contenitore principale (nel quale andremo in seguito a posizionare i link next e prev), galleryContainer è una sorta di Viewport ovvero una “finestra” che ci permetterà di vedere una sola immagine per volta; la sezione gallery infine, conterrà tutte le immagini recuperate dinamicamente dal nostro account Flickr. Prima di chiudere la sezione container, andiamo ad inserire i link per per andare avanti e indietro nello slideshow (li posizioneremo in seguito con i css).
Salviamo il nostro file come index.html.

Parte II: diamo un po’ di stile

Creiamo un nuovo file che chiameremo style.css (e ricordiamoci di inserire il riferimento ad esso nella nostra index). Iniziamo a dare un po’ di stile alle varie sezioni e alle immagini:

#container{
	width: 510px;
	height:371px;
	margin: 0 auto;
	position:relative;
	background: url('../images/ombra.png') 0 343px no-repeat;	}

#galleryContainer{
	width:500px;
	height:332px;
	margin:0 auto;
	padding: 5px;
	overflow:hidden;
	position: relative;
	border: 1px solid black;
}

#gallery{
	/* l'attributo width viene prelevato dinamicamente con jQuery */
	height: 332px;
	position:relative;
}

#gallery img{
	width:500px;
	float:left;
	padding-right:5px;
}

img{display: block;}

Abbiamo semplicemente fissato le dimesioni delle tre sezioni, le abbiamo posizionate relativamente,  abbiamo reso le immagini flottanti con float: left per fare in modo che si dispongano tutte in fila e abbiamo assegnato loro un padding-right di 5px. Inoltre è importante impostare galleryContainer con overflow:hidden per far si che le immagini al di fuori dei suoi margini non siano visualizzate.
Diamo un po’ di stile anche ai link next e prev:

#prevButton{
	position:absolute;
	display:block;
	width:28px;
	height:28px;
	background: url("../images/prevButton.png") top left no-repeat;
	text-indent: -99999px;
	top:47%;
	left:-50px;
}

#nextButton{
	position:absolute;
	display:block;
	width:28px;
	height:28px;
	background: url("../images/nextButton.png") top left no-repeat;
	text-indent: -99999px;
	top:47%;
	right:-50px;
}

Cosa abbiamo fatto?

  • Abbiamo posizionato i link in maniera assoluta (in questo modo andranno a posizionarsi  relativamente alla sezione wrapper) e resi elementi blocco;
  • abbiamo nascosto il testo con la proprietà text-indent e impostato un’immagine di background;
  • infine abbiamo impostato il posizionamento vero e proprio, con top: 39%; right: -72px;

Perché proprio 47%?

Il motivo è semplice, vogliamo allineare i link perfettamente al cenro delle immagini; lo so, ti starai chiedendo “ma non bastava impostare il 50%?”.
La risposta è no, e ti spiego subito il perché. Impostando il 50% dal top, il link viene allineato al centro rispetto al margine superiore, noi invece vogliamo che sia centrato rispetto al centro (scusa il gioco di parole) dell’immagine di sfondo, come fare quindi?
Fortunatamente la matematica ci viene incontro e basta una semplice proporzione:

(altezza del contenitore) : 100 = (altezza del contenitore/2)-(altezza dello sfondo/2) : x

x = (((altezza del contenitore/2)-(altezza dello sfondo/2))*100 ) / (altezza del contenitore)

che tradotta in cifre diventa:

altezza del contenitore = 510
altezza dello sfondo = 28

510: 100 = (255 – 14) : x

x = (241*100)/510 = 47,25(arrotondiamo a 47)

Facile vero? In questo modo i nostri link saranno posizionati esattamente al centro del contenitore.

Parte III : finalmente lo script

Iniziamo a scrivere il nostro file function.js (e ricordiamoci sempre di richiamarlo nel documento principale, il nostro index.html), all’interno di $(document).ready() inseriamo questa funzione:

function getFlickrStream(id, number)
{
	flickrUrl = id ? "https://api.flickr.com/services/feeds/photos_public.gne?id="+id+"&format=json&jsoncallback=?" : "https://api.flickr.com/services/feeds/photos_public.gne?format=json&jsoncallback=?";
	numOfImages = number ? number : 10;

	$.getJSON(flickrUrl, function(data){
		$.each(data.items, function(i, item){
			if(i < numOfImages)
			{
				var thumbItem = item.media.m;
				var realSizeItem = thumbItem.slice(0, -6)+thumbItem.slice(-4);
	    			$('</pre>
<img alt="" />
<pre>').attr('src', realSizeItem).appendTo("#gallery");
			}
			else return false;
		});
		images = $("#gallery img");
		numImages = images.length;
		imageWidth = images.outerWidth(true);
		totalWidth = numImages * imageWidth;
		stopPosition = (imageWidth - totalWidth);
		wrapper = $('#gallery');
		wrapper.width(totalWidth);

		$('#prevButton').click(slidePrev);

		$('#nextButton').click(slideNext);
	});
};

La nostra funzione si occupa, come abbiamo visto nel precendente tutorial, di aprire una chiamata JSON per recuperare le foto dal nostro account di Flickr, e di inserire le stesse all’interno del div gallery.
Dopo aver terminato il ciclo $.each dichiariamo alcune variabili che ci saranno utili:

//identifica tutti gli elementi img all'interno del div gallery
images = $("#gallery img");

//ricava la lunghezza dell'array images (creato precedentemente), quindi indica
//il numero di immagini a nostra disposizione
numImages = images.length;

//contiene la lunghezza della singola immagine
imageWidth = images.outerWidth(true);

//indica la lunghezza di tutte le immagini messe in fila
//così come sono inserite nel div gallery
totalWidth = numImages * imageWidth;

//è la posizione di stop per la proprietà left:
stopPosition = (imageWidth - totalWidth);

//è semplicemente una scorciatoia per non
//riscrivere ogni volta $('#gallery)
wrapper = $('#gallery');

Impostiamo dinamicamente la dimensione del div#gallery:

wrapper.width(totalWidth);

Infine aggiungiamo gli eventi al click dei due link:

$('#prevButton').click(slidePrev);

$('#nextButton').click(slideNext);

Fatto questo, la nostra funzione è completa, ora non ci resta che implementare le funzioni da eseguire al click sui due link di navigazione.

Clicca avanti, clicca indietro

Quello che segue è il codice che trasforma la nostra pagina con una sola foto, in un vero e proprio slideshow:

function slideNext()
{
	if(wrapper.position().left > stopPosition-5)
	{
		wrapper.animate({left: '-='+imageWidth+'px'});
	}
	else
	{
		wrapper.animate({left: 0});
		return false;
	};

};

In questa funzione – che viene eseguita al click sul link nextButton – controlliamo prima che l’attributo left del nostro div gallery non sia superiore al massimo consentito, la variabile stopPosition-5 (in tal caso riporta left a 0 con un effetto slide), quindi sottrae all’attributo left un valore pari alla variabile imageWidth, con un piacevole effetto slide (dovuto dal metodo .animate di jquery).

N.B.: Se ti stai chiedendo perché quel “-5” nella condizione della funzione slideNext, serve per compensare il padding: 5px che abbiamo assegnato alla sezione galleryContainer, che sposta a destra la sezione gallery di 5 pixel. Senza di esso avresti una immagine bianca in più nello slider.

La funzione per il link prevButton è molto simile:

function slidePrev()
{
	if(wrapper.position().left < 0){
		wrapper.animate({left: '+='+imageWidth+'px'});
	}
	else
	{
		wrapper.animate({left: stopPosition});
		return false;
	};
};

L’unica differenza è nel costrutto if all’inizio: questa volta controlliamo che l’attributo left sia minore di 0, in tal caso animiamo il div gallery verso sinistra, altrimenti animiamo il div per fare in modo di visualizzare l’ultima immagine della nostra gallery.

A questo punto l’ultima riga di codice da scrivere è questa:

getFlickrStream(id, num);

che non fa altro che chiamare la funzione dichiarata in precedenza. Ricorda di sostituire l’attributo id con il tuo id di Flickr (nel precedente tutorial ti ho spiegato come fare) e l’attributo num con il numero di immagini che vuoi inserire nel tuo slideshow.

Piccola chicca:

E se volessimo animare il nostro slideshow in maniera automatica, oltre che con i link?
Semplice, basterà inserire questa riga di codice subito prima della chiusura della funzione getFlickrStream:

setInterval(slideNext, 3000);

in questo modo la funzione slideNext() verrà eseguita ogni tre secondi (ma puoi cambiare il valore del secondo argomento di setInterval come preferisci).

Conclusioni

Abbiamo visto, sfruttando le nozioni apprese nel precedente tutorial, come sviluppare un semplice slideshow in jQuery, recuperando le immagini da un account di Flickr (se non è il tuo ricorda prima di chiedere il permesso) e abbiamo visto che in fondo non è poi così difficile.

E tu, in cosa miglioreresti lo slideshow che ti ho proposto?

Tag: , ,

L'autore

Appassionato di web design da qualche anno, ha deciso di prendere la strada del "uebdeveloper" perché ritiene di essere negato con la grafica (anche se ogni tanto ci prova lo stesso), spera di diventare presto un bravo sviluppatore.

Sito web dell'autore | Altri articoli scritti da

Articoli correlati

Potresti essere interessato anche ai seguenti articoli:

25 commenti

Trackback e pingback

  1. Raccolta di articoli della settimana 6/11/2011 | Saverio Gravagnola
    [...] jQuery+Flickr: Realizziamo un semplice slideshow (Your Inspiration Web) [...]
  2. FlickrPhotogallery : un plugin wordpress che sfrutta le API di Flickr | Your Inspiration Web
    [...] settimana fa ho mostrato come recuperare le foto da Flickr e come realizzare un semplice slideshow utilizzando il flusso…