Hoverizr – Uma visão detalhada do plugin jQuery
Publicados: 2015-10-19Como um web designer, de tempos em tempos, você pode precisar fazer uma imagem em tons de cinza desbotar em cores ao passar o mouse. Portanto, a solução típica seria ter cada imagem dessaturada para obter o efeito de escala de cinza no Photoshop. Então, você teria que adicionar alguns divs extras e tags de imagem à marcação e, em seguida, adicionar alguma mágica do jQuery para fazer o fade in e out das imagens. Ou você poderia ter mesclado duas imagens em uma imagem maior com o dobro da altura e brincar com o posicionamento do plano de fundo nos arquivos CSS e Javascript.
Vamos dar uma olhada nos prós e contras de cada uma dessas duas soluções:
Prós:
- Se você usar um sprite de imagem (ambas as imagens em um arquivo), terá uma solicitação HTTP a menos para cada imagem.
Contras:
- Você tem que manipular cada imagem separadamente, o que significa que o cliente pode não conseguir atualizar imagens com esse efeito dinamicamente e é um processo demorado.
- Se você usar duas imagens, terá muitas solicitações HTTP. De qualquer forma, se as imagens forem grandes, o site ficará significativamente lento.
- Você precisa escrever o código jQuery para os efeitos hover e fade.
Ter que fazer isso todas as vezes realmente me surpreendeu, então procurei um método para fazer isso dinamicamente para cada imagem, sem a necessidade de perder a marcação semântica e ter que processar cada imagem.
Insira o elemento canvas. Com a introdução do HTML5, o elemento canvas tornou-se cada vez mais proeminente na comunidade. A maioria de vocês já deve ter ouvido falar do que a tela faz, então não vou entrar nisso aqui. O que eu precisava do canvas, eram seus recursos de manipulação de imagem. Você pode importar uma imagem dentro de sua tela e manipular o valor de cada pixel.
Isso era praticamente o que eu precisava para desenvolver meu plugin Hoverizr. Um plug-in jQuery que adiciona dinamicamente um efeito (escala de cinza, desfoque ou inversão de cor) às imagens de destino e inclui um efeito fade out/in ao passar o mouse. E, seguindo as tendências do web design, é totalmente responsivo.
Isto é o que conseguiremos com um belo fade out da versão manipulada no topo:
Você pode ver um exemplo ao vivo junto com demos dos outros efeitos do Hoverizr aqui.
Agora vamos mergulhar.
Hoverizr
Hoverizr é separado em três partes.
- Inicialize e crie os elementos necessários.
- Crie o elemento canvas e adicione o efeito.
- Adicione o efeito de fade in/out de foco para os elementos de imagem direcionados.
Hoverizr leva marcação simples como esta…
<img class="classname" src="imagem-arquivo" />
…e produz algo assim…
<div class="hoverizr-container"> <img class="classname" src="imagem-arquivo" /> <canvas class=".canv"></canvas> </div>
Parte 1. Inicialize e crie os elementos necessários
Para obter essa marcação e adicionar estilo essencial na tela, imagem e contêiner div, usei o jQuery abaixo dentro de uma função .each()
para afetar todas as imagens de destino:
$(this).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)
refere-se a cada uma das imagens direcionadas com nosso código na inicialização. Criamos uma div que envolve o elemento da imagem de destino, definimos sua posição relativa para ter a imagem e a tela em cima uma da outra. Em seguida, criamos o elemento canvas abaixo do elemento image e, finalmente, adicionamos algum estilo para posicionar a tela exatamente sobre a imagem.
Claro, no código do plugin algumas partes são diferentes.
Parte 2. Crie o Elemento canvas e adicione o Efeito
Vamos para a segunda parte, onde inicializamos a tela e acionamos a manipulação da imagem. Para os propósitos deste tutorial, explicarei apenas o efeito de tons de cinza.
Primeiramente, obtemos a largura e a altura em duas variáveis para usá-las na inicialização do canvas. Novamente, $(this)
refere-se a cada uma das imagens que o plugin tem como alvo.
var largura = $(this).width(); var altura = $(this).height();
Vamos criar nossa tela:
$(this).next('.canv').attr({"largura": largura "altura": altura}); var tela = $(this).next('.canv').get(0); var context = canvas.getContext("2d"); var imagem = $(this).get(0); context.drawImage(imagem, 0, 0);
Então definimos a largura e a altura da tela, pegamos o elemento na variável, pegamos o contexto e finalmente adicionamos nossa imagem dentro do contexto.
Agora para a mágica de manipulação de imagem!
experimentar { experimentar { var imgd = context.getImageData(0, 0, largura, altura) } pegar (e) { netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead"); var imgd = context.getImageData(0, 0, largura, altura) } } pegar (e) { throw new Error("não foi possível acessar os dados da imagem: " + e) } var pix = imgd.data;
Toda essa parte de tentar e pegar é habilitar privilégios para alguns navegadores que possuem medidas de segurança extras (nada crítico, é claro). Temos uma nova variável imgd
para armazenar os dados da imagem que salvamos dentro da variável pix
como um array.
Agora o efeito de tons de cinza:
for (var i = 0, n = pix.length; i < n; i += 4) { var tons de cinza = pix[i ] * .3 + pix[i+1] * .59 + pix[i+2] * .11; pix[i] = tons de cinza; // vermelho pix[i+1] = tons de cinza; // verde pix[i+2] = tons de cinza; // azul // i+3 é alfa (o quarto elemento) } context.putImageData(imgd, 0, 0);
Temos um padrão de repetição aqui. Cada quatro valores da matriz pix
representam um valor vermelho, verde, azul e alfa de um pixel. Obviamente, não queremos alterar o alfa, então vamos deixá-lo de fora. Em vez de apenas obter o valor médio dos três canais de cores, estou usando uma boa fórmula que obtive de um bom tutorial, HTML5 Canvas Image Effects: Black & White. Por fim, colocamos os novos dados da imagem de volta em nossa tela.
Parte 3. Adicione o efeito de fade in/out do hover para os elementos de imagem direcionados
Esta é a parte final e provavelmente a mais fácil. Fazendo a tela desaparecer para revelar a imagem original abaixo quando o mouse passa sobre ela.
this.parent('.hoverizr-container').hover(function() { $(this).children('.canv').stop(true,true).fadeOut("fast"); },função(){ $(this).children('.canv').stop(true,true).fadeIn("lento"); });
Novamente, isso representa o elemento da imagem de destino. A função hover é bastante auto-explicativa. Tudo o que fazemos é direcionar a tela, parar qualquer animação enfileirada e sair. A velocidade é definida como “rápida”, mas pode ser definida como “lenta” ou um valor numerado em milissegundos. Quando o foco é concluído, a segunda função ocorre, esmaecendo a tela novamente.
Problema conhecido
Uma medida de segurança dos navegadores pode surgir se você tentar usar imagens de outro domínio. Infelizmente, não há nada que possamos fazer no momento. As imagens precisam ser hospedadas no mesmo domínio da sua página.
Hoverizr vs. este tutorial
Hoverizr é um plugin que já tem tudo o que você precisa para conseguir esse efeito junto com efeitos de desfoque e inversão de cores. Ele tem muitas opções de personalização incluídas, como configuração de largura e altura, velocidade da configuração de fade in e out e muitas outras. O objetivo deste tutorial foi apenas mostrar como algumas das partes mais interessantes do Hoverizr funcionam. O código não funcionará como está, pois faz parte do plugin - despojado ao básico -.
Se você estiver interessado em usar o Hoverizr, melhorá-lo ou me dar alguma sugestão, sinta-se à vontade para dar uma olhada aqui: Hoverizr jQuery Plugin.