JS Canvas implémente les effets de pluie et de neige
J'ai récemment travaillé sur un projet dans lequel il était nécessaire de réaliser les effets d'animation de la pluie et de la neige légère. J'ai donc créé un composant de chute ici pour montrer l'effet courant d'objet qui tombe sur la toile. Avant de vous présenter le texte, laissez-moi vous montrer les rendus :
Afficher les rendus :
Il pleut et il neige
L'effet semble bon. Par rapport à l'utilisation d'éléments dom créés pour créer des animations de positionnement multi-objets, l'utilisation de Canvas sera plus facile et plus rapide, et les performances seront meilleures
Appelez le code
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Document</title> <style> #canvas{ width:100%; height: 100%; } </style> </head> <body> <canvas id="canvas"></canvas> <script src="canvasDrop.js"></script> <script> canvasDrop.init({ type: "rain", // drop类型,有rain or snow speed : [0.4,2.5], //速度范围 size_range: [0.5,1.5],//大小半径范围 hasBounce: true, //是否有反弹效果or false, wind_direction: -105 //角度 hasGravity: true //是否有重力考虑 }); </script> </body> </html>
D'accord, expliquons le principe de mise en œuvre simple. Tout d'abord, définissons quelques variables globales que nous utiliserons, telles que l'angle de direction du vent, la probabilité, les données d'objet, etc.
Définissez les variables globales
//定义两个对象数据 //分别是drops下落物体对象 //和反弹物体bounces对象 var drops = [], bounces = []; //这里设定重力加速度为0.2/一帧 var gravity = 0.2; var speed_x_x, //横向加速度 speed_x_y, //纵向加速度 wind_anger; //风向 //画布的像素宽高 var canvasWidth, canvasHeight; //创建drop的几率 var drop_chance; //配置对象 var OPTS; //判断是否有requestAnimationFrame方法,如果有则使用,没有则大约一秒30帧 window.requestAnimFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(callback) { window.setTimeout(callback, 1000 / 30); };
Définir les objets principaux
Ensuite, nous devons définir plusieurs objets importants. L'organisation doit définir relativement peu d'objets, seulement trois au total. Il y a trois objets principaux définis dans l'ensemble du composant drop, à savoir comme suit. :
Objet de vitesse vectoriel, avec x horizontal et y vertical. L'unité de vitesse est : V = pixel de déplacement/image
La compréhension de l'objet vectoriel est également très simple et grossière, c'est-à-dire. , enregistrement La vitesse de chute de l'objet/V
var Vector = function(x, y) { //私有属性 横向速度x ,纵向速度y this.x = x || 0; this.y = y || 0; }; //公有方法- add : 速度改变函数,根据参数对速度进行增加 //由于业务需求,考虑的都是下落加速的情况,故没有减速的,后期可拓展 /* * @param v object || string */ Vector.prototype.add = function(v) { if (v.x != null && v.y != null) { this.x += v.x; this.y += v.y; } else { this.x += v; this.y += v; } return this; }; //公有方法- copy : 复制一个vector,来用作保存之前速度节点的记录 Vector.prototype.copy = function() { //返回一个同等速度属性的Vector实例 return new Vector(this.x, this.y); }; Drop 下落物体对象, 即上面效果中的雨滴和雪, 在后面你也可自己拓展为陨石或者炮弹 对于Drop对象其基本定义如下 //构造函数 var Drop = function() { /* .... */ }; //公有方法-update Drop.prototype.update = function() { /* .... */ }; //公有方法-draw Drop.prototype.draw = function() { /* .... */ };
Après avoir lu les trois méthodes ci-dessus, avez-vous deviné leurs fonctions ? Ensuite, comprenons ce que font ces trois méthodes
Constructeur ?
Le constructeur est principalement responsable de la définition des informations initiales de l'objet drop, telles que la vitesse, les coordonnées initiales, la taille, l'accélération, etc.
//构造函数 Drop var Drop = function() { //随机设置drop的初始坐标 //首先随机选择下落对象是从从哪一边 var randomEdge = Math.random()*2; if(randomEdge > 1){ this.pos = new Vector(50 + Math.random() * canvas.width, -80); }else{ this.pos = new Vector(canvas.width, Math.random() * canvas.height); } //设置下落元素的大小 //通过调用的OPTS函数的半径范围进行随机取值 this.radius = (OPTS.size_range[0] + Math.random() * OPTS.size_range[1]) *DPR; //获得drop初始速度 //通过调用的OPTS函数的速度范围进行随机取值 this.speed = (OPTS.speed[0] + Math.random() * OPTS.speed[1]) *DPR; this.prev = this.pos; //将角度乘以 0.017453293 (2PI/360)即可转换为弧度。 var eachAnger = 0.017453293; //获得风向的角度 wind_anger = OPTS.wind_direction * eachAnger; //获得横向加速度 speed_x = this.speed * Math.cos(wind_anger); //获得纵向加速度 speed_y = - this.speed * Math.sin(wind_anger); //绑定一个速度实例 this.vel = new Vector(wind_x, wind_y); };
La méthode de mise à jour de l'objet Drop
La méthode de mise à jour est responsable du changement des attributs de l'instance de dépôt dans chaque image, comme le changement de déplacement
Drop.prototype.update = function() { this.prev = this.pos.copy(); //如果是有重力的情况,则纵向速度进行增加 if (OPTS.hasGravity) { this.vel.y += gravity; } // this.pos.add(this.vel); };
La méthode de dessin du Objet déposé
La méthode de dessin est responsable de chaque image Dessin d'une instance de chute d'image
Drop.prototype.draw = function() { ctx.beginPath(); ctx.moveTo(this.pos.x, this.pos.y); //目前只分为两种情况,一种是rain 即贝塞尔曲线 if(OPTS.type =="rain"){ ctx.moveTo(this.prev.x, this.prev.y); var ax = 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.prev.y + ay, this.pos.x, this.pos.y); ctx.stroke(); //另一种是snow--即圆形 }else{ ctx.moveTo(this.pos.x, this.pos.y); ctx.arc(this.pos.x, this.pos.y, this.radius, 0, Math.PI*2); ctx.fill(); } };
rebond objet de rebond tombant, c'est-à-dire les gouttelettes d'eau qui rebondissent sur la pluie au-dessus. Vous pouvez également l'étendre en morceaux de gravier rebondissants plus tard. Ou la définition de la fumée
est très simple, il n'y aura donc pas d'explication détaillée ici
var Bounce = function(x, y) { var dist = Math.random() * 7; var angle = 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(angle) * dist, Math.sin(angle) * 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(); };
Interface externe
mise à jour
est équivalente à la fonction de démarrage de toute l'animation du canevas
function update() { var d = new Date; //清理画图 ctx.clearRect(0, 0, canvas.width, canvas.height); var i = drops.length; while (i--) { var drop = drops[i]; drop.update(); //如果drop实例下降到底部,则需要在drops数组中清楚该实例对象 if (drop.pos.y >= canvas.height) { //如果需要回弹,则在bouncess数组中加入bounce实例 if(OPTS.hasBounce){ var n = Math.round(4 + Math.random() * 4); while (n--) bounces.push(new Bounce(drop.pos.x, canvas.height)); } //如果drop实例下降到底部,则需要在drops数组中清楚该实例对象 drops.splice(i, 1); } drop.draw(); } //如果需要回弹 if(OPTS.hasBounce){ var i = bounces.length; while (i--) { var bounce = bounces[i]; bounce.update(); bounce.draw(); if (bounce.pos.y > canvas.height) bounces.splice(i, 1); } } //每次产生的数量 if(drops.length < OPTS.maxNum){ if (Math.random() < drop_chance) { var i = 0, len = OPTS.numLevel; for(; i<len; i++){ drops.push(new Drop()); } } } //不断循环update requestAnimFrame(update); }
init
interface init, initialise l'ensemble du canevas Toutes les propriétés de base telles que l'obtention du rapport de pixels de l'écran, la définition de la taille en pixels du canevas et le réglage le style
function init(opts) { OPTS = opts; canvas = document.getElementById(opts.id); ctx = canvas.getContext("2d"); ////兼容高清屏幕,canvas画布像素也要相应改变 DPR = window.devicePixelRatio; //canvas画板像素大小, 需兼容高清屏幕,故画板canvas长宽应该乘于DPR canvasWidth = canvas.clientWidth * DPR; canvasHeight =canvas.clientHeight * DPR; //设置画板宽高 canvas.width = canvasWidth; canvas.height = canvasHeight; drop_chance = 0.4; //设置样式 setStyle(); } function setStyle(){ if(OPTS.type =="rain"){ 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)'; } }
Conclusion
D'accord Maintenant, un simple composant de dépôt a été complété. Bien sûr, il comporte de nombreuses imperfections. .Après avoir écrit ce composant drop, je pense qu'il y a beaucoup de choses qui peuvent être explorées dans la scène H5 pour l'implémentation de l'animation du canevas.
Enfin, parlons des lacunes et des travaux ultérieurs :
0 Ce composant n'a actuellement pas assez d'interfaces externes, la plage de réglage n'est pas très grande et l'abstraction est. pas très approfondi
1. setStyle définit le style de base
2 Personnalisation des méthodes de mise à jour et de dessin des objets Drop et Bounce, permettant aux utilisateurs de définir plus de vitesse de chute. et changements de taille Les effets de forme et de style
3. Des interfaces pour les opérations de pause, d'accélération et de décélération de l'animation doivent être ajoutées
Ce qui précède est l'implémentation JS et Canvas introduite par l'éditeur I. j'espère que ces connaissances sur l'effet de la pluie et de la neige vous seront utiles. Si vous avez des questions, laissez-moi un message et l'éditeur vous répondra à temps. Je voudrais également vous remercier tous pour votre soutien au site Web PHP chinois !
Pour plus d'articles liés à JS Canvas pour obtenir des effets de pluie et de neige, veuillez faire attention au site Web PHP chinois !

Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

AI Hentai Generator
Générez AI Hentai gratuitement.

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

L'article discute de la création, de la publication et du maintien des bibliothèques JavaScript, en se concentrant sur la planification, le développement, les tests, la documentation et les stratégies de promotion.

L'article traite des stratégies pour optimiser les performances JavaScript dans les navigateurs, en nous concentrant sur la réduction du temps d'exécution et la minimisation de l'impact sur la vitesse de chargement de la page.

Des questions et des solutions fréquemment posées pour l'impression de billets thermiques frontaux pour le développement frontal, l'impression de billets est une exigence commune. Cependant, de nombreux développeurs mettent en œuvre ...

Il n'y a pas de salaire absolu pour les développeurs Python et JavaScript, selon les compétences et les besoins de l'industrie. 1. Python peut être davantage payé en science des données et en apprentissage automatique. 2. JavaScript a une grande demande dans le développement frontal et complet, et son salaire est également considérable. 3. Les facteurs d'influence comprennent l'expérience, la localisation géographique, la taille de l'entreprise et les compétences spécifiques.

L'article traite du débogage efficace de JavaScript à l'aide d'outils de développeur de navigateur, de se concentrer sur la définition des points d'arrêt, de l'utilisation de la console et d'analyser les performances.

Comment fusionner les éléments du tableau avec le même ID dans un seul objet en JavaScript? Lors du traitement des données, nous rencontrons souvent la nécessité d'avoir le même ID ...

L'article explique comment utiliser les cartes source pour déboguer JavaScript minifiée en le mappant au code d'origine. Il discute de l'activation des cartes source, de la définition de points d'arrêt et de l'utilisation d'outils comme Chrome Devtools et WebPack.

JavaScript est la pierre angulaire du développement Web moderne, et ses principales fonctions incluent la programmation axée sur les événements, la génération de contenu dynamique et la programmation asynchrone. 1) La programmation axée sur les événements permet aux pages Web de changer dynamiquement en fonction des opérations utilisateur. 2) La génération de contenu dynamique permet d'ajuster le contenu de la page en fonction des conditions. 3) La programmation asynchrone garantit que l'interface utilisateur n'est pas bloquée. JavaScript est largement utilisé dans l'interaction Web, les applications à une page et le développement côté serveur, améliorant considérablement la flexibilité de l'expérience utilisateur et du développement multiplateforme.
