Es gibt kein Bestes, nur Besseres. Wie der Titel schon sagt, möchte dieser Artikel nur einen mit Canvas erzielten Partikelbewegungseffekt vorstellen. Es fühlt sich ein wenig wie eine Schlagzeile an, aber aus einer anderen Perspektive kann man es kaum als blendend bezeichnen. Obwohl die Farbe nichts mit Blendung zu tun hat, ist der Bewegungseffekt dennoch ein bisschen blendend. Wie dem auch sei, beginnen wir mit diesem sogenannten Blendeffekt!
Gehen Sie direkt zum Code. Wenn Sie ihn nicht verstehen, können Sie die Codekommentare lesen. Sie werden wahrscheinlich die allgemeine Idee verstehen.
HTML-Code
<!DOCTYPE html><html lang=en><head><meta charset=UTF-8><title>Canvas erzielt atemberaubende Partikelbewegungseffekte – Cloud-Bibliotheks-Frontend</title><style>* { margin: 0; padding : 0;}html,body { width: 100%; height: 100%;}canvas { display: block; #000;}body::-webkit-scrollbar{ display: none;}.operator-box{ position: Fixed; left: 50%; border: 1px solid #fff; padding: 20px 10px; (-50 %); transform: translatorX(-50 %);}.back-type,.back-animate{ margin-right: 20px;}.flex-box{ display: flex; align-items: center;}#input-text{ line-height: 260px; height: rgba(0, 0, 0,7); Farbe: #fff; Rand: keine; 12px; box-shadow: inset 0 0 12px 1px rgba(0,0,0,0.7);}#input-text::placeholder{ color: #ccc; height: 55px;}select{ Webkit-Aussehen: keine; -moz-Aussehen: keine; Rand: keine; 0px 6px; Höhe: 35px; Farbe: #fff; Hintergrund: rgba(0, 0, 0,7) url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAICAYAAAAx8TU7AAAAOUlEQ…R4gPgWEIMAiOYBCS4C8ZDAIrBq4gigNkztQEFMi6AuQHESAPMeXiEMiWfpAAAAAElFTkSuQmCC) keine Wiederholung 190px 12px; Hintergrundgröße: 5px 8px; box-shadow: inset 0 0 12px 1px rgba(0,0,0,0.7);</style></head><body><div class=operator-box>< div class=flex-box> <div class=back-type>Spread-Typ: <select name= id=selectType> <option value=back>Return</option> <option value=auto>Zufällig</option> </select> </div> <div class=back-animate>Dispersionseffekt (wirksam für Homing): <select class=back-dynamics id=selectDynamics> <option value= spring>dynamics.spring</option> <option value=bounce>dynamics.bounce</option> <option value=forceWithGravity>dynamics.forceWithGravity</option> <option value=gravity>dynamics.gravity</option> <option value=easeInOut>dynamics.easeInOut</option> <option value=easeIn>dynamics.easeIn</option> <option value=easeOut>dynamics.easeOut</ option> <option value=linear>dynamics.linear</option> </select> </div> <div class=input-box><input type=text placeholder=Geben Sie chinesische Zeichen ein und drücken Sie die Eingabetaste id=input-text></div></div></div><script src=dynamics.min.js></script><script src=index.js></ script ><script>var iCircle = new Circle();</script></body></html>
Es gibt nicht viel HTML-Code, nur ein paar Bedienelemente. Hier ist es auf einen Blick leicht zu verstehen. Sie müssen nicht zu viele Worte verschwenden. Schauen wir uns den Protagonisten-JavaScript-Code dieses Artikels an. Bevor wir uns den Code ansehen, können wir uns jedoch auch die Idee anhören, wie dieser Effekt erzielt werden kann:
Im JavaScript-Code werden drei Canvas-Leinwände verwendet: this.iCanvas (Homepage), this.iCanvasCalculate (zur Berechnung der Textbreite) und this.iCanvasPixel (zum Zeichnen von Text und zum Erhalten der Positionskoordinaten der dem Text entsprechenden Pixel). ).
this.iCanvasCalculate und this.iCanvasPixel müssen nicht auf der Seite angezeigt werden, es handelt sich lediglich um Hilfsfunktionen.
Hier ist der tolle JS-Implementierungscode
function Circle() { var This; this.generalParam(); this.ballAnimate(); Holen Sie sich den Bildschirm window.onresize = function(){ This.stateW = document.body.offsetWidth; This.stateH = document.body.offsetHeight; This.iCanvas.width = This.stateW; This.iCanvasH = This.iCanvas.height = This.stateH; This.ctx = This.iCanvas.getContext(2d }}//Initialize Circle.prototype.init = function( ){ //Breite und Höhe des übergeordneten Elements this.stateW = document.body.offsetWidth; this.stateH = document.body.offsetHeight; document.createElement(canvas); // Canvas auf die gleiche Breite und Höhe wie das übergeordnete Element setzen this.iCanvasW = this.iCanvas.width = this.stateW; this.iCanvasH = this.iCanvas.height = this.stateH; // 2D-Malumgebung abrufen this.ctx = this.iCanvas.getContext(2d); // In das Body-Element einfügen document.body.appendChild(this.iCanvas); this.iCanvasCalculate = document.createElement(canvas); // Canvas zum Speichern der berechneten Textbreite this.mCtx = this.iCanvasCalculate.getContext(2d); this.iCanvasPixel = document .createElement (Leinwand); this.iCanvasPixel.setAttribute(style,position:absolute;top:0;left:0;); this.pCtx = null; // Canvas zum Zeichnen von Text // Die Anzahl der zufällig generierten Kreise this.ballNumber = ramdomNumber(1000 , 2000); // Ein Array aller Bälle speichern this.balls = []; // Den letzten Ball speichern, der in der Animation angehalten hat this.animte = null; this.imageData = null; this.textWidth = 0; // Speichern Sie die Breite des generierten Textes this.textHeight = 150; // Speichern Sie den vom Benutzer eingegebenen Inhalt this.actionCount = 0; this.ballActor = []; // Speichere die Partikel, die Text generieren this.backType = back; ; // Animationseffekt this.isPlay = false; // Logo (kann nicht während der Textgenerierung generiert werden)}// Alle Kreise rendern Circle.prototype.drawCircles = function () { for(var i=0;i <this.ballNumber ;i++){ this.renderBall(this.balls[0]); }}// Benutzereingabetext abrufen Circle.prototype.getUserText = function(){ This = this; // Speichern Sie dies, um auf ipu = document.getElementById(input-text); ipu.addEventListener(keydown,function(event){ if(event.which === 13){ // zu verweisen ipu.value = ipu.value.trim(); // Führende und nachfolgende Leerzeichen entfernen var pat = /[/u4e00-/u9fa5]/ // Chinesisches Urteil var isChinese = pat.test(ipu.value); if(ipu.value.length !=0 && isChinese){ This.inputText = ipu.value; }else{ warning(Bitte geben Sie chinesische Zeichen ein) if(This.isPlay ) { return } This.getAnimateType(); This.getTextPixel(); This.isPlay = true; Berechnen Sie die Breite des Textes Circle.prototype.calculateTextWidth = function () { this.textWidth = this.mCtx.measureText(this.inputText).width;}// Holen Sie sich die Textpixel Circle.prototype.getTextPixel = function () { if( this.pCtx){ this.pCtx.clearRect(0,0,this.textWidth,this.textHeight); this.calculateTextWidth(this.inputText); this.iCanvasPixel.width = this.iCanvasPixel.height; .pCtx = this.iCanvasPixel.getContext(2d); this.pCtx.font = 128px Microsoft Yahei; this.pCtx.textBaseline = botom; this.imageData = this.pCtx.getImageData ( 0,0,this.textWidth,this.textHeight).data; this.getTextPixelPosition(this.textWidth,this.textHeight);}//Die Pixelposition des Textpartikels abrufen Circle.prototype.getTextPixelPosition = function (width,height) { var left = (this.iCanvasW - width)/2; = (this.iCanvasH - height)/2; var space = 4; this.actionCount = 0; i=0;i<this.textHeight;i+=space){ for(var j=0;j<this.textWidth;j+=space){ var index = j*space+i*this.textWidth*4; this.imageData[index] == 255){ if(this.actionCount<this.ballNumber){ this.balls[this.actionCount].status = 1; this.balls[this.actionCount].targetX = left+j; this.balls[this.actionCount].targetY = top+i this.balls[this.actionCount].backX = this.balls[this.actionCount]. x; this.balls[this.actionCount].backY = this.balls[this.actionCount].y; } } } this.actorNumber = this.ballActor.length; } this.animateToText();}//Das Partikel bewegt sich an die angegebene Position Circle.prototype.animateToText = function(){ for(var i=0;i<This .actorNumber ;i++){dynamics.animate(This.ballActor[i], { x: this.ballActor[i].targetX, y: this.ballActor[i].targetY },{ type:dynamics.easeIn, duration: 1024, }); } setTimeout(function(){ This.ballbackType(); },3000);}//Die Partikel kehren zum zurück Kreisen Sie entlang des ursprünglichen Pfads .prototype.ballBackPosition = function(){ for(var i=0;i<This.actorNumber;i++){ var ball = This.ballActor[i];dynamics.animate(ball, {x:ball.backX, y:ball.backY},{type:dynamics[this.backDynamics], Dauer: 991,complete:this.changeStatus(ball)} ); }}// Typ abrufen|Animationseffekt Circle.prototype.getAnimateType = function() { var selectType = document.getElementById(selectType); var selectDynamics = document.getElementById(selectDynamics); this.backType = selectType.options[selectType.options.selectedIndex].value; this.backDynamics = selectDynamics.options[selectDynamics.options.selectedIndex].value;}//Spread Circle zurücksetzen .prototype.ballbackType = function(){ if(this.backType == back){ this.ballBackPosition(); }else{ this.ballAutoPosition(); } this.ballActor = [];}// Zufällig streuen Circle.prototype.ballAutoPosition = function(ball){ for(var i= 0 ;i<this.actorNumber;i++){ this.changeStatus(this.ballActor[i]) }}// Ändern Sie den Ballstatus Circle.prototype.changeStatus = function(ball){ ball.status = 0; if(this.isPlay == true){ this.isPlay = false }}/ Generieren Sie zufällig die relevanten Parameter jedes Kreises .prototype.generalRandomParam = function(){ for(var i=0;i<this.ballNumber;i++){ var ball = {}; Kreisradius zufällig generieren // Kreismittelpunkt x-Koordinate zufällig generieren ball.x = ramdomNumber(0+ball.size, this.iCanvasW-ball.size); ball.y = ramdomNumber(0+ball.size, this.iCanvasH-ball . size); ball.speedX = ramdomNumber(-1, 1); ball.speedY = ramdomNumber(-1, 1); ball.status = 0; ball.targetX = 0; ball.backY = 0; ball.backY = 0; for( var i=0;i<this.ballNumber;i++){ if( this.balls[i].status == 0){ this.balls[i].x += this.balls[i].speedX; this.balls[i].y += this.balls[i].speedY; } }}// Zeichne einen Kreis Circle.prototype.renderBall = function(ball){ this.ctx . fillStyle = #fff; this.ctx.beginPath(); // Dies muss mit this.ctx.arc(ball.x, ball.y, ball.size, 0, 2 * hinzugefügt werden Math.PI); this.ctx.closePath(); // Dies muss mit this.ctx.fill();}/ Ball-Kollisionsbeurteilung Circle.prototype.collision = function(ball){ for(var i= 0;i<this.ballNumber;i++){ if(ball.x>this.iCanvasW-ball.size || ball.x<ball.size){ if(ball.x>this.iCanvasW-ball.size){ ball.x = this.iCanvasW-ball.size; }else{ ball.x = ball.size } ball.speedX = - ball.speedX; (ball.y>this.iCanvasH-ball.size || ball.y<ball.size){ if(ball.y>this.iCanvasH-ball.size){ ball.y = this.iCanvasH-ball.size; }else{ ball.y = ball.size; } ball.speedY = - ball.speedY; } }}// Animation starten Circle.prototype.ballAnimate = function(){ var This = this ; var animateFrame = window.requestAnimationFrame || window.msRequestAnimationFrame; (function move(){ animte = animateFrame(move); This.ctx.clearRect(0, 0, This.iCanvasW, This.iCanvasH); This.changeposition(); for(var i=0;i <This.ballNumber;i++){ This.collision(This.balls[i]); })();}//Erzeuge eine Zufallszahlenfunktion ramdomNumber(min, max) { return Math.random() * (max - min) + min;}
Nachdem ich den Code gelesen habe, denke ich, dass es nur eine Art Angeberei war und es Ihnen nicht den Wunsch geweckt hat, dieses Ding zu machen. Ich weiß, dass Sie dafür mit Ihren Augen und Ihrem Mund überzeugt werden müssen. Online-DEMO: Beispiel für dynamische Partikel.
Niemand ist perfekt und Code auch nicht. Der Code, der scheinbar reibungslos läuft, weist mehr oder weniger Mängel auf. Derzeit unterstützt dieser Effekt nur Chinesisch. Was Englisch angeht, muss ich auf jeden Fall härter arbeiten, Englisch wird auf jeden Fall später dazukommen, es ist nur eine Frage der Zeit. Es gibt auch ein Attribut im Code, mit dem markiert wird, ob der generierte Text erneut ausgeführt werden kann: this.isPlay, was immer noch ein kleiner Fehler ist. Die Zustandsänderung von this.isPlay ändert sich nicht genau in dem Moment, in dem die Partikel zurückkehren. ändert aber den Zustand im Voraus. Dieser Zustand hat jedoch keinen Einfluss auf die vollständige Umsetzung des Effekts dieses Beispiels.
In diesem Beispiel wird die Bibliothek „dynamics.js“ verwendet, hauptsächlich um einige darin enthaltene Bewegungsfunktionen zu verwenden, um die Bewegung der Partikel eindrucksvoller zu gestalten, das ist alles.
Das Obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, dass er für das Studium aller hilfreich ist. Ich hoffe auch, dass jeder das VeVb Wulin Network unterstützt.