Em um projeto recente, a UI projetou uma animação de fundo com efeito de onda de água. No entanto, não havia animação GIF ou SVG. Tentei usar CSS para implementá-lo, mas o efeito da animação não era muito bom. usei curvas de Bézier para conseguir isso, pensei nos vários diagramas de formas de onda que tinha visto antes, então pensei em simulá-los brevemente usando imagens de funções trigonométricas.
1. Desenhe a imagem da função pecadoA expressão da função sin é a seguinte,
y=Asin(wx+φ)+h
Entre eles, A representa a amplitude, ω representa a frequência angular (ω=2π/T, T é o período da função), φ representa a fase inicial e h representa o comprimento de translação da imagem na direção positiva de o eixo y (deve-se notar aqui: h em matemática significa originalmente translação para cima, mas o sistema de coordenadas da tela é usado no canvas, ou seja, o canto superior esquerdo é a origem e h significa translação para baixo);
O código do desenho é o seguinte:
(1) Adicionar tag de tela
<canvas id=canvas></canvas>
(2) Adicione o estilo CSS e defina a largura e a altura da tela
html,corpo { preenchimento: 0; margem: 0; largura: 100%; altura: 100%;}tela { largura: 100% altura: 100%;}
(3) Desenhar imagem da função
var canvas = document.getElementById(canvas), ctx = canvas.getContext('2d'), width = canvas.width = canvas.offsetWidth, height = canvas.height = canvas.offsetHeight;//Declarar parâmetros var A=50, W=1/50, Q=0, H= altura / 2;//Método de desenho (função draw(){ ctx.clearRect(0, 0, largura, height);//Limpa a tela ctx.beginPath(); //Caminho inicial ctx.strokeStyle=#000; //Defina a cor da linha ctx.lineWidth = 1; /2) ; //Posição do ponto inicial para (seja x = 0; x <= largura; x++) {// Desenha a var de x correspondente a y = A*Math.sin(W*x+Q) +H ctx.lineTo(x, y) } ctx.stroke(); //Desenhe o caminho ctx.closePath();
Desta forma obtemos a seguinte imagem:
2. Adicione animação à imagem funcionalO que é obtido acima é uma imagem de função estática, e as formas de onda ou ondas de água que geralmente vemos mudam continuamente com o tempo. Aqui precisamos usar o parâmetro fase φ na etapa anterior, (js é Q no código), podemos continuamente. aumentar ou diminuir φ com o tempo para obter imagens diferentes em momentos diferentes; usar window.requestAnimationFrame para implementar animação de quadro;
Modifique o código acima para:
var canvas = document.getElementById(canvas), ctx = canvas.getContext('2d'), width = canvas.width = canvas.offsetWidth, height = canvas.height = canvas.offsetHeight;//Declarar parâmetros var A=50, W=1/50, Q=0, H= altura / 2;//Método de desenho (função draw(){ ctx.clearRect(0, 0, largura, height);//Limpa a tela ctx.beginPath(); //Caminho inicial ctx.strokeStyle=#000; //Defina a cor da linha ctx.lineWidth = 1; /2) ; //Posição do ponto inicial para (seja x = 0; x <= largura; x++) {// Desenha a var de x correspondente a y = A*Math.sin(W*x+Q) +H ctx.lineTo(x, y) } ctx.stroke(); //Desenhe o caminho ctx.closePath();
O efeito é o seguinte (software de captura de tela Zhazha):
3. Desenhe um caminho preenchido completoEmbora o caminho acima esteja fechado, ele não atende à parte que precisamos preencher. O efeito do preenchimento direto é o seguinte:
O caminho completo preenchido deve ficar assim:
Após fechar o caminho, crie uma cor gradiente como cor de preenchimento. O código é o seguinte:
var lingrad = ctx.createLinearGradient(0,0,width,0); lingrad.addColorStop(0, 'rgba(0,186,128,0.8)'); desenhar(){ window.requestAnimationFrame(desenhar); ctx.clearRect(0, 0, largura, altura); ctx.strokeStyle=#000; =velocidade; for (seja x = 0; x <= largura; x++) { var y = A*Math.sin(W*x+Q) +H; .closePath();})()
O efeito é o seguinte:
4. Melhore a animação das ondas de água1. Primeiro, você pode sobrepor uma forma de onda de frequência mais alta à forma de onda acima para torná-la irregular.
var s = 0,1*Math.sin(x/150)+1;var y = A*Math.sin(W*x+Q) +H;y=y*s;
2. Adicione outra forma de onda com diferentes mudanças de fase, e seu preenchimento de gradiente é oposto à direção do gradiente anterior para formar um efeito de sombra sobreposto e definir o efeito de sobreposição de caminho globalCompositeOperation;
var canvas = document.getElementById(canvas), ctx = canvas.getContext('2d'), width = canvas.width = canvas.offsetWidth, height = canvas.height = canvas.offsetHeight;var A=30, W=1 / 200, Q=0, H= altura / 2;var A2=30, W2=1/300, Q2=0, H2= altura / 2;var velocidade=-0,01;var velocidade2=-0,02;var lingrad = ctx.createLinearGradient(0,0,largura,0);lingrad.addColorStop(0, 'rgba(0,186,128,0,8)');lingrad.addColorStop( 1, 'rgba(111.224.195,1)'); var lingrad2 = ctx.createLinearGradient(0,0,width,0);lingrad2.addColorStop(0,'rgba(111,224,195,1)');lingrad2.addColorStop(1, 'rgba(0,186,128,0.8)'); desenhar(){ window.requestAnimationFrame(desenhar); ctx.clearRect(0, 0, width, height); = 0; x <= largura x++) { var s = 0,1*Math.sin(x/150)+1; A*Math.sin(W*x+Q) +H; y=y*s; .fill(); ctx.closePath() //Definir o efeito de sobreposição ctx.globalCompositeOperation = destination-over //Desenhe a segunda forma de onda ctx.beginPath(); ctx.fillStyle = lingad2; Q2+=velocidade2; for (seja x = 0; x < largura; x++) { var y = A2*Math.sin(x*W2+Q2) +H2; ; } ctx.lineTo(largura,altura ctx.lineTo(0,altura()); ctx.closePath();})()
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.