Post Actualizado en julio 25, 2013


Carrusel de imágenes con Canvas y jQuery

Mucho se ha oído y hablado sobre la implementación del nuevo elemento Canvas en la quinta y más reciente revisión del lenguaje HTML, su potencial se ha convertido en fuente de energía para que tanto desarrolladores como artistas comiencen a explorar y emplearlo en brillantes proyectos que causan el asombro de varios. Su concepto es […]

Mucho se ha oído y hablado sobre la implementación del nuevo elemento Canvas en la quinta y más reciente revisión del lenguaje HTML, su potencial se ha convertido en fuente de energía para que tanto desarrolladores como artistas comiencen a explorar y emplearlo en brillantes proyectos que causan el asombro de varios.

Su concepto es básico, Canvas es una región dibujable hecha con HTML que cuenta con cierta altura y anchura, en donde se permite realizar trazos y composiciones a través de funciones. En dicho elemento se permite la generación, modificación y manipulación de gráficos mediante código, se pueden crear imágenes de cero, animaciones y juegos sin necesidad de algún editor externo y al ser un elemento más del código HTML puede ser accedido y manipulado mediante JavaScript directo o por métodos de alguno de sus frameworks como jQuery o Mootools.

Aunque como ya se mencionó, su función este enfocada a permitir trazados complejos directamente en el código fuente del sitio, en este artículo usaremos sus propiedades para llevar acabo una funcionalidad mucho más común en nuestros proyectos, haremos un carrusel progresivo de imágenes donde aplicaremos Canvas para desplegar un estupendo efecto de transición.

Básicamente, lo que haremos será optimizar la funcionalidad a lo que ya se ha venido desarrollando, mediante JavaScript aplicaremos un filtro a cada imagen de la presentación para crear una nueva versión con apariencia distinta a la original, dichas nuevas versiones contendrán imágenes con colores más vivos y con un mayor contraste, las cuáles serán almacenadas en los elementos Canvas que se crearán para cada una de ellas.

Al agregar un efecto de desvanecimiento cuando el usuario de clic en el icono para cambiar de imagen se creará la impresión de una transición suave, con un tipo de iluminación distinto al que normalmente se utiliza, haciendo aún más estético el cambio de una imagen a otra.

Antes de empezar a trabajar con el código hay que aclarar que existen ciertas limitaciones de seguridad para trabajar con Canvas en un servidor local, por lo que debemos subir nuestra aplicación a un servidor web externo para poder observar su comportamiento, si no cuentas con uno puedes acceder algún sitio de alojamiento gratuito para probarlo ya que si continuas trabajando en tu servidor local recibirás el error NS_ERROR_NOT_AVAILABLE en tu consola.

Primero que nada creamos la estructura de nuestro sitio, donde mostraremos 4 imágenes dentro de una lista que se encuentra depositada en una capa llamada “presentación”.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Carrusel de imágenes Canvas + jQuery</title>

<link rel="stylesheet" type="text/css" href="estilo.css" />

</head>
 
<body>

<div id="presentacion">

    <ul class="slides">
        <li><img src="http://www.dehermosillo.org/imagenes/fotos/Bomberos_hermosillo.jpg" width="620" height="320" alt="Bomberos" /></li>
        <li><img src="http://www.dehermosillo.org/imagenes/fotos/plaza_hidalgo_cinenoriega.jpg" width="620" height="320" alt="Plaza Hidalgo" /></li>
        <li><img src="http://www.dehermosillo.org/imagenes/fotos/mercado_municipal_3.jpg" width="620" height="320" alt="Mercado Municipal" /></li>
        <li><img src="http://www.dehermosillo.org/imagenes/fotos/cine_nacional_1938.jpg" width="620" height="320" alt="Cine Nacional" /></li>
    </ul>

    <span class="flecha anterior"></span>
    <span class="flecha siguiente"></span>
</div>
   
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script src="script.js"></script>
</body>
</html>

Ha dicha lista le aplicaremos un estilo para que se muestre como una presentación de fotografías, así mismo agregaremos las imágenes de las flechas para las capas que nos enviarán de una fotografía a otra y que serán las que detonen el llamado a nuestra funcionalidad de JavaScript para crear los Canvas.

*{
    margin:0;
    padding:0;
}

body{
    background: #333333;
}

#presentacion{
    background-color:#F5F5F5;
    border: 2px dashed #333333;
    height:340px;
    margin:10% auto;
    position:relative;
    width:640px;
}
 
#presentacion ul{
    height:320px;
    left:10px;
    list-style:none outside none;
    overflow:hidden;
    position:absolute;
    top:10px;
    width:620px;
}

#presentacion li{
    position:absolute;
    display:none;
    z-index:10;
}

#presentacion li:first-child{
    display:block;
    z-index:1000;
}

#presentacion .activa{
    z-index:1000;
}

#presentacion canvas{
    display:none;
    position:absolute;
    z-index:100;
}

#presentacion .flecha{
    height:110px;
    width:120px;
    position:absolute;
    top:50%;
    margin-top:-43px;
    cursor:pointer;
    z-index:5000;
}

#presentacion .anterior{ background:url(‘http://cdn.iconfinder.net/data/icons/49handdrawing/128×128/left.png’) no-repeat; }

#presentacion .siguiente{ background:url(‘http://cdn.iconfinder.net/data/icons/49handdrawing/128×128/right.png’) no-repeat; right:0;}

Finalmente crearemos el Script necesario para crear los Canvas, agregarle las imágenes y modificarles su contraste.

$(window).load(function(){
     
    // Realizamos las funciones mediante un windows.load para segurarnos que las imagenes de la presentacion fueron cargadas.

    // Probamos si el navegador usado soporta canvas
    var aceptaCanvas = ‘getContext’ in document.createElement(‘canvas’);

    // Mejoramos la respuesta de la página haciendo asíncrono nuestro proceso
    var imagenes = $(‘#presentacion li’),
        current = 0,
        presentacion = {width:0,height:0};

    setTimeout(function(){
         
        window.console && window.console.time && console.time(‘Generado en’);
         
        if(aceptaCanvas){
            $(‘#presentacion img’).each(function(){

                if(!presentacion.width){
                    // Tomamos las dimensiones de la primera imagen:
                    presentacion.width = this.width;
                    presentacion.height = this.height;
                }
                 
                // Presentamos las versiones modificadas de las imágenes
                createCanvasOverlay(this);
            });
        }
         
        window.console && window.console.timeEnd && console.timeEnd(‘Generated In’);
         
        $(‘#presentacion .flecha’).click(function(){
            var li            = imagenes.eq(current),
                canvas        = li.find(‘canvas’),
                siguienteIndex    = 0;

            // En base a la flecha seleccionada, calculamos el indice de la siguiente imagen             
            if($(this).hasClass(‘siguiente’)){
                siguienteIndex = current >= imagenes.length-1 ? 0 : current+1;
            }
            else {
                siguienteIndex = current <= 0 ? imagenes.length-1 : current-1;
            }

            var siguiente = imagenes.eq(siguienteIndex);
             
            if(aceptaCanvas){
                canvas.fadeIn(function(){
                     
                    // Mostramos la siguiente imagen
                    siguiente.show();
                    current = siguienteIndex;
                     
                    //Agregamos la clase y el efecto
                    li.fadeOut(function(){
                        li.removeClass(‘activa’);
                        canvas.hide();
                        siguiente.addClass(‘activa’);
                    });
                });
            }
            else {                 
                // Si el browser no soporta canvas mostramos la version sin efecto                 
                current=siguienteIndex;
                siguiente.addClass(‘activa’).show();
                li.removeClass(‘activa’).hide();
            }
        });
         
    },100);

    // Esta función se encargará de crear el efecto de contraste sobre la imagen     
    function createCanvasOverlay(image){

        var canvas    = document.createElement(‘canvas’),
        canvasContext    = canvas.getContext("2d");
         
        //Igualamos los tamaños
        canvas.width = presentacion.width;
        canvas.height = presentacion.height;
         
        // Comienza el dibujo
        canvasContext.drawImage(image,0,0);
         

        // Tomamos los datos de imagen y los almacenamos en el arreglo imageData
        var imageData    = canvasContext.getImageData(0,0,canvas.width,canvas.height),
            data        = imageData.data;
         
        // Recorremos el arreglo y modificamos los valores RGB         
        for(var i = 0,z=data.length;i<z;i++){             
            data[i] = ((data[i] < 128) ? (2*data[i]*data[i] / 255) : (255 – 2 * (255 – data[i]) * (255 – data[i]) / 255));
            data[++i] = ((data[i] < 128) ? (2*data[i]*data[i] / 255) : (255 – 2 * (255 – data[i]) * (255 – data[i]) / 255));
            data[++i] = ((data[i] < 128) ? (2*data[i]*data[i] / 255) : (255 – 2 * (255 – data[i]) * (255 – data[i]) / 255));
            ++i;
        }
         
        // Colocamos la imagen modificada en el canvas
        canvasContext.putImageData(imageData,0,0);
         
        // Insertamos el canvas en el DOM
        image.parentNode.insertBefore(canvas,image);
    }
     
});

Gracias a este ejemplo podemos agregar un poco más de estilo y lucidez a nuestra presentación, jQuery nos permitirá realizar la mecánica de las transiciones y junto con Canvas embellecer el estilo particular de cada una de ellas.

Escrito por:
ISC Daniel Ernesto Navarro Herrera
OK HOSTING TEAM.