Dieses Mal werde ich Ihnen eine detaillierte Erklärung zum Erstellen dynamischer Partikelgitteranimationen mit Canvas geben. Was sind die Vorsichtsmaßnahmen für die Erstellung dynamischer Partikelgitteranimationen mit Canvas? .
Ich habe kürzlich eine sehr coole Partikelgitteranimation gesehen, also habe ich selbst eine erstellt. Sie eignet sich gut als Hintergrund. Da CSDN keine Bilder hochladen kann, die größer als 2 M sind, schneide ich einfach ein statisches Bild aus:
Beginnen wir damit, wie man diesen Effekt erzielt:
Zuallererst von Natürlich ist es Zeit, eine Leinwand hinzuzufügen:
<canvas></canvas>
Das Folgende ist der Stil:
<style> #canvas{ position: absolute; display: block; left:0; top:0; background: #0f0f0f; z-index: -1; } </style>
Der Z-Index der Leinwand oben: -1 kann unter einigen Elementen platziert werden als ein Hintergrund.
Um sicherzustellen, dass die Leinwand den gesamten Browser ausfüllen kann, müssen Breite und Höhe der Leinwand mit denen des Browsers übereinstimmen:
function getSize(){ w = canvas.width = window.innerWidth; h = canvas.height = window.innerHeight; }
B und H oben stellen die Breite bzw. Höhe des Browsers dar.
Nachdem wir die Breite und Höhe des Browsers ermittelt haben, besteht der nächste Schritt darin, Partikel hineinzuzeichnen. Hier müssen wir im Voraus einige Partikelparameter definieren:
var opt = { particleAmount: 50, //粒子个数 defaultSpeed: 1, //粒子运动速度 variantSpeed: 1, //粒子运动速度的变量 particleColor: "rgb(32,245,245)", //粒子的颜色 lineColor:"rgb(32,245,245)", //网格连线的颜色 defaultRadius: 2, //粒子半径 variantRadius: 2, //粒子半径的变量 minDistance: 200 //粒子之间连线的最小距离 };
Die oben genannten Geschwindigkeitsvariablen und Radiusvariablen sind beides. Dies soll sicherstellen, dass die Größe und Geschwindigkeit der Partikel nicht genau gleich sind.
Dann erstellen wir eine Klasse, um die Partikel zu initialisieren, daher habe ich Kommentare hinzugefügt:
function Partical(){ this.x = Math.random()*w; //粒子的x轴坐标 this.y = Math.random()*h; //粒子的y轴坐标 this.speed = opt.defaultSpeed + opt.variantSpeed*Math.random(); //粒子的运动速度 this.directionAngle = Math.floor(Math.random()*360); //粒子运动的方向 this.color = opt.particleColor ; //粒子的颜色 this.radius = opt.defaultRadius+Math.random()*opt.variantRadius; //粒子的半径大小 this.vector = { x:this.speed * Math.cos(this.directionAngle), //粒子在x轴的速度 y:this.speed * Math.sin(this.directionAngle) //粒子在y轴的速度 } this.update = function(){ //粒子的更新函数 this.border(); //判断粒子是否到了边界 this.x += this.vector.x; //粒子下一时刻在x轴的坐标 this.y += this.vector.y; //粒子下一时刻在y轴的坐标 } this.border = function(){ //判断粒子是都到达边界 if(this.x >= w || this.x= h || this.y w){ //下面是改变浏览器窗口大小时的操作,改变窗口大小后有的粒子会被隐藏,让他显示出来即可 this.x = w; } if(this.y > h){ this.y = h; } if(this.x <p style="text-align: left;">1 Die Anfangsgeschwindigkeit und der Anfangswinkel jedes Partikels werden zufällig generiert. , die Farbe der Partikel wird durch die jeweiligen Einstellmöglichkeiten bestimmt. </p><p style="text-align: left;">2. This.vector wird verwendet, um die Bewegungsrichtung von Partikeln zu speichern: Wenn this.vector.x 1 ist, bewegen sich die Partikel nach rechts; wenn es -1 ist, bewegen sich die Partikel nach links. Wenn this.vector.y negativ ist, bewegt sich das Teilchen ebenfalls nach oben, und wenn es positiv ist, bewegt sich das Teilchen nach unten. </p><p style="text-align: left;">Dieses Update wird verwendet, um die Koordinaten der nächsten Position jedes Partikels zu aktualisieren. Zunächst wird eine Kantenerkennung durchgeführt. Wenn die Bewegung des Partikels die Größe der Leinwand überschreitet, wird der Richtungsvektor mit -1 multipliziert, um die umgekehrte Bewegungsrichtung zu erzeugen. </p><p style="text-align: left;">3. Die Fensterskalierung kann dazu führen, dass Partikel über die Grenze hinausgehen, sodass die Kantenerkennungsfunktion sie nicht erfassen kann. Daher sind eine Reihe von if-Anweisungen erforderlich, um diese Situation zu erkennen und die Partikelposition auf die aktuelle Grenze zurückzusetzen der Leinwand. </p><p style="text-align: left;">4. Der letzte Schritt besteht darin, diese Punkte auf die Leinwand zu zeichnen. </p><p style="text-align: left;">Die Partikelklasse wurde geschrieben, zeichnen wir sie: </p><pre class="brush:php;toolbar:false">function init(){ getSize(); for(let i = 0;i<opt.particleamount><p style="text-align: left;">Die opt.particleAmount-Partikelobjekte werden oben initialisiert, und die Objekte werden initialisiert, aber nicht gezeichnet. Unten ist die Schleife Funktion: </p> <pre class="brush:php;toolbar:false">function loop(){ ctx.clearRect(0,0,w,h); for(let i = 0;i<particle.length><p style="text-align: left;">Jedes Mal, wenn die Funktion „loop()“ ausgeführt wird, wird der Inhalt auf der Leinwand gelöscht und anschließend werden die Koordinaten der Partikel über die Funktion „update()“ des Partikelobjekts neu berechnet und schließlich über die Funktion draw() des Partikelobjekts die Funktion zum Zeichnen von Partikeln. Dies ist der folgende Effekt: </p><p style="text-align: left;"><img title="" alt="Ausführliche Erklärung zum Erstellen dynamischer Partikelgitteranimationen mit Canvas" src="https://img.php.cn/upload/article/000/061/021/c0c9b9891fd6ff9bfb9f8bad2673271e-1.gif"></p><p style="max-width:90%">Aber einige Partikel verschwinden, nachdem sich die Größe des Browserfensters geändert hat. Zu diesem Zeitpunkt müssen Sie ein Ereignis hinzufügen, um zu überwachen, ob Browsergröße ändert sich. :</p><pre class="brush:php;toolbar:false">window.addEventListener("resize",function(){ winResize() },false);
Dann müssen Sie die Funktion winResize() schreiben. Dabei ist zu beachten, dass das Resize-Ereignis sehr häufig ausgelöst wird, wenn Sie den Rand von verschieben Wenn die Größe des Browsers leicht verändert wird, wird die Größe des Browsers Dutzende Male neu berechnet. Sie können dies einfach testen Nur die endgültige Größe des Browsers nach der Änderung. Es hat nichts damit zu tun, wie oft es geändert wurde. Daher können wir das Ereignis zur Berechnung der Browsergröße um 200 Millisekunden verzögern, wenn sich das Browserfenster ändert. Wenn das Größenänderungsereignis in diesem Zeitraum ausgelöst wird, dann verzögern Sie es um 200 Millisekunden. Es klingt kompliziert, aber der Code ist eigentlich sehr einfach:
var particle = [], w,h; //粒子数组,浏览器宽高 var delay = 200,tid; //延缓执行事件和setTimeout事件引用 function winResize(){ clearTimeout(tid); tid = setTimeout(function(){ getSize(); //获取浏览器宽高,在文章最上面有介绍 },delay) }
Auf diese Weise werden alle Partikelanimationen abgeschlossen. Sie können Linien zwischen Partikeln zeichnen. In dem oben definierten Opt-Objekt gibt es eine Linie. Wenn die Linie zwischen zwei Partikeln kleiner als dieser Wert ist, zeichnen wir eine Linie zwischen ihnen.
Wie berechnet man also den Abstand zwischen zwei Teilchen? Sie können sich an die erste Lektion der Mathematik der Mittelstufe erinnern, den Satz des Pythagoras. Die Summe der Quadrate der beiden rechtwinkligen Seiten eines rechtwinkligen Dreiecks ist gleich zum Quadrat der dritten Variablen. Siehe unten:
我们现在知道每个粒子的x轴和y轴的坐标,那么我们就可以计算出两个点之间的距离了,写一个函数,传入两个点,如下:
function getDistance(point1,point2){ return Math.sqrt(Math.pow(point1.x-point2.x,2) + Math.pow(point1.y - point2.y ,2)); }
现在我们可以计算出两个点的距离,那么我们就计算出所有每个粒子同其他所有粒子的距离,来确定它们之间是否需要连线,当然如果所有粒子的颜色深度都一模一样,那就有点丑了,所以我们这里可以根据两个粒子之间的距离来决定连线的透明度,两个粒子距离越近,越不透明,距离越远,越透明,超过一定距离就不显示了。
function linePoint(point,hub){ for(let i = 0;i<hub.length> 0){ ctx.lineWidth = 0.5; ctx.strokeStyle = "rgba("+line[0]+","+line[1]+","+line[2]+","+opacity+")"; ctx.beginPath(); ctx.moveTo(point.x,point.y); ctx.lineTo(hub[i].x,hub[i].y); ctx.closePath(); ctx.stroke(); } } }</hub.length>
上面传入的两个参数分别是一个点和整个点的数组,let opacity = 1 -distance/opt.minDistance;用于判断连线之间的透明度同时也判断了距离,距离大于opt.minDistance时,opacity为负,下面判断时就过滤掉了,上面的颜色用到了正则表达式,需要先解析最上面opt对象里给出的颜色,然后再加上透明度,这段代码如下:
var line = opt.lineColor.match(/\d+/g);
最后在loop()函数里面不断循环计算距离就可以了,在loop()中加入代码后如下:
function loop(){ ctx.clearRect(0,0,w,h); for(let i = 0;i需要指出的是:如果添加过多的点和/或过多的连接距离(连接距离会创建过多的线条),动画也会扛不住。当视口变窄时最好降低粒子的运动速度:粒子的尺寸越小,在愈加狭窄空间内的移动速度貌似会越快。
显示整段代码:
nbsp;html>canvasAusführliche Erklärung zum Erstellen dynamischer Partikelgitteranimationen mit Canvas <canvas></canvas> <script> var canvas = document.getElementById("canvas"); var ctx = canvas.getContext("2d"); var opt = { particleAmount: 50, //粒子个数 defaultSpeed: 1, //粒子运动速度 variantSpeed: 1, //粒子运动速度的变量 particleColor: "rgb(32,245,245)", //粒子的颜色 lineColor:"rgb(32,245,245)", //网格连线的颜色 defaultRadius: 2, //粒子半径 variantRadius: 2, //粒子半径的变量 minDistance: 200 //粒子之间连线的最小距离 }; var line = opt.lineColor.match(/\d+/g); console.log(line); var particle = [], w,h; var delay = 200,tid; init(); window.addEventListener("resize",function(){ winResize() },false); function winResize(){ clearTimeout(tid); tid = setTimeout(function(){ getSize(); },delay) } function init(){ getSize(); for(let i = 0;i<opt.particleAmount; i++){ particle.push(new Partical()); } loop(); } function loop(){ ctx.clearRect(0,0,w,h); for(let i = 0;i<particle.length; i++){ particle[i].update(); particle[i].draw(); } for(let i = 0;i<particle.length; i++){ linePoint(particle[i],particle) } window.requestAnimationFrame(loop); } function linePoint(point,hub){ for(let i = 0;i<hub.length;i++){ let distance = getDistance(point,hub[i]); let opacity = 1 -distance/opt.minDistance; if(opacity > 0){ ctx.lineWidth = 0.5; ctx.strokeStyle = "rgba("+line[0]+","+line[1]+","+line[2]+","+opacity+")"; ctx.beginPath(); ctx.moveTo(point.x,point.y); ctx.lineTo(hub[i].x,hub[i].y); ctx.closePath(); ctx.stroke(); } } } function getDistance(point1,point2){ return Math.sqrt(Math.pow(point1.x-point2.x,2) + Math.pow(point1.y - point2.y ,2)); } function getSize(){ w = canvas.width = window.innerWidth; h = canvas.height = window.innerHeight; } function Partical(){ this.x = Math.random()*w; //粒子的x轴坐标 this.y = Math.random()*h; //粒子的y轴坐标 this.speed = opt.defaultSpeed + opt.variantSpeed*Math.random(); //粒子的运动速度 this.directionAngle = Math.floor(Math.random()*360); //粒子运动的方向 this.color = opt.particleColor ; //粒子的颜色 this.radius = opt.defaultRadius+Math.random()*opt.variantRadius; //粒子的半径大小 this.vector = { x:this.speed * Math.cos(this.directionAngle), //粒子在x轴的速度 y:this.speed * Math.sin(this.directionAngle) //粒子在y轴的速度 } this.update = function(){ //粒子的更新函数 this.border(); //判断粒子是否到了边界 this.x += this.vector.x; //粒子下一时刻在x轴的坐标 this.y += this.vector.y; //粒子下一时刻在y轴的坐标 } this.border = function(){ //判断粒子是都到达边界 if(this.x >= w || this.x<= 0){ //如果到达左右边界,就让x轴的速度变为原来的负数 this.vector.x *= -1; } if(this.y >= h || this.y <= 0){ //如果到达上下边界,就让y轴的速度变为原来的负数 this.vector.y *= -1; } if(this.x > w){ //下面是改变浏览器窗口大小时的操作,改变窗口大小后有的粒子会被隐藏,让他显示出来即可 this.x = w; } if(this.y > h){ this.y = h; } if(this.x < 0){ this.x = 0; } if(this.y < 0){ this.y = 0; } } this.draw = function(){ //绘制粒子的函数 ctx.beginPath(); ctx.arc(this.x, this.y, this.radius ,0 ,Math.PI * 2); ctx.closePath(); ctx.fillStyle = this.color; ctx.fill(); } } </script>Nach dem Login kopieren
相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!
推荐阅读:
Das obige ist der detaillierte Inhalt vonAusführliche Erklärung zum Erstellen dynamischer Partikelgitteranimationen mit Canvas. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!