Galería Con Tamaños de Imágenes Personalizados (Plugin jQuery Extra)
Spanish (Español) translation by Eva Collados Pascual (you can also view the original English article)
Como prometí en mi artículo previo, aquí tienes el tutorial sobre la creación de una galería que no usa los tamaños de imagen estándar. Como extra aprenderás a crear un plugin básico jQuery para presentar las imágenes de mayor tamaño de las miniaturas de una forma más atractiva.
Si no leíste mi artículo anterior sobre los tamaños de imágenes personalizados, por favor léelo de forma que te resulte más fácil comprender este tutorial.
Paso 1 Decidir los Tamaños de Imagen
Dependiendo de la maquetación de tu tema, y el sistema de retícula que use, podrás decidir entre diferentes tamaños de imagen para las miniaturas. Antes de decidir sobre cuantas imágenes quieres disponer en una fila, cual es la anchura del contenedor en el que las miniaturas serán mostradas, los márgenes, el padding, etc.
Yo voy a usar una anchura de 940 píxeles, una maquetación de dos columnas (un ratio de 8/4) como ejemplo, en donde el contenido tendrá 620 píxeles y la columna lateral 300 píxeles con un margen izquierdo de 20 píxeles. El área para el contenido y la columna lateral tendrán un padding interior de 20 píxeles. Ahora un poco de matemáticas: el contenido tiene 620px de anchura con un padding de 20px, esto nos deja 580px para las miniaturas; y mostrando 5 miniaturas por línea, teniendo cada una un margen derecho de 10px de forma que no estén pegadas una junto a otra; la quinta imagen de cada línea no tendrá un margen derecho; las miniaturas tendrán 108px de anchura y altura, y estarán recortadas.
La imagen más grande será como máximo 660px de ancho y 660px de alto, serán redimensionadas proporcionalmente sin recortar.
Puedes elegir que medida se ajusta a tu maquetación, si decides cambiar los tamaños, pueden ser fácilmente regenerados (ver la entrada anterior para saber cómo hacerlo), además no tienen porque ser cuadradas.


Paso 2 Configurar los Tamaños Personalizados
Edita el archivo functions.php de forma que se parezca a algo como esto:
1 |
|
2 |
add_action( 'after_setup_theme', 'setup' ); |
3 |
function setup() { |
4 |
// ...
|
5 |
|
6 |
add_theme_support( 'post-thumbnails' ); |
7 |
add_image_size( 'preview', 108, 108, true ); // thumbnail |
8 |
add_image_size( 'zoomed', 660, 600 ); // large |
9 |
|
10 |
// ...
|
11 |
}
|
Paso 3 Generar una Lista de Miniaturas, Excluyendo el Grupo de Imágenes tal y Como Aparece
Todavía en functions.php añade el métodogenerate_thumbnail_list:
1 |
|
2 |
function generate_thumbnail_list( $post_id = null ) { |
3 |
if ( $post_id == null ) return; |
4 |
$images = get_posts( |
5 |
array( |
6 |
'numberposts' => -1, |
7 |
'post_type' => 'attachment', |
8 |
'post_mime_type' => 'image/jpeg, image/jpg, image/png, image/gif', |
9 |
'post_parent' => $post_id, |
10 |
'orderby' => 'menu_order', |
11 |
'order' => 'ASC', |
12 |
'exclude' => get_post_thumbnail_id( $post_id ) |
13 |
)
|
14 |
);
|
15 |
if ( count( $images ) > 0 ) { |
16 |
echo '<ul class="gallery">'; |
17 |
foreach ( $images as $image ) { |
18 |
$src = wp_get_attachment_image_src($image->ID, 'zoomed'); |
19 |
echo '<li><a href="' . $src[0] .'">' . wp_get_attachment_image( $image->ID, 'preview' ) . '</a></li>'; |
20 |
}
|
21 |
echo '</ul>'; |
22 |
echo '<div class="clear"></div>'; |
23 |
}
|
24 |
}
|
En el archivo content-single.php invoca el método generate_thumbnail_list, pasando como parámetro el ID de la entrada.
1 |
|
2 |
<?php the_content(); ?> |
3 |
<h3>Images</h3> |
4 |
<?php generate_thumbnail_list( get_the_ID() ); ?> |
Lo anterior mostrará una lista sin orden, conteniendo enlaces a los archivos más grandes y a las miniaturas de las imágenes.
Paso 4 Aplicar Estilo a la Galería
Obviamente las miniaturas necesitan estilo, de ora forma sería sólo una simple lista de imágenes. Añade lo siguiente a tu actual hoja de estilo o crea una nueva y vincúlala:
1 |
|
2 |
.clear { |
3 |
clear: both; |
4 |
}
|
5 |
.gallery { |
6 |
list-style-type: none; |
7 |
padding: 0; |
8 |
margin: 0; |
9 |
}
|
10 |
.gallery li { |
11 |
float: left; |
12 |
margin: 0 10px 10px 0; |
13 |
}
|
14 |
.gallery li:nth-child(5n) { |
15 |
margin-right: 0; |
16 |
}
|
17 |
.gallery a { |
18 |
float: left; |
19 |
cursor: pointer; |
20 |
text-decoration: none; |
21 |
}
|
22 |
.gallery img { |
23 |
float: left; |
24 |
border: 0; |
25 |
}
|
Esto colocará las imágenes una junto a la otra, dejando algo de espacio alrededor.
En este punto, al pulsar sobre la miniatura se abrirá la imagen más grande en una página vacía. Ésta es una buena alternativa en caso de que JavaScript esté deshabilitado.
Paso 5 Abrir las Imágenes Con una Galería de Imagen jQuery
Aplicar Estilo a una Imagen de Galería Aumentada
Antes de escribir cualquier JavaScript sería deseable saber como se mostrará la imagen mayor. Aquí está lo que yo tenía pensado:


Nota: todo esto será generado por el plugin jQuery. Esto es sólo para mostrarte el proceso de creación.
Una capa transparente sobre todo el contenido, con la imagen en el centro y los controles en la esquina superior derecha. Mientras la imagen se carga se mostrará una rueda girando. En la raíz del cuerpo del documento se añadirá un div contenedor, el cual contedrá los enlaces para la navegación hacia la siguiente imagen y la anterior, un enlace para cerrar la galería, y el div contenedor alrededor de la imagen donde esta será cargada. Éste es código HTML mínimo que se usará para la galería.
1 |
|
2 |
<div id="zoom"> |
3 |
<a href="#next" class="next">Next</a> |
4 |
<a href="#previous" class="previous">Previous</a> |
5 |
<div class="close"></div> |
6 |
<div class="content"></div> |
7 |
</div>
|
Añadiendo el siguiente código se aplicará estilo a los elementos anteriores para que se vean como en la imagen de arriba (los comentarios están incluidos para explicar las partes que podrían no ser inmediatamente obvias):
1 |
|
2 |
#zoom { |
3 |
z-index: 99990; /* high index so it stays on top of all other elements */ |
4 |
position: fixed; /* is fixed so if content is scrolled this stays in the same place */ |
5 |
top: 0; |
6 |
left: 0; |
7 |
width: 100%; |
8 |
height: 100%; |
9 |
/* creates a transparent background, so the content under it will be visible,
|
10 |
transparency can be adjusted */
|
11 |
background: rgba(0, 0, 0, 0.8); |
12 |
}
|
13 |
#zoom .content { |
14 |
z-index: 99991; /* higher index so the image will stay on top of the overlay */ |
15 |
position: absolute; |
16 |
/* start initial positioning: will be centered horizontally and vertically */
|
17 |
top: 50%; |
18 |
left: 50%; |
19 |
width: 200px; |
20 |
height: 200px; |
21 |
margin: -100px 0 0 -100px; |
22 |
/* end positioning */
|
23 |
/* an animated spinner as background will be visible while the image is loading */
|
24 |
background: #ffffff url('../img/spinner.gif') no-repeat 50% 50%; |
25 |
border: 20px solid #ececec; |
26 |
padding: 0; |
27 |
}
|
28 |
#zoom img { |
29 |
display: block; |
30 |
max-width: none; |
31 |
background: #ececec; |
32 |
-moz-box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3); |
33 |
-webkit-box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3); |
34 |
box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.4); |
35 |
}
|
36 |
#zoom .close { |
37 |
z-index: 99993; /* higher index so the close will stay above the overlay and image */ |
38 |
position: absolute; |
39 |
top: 0; |
40 |
right: 0; |
41 |
width: 49px; |
42 |
height: 49px; |
43 |
cursor: pointer; |
44 |
background: transparent url('../img/icons/close.png') no-repeat 50% 50%; |
45 |
opacity: 1; |
46 |
filter: alpha(opacity=100); |
47 |
}
|
48 |
#zoom .previous, |
49 |
#zoom .next { |
50 |
z-index: 99992; /* higher index so the close will stay above the overlay and image */ |
51 |
position: absolute; |
52 |
top: 0; |
53 |
overflow: hidden; |
54 |
display: block; |
55 |
width: 49px; |
56 |
height: 49px; |
57 |
text-indent: 100%; |
58 |
}
|
59 |
#zoom .previous { |
60 |
right: 100px; |
61 |
background: url('../img/icons/arrows.png') no-repeat 0 0; |
62 |
}
|
63 |
#zoom .next { |
64 |
right: 50px; |
65 |
background: url('../img/icons/arrows.png') no-repeat 100% 0; |
66 |
}
|
67 |
#zoom .close:hover { |
68 |
background-color: #da4f49; /* adds a red tint on hover */ |
69 |
}
|
70 |
#zoom .previous:hover, |
71 |
#zoom .next:hover { |
72 |
background-color: #0088cc; /* adds a blue tint on hover */ |
73 |
}
|
La muestra de lo anterior:


Ahora Algo de JavaScript
El código HTML de arriba no será necesario, ya que se generará con JavaScript. Los eventos se incorporarán para abrir, navegar y cerrar la galería. Navegar y cerrar la galería puede hacerse desde el teclado o usando el ratón.
El JavaScript de abajo también está comentado para explicar lo que está sucediendo:
1 |
|
2 |
(function($) { |
3 |
$.zoom = function() { |
4 |
// append a gallery wrapper to the document body
|
5 |
$('body').append('<div id="zoom"></div>'); |
6 |
var zoomedIn = false, // a flag to know if the gallery is open or not |
7 |
zoom = $('#zoom'), |
8 |
zoomContent = null, |
9 |
opened = null; // the opened image element |
10 |
|
11 |
function setup() { |
12 |
zoom.hide(); // hide it |
13 |
// add the inner elements, image wrapper, close and navigation links
|
14 |
zoom.prepend('<div class="content"></div>'); |
15 |
zoom.prepend('<div class="close"></div>'); |
16 |
zoom.prepend('<a href="#previous" class="previous">Previous</a>'); |
17 |
zoom.prepend('<a href="#next" class="next">Next</a>'); |
18 |
|
19 |
zoomContent = $('#zoom .content'); |
20 |
// attach events to the added elements
|
21 |
$('#zoom .close').on('click', close); |
22 |
$('#zoom .previous').on('click', openPrevious); |
23 |
$('#zoom .next').on('click', openNext); |
24 |
|
25 |
// observe keyboard events for navigation and closing the gallery
|
26 |
$(document).keydown(function(event) { |
27 |
if (!opened) { |
28 |
return; |
29 |
}
|
30 |
if (event.which == 27) { |
31 |
$('#zoom .close').click(); |
32 |
return; |
33 |
}
|
34 |
if (event.which == 37) { |
35 |
$('#zoom .previous').click(); |
36 |
return; |
37 |
}
|
38 |
if (event.which == 39) { |
39 |
$('#zoom .next').click(); |
40 |
return; |
41 |
}
|
42 |
return; |
43 |
});
|
44 |
|
45 |
if ($('.gallery li a').length == 1) { |
46 |
// add 'zoom' class for single image so the navigation links will hide
|
47 |
$('.gallery li a')[0].addClass('zoom'); |
48 |
}
|
49 |
// attach click event observer to open the image
|
50 |
$('.zoom, .gallery li a').on('click', open); |
51 |
}
|
52 |
|
53 |
function open(event) { |
54 |
event.preventDefault(); // prevent opening a blank page with the image |
55 |
var link = $(this), |
56 |
src = link.attr('href'), |
57 |
// create an image object with the source from the link
|
58 |
image = $(new Image()).attr('src', src).hide(); |
59 |
if (!src) { |
60 |
return; |
61 |
}
|
62 |
$('#zoom .previous, #zoom .next').show(); |
63 |
if (link.hasClass('zoom')) { |
64 |
$('#zoom .previous, #zoom .next').hide(); |
65 |
}
|
66 |
|
67 |
// show the gallery with loading spinner, navigation and close buttons
|
68 |
if (!zoomedIn) { |
69 |
zoomedIn = true; |
70 |
zoom.show(); |
71 |
}
|
72 |
|
73 |
// clean up and add image object for loading
|
74 |
zoomContent.empty().prepend(image); |
75 |
// event observer for image loading, render() will be
|
76 |
// called while image is loading
|
77 |
image.load(render); |
78 |
opened = link; |
79 |
}
|
80 |
|
81 |
function openPrevious(event) { |
82 |
event.preventDefault(); |
83 |
if (opened.hasClass('zoom')) { |
84 |
return; |
85 |
}
|
86 |
var prev = opened.parent('li').prev(); |
87 |
if (prev.length == 0) { |
88 |
prev = $('.gallery li:last-child'); |
89 |
}
|
90 |
prev.children('a').trigger('click'); |
91 |
}
|
92 |
|
93 |
function openNext(event) { |
94 |
event.preventDefault(); |
95 |
if (opened.hasClass('zoom')) { |
96 |
return; |
97 |
}
|
98 |
var next = opened.parent('li').next(); |
99 |
if (next.length == 0) { |
100 |
next = $('.gallery li:first-child'); |
101 |
}
|
102 |
next.children('a').trigger('click'); |
103 |
}
|
104 |
|
105 |
function render() { |
106 |
// if the image is not fully loaded do nothing
|
107 |
if (!this.complete) { |
108 |
return; |
109 |
}
|
110 |
var image = $(this); |
111 |
// if image has the same dimensions as the gallery
|
112 |
// just show the image don't animate
|
113 |
if (image.width() == zoomContent.width() && |
114 |
image.height() == zoomContent.height()) { |
115 |
show(image); |
116 |
return; |
117 |
}
|
118 |
var borderWidth = parseInt(zoomContent.css('borderLeftWidth')); |
119 |
// resize the gallery to the image dimensions before
|
120 |
// displaying the image
|
121 |
zoomContent.animate({ |
122 |
width: image.width(), |
123 |
height: image.height(), |
124 |
marginTop: -(image.height() / 2) - borderWidth, |
125 |
marginLeft: -(image.width() / 2) - borderWidth |
126 |
}, 300, function(){ |
127 |
show(image); |
128 |
});
|
129 |
|
130 |
function show(image) { |
131 |
image.fadeIn('fast'); |
132 |
}
|
133 |
}
|
134 |
|
135 |
function close(event) { |
136 |
event.preventDefault(); |
137 |
zoomedIn = false; |
138 |
zoom.hide(); |
139 |
zoomContent.empty(); |
140 |
}
|
141 |
|
142 |
setup(); |
143 |
};
|
144 |
})(jQuery); |
Tras incluir el plugin de arriba, inicialízalo añadiendo la llamada al plugin en el método generate_thumbnail_list:
1 |
|
2 |
function generate_thumbnail_list( $post_id = null ) { |
3 |
// ...
|
4 |
if ( count( $images ) > 0 ) { |
5 |
// ...
|
6 |
echo '<script type="text/javascript">jQuery.zoom();</script>'; |
7 |
}
|
8 |
}
|
Ejemplo
Un ejemplo de la vida real sobre como funciona esto y como se puede usar: Zoom jQuery Photo Gallery Plugin demo



