Hoverizr: una vista en profundidad del complemento jQuery
Publicado: 2015-10-19Como diseñador web, de vez en cuando, es posible que deba hacer que una imagen en escala de grises se desvanezca en color al pasar el mouse. Entonces, la solución típica sería desaturar cada imagen para lograr el efecto de escala de grises en Photoshop. Luego, tendría que agregar algunos divs adicionales y etiquetas de imagen al marcado y luego agregar algo de jQuery magic para atenuar las imágenes hacia adentro y hacia afuera. O bien, podría haber fusionado dos imágenes en una imagen más grande con el doble de altura y jugar con la posición de fondo en los archivos CSS y Javascript.
Echemos un vistazo a los pros y los contras de cada una de esas dos soluciones:
Ventajas:
- Si usa un sprite de imagen (ambas imágenes en un archivo), entonces tiene una solicitud HTTP menos para cada imagen.
Contras:
- Debe manipular cada imagen por separado, lo que significa que es posible que el cliente no pueda actualizar las imágenes con ese efecto dinámicamente y es un proceso que lleva mucho tiempo.
- Si usa dos imágenes, tendrá muchas solicitudes HTTP. De cualquier manera, si las imágenes son grandes, el sitio se vuelve significativamente lento.
- Debe escribir el código jQuery para los efectos de desplazamiento y desvanecimiento.
Tener que hacer eso cada vez realmente me superó, así que busqué un método para hacer esto dinámicamente para cada imagen, sin la necesidad de perder el marcado semántico y tener que procesar cada imagen.
Introduzca el elemento de lienzo. Con la introducción de HTML5, el elemento canvas se hizo cada vez más prominente en la comunidad. La mayoría de ustedes ya habrán oído hablar de lo que hace el lienzo, así que no entraré en eso aquí. Lo que necesitaba del lienzo era su capacidad de manipulación de imágenes. Puede importar una imagen dentro de su lienzo y manipular el valor de cada píxel.
Eso era más o menos lo que necesitaba para desarrollar mi complemento Hoverizr. Un complemento de jQuery que agrega dinámicamente un efecto (escala de grises, desenfoque o inversión de color) a las imágenes de destino e incluye un efecto de fundido de entrada/salida al pasar el mouse por encima. Y, siguiendo las tendencias del diseño web, es totalmente responsive.
Esto es lo que lograremos con un buen desvanecimiento de la versión manipulada en la parte superior:
Puede ver un ejemplo en vivo junto con demostraciones de los otros efectos de Hoverizr aquí.
Ahora vamos a sumergirnos.
hoverizr
Hoverizr está separado en tres partes.
- Inicialice y cree los elementos necesarios.
- Cree el elemento de lienzo y agregue el efecto.
- Agregue el efecto de aparición/desaparición gradual para los elementos de la imagen de destino.
Hoverizr toma un marcado simple como este...
<img class="nombre de clase" src="archivo de imagen" />
…y genera algo como esto…
<div class="contenedor-hoverizr"> <img class="nombre de clase" src="archivo de imagen" /> <clase lienzo=".canv"></lienzo> </div>
Parte 1. Inicializar y crear los elementos necesarios
Para lograr este marcado y agregar un estilo esencial en el lienzo, la imagen y el contenedor div, utilicé jQuery a continuación dentro de una función .each()
para afectar a todas las imágenes objetivo:
$(esto).wrap('<div class="hoverizr-container" />'); $(this).parent('.hoverizr-container').css({'position':'relative'}); $(this).parent('.hoverizr-container').append('<canvas class="canv"></canvas>'); $(this).next('.canv').css({'position':'absolute','top':'0','left':'0','z-index':10});
$(this)
se refiere a cada una de las imágenes seleccionadas con nuestro código en la inicialización. Creamos un div que envuelve el elemento de la imagen de destino, establecemos su posición relativa para tener la imagen y el lienzo uno encima del otro. Luego, creamos el elemento del lienzo debajo del elemento de la imagen y, finalmente, agregamos algo de estilo para colocar el lienzo exactamente encima de la imagen.
Por supuesto, en el código del complemento, algunas partes son diferentes.
Parte 2. Crea el elemento canvas y agrega el efecto
En la segunda parte, donde inicializaremos el lienzo y accionaremos la manipulación de la imagen. A los efectos de este tutorial, solo explicaré el efecto de escala de grises.
En primer lugar, obtenemos el ancho y la altura de dos variables para usarlas en la inicialización del lienzo. De nuevo, $(this)
se refiere a cada una de las imágenes a las que se dirige el complemento.
var ancho = $(este).ancho(); var alto = $(este).alto();
Vamos a crear nuestro lienzo:
$(esto).next('.canv').attr({"ancho": ancho ,"alto": alto}); var canvas = $(esto).next('.canv').get(0); var contexto = lienzo.getContext("2d"); var imagen = $(esto).get(0); context.drawImage(imagen, 0, 0);
Así que establecemos el ancho y el alto del lienzo, llevamos el elemento a la variable, obtenemos el contexto y finalmente agregamos nuestra imagen dentro del contexto.
¡Ahora la magia de la manipulación de imágenes!
tratar { tratar { var imgd = context.getImageData(0, 0, ancho, alto) } atrapar (e) { netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead"); var imgd = context.getImageData(0, 0, ancho, alto) } } atrapar (e) { throw new Error("no se puede acceder a los datos de la imagen: " + e) } var pix = imgd.datos;
Toda esta parte de prueba y captura es para habilitar privilegios a algunos navegadores que tienen medidas de seguridad adicionales (nada crítico, por supuesto). Tenemos una nueva variable imgd
para almacenar los datos de la imagen que luego guardamos dentro de la variable pix
como una matriz.
Ahora el efecto de escala de grises:
for (var i = 0, n = pix.length; i < n; i += 4) { var escala de grises = pix[i] * .3 + pix[i+1] * .59 + pix[i+2] * .11; pix[i] = escala de grises; // rojo pix[i+1] = escala de grises; // verde pix[i+2] = escala de grises; // azul // i+3 es alfa (el cuarto elemento) } contexto.putImageData(imgd, 0, 0);
Tenemos un patrón repetitivo aquí. Cada cuatro valores de la pix
de píxeles representan un valor rojo, verde, azul y alfa de un píxel. Obviamente, no queremos cambiar el alfa, así que lo dejaremos fuera. En lugar de simplemente obtener el valor promedio de los tres canales de color, estoy usando una buena fórmula que obtuve de un buen tutorial, HTML5 Canvas Image Effects: Black & White. Finalmente, volvemos a colocar los datos de la nueva imagen en nuestro lienzo.
Parte 3. Agregue el efecto de aparición/desaparición gradual para los elementos de la imagen de destino
Esta es la parte final y probablemente la más fácil. Hacer que el lienzo se desvanezca para revelar la imagen original debajo cuando se pasa el mouse por encima.
this.parent('.hoverizr-container').hover(function() { $(esto).niños('.canv').stop(verdadero,verdadero).fadeOut("rápido"); }, función () { $(esto).niños('.canv').stop(verdadero,verdadero).fadeIn("lento"); });
Nuevamente, esto representa el elemento de imagen de destino. La función de desplazamiento se explica por sí misma. Todo lo que hacemos es apuntar al lienzo, detener las animaciones en cola y eliminarlo. La velocidad se establece en "rápido", pero se puede establecer en "lento" o un valor numerado en milisegundos. Cuando finaliza el desplazamiento, se lleva a cabo la segunda función, desvaneciendo el lienzo nuevamente.
Problema conocido
Es posible que surja una medida de seguridad de los navegadores si intenta utilizar imágenes de otro dominio. Desafortunadamente, no hay nada que podamos hacer en este momento. Las imágenes deben estar alojadas en el mismo dominio que su página.
Hoverizr frente a este tutorial
Hoverizr es un complemento que ya tiene todo lo que necesita para lograr este efecto junto con efectos de desenfoque e inversión de color. Tiene muchas opciones de personalización incluidas, como la configuración de ancho y alto, la velocidad de la configuración de entrada y salida gradual y muchas otras. El propósito de este tutorial era solo mostrar cómo funcionan algunas de las mejores partes de Hoverizr. El código no funcionará tal como está, ya que es parte del complemento, reducido a lo básico.
Si está interesado en usar Hoverizr, mejorarlo o darme alguna sugerencia, no dude en consultarlo aquí: Hoverizr jQuery Plugin.