Tabla de contenido
Una vez más aquí. Hoy vengo a dejar otro pequeño artículo sobre una duda que un usuario me comentó esta misma semana. El caso es que esta persona me preguntaba cómo se podría aplicar un efecto morphing con texto. Y pensándolo un poco, me di cuenta de que no conocía ningún programa que hiciese esto, aun que esto tampoco quiere decir que no exista. Tan solo es mi propia ignorancia.
Bueno, el caso es que como no sabía decirle de ninguna web que le hiciese este trabajo, pues decidí hacerlo yo mismo con un poco de HTML, CSS y JavaScript. Por si alguien todavía no conoce esto (cosa que sinceramente dudo), decir que el concepto de morphing designa la transformación fluida de una figura en otra. Para lograr un efecto de morphing, se necesitan dos imágenes que se superponen, aun que en este caso utilizaremos palabras.
El objetivo general es generar una transición realista desde la imagen de partida hasta la imagen final. Por ejemplo, esta técnica se usa en el morphing de caras para alterar un rostro y mostrar el proceso de envejecimiento, etc… Para aplicar el morphing entre dos caras, por ejemplo, se seleccionan puntos característicos, como la boca y los ojos, y se comparan con la imagen final. Aun que en este caso utilizaremos tan solo CSS y algunas líneas de JavaScript, para crear algo como esto con texto.
Morphing con texto, el código necesario

Para crear este ejemplo de morphing con texto, solo necesitaremos tres archivos. El primero de ellos será el archivo .html, en el que añadiremos la estructura para ver el texto. Después necesitaremos el archivo .css, que nos servirá para añadir algunas reglas necesarias. Para terminar, solo quedará crear un archivo .js, que será en el que sucederá todo. En este último archivo, será en el lugar en en el que añadiremos el texto que queremos que se muestre.
Archivo index.html
En este archivo vamos a guardar una plantilla HTML básica, que será la que utilizaremos para crear un efecto de morphing con texto, utilizando CSS y JavaScript. Dentro del archivo, basta con guardar las siguientes líneas:
<!DOCTYPE html> <html lang="es"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Crear Morphing de Texto</title> <link rel="stylesheet" href="./style.css" /> </head> <body> <div class="titulo" title="made in entreunosyceros.net"></div> <div id="container"> <span id="text1"></span> <span id="text2"></span> </div> <svg id="filters"> <defs> <filter id="threshold"> <feColorMatrix in="SourceGraphic" type="matrix" values="1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 255 -100"/> </filter> </defs> </svg> <script src="./script.js"></script> </body> </html>
Dentro del <body>
encontramos el contenido principal de la página. En este caso, hay dos elementos <div>
que contienen elementos <span>
con los identificadores «text1» y «text2». Estos son los lugares donde se mostrarán los textos.
También hay un elemento <svg>
con el identificador «filters» que contiene un filtro SVG que se utilizará para crear el efecto de morphing de texto.
Por último, se incluye un archivo de JavaScript externo llamado «script.js» que se utiliza para implementar la funcionalidad del morphing de texto.
Archivo style.css
Dentro de este archivo style.css, vamos a guardar este código es un conjunto de estilos CSS, para una página web que contiene un de efecto morphing en un texto.
body { margin-top: 10em; display: grid; justify-content: center; align-items: center; background-color: #afafaf; } #container { /* Contenedor donde situar el texto */ position: absolute; margin: auto; width: 90vw; height: 100pt; top: 0; bottom: 0; border: 1px solid #ffffff; padding: 2%; transform: perspective(500px) translateZ(-100px); /* Este filtro es gran parte de la magia. Si se comenta el texto solo se desvanece */ filter: url(#threshold) blur(0.8px); } /* Estilo de los textos */ #text1, #text2 { position: absolute; width: 100%; display: inline-block; text-align: center; color:#fff; font-family: 'Arial', sans-serif; font-size: 100pt; font-weight: bold; transform: perspective(500px) translateZ(-80px); user-select: none; } /*Título*/ .titulo { box-sizing: border-box; padding: 10px; border: none; font: normal 38px / normal "Warnes", Helvetica, sans-serif; color: rgba(255, 255, 255, 1); text-align: center; white-space: pre; text-shadow: 0 0 10px rgb(255, 0, 0), 0 0 20px rgba(255, 0, 0), 0 0 30px rgba(255, 0, 0), 0 0 40px #727272, 0 0 70px #727272, 0 0 80px #4e4e4e, 0 0 100px #2b2b2b; -webkit-transition: all 200ms cubic-bezier(0.42, 0, 0.58, 1); -moz-transition: all 200ms cubic-bezier(0.42, 0, 0.58, 1); -o-transition: all 200ms cubic-bezier(0.42, 0, 0.58, 1); transition: all 200ms cubic-bezier(0.42, 0, 0.58, 1); width: 100%; margin-top: 10px; margin-bottom: 10px; } .titulo:hover { text-shadow: 0 0 10px rgb(73, 73, 73), 0 0 20px rgb(56, 56, 56), 0 0 30px rgb(48, 48, 48), 0 0 40px #5c5c5c, 0 0 70px #000000, 0 0 80px #000000, 0 0 100px #000000; } /* Texto a mostrar encima del morphing del texto */ .titulo::after { content: "Morphing De Texto"; }
El primer bloque de código establece algunos estilos generales para el cuerpo de la página, incluyendo un margen superior de 10em, un fondo gris claro, y un sistema de rejilla centrado en la página.
El segundo bloque de código establece estilos específicos para el contenedor de texto (#container). El contenedor se posiciona de manera absoluta y se centra en la página. El ancho del contenedor es del 90% del ancho de la ventana y su altura es de 100pt. Además se añade un borde blanco de 1px y un relleno del 2%. Se utiliza la propiedad «transform» para aplicar una perspectiva de 500px y desplazar el contenedor -100px en el eje z (profundidad). También se aplica un filtro CSS que desvanece el texto utilizando un mapa de bits de umbral (#threshold) y un desenfoque de 0,8px.
El tercer bloque de código establece los estilos para el texto en sí. Este texto se divide en dos elementos HTML con los ID «text1» y «text2«. Ambos elementos se posicionan absolutamente y se centran horizontalmente utilizando «text-align: center«. El color del texto es blanco, la fuente utilizada es Arial con un tamaño de 100pt y negrita. También se establece «user-select: none» para evitar que el texto sea seleccionable por el usuario.
El cuarto bloque de código establece los estilos para el título. El título se define con la clase «titulo», y es el que hace tiempo vengo utilizando en todos los ejemplos, así que no lo voy a explicar más.
El sexto bloque de código se utiliza el selector «::after» para agregar contenido al final del elemento con la clase «titulo«.
Archivo script.js
Este código es una implementación en JavaScript del efecto de morphing de texto que se utiliza en la página web, y utiliza la biblioteca del DOM para acceder y manipular los elementos HTML.
Para que este ejemplo funcione correctamente, dentro del archivo script.js, solo tendremos que guardar las siguientes líneas de código:
const elts = { text1: document.getElementById("text1"), text2: document.getElementById("text2") }; // Se establecen algunas variables iniciales, como el índice de texto actual, el tiempo actual, el tiempo de morph y el tiempo entre transiciones (cooldown) const texts = [ "entreunosyceros.net", "Aprendiendo", "Y", "Compartiendo", "Desde", "La", "Red" ]; const morphTime = 0.8; const cooldownTime = 0.5; let textIndex = texts.length - 1; let time = new Date(); let morph = 0; let cooldown = cooldownTime; elts.text1.textContent = texts[textIndex % texts.length]; elts.text2.textContent = texts[(textIndex + 1) % texts.length]; /* Realiza la transición de morphing */ function doMorph() { morph -= cooldown; cooldown = 0; let fraction = morph / morphTime; if (fraction > 1) { cooldown = cooldownTime; fraction = 1; } setMorph(fraction); } /* Establece la opacidad y el desenfoque de los elementos de texto y actualiza el contenido de cada elemento */ function setMorph(fraction) { elts.text2.style.filter = `blur(${Math.min(8 / fraction - 8, 100)}px)`; elts.text2.style.opacity = `${Math.pow(fraction, 0.4) * 100}%`; fraction = 1 - fraction; elts.text1.style.filter = `blur(${Math.min(8 / fraction - 8, 100)}px)`; elts.text1.style.opacity = `${Math.pow(fraction, 0.4) * 100}%`; elts.text1.textContent = texts[textIndex % texts.length]; elts.text2.textContent = texts[(textIndex + 1) % texts.length]; } /* Restablece los elementos de texto a su estado inicial */ function doCooldown() { morph = 0; elts.text2.style.filter = ""; elts.text2.style.opacity = "100%"; elts.text1.style.filter = ""; elts.text1.style.opacity = "0%"; } /* Realiza una animación suave llamando a "doMorph" y "doCooldown" según sea necesario */ function animate() { /*La animación se realiza a través de la función requestAnimationFrame que se llama continuamente para actualizar la pantalla a la tasa de refresco del dispositivo.*/ requestAnimationFrame(animate); let newTime = new Date(); let shouldIncrementIndex = cooldown > 0; let dt = (newTime - time) / 1000; time = newTime; cooldown -= dt; if (cooldown <= 0) { if (shouldIncrementIndex) { textIndex++; } doMorph(); } else { doCooldown(); } } animate();
El primer bloque de código crea un objeto elts
que contiene los elementos de texto HTML que se van a utilizar para el morphing. Estos elementos se obtienen del DOM utilizando el método getElementById()
.
El segundo bloque de código establece algunas variables iniciales, como el índice de texto actual, el tiempo actual, el tiempo de morph y el tiempo entre transiciones (cooldown). También se define un array de textos que se van a utilizar para el morphing.
La función doMorph()
realiza la transición de morphing ajustando la opacidad y el desenfoque de los elementos de texto, utilizando una fracción de morph y el tiempo de morph establecidos previamente. La función setMorph()
establece la opacidad y el desenfoque de los elementos de texto y actualiza el contenido de cada elemento.
En cuanto a la función doCooldown(), decir que
restablece los elementos de texto a su estado inicial.
La función animate()
realiza una animación suave llamando a doMorph()
y doCooldown()
según sea necesario. La animación se realiza a través de la función requestAnimationFrame()
que se llama continuamente para actualizar la pantalla a la tasa de refresco del dispositivo. La animación se basa en el tiempo actual y el tiempo transcurrido desde la última actualización.
Ejemplo y repositorio en GitHub
Y con esto ya tendremos listo este pequeño ejemplo de morphing con texto. Para ejecutarlo no habrá que guardar todos los archivos dentro de la misma carpeta. Después bastará con hacer doble clic en el archivo index.html, para que se abra en nuestro navegador web favorito. Pero si quieres ver funcionando este pequeño ejemplo, solo tienes que dirigirte a la sección de ejemplos de esta web.
Para descargar el código fuente, puedes hacerlo desde este artículo, o desde el repositorio en GitHub donde alojé este proyecto.