En un proyecto reciente, la interfaz de usuario diseñó una animación de fondo con un efecto de onda de agua. Sin embargo, no había animación gif o svg. Intenté usar CSS para implementarla, pero el efecto de animación no fue muy bueno, lo verifiqué en línea. Usé curvas de Bézier para lograrlo, pensé en los diversos diagramas de formas de onda que había visto antes, así que pensé en simularlo brevemente usando imágenes de funciones trigonométricas.
1. Dibuja la imagen de la función pecado.La expresión de la función sin es la siguiente,
y=Asin(wx+φ)+h
Entre ellos, A representa la amplitud, ω representa la frecuencia angular (ω = 2π/T, T es el período de la función), φ representa la fase inicial y h representa la longitud de traslación de la imagen en la dirección positiva de el eje y (Cabe señalar aquí: h en matemáticas originalmente significa traducción hacia arriba, pero el sistema de coordenadas de la pantalla se usa en lienzo, es decir, la esquina superior izquierda es el origen y h significa traducción hacia abajo);
El código de dibujo es el siguiente:
(1) Agregar etiqueta de lienzo
<canvas id=canvas></canvas>
(2) Agregue estilo CSS y establezca el ancho y alto del lienzo
html,cuerpo {relleno: 0; margen: 0; ancho: 100%; alto: 100%;}lienzo {ancho: 100%;
(3) Dibujar imagen de función
var lienzo = document.getElementById(canvas), ctx = lienzo.getContext('2d'), ancho = lienzo.width = lienzo.offsetWidth, alto = lienzo.height = lienzo.offsetHeight;//Declarar parámetros var A=50, W=1/50, Q=0, H= alto/2;//Método de dibujo (función draw(){ ctx.clearRect(0, 0, ancho, height);//Borrar el lienzo ctx.beginPath(); //Iniciar ruta ctx.strokeStyle=#000; //Establecer el color de la línea ctx.lineWidth = 1 //Establecer el ancho de la línea ctx.moveTo(0, height; /2) ; //Posición del punto inicial para (let x = 0; x <= width; x++) {// Dibujar la var de x correspondiente a y = A*Math.sin(W*x+Q) +H ctx.lineTo(x, y) } ctx.stroke(); //Dibujar la ruta ctx.closePath() //Cerrar la ruta})();
De esta manera obtenemos la siguiente imagen:
2. Agregar animación a la imagen funcional.Lo que se obtiene arriba es una imagen de función estática, y las formas de onda u ondas de agua que generalmente vemos cambian continuamente con el tiempo. Aquí necesitamos usar el parámetro fase φ en el paso anterior (js es Q en el código), podemos hacerlo continuamente. aumente o disminuya φ con el tiempo para obtener diferentes imágenes en diferentes momentos; use window.requestAnimationFrame para implementar la animación de cuadros;
Modifique el código anterior para:
var lienzo = document.getElementById(canvas), ctx = lienzo.getContext('2d'), ancho = lienzo.width = lienzo.offsetWidth, alto = lienzo.height = lienzo.offsetHeight;//Declarar parámetros var A=50, W=1/50, Q=0, H= alto/2;//Método de dibujo (función draw(){ ctx.clearRect(0, 0, ancho, height);//Borrar el lienzo ctx.beginPath(); //Iniciar ruta ctx.strokeStyle=#000; //Establecer el color de la línea ctx.lineWidth = 1 //Establecer el ancho de la línea ctx.moveTo(0, height; /2) ; //Posición del punto inicial para (let x = 0; x <= width; x++) {// Dibujar la var de x correspondiente a y = A*Math.sin(W*x+Q) +H ctx.lineTo(x, y) } ctx.stroke(); //Dibujar la ruta ctx.closePath() //Cerrar la ruta})();
El efecto es el siguiente (software de captura de pantalla Zhazha):
3. Dibuja un camino completo y lleno.Aunque el camino anterior está cerrado, no cumple con la parte que necesitamos llenar. El efecto del llenado directo es el siguiente:
La ruta completa debería verse así:
Después de cerrar la ruta, cree un color degradado como color de relleno. El código es el siguiente:
var lingrad = ctx.createLinearGradient(0,0,width,0); lingrad.addColorStop(0, 'rgba(0,186,128,0.8)'); lingrad.addColorStop(1, 'rgba(111,224,195,1)'); dibujar(){ ventana.requestAnimationFrame(dibujar); ctx.clearRect(0, 0, ancho, alto); ctx.beginPath(); ctx.strokeStyle=#000; ctx.fillStyle = ctx.lineWidth = 1; =velocidad; for (sea x = 0; x <= ancho; x++) { var y = A*Math.sin(W*x+Q) +H; ctx.lineTo(x, y } ctx.lineTo(ancho, alto); ctx.lineTo(0, alto); .closePath();})()
El efecto es el siguiente:
4. Mejorar la animación de las olas de agua.1. Primero, puede superponer una forma de onda de mayor frecuencia a la forma de onda anterior para hacer que la forma de onda sea irregular.
var s = 0,1*Math.sin(x/150)+1;var y = A*Math.sin(W*x+Q) +H;y=y*s;
2. Agregue otra forma de onda con diferentes cambios de fase y su relleno de degradado sea opuesto a la dirección del degradado anterior para formar un efecto de sombra superpuesto y establezca el efecto de superposición de ruta globalCompositeOperation;
var lienzo = document.getElementById(lienzo), ctx = lienzo.getContext('2d'), ancho = lienzo.ancho = lienzo.offsetWidth, alto = lienzo.height = lienzo.offsetHeight;var A=30, W=1 / 200, Q=0, H= altura/2;var A2=30, W2=1/300, Q2=0, H2= altura/ 2;var velocidad=-0.01;var velocidad2=-0.02;var lingrad = ctx.createLinearGradient(0,0,width,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)'); dibujar(){ ventana.requestAnimationFrame(dibujar); ctx.clearRect(0, 0, width, height); ctx.beginPath(); ctx.fillStyle = lingrad; ctx.moveTo(0, height /2); //Dibuja la primera forma de onda Q+=speed; = 0; x <= ancho; x++) { var s = 0.1*Math.sin(x/150)+1; A*Math.sin(W*x+Q) +H; y=y*s; ctx.lineTo(x, y } ctx.lineTo(ancho, alto); .fill(); ctx.closePath() //Establece el efecto de superposición ctx.globalCompositeOperation = destino-over //Dibuja la segunda forma de onda ctx.beginPath(); ctx.fillStyle = lingrad2; Q2+=speed2; for (let x = 0; x < ancho; x++) { var y = A2*Math.sin(x*W2+Q2) +H2; } ctx.lineTo(ancho,alto); ctx.lineTo(0,alto ctx.fill()); ctx.closePath();})()
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.