En que consiste y como hacerlo
En este tutorial vas a aprender como hacer un efecto morphing con dos imágenes (imágenes originales de www.pexels.com y modificadas posteriormente por mí). Haz clic en cada una de las imágenes que hay debajo de este párrafo para ver el efecto.




Código necesario
Funcionamiento
Este efecto hace uso de JavaScript y CSS, y utiliza para ello dos imágenes diferentes. Necesitamos, por tanto, dos imágenes. Una es la 'normal' y la otra es la 'modificada'. En efecto consiste en hacer una transición suave de la primera a la segunda imagen, de manera que de la impresión de que se transforma. Para que el efecto sea creíble, deben ser dos imágenes relativamente parecidas; No se trata de convertir un gato en un autobús. Puedes coger una imagen cualquiera, y editarla con un programa de imágenes tipo GIMP o Photoshop, y guardar la imagen modificada con distinto nombre. Entonces con este efecto lo que hacemos es pasar de la imagen original, a la imagen modificada (o viceversa).
A continuación posicionaremos las dos imágenes de manera que la segunda imagen quede superpuesta encima de la primera (utilizando CSS y el atributo position
), y a la segunda imagen le damos un valor de opacity
igual a 0.0 .
Después, utilizando JavaScript modificaremos el valor de opacity
de la segunda imagen para que poco a poco vaya tapando la primera imagen. Para ello utilizaremos la recursividad con ayuda de setTimeout
.
HTML necesario
Para aprender a utilizar y comprender como funciona este efecto, vamos a usar una web de ejemplo dedicada para esto, posteriormente ya puedes adaptarlo a tus necesidades concretas. Lo primero es el código HTML, que puede ser este:
<!DOCTYPE html> <html lang="es-ES"/> <head> <meta charset="UTF-8" /> <title> Efecto morphing con 2 imágenes </title> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link rel="stylesheet" href="css/estilos_pagina.css" media="screen" type="text/css" id="linkcss4"/> <script src="js/efecto_morph.js"> </script> </head> <body id="body_"> </body> </html>
En este ejemplo tenemos el HTML por un lado, el CSS lo tenemos en una hoja de estilos aparte llamada "estilos_pagina.css", y el JavaScript en un archivo js llamado "efecto_morph.js".
Necesitaremos dos imágenes con un id
para poder enviarlo como argumento a la función que hace la transformación.
Los grupos de dos imágenes van dentro de un bloque div, y estos a su vez en otro bloque div. Esto es para lograr posicionar las imágenes sin problemas. Tanto el contenedor principal como los secundarios tienen un position:relative
, y las imágenes un position absolute, consiguiendo así que se solapen sin que se muevan al resizar la página.
Todo este bloque de código HTML va dentro de la etiqueta body
de la página.
<div id="contenedorImgs"> <div id="cajaImgs"> <img src="img/pexels-simon-robben-614810.jpg" id="imgMorph1" alt="Haz clic en la imagen para transformar" title="Haz clic en la imagen para transformar" /> <img src="img/pexels-simon-robben-614810_amorfo.jpg" id="imgMorph2" alt="Haz clic en la imagen para transformar" title="Haz clic en la imagen para transformar" /> </div> <div id="cajaImgs2"> <img src="img/pexels-lukas-rodriguez-3551762.jpg" id="imgMorph3" alt="Haz clic en la imagen para transformar" title="Haz clic en la imagen para transformar" /> <img src="img/pexels-lukas-rodriguez-3551762_luz.jpg" id="imgMorph4" alt="Haz clic en la imagen para transformar" title="Haz clic en la imagen para transformar" /> </div> </div>
También podríamos haber añadido el estilo en una propiedad 'style' dentro de la etiqueta img, pero no es la manera más limpia de hacerlo. Si lo hiciésemos así, podríamos acceder a los estilos de manera más sencilla. El uso de document.styleSheets es algo más complejo y todos los navegadores no lo soportan igual.
Si añadimos el estilo dentro de la etiqueta img, normalmente accederemos a la propiedad opacity de la siguiente manera:
document.getElementById(id_de_la_imagen).style.opacity;
document.styleSheets[indice_de_la_hoja_de_estilos].cssRules[índice_de_la_regla_CSS].style.opacity;
Estos son los estilos que necesitaremos tener en una hoja de estilos aparte:
#contenedorImgs{ position:relative; margin:0px; width:100%; height:600px; } #cajaImgs{ position:relative; margin:0px; outline:0px solid red; width:100%; height:258px; } #cajaImgs2{ position:relative; margin:0px; width:100%; height:313px; } #imgMorph1{ width:300px; opacity:1.0; position:absolute; } #imgMorph2{ width:300px; opacity:0.0; position:absolute; } #imgMorph3{ width:300px; opacity:1.0; position:absolute; } #imgMorph4{ width:300px; opacity:0.0; position:absolute; }
Finalmente, este es el código JavaScript necesario para lograr el efecto morphing:
var img_; var img2_; var img3_; var img4_; var hojaEstilo; function init_(){ img_=document.getElementById("imgMorph1"); img2_=document.getElementById("imgMorph2"); img3_=document.getElementById("imgMorph3"); img4_=document.getElementById("imgMorph4"); img2_.addEventListener("click",function(){ morph1(img2_,4); },false); img4_.addEventListener("click",function(){ morph1(img4_,6); },false); hojaEstilo=document.styleSheets[0]; } window.addEventListener("load",init_,false); function morph1(imagen,reglaCss){ if(imagen!=null){ var opa=hojaEstilo.cssRules[reglaCss].style.opacity; if(parseFloat(opa)<1.0){ var suma=parseFloat(opa)+0.1; hojaEstilo.cssRules[reglaCss].style.opacity=parseFloat(suma); setTimeout(function(){ morph1(imagen,reglaCss); },50); }else{ setTimeout(function(){ morph2(imagen,reglaCss); },50); } } } function morph2(imagen,reglaCss){ if(imagen!=null){ var opa=hojaEstilo.cssRules[reglaCss].style.opacity; if(parseFloat(opa)<0.0){ var resta=parseFloat(opa)-0.1; hojaEstilo.cssRules[reglaCss].style.opacity=parseFloat(resta); setTimeout(function(){ morph2(imagen,reglaCss); },50); } } }
Como se puede ver, las funciones morph1
y morph2
reciben dos argumentos. El primero es la imagen sobre la que se quiere modificar el atributo opacity, el segundo argumento es un número y corresponde al indice de cssRules
, o sea, el número de regla a la que queremos acceder dentro de la hoja de estilos. La primera regla correspondería al número 0, por lo que el número 4 corresponde a la quinta regla. Dentro de la regla que señalamos, accedemos a la propiedad opacity
mediante style.opacity
.
Puedes ver el ejemplo funcionando aquí.