Slide original y divertido con burbujas con jQuery

Hoy vamos a desarrollar un efecto de animado de burbujas mediante jQuery. Será una gran manera de presentar un conjunto de imágenes en tu sitio web a modo slide. Destacar que el código expuesto en este artículo es completamente modular, es decir, serás capaz de utilizarlo fácilmente y también de modificarlo.

El HTML

El efecto de slide que vamos a crear hoy, tiene el mismo modo de uso que un plugin común de jQuery. Como la mayor parte del trabajo será realizada por el plugin, no hay mucho más que ver en esta sección. Sin embargo, para utilizarlo es necesario agregar una lista desordenada en tu página. Los slides individuales del slideshow se añadirá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 utilizar el plugin, necesitas incluir el jquery.bubble Slideshow.css en el head de la página, y bgpos.js jquery.bubble Slideshow.js antes de cerrar la etiqueta body. bgpos.js es un jQuery que nos permitirá animar la propiedad background-position (necesaria en la animación de burbujas), y jquery.bubbleSlideshow.js contiene el código que escribiremos justo más abajo. Recuerda que debes incluir la librería jQuery también.

Javascript y jQuery

En primer lugar vamos a escribir una clase de JavaScript con el nombre Bubble. Cada burbuja del slideshow va a ser un objeto de esta clase. Tendrá propiedades tales como top y left (offsets de posición), size (diámetro del círculo) y una propiedad elem, que es un objeto jQuery que contiene div actual. Vamos a utilizar esta propiedad más tarde, cuando animemos las burbujas en el método flyFrom().

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 método flyFrom() toma una serie de coordenadas que determinan la posición de los vuelos de la burbuja. Este método se define en el prototipo de la función de la burbuja, lo que hace que, de forma automática, esté a disposición de todas sus instancias. Este es un enfoque más eficaz, ya que sólo existe una copia de este método a la vez, en lugar de una copia de este método para cada objeto. Además, ten en cuenta la función rand() definida en la parte inferior del código. Esta función imita a la función de PHP del mismo nombre y se utiliza en todo el código del plugin.

Ahora que tenemos la clase colocada, vamos a escribir una función que cree un array con los objetos bubble, que los añada a los nuevos elementos li y los anime. La función tiene tres parámetros:

  • stage, que es un objeto jQuery que contiene un elemento ul. Esto llevará a cabo el slideshow, con cada siendo un li individual
  • imgURL es la dirección URL de la imagen que se mostrará en las burbujas
  • func es una función de devolución de llamada que se llamará una vez que todas las animaciones se hayan completado. Esto se utiliza para cambiar las diapositivas y destruir las burbujas, ya que no serán necesarias después de que se haya completado la transición al nuevo slide

Como has adivinado, para cada transición de slide, se crea un nuevo conjunto aleatorio de burbujas, y se destruyen después de que la siguiente diapositiva sea visible.

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 = $('
  • ').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 ); } }

¡Estupendo! Ahora sí que tenemos una función que crea un conjunto de burbujas en un nuevo elemento LI y las anima. Pero éstas son sólo las funciones, aún no son un plugin, así que esa es nuestra próxima tarea. Tampoco disponemos de slides. Vamos a escribir 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 plugin llamado bubbleSlideshow(). Debe llamarse en un elemento UL y coge un array de URLs de fotos como parámetro. Este array se añadirá al ul.

En el body, el plugin crea un nuevo elemento li para cada una de las fotos del array, y añade los métodos shownext, showPrev, AutoAdvance al ul. Éstas envuelven las funciones locales con los mismos nombres, tal y como puedes 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');
        });        

    }

He usado "local" para describir estas funciones, debido a que no están disponibles desde fuera del plugin. Las funciones ShowNext y ShowPrev llaman a showFrame, pasándole el ul y el slide del li que se va a mostrar. showFrame se asegura de que sólo hay una animación en ejecución a la vez, y llama a la función showBubbles que escribimos antes.

La función de devolución de llamada que se pasa junto con la llamada al método, muestra el slide que desea mostrar por encima de todos los demás adjuntándola como última del UL. Esta sería la manera de inicializar nuestro slideshow de burbujas:

script.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 añaden propiedades tales posicionamiento, overflows y background-positions:

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 todo esto, nuestro efecto de burbujas quedaría completo.

Fuente: tutorialzine.com

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP