Beispielcode zur Implementierung von Zeitleisten- und Animationseffekten mit JavaScript (Front-End-Komponentenbildung)

Beispielcode zur Implementierung von Zeitleisten- und Animationseffekten mit JavaScript (Front-End-Komponentenbildung)

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 CSS Animation implementiert, das keine Anpassungen oder entsprechenden Änderungen aufweist.

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-Bereinigung

Zunä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 carousel.js “ und verschieben Sie dann alle mit der Karussellkomponente verbundenen Codes in unserer main.js nach „carousel.js“.

In carousel.js müssen wir nur Component importieren und dann unsere Karussellklasse exportieren. Die Codestruktur ist wie folgt:

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: animation.js .

Wir müssen diese Zeitleiste verwenden, um unsere nachfolgende Animationsbibliothek zu implementieren. In der Animation gibt es ein sehr wichtiges Konzept: „ Frame “.

Die grundlegendste Animationsfunktion besteht darin, pro Frame ein Ereignis auszuführen.


"Frames" in JavaScript

Da 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.

Aus diesem Grund verwenden wir üblicherweise 16 Millisekunden als Framelänge.


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 , das wir tatsächlich beim Schreiben des Karussells verwendet haben. Um eine Logik in jedem Frame auszuführen, gehen Sie folgendermaßen vor:

setInterval(() => {/** Was passiert in einem Frame*/}, 16)

Das hier eingestellte Zeitintervall beträgt 16 Millisekunden, die Länge eines Frames.

2. setTimeout

Wir 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.

Im Allgemeinen wird diese Art von setTimeout, das als Frame in der Animation verwendet wird, tick genannt. Denn „tick“ ist im Englischen das Geräusch, das entsteht, wenn der Sekundenzeiger unserer Uhr eine Sekunde weitergeht. Dieses Geräusch wird auch als Wort verwendet, um einen Frame/eine Sekunde auszudrücken.

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 requrestAnimationFrame (auch RAF genannt). Dies wird häufig beim Schreiben von Animationen verwendet und erfordert keine Definition der Dauer eines Frames.

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 requestAnimationFrame empfohlen.

„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.

Denn die hier von uns implementierte Animationsbibliothek muss die Kompatibilität alter Browser nicht berücksichtigen. Wir entscheiden uns hier für die Verwendung von requestAnimationFrame.

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 tick in eine Timeline packen.

Als nächstes implementieren wir gemeinsam diese Timeline-Klasse. Normalerweise muss eine Timeline nur start werden und es gibt keinen stop -Zustand. Da eine Timeline auf jeden Fall bis zum Ende abgespielt wird, ist ein Stopp mittendrin nicht möglich.

Es verfügt jedoch über eine Kombination aus pause und resume . Diese Gruppe von Zuständen ist auch in der Timeline eine sehr wichtige Funktion. Wenn wir beispielsweise viele Animationen schreiben, müssen wir sie alle zur Ausführung in dieselbe Animationszeitleiste einfügen. Während des Ausführungsvorgangs kann ich die Wiedergabe aller dieser Animationen anhalten und fortsetzen.

Eine weitere Sache ist die rate (Wiedergabegeschwindigkeit), diese ist allerdings nicht für alle Zeitleisten verfügbar. Rate hat zwei Methoden, eine ist set und die andere ist get . Da die Wiedergaberate ein Vielfaches beträgt, können wir die Animation schnell vorspulen oder verlangsamen.

Beim Entwerfen dieser Animationsbibliothek gibt es auch ein sehr wichtiges Konzept namens reset . Dadurch wird die gesamte Zeitleiste bereinigt, sodass wir einige Zeitleisten wiederverwenden können.

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 pause und resume sind für unser Karussell von entscheidender Bedeutung, deshalb müssen wir sie hier implementieren.

Nachdem so viel gesagt wurde, fangen wir an! ~

Implementieren der Startfunktion

In unserer Startmethode wird es einen Prozess zum Starten tick geben. Hier wählen wir aus, dieses Häkchen zu einer privaten Methode zu machen (es auszublenden). Andernfalls kann jeder diesen Tick aufrufen, wodurch das gesamte Statussystem der Timeline-Klasse durch externe Benutzer leicht zerstört werden kann.

Wie können wir die Zecke also perfekt verstecken? Wir deklarieren eine Konstante namens TICK im globalen Bereich der Datei animation.js. Und verwenden Sie Symbol , um ein Häkchen zu erstellen. Auf diese Weise kann das Häkchen-Symbol nirgendwo anders abgerufen werden, außer dass wir unser Häkchen in animation.js abrufen können.

In ähnlicher Weise kann requestAnimationFrame in Tick auch eine globale Variable TICK_HANDLER erstellen, um es zu speichern. Diese Variable wird auch in ein Symbol eingeschlossen, sodass sie nur in dieser Datei verwendet werden kann.

Für diejenigen, die mit Symbolen nicht so vertraut sind: Wir können es eigentlich als eine Art „Sonderzeichen“ verstehen. Auch wenn wir beide an das Symbol übergebenen Schlüssel ‚Tick‘ nennen, werden die beiden erstellten Werte unterschiedlich sein. Dies ist eine Funktion von Symbol.

Tatsächlich haben wir in unserem vorherigen Artikel „Front-End – Erweiterte Funktionen“ auch ausführlich über Symbole gesprochen und sie verwendet. Beispielsweise haben wir Symbol verwendet, um das Dateiendesymbol EOF (End Of File) darzustellen. Daher ist die Funktion als Schlüssel zu einem Objekt nicht seine einzige Verwendung. Das einzigartige Merkmal eines Symbols ist eine der Bedeutungen seiner Existenz.

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 TICK direkt in der start aufrufen. Auf diese Weise beginnt die Zeit in unserer Timeline mit einer Wiedergaberate von 60 Frames zu laufen.

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 Animationsklasse

Als 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:

  • object : das zu animierende Elementobjekt
  • property : Die zu animierende Eigenschaft
  • startValue : Startwert der Animation
  • endValue : Endwert der Animation
  • duration : Dauer der Animation
  • timingFunction : Animation und Zeitverlauf

Was wir hierbei beachten müssen, ist, dass die übergebene Eigenschaft im Allgemeinen mit einer Einheit versehen ist, beispielsweise: px (Pixel). Weil unser startValue und endValue ein Wert in JavaScript sein müssen. Wenn wir also eine vollständige Animation möchten, müssen wir weitere Parameter übergeben.

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 run . Ich persönlich denke, dass es der Funktion besser entspricht.

Diese Funktion muss einen time erhalten, der eine virtuelle Zeit ist. Wenn wir Echtzeit verwenden, müssen wir nicht einmal eine Zeitleiste erstellen.

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.

Formel:變化區間(range) = 終止值(endValue) - 初始值(startValue)

Nachdem wir變換區間ermittelt haben, können wir berechnen, wie stark sich die Animation in jedem Frame ändern soll. Die Formel lautet wie folgt:

變化值= 變化區間值(range) * 時間(time) / 動畫時長(duration)

Der hier erhaltene Änderungswert berechnet einen progression (Fortschritt %) basierend auf der aktuellen Ausführungszeit und der Gesamtdauer der Animation und verwendet dann diesen Fortschrittsprozentsatz und den Änderungsbereich, um die Differenz zwischen unserem Anfangswert und dem aktuellen Fortschrittswert zu berechnen. Diese Differenz ist unser變化值.

Dieser Änderungswert entspricht der linear Animationskurve in unserer CSS-Animation. Diese Animationskurve ist eine gerade Linie. Hier verwenden wir dies, um zuerst unsere Animation zu implementieren, ohne uns mit unserer timingFunction zu befassen. Mit dieser dynamischen Animationskurve werden wir uns später befassen.

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 add() Methode hinzufügen. Die Implementierungslogik ist wie folgt:

Konstruktor() {
 dies[ANIMATIONEN] = neues Set();
}

Wir müssen die aktuelle Ausführungsdauer an den run in der Timeline übergeben. Um diese Dauer zu berechnen, müssen Sie am Anfang der Zeitleiste eine Startzeit aufzeichnen. Dann wird jedes Mal, wenn eine Animation ausgelöst wird,當前時間- Timeline 開始時間verwendet, um zu ermitteln, wie lange sie bereits ausgeführt wird.

Der vorherige tick wurde jedoch im constructor geschrieben, und die Startzeit der Zeitleiste muss in die Startmethode eingefügt werden. Um diese Zeit bequemer zu erhalten, können wir die Tick-Deklaration direkt in Start einfügen.

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 console.log(time) hinzu, um das Debuggen zu erleichtern.

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 start ändern und eine bedingte Beurteilung hinzufügen, bevor animation.run ausgeführt wird. Hier müssen wir feststellen, ob die aktuelle Zeit länger ist als die Dauer der Animation. Wenn die Animation erstellt ist, kann sie gestoppt werden und muss aus der ANIMATIONS-Warteschlange entfernt werden.

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 Designzeitplans

Als 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ügt

Wä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 add() Methode der Timeline beim Hinzufügen der Animation zur Warteschlange eine Verzögerung hinzu.

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 t und t0 nicht unbedingt identisch sind. Weil unsere Startzeit basierend auf der Verzögerung manuell definiert werden kann. Daher müssen wir die Logik für diesen Wert neu schreiben.

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 delay hinzuzufügen und ihn im Attributobjekt der Klasse zu speichern.

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 START_TIMES Speicherplatz erstellen, um die Startzeit aller unserer Animationen zu speichern.

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 Date.now() zuweisen.

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 erste Fall: Wenn die Startzeit unserer Animation vor der Startzeit der Zeitleiste liegt, dann ist der Zeitverlauf unserer aktuellen Animation當前時間- Timeline 開始時間
  • Der zweite Fall: Die Startzeit der Animation ist größer als die Startzeit der Timeline, dann ist der Zeitverlauf der aktuellen Animation當前時間- 動畫的開始時間

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 tl als auch animation im window .

Hier ändern wir den Code in main.js :

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 t berechnen und dann animation.delay davon abziehen.

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 t - 延遲時間erhaltene Zeit kleiner als 0 ist, bedeutet dies, dass unsere Animation nicht die für die Ausführung erforderliche Zeit erreicht hat. Die Animation muss nur ausgeführt werden, wenn t > 0 ist. Fügen Sie der Logik der Animationsausführung abschließend eine Beurteilung hinzu.

wenn (t > 0) animation.run(t);

Versuchen wir dann, die Pausen- und Fortsetzen-Funktionen zu implementieren.


Implementieren von Pausen- und Neustartfunktionen

Versuchen wir zunächst, eine Pausenfunktion hinzuzufügen.

Pause implementieren

Um 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 requestAnimationFrame .

Erinnern Sie sich an TICK_HANDLER , den wir am Anfang deklariert haben? Diese Konstante wird zum Speichern unseres aktuellen Tick-Ereignisses verwendet.

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 requestAnimationFrame in der Startmethode ändern:

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() den folgenden cancelAnimationFrame auf.

pause() {
 AnimationsFrame abbrechen (dieser [TICK_HANDLER]);
}

Das Anhalten ist relativ einfach, das Fortsetzen jedoch ist komplizierter.

Lebenslauf implementieren

Der 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 div Element.

<!-- 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 main.js nicht mehr und erstellen ein weiteres animation-demo.js um unsere Animationsaufrufe zu implementieren. Auf diese Weise müssen wir unser Karussell nicht durcheinanderbringen.

// 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 webpack.config.js gehen und den Eintrag in animation-demo.js ändern.

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 id="el" hinzu, um es uns zu erleichtern, dieses Element im Skript abzurufen.

<div Klasse="box" id="el"></div>

Dann können wir diesen Prototyp animieren. Zuerst müssen wir zu animation-demo.js zurückkehren und den ersten Parameter der Animationsinstanziierung in document.querySelector('#el').style ändern.

Anschließend wird die Eigenschaft des zweiten Parameters in "transform" geändert. Beachten Sie jedoch, dass die folgende Start- und Endzeit nicht für das Transform-Attribut verwendet werden kann.

Wir benötigen also eine template und verwenden diese Vorlage, um die Zeit in den entsprechenden Transformationswert umzuwandeln.

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 this.object[this.property] die Vorlagenmethode aufrufen, um den Eigenschaftswert zu generieren. Anstatt es wie bisher direkt einem bestimmten Attribut zuzuordnen.

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 resume() in unserer Zeitleiste aufrufen.

<!-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, this[TICK]() direkt in der Lebenslaufmethode auszuführen.

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暫停的開始時間aufzeichnen und暫停時間.

Da diese beiden Variablen in der Animationsklasse verwendet werden müssen, sollten sie im globalen Bereich definiert werden. Dann verwenden wir die beiden Konstanten PAUSE_START und PAUSE_TIME , um sie zu speichern.

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 t(動畫開始時間)- 暫停時長= 當前動畫應該繼續播放的時間.

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 Date.now() - PAUSE_START verwenden.

Es gibt hier einen Punkt, auf den wir achten müssen. Unsere Animation kann mehrmals angehalten und mehrmals wieder aufgenommen werden. In diesem Fall, wenn wir diese Formel verwenden, um die neue Pausedauer jedes Mal zu berechnen und dann den Wert von pause_time zu überschreiben, ist sie tatsächlich falsch.

Denn sobald unsere Timeline begonnen ist, wird es nicht aufhören und die Zeit wird weiter vergehen. Wenn wir nur die aktuelle Pausedauer jedes Mal berechnen, ist die Fallback -Zeit tatsächlich falsch. Die korrekte Art und Weise ist, die Dauer der vorherigen Pause jedes Mal hinzuzufügen, wenn Sie innehalten. Auf diese Weise ist die endgültige Rollback -Zeit genau.

Wenn wir Pause_time einen Wert zuweisen, verwenden wir += anstatt den Wert zu überschreiben.

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.

Thema Github Adresse: https://github.com/aural-ui/hexo-theme-aurora
Themendokumentation: https://aurora.tridiamond.tech/zh/


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:
  • D3.JS implementiert den Stichprobencode des Topologiediagramms mit teleskopischer Zeitleiste
  • AngularJS -Probencode, um den Zeitleisteneffekt zu erzielen
  • JS, um den Effekt der automatischen Anordnung der Zeitachse zu erreichen
  • TimergLiderJS ist ein JQuery-basierter Timeline-Plugin

<<:  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

Artikel empfehlen

Mehrere allgemeine Beispielcodes für Weiterleitungsverbindungen in HTML

Code kopieren Der Code lautet wie folgt: window.l...

CSS-Stil zum Zentrieren des HTML-Tags im Browser

CSS-Stil: Code kopieren Der Code lautet wie folgt:...

So verwenden Sie die asynchrone Anforderungs-API von Axios in Vue

Inhaltsverzeichnis Einrichten einer einfachen HTT...

impress.js Präsentationsschicht-Framework (Demonstrationstool) - erste Erfahrungen

Ich habe ein halbes Jahr lang nicht gebloggt, wofü...

Einfache Prinzipien für die Gestaltung des Webseiten-Layouts

Dieser Artikel fasst einige einfache Prinzipien d...

Eine kurze Zusammenfassung aller Kapselungsmethoden in Vue

Inhaltsverzeichnis 1. Kapselungs-API 2. Globale T...

Einführung in RHCE-Bridging, passwortfreie Anmeldung und Portnummernänderung

Inhaltsverzeichnis 1. Konfigurieren Sie Bridging ...

Implementierung der CSS-Variableneinfügung im Vue3-Stil

Inhaltsverzeichnis Zusammenfassung Einfaches Beis...

Vorschläge zur Optimierung der Webseiten-Kopfzeile

Logo-Optimierung: 1. Das Logobild sollte so klein...