JS implementiert einen detaillierten Plan für die reibungslose Version des Fortschrittsbalkens

JS implementiert einen detaillierten Plan für die reibungslose Version des Fortschrittsbalkens

Der Fortschrittsbalken ist nicht gleichmäßig

Ich glaube, dass die meisten Front-End-Studenten Audio- und Videoplayer selbst geschrieben haben und die Implementierung nicht kompliziert ist. Kürzlich wurde in einem Miniprogramm eine Anforderung erstellt, die dem Ansehen von Videos auf Weibo ähnelt. Einige der Funktionen erfordern die Implementierung eines benutzerdefinierten Fortschrittsbalkens. Nachdem ich die erste Version fertiggestellt hatte, stellte ich fest, dass der Fortschrittsbalken nicht gleichmäßig war. Dann wollte ich online nachsehen, ob es gute Lösungen gibt, aber am Ende habe ich keine passende gefunden. Ich wollte also sehen, wie der „Weibo“-Fortschrittsbalken im WeChat-Miniprogramm aussieht, und das Ergebnis war auch eine sehr steife Animation. Ich habe unten ein GIF eingefügt. Sie können auch selbst im WeChat-Miniprogramm nach Weibo suchen und ein Video finden, um den Effekt zu sehen.

Konventionelle Lösung

Schließlich haben wir uns entschieden, dieses Problem zu optimieren. Lassen Sie uns zunächst unsere bestehenden konventionellen Lösungen überprüfen.

  • Warten auf TimeUpdate-Ereignisse
  • Holen Sie sich die aktuelle Wiedergabezeit und berechnen Sie den Fortschrittsprozentsatz basierend auf der Gesamtzeit (aktuelle Zeit / Dauer * 100).
  • Die Eigenschaft „Fortschrittsbalkenbreite“ legt den Fortschrittsprozentsatz fest

Die vorhandene Lösung verwendet Ereignisse, um die aktuelle Wiedergabezeit zu ermitteln. Dieses Ereignis wird etwa alle 100 bis 350 Millisekunden ausgelöst. Nachfolgend sehen Sie die Ereignisobjektwarteschlange des Applets, das ich aufgezeichnet habe.

[
    {"detail":{"currentTime":0.10509,"duration":5.83}},
    {"detail":{"currentTime":0.364527,"duration":5.83}},
    {"detail":{"currentTime":0.613648,"duration":5.83}},
]

Das aktuelle Problem besteht darin, dass der Fortschrittsbalken jedes Mal, wenn ein Ereignis eintrifft, ohne Übergangsanimation aktualisiert wird, was sehr abrupt ist. Im Folgenden sehen Sie einen Fortschrittsbalken-Änderungsprozess mit einer Gesamtdauer von 5 Sekunden:

Kerncode:

const onProgress = (e, $dom) => {
    const updateFunc = (Prozent) => {
        $dom.style.width = Prozent+'%'
    }
    let Prozent = ((e.detail.currentTime / e.detail.duration) * 100).toFixed(1)
    updateFunc(Prozent)
}

Übergang

Wir können schnell darüber nachdenken, CSS-Animationseigenschaften zur Optimierung zu verwenden. Wenn wir eine flexible Steuerung wünschen, wähle ich den Übergang. Der Übergang kann die Ausführungsdauer der Animation definieren. Wenn wir die Breite ändern, ändert der Übergang die Breite des Fortschrittsbalkens auf animierte Weise innerhalb der angegebenen Zeit. Zunächst muss die Ausführungsdauer der Animation festgelegt werden. Am besten ändern Sie die Breite nicht, bevor die vorherige Ausführungsdauer endet. Andernfalls treten Konflikte auf und die Animation wird seltsam.

  • Wählen Sie eine angemessene Übergangsausführungszeit: 0,5 s
  • Ermitteln Sie anhand der aktuellen Gesamtdauer den Prozentsatz von 0,5 Sekunden im Fortschrittsbalken (100/Dauer/2).
  • Das erste TimeUpdate-Ereignis führt die Breitenänderung aus und setzt den Fortschrittsbalken auf die 0,5-Sekunden-Position: Breite = 100/Dauer/2
  • Nicht das erste TimeUpdate-Ereignis. Immer wenn currentTime die vorherige Position des Fortschrittsbalkens überschreitet, wird der aktuelle Prozentsatz des Fortschrittsbalkens aktualisiert.

Das klingt ein bisschen schwer zu verstehen, lasst uns ein Bild zeichnen:

  1. Wenn das TimeUpdate-Ereignis zum ersten Mal ausgelöst wird, nämlich bei 0,1336 Sekunden (dieser Wert ist natürlich zufällig und kann zwischen 0,1 und 0,3 liegen), stellen wir die Breite auf 0,5 Sekunden ein, sodass sich der Fortschrittsbalken synchron mit dem Video bewegt, mit einer kleinen Differenz von 0,1 Sekunden zum tatsächlichen Fortschritt. Während der 0,5 Sekunden dauernden Ausführung der Animation wird UpdateTime mehrmals ausgelöst.
  2. Wenn die aktuelle Zeit (0,7123 s, dieser Wert ist ebenfalls zufällig) einer bestimmten UpdateTime größer als die 0,5 s der letzten Ausführung ist, beträgt die Position des Fortschrittsbalkens ebenfalls etwa 0,5 s. Wir lösen die nächste 0,5-s-Animation erneut aus, d. h. wir stellen die Breite auf die Position des Fortschrittsbalkens von 1 s ein.
  3. Dann wird in der nächsten Iteration, currentTime>1s, die Breite auf 1,5s eingestellt und der Zyklus wird fortgesetzt.

Kerncode:

const Spielsteuerung = {
  Prozent: 0,
  Zeit: 0,
  Dauer: 0,
  zuerst: wahr
}
const onProgress = (e, $dom) => {
    const updateFunc = (Prozent) => {
        playControl.percent = Prozent
        Spielsteuerung.Zeit = e.Detail.aktuelleZeit
        $dom.style.width = Prozent+'%'
    }
    //Der aktuelle Videofortschritt wird zum ersten Mal aktualisiert if (playControl.first) {
        playControl.duration = e.detail.duration
        playControl.first = falsch
        Aktualisierungsfunktion (100 / e.detail.dauer / 2)
    } anders {
        let Prozent = ((e.detail.currentTime / e.detail.duration) * 100).toFixed(1)
        wenn (Prozent - PlayControl.Prozent > 0 || e.detail.currentTime >= e.detail.duration) {
            updateFunc(Prozent)
        }
    }
}

Endgültiger Effektvergleich (PS: Der GIF-Bildeffekt ist beeinträchtigt)

Die 60er-Version sieht der normalen Version ähnlich? Blockieren Sie die anderen 60er und vergleichen Sie sie miteinander, und Sie werden feststellen, dass es immer noch einige Unterschiede gibt.

Es ist immer noch ein bisschen schwer zu erklären oder du verstehst es immer noch nicht? Gehen Sie direkt zum Code des GitHub-Repositorys. Der Code kann direkt ausgeführt werden: https://github.com/zimv/smooth-progress

Bei dieser Lösung kommt es in manchen Szenarien zu einer kurzen Verzögerung, z. B. beim Anhalten, Ziehen usw. Ich persönlich denke, dass die Vorteile die Nachteile überwiegen.

Dies ist das Ende dieses Artikels über die detaillierte Lösung zur Implementierung der glatten Version des Fortschrittsbalkens mit JS. Weitere relevante Inhalte zur glatten Version des JS-Fortschrittsbalkens finden Sie in früheren Artikeln auf 123WORDPRESS.COM oder durchsuchen Sie die verwandten Artikel weiter unten. Ich hoffe, Sie werden 123WORDPRESS.COM auch in Zukunft unterstützen!

Das könnte Sie auch interessieren:
  • JS implementiert einen steuerbaren Fortschrittsbalken
  • vue.js + ElementUI realisiert den Effekt des Fortschrittsbalkens, der zur Kennwortstärke auffordert
  • JS + HTML5 zum asynchronen Hochladen von Bildern und Anzeigen des Funktionsbeispiels für den Fortschrittsbalken beim Hochladen von Dateien
  • Detaillierte Erläuterung der Plug-In-Funktion für mobile ziehbare Fortschrittsbalken, die von nativem js implementiert wird
  • js+HTML5-Canvas zur Implementierung eines einfachen Ladebalken-Funktionsbeispiels (Fortschrittsbalken)
  • Code zur Implementierung eines Download-Fortschrittsbalkens und eines Wiedergabe-Fortschrittsbalkens in JS
  • Implementierung eines Prozessfortschrittsbalkens mit Animationseffekten basierend auf JS

<<:  CentOS7-Netzwerkkonfiguration unter virtueller VMware-Maschine (Host für drahtlosen Internetzugang)

>>:  So wählen Sie den richtigen Index in MySQL

Artikel empfehlen

So stellen Sie per SSH eine Verbindung zum Docker-Server her

Als ich zum ersten Mal mit Docker in Berührung ka...

Installation und Verwendung von Apache-Stresstest-Tools

1. Herunterladen Gehen Sie zur offiziellen Apache...

Beispiel für eine automatische Importmethode für allgemeine Vue3.0-Komponenten

1. Voraussetzungen Wir verwenden zum Importieren ...

Eine kurze Diskussion über MySql-Ansichten, Trigger und gespeicherte Prozeduren

Sicht Was ist eine Ansicht? Welche Rolle spielt e...

JavaScript implementiert eine bidirektionale verknüpfte Listenprozessanalyse

Inhaltsverzeichnis 1. Was ist eine doppelt verknü...

JavaScript Canvas implementiert die Bewegung des Balls entlang der Maus

In diesem Artikelbeispiel wird der spezifische Co...

Beispiel einer langsamen MySQL-Abfrage

Einführung Durch Aktivieren des Slow Query Log ka...

MySQL-Gruppe durch Gruppieren mehrerer Felder

Bei täglichen Entwicklungsaufgaben verwenden wir ...

Detaillierte Erklärung des MySQL-Prepare-Prinzips

Vorteile von Prepare Der Grund, warum Prepare SQL...

Beispiele für häufige Nginx-Fehlkonfigurationen

Inhaltsverzeichnis Fehlender Stammspeicherort Off...

Eine kurze Analyse der asynchronen DOM-Aktualisierung von Vue

Inhaltsverzeichnis Das Prinzip der asynchronen DO...