- div.views-field-field-bijou-foto-fid, che ha la thumbnail con il link al nodo
- div.views-field-markup, che contiene lo <span> con le informazioni sul titolo del bijou e il path della sua immagine grande, che abbiamo creato prima.
Il markup del customfield ha poco senso, mi rendo conto. Purtroppo di base Views non consente una customizzazione dell’output dei vari campi, il cui contenuto è sempre inserito in uno span.field-content, anche quando questo potrebbe creare problemi di validazione (ad esempio se uno volesse inserirvi uno heading o altri elementi block level…). La soluzione più veloce è usare il modulo Semantic Views, che ci consente di scegliere e customizzare i tag che costituiscono i campi visualizzati. Ma qui non è proprio necessario.
Per avere una film strip orizzontale (e non un elenco-lista verticale) ci serve del CSS per gli
<li>, nel template della pagina (
page-taxonomy-term.tpl.php):
.views-row{
display: inline-table;
width: 100px;
}
La proprietà
inline-table ci consente di avere ogni thumbnail accanto all’altra in fila, mentre la larghezza ci dà maggiore spaziatura orizzontale.
4.2 Visualizzazione dell’immagine ingrandita con jQuery
Il piano è questo:
- inserire un <div> tra il titolo della pagina <h3> e la lista <ul>, dove visualizzare l’immagine grande con il suo titolo, collegati al bijou rappresentato
- caricare subito l’ingrandimento della prima thumbnail
- collegare il click su ogni thumbnail con l’aggiornamento dell’immagine, sostituendo quella corrente con quella relativa alla thumbnail cliccata.
Finalmente si passa a jQuery, e si procede in questo modo: prima di tutto si devono salvare i dati che ci servono, che sono:
- il link al nodo di destinazione
- il path dell’immagine grande da caricare
- il titolo del nodo da visualizzare insieme all’immagine grande.
Si parte con il primo elemento della lista, perché vogliamo che il suo ingrandimento sia visualizzato al caricamento della pagina. Basta accedere al suo attributo href:
var item = $('.views-row-first a:first').attr('href');
Gli altri due parametri li avevamo inseriti nel
title dello
<span> creato con il customfield, ma siccome è una sola stringa con due attributi, prima di poterli utilizzare vanno separati. Ecco come si fa:
var rel = $('.views-row-first').find('.img-link').attr('title');
var split = rel.split("|");
var title = split[0];
var imglink = split[1];
Il metodo Javascript
split, data una stringa, restituisce un array con i risultati della suddivisione. Il carattere “|” ci è servito come indicatore del punto di suddivisione.
A questo punto basta inserire il contenitore dove caricare l’immagine, che chiamiamo “zoom”:
$('h3').after('<div id="zoom"><a href="' + item + '"><img class="zoom" src="/' + imglink + '" alt="" /></a><a class="desc" href="' + item + '">' + title + '</a></div>');
Il
div#zoom lo formattiamo con questo CSS:
#zoom{
width: 400px; /* la larghezza esatta dell’immagine grande data da Imagecache */
height: 270px;
margin: 5px auto;
position: relative;
}
Al suo interno abbiamo aggiunto due tag
<a>: il primo contiene l’immagine, il secondo (
.desc) il suo titolo, che formatteremo con un’etichetta, così:
.desc{
background: url(<?php print $base_path.$directory; ?>/images/fold.png) top left no-repeat; color: #d00000;
font: 1em Monika, 'Monika italic', "trebuchet ms", sans-serif;
text-align: center;
text-decoration: none;
position: absolute;
bottom: 50px; right: -3em;
padding: 1em;
}
Il php nella proprietà background serve per stampare il percorso fino alla cartella del tema, dove c’è l’immagine di sfondo con la “piega” dell’etichetta.
La font “Monika” è un carattere calligrafico molto in sintonia con l’argomento: “Monika italic” è la font che ho creato con
Font Squirrel per importarla con il metodo
@font-face, mentre il primo “Monika” è il nome standard della font (così se qualcuno ce l’ha già installata sul proprio computer, utilizziamo quella, che di solito viene renderizzata meglio).
Il posizionamento assoluto è relativamente al contenitore
div#zoom, che abbiamo dichiarato appositamente come
position: relative.
Adesso la pagina visualizza appena caricata l’ingrandimento della prima thumbnail, con un’etichetta col titolo. Ambedue linkano al nodo visualizzato.
Per estendere la funzione d’ingrandimento anche alle altre thumbnail, basta replicare il codice al click di ogni thumb, con qualche piccola modifica:
$('.views-row a').click(function(){
var itemlink = $(this).attr('href');
var rel = $(this).parents('.views-row').find('.img-link').attr('title');
var split = rel.split("|");
var imglink = split[1];
var title = split[0];
$('.zoom').fadeOut(250);
$('#zoom').html('<a href="' + itemlink + '"><img class="zoom" src="/' + imglink + '" alt="" /></a><a class="desc" href="' + itemlink + '">' + title + '</a>');
$('.zoom').hide().fadeIn(500);
return false;
});
Come transizione tra due fotografie, abbiamo inserito un fade out/fade in (in pratica: si nasconde l’immagine facendola dissolvere nel nulla; mentre è nascosta cambiamo l’immagine visualizzata e poi la facciamo ricomparire bella nuova); per il resto lo script è identico nel suo funzionamento.
Return false; serve per impedire al browser di seguire il link alla pagina del nodo: le thumbnail servono solo per ingrandire l’immagine.
Ora la pagina ha tutto ciò che le serve per il funzionamento di base.
4.3 Effetti per la film strip
Aggiungiamo adesso qualche semplice effetto di hover e selezione per le thumbnail. Ecco cosa implementerò:
- Le thumbnail, da un’opacità dell’80%, diventeranno completamente opache al passaggio del mouse
- Contemporaneamente, si creerà sfumando un bordo rosso
- La thumbnail dell’immagine correntemente visualizzata avrà queste due caratteristiche fisse su di sé.
Innanzitutto, un po’ di CSS per l’aspetto di default delle thumbs:
.views-row a img{
opacity: .8;
-moz-opacity: .8;
filter: alpha(opacity=80);
padding: 1px;
}
.views-row a{
outline: none;
}
Qualche dichiarazione cross-browser per l’opacità e un padding per creare il “bordo”, che per far prima sarà solo un cambio di
background-color. Ho tolto l’outline dai link delle thumb perché è antiestetico quando un link non fa lasciare la pagina.
Passiamo al comportamento delle thumb quando il puntatore ci passa sopra. Ecco il codice jQuery, basta anteporlo a quello che abbiamo scritto prima per la visualizzazione dell’immagine ingrandita:
$('.views-row a').hover(
function(){
$(this).children('img').animate({
opacity: 1,
backgroundColor: "#d00000"
}, 300);
},
function(){
$(this).children('img').animate({
opacity: .8,
backgroundColor: "#000"
}, 300);
}
);
L’unica cosa da notare qui è che per far funzionare l’animazione del
background-color (che grazie al padding di cui sopra ci dà l’illusione di creare un bordo attorno all’immagine) è necessario inserire il plugin
jquery.color, ad esempio inserendo nel file .info del tema Drupal la seguente dichiarazione (in questo modo però verrà caricato in ogni pagina – cosa che nel mio progetto è sicuramente desiderabile):
scripts[] = scripts/jquery.color.min.js
(ovviamente dopo aver messo il file dichiarato nella sottocartella indicata della directory del tema, che nel mio caso è “scripts”).
La versione del plugin che ho indicato è ottimale perché funziona anche con Safari (altre non vanno).
Adesso, per cambiare le proprietà della thumbnail relativa all’immagine corrente, creiamo una classe CSS che appiopperemo di volta in volta alla thumb cliccata:
.current img{
opacity: 1 !important;
-moz-opacity: 1 !important;
filter: alpha(opacity=100) !important;
background-color: #d00000 !important;
}
Le dichiarazioni
!important ci servono per passar sopra ai settaggi imposti da altre operazioni dello script jQuery.
Per attaccarla/staccarla dalle thumb man mano che vengono cliccate usiamo i metodi jQuery addClass/removeClass. Per prima cosa si attribuisce alla prima thumbnail, quella dell’immagine che è visualizzata di default:
$('.views-row-first a').addClass('current');
var item = $('.views-row-first a').attr('href');
/* [...] */
e poi nell’evento click di ciascun thumb:
.click(function(){
$('.views-row').find('.current').removeClass('current');
$(this).addClass('current');
var itemlink = $(this).attr('href');
/* [...] */
Con questo abbiamo finito!
5 Script completo
Ecco quindi lo script completo che abbiamo costruito passo passo:
$(document).ready(function(){
$('.views-row-first a').addClass('current');
var item = $('.views-row-first a').attr('href');
var rel = $('.views-row:first').find('.img-link').attr('title');
var split = rel.split("|");
var imglink = split[1];
var title = split[0];
$('h3').after('<div id="zoom"><a href="' + item + '"><img class="zoom" src="/' + imglink + '" alt="" /></a><a class="desc" href="' + item + '">' + title + '</a></div>');
$('.views-row a').hover(
function(){
$(this).children('img').animate({
opacity: 1,
backgroundColor: "#d00000"
}, 300);
},
function(){
$(this).children('img').animate({
opacity: .8,
backgroundColor: "#000"
}, 300);
}
).click(function(){
$('.views-row').find('.current').removeClass('current');
$(this).addClass('current');
var itemlink = $(this).attr('href');
var rel = $(this).parents('.views-row').find('.img-link').attr('title');
var split = rel.split("|");
var imglink = split[1];
var title = split[0];
$('.zoom').fadeOut(250);
$('#zoom').html('<a href="' + itemlink + '"><img class="zoom" src="/' + imglink + '" alt="" /></a><a class="desc" href="' + itemlink + '">' + title + '</a>');
$('.zoom').hide().fadeIn(500);
return false;
});
});
Ed ecco anche il CSS:
.views-row{
display: inline-table;
width: 100px;
}
.views-row a{
outline: none;
}
.views-row a img{
opacity: .8;
-moz-opacity: .8;
filter: alpha(opacity=80);
padding: 1px;
}
#zoom{
width: 400px;
height: 270px;
margin: 5px auto;
position: relative;
}
.desc{
background: url(<?php print $base_path.$directory; ?>/images/fold.png) top left no-repeat; color: #d00000;
font: 1em Monika, 'Monika italic', "trebuchet ms", sans-serif;
text-align: center;
text-decoration: none;
position: absolute;
bottom: 50px; right: -3em;
padding: 1em;
}
.current img{
opacity: 1 !important;
-moz-opacity: 1 !important;
filter: alpha(opacity=100) !important;
background-color: #d00000 !important;
}