Tabla de contenido
Una vez más aquí. Sigo poniéndome al día con las cosas que algunos usuarios me han consultado durante las pasadas navidades. En esta ocasión vengo a dejar un pequeño artículo sobre el que me me han preguntado (hace ya unas pocas semanas). El caso es que el usuario estaba interesado en crear un efecto matrix utilizando canvas.
La verdad es que estuve apunto de no contestarle, ya que internet está plagado de diferentes formas para realizar este efecto en una web. Pero buscando un poco entre mis cosas, encontré el código que vamos a ver a continuación, y que puede ser que le sirva al usuario (si es que todavía le interesa).
Crea tu propio efecto Matrix
Bueno, como decía, este código tiene algún tiempo. Lo he intentado adaptar a los tiempos que corren, pero me imagino que todavía le quedan cosas por pulir. Por eso, quien esté interesado en utilizarlo (a saber para qué), pues que se moleste en pulirlo. El código que vamos a ver a continuación, se ha dividido en tres archivos.
Archivo index.html
El código que vamos a ver a continuación, es una página HTML que es donde vamos a mostrar un efecto estilo Matrix con texto y emojis. Este archivo HTML tiene una estructura estándar, con una cabecera «head» que incluye información sobre la página, como el título y los archivos CSS y el favicon de turno.
En el cuerpo «body» se encuentra un div con un texto que aparecerá a los 3 segundos de cargar la página, y cuatro divs con emojis que mostraremos en las esquinas de la ventana del navegador. Además, también veremos un canvas en el que se dibujan las letras del fondo. En este archivo también encontraremos dos scripts, uno para cargar el JavaScript con el que vamos a generar el efecto Matrix, y otro para hacer aparecer el texto después de 3 segundos.
El código a guardar dentro del archivo index.html es el siguiente:
<!DOCTYPE html> <html lang="es"> <head> <meta charset="UTF-8"/> <meta http-equiv="X-UA-Compatible" content="IE=edge"/> <meta name="viewport" content="width=device-width, initial-scale=1.0"/> <title>Efecto Matrix</title> <link rel="icon" type="image/jpg" href="img/favicon.ico"/> <link rel="stylesheet" type="text/css" href="./css/style.css"/> </head> <body> <!-- Texto que aparece --> <div id="texto" class="titulo">entreunosyceros.net</div> <!-- Emojis esquineros --> <div class="emoji1">☠️</div> <div class="emoji2">☠️</div> <div class="emoji3">☠️</div> <div class="emoji4">☠️</div> <!-- canvas sobre el se dibujan las letras del fondo --> <canvas width="800" height="800" id="canvas"></canvas> <script src="./js/matrix.js"></script> <!-- Función para hacer aparecer el texto --> <script> window.onload = function() { setTimeout(function() { document.getElementById("texto").style.display = "block"; }, 3000); }; </script> </body> </html>
Archivo style.css
El código que vamos a añadir dentro del archivo style.css, es código es CSS (Cascading Style Sheets). Este se utiliza para definir la apariencia visual de una página web. Por eso, dentro vamos a pegar el siguiente código, con el que dar un poco de estilo a lo que veremos al ejecutar el archivo index.html:
body { margin: 0; display: flex; align-items: center; justify-content: center; min-height: 100vh; } /* Texto que aprece en fadedIn */ #texto { display: none; text-align: center; font-weight: bold; left: 50%; transform: translate(-50%, -50%); opacity: 0.5; margin: 0 auto; position: absolute; z-index: 1; /* Agrega un nivel de profundidad superior que el que tiene canvas */ animation: fadeIn 5s; /* Animaciónde 5 segundos*/ } @keyframes fadeIn { 0% { opacity: 0; } 100% { opacity: 0.5; } /* Solo carga hasta el 50% */ } /* Canvas en el que se dibuja el fondo */ #canvas { position: absolute; z-index: 0; /* Agrega un nivel de profundidad inferior que el que tiene el texto */ } /* Posición emojis esquineros */ .emoji1 { position: fixed; top: 0; left: 0; z-index: 19; opacity: 0.3; } .emoji2 { position: fixed; top: 0; right: 0; z-index: 19; opacity: 0.3; } .emoji3 { position: fixed; bottom: 0; left: 0; z-index: 19; opacity: 0.3; } .emoji4 { position: fixed; bottom: 0; right: 0; z-index: 19; opacity: 0.3; } /*Título*/ .titulo { display: inline-block; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; border: none; font: normal 62px / normal "Sans-Serif", Helvetica, Comic Sans MS; color: rgb(14, 165, 0); text-decoration: none; white-space: pre; text-shadow: 0 0 10px rgb(0, 94, 23), 0 0 20px rgba(0, 94, 23), 0 0 30px rgba(0, 94, 23), 0 0 40px #011d00, 0 0 70px #011d00, 0 0 80px #011d00, 0 0 100px #001d05; -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%; } .titulo:hover { text-shadow: 0 0 10px rgb(0, 34, 7), 0 0 20px rgba(0, 34, 7), 0 0 30px rgba(0, 34, 7), 0 0 40px #000000, 0 0 70px #000000, 0 0 80px #000000, 0 0 100px #000000; }
Archivo script.js
El código que vamos a incluir en este archivo, es una animación de caída de caracteres al estilo «Matrix» utilizando un canvas HTML. El el código obtenemos un elemento HTML con id «canvas» y se crea un contexto de dibujo en 2D en él. Se establece el ancho y altura del canvas a la anchura y altura de la ventana del navegador.
También vamos a crear una matriz de caracteres que serán utilizados en la animación. Se define una clase «Matrix» que representa un objeto en la animación con una posición «x» e «y«, y un método para dibujar el objeto en el canvas. La función «actualizar» se ejecuta en un bucle para actualizar la animación. Si la cantidad de objetos «Matrix» en la matriz «codigoArray» es menor que la cantidad definida en «conteoCodigo», se crea un nuevo objeto «Matrix» con posición x e y aleatorias y se agrega a la matriz.
const canvas = document.getElementById("canvas"); // Obtiene un elemento HTML con id "canvas" const ctx = canvas.getContext('2d'); // Crea un contexto de dibujo en 2D en el elemento canvas canvas.width = window.innerWidth; // Establece el ancho del canvas en la anchura de la ventana del navegador canvas.height = window.innerHeight; // Establece la altura del canvas en la altura de la ventana del navegador const arrayCaracteres = [ "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "ñ", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "£", "¥", "§", "¤","€","$","±","µ","Ø","×","≥","Æ","☠" ]; // Matriz de caracteres que serán utilizados en la animación const codigoArray = []; // Matriz vacía para almacenar objetos const conteoCodigo = 100; // Constante que representa la cantidad de objetos "Matrix" que se crearán const fontSize = 18; // Tamaño de la fuente para lo caracteres const numeroColumna = canvas.width / fontSize; // Constante que representa el número de columnas que caben en el canvas basándose en el tamaño de la fuente let frame = 0; // Variable para contar el número de frames en la animación // Clase que representa un objeto "Matrix", con un constructor que recibe la posición x e y, y un método para dibujar el objeto en el canvas class Matrix { constructor(x, y) { this.y = y this.x = x } dibujar(ctx) { this.valor = arrayCaracteres[Math.floor(Math.random() * (arrayCaracteres.length - 1))].toUpperCase() // Asigna un valor aleatorio de un carácter de "arrayCaracteres" en mayúscula this.velocidad = Math.random() * fontSize * 3 / 4 + fontSize * 3 / 4 // Asigna un valor aleatorio que será usado para mover la posición vertical del texto. ctx.fillStyle = "rgba(0,255,0)" // Establece el color de relleno de la fuente en verde ctx.font = fontSize + "px comic-sans" // Establece el tamaño y tipo de fuente como "comic-sans" con tamaño 18px ctx.fillText(this.valor, this.x, this.y) // Dibuja el texto con las propiedades previamente establecidas en las coordenadas (x, y) this.y += this.velocidad // aumenta la posición vertical del texto según la velocidad previamente establecida // Si this.y es mayor a la altura de canvas, se re-calculan las coordenadas x e y y la velocidad se vuelve a asignar. if (this.y > canvas.height) { this.x = Math.floor((Math.random() * numeroColumna) * fontSize) this.y = 0 this.velocidad = (-Math.random() * fontSize * 3) / 4 + (fontSize * 3) / 4 } } } // Se define una función "actualizar" que se ejecuta en un bucle para actualizar la animación let actualizar = () => { if (codigoArray.length < conteoCodigo) { // Se comprueba si la cantidad de objetos "Matrix" es menor que la cantidad definida en "conteoCodigo" let matrix = new Matrix(Math.floor(Math.random() * numeroColumna) * fontSize, 0) // Se crea un nuevo objeto "Matrix" con posición x e y aleatorias codigoArray.push(matrix) // Se agrega el nuevo objeto "Matrix" a la matriz "codigoArray" } ctx.fillStyle = "rgba(0,0,0,0.05)" // Se establece el color y la transparencia para rellenar el canvas ctx.fillRect(0, 0, canvas.width, canvas.height) // Se dibuja un rectángulo en el canvas para cubrirlo y crear un efecto de fundido // solo se dibujara cada segundo caracter for (let i = 0; i < codigoArray.length && frame % 2 == 0; i++) { codigoArray[i].dibujar(ctx) // Invoca el método dibujar de cada elemento del arreglo codigoArray, que se encarga de mostrar en pantalla cada caracter en el canvas } requestAnimationFrame(actualizar) // Llama a la función actualizar en cada frame, para mantener la animación continua frame++ // Aumenta en uno el valor de la variable frame en cada iteración del bucle } actualizar(); // Una llamada a la función actualizar. Esta función se encarga de iniciar la animación y mantenerla actualizada
Y con esto ya tendremos listo el «cansino» y famoso efecto matrix. Una vez guardados todos los códigos en sus correspondientes archivos, solo queda ejecutar el index.html para ver el resultado. Si quieres verlo funcionando, puedes hacerlo en la sección de ejemplos de esta página web.
2 Comentarios
Funciona perfectamente. Pero quisiera bajarle la velocidad en general de todo el efecto. No consigo hacerlo por mucho que modifique los parametros referentes a la velocidad. Me puedes ayudar?
Hola. Prueba a cambiar en la última función del código JS:
// solo se dibujara cada segundo caracter
for (let i = 0; i < codigoArray.length && frame % 2 == 0; i++) { codigoArray[i].dibujar(ctx) // Invoca el método dibujar de cada elemento del arreglo codigoArray, que se encarga de mostrar en pantalla cada caracter en el canvas }
por
// Solo se dibujará cada cuarto carácter
for (let i = 0; i < codigoArray.length && frame % 4 == 0; i++) { codigoArray[i].dibujar(ctx) }
Cambiar el 2 por el 4 debería hacer que el efecto se viese a mitad de velocidad que la actual. Un valor mayor hará que la animación sea más lenta, mientras que un valor menor la acelerará. Pero todo esto no he podido probarlo, te digo esto por lo que recuerdo. La semana próxima lo probaré y te lo confirmo (si es que no lo confirmas o desmientes tú antes). Salu2.