Este artículo presenta el código de implementación del texto Canvas con efecto de partículas y lo comparte con todos. Espero que sea útil para todos. Los detalles son los siguientes:
Dibujar texto a través de partículas resulta interesante y hacer coincidir el movimiento de las partículas hará que el efecto sea aún más genial. Este artículo presenta cómo dibujar texto a través de partículas en un lienzo.
Principio de implementaciónEn términos generales, es muy sencillo realizar el efecto de convertir el texto en visualización de partículas. El principio de implementación es utilizar dos lienzos. Uno es el lienzo que el usuario no puede ver, que se utiliza para dibujar texto; uno que el usuario puede ver. El lienzo B obtenido se utiliza para generar partículas basadas en los datos de texto de A. La representación visual es como se muestra en la figura:
Crea un lienzo fuera de la pantallaSólo es necesario colocar HTML en el lienzo principal:
<!-- Estructura HTML--><html><head> ...</head><body> <canvas id=stage></canvas></body></html>
Luego crea un lienzo fuera de la pantalla y dibuja texto:
const WIDTH = window.innerWidth; const offscreenCtx = offscreenCanvas.getContext('2d'); offscreenCanvas.width = offscreenCanvas.height = ALTURA; offscreenCtx.font = '100px PingFang SC';offscreenCtx.textAlign = 'centro';offscreenCtx.baseline = 'medio';offscreenCtx.fillText('Hola', ANCHO / 2, ALTO / 2);No sucede nada en la página en este momento, pero puedes imaginarlo en el lienzo fuera de la pantalla. Debería verse como se muestra en la figura:
Método principal getImageData Usando el método getImageData del lienzo, puede obtener un objeto ImageData , que se usa para describir los datos de píxeles en el área especificada del lienzo. En otras palabras, podemos obtener la posición y el color de cada píxel del texto Hola y podemos generar partículas en la ubicación especificada. El efecto final es que las partículas se unen formando texto.
Para obtener información de píxeles, debe utilizar el atributo data del objeto ImageData , que distribuye los valores rgba de todos los píxeles en una matriz. Cada píxel tiene cuatro valores rgba. El número de esta matriz es 像素点数量* 4 .
Supongamos que selecciono un área de 3 * 4 , luego hay un total de 12 píxeles, cada píxel tiene cuatro valores rgba, por lo que la matriz de datos tendrá 12 * 4 = 48 elementos.
Si imprime los datos, podrá ver el rgba de estos píxeles ordenados de izquierda a derecha y de arriba a abajo.
Por supuesto, el área que queremos obtener debe contener texto, por lo que deberíamos obtener toda el área del lienzo fuera de pantalla:
const imgData = offscreenCtx.getImageData(0, 0, ANCHO, ALTO).datos;Generar partículas
Después de obtener ImageData, al atravesar la matriz de datos, puede determinar qué puntos en el lienzo fuera de la pantalla están coloreados (en el medio del texto) y qué puntos son incoloros (no en el texto), y escribir esos píxeles coloreados. baje la posición, luego genere partículas en el lienzo principal y estará listo para comenzar.
Primero crea una clase de partícula:
clase Partícula { constructor (opciones = {}) { const { x = 0, y = 0, color = '#fff', radio = 5} = opciones; = y; este.color = color; } dibujar (ctx) { ctx.beginPath(); Math.PI, falso); ctx.fillStyle = este.color; ctx.fill();Al recorrer los datos, podemos determinar si el píxel está en el texto en función de la transparencia, es decir, si el cuarto elemento en rgba no es 0.
partículas const = [];const skip = 4;for (var y = 0; y < ALTURA; y += saltar) { for (var x = 0; x < ANCHO; x += saltar) { var opacityIndex = (x + y * ANCHO) * 4 + 3; if (imgData[opacityIndex] > 0) { partículas.push(nueva partícula({ x, y, radio: 1, color: '#2EA9DF' })); } }} Usamos particles para almacenar todas las partículas. La función de skip aquí es el tamaño del paso del recorrido. Si escaneamos píxel por píxel, las partículas que eventualmente unirán el texto serán muy densas. Se generarán partículas más escasas.
Finalmente, crea el lienzo principal y dibújalo:
const canvas = document.querySelector('#stage');canvas.width = WIDTH;canvas.height = HEIGHT;const ctx = canvas.getContext('2d');for (const partícula de partículas) { partícula.draw(ctx );}El efecto es el siguiente:
Para obtener el código completo, consulte 01-texto-básico-a-partículas
Agregar efectosDespués de comprender el principio de implementación, el resto es agregar algunos efectos de animación a las partículas. Primero, puedes darle a las partículas algún desplazamiento aleatorio para evitar que se vean demasiado ordenadas.
partículas const = [];const skip = 4;for (var y = 0; y < ALTURA; y += saltar) { for (var x = 0; x < ANCHO; x += saltar) { var opacityIndex = (x + y * WIDTH) * 4 + 3; if (imgData[opacityIndex] > 0) { // Agrega desplazamiento aleatorio al crear partículas partículas.push(new Partícula({ x: x + Math.random() * 6 - 3, y: y + Math.random() * 6 - 3, radio: 1, color: '#2EA9DF' }) } }}El efecto es el siguiente:
Si desea lograr un efecto mayor, como por ejemplo:
¿Cómo implementar esto? Primero, debe generar aleatoriamente el tamaño de las partículas. Esto solo requiere aleatorizar el radio al crear las partículas. Además, si desea que el radio de la partícula cambie dinámicamente, debe distinguir el radio de representación de la partícula y el radio inicial, y usar requestAnimationFrame para la representación de la animación:
clase Partícula { constructor (opciones = {}) { const { x = 0, y = 0, color = '#fff', radio = 5} = opciones this.radius = radio; radio; // Agregar propiedad DynamicRadius} draw (ctx) { // ... ctx.arc(this.x, this.y, this.dynamicRadius, 0, 2 * Math.PI, false); Reemplazar con radiodinámico // ... } actualizar () { // TODO }}requestAnimationFrame(function loop() { requestAnimationFrame(loop); ctx.fillStyle = '#fff'; ctx.fillRect(0, 0, WIDTH, HEIGHT ); para (partícula constante de partículas) { partícula.update(); partícula.draw(ctx }}); Entonces la clave está en cómo implementar el método update de las partículas. Supongamos que queremos que el radio de las partículas cambie suave y cíclicamente de 1 a 5. Es fácil pensar en funciones trigonométricas, como por ejemplo:
El eje horizontal debe estar relacionado con el tiempo. Puede mantener una variable y agregarla cada vez que llame a la actualización. También puede usar la marca de tiempo para calcularla de manera simple. Un ejemplo del método update es el siguiente:
actualizar () { this.dynamicRadius = 3 + 2 * Math.sin(nueva fecha() / 1000 % 1000 * this.radius);}Para obtener el código completo, consulte 02-texto-a-partículas-con-cambio de tamaño
Lo anterior es el contenido completo de este artículo. Espero que sea útil para el estudio de todos. También espero que todos apoyen VeVb Wulin Network.