Heim >Web-Frontend >js-Tutorial >So erstellen Sie eine Uhranimation mit Canvas
Als ich die Wissenspunkte von Javascript zu Canvas überprüfte, sah ich ein Beispiel einer statischen Uhr, die mit Canvas gezeichnet wurde, und wollte daraus eine Uhrenanimation machen, die die Systemzeit dynamisch anzeigt. Darüber hinaus wurde in Verbindung mit einer Digitalanzeigeuhr ein kleines Uhrenmodul geboren! Die aktuelle Benutzeroberfläche ist noch relativ grob, mit nur einer einfachen Benutzeroberfläche und Animationseffekten.
Diese Uhr besteht aus zwei Teilen, der animierten Scheibenuhr und der Digitaluhr. Die erste besteht darin, das Timeout zu verwenden, um die Methode setTimeout () aufzurufen und einen Schleifenanimationseffekt zur Anzeige der Zeit zu erstellen. Schauen wir uns zunächst den Code der Digitaluhr an. Auch die Scheibenuhr ist so gestaltet, dass sie die Digitaluhr nachahmt.
var ntimeoutId = setTimeout(ntimeOut,0);function ntimeOut() { clearTimeout(ntimeoutId); var now = new Date(); var hours = now.getHours().toString(), minutes = now.getMinutes().toString(), seconds = now.getSeconds().toString(); var time = hours+" : "+minutes+" : "+seconds; var timep = document.getElementById("time"); timep.innerHTML = time; ntimeoutId = setTimeout(ntimeOut, 1000); }
1. Legen Sie zunächst einen Timeout-Aufruf fest, um die Methode zum ersten Mal aufzurufen und die aktuelle Uhrzeit anzuzeigen System. Der Grund, warum die Zeit eingestellt ist. Es ist 0, die Zeit ohne Verzögerung anzuzeigen.
2. Löschen Sie den vorherigen Timeout-Aufruf vor jeder Schleife (warum Sie das tun müssen, weiß ich noch nicht??? Es kann mit der Speicherleistung zusammenhängen, kommentiert Das Programm kann in Zukunft normal ausgeführt werden)
3. Holen Sie sich die aktuelle Systemzeit und speichern Sie sie in einem bestimmten Zeichenfolgenformat.
4. Um es dynamisch auf der Seite anzuzeigen, wird auf der HTML-Seite ein leeres p-Element definiert, um die Zeitzeichenfolge zu speichern. Fügen Sie es mithilfe der DOM-Manipulation dem p-Element hinzu, um es dynamisch anzuzeigen.
5. Durch kontinuierliche Schleife des Timeout-Aufrufs kann die Digitaluhr dynamisch angezeigt werden und die dynamischen Änderungen im p-Element können auch über die Entwicklertools gesehen werden.
Der nächste Schritt besteht darin, eine Festplattenuhranimation zu erstellen. Die Charakterisierung der Festplatte und des numerischen Werts ist relativ einfach. arc()-Methode und Kontext Verwenden Sie einfach die .fillText()-Methode. Das Folgende ist der Quellcode:
context.beginPath(); context.restore(); context.translate(0,0); context.clearRect(0,0,300,300); //绘制时钟内外边框 context.arc(150,150,149,0,2 * Math.PI,false); context.moveTo(295,150); context.arc(150,150,145,0,2 * Math.PI,false); context.font = "bold 18px Arial"; context.textAlign = "center"; //绘制时钟表盘数值 context.fillText("12",150,25); context.fillText("3",285,150); context.fillText("6",150,290); context.fillText("9",15,150); context.fillText("1",215,45); context.fillText("2",265,95); context.fillText("4",265,225); context.fillText("7",95,275); context.fillText("5",215,275); context.fillText("8",35,225); context.fillText("10",35,95); context.fillText("11",75,45); context.stroke(); context.closePath();
Der nächste Schritt besteht darin, den Zeiger zu zeichnen Wenn Sie die Methode in Elevation verwenden, ist es viel praktischer, die Methode context.translate() der Transformationsoperation zu verwenden, um den Ursprung zu ändern und dann den Pfad als Zeiger zu zeichnen. Eine weitere Schwierigkeit beim Zeichnen von Zeigern ist die Berechnung des Bogenmaßes. Dies ist natürlich ein mathematisches Problem. Schauen wir uns zunächst den Quellcode an:
//绘制指针 context.save(); context.translate(150,150); //时针 context.moveTo(0,0); hour(hours); function hour(thour) { context.save(); var newhour = 0; if(thour>12) { newhour = thour-12; } else { newhour = thour; } context.rotate((2*Math.PI/12)*newhour); context.lineTo(0,-80); context.restore(); } //分针 context.moveTo(0,0); minute(minutes); function minute(tminute) { context.save(); context.rotate((2*Math.PI/12)*tminute/5); context.lineTo(0,-110); context.restore(); } //秒针 context.moveTo(0,0); second(seconds); function second(tsecond) { context.save(); context.fillStyle = "#fff"; context.rotate((2*Math.PI/12)*tsecond/5); context.lineTo(0,-120); context.restore(); } context.stroke();
Beim Zeichnen von Zeigern verwendet jeder Zeigertyp eine Funktion, um den Bogen jedes Zeigers zu ändern Zeichnen. Um den Animationseffekt der Zeigerdrehung zu erzielen. Für den Stundenzeiger wandeln Sie die 24-Stunden-Uhr in die Zwölf-Stunden-Uhr um und drehen Sie sie jeweils um 30°. Der Minutenzeiger und der Sekundenzeiger drehen sich von 0 auf 11. Ich glaube, dass jeder diese einfache Matheaufgabe besser beherrscht als ich. Ich hatte eine Weile damit zu kämpfen. Die context.save()-Methode und die context.restore()-Methode werden in jeder Funktion verwendet, um den Pfad während der Initialisierung zu speichern und wiederherzustellen, andernfalls gerät der Zeiger aus der Spur.
Die ganze Arbeit ist im Grunde genommen fertig. Als nächstes müssen wir nur noch das Zifferblatt und die Zeiger im Timeout-Aufruf platzieren. Es gibt jedoch noch einige Probleme, die Aufmerksamkeit erfordern Die Ursprungseinstellungen sind unterschiedlich. Achten Sie daher darauf, den Pfad während der Initialisierung mit „Speichern und Wiederherstellen“ wiederherzustellen, da sonst das Zifferblatt und die Zeiger aus der Spur geraten. Beachten Sie außerdem, dass bei der Verwendung von Canvas zum Erstellen von Animationen bei jedem Animationszyklus die Leinwand gelöscht und neu gezeichnet werden muss, da sich der Zeiger sonst weiter dreht und sich in eine Blume verwandelt.
Der vollständige Disc-Clock-Code lautet wie folgt:
//显示指针时间var drawing = document.getElementById("drawing");if(drawing.getContext) { var context = drawing.getContext("2d"); var rtimeoutId = setTimeout(roudClock,0); function roudClock() { clearTimeout(rtimeoutId); context.beginPath(); context.restore(); context.translate(0,0); context.clearRect(0,0,300,300); //绘制时钟内外边框 context.arc(150,150,149,0,2 * Math.PI,false); context.moveTo(295,150); context.arc(150,150,145,0,2 * Math.PI,false); context.font = "bold 18px Arial"; context.textAlign = "center"; //绘制时钟表盘数值 context.fillText("12",150,25); context.fillText("3",285,150); context.fillText("6",150,290); context.fillText("9",15,150); context.fillText("1",215,45); context.fillText("2",265,95); context.fillText("4",265,225); context.fillText("7",95,275); context.fillText("5",215,275); context.fillText("8",35,225); context.fillText("10",35,95); context.fillText("11",75,45); context.stroke(); context.closePath(); var now = new Date(); var hours = now.getHours(), minutes = now.getMinutes(), seconds = now.getSeconds(); //绘制指针 context.save(); context.translate(150,150); //时针 context.moveTo(0,0); hour(hours); function hour(thour) { context.save(); var newhour = 0; if(thour>12) { newhour = thour-12; } else { newhour = thour; } context.rotate((2*Math.PI/12)*newhour); context.lineTo(0,-80); context.restore(); } //分针 context.moveTo(0,0); minute(minutes); function minute(tminute) { context.save(); context.rotate((2*Math.PI/12)*tminute/5); context.lineTo(0,-110); context.restore(); } //秒针 context.moveTo(0,0); second(seconds); function second(tsecond) { context.save(); context.fillStyle = "#fff"; context.rotate((2*Math.PI/12)*tsecond/5); context.lineTo(0,-120); context.restore(); } context.stroke(); context.restore(); context.translate(0,0); context.save(); rtimeoutId = setTimeout(roudClock,1000); } }
Abschließend fasse ich das zusammen Zeit Während der Demo-Übung sind mehrere Probleme aufgetreten:
1. Problem beim Neuzeichnen der Leinwand
Wenn die Zeigeranimation eine Schleife durchläuft, gibt es keine Möglichkeit, den vorherigen Pfad zu löschen, sodass jede Schleife eine Markierung hinterlässt. Ich habe versucht, die Methode „clearRect()“ in einem kleinen Bereich zu verwenden, stellte jedoch fest, dass sie nur den Inhalt des Zifferblatts und die Zahlen innerhalb des Bereichs löschen konnte und der Zeiger immer noch Spuren hinterließ. Später erhielt ich bei der Suche die Antwort, dass bei der Verwendung von Canvas zum Erstellen von Animationen diese neu gezeichnet werden müssen. Der Canvas-Inhalt muss vor dem Zeichnen neuer Inhalte gelöscht werden, und jede Animationsänderung muss gelöscht werden. Informationen zur Neuzeichnungsmethode finden Sie unter dem Link. Ich verwende die Methode „clearRect()“, um die gesamte Leinwand zu löschen.
2. Verwendung der save()-Methode und der restart()-Methode
Da die Ursprungseinstellungen meines Zifferblatts und Zeigers unterschiedlich sind, Daher ändert sich nach dem Neuzeichnen der Ursprung des Zifferblatts zum Ursprung des Zeigers. Daher müssen zum Ändern die Methoden save () und restart () verwendet werden. Zusätzlich zu diesem Ort gibt es auch andere Orte, die verwendet werden müssen. Er eignet sich für Situationen, in denen die Einstellungen nach dem Vorgang geändert werden, die ursprünglichen Einstellungen jedoch für nachfolgende Vorgänge verwendet werden müssen. Beachten Sie, dass diese beiden Methoden nur Einstellungen speichern und wiederherstellen, nicht jedoch Inhalte.
3. Verwendung der Translate()-Methode
Die Translate()-Methode gehört zur Transformationsoperation und kann den Ursprung der Leinwand ändern . Der Standardursprung der Leinwand liegt in der oberen linken Ecke der Leinwand. Die Verwendung dieser Methode erleichtert das Zeichnen des Zeigerpfads. Natürlich gibt es noch einige andere Verwendungsmöglichkeiten, die ich noch nicht berührt habe.
4. Verwendung der setTimeout()-Methode
Die Verwendung von Timeout-Aufrufen ist eine bessere Methode als die Verwendung von Timeout-Aufrufen, um intermittierende Anrufe zu simulieren . Anruf. Eine Schleife kann gut simuliert werden, indem ein Timeout-Aufruf innerhalb der Funktion hinzugefügt wird, an die der Timeout-Aufruf übergeben wird. Sie können die Anzahl und Dauer der Schleifen auch basierend auf einigen Bedingungen in der Funktion begrenzen.
5. Wie man das Bogenmaß entsprechend der aktuellen Zeit verwendet
Das ist ein mathematisches Problem, mit dem ich lange zu kämpfen hatte Zeit, aber ich habe es nicht falsch verstanden. Nach dem Umdrehen ist es kein technisches Problem mehr, das Prinzip zu verstehen.
6. In Bezug auf das Problem der wiederholten Erfassung und Wiederverwendung von Zeitmethoden
In Bezug auf die Situation, in der es wiederholte Codes in der gibt Code ist mir kein besserer Weg zur Reduzierung der Redundanz eingefallen. In Bezug auf die Erfassungszeit gibt es beispielsweise wiederholte Definitionen in den beiden Timeout-Aufrufen. Wenn sie jedoch global platziert werden, gibt es keinen Animationseffekt und es wird nur die statische Zeit nach Abschluss des Ladevorgangs angezeigt. Eine andere Sache ist, dass es in der Funktionseinstellung des Zeigers wiederholte Teile gibt. Kann er zu einer Funktionsmethode kombiniert und dann aufgerufen werden?
Jeder ist willkommen, Ideen einzubringen, Vorschläge für Mängel zu machen und gemeinsam zu kommunizieren.
Das obige ist der detaillierte Inhalt vonSo erstellen Sie eine Uhranimation mit Canvas. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!