JSはプログレスバーのスムーズバージョンの詳細な計画を実装します

JSはプログレスバーのスムーズバージョンの詳細な計画を実装します

進捗バーがスムーズではない

フロントエンドを学ぶ学生のほとんどは、オーディオプレーヤーやビデオプレーヤーを自分で作成しており、実装は複雑ではないと思います。最近、Weiboで動画を視聴するのと同様の要件がミニプログラムに作成されました。一部の機能では、カスタム プログレス バーの実装が必要です。最初のバージョンを完了した後、プログレス バーがスムーズでないことに気付きました。その後、オンラインで調べて、良い解決策があるかどうかを確認したいと思いましたが、結局適切なものは見つかりませんでした。そこで、WeChatミニプログラム内の「Weibo」プログレスバーがどのように見えるかを確認したかったのですが、結果も非常に硬いアニメーションになりました。下にGIFを置きました。自分でWeChatミニプログラムでWeiboを検索して、効果を確認するビデオを見つけることもできます。

従来の解決策

最終的に、この問題を最適化することにしました。まず、既存の従来のソリューションを確認しましょう。

  • TimeUpdate イベントのリッスン
  • 現在の再生時間を取得し、合計時間に基づいて進行状況のパーセンテージを計算します (currentTime /duration * 100)
  • プログレスバーの幅プロパティは進行状況のパーセンテージを設定します

既存のソリューションは、現在の再生時間を取得するためにイベントに依存しており、このイベントは約 100 ~ 350 ミリ秒ごとに 1 回トリガーされます。以下は、記録したアプレットのイベント オブジェクト キューです。

[
    {"詳細":{"現在の時間":0.10509,"継続時間":5.83}},
    {"詳細":{"現在の時間":0.364527,"期間":5.83}},
    {"詳細":{"現在の時間":0.613648,"期間":5.83}},
]

現在の問題は、イベントが取得されるたびに、進行状況バーが遷移アニメーションなしで更新され、非常に突然になることです。以下は、合計期間が 5 秒の進行状況バーの変更プロセスです。

コアコード:

定数 onProgress = (e, $dom) => {
    const updateFunc = (パーセント) => {
        $dom.style.width = パーセント+'%'
    }
    パーセント = ((e.detail.currentTime / e.detail.duration) * 100).toFixed(1) とします。
    updateFunc(パーセント)
}

遷移

最適化のために CSS アニメーション プロパティを使用することはすぐに考えられます。柔軟な制御が必要な場合は、トランジションを使用することを選択します。トランジションは、アニメーションの実行期間を定義できます。幅を変更すると、トランジションは指定された時間内にプログレス バーの幅をアニメーションで変更します。まず、アニメーションの実行期間は固定する必要があり、前回の実行期間が終了する前に幅を変更しないことが最善です。そうしないと、競合が発生し、アニメーションがおかしくなります。

  • 適切な遷移実行時間を選択してください: 0.5秒
  • 現在の合計継続時間に応じて、進行状況バーの 0.5 秒のパーセンテージを調べます (100/継続時間/2)
  • 最初のTimeUpdateイベントは幅の変更を実行し、プログレスバーを0.5秒の位置に設定します: width = 100/duration/2
  • 最初のTimeUpdateイベントではありません。currentTimeが前の進捗バーの位置を超えるたびに、現在の進捗バーのパーセンテージが更新されます。

ちょっとわかりにくいので、図を描いてみましょう。

  1. TimeUpdate イベントが 0.1336 秒 (もちろんこの値はランダムで、0.1 ~ 0.3 の間になります) で初めてトリガーされたときに、幅を 0.5 秒に設定して、実際の進行状況とのわずかな差 0.1 秒で進行状況バーがビデオと同期して動くようにします。アニメーション実行の 0.5 秒間に、UpdateTime が複数回トリガーされます。
  2. ある UpdateTime の currentTime (0.7123 秒、この値もランダム) が前回の実行の 0.5 秒より大きい場合、プログレス バーの位置も 0.5 秒付近になります。次の 0.5 秒のアニメーションを再度トリガーします。つまり、幅をプログレス バーの位置 1 秒に設定します。
  3. 次の反復では、currentTime>1s、width は 1.5s に設定され、サイクルが継続されます。

コアコード:

const プレイコントロール = {
  パーセント: 0,
  時間: 0,
  期間: 0,
  最初: 本当
}
定数 onProgress = (e, $dom) => {
    const updateFunc = (パーセント) => {
        playControl.percent = パーセント
        再生コントロール時間 = e.detail.currentTime
        $dom.style.width = パーセント+'%'
    }
    //現在のビデオの進行状況が初めて更新される if (playControl.first) {
        再生コントロール期間 = e.detail.duration
        playControl.first = false
        updateFunc(100 / e.detail.duration / 2)
    } それ以外 {
        パーセント = ((e.detail.currentTime / e.detail.duration) * 100).toFixed(1) とします。
        if (パーセント - playControl.percent > 0 || e.detail.currentTime >= e.detail.duration) {
            updateFunc(パーセント)
        }
    }
}

最終的な効果の比較(追記:gif画像の効果は損なわれています)

60年代バージョンは通常バージョンと似ていますか?他の 60 をブロックして比較してみると、まだいくつかの違いがあることがわかります。

まだ説明するのが少し難しいですか、それともまだ理解できないですか? github リポジトリのコードに直接アクセスすると、コードを直接実行できます: https://github.com/zimv/smooth-progress

このソリューションでは、一時停止、ドラッグなどの一部のシナリオで短い遅延が発生します。個人的には、利点が欠点を上回ると思います。

JS でスムーズなプログレスバーを実装するための詳細なソリューションに関するこの記事はこれで終わりです。スムーズな JS プログレスバーに関するより関連性の高いコンテンツについては、123WORDPRESS.COM で以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後も 123WORDPRESS.COM を応援していただければ幸いです。

以下もご興味があるかもしれません:
  • JSは制御可能なプログレスバーを実装します
  • vue.js+ElementUI はパスワードの強度を促すプログレスバーの効果を実現します
  • JS+html5 で画像の非同期アップロードを実現し、アップロードファイルの進行状況バー機能の例を表示する
  • ネイティブ js で実装されたモバイル ドラッグ可能なプログレス バー プラグイン機能の詳細な説明
  • js+HTML5 キャンバスでシンプルな読み込みバー (プログレスバー) 関数を実装する例
  • JS でダウンロード進行状況バーと再生進行状況バーを実装するためのコード
  • JS ベースのアニメーション効果を備えたプロセス進行状況バーの実装

<<:  VMware 仮想マシンでの CentOS7 ネットワーク構成 (ホストのワイヤレス インターネット アクセス)

>>:  MySQLで適切なインデックスを選択する方法

推薦する

Web フロントエンドのパフォーマンス最適化の詳細説明: リソースのマージと圧縮

2つの目的のためのリソースの結合と圧縮httpリクエストの数を減らす要求されたリソースのサイズを縮小...

CentOS 7 で RPM パッケージを使用して MySQL 5.7.9 をインストールするチュートリアル

MySQL 5.7.9 のインストールチュートリアルを録画してみんなと共有しましょう環境の紹介:オペ...

Windows での Nginx のインストールと環境設定 (nginx をサービスとして実行)

最初で最も重要なステップは、Windows 環境に Ngnix サービスをインストールする方法です。...

CSS テキスト強調を使用してテキストを強調するための実装コード

1. はじめにこれまで、テキストの特定の部分を強調したい場合、通常は太字にしたり明るい色を使用したり...

Dockerイメージサイズを最適化する一般的な方法

通常、私たちが構築する Docker イメージはサイズが大きく、多くのディスク領域を占有します。コン...

ウェブページのコピー防止機能の実装方法(クラッキング手法付き)

ソース ファイルを右クリックすると、次のコードが見つかります。 1. CSSを使用してFirefox...

Apache Bench で Web ストレス テストを実装する方法

1. Apache Benchの紹介ApacheBench は、Apache サーバーに付属する W...

JSにおける合同と不等式、等式と不等式の問題について

目次一致と不一致一致するすべてが平等ではない平等と不平等等しい等しくない一致と不一致シンボルの両側の...

MySQL インポートおよびエクスポートのバックアップの詳細

目次1. MySQLのバックアップタイプの詳細な説明1. バックアップがデータベースに与える影響に基...

プレーンな JS オブジェクトの代わりに Map を使用する場合

目次1. マップは任意のタイプのキーを受け入れます2. マップにはキー名に関する制限はありません3....

jsイベント委譲の詳細な説明

1. 各関数はオブジェクトであり、メモリを占有します。メモリ内のオブジェクトが増えるほど、パフォーマ...

モバイルデバイス上の 1px 境界線を解決する最善の方法 (推奨)

モバイル デバイス向けに開発する場合、Retina 画面上で要素の境界線が太くなるという問題に遭遇す...

IE9 のネイティブ ページ互換性の問題に対する解決策についての簡単な説明

序文最近、クライアントのネイティブページを引き継ぎました。顧客は、ページが IE9 以降のバージョン...

Linux システムで IPv6 をサポートするように Nginx を設定する方法

1. 既存のnginxがipv6をサポートしているかどうかを確認する既存の nginx が ipv6...

スクロール時に選択領域のフォント色を暗くするために CSS を使用するサンプルコード

日付ピッカーをカプセル化する場合、選択時にフォントの色を暗くする必要があります。実装後の効果を見てみ...