Pila de fotos animadas CSS3

En este tutorial, vamos a crear una pila de fotos animadas, que usará todo tipo de efectos sofisticados para hacer la transición entre un conjunto de imágenes. Los efectos se implementan únicamente con CSS3, lo que significa que se ejecutan sin problemas en navegadores y dispositivos móviles modernos. También haremos que la pila de fotos avance automáticamente, para que pueda usarla como una presentación de diapositivas.

El HTML

Como siempre, el primer paso es presentar el marcado del ejemplo. Comenzamos con un documento HTML5 normal en el que incluimos varios archivos CSS/JS:

index.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />

    <title>Animated CSS3 Photo Stack | Tutorialzine Demo</title>

    <!-- CSS Includes -->
    <link href="assets/css/style.css" rel="stylesheet" />
    <link href="assets/css/animate.css" rel="stylesheet" />

</head>
<body>

    <ul id="photos">
        <li><a href="http://www.flickr.com/photos/brockwhittaker/8500935165/"
        style="background-image:url(...)">Landscape 5</a></li>
        <!-- More photos here -->
    </ul>

    <a href="#" class="arrow previous"></a>
    <a href="#" class="arrow next"></a>

    <!-- Libraries -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
    <script src="assets/js/script.js"></script>

</body>
</html>

Las #fotos UL tiene las fotos que animaremos. Para cada foto, he definido un elemento LI con un elemento ancla dentro. La imagen se establece como la propiedad de imagen de fondo del enlace. Como verá en la parte de CSS, estoy usando la propiedad de tamaño de fondo para obligar a la imagen a cubrir todo el ancho y alto del enlace. Al agregar más fotos, tenga en cuenta que debido a que están posicionadas de forma absoluta, se mostrarán en orden inverso (la última foto estará en la parte superior).

En la sección principal del documento, incluyo nuestra hoja de estilo principal y animate.css, la biblioteca que nos brinda esas maravillosas animaciones CSS3. Antes de la etiqueta del cuerpo de cierre, tenemos la biblioteca jQuery y el script.js que analizaremos a continuación.

JavaScript

Para activar los efectos que nos da la librería animate, tenemos que asignar un nombre de clase al elemento con el nombre de la animación. También tendremos que mover la foto animada al final de la pila después de que termine la animación, para que podamos mostrar la siguiente imagen. Esto es lo que debemos hacer para que este ejemplo funcione:

  • Primero, escucharemos los clics en las flechas;
  • Luego, cuando se haga clic en la siguiente flecha, activaremos una animación CSS elegida al azar asignando un nombre de clase al elemento superior de la pila (este es en realidad el último elemento LI debido al posicionamiento);
  • Después de un segundo, cuando se complete la animación, moveremos el elemento animado antes que los otros LI con el método prependTo jQuery (esto lo empujará al final de la pila) y eliminaremos las clases que hemos asignado anteriormente.
  • Para la flecha anterior, haremos casi lo mismo, con la única diferencia de que tomaremos la última imagen y la colocaremos en la parte superior de la pila antes de activar la animación.

Además, también agregaré la funcionalidad de avance automático como lo hicimos en este artículo. Esto convertirá el ejemplo en una presentación de diapositivas genial que detendrá las transiciones automáticas cuando haga clic en una de las flechas.

Así es como se ve el código:

activos/js/script.js

$(function() {

    var exits = ['fadeOut', 'fadeOutDown', 'fadeOutUpBig', 'bounceOut', 'bounceOutDown',
        'hinge', 'bounceOutUp', 'bounceOutLeft', 'rotateOut', 'rotateOutUpLeft',
        'lightSpeedOut', 'rollOut'];

    var entrances = ['fadeIn', 'fadeInDown', 'fadeInRight', 'bounceIn', 'bounceInRight',
            'rotateIn', 'rotateInDownLeft', 'lightSpeedIn', 'rollIn', 'bounceInDown']; 

    var photos = $('#photos'),
        ignoreClicks = false;

    $('.arrow').click(function(e, simulated){
        if(ignoreClicks){

            // If clicks on the arrows should be ignored,
            // stop the event from triggering the rest
            // of the handlers

            e.stopImmediatePropagation();
            return false;
        }

        // Otherwise allow this click to proceed,
        // but raise the ignoreClicks flag

        ignoreClicks = true;

        if(!simulated){
            // Once the user clicks on the arrows,
            // stop the automatic slideshow
            clearInterval(slideshow);
        }
    });

    // Listen for clicks on the next arrow
    $('.arrow.next').click(function(e){

        e.preventDefault();

        // The topmost element
        var elem = $('#photos li:last');

        // Apply a random exit animation
        elem.addClass('animated')
            .addClass( exits[Math.floor(exits.length*Math.random())] );

        setTimeout(function(){

            // Reset the classes
            elem.attr('class','').prependTo(photos);

            // The animation is complate!
            // Allow clicks again:
            ignoreClicks = false;

        },1000);
    });

    // Listen for clicks on the previous arrow
    $('.arrow.previous').click(function(e){

        e.preventDefault();

        // The bottom-most element
        var elem = $('#photos li:first');

        // Move the photo to the top, and
        // apply a random entrance animation

        elem.appendTo(photos)
            .addClass('animated')
            .addClass( entrances[Math.floor(entrances.length*Math.random())] );

        setTimeout(function(){

            // Remove the classess
            elem.attr('class','');

            // The animation is complate!
            // Allow clicks again:
            ignoreClicks = false;

        },1000);
    });

    // Start an automatic slideshow
    var slideshow = setInterval(function(){

        // Simulate a click every 1.5 seconds
        $('.arrow.next').trigger('click',[true]);

    }, 1500);

});

No he usado todos los efectos que proporciona animate.css, pero puedes encontrar una lista completa en su página de github.

Todo lo que nos queda por hacer es escribir algunos estilos CSS.

El CSS

No mostraré todos los estilos aquí, solo aquellos que son directamente responsables de la pila de fotos:

activos/css/estilos.css

#photos{
    margin:0 auto;
    padding-top:120px;
    width:450px;
    position:relative;
}

#photos li{
    position:absolute;
    width:450px;
    height:450px;
    overflow:hidden;
    background-color:#fff;
    box-shadow: 1px 1px 1px #ccc;
    z-index:10;

    -webkit-animation-duration: 1s;
    -moz-animation-duration: 1s;
    animation-duration: 1s;
}

#photos li a{
    position:absolute;
    top:6px;
    left:6px;
    right:6px;
    bottom:6px;
    background-size: cover;
    text-indent:-9999px;
    overflow:hidden;
}

Para cambiar la duración de las animaciones, deberá proporcionar la propiedad animation-duration. En el fragmento de arriba, lo configuré en 1 segundo. Más propiedades que puede establecer son animation-delay para el retraso antes de que se active la animación y animation-iteration-count para el número de repeticiones.

¡Listo!

¡Con esto, nuestro efecto de pila de fotos animadas está completo! Puede usar este ejemplo como una presentación de diapositivas liviana que funciona sin problemas incluso en dispositivos móviles.