Im vorherigen Artikel „Implementieren der Karussellkomponente mit JSX“ haben wir eine „einfache“ Karussellkomponente implementiert. Warum nennen wir es „Stiftung“? Denn es scheint zwar die Funktionen unserer Karussellkomponente zu erfüllen, weist jedoch noch viele Mängel auf, die wir noch nicht behoben haben. Obwohl wir darin zwei Funktionen implementiert haben, ist eine das automatische Karussell und die andere das Ziehen per Geste. Tatsächlich ist es aber noch weit von einer wirklichen Nutzbarkeit entfernt. Erstens können unser automatisches Karussell und das Ziehen nicht nahtlos miteinander verbunden werden, d. h., nachdem wir mit dem Ziehen fertig sind, sollte sich unser Karussell automatisch weiterdrehen. Dies ist uns bisher noch nicht gelungen. Auch beim Ziehen selbst gibt es einige Probleme mit Details. Beispielsweise werden derzeit nur Ziehvorgänge mit der Maus unterstützt, nicht aber Ziehen über Touchscreen. Auch dies ist ein Problem, mit dem wir uns bei der Entwicklung von Webseiten auseinandersetzen müssen. Zweitens wird unsere Animation mithilfe von Lassen Sie uns also gemeinsam unsere Animationsbibliothek implementieren, aber bevor wir die Animationsbibliothek implementieren, benötigen wir eine Zeitleistenbibliothek in der Animationsbibliothek. In diesem Artikel schauen wir uns zunächst an, wie man eine Zeitleistenklasse und eine grundlegende Animationsklasse implementiert, um diese Zeitleiste zu verwenden. Code-BereinigungZunächst haben wir festgestellt, dass der Code der zuvor geschriebenen Karussellkomponente bereits sehr kompliziert ist. Daher müssen wir ihn kapseln. Hier fügen wir ihn in eine separate JavaScript-Datei ein. Erstellen Sie im Stammverzeichnis des Projekts eine In carousel.js müssen wir nur importiere { Komponente } aus './framework.js'; Exportklasse Karussell erweitert Komponente {/** Code im Karussell*/} Schließlich können wir die Karussellkomponente erneut in main.js importieren. importiere { Komponente, createElement } aus './framework.js'; importiere { Karussell } aus './carousel.js'; Galerie lassen = [ 'https://source.unsplash.com/Y8lCoTRgHPE/1600x900', 'https://source.unsplash.com/v7daTKlZzaw/1600x900', 'https://source.unsplash.com/DlkF4-dbCOU/1600x900', 'https://source.unsplash.com/8SQ6xjkxkCo/1600x900', ]; let a = <Karussell src={gallery} />; // Dokument.Body.AppendChild(a); a.mountTo(Dokument.Textkörper); Nachdem wir unseren Code organisiert haben, können wir mit dem Schreiben unserer Zeitleistenbibliothek beginnen. Diese Zeitleiste ist Teil unserer Animationsbibliothek, daher haben wir sie in die JavaScript-Datei unserer Animationsbibliothek eingefügt: Wir müssen diese Zeitleiste verwenden, um unsere nachfolgende Animationsbibliothek zu implementieren. In der Animation gibt es ein sehr wichtiges Konzept: „ Frame “.
"Frames" in JavaScriptDa wir „Frames“ benötigen, um unsere Animation zu realisieren, müssen wir zunächst mehrere Lösungen zur Frame-Verarbeitung in JavaScript verstehen. Die höchste Animationsfrequenz, die das menschliche Auge erkennen kann, beträgt 60 Bilder . Einige Studenten haben möglicherweise die Filme von Ang Lee gesehen. Beispielsweise ist „Der verrückte Billy Lynn’s Long Halftime Walk“ der weltweit erste Film, der mit 120 Bildern gedreht und abgespielt wurde. Auch weil sich die Bildrate verdoppelt hat, werden sich viele Stellen sehr flüssig anfühlen. Aber im Allgemeinen unterstützen alle unsere Spiele, einschließlich unserer Monitore, 60 Frames. Obwohl in den Monitoreinstellungen möglicherweise 70 oder 80 Bilder angezeigt werden, wird es von allgemeiner Software auf 60 Bilder ausgerichtet. Wenn wir 60 Frames in 1000 Millisekunden (einer Sekunde) benötigen, wie viele Millisekunden sind dann ein Frame? Das ist 1000 / 60 = 16,666 1000 / 60 = 16,666 1000/60=16,666, also sind 16 Millisekunden ungefähr die Zeit für einen Frame.
So implementieren Sie "Frame"Als nächstes analysieren wir, mit welchen Methoden „Frames“ in JavaScript implementiert werden können. 1. Intervall festlegen Das erste ist setInterval(() => {/** Was passiert in einem Frame*/}, 16) Das hier eingestellte Zeitintervall beträgt 16 Millisekunden, die Länge eines Frames. 2. setTimeoutWir können setTimeout auch verwenden, um Ereignisse in einem Frame wiederholt zu verarbeiten. Aber weil setTimeout nur einmal ausgeführt wird. Daher müssen wir ihm einen Funktionsnamen geben, damit wir ihn später wiederholt aufrufen können.
Wir verwenden es, um eine Tick-Funktion zu definieren und sie eine Logik/ein Ereignis ausführen zu lassen. Verwenden Sie dann „setTimeout“, um eine Verzögerung von 16 Millisekunden hinzuzufügen, bevor die erneute Ausführung erfolgt. lass tick = () => { /** Unsere Logik/Ereignisse*/ setTimout(tick, 16); } 3. requestAnimationFrame Schließlich unterstützen moderne Browser einen Wenn wir den Browser auffordern, den nächsten Frame auszuführen, wird die an RAF übergebene Rückruffunktion ausgeführt. Und die Ausführungszeit dieser Funktion hängt von der Bildrate des Browsers ab. Wenn wir daher eine Reduzierung der Bildrate oder der Frequenz des Browsers durchführen möchten, kann RAF zusammen mit der Bildrate des Browsers reduziert werden. Die Bedienung ist zudem ganz einfach: lass tick = () => { /** Unsere Logik/Ereignisse*/ setTimout(tick, 16); } Daher werden diese drei Lösungen im Allgemeinen am häufigsten verwendet. Wenn die meisten unserer Benutzer moderne Browser verwenden, wird „Warum nicht setInterval verwenden?“ Da setInterval relativ unkontrollierbar ist, wird der Browser es gemäß den von uns festgelegten 16 Millisekunden ausführen? Das ist schwer zu sagen. Eine weitere Sache ist, dass es bei setInterval zu einem Rückstand kommen kann, wenn unser Tick nicht richtig geschrieben ist. Da die Ausführung in einer festen Schleife von 16 Millisekunden erfolgt, gelangt der Code des zweiten Intervalls in die Intervallwarteschlange, unabhängig davon, ob der Code im vorherigen Intervall ausgeführt wurde. Dies hängt auch von der zugrunde liegenden Implementierung des Browsers ab. Jeder Browser kann eine andere Strategie wählen.
In der folgenden Zeitleistenbibliothek verwenden wir requestAnimationFrame, um einen sich selbst wiederholenden Vorgang durchzuführen. Hier sollten wir auch einen cancelAnimationFrame erwähnen, der dem requestAnimationFrame entspricht. Wenn wir eine Variable zum Speichern von requestAnimationFrame deklarieren, können wir diese Variable an cancelAnimationFrame übergeben, um die Animation zu stoppen. lass tick = () => { let handler = requestAnimationFrame(tick); AnimationFrame abbrechen(Handler); } Auf diese Weise können wir eine gewisse Verschwendung von Ressourcen vermeiden. Implementierung der Zeitleiste Wie wir am Anfang erwähnt haben, müssen wir beim Erstellen einer Animation den Als nächstes implementieren wir gemeinsam diese Timeline-Klasse. Normalerweise muss eine Timeline nur Es verfügt jedoch über eine Kombination aus Eine weitere Sache ist die Beim Entwerfen dieser Animationsbibliothek gibt es auch ein sehr wichtiges Konzept namens Die in diesem Tutorial implementierten Set- und Get-Raten werden nicht implementiert, da es sich hierbei um eine fortgeschrittenere Zeitleistenfunktion handelt. Wenn wir dies tun wollen, müssen wir uns viel relevantes Wissen aneignen. Aber Nachdem so viel gesagt wurde, fangen wir an! ~ Implementieren der Startfunktion In unserer Startmethode wird es einen Prozess zum Starten Wie können wir die Zecke also perfekt verstecken? Wir deklarieren eine Konstante namens In ähnlicher Weise kann requestAnimationFrame in Tick auch eine globale Variable
Mit diesen beiden Konstanten können wir das Häkchen im Konstruktor der Timeline-Klasse initialisieren. Nach der Initialisierung von Tick können wir den globalen Der endgültige Code lautet wie folgt: const TICK = Symbol('Häkchen'); const TICK_HANDLER = Symbol('Tick-Handler'); Exportklasse Zeitleiste { Konstruktor() { dies[TICK] = () => { Konsole.log('tick'); AnfrageAnimationFrame(dieses[TICK]); }; } Start() { dies[TICK](); } pause() {} wieder aufnehmen() {} zurücksetzen() {} } Nachdem wir diesen Teil abgeschlossen haben, können wir diese Timeline-Klasse in unser main.js einführen, um sie auszuprobieren. importiere { Timeline } aus './animation.js'; let tl = neue Zeitleiste(); tl.start(); Erstellen Sie unseren Code und führen Sie ihn im Browser aus. Sie können in der Konsole sehen, dass unser Tick normal ausgeführt wird. Dies zeigt, dass die aktuelle Logik unserer Timeline korrekt geschrieben ist. Bisher haben wir eine sehr einfache Zeitleistenoperation implementiert. Als Nächstes implementieren wir eine einfache Animationsklasse, um unsere Zeitleiste zu testen. Implementieren der AnimationsklasseAls nächstes fügen wir Tick eine Animation hinzu und führen sie aus. Die von uns erstellte Zeitleiste wird letztendlich in der Animation unseres Karussells verwendet. Die Animation auf dem Karussell wird „Attributanimation“ genannt. Weil wir eine Eigenschaft eines Objekts von einem Wert in einen anderen Wert ändern. Im Gegensatz zur Attribut-Animation gibt es die Frame-Animation, bei der jede Sekunde ein Bild angezeigt wird. Wenn es um Einzelbildanimation geht, sollten wir alle die Animationen von Herrn Hayao Miyazaki kennen, wie etwa die Klassiker „Mein Nachbar Totoro“, „Das Schloss im Himmel“ und so weiter. Diese Animationen werden alle von Herrn Hayao Miyazaki Bild für Bild gezeichnet und dann wird pro Frame ein Bild abgespielt. In einem schnellen Wiedergabeprozess können wir die Personen und Objekte in den Bildern in Bewegung sehen. Schon vor der Anime-Ära gab es Animationen, die unsere Vorfahren als Zoetrop bezeichneten. Die oben genannten Animationen werden nicht über Attribute durchgeführt. Aber das meiste, was wir im Browser tun, sind Attributanimationen. Jede Animation hat einen Anfangseigenschaftswert und einen Endeigenschaftswert. Nachdem wir die Theorie der Animation verstanden haben, können wir mit der Implementierung der Logik dieses Teils beginnen. Zunächst einmal ist die Logik unserer Animation relativ unabhängig von der Zeitleiste, sodass wir die Animation in einer separaten Klasse kapseln können. ( Wir werden die Funktionalität der Animationsbibliothek in unseren späteren Artikeln zur Front-End-Komponentenbildung weiter verbessern. ) exportiere Klasse Animation { Konstruktor() {} } Erstellen Sie zunächst eine Animation. Wir benötigen die folgenden Parameter:
Was wir hierbei beachten müssen, ist, dass die übergebene Eigenschaft im Allgemeinen mit einer Einheit versehen ist, beispielsweise: Aber hier werden wir es später nicht hinzufügen, sondern zuerst eine einfache Animation implementieren. Beim Initialisieren unseres Animationsobjekts müssen wir alle übergebenen Parameter in den Eigenschaften dieses Objekts speichern. Daher müssen wir im Konstruktor alle übergebenen Parameter genau so kopieren, wie sie sind. exportiere Klasse Animation { Konstruktor(Objekt, Eigenschaft, Startwert, Endwert, Dauer, Zeitfunktion) { dieses.Objekt = Objekt; diese.Eigenschaft = Eigenschaft; this.startValue = Startwert; dies.Endwert = Endwert; this.duration = Dauer; this.timingFunction = Zeitgebungsfunktion; } } Als nächstes brauchen wir eine Funktion zum Ausführen der Animation. Wir können sie exec oder go nennen. Hier verwenden wir das Wort Diese Funktion muss einen Mit dieser Zeit können wir berechnen, wie stark sich die aktuelle Animationseigenschaft basierend auf dieser Zeit ändern soll. Um die Änderung dieser Eigenschaft zu berechnen, müssen wir zunächst den gesamten Änderungsbereich vom Anfangswert bis zum Endwert der Animation kennen.
Nachdem wir
Der hier erhaltene Änderungswert berechnet einen Dieser Änderungswert entspricht der Mit diesem Änderungswert können wir startValue (Anfangswert) + Änderungswert verwenden, um den Attributwert zu erhalten, der dem aktuellen Fortschritt entspricht. So funktioniert unser Code: Laufzeit (Zeit) { let range = dieser.Endwert - dieser.Startwert; dieses.Objekt[diese.Eigenschaft] = dieser.Startwert + (Bereich * Zeit) / diese.Dauer; } Auf diese Weise kann die Animation funktionieren. Als Nächstes fügen wir diese Animation der Animationswarteschlange der Zeitleiste hinzu, damit sie in der Warteschlange ausgeführt werden kann. Wie oben erwähnt, ist die von der Run-Methode in dieser Animation empfangene Zeit eine virtuelle Zeit. Wenn wir also die Run-Methode in der Timeline aufrufen, müssen wir eine virtuelle Zeit an Animation übergeben, damit unsere Animation funktionieren kann. Okay, hier möchten wir der Zeitleiste eine Animation hinzufügen. Zuerst benötigen wir eine Animationswarteschlange. Hierzu generieren wir direkt ein Animationsset. Dies ist die gleiche Speichermethode wie in anderen Timelines. Wir erstellen eine globale ANIMATIONS-Konstante, um sie zu speichern, und ihr Wert wird in ein Symbol eingeschlossen. Dadurch kann verhindert werden, dass die Warteschlange versehentlich von außen aufgerufen wird. const ANIMATIONS = Symbol('Animationen'); Dieser Warteschlange muss beim Erstellen der Timeline-Klasse auch ein leeres Set zugewiesen werden. Konstruktor() { dies[ANIMATIONEN] = neues Set(); } Wenn eine Warteschlange vorhanden ist, müssen wir über eine Methode zum Beitritt zur Warteschlange verfügen. Daher müssen wir der Timeline-Klasse auch eine Konstruktor() { dies[ANIMATIONEN] = neues Set(); } Wir müssen die aktuelle Ausführungsdauer an den Der vorherige Diese Änderung führt allerdings dazu, dass wir bei jedem Start der Timeline eine Tick-Objektfunktion neu erstellen müssen. Allerdings erleichtert diese Methode die schnelle Implementierung dieser Funktion, aber auch Studierende, die eine bessere Leistung wünschen, können diesen Bereich optimieren. Nachdem wir unser Häkchen verschoben haben, können wir dem Häkchen Animationen hinzufügen, die die Warteschlange ANIMATIONS aufrufen. Denn eine Zeitleiste kann mehrere Animationen enthalten und jedes Frame versetzt sie in den nächsten Fortschrittsattributstatus. Daher verwenden wir hier eine Schleife und rufen die Run-Methode aller Animationen in unserer ANIMATIONS-Warteschlange auf. Schließlich sieht unser Code folgendermaßen aus: const TICK = Symbol('Häkchen'); const TICK_HANDLER = Symbol('Tick-Handler'); const ANIMATIONS = Symbol('Animationen'); Exportklasse Zeitleiste { Konstruktor() { dies[ANIMATIONEN] = neues Set(); } Start() { let startTime = Date.now(); dies[TICK] = () => { lass t = Date.now() - Startzeit; für (let Animation davon [ANIMATIONEN]) { animation.run(t); } AnfrageAnimationFrame(dieses[TICK]); }; dies[TICK](); } pause() {} wieder aufnehmen() {} zurücksetzen() {} hinzufügen(Animation) { dies[ANIMATIONEN].add(animation); } } exportiere Klasse Animation { Konstruktor(Objekt, Eigenschaft, Startwert, Endwert, Dauer, Zeitfunktion) { dieses.Objekt = Objekt; diese.Eigenschaft = Eigenschaft; this.startValue = Startwert; dies.Endwert = Endwert; this.duration = Dauer; this.timingFunction = Zeitgebungsfunktion; } Laufzeit (Zeit) { console.log(Zeit); let range = dieser.Endwert - dieser.Startwert; dieses.Objekt[diese.Eigenschaft] = dieser.Startwert + (Bereich * Zeit) / diese.Dauer; } } Wir fügen der Ausführungsmethode der Animation ein Schließlich fügen wir in main.js die Animation zu unserer Timeline hinzu. importiere { Komponente, createElement } aus './framework.js'; importiere { Karussell } aus './carousel.js'; importiere { Zeitleiste, Animation } aus './animation.js'; Galerie lassen = [ 'https://source.unsplash.com/Y8lCoTRgHPE/1600x900', 'https://source.unsplash.com/v7daTKlZzaw/1600x900', 'https://source.unsplash.com/DlkF4-dbCOU/1600x900', 'https://source.unsplash.com/8SQ6xjkxkCo/1600x900', ]; let a = <Karussell src={gallery} />; // Dokument.Body.AppendChild(a); a.mountTo(Dokument.Textkörper); let tl = neue Zeitleiste(); // tl.add(neue Animation({}, 'Eigenschaft', 0, 100, 1000, null)); tl.start(); Wir haben festgestellt, dass die Animation tatsächlich funktionieren kann und die Zeit eingehalten werden kann. Es wurde jedoch auch ein Problem festgestellt: Die Animation wurde ohne Unterbrechung weiter abgespielt. Dann müssen wir eine Abbruchbedingung hinzufügen. Unsere bedingte Beurteilung sollte vor der Ausführung von animation.run erfolgen, wenn die aktuelle Zeit die Dauer der Animation überschritten hat. Jetzt müssen wir die Animation stoppen. Zuerst müssen wir den Aufruf der Animationsschleife in Exportklasse Zeitleiste { Konstruktor() { dies[ANIMATIONEN] = neues Set(); } Start() { let startTime = Date.now(); dies[TICK] = () => { lass t = Date.now() - Startzeit; für (let Animation davon [ANIMATIONEN]) { wenn (t > Animationsdauer) { dies[ANIMATIONEN].löschen(Animation); } animation.run(t); } AnfrageAnimationFrame(dieses[TICK]); }; dies[TICK](); } pause() {} wieder aufnehmen() {} zurücksetzen() {} hinzufügen(Animation) { dies[ANIMATIONEN].add(animation); } } Einfach so haben wir die Stoppbedingung ohne komplizierte Logik hinzugefügt. Schließlich ändern wir in main.js den ersten Parameter der Animation. Indem wir dem übergebenen Objekt einen Setter hinzufügen, können wir in unserer Animation die Zeit ausgeben lassen. Dies erleichtert das Debuggen. tl.add( neue Animation( { Menge a(a) { konsole.log(a); }, }, 'Eigentum', 0, 100, 1000, Null ) ); Wir können sehen, dass die Animation tatsächlich gestoppt ist, aber es besteht immer noch ein Problem. Wir haben die Dauer der Animation auf 1000 Millisekunden eingestellt, der letzte Wert hier beträgt jedoch 1002, was unsere Animationsdauer offensichtlich überschreitet. Wenn wir daher auf die Bedingung „Animationsende“ stoßen, müssen wir ihre Dauer (den Wert der Animationsdauer) an die Animation übergeben. Hier müssten wir schreiben: Start() { let startTime = Date.now(); dies[TICK] = () => { lass t = Date.now() - Startzeit; für (let Animation davon [ANIMATIONEN]) { sei t0 = t; wenn (t > Animationsdauer) { dies[ANIMATIONEN].löschen(Animation); t0 = Animationsdauer; } Animation.Lauf(t0); } AnfrageAnimationFrame(dieses[TICK]); }; dies[TICK](); } pause() {} wieder aufnehmen() {} zurücksetzen() {} hinzufügen(Animation) { dies[ANIMATIONEN].add(animation); } } Auf diese Weise werden unsere vorläufigen Timeline- und Animationsfunktionen eingerichtet. Aktualisierungen des DesignzeitplansAls Nächstes werden wir dieser Zeitleiste weitere Funktionen hinzufügen, um unsere Animationsbibliothek wirklich nutzbar zu machen. Bei CSS-Animationen wissen wir, dass sie eine Dauer haben (Animationsdauer), tatsächlich gibt es aber auch eine Verzögerung (Animationsverzögerungszeit). Versuchen wir also zunächst, diese Funktion hinzuzufügen. Unterstützung für die Eigenschaft „Verzögerung“ hinzugefügtWährend der Entwicklung, wenn wir der ursprünglichen Bibliothek Funktionen hinzufügen möchten. Unsere erste Überlegung ist: „Finden Sie einen sinnvollen Ort, um diese Funktionalität hinzuzufügen.“ Intuitiv gesehen besteht unser erster Instinkt darin, diese Verzögerung in die Animationsklasse einzufügen, schließlich ist diese Funktion Teil der Animation. Es gibt jedoch eine bessere Idee: die Verzögerung in die Timeline einzufügen. Wir können es so verstehen: Startzeit, Endzeit und Zeitsteuerung einer Animation sind allesamt zeitleistenbezogene Angelegenheiten, die sich eigentlich von dem unterscheiden, worauf sich die Animation konzentriert. Bei der Animation liegt der Schwerpunkt meiner Meinung nach mehr auf den Effekten und der Funktionsweise der Animation. Daher ist es offensichtlich sinnvoller, eine Verzögerung in die Zeitleiste einzufügen. Fügen Sie in der Während wir die Verzögerungslogik hinzufügen, können wir auch ein Problem lösen. Das heißt, wenn wir der Warteschlange eine Animation hinzufügen, wird die Zeitleiste möglicherweise bereits ausgeführt. Wenn wir also die Animation hinzufügen, ist ihre Startzeit falsch. Ein weiteres Problem besteht darin, dass bei der Startmethode unsere Startzeit Okay, also können wir bei der Implementierung unserer Verzögerungsfunktion beide Faktoren berücksichtigen. Fügen wir zunächst einen Verzögerungsparameter hinzu: exportiere Klasse Animation { Konstruktor(Objekt, Eigenschaft, Startwert, Endwert, Dauer, Verzögerung, Zeitfunktion) { dieses.Objekt = Objekt; diese.Eigenschaft = Eigenschaft; this.startValue = Startwert; dies.Endwert = Endwert; this.duration = Dauer; this.timingFunction = Zeitgebungsfunktion; this.delay = Verzögerung; } Laufzeit (Zeit) { console.log(Zeit); let range = dieser.Endwert - dieser.Startwert; dieses.Objekt[diese.Eigenschaft] = dieser.Startwert + (Bereich * Zeit) / diese.Dauer; } } Alles, was wir hier tun, ist, dem Konstruktor einen Denn jede zur Timeline-Warteschlange hinzugefügte Animation kann eine andere Verzögerung aufweisen, was eine andere Startzeit für die Animation bedeutet. Daher müssen wir unter dem Konstruktor der Timeline-Klasse einen exportiere Klasse Animation { Konstruktor(Objekt, Eigenschaft, Startwert, Endwert, Dauer, Verzögerung, Zeitfunktion) { dieses.Objekt = Objekt; diese.Eigenschaft = Eigenschaft; this.startValue = Startwert; dies.Endwert = Endwert; this.duration = Dauer; this.timingFunction = Zeitgebungsfunktion; this.delay = Verzögerung; } Laufzeit (Zeit) { console.log(Zeit); let range = dieser.Endwert - dieser.Startwert; dieses.Objekt[diese.Eigenschaft] = dieser.Startwert + (Bereich * Zeit) / diese.Dauer; } } Fügen Sie dann in der Add-Methode zum Hinzufügen einer Animation zur Zeitleiste die Startzeit der Animation zu den START_TIMES-Daten hinzu. Wenn der Benutzer den Parameter startTime nicht an die Methode add übergibt, müssen wir ihm den Standardwert add(Animation, Startzeit) { wenn (Argumente.Länge < 2) Startzeit = Date.now(); dies[ANIMATIONEN].add(animation); dies[START_TIMES].set(Animation, Startzeit); } Als nächstes können wir die Logik der Startzeit umwandeln:
Der Code wird wie folgt implementiert: Start() { let startTime = Date.now(); dies[TICK] = () => { lass jetzt = Date.now(); für (let Animation davon [ANIMATIONEN]) { lass t; wenn (diese[START_TIMES].get(Animation) < Startzeit) { t = jetzt - Startzeit; } anders { t = jetzt - diese[START_TIMES].get(Animation); } wenn (t > Animationsdauer) { dies[ANIMATIONEN].löschen(Animation); t = Animationsdauer; } animation.run(t); } AnfrageAnimationFrame(dieses[TICK]); }; dies[TICK](); } Auf diese Weise unterstützt Timline jederzeit das Hinzufügen einer Animation. Um das Testen dieser neuen Funktion zu erleichtern, mounten wir sowohl Hier ändern wir den Code in Start() { let startTime = Date.now(); dies[TICK] = () => { lass jetzt = Date.now(); für (let Animation davon [ANIMATIONEN]) { lass t; wenn (diese[START_TIMES].get(Animation) < Startzeit) { t = jetzt - Startzeit; } anders { t = jetzt - diese[START_TIMES].get(Animation); } wenn (t > Animationsdauer) { dies[ANIMATIONEN].löschen(Animation); t = Animationsdauer; } animation.run(t); } AnfrageAnimationFrame(dieses[TICK]); }; dies[TICK](); } Nachdem wir mit Webpack neu verpackt haben, können wir den folgenden Befehl in der Konsole ausführen, um der Timeline eine Animation hinzuzufügen: tl.add(Animation); Okay, dies ist das aktualisierte Design der Timeline. Aber an diesem Punkt haben wir den Wert des Verzögerungsparameters noch nicht festgelegt, um die Animation zu verzögern. Tatsächlich müssen wir hier nur wenn (diese[START_TIMES].get(Animation) < Startzeit) { t = jetzt – Startzeit – Animation.Verzögerung; } anders { t = jetzt – diese[START_TIMES].get(Animation) – Animation.Verzögerung; } Wir müssen jedoch auf einen Sonderfall achten. Wenn die durch wenn (t > 0) animation.run(t); Versuchen wir dann, die Pausen- und Fortsetzen-Funktionen zu implementieren. Implementieren von Pausen- und NeustartfunktionenVersuchen wir zunächst, eine Pausenfunktion hinzuzufügen. Pause implementierenUm die Pausenfunktion für die Timeline zu implementieren, müssen wir zuerst das Häkchen entfernen. Das heißt, unsere Zeitlinie bleibt stehen. Wenn der Sekundenzeiger einer Uhr stehen bleibt, bleibt auch die Zeit stehen. Um einen Tick abzubrechen, müssen wir zunächst wissen, was passiert, wenn der Tick ausgelöst wird. Es ist selbstverständlich unser Erinnern Sie sich an Der erste Schritt besteht also darin, TICK_HANDLER zu verwenden, um unseren requestAnimationFrame zu speichern. Das Häkchen wird in der Startmethode unserer Timeline-Klasse gestartet, daher müssen wir hier Start() { let startTime = Date.now(); dies[TICK] = () => { lass jetzt = Date.now(); für (let Animation davon [ANIMATIONEN]) { lass t; wenn (diese[START_TIMES].get(Animation) < Startzeit) { t = jetzt – Startzeit – Animation.Verzögerung; } anders { t = jetzt – diese[START_TIMES].get(Animation) – Animation.Verzögerung; } wenn (t > Animationsdauer) { dies[ANIMATIONEN].löschen(Animation); t = Animationsdauer; } wenn (t > 0) animation.run(t); } dies[TICK_HANDLER] = requestAnimationFrame(dieses[TICK]); }; dies[TICK](); } Anschließend rufen wir in pause() { AnimationsFrame abbrechen (dieser [TICK_HANDLER]); } Das Anhalten ist relativ einfach, das Fortsetzen jedoch ist komplizierter. Lebenslauf implementierenDer erste Schritt zur Wiederaufnahme muss dann das Häkchen „Neustart“ sein. Aber das t (Startzeit der Animation) im Tick ist definitiv falsch, also müssen wir einen Weg finden, mit der Logik in der Pause umzugehen. Bevor wir Resume implementieren, müssen wir einige DOM-Sachen zum Testen bereitstellen. Also erstellen wir zuerst ein neues HTML und erstellen darin ein <!-- Erstellen Sie eine neue Datei animation.html (legen Sie sie in den Ordner „dist“) --> <Stil> .Kasten { Breite: 100px; Höhe: 100px; Hintergrundfarbe: Aqua; } </Stil> <Text> <div Klasse="Box"></div> <script src="./main.js"></script> </body> Dann brauchen wir // Erstellen Sie eine `animation-demo.js` im Stammverzeichnis importiere { Zeitleiste, Animation } aus './animation.js'; let tl = neue Zeitleiste(); tl.start(); tl.add( neue Animation( { Menge a(a) { konsole.log(a); }, }, 'Eigentum', 0, 100, 1000, Null ) ); Weil wir die von unserer Seite verwendete JS-Eintragdatei geändert haben. Also müssen wir hier zu modul.exporte = { Eintrag: './animation-demo.js', Modus: "Entwicklung", devServer: { Inhaltsbasis: "./dist", }, Modul: { Regeln: { Test: /\.js$/, verwenden: { Lader: 'babel-loader', Optionen: Voreinstellungen: ['@babel/preset-env'], Plugins: [['@babel/plugin-transform-react-jsx', { pragma: 'createElement' }]], }, }, }, ], }, }; Derzeit ist unser JavaScript eine simulierte Animationsausgabe. Als nächstes versuchen wir, der Animation die Möglichkeit zu geben, ein Element zu manipulieren. Wir fügen dem Element zunächst eine <div Klasse="box" id="el"></div> Dann können wir diesen Prototyp animieren. Zuerst müssen wir zu Anschließend wird die Eigenschaft des zweiten Parameters in Wir benötigen also eine Der Vorlagewert wird hier direkt als Funktion geschrieben: v => `übersetzen(${$v}px)`; Schließlich sieht unser Code folgendermaßen aus: tl.add( neue Animation( Dokument.QuerySelector('#el').style, 'verwandeln', 0, 100, 1000, 0, null, v => `übersetzen(${v}px)` ) ); Nachdem wir diesen Teil angepasst haben, müssen wir zu animation.js gehen, um entsprechende Anpassungen vorzunehmen. Der erste Schritt besteht darin, den Vorlagenparameter zum Konstruktor der Animationsklasse hinzuzufügen. Wie andere Eigenschaften ist es lediglich eine Speicheroperation im Konstruktor. Dann sollte in der Run-Methode der Animation der Wert in exportiere Klasse Animation { Konstruktor( Objekt, Eigentum, Startwert, Endwert, Dauer, Verzögerung, Timing-Funktion, Vorlage ) { dieses.Objekt = Objekt; diese.Eigenschaft = Eigenschaft; this.startValue = Startwert; dies.Endwert = Endwert; this.duration = Dauer; this.timingFunction = Zeitgebungsfunktion; this.delay = Verzögerung; diese.Vorlage = Vorlage; } Laufzeit (Zeit) { let range = dieser.Endwert - dieser.Startwert; dieses.Objekt[diese.Eigenschaft] = diese.Vorlage( this.startValue + (Bereich * Zeit) / this.duration ); } } Der endgültige Effekt ist wie folgt: Wir haben festgestellt, dass wir unsere Animationsbibliothek bereits verwenden können, um die Animation von Elementen zu steuern. Passen wir zunächst die Parameter dieser Animationen an, ändern die Start- und Endpositionen auf 0 bis 500 und ändern dann die Animationsdauer auf 2000 Millisekunden. Diese Einstellung hilft uns beim Debuggen der folgenden Funktionen. tl.add( neue Animation( Dokument.QuerySelector('#el').style, 'verwandeln', 0, 500, 2000, 0, null, v => `übersetzen(${v}px)` ) ); Okay, als nächstes fügen wir eine Pause-Taste hinzu. <Text> <div Klasse="box" id="el"></div> <button id="pause-btn">Pause</button> <script src="./main.js"></script> </body> Dann gehen wir zurück zu animation-demo.js, um dieses Element zu binden. Und lassen Sie es die Pausenmethode in unserer Timeline ausführen. document.querySelector('#pause-btn').addEventListener( 'klicken', () => tl.pause() ); Wir können sehen, dass die Pause -Funktion jetzt verfügbar ist, aber wie sollen wir die Animation fortsetzen? Das heißt, die Funktion eines Lebenslaufs zu realisieren. Bevor wir die Logik der Lebenslauffunktion implementieren, erstellen wir zunächst eine Lebenslaufschaltfläche auf die gleiche Weise. Lassen Sie diese Schaltfläche <!-Animation.html-> <Text> <div class = "box" id = "el"> </div> <button id = "pause-btn"> pause </button> <button id = "resume-btn"> Lebenslauf </button> <script src="./main.js"></script> </body> // Fügen Sie die Ereignisereignis für Lebenslauf für Animation-Demo.js hinzu. document.querySelector ('#resume-btn'). AddEventListener ( 'klicken', () => tl.resume () ); Nach der oben gesprochenen Logik besteht das grundlegendste Verständnis des Lebenslaufs darin, unsere Zecke neu zu starten. Dann versuchen wir, wieder aufnehmen() { dieses [tick] (); } In der Animation können wir sehen, dass das Feld, das die Animation neu startet, die Animation in der Original -Pauseposition nicht weitergegeben wird, wenn wir den Zecken direkt im Lebenslauf ausführen. Stattdessen sprang er nach hinten. Wenn wir auf Lebenslauf klicken, erinnert sich unsere Animation anscheinend nicht daran, wo wir waren, als wir innehalten. Wenn unsere Animation innehalten wird, müssen wir Da diese beiden Variablen in der Animationsklasse verwendet werden müssen, sollten sie im globalen Bereich definiert werden. Dann verwenden wir die beiden Konstanten const pause_start = symbol ('pause-start'); const pause_time = symbol ('pause-time'); Der nächste Schritt besteht darin, die Zeit aufzuzeichnen, in der wir innehalten: pause() { this [pause_start] = date.now (); CancelAnimationFrame (this [tick_handler]); } Warum zeichnen wir tatsächlich die Startzeit der Pause auf? Dies soll uns wissen lassen, wie lange die Zeit dauert, wenn wir anfangen zu innehalten, wenn wir die Animation weiter spielen. Was ist das Phänomen, das wir gerade in der Animation gesehen haben? Das heißt, wenn wir das Zecken neu starten, nutzt die Startzeit der Animation die aktuelle Zeit. Die hier genannte "aktuelle" Zeit bezieht sich darauf, wo die Zeitleiste erreicht ist. Offensichtlich ist diese Startzeit falsch. Wenn wir innehalten, erfassen wir die Zeit dieses Augenblicks. Wenn Sie dann auf Lebenslauf klicken, berechnen Sie die Dauer vom Beginn der Pause bis zum Zeitpunkt, an dem Sie auf Lebenslauf klicken. Auf diese Weise können wir Mit diesem Algorithmus können wir unsere Animation weiterhin genau in der ursprünglichen Pauseposition spielen. Schauen wir uns als nächstes an, wie die Codelogik implementiert wird: Wir haben gerade die Pause für die Zeitaufzeichnungslogik hinzugefügt. Vor der Aufzeichnung der Pausedauer benötigen wir einen Ort, um diesen Wert einen Anfangswert von 0 zuzuweisen. Der beste Startort ist die Zuweisung dieses Standardwerts zu Beginn der Zeitleiste. Nachdem unsere Pause_Time einen Anfangswert hat, können wir beim Ausführen von Lebenslauf das
Wenn wir Pause_time einen Wert zuweisen, verwenden wir Schließlich sieht unsere modifizierte Zeitleiste so aus: Timeline der Klasse exportieren { Konstruktor() { dies [Animationen] = new set (); this [start_times] = new map (); } Start() { let startTime = Date.now(); this [pause_time] = 0; this [tick] = () => { lass jetzt = Date.now(); für (let Animation dieser [Animationen]) { sei T; if (this [start_times] .get (Animation) <startTime) { T = jetzt - StartTime - Animation.Delay - this [pause_time]; } anders { t = now - this [start_times] .get (Animation) - Animation.Delay - this [pause_time]; } if (t> animation.duration) { Dies [Animationen] .Delete (Animation); t = Animation.Duration; } if (t> 0) Animation.run (t); } this [tick_handler] = RequestAnimationFrame (dieses [tick]); }; dieses [tick] (); } pause() { this [pause_start] = date.now (); CancelAnimationFrame (this [tick_handler]); } wieder aufnehmen() { this [pause_time] += date.now () - this [pause_start]; dieses [tick] (); } zurücksetzen() {} add (Animation, StartTime) { if (Argumente.Length <2) startTime = Datum.Now (); diese [Animationen] .Add (Animation); this [start_times] .set (Animation, StartTime); } } Lassen Sie uns den Code ausführen, um festzustellen, ob er korrekt ist: Auf diese Weise haben wir die Pause- und Lebenslauffunktionen abgeschlossen. Hier haben wir eine nutzbare Zeitleiste implementiert. Wenn Sie Entwickler sind, ist es auch eine großartige Ergänzung zu Ihrem Lebenslauf. Und wenn Sie einen super coolen Blog haben, wird es noch heller und es wird einfach glänzen.
Dadurch wird dieser Artikel über die Verwendung von JavaScript zur Implementierung von Timeline- und Animationseffekts-Beispielcode (Front-End-Komponentierung) für relevantere JS-Implementierung von Timeline-Animationsinhalten 123WordPress.coms früheren Artikeln oder weiter durchsuchen, um die folgenden Artikel zu durchsuchen. Das könnte Sie auch interessieren:
|
<<: So löschen und deinstallieren Sie MySQL in Windows 10 vollständig
>>: So führen Sie nginx in Docker aus und mounten das lokale Verzeichnis in das Image
Code kopieren Der Code lautet wie folgt: window.l...
Methode 1: Verwenden Sie den Befehl SET PASSWORD ...
CSS-Stil: Code kopieren Der Code lautet wie folgt:...
Inhaltsverzeichnis Einrichten einer einfachen HTT...
Inhaltsverzeichnis Primärschlüsseleinschränkung E...
Ich habe ein halbes Jahr lang nicht gebloggt, wofü...
Inhaltsverzeichnis Einführung So stellen Sie eine...
Dieser Artikel fasst einige einfache Prinzipien d...
Inhaltsverzeichnis Vorwort Zweidimensionales Arra...
Inhaltsverzeichnis 1. Kapselungs-API 2. Globale T...
Inhaltsverzeichnis 1. Konfigurieren Sie Bridging ...
Inhaltsverzeichnis Zusammenfassung Einfaches Beis...
Inhaltsverzeichnis Installation des ESLint-Plugin...
Logo-Optimierung: 1. Das Logobild sollte so klein...
Lösung für Host „xxxx“ darf keine Verbindung zu d...