Este artigo apresenta o código de implementação do texto do Canvas para efeito de partícula e o compartilha com todos. Espero que seja útil para todos.
Desenhar texto através de partículas parece interessante, e combinar o movimento das partículas tornará o efeito ainda mais legal. Este artigo apresenta como desenhar texto através de partículas na tela.
Princípio de implementaçãoDe modo geral, é muito simples transformar o texto em exibição de partículas. O princípio de implementação é usar duas telas. Uma é a tela A que o usuário não pode ver, que é usada para desenhar o texto; aquele que o usuário pode ver A tela B obtida é usada para gerar partículas com base nos dados de texto de A. A representação visual é mostrada na figura:
Crie uma tela fora da telaO HTML só precisa ser colocado na tela principal:
<!-- Estrutura HTML--><html><head> ...</head><body> <canvas id=stage></canvas></body></html>
Em seguida, crie uma tela fora da tela e desenhe o texto:
const WIDTH = window.innerWidth; const HEIGHT = window.innerHeight; const offscreenCanvas = document.createElement('canvas'); offscreenCtx.font = '100px PingFang SC';offscreenCtx.textAlign = 'center';offscreenCtx.baseline = 'meio';offscreenCtx.fillText('Olá', WIDTH/2, HEIGHT/2);Nada acontece na página neste momento, mas você pode realmente imaginar isso na tela fora da tela. Deve ser como mostrado na figura:
Método principal getImageData Usando o método getImageData da tela, você pode obter um objeto ImageData , que é usado para descrever os dados de pixel na área especificada da tela. Em outras palavras, podemos obter a posição e a cor de cada pixel do texto Hello e gerar partículas no local especificado. O efeito final é que as partículas são agrupadas em texto.
Para obter informações de pixel, você precisa usar o atributo data do objeto ImageData , 像素点数量* 4 espalha os valores rgba de todos os pixels em uma matriz. Cada pixel possui quatro valores rgba. .
Suponha que eu selecione uma área 3 * 4 , então há um total de 12 pixels, cada pixel tem quatro valores rgba, então a matriz de dados terá 12 * 4 = 48 elementos.
Se você imprimir os dados, poderá ver o rgba desses pixels organizados da esquerda para a direita e de cima para baixo.
Claro, a área que queremos obter deve conter texto, então devemos obter toda a área fora da tela da tela:
const imgData = offscreenCtx.getImageData(0, 0, WIDTH, HEIGHT).data;Gerar partículas
Depois de obter o ImageData, percorrendo a matriz de dados, você pode determinar quais pontos na tela fora da tela são coloridos (no meio do texto) e quais pontos são incolores (não no texto) e colocar esses pixels coloridos. desça a posição, gere partículas na tela principal e pronto.
Primeiro crie uma classe de partículas:
class Partícula { construtor (opções = {}) { const { x = 0, y = 0, cor = '#fff', raio = 5} = opções; = y; this.color = color } desenhar (ctx) { ctx.beginPath(); Math.PI, falso); ctx.fillStyle = this.color;Percorrendo os dados, podemos determinar se o pixel está no texto com base na transparência, ou seja, se o quarto elemento em rgba não é 0.
partículas const = [];const skip = 4;for (var y = 0; y < HEIGHT; y += pular) { for (var x = 0; x < WIDTH; x += pular) { var opacityIndex = (x + y * LARGURA) * 4 + 3; if (imgData[opacityIndex] > 0) { partículas.push(new Particle({ x, y, raio: 1, cor: '#2EA9DF' })); Usamos particles para armazenar todas as partículas. A função de skip aqui é o tamanho do passo da travessia. Se digitalizarmos pixel por pixel, as partículas que eventualmente juntarão o texto serão muito densas. as partículas serão geradas serão mais esparsas.
Por fim, crie a tela principal e desenhe-a:
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 );}O efeito é o seguinte:
Para o código completo, consulte 01-basic-text-to-particles
Adicionar efeitosDepois de entender o princípio de implementação, o resto é adicionar alguns efeitos de animação às partículas. Primeiro, você pode dar às partículas algum deslocamento aleatório para evitar que pareçam muito organizadas.
partículas const = [];const skip = 4;for (var y = 0; y < HEIGHT; y += pular) { for (var x = 0; x < WIDTH; x += pular) { var opacityIndex = (x + y * WIDTH) * 4 + 3; if (imgData[opacityIndex] > 0) { // Adiciona deslocamento aleatório ao criar partículas partículas.push(new Partícula({ x: x + Math.random() * 6 - 3, y: y + Math.random() * 6 - 3, raio: 1, cor: '#2EA9DF' }));O efeito é o seguinte:
Se você deseja obter um efeito maior, como:
Como implementar isso? Primeiro, você precisa gerar aleatoriamente o tamanho das partículas. Isso requer apenas aleatoriedade do raio ao criar as partículas. Além disso, se quiser que o raio da partícula mude dinamicamente, você precisa distinguir o raio de renderização da partícula e o raio inicial e usar requestAnimationFrame para renderização de animação:
class Particle { construtor (opções = {}) { const { x = 0, y = 0, color = '#fff', raio = 5} = opções; radius; // Adiciona propriedade dynamicRadius} draw (ctx) { // ... ctx.arc(this.x, this.y, this.dynamicRadius, 0, 2 * Math.PI, false); Substitua por dynamicRadius // ... } update () { // TODO }}requestAnimationFrame(function loop() { requestAnimationFrame(loop); ctx.fillStyle = '#fff'; ctx.fillRect(0, 0, WIDTH, HEIGHT ); for (const partícula de partículas) { partícula.update(); Então a chave está em como implementar o método update das partículas. Suponha que queremos que o raio da partícula mude suave e ciclicamente de 1 a 5. É fácil pensar em funções trigonométricas, como:
O eixo horizontal deve estar relacionado ao tempo. Você pode manter uma variável e adicioná-la toda vez que chamar a atualização. Você também pode usar o carimbo de data/hora para calculá-la de forma simples. Um exemplo do método update é o seguinte:
update() { this.dynamicRadius = 3 + 2 * Math.sin(new Date() / 1000% 1000 * this.radius);}Para o código completo, consulte 02-texto-para-partículas-com-mudança de tamanho
O texto acima é todo o conteúdo deste artigo. Espero que seja útil para o estudo de todos. Também espero que todos apoiem a Rede VeVb Wulin.