Este artículo habla sobre cómo usar un lienzo para dibujar un hermoso efecto de lluvia. Primero echemos un vistazo al efecto final.
representaciones
explicarMire la imagen para analizar qué efectos necesitamos lograr.
1. Efecto de caída de gotas de lluvia, mueva el mouse para controlar la dirección de caída
2. Las gotas de lluvia caen y se dispersan en pequeñas gotas de agua. La dirección del movimiento de las pequeñas gotas de agua es la misma que la dirección del movimiento del mouse.
3. Las gotas de lluvia caen dentro de un cierto rango de las coordenadas del mouse y se dispersan en pequeñas gotas de agua. De manera similar, la dirección del movimiento de las pequeñas gotas de agua es la misma que la dirección del movimiento del mouse.
Bien, dividamos aproximadamente el efecto completo en tres efectos, logremos estos tres efectos y listo.
Hagámoslo paso a paso.
1. Efecto de caída de gotas de lluvia, mueva el mouse para controlar la dirección de caídaLa idea para lograr el efecto completo es,
hora inicialUtilice una matriz para guardar objetos de gotas de lluvia.
Un objeto de gota de lluvia tiene varios atributos que se utilizan para representar la coordenada x, la coordenada y, la longitud, la velocidad de caída, el color y una bandera de la gota de lluvia para determinar si se debe eliminar.
Al actualizar la animaciónAgregue una cierta cantidad de objetos de gota de lluvia a la matriz, luego recorra la matriz, modifique las coordenadas x e y de cada objeto de gota de lluvia y use el lienzo para dibujar dos puntos según las coordenadas del objeto de gota de lluvia, que juntos forman un gota de agua.
Entonces la clave para lograr el efecto son las coordenadas.
Al inicializar una gota de lluviaCoordenada x de la gota de lluvia: un número aleatorio
Coordenada y de la gota de lluvia: -100, esto es para permitir que las gotas de lluvia entren desde fuera del área visible
Al actualizar la animación Coordenada x de la gota de lluvia:原x坐标的值+ speed * speedx
la velocidad es un valor fijo, que indica la velocidad de caída de las gotas de lluvia,
speedx es una variable relacionada con la dirección del movimiento del mouse, speedx = speedx + (maxspeedx - speedx) / 50
Y maxspeedx es un valor obtenido en función de la dirección del movimiento del mouse.
maxspeedx = (e.clientX - canvasEl.clientWidth / 2) / (canvasEl.clientWidth / 2)
,
e.clientX: el valor de la distancia del mouse a la izquierda del área visible
canvasEl.clientWidth: ancho de toda el área visual
En otras palabras, speedx es un valor que se acerca gradualmente a maxspeedx.
El rango de valores de maxspeedx es de -1 a 1. Cuanto más cerca esté su valor de -1, la dirección estará más hacia la izquierda. Cuanto más cerca esté el valor de 1, más hacia la derecha.
¿Por qué no utilizar simplemente maxspeedx?
Esto es para evitar que las gotas de lluvia cambien de dirección tan rápidamente. En lugar de cambiar la dirección inmediatamente después del cambio del mouse, debería haber un ligero retraso para que se vea mejor.
Si usas maxspeedx, el efecto es así
Si usas speedx, el efecto es así.
Coordenada y de la gota de lluvia:原y坐标的值+ speed
La velocidad es la misma que se menciona en la coordenada x anterior. Es un valor fijo que representa la velocidad de caída de las gotas de lluvia.
Bien, finalmente, uso el lienzo para dibujar dos puntos de acuerdo con las coordenadas del objeto gota de lluvia, luego los conecto y se dibuja la gota de lluvia.
La coordenada del primer punto es relativamente simple. Obtenga directamente las coordenadas xey del objeto gota de lluvia, que es la coordenada de este punto.
Coordenadas del segundo punto:
x坐标= 雨滴x坐标的值+ 雨滴长度* speedx
y坐标= 雨滴y坐标的值+ 雨滴长度
Finalmente, conecta estos dos puntos y quedará una línea, que es una gota de lluvia.
Al configurar la coordenada x, la variable speedx se usa nuevamente. Esto es para hacer que la dirección de la gota de lluvia y la dirección de caída de la gota de lluvia sean iguales.
Cuando no se usa speedx, es así
Cuando se utiliza speedx, este es el caso
2. Las gotas de lluvia caen y se dispersan en pequeñas gotas de agua. La dirección del movimiento de las pequeñas gotas de agua es la misma que la dirección del movimiento del mouse.La idea aquí es en realidad algo similar al efecto anterior.
hora inicialUtilice una matriz para guardar pequeños objetos de gotas de agua.
Una pequeña gota de agua es en realidad un arco circular.
Un objeto de gota de agua pequeña tiene varios atributos que se utilizan para representar las coordenadas de la gota de agua pequeña, la velocidad de movimiento del eje x, la velocidad de movimiento del eje y, el radio del círculo y una bandera para determinar si se debe eliminar.
Al actualizar la animaciónAgregue una cierta cantidad de objetos pequeños de gota de agua a la matriz, luego recorra la matriz, modifique las coordenadas x e y de cada objeto pequeño de gota de agua y use el lienzo para dibujar un arco según los atributos de coordenadas y los atributos de radio del pequeño objeto de gota de agua.
Por lo tanto, el foco para lograr el efecto todavía está en las coordenadas.
Al inicializar una pequeña gota de aguaAparecen pequeñas gotas de agua cuando la gota de lluvia desaparece, por lo que las coordenadas de la pequeña gota de agua también se basan en las coordenadas de la gota de lluvia. Cuando eliminas una gota de lluvia, aparecerán algunas pequeñas gotas de agua y la dirección de movimiento de la pequeña gota de agua es. también la dirección de la caída de la gota de lluvia Mouse La dirección del movimiento es la misma, por lo que la velocidad variable mencionada anteriormente seguirá siendo necesaria.
小水珠x坐标: 删除的雨滴x坐标+ 删除的雨滴长度* speedx
小水珠y坐标:删除的雨滴y坐标+ 删除的雨滴长度
Aquí necesitamos usar dos atributos del objeto pequeña gota de agua vx (la velocidad de cambio del valor del eje x) y vy (la velocidad de cambio del valor del eje y).
La coordenada x de la pequeña gota de agua.
vx = vx + speedx / 2
小水珠的x坐标=原x坐标+ vx
,
speedx: una variable relacionada con la dirección del movimiento del mouse mencionada anteriormente. La función aquí es controlar la dirección del movimiento de las pequeñas gotas de agua en la misma dirección que otras direcciones.
speedx / 2
, el propósito de dividir entre 2 es hacer que la distancia de movimiento de las pequeñas gotas de agua en el eje x sea más corta y parezca más realista.
La coordenada y de la pequeña gota de agua.
vy = vy + gravity
小水珠的y坐标= 原y坐标+ vy;
vy: un número negativo
Gravedad: Gravedad, un número positivo, establecido en 0,5 en el código completo
Debido a que la coordenada y original es un número positivo, el valor de la coordenada y de la pequeña gota de agua primero disminuirá y luego aumentará. Esto es para lograr el efecto de que la pequeña gota de agua primero suba y luego caiga.
Finalmente, simplemente use el lienzo para dibujar un arco según los atributos de coordenadas y los atributos de radio de la pequeña gota de agua.
3. Las gotas de lluvia caen dentro de un cierto rango de las coordenadas del mouse y se dispersan en pequeñas gotas de agua. De manera similar, la dirección del movimiento de las pequeñas gotas de agua es la misma que la dirección del movimiento del mouse.
Es fácil determinar el tamaño del círculo en la imagen. Supongamos que el radio del círculo es 35. Podemos obtener las coordenadas del mouse tomando las coordenadas del mouse como el centro del círculo y 35 como el radio. , podemos determinar el tamaño del círculo.
El punto clave es cómo juzgar si las gotas de lluvia han entrado en este rango. Esto requiere el uso del Teorema de Pitágoras. Mira la imagen.
Debido a que una gota de lluvia es una línea que conecta dos puntos, para ver si la gota de lluvia ha entrado en este rango, debe observar las coordenadas del punto debajo de la gota de lluvia. ¿Cuál es la distancia en línea recta desde el mouse? AB en la imagen.
Teorema de Pitágoras: La suma de los cuadrados de los dos lados rectángulos de un triángulo rectángulo es igual al cuadrado de la hipotenusa.
AB = Matemáticas.sqrt(BC BC + AC AC)
BC = coordenada x de la gota de lluvia - coordenada x del ratón
AC = coordenada y de la gota de lluvia - coordenada y del ratón
El método Math.sqrt() se utiliza para calcular la raíz cuadrada de un número.
Después de conocer la distancia en línea recta desde la gota de lluvia hasta el mouse, compárela con el radio del círculo. Si es mayor que el radio, no está dentro del rango; de lo contrario, sí.
Si está dentro del alcance, elimina las gotas de lluvia y extrae algunas pequeñas gotas de agua.
Resumir
Para lograr este efecto, el problema radica en la dirección, la dirección de las gotas de lluvia, la dirección de las gotas de lluvia y la dirección del movimiento de las pequeñas gotas de agua. Después de determinar las distintas direcciones, use lienzo para dibujar líneas continuamente según la distancia. Un arco servirá.
código completo
<!doctype html><html lang=en><head> <meta charset=UTF-8> <style> * { margin: 0; padding: 0 } </style></head><body> <canvas id; =estilo del lienzo=posición: absoluta; altura: 100%; ancho:100%;></canvas> <script> window.onload = main; // Obtener el elemento del lienzo var canvasEl = document.getElementById('canvas'); var ctx = canvasEl.getContext('2d'); // El color de fondo del lienzo var backgroundColor = '#000' // El ancho del lienzo es igual al ancho del área visual canvasEl. width = canvasEl.clientWidth; // La altura del lienzo es igual a la altura del área visible canvasEl.height = canvasEl.clientHeight // Matriz para guardar pequeñas gotas de agua // Después de que caen las gotas de lluvia, se dispersan en pequeñas gotas de agua. Las pequeñas gotas de agua son arcos. var dropList = []; // Gravedad // Después de que caen las gotas de lluvia, las pequeñas gotas de agua se dispersan primero. luego cae, principalmente debido a la gravedad var gravitación = 0.5; // Guarda la matriz de gotas de lluvia // Cada gota de lluvia es una línea dibujada var linelist = [] // Guarda las coordenadas del mouse // mousePos[0; ] Representa el valor del eje x, mousePos[1] representa el valor del eje y var mousePos = [0, 0] // Siguiendo el mouse, las gotas de lluvia en el área de tamaño de mouseDis desaparecerán, formando un efecto de dispersión. // Con mousePos como centro del círculo, mouseDis es Radio, las gotas de lluvia dentro de este rango se esparcirán y formarán muchas gotas de agua pequeñas var mouseDis = 35 // Actualiza la animación una vez y dibuja lineNum gotas de lluvia Cuanto mayor sea el valor de lineNum. , más densa será la lluvia var. lineNum = 3; // Sigue la dirección del mouse para cambiar la dirección de la lluvia // Después de que el mouse se mueve, la dirección de la lluvia cambiará lentamente, principalmente dependiendo de la variable speedx var speedx = 0 // maxspeedx es el máximo; valor que speedx puede tomar // Cuando speedx = maxspeedx, la dirección de la lluvia cambiará inmediatamente con la dirección del movimiento del mouse var maxspeedx = 0 // Cuando el tamaño de la página cambie, restablezca el tamaño del lienzo window.onresize = function () { lienzoEl.ancho = canvasEl.clientWidth; canvasEl.height = canvasEl.clientHeight; } //Mueve el mouse para activar el evento window.onmousemove = function (e) { //Establece mousePos igual a las coordenadas del mouse // e.clientX es la distancia al izquierda del área visible de la ventana del navegador Distancia // e.clientY es la distancia desde la parte superior del área visible de la ventana del navegador mousePos[0] = e.clientX[1] = e.clientY; // Establece el valor de maxspeedx a través de la posición del mouse, el rango de valores es de -1 a 1 // El valor de maxspeedx está relacionado con // 1. La dirección de la gota de lluvia // 2. La dirección de la gota de lluvia cayendo // 3. La velocidad a la que la dirección de caída de las gotas de lluvia cambia con la dirección del movimiento del mouse // 4. La dirección de movimiento de las pequeñas gotas de agua // Cuanto más cerca está el valor de 1, la dirección está más hacia la derecha // Cuanto más cerca esté el valor de -1, la dirección estará más hacia la izquierda maxspeedx = (e.clientX - canvasEl.clientWidth / 2) / (canvasEl.clientWidth / 2); // Según los parámetros, devuelve un color rgb, utilizado para establecer el color de las gotas de lluvia function getRgb(r, g, b) { return rgb( + r + , + g + , + b + } // Dibujar una gota de lluvia (una línea) function createLine(e) { // Generar aleatoriamente la longitud de la gota de lluvia var temp = 0.25 * (50 + Math.random() * 100); // Un objeto de línea, que representa una gota de lluvia var line = { // Velocidad de caída de la gota de lluvia: 5.5 * (Math.random() * 6 + 3), / / Determine si eliminar, si el valor es verdadero, elimínelo die: false, // Gota de lluvia x coordenada posx: e, // Gota de lluvia y coordenada posy: -50, // Longitud de la gota de lluvia h: temp, // Color del color de las gotas de lluvia: getRgb(Math.floor(temp * 255/75), Math.floor(temp * 255/75), Math.floor(temp * 255/75)) } // Crear bien objeto de línea (gota de lluvia), agregado a la matriz que contiene gotas de lluvia linelist.push(line } //); Dibuja una pequeña gota de agua (las pequeñas gotas de agua después de que las gotas de lluvia se dispersan son arcos) function createDrop(x, y) { // Un objeto de gota, que representa un arco var drop = { // Determina si se elimina, valor Si es verdadero, elimina die: false, // La coordenada x del centro del arco posx: x, // La coordenada y del centro del arco posy: y, // vx representa la velocidad a la que cambia el valor del eje x vx: (Math.random ( ) - 0.5) * 8, // vy representa la velocidad a la que cambia el valor del eje y. El rango de valores es: -3 a -9 vy: Math.random() * (-6) - 3, // The. radio del arco radio: Math. random() * 1.5 + 1 }; return drop } // Dibuja un cierto número de pequeñas gotas de agua function madedrops(x, y) { // Genera aleatoriamente un número maxi // maxi Representa el número de pequeñas gotas de agua que se extraerán var maxi = Math.floor(Math.random() * 5 + 5 for (var i = 0; i < maxi; i++) { dropList.push(createDrop(x, y) ); } } // Comienza a llamar a la función de actualización para actualizar la animación window.requestAnimationFrame(update); // Actualiza la función de animación update() { // Si la matriz que contiene las pequeñas gotas de agua tiene contenido if. (dropList.length > 0) { // Recorre la matriz que contiene pequeñas gotas de agua dropList.forEach(function (e) { //Establece e.vx, vx representa la velocidad del cambio de coordenadas x // (speedx)/2 es para, hacer que la distancia de movimiento de las pequeñas gotas de agua en el eje x sea más corta y parezca más realista // También haga que la dirección de movimiento de las pequeñas gotas de agua sea la misma que la dirección de las gotas de lluvia, la dirección de caída de las gotas de lluvia y la dirección de movimiento del mouse e.vx = e.vx + (velocidadx / 2); e.posx = e.posx + e.vx; // Establece e.vy, vy representa la velocidad de cambio de la coordenada y // El rango de e.vy es de -3 a -9, y en este momento e.posy (coordenada y) debe ser un valor positivo, por lo que el valor de e.posy primero disminuirá y luego aumentará // es decir, las gotas de lluvia se dispersarán en pequeñas gotas de agua, y las pequeñas gotas de agua primero subirán y luego caída e.vy = e.vy + gravedad; + e.vy; // Si la coordenada y de la pequeña gota de agua es mayor que la altura del área visible, establezca el atributo die en verdadero // Si la pequeña gota de agua excede el área visible, elimínela si (e. posy > canvasEl.clientHeight) { e .die = true; } } } // Eliminar el miembro de la matriz cuyo atributo die es verdadero // Eliminar las pequeñas gotas de agua fuera del área visible para (var i = dropList.length - 1) ; yo >= 0; yo- -) { si (dropList[i].die) { dropList.splice(i, 1 } } // Establece la velocidad del cambio de dirección de la lluvia, rango de valores: -1 a 1 // Cuando speedx = maxspeedx, la dirección de la lluvia cambiará speedx inmediatamente cuando el mouse se mueve dirección = speedx + (maxspeedx - speedx) / 50; // Dibuja un cierto número de gotas de lluvia según el valor de lineNum for (var i = 0; i < lineNum; i++) { // Llame a la función createLine, el parámetro es la coordenada x de la gota de lluvia createLine(Math.random() * 2 * canvasEl.width - (0.5 * canvasEl.width) } // Establece la línea final, es decir, la las gotas de lluvia se extienden para formar muchas gotas de agua pequeñas Posición var endLine = canvasEl.clientHeight - Math.random() * canvasEl.clientHeight / 5; Recorre la matriz que contiene las gotas de lluvia linelist.forEach(function (e) { // Usa el teorema de Pitágoras para determinar un rango dentro del cual las gotas de lluvia se esparcirán para formar pequeñas gotas de agua // e.posx + speedx * eh es la coordenada x de la gota de lluvia/ / e.posy + eh es la coordenada y de la gota de lluvia var dis = Math.sqrt(((e.posx + speedx * eh) - mousePos[0]) * ((e.posx + speedx * eh) - mousePos[0]) + (e.posy + eh - mousePos[1]) * (e.posy + eh - mousePos[1])); // Si está en el área mouseDis, elimina la gota de lluvia. y dibújalo Algunas pequeñas gotas de agua (arcos) // Realiza el efecto del mouse tocando las gotas de lluvia y las gotas de lluvia se dispersan en pequeñas gotas de agua if (dis < mouseDis) { // Elimina las gotas de lluvia e.die = true; algunas pequeñas gotas de agua (arco circular) madedrops(e.posx + speedx * eh, e.posy + eh); // Si las gotas de lluvia exceden la línea final, elimina las gotas de lluvia y dibuja algunas pequeñas gotas de agua (arcos) if ((e.posy + eh) > endLine) { e.die = true; madedrops(e.posx + speedx * eh, e.posy + eh } // Si la coordenada y de la gota de lluvia es mayor que la altura del área visible, configura el dado); atributo a verdadero // Si la gota de lluvia excede el área visible, elimínela if (e.posy >= canvasEl.clientHeight) { e.die = true } else { // Aumente gradualmente el valor de la coordenada y de la gota de lluvia e.posy = e. posy + e.speed ; // Cambia la coordenada x de la gota de lluvia // * speedx se usa para controlar la dirección de caída de la gota de lluvia // Hace que la dirección de caída de la gota de lluvia sea la misma que la dirección del movimiento del mouse e.posx = e .posx + e.velocidad * velocidadx; } }); Eliminar los miembros de la matriz cuyo atributo die es verdadero // Eliminar las gotas de lluvia en el área del mouse, más allá de la línea final y fuera del área visible para (var i = linelist.length - 1; i >= 0; i--) { if (linelist[i].die) { linelist.splice(i, 1); // Renderizar render(); // Llamar recursivamente a actualización para lograr el efecto de animación window.requestAnimationFrame(update); // Función de renderizado render() { // Dibuja un rectángulo tan grande como el área visible ctx.fillStyle = backgroundColor; ctx.fillRect(0, 0, canvasEl.width, canvasEl.height); // Dibuja un efecto de gota de lluvia ctx. lineWidth = 5; linelist.forEach(función (línea) { ctx.strokeStyle = line.color; ctx.beginPath(); ctx.moveTo(line.posx, line.posy); // * speedx se usa para controlar la dirección de las gotas de lluvia // Hace que la dirección de las gotas de lluvia sea la misma que la dirección del movimiento del mouse ctx.lineTo(line.posx + line. h * speedx, line.posy + line.h); ctx.stroke(); }); // Dibuja gotas de lluvia que se extienden para formar pequeñas gotas de agua. dropList.forEach(function (e) { ctx.beginPath(); ctx.arc(e.posx, e.posy, e.radius, Math.random() * Math.PI * 2, 1 * Math.PI); ctx.stroke(); }); // Descomente y podrá ver el rango del mouse/* ctx.beginPath(); mousePos[1], mouseDis, 0, 2 * Math.PI; ctx.stroke(); */ } } </script></body></html>
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.