Efecto de presentación de burbujas con jQuery

Hoy vamos a crear un efecto de animación de burbujas basado en jQuery. Será una excelente manera de presentar un conjunto de imágenes en su sitio web como una presentación de diapositivas interesante. Y como el código será completamente modular, podrás usarlo y modificarlo fácilmente.

El HTML

El efecto de presentación de diapositivas que crearemos hoy tomará la forma de un complemento jQuery fácil de usar. Como la mayor parte del trabajo lo realiza el complemento, no hay mucho que hacer en esta sección. Sin embargo, para usar el complemento, debe agregar una lista desordenada en su página. Las diapositivas individuales de la presentación de diapositivas se agregarán como elementos LI.

index.html

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>Bubble Slideshow Effect with jQuery | Tutorialzine Demo</title>

        <!-- Our CSS stylesheet file -->
        <link rel="stylesheet" href="assets/css/styles.css" />

        <!-- The plugin stylehseet -->
        <link rel="stylesheet" href="assets/jquery.bubbleSlideshow/jquery.bubbleSlideshow.css" />

        <!--[if lt IE 9]>
          <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
        <![endif]-->
    </head>

    <body>

        <!-- The bubble slideshow holder -->
        <ul id="slideShow"></ul>

        <!-- JavaScript includes -->
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
        <script src="assets/jquery.bubbleSlideshow/bgpos.js"></script>
        <script src="assets/jquery.bubbleSlideshow/jquery.bubbleSlideshow.js"></script>
        <script src="assets/js/script.js"></script>

    </body>
</html>

Para poder usar el complemento, deberá incluir jquery.bubbleSlideshow.css en el encabezado de la página, bgpos.js y jquery.bubbleSlideshow.js antes de la etiqueta del cuerpo de cierre. bgpos.js es un complemento de jQuery CSS hooks que nos permitirá animar la posición de fondo propiedad (necesaria en la animación de la burbuja) y jquery.bubbleSlideshow.js contiene el código que escribiremos hoy. También recuerde incluir la biblioteca jQuery también.

Puede ver una explicación simple del efecto de burbuja a continuación.

JavaScript y jQuery

Primero escribiremos una clase JavaScript llamada Bubble . Cada burbuja en la presentación de diapositivas será un objeto de esta clase. Tendrá propiedades como top y izquierda (compensaciones de posición), tamaño (diámetro del círculo) y un elemento property, que es un objeto jQuery que contiene el div real. Usaremos esta propiedad más adelante cuando animemos la burbuja en el flyFrom() método.

jquery.bubbleSlideshow.js

  // This is the Bubble class. It takes left and top
    // coordinates, size (diameter) and a image URL

    function Bubble( left, top, size, imgURL ){

        this.top    = top;
        this.left   = left;
        this.size   = size;

        // This places the center of the
        // circles on the specified position:

        top -= size/2;
        left-= size/2;

        this.elem = $('<div>',{
            'class':'bubble',
            'css'   : {
                'width'     : size,
                'height'    : size,
                'top'       : top,
                'left'      : left,
                'background-position': (-left)+'px '+(-top)+'px',
                'background-image': 'url('+imgURL+')'
            }
        });

    }

    // The fly from method takes a starting position, time,
    // and a callback function, executed when the animation finishes.

    Bubble.prototype.flyFrom = function( startX, startY, time, callBack ){

        time = time || 250;
        callBack = callBack || function(){};

        startX -= this.size/2;
        startY -= this.size/2;

        // Offsetting the element

        this.elem.css({
            'display'               : 'block',
            'backgroundPositionX'   : -startX,
            'backgroundPositionY'   : -startY,
            'left'                  : startX,
            'top'                   : startY
        });

        // Animating it to where it should be

        this.elem.animate({
            'backgroundPositionX'   : -this.left,
            'backgroundPositionY'   : -this.top,
            'left'                  : this.left,
            'top'                   : this.top
        }, time, 'easeOutCirc', callBack );

    };

    // Helper function for generating random
    // values in the [min,max] range

    function rand( min, max ){
        return Math.floor( Math.random()*((max+1)-min) + min);
    }

El flyFrom() El método toma un conjunto de coordenadas que determinan la posición desde la que la burbuja vuela. . Todavía termina en la posición que especifica al crearlo. Este método está definido en el prototipo de la función Bubble, que automáticamente lo pone a disposición de todas sus instancias. Este es un enfoque más efectivo, ya que solo existe una copia de este método a la vez, en lugar de una copia de este método para cada objeto. Además, observe el rand() función definida en la parte inferior del fragmento. Imita la función PHP del mismo nombre y se usa en todo el código del complemento.

Ahora que tenemos la clase en su lugar, escribamos una función que cree una matriz con objetos de burbujas, los agregue a un nuevo elemento LI y los anime. La función toma tres parámetros:

  • escenario , que es un objeto jQuery que contiene un elemento UL. Esto mantendrá la presentación de diapositivas, siendo cada diapositiva un LI individual;
  • imgURL es la URL de la imagen que se mostrará en las burbujas;
  • función es una función de devolución de llamada que se llamará una vez que se completen todas las animaciones de burbujas. Esto se usa para cambiar las diapositivas y destruir las burbujas, ya que no serán necesarias una vez que se complete la transición a la nueva diapositiva;

Como habrás adivinado, por cada transición de diapositiva, se crea un nuevo conjunto aleatorio de burbujas y se destruyen después de que se hace visible la siguiente diapositiva.

jquery.bubbleSlideshow.js

  function showBubbles( stage, imgURL, func ){

        // This function appends a new LI element to the UL
        // and uses it to hold and animate the bubbles.

        var i = 0,
            bubbles = [],
            totalBubbles = 75,
            stageWidth = stage.outerWidth(),
            stageHeight = stage.outerHeight(),
            emptyFunc = function(){};

        // This li holds the bubbles
        var li = $('<li class="bubbleStage">').appendTo(stage);

        // This function is passed to the flyFrom method call:

        var callBack = function(){

            // Waiting for the func function to
            // finish and removing the li.

            $.when(func()).then(function(){
                li.remove();
            });
        };

        for( i=0; i<totalBubbles; i++ ){

            var x    = rand(0, stageWidth),
                y    = rand(0,stageHeight),
                size = rand(30,150);

            var bubble = new Bubble( x, y, size, imgURL );
            li.append(bubble.elem);

            bubbles.push(bubble);
        }

        // Sorting the bubbles so that the
        // bubbles closest to the top border of
        // the image come first:

        bubbles = bubbles.sort(function( b1, b2 ){
            return b1.top+b1.size/2 > b2.top+b2.size/2;
        });

        // Looping through all the bubbles,
        // and triggering their flyFrom methods

        for( i=0; i<bubbles.length; i++){

            (function( bubble, i ){
                setTimeout(function(){

                    bubble.flyFrom(
                        stageWidth/2,
                        stageHeight+200,
                        250,
                        (i == bubbles.length-1) ? callBack : emptyFunc
                    );

                // This Math.floor schedules five bubbles
                // to be animated simultaneously

                }, Math.floor(i/5)*100); 

            })( bubbles[i], i );
        }
    }

¡Excelente! Así que ahora tenemos una función que crea un conjunto de burbujas en un nuevo elemento LI y las anima. Pero estas son solo funciones, aún no son un complemento, por lo que tendremos que trabajar en eso. Además, todavía nos faltan las diapositivas. Escribamos las piezas que faltan:

jquery.bubbleSlideshow.js

$.fn.bubbleSlideshow = function(photos){

        if(!$.isArray(photos)){
            throw new Error("You need to pass an array of photo URLs as a parameter!");
        }

        photos = photos.reverse();

        var ul = this.addClass('bubbleSlideshow');

        $.each(photos,function(){
            ul.append('<li><img src="'+this+'" /></li>');
        });

        // These methods are available externally and
        // can be used to control the bubble slideshow

        ul.showNext = function(){
            showNext(ul);
        };

        ul.showPrev = function(){
            showPrev(ul);
        };

        ul.autoAdvance = function(timeout){
            timeout = timeout || 6000;
            autoAdvance(ul,timeout);
        };

        ul.stopAutoAdvance = function(){
            stopAutoAdvance(ul);
        };

        return ul;
    };

El código anterior define un nuevo complemento llamado bubbleSlideshow() . Debe invocarse en un elemento UL y tomar una matriz de URL de fotos como su parámetro. Estos se agregan a la UL.

Dentro de su cuerpo, el complemento crea un nuevo elemento LI para cada una de las fotos de la matriz y agrega showNext , mostrarAnterior , avance automático y detener el avance automático métodos a la UL. Estos envuelven funciones locales con los mismos nombres, que puede ver a continuación:

jquery.bubbleSlideshow.js

  function autoAdvance(stage,timeout){
        stage.data('timeout',setTimeout(function(){
            showNext(stage);
            autoAdvance(stage,timeout);
        },timeout));
    }

    function stopAutoAdvance(stage){
        clearTimeout(stage.data('timeout'));
    }

    function showNext(stage){
        showFrame(stage, stage.find('li.bubbleImageFrame').first());
    }

    function showPrev(stage){
        showFrame(stage, stage.find('li.bubbleImageFrame').last().prev());
    }

    function showFrame(stage, frame ){

        // This function shows a frame,
        // passed as a jQuery object

        if(stage.data('working')){
            // Prevents starting more than
            // one animation at a time:
            return false;
        }
        stage.data('working',true);

        var frame = frame.hide().detach();

        // Using the showBubbles function, defined below.
        // The frame is showed after the bubble animation is over.

        showBubbles( stage, frame.find('img').attr('src'), function(){
            stage.append(frame);
            stage.data('working',false);

            // This returns a jQuery Promise object.
            return frame.fadeIn('slow');
        });     

    }

Usé "local" para describir estas funciones, ya que no están disponibles desde fuera del complemento. El mostrarSiguiente y mostrarAnterior las funciones por encima de ambas llaman a showFrame , pasándole la diapositiva UL y LI que se quiere mostrar. marco de presentación se asegura de que solo se esté ejecutando una animación a la vez y llama a showBubbles función que ya escribimos.

La función de devolución de llamada que se pasa junto con la llamada al método, muestra la diapositiva que desea mostrar sobre todas las demás al agregarla en último lugar en la UL (las diapositivas están absolutamente posicionadas, lo que significa que el último elemento en la UL se muestra en la parte superior ). Esta función se llama una vez que se completa la animación de la burbuja.

Así es como inicializa la presentación de diapositivas de burbujas:

secuencia de comandos.js

$(function(){
    var photos = [
        'http://farm6.static.flickr.com/5230/5822520546_dd2b6d7e24_z.jpg',
        'http://farm5.static.flickr.com/4014/4341260799_b466a1dfe4_z.jpg',
        'http://farm6.static.flickr.com/5138/5542165153_86e782382e_z.jpg',
        'http://farm5.static.flickr.com/4040/4305139726_829be74e29_z.jpg',
        'http://farm4.static.flickr.com/3071/5713923079_60f53b383f_z.jpg',
        'http://farm5.static.flickr.com/4108/5047301420_621d8a7912_z.jpg'
    ];

    var slideshow = $('#slideShow').bubbleSlideshow(photos);

    $(window).load(function(){
        slideshow.autoAdvance(5000);
    });

    // Other valid method calls:

    // slideshow.showNext();
    // slideshow.showPrev();
    // slideshow.stopAutoAdvance();
});

Todo lo que queda es definir algunas reglas CSS que agregan propiedades como posicionamiento, desbordamientos y posiciones de fondo:

jquery.bubbleSlideshow.css

ul.bubbleSlideshow{
    position:relative;
    list-style:none;
    overflow:hidden;
}

.bubbleSlideshow li{
    position:absolute;
    top:0;
    left:0;
}

.bubbleSlideshow li img{
    display:block;
}

.bubbleSlideshow li div.bubble{
    -moz-border-radius:50%;
    -webkit-border-raidus:50%;
    border-radius:50%;

    background-repeat:no-repeat;
    display:none;
    position:absolute;
}

¡Con esto, la presentación de diapositivas con efecto de burbuja está completa!

Palabras finales

El efecto que hicimos hoy puede no estar limitado solo a presentaciones de diapositivas. Se puede utilizar para crear fondos, encabezados y presentaciones de sitios web únicos. El complemento está diseñado para cambiar de tamaño automáticamente para adaptarse a la UL, por lo que puede cambiar fácilmente su tamaño ajustando algunas propiedades de CSS.