Recientemente hice un proyecto en el que existe la necesidad de realizar los efectos de animación de la lluvia y la nieve ligera, por lo que hice un componente de caída aquí para mostrar los objetos que caen comunes de este lienzo. Antes de presentarte el texto principal, déjame mostrarte las representaciones:
Renderizaciones de visualización:
Llueve y nieva
Se ve bien. En comparación con el uso de la creación de elementos DOM para crear imágenes de movimiento de posición de objetos múltiples, usar lienzo será más fácil y rápido, y el rendimiento será mejor.
Código de llamada
<! Doctype html> <html lang = "en"> <fead> <meta charset = "utf-8"> <title> documento </title> <style> #canvas {width: 100%; altura: 100%;} </style> </head> <body> <Canvas id = "canvas"> </canvas> <script. src = "canvasdrop.js"> </script> <script> canvasdrop.init ({type: "lluvia", // type de caída, lluvia o sbnowspeed: [0.4,2.5], // rango de velocidad size_range: [0.5,1.5], // el tamaño y el rango de radios rango de rango: verdadero, // está existe cualquier efecto de renovación o falso, wind_direction: -105///el rango de rango de Radius: verdadero: es cierto, // está existe un efecto de renovación o falso, wind_direction: -105/. Hasgravity: True // ¿Hay alguna consideración de gravedad}); </script> </body> </html>Ok, expliquemos el principio de implementación simple. Primero, defina algunas variables globales que utilizaremos, como el ángulo de dirección del viento, la probabilidad, los datos de los objetos, etc.
Definir variables globales
// Defina dos datos de objeto // el objeto objeto de objeto de caída de caída // y el objeto de rebote rebota objeto var gots = [], bounces = []; // La aceleración de la gravedad se establece en 0.2/un marco var gravity = 0.2; var speed_x_x, // horizontal aceleración velocidad_x_y, // longiline aceleration wind_anger; // Dirección de viento // El ancho y la altura del píxel del Canvas var Canvaswidth, Canvasheight; // La probabilidad de crear drop var drop_chance; // Configurar objeto var de upts; // predeterminado si hay un método requestanimationFrame, si hay, úselo, si no hay no, habrá aproximadamente 30 mares por segundo. || window.webkitRequestanimationFrame || window.mozRequestanimationFrame || window.orequestanimationFrame || window.msequestanimationFrame || function (callback) {window.setTimeout (devolución de llamada, 1000 /30);};Defina el objeto central
A continuación, debemos definir varios objetos importantes. Hay menos objetos que la organización necesita definir. En total, solo se definen tres objetos centrales en todo el componente de caída, que son los siguientes:
Objeto de velocidad vectorial, con unidades horizontales X y de tamaño de velocidad Y vertical: V = Píxeles de desplazamiento/marcos
La comprensión del objeto vectorial también es muy simple y crudo, que es registrar la velocidad de la caída del objeto de caída/V
var vector = function (x, y) {// Velocidad horizontal de atributo privado x, velocidad vertical ythis.x = x || 0; this.y = y || 0;}; // Método público- Agregar: función de cambio de velocidad, aumente la velocidad de acuerdo con los parámetros // Debido a las necesidades comerciales, se considera toda la aceleración de caída, por lo que no hay ralentización, y se puede ampliar en la etapa posterior/** @param v Object || string */vector.prototype.add = function (v) {if (vx! = null && vy! = null) {this.x += vx; this.y += vy;} else {this.x += v; this.y += v;} return this;}; // Method público- Copiar: Copiar un vector para guardar el registro del vector de la velocidad anterior. {// Devuelve una instancia vectorial con el mismo atributo de velocidad return New Vector (this.x, this.y);}; soltar el objeto del objeto de caída, es decir, las gotas de lluvia y la nieve en el efecto anterior, más tarde puede expandirlo a un meteorito o concha. La definición básica del objeto de caída es la siguiente // constructor var drop = function () {/ * .... */}; // public Method-update drop.prototype.update = function () {/ * .... */}; // public Method-drawdrop.prototype.draw = function () {/ * ...... */};Después de leer los tres métodos anteriores, ¿ha adivinado su papel? Entendamos qué hacen estos tres métodos.
Constructor
El constructor es el principal responsable de definir la información inicial del objeto de caída, como la velocidad, las coordenadas iniciales, el tamaño, la aceleración, etc.
// constructor dropvar drop = function () {// ¡Establecer las coordenadas iniciales de Drop // Seleccione primero el elemento que cae desde el lado del lado es el de var randomedge = math.random () * 2; if (randomedge> 1) {this.pos = new vector (50 + math.random () * canvas.width, -80);} más {this.Pos = new vector Math.random () * Canvas.height);} // Establezca el tamaño del elemento que cae // El valor aleatorio se toma por el rango de radio de la función OPTS llamada this.radius = (opts.size_range [0] + Math.random () * Opts.Size_Range [1]) * dPr; // Obtenga la velocidad de caída de la velocidad por el rango de velocidad de la velocidad del rango de velocidad del rango de velocidad del rango de velocidad del rango de velocidad de la serie (Opts.speed [0] + math.random () * opts.speed [1]) * dpr; this.prev = this.pos; // Multiplica el ángulo por 0.017453293 (2pi/360) para convertirlo en radianes. var cada vez = 0.017453293; // Obtenga el ángulo de la dirección del viento Wind_anger = opts.wind_direction * Everyager; // Obtenga la aceleración lateral Speed_x = this.speed * Math.cos (Wind_anger); // Obtenga la aceleración longitudinal Speed_y = - this.speed * Math.sin (Wind); // unir una instancia de velocidad this.vel = New Vector (New Vector (NEX, Wind);};};};};Método de actualización del objeto Drop
El método de actualización es responsable de cambiar los atributos de cada instancia de caída de cuadro, como cambiar el desplazamiento.
Drop.prototype.update = function () {this.prev = this.pos.copy (); // Si hay gravedad, la velocidad longitudinal se incrementará si (opts.hasgravity) {this.vel.y += gravity;} // this.pos.add (this.vel);};};El método de dibujo del objeto de caída
El método de dibujo es responsable de dibujar cada instancia de caída de cuadro
Drop.prototype.draw = function () {ctx.beginpath (); ctx.moveto (this.pos.x, this.pos.y); // Actualmente solo hay dos situaciones, uno es lluvia, es decir, bezier curve if (opts.type == "lluvia") {ctx.moveto (this.prev.x, este.prev.p. = Math.abs (this.radius * Math.cos (Wind_anger)); var Ay = Math.abs (this.radius * Math.sin (wind_anger)); ctx.beziercurveto (this.pos.x + ax, this.pos.y + ay, this.prev.x + ax. this.pos.y); ctx.stroke (); // El otro es nieve---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------rebotar el objeto de rebotar de caer y caer, es decir, las gotas de agua que se recuperan del agua de lluvia de arriba, también puede expandirse a grava o humo en la etapa posterior.
La definición es muy simple, por lo que no la explicaré en detalle aquí.
var bounce = function (x, y) {var dist = Math.random () * 7; var ángulo = math.pi + math.random () * math.pi; this.pos = new vector (x, y); this.radius = 0.2+ math.random () * 0.8; this.vel = new vector (math.cos (ángulo) * Dist, Math.sin (ángulo) (ángulo) * * dist);};Bounce.prototype.update = function() {this.vel.y += gravity;this.vel.x *= 0.95;this.vel.y *= 0.95;this.pos.add(this.vel);};Bounce.prototype.draw = function() {ctx.beginPath();ctx.arc(this.pos.x, this.pos.y, this.radius * dpr, 0, math.pi * 2); ctx.fill ();};Interfaz externa
actualizar
Es decir, la función de inicio equivalente a toda la animación de lienzo
función actualización () {var d = nueva fecha; // limpia el dibujo ctx.clearrect (0, 0, canvas.width, canvas.height); var i = drops.length; while (i--) {var drop = drops [i]; drop.update (); // la instancia de caída de caída en el fondo, debe estar claro en el arranque de gotas si (drops (drops.pos.yps. Canvas.Height) {// Si necesita rebote, agregue la instancia de Bounce a la matriz de rebote si (opts.hasbunce) {var n = math.round (4 + math.random () * 4); while (n-) bounces.push (new Bounce (drop.pos.x, Canvas.height)));} // Si la instancia de caída cae a la parte inferior, debe estar claro en la matriz de caída de la matriz de la instancia. (i--) {var Bounce = Bounces [i]; bounce.update (); bounce.draw (); if (bounce.pos.y> canvas.height) bounces.splice (i, 1);}} // Si el número de generado cada vez es si (drops.length <opts.Maxnum) {if (math.random () 0, len = opts.numlevel; for (; i <len; i ++) {drops.push (nuevo drop ());}}} // Continuamente bucle UpdateRequestanImframe (update);}inicio
Interfaz Init, inicialice todas las propiedades básicas de todo el lienzo de lienzo, como obtener la relación píxel de la pantalla y establecer el tamaño de píxel del lienzo, y establecer el estilo del lienzo
function init (opts) {opts = opts; canvas = document.getElementById (opts.id); ctx = canvas.getContext ("2d"); /// compatible con pantallas de alta definición, el canvas Canvas Pixels también debe cambiar el tamaño de dPR = Window.devicePixelratio;//Canvasvas de placa de placa, y debe cambiar el tamaño de píxel de tablero de canvas, y debe cambiar el tamaño de la placa, y debe cambiar el tamaño de la placa, y debe cambiar el tamaño de la placa, y debe cambiar el tamaño de la placa de placa de canvas. pantallas de alta definición, por lo que la longitud y el ancho del lienzo de la tabla de arte deben multiplicarse por dPR CanvasWidth = Canvas.clientWidth * dpr; canvasheight = canvas.clientheight * dpr; // establece el ancho y la altura del article canvas.width = canvaswidth; canvas.height = canvasheight; 0.4; // set Style setStyle ();} function setStyle () {if (opts.type == "lluvia") {ctx.linewidth = 1 * dpr; ctx.strokestyle = 'rgba (223,223,223,0.6)'; ctx.fillstyle = = 'rgba (223,223,223,0.6)';} else {ctx.linewidth = 2 * dpr; ctx.StrokeStyle = 'rgba (254,254,254,0.8)'; ctx.fillStyle = 'rgba (254,254,254,0.8)';}}}Conclusión
Ok, se ha completado un componente de caída simple, por supuesto, hay muchas cosas que no son perfectas. Después de escribir este componente de caída, para la implementación de animación de lienzo, creo que hay muchos lugares para descubrir en la escena H5.
Finalmente, hablemos sobre las deficiencias y el trabajo posterior:
0. No hay suficientes interfaces externas para este componente, el rango ajustable no es muy grande y la abstracción no es muy exhaustiva.
1. setstyle set estilo básico
2. Personalización de los métodos de actualización y dibujo de objetos de caída y rebote permite a los usuarios establecer más formas y efectos de estilo de la velocidad de caída y el cambio de tamaño.
3. La interfaz para la pausa de la animación, las operaciones de aceleración y desaceleración se deben agregar.
Lo anterior es el conocimiento relevante sobre JS y lienzo que le presenté para lograr efectos lluviosos y de nieve. Espero que te sea útil. Si tiene alguna pregunta, déjame un mensaje y el editor le responderá a tiempo. ¡Muchas gracias por su apoyo al sitio web de Wulin.com!
Este artículo se reproduce: http://blog.csdn.net/xllily_11/article/details/51444311