Convertir una lista de imágenes en una galería con miniaturas (jQuery) | Oloblogger Todo el mundo tiene un pasado y hubo en tiempo en que en lugar de estar un pelín por encima de la media, estaba en lo más hondo por debajo d...

18 de mayo de 2016

Convertir una lista de imágenes en una galería con miniaturas (jQuery)

Todo el mundo tiene un pasado y hubo en tiempo en que en lugar de estar un pelín por encima de la media, estaba en lo más hondo por debajo de ella. Por aquel entonces publiqué un más que incómodo y poco configurable código para crear una Sencilla galería de imágenes con miniaturas. Algo después ya diseñé una que era adaptable y sólo con CSS, pero tanto esta como la otra tenían carencias o inconvenientes en mayor o menor medida.

¿Y qué tiene la de hoy de particular? Pues que simplemente creando una lista de imágenes, ya se genera automáticamente una galería con miniaturas que al pincharlas permiten ver la imagen ampliada.

Además podréis incorporar más de una galería de este tipo por página, el conjunto es adaptable (RWD) y no tiene limitaciones en cuanto a número de imágenes o medidas de estas.

No tiene limitaciones pero por razones estéticas quizás lo conveniente es que no sean más de 10 (simplemente para que no se vean demasiado pequeñas las miniaturas) y que tengan aproximadamente la misma proporción ancho/alto evitando mezclar formatos verticales y horizontales. Esto último sería para que no se vieran huecos.


Demo


A continuación la versión con las miniaturas arriba y luego veremos otra con las miniaturas abajo. Podéis probarla.



Añadiendo el código necesario


Lo primero será asegurarse de que tenéis cargada la librería jQuery en vuestra plantilla. Si no es así, insertad la siguiente línea (en Blogger justo después de ]]></b:skin>):

<script src='http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js' type='text/javascript'/>


El estilo y el JavasScript lo podéis añadir tanto en un gadget como en la plantilla. Si va en la plantilla sería entre ]]></b:skin> y </head> y en cualquier caso, siempre detrás de cargar jQuery. Sería el siguiente, uno a continuación de otro, para que se pueda eliminar con facilidad de una vez si en el futuro os aburrís del plugin.

<style>
ul.obgaleria{width: 100%;height:0;overflow:hidden;margin: 30px auto;list-style: none;background:transparent;font-size:0;line-height:0;}
ul.obgaleria li{position: relative;display:inline-block;height:0;margin:0;list-style:none;cursor:pointer;vertical-align:top;overflow:hidden;}
ul.obgaleria li img {position: absolute;top: -150%;bottom: -150%;left: -150%;right: -150%;width: auto;max-width: none;height: 150%;margin: auto;padding:0;border:0;}
ul.obgaleria li:last-child img {top: 0;bottom: 0;left: 0;right: 0;margin: auto;width: 100%;height: auto;}
ul.obgaleria li {border-left: 3px solid transparent;border-bottom: 3px solid transparent;box-sizing: border-box;}
ul.obgaleria li:first-child, ul.obgaleria li:last-child {border-left:0;}
</style>

<script type='text/javascript'>//<![CDATA[
var prop = 60.00; // proporción alto/ancho*100 imagen principal
$(document).ready(function() {
$("ul.obgaleria").each(function() {
var id = "#" + $(this).attr("id");
var ancho = 100 / $(id + " li").length;
$("head").append("<style>" + id + "{padding: 0 0 " + (prop + ancho) + "% 0;} " + id + " li{width:" + ancho + "%;padding: 0 0 " + ancho + "% 0;} " + id + " li:last-child {padding-bottom: " + prop + "%;}</style>");
$(id + " li:first-child").clone().appendTo(id);
$(id + " li:last-child").css({
"width": "100%"
});
$(id + " li").click(function() {
$(id + " li:last-child").remove()
$(this).clone().appendTo(id).animate({
width: "100%"
}, 200);
});
});
});
//]]></script>

La variable var prop = 60.00; sirve para determinar la proporción de las imágenes que vais a utilizar. Sólo se trata de dividir el alto por el ancho y multiplicar por 100. Si por ejemplo son el doble de anchas que de altas, el valor os saldrá 50 y si son cuadradas, el valor os saldrá 100.

Todo esto sólo es necesario añadirlo una vez.


Creando la lista de imágenes


La estructura HTML, o sea, lo que tenéis que poner en un gadget o dentro de una entrada, será la lista de imágenes con la cantidad de ellas que queráis.

<ul class="obgaleria" id="galeria1">
<li><img src="URL_IMAGEN1.jpg"/></li>
<li><img src="URL_IMAGEN2.jpg"/></li>
<li><img src="URL_IMAGEN3.jpg"/></li>
</ul>

Siendo obligatoria la clase obgaleria, por contra dentro de la id podéis poner el valor que queráis. Sólo hay que tener en cuenta que si vais a poner más de una galería por página, esa id debe ser distinta para cada lista.

Y listo. Cada vez que pongáis una lista de imágenes como la de antes con clase obgaleria, esta se convertirá en una galería.


¿Qué hace el JavasScript


El código principal lo que hace es buscar en la página todas las listas que tengan la clase obgaleria (1). Para cada una de ellas localiza y graba su id (2) y a partir de ahí calcula cuantas imágenes tiene la lista para dividir el ancho total entre ese número (3).

Luego utilizamos todos esos datos para formatear con CSS las dimensiones de las miniaturas y del espacio para la imagen grande, añadiendo el estilo necesario en el head (4).

Para que de inicio no se muestre vacío el hueco grande, clonamos la primera imagen y la añadimos al final de la lista (5). La que ahora será la última (hueco grande) la ampliamos hasta el máximo ancho disponible (6). Y esperamos un click (7).

Ya sólo resta que cuando este se produzca borremos la última imagen (hueco grande) (8) y a continuación volvamos a clonar y a poner en ese mismo lugar la pinchada (9). Este paso incluye una pequeña animación jugando con el ancho.

(x) var prop = 60.00; // proporción alto/ancho*100 imagen principal
(x) $(document).ready(function() {
(1) $("ul.obgaleria").each(function() {
(2) var id = "#" + $(this).attr("id");
(3) var ancho = 100 / $(id + " li").length;
(4) $("head").append("<style>" + id + "{padding: 0 0 " + (prop + ancho) + "% 0;} " + id + " li{width:" + ancho + "%;padding: 0 0 " + ancho + "% 0;} " + id + " li:last-child {padding-bottom: " + prop + "%;}</style>");
(5) $(id + " li:first-child").clone().appendTo(id);
(6) $(id + " li:last-child").css({"width": "100%"});
(7) $(id + " li").click(function() {
(8) $(id + " li:last-child").remove()
(9) $(this).clone().appendTo(id).animate({width: "100%"}, 200);
(x) });
(x) });
(x) });

Variante con miniaturas abajo


Tanto el CSS como el JavaScript cambian un poco debido a que ahora la imagen grande será la primera y no la última.



ul.obgaleria{width: 100%;height:0;overflow:hidden;margin: 30px auto;list-style: none;background:transparent;font-size:0;line-height:0;}
ul.obgaleria li{position: relative;display:inline-block;width:100%;height:0;margin:0;list-style:none;cursor:pointer;vertical-align:top;overflow:hidden;}
ul.obgaleria li img {position: absolute;top: -150%;bottom: -150%;left: -150%;right: -150%;width: auto;max-width: none;height: 150%;margin: auto;padding: 0;border:0;}
ul.obgaleria li:first-child img {top: 0;bottom: 0;left: 0;right: 0;margin: auto;width: 0;height: auto;}
ul.obgaleria li {border-left: 3px solid transparent;border-top: 3px solid transparent;box-sizing: border-box;}
ul.obgaleria li:nth-child(2), ul.obgaleria li:first-child {border-left:0;}

<script type='text/javascript'>//<![CDATA[
var prop = 60.00; // proporción alto/ancho*100 imagen principal
$("ul.obgaleria").each(function() {
var id = "#" + $(this).attr("id");
var ancho = 100 / $(id + " li").length;
$("head").append("<style>" + id + "{padding: 0 0 " + (prop + ancho) + "% 0;} " + id + " li{width:" + ancho + "%;padding: 0 0 " + ancho + "% 0;} " + id + " li:first-child {width: 100%;padding-bottom: " + prop + "%;}</style>");
$(id + " li:first-child").clone().prependTo(id);
$(id + " li:first-child img").css({
"width": "100%"
});
$(id + " li").click(function() {
$(id + " li:first-child").remove()
$(this).clone().prependTo(id);
$(id + " li:first-child img").animate({
width: "100%"
}, 200);
});
});
//]]></script>

Codepen dónde practicar


Miniaturas arriba: http://codepen.io/oloman/pen/VaqVww
Miniaturas abajo: http://codepen.io/oloman/pen/wGZKzM

¿Vemos otro post al azar por si le encuentras utilidad o quizás prefieres ser más metódico y suscribirte a nuestras entradas por correo? También puedes imprimir este artículo y por supuesto compartirlo en redes sociales si fue de tu agrado.

Compartir
Copy URL

Y muchos más artículos interesantes si nos sigues en...

follow us in feedly

32 comentarios :

  1. Te ha quedado muy chulo Oloman. Pero dime como seria con la carga de la pagina. Si hago varios post con este sistema se pondría lento la carga del blog o no tiene nada que ver, ya que por ser entradas independientes no afectaría la home.

    ResponderEliminar
    Respuestas
    1. ¿Tú observaste mucha demora en este post? Pues lleva el doble de código de lo que sería necesario, para poder mostrar los dos tipos de galerías.

      Siempre que la galería vaya en una entrada, no te va a demorar el Home... por pura lógica.
      De todas formas el código es muy liviana y en cualquier caso, también lo puedes meter todo (CSS y JS) dentro de una condición para evitar que siquiera se cargue eso en otras páginas que no sean entradas.

      Lo que más demora son las propias imágenes, no la galería.

      Eliminar
    2. Oloman instale la galeria con miniaturas abajo, pero las imagenes se ven redimencionadas (se ven muy cerca y cortadas). Todas las imagenes están en vertical. Haber si me echas un cable. Quiza deben tener alguna medida.

      Eliminar
    3. Si todas son verticales, entonces intercambia los valores de HEIGHT y WIDTH de este selector:
      ul.obgaleria li img {position: absolute;top: -150%;bottom: -150%;left: -150%;right: -150%;width: auto;max-width: none;height: 150%;margin: auto;padding:0;border:0;}

      Que el ancho sea 150% y el alto AUTO.

      Eliminar
  2. Gracias Oloman ;)
    Bonito recurso pero no cargaré más la página hasta que solvente algún problemilla pendiente... y me espero a que respondas a Jhonny Sán ;)
    Un saludo.

    ResponderEliminar
    Respuestas
    1. Pues ya lo tienes ;)
      Un saludo y tomé nota de tu petición sobre la encuesta musical. Poco quorum voy consiguiendo, pero no me canso de intentarlo.

      Eliminar
    2. Oído...
      Se puede hacer la encuesta treinta veces?, podría ir engrosando mi lista casi a diario, jeje...

      Eliminar
  3. Muy buena opción para galería. La segunda opción con las miniaturas debajo parece que no funciona.

    ResponderEliminar
  4. ¿Como hacer cuando quieres poner fotos de diferente tamaño, sea en la misma galería o en otra?

    ResponderEliminar
    Respuestas
    1. ¿Cómo que no funciona? La veo tanto en la demo de este post como en el Codepen enlazado al final del mismo ¿Dónde te falla a tí?

      Y para lo de las imágenes de diferente tamaño, ya está previsto así en el código. Lo único que decía es que deberían tener APROXIMADAMENTE la misma proporción evitando en lo posible mezclar imágenes verticales con horizontales, pero aún si las mezclas te funcionará.

      Eliminar
  5. Hola Oloman! Cuanto tiempo. Vengo a hacer una pregunta algo fuera de topico. Estoy en planes de comenzar un blog con una plantilla bastante bonita pero, con un error. Como puedes ver, la imagen de preview de la entrada esta estirada y pierde calidad por eso, como puedo arreglarlo para que se vea mas estetico y no dañe la foto?

    http://jardincaribeno.blogspot.com/

    ResponderEliminar
    Respuestas
    1. Hola Isaac. En primer lugar, para que la imagen te salga en portada con calidad, usa en las entradas imágenes más grandes. Si usas una de 320px como es el caso, al ampliarla para portada pixelará irremediablemente.

      Por otra parte está el asunto de que se deforme. Esto lo puedes arreglar añadiendo al CSS de tu plantilla lo siguiente:
      .entry-thumb {
      position: relative;
      width: 100%;
      height: 0;
      padding-bottom: 50%;
      }
      .entry-thumb img {
      height: auto !important;
      position: absolute;
      top: 0;
      bottom: 0;
      left: 0;
      right: 0;
      margin: auto;
      }

      Eliminar
  6. Hola Oloman! Que suerte me da saber de que esta pagina sigue en pie y sigues publicando contenido. Hace como unos 7 años consultaba tu pagina a diario para añadirle cosas chulas a mi blog. Hoy tengo 17 y queriendo volver a mi blog me encontré con tu blog de ayuda nuevamente. Muchas gracias por tu ayuda desde hace años, y nunca lo abandones. Te mando un saludo desde Argentina

    ResponderEliminar
    Respuestas
    1. Hola Facundo. Gracias, pero aclárame esto ¿hoy tienes 17 blogs o 17 años? Es que si hace 7 que me sigues... ¡tenías que ser un bebé! XD

      Eliminar
    2. Recién leo este mensaje jaja. Si, me refería a 17 años. Hace unos días cumplí 18. Y desde los 10 u 11 empecé a crear mi propio blog gracias a tu ayuda. Un saludo!!!

      Eliminar
    3. Un chico adelantado... y un fiel lector. Gracias ;)

      Eliminar
  7. Muchas gracias.. me interesa mucho este efecto.. estaré usando el segundo efecto.. Gracias!!!
    Permiteme para preguntarte algo, que me tiene con la cabeza vuelta un ocho:
    como hago para agregar en una template respective un footer ancho o largo..?
    La plantilla tiene en el footer tres columnas, pero debajo de esas 3 columnas quiero agregar una columna mas
    pero larga o ancha, no se como llamarle.
    Es para agregar el widgets de instagram que con 100% de ancho para que abarque el ancho de la pantalla dicho widget allí donde lo coloque..
    Trate de hacerlo pero, el widget sale como mal ubicado al ponerlo, y me desconfigura un poco los créditos del footer (al final de todo).. Me podrías pasar el codigo a usar para generar este sección en diseño en blogger?
    Gracias anticipadas!!

    ResponderEliminar
    Respuestas
    1. Hola Opic. En esta entrada y las dos sucesivas expliqué hace tiempo como añadir bloques a la plantilla de Blogger. Luego sólo es cuestión de formatearlas con CSS. No puedo desarrollarlo más en un comentario que allí y por eso te remito a ellas.

      Eliminar
  8. Que tal Oloman excelente los tips que haces, ese jquery esta genial, no me funciono la segunda.
    Por Cierto hace poco de envié un mail. espero que te haya llegado. ( www.dpstudio3d.com )
    Saludos Cordiales

    ResponderEliminar
    Respuestas
    1. Hola. Supongo que te refieres a la segunda opción de las miniaturas abajo. En cualquier caso siempre pongo demo para que comprobéis que los códigos funcionan 100%. Adicionalmente en el correspondient Codepen podrás ver también que todo va bien, así que en principio debo achacar el problema a qué algo no hiciste bien.

      Sobre el correo, voy escaso de tiempo, pero te contesté hace poco.

      Eliminar
    2. Hola, Oloblogger de hecho, DP Studio tiene razón, el segundo script no funciona al menos en Blogger... La solución que le di a mi caso (no se si funcione con los demás) fue agregar unas líneas al segundo script que el primero SÍ tiene:
      Luego de la var prop pegar:
      $(document).ready(function() {


      Y al final de todo el script:
      });

      Con eso funcionó entonces la galería. Saludos y Feliz Año a todos.

      Eliminar
    3. Pues sí Cyball. Depende de dónde se ponga el código esa instrucción que indicas será necesaria.

      Gracias.

      Eliminar
  9. Hola hoy escrito varios comentarios en varios Temas y el segundo Ejemplo es lo que busco, pero por mas que lo realise el 2° no me queda, ya revise todo y no queda :( y necesito algo asi espero que me conteste lo mas rapido posible (espero que mañana) por favorrr

    ResponderEliminar
    Respuestas
    1. "Mañana" no fue. Me pillaste de vacaciones y con otras cosas para hacer.

      Si llego a tiempo, prueba mejor la primera opción, pues ahí explique paso a paso dónde incluir cada parte de código.

      Te debe funcionar y cuando lo compruebes, entonces simplemente cambia la parte CSS y el JavaScript por el que se indica para la segunda opción.

      Eliminar
  10. Ojala andes bien, tenia una duda. Al momento de hacer la galeria, hay una chance de ponerle Url a cada img o sea.. pinchas una imagen y te lleva a x lugar, en mi caso seria a una entrada o post. ¿Se puede hacer eso?

    ResponderEliminar
    Respuestas
    1. Se puede hacer Nasu. Lo que pasa es que hay que modificar un poco la estructura HTML, añadiendo un atributo y también modificando el JavaScript.

      En el Codepen del ejemplo 1 he añadido lo necesario para que veas como sería. Para la dirección añades una DATA="DIRECCION_DESTINO" en cada LI. Luego las modificaciones en el JS que he marcado con comentarios.

      Eliminar
  11. Muchísimas gracias por tus códigos. Eres un crack. Suelo seguirte y estoy muy agradecido. Con esta galería tengo un problema: sale todo fenomenal, pero las miniaturas de arriba están muy separadas de la foto grande de abajo, quedando un efecto óptico muy feo. En tu ejemplo no pasa eso. ¿Puedes ayudarme?, por favor.
    Gracias.

    ResponderEliminar
    Respuestas
    1. Hola. Quizás dejaste en el código HTML algún salto de línea. En Blogger, si pones el HTML dentro de un post y existen saltos, estos se interpretan y por tanto se viaualizan en el resultado.

      Si con eso no logras resolver el problema dime la página dónde lo tienes puesto que eche un vistazo.

      Eliminar
  12. Gracias por todas tus aportaciones Oloman.
    Por favor, ¿podrías indicar cómo sustituir la foto pequeña por un texto, tipo menú, que no sea un link a otra página sino que aparezca la imagen grande como ahora? Un menú de tres pestañas que hacen que aparezca una imagen debajo ( o texto, o cualquier cosa, pero no que active un link a otra página ).
    Gracias de nuevo, has sido siempre de gran ayuda.

    ResponderEliminar
    Respuestas
    1. Buenas ATM. Eso que propones no tiene nada que ver con esto y el código sería muy muy distinto. No es lo mismo tomar una serie de imágenes y replicar una en grande, que a partir de un texto sacar una imagen que no tiene nada que ver.

      Eliminar
  13. Hola Oloman, está buenísimo, solo me faltaría que al hacer clic sobre la imagen grande abra en otra pagina para ver completa. Gracias

    ResponderEliminar
  14. Hola, lo instale y se ve bien, pero le hace falta ese borde blanco que tienen las imagenes pequeñas. agradecería tu ayuda. Gracias

    ResponderEliminar