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で適切なインデックスを選択する方法

推薦する

Centos7 での Mysql5.7.19 の詳細なインストールチュートリアル

1. ダウンロード公式サイトからmysql-5.7.19-linux-glibc2.12-x86_6...

LED を使って Linux カーネルを使い始める方法を探る

目次序文LEDトリガー探索を始めるLEDデバイス登録LEDディレクトリ類推によって理解するクラスディ...

Dockerfile における ENV 命令の具体的な使用法の詳細な説明

1. Dockerfile 内の ENV 命令は、イメージの環境変数を定義するために使用されます。次...

Vue2.x における双方向バインディングの原理と実装

目次1. 実施プロセス2. オブザーバーを表示する3. ウォッチャーを実装する4. コンパイルを実装...

HTML構造化実装方法

DIV+css構造 CSSレイアウトを学んでいますか?まだ純粋な CSS レイアウトを完全に習得でき...

Zabbixで監視する必要があるホストを追加するための詳細な手順

監視ホストの追加ホスト 192.168.179.104 が zabbix 監視項目に追加されます (...

Node の SMS API で検証コード ログインを実装するためのサンプル コード

1. ノードサーバーのセットアップ + データベース接続ここでの操作は比較的簡単でわかりやすいです。...

2級コンピュータ試験のMySQL知識ポイント mysql alterコマンド

テーブル構造を編集するための MySQL の alter コマンドの使用。具体的な内容は以下のとおり...

リストループスクロールを実現するための HTML+CSS+JavaScript サンプルコード

説明: 指定された時間内に前のノードのコンテンツを置き換えるタイマーを設定します。 1. キーコード...

MySQL トランザクションの概念と使用法の詳細な説明

目次情事の概念取引の状態取引の役割取引の特徴トランザクション構文トランザクション対応ストレージエンジ...

JavaScript における Promise の詳細な説明

目次Promise の基本的な使用法: 1. Promiseオブジェクトを作成する2. プロミス方式...

React Native環境のインストールプロセス

react-native インストールプロセス1.npx react-native init Awe...

MySQLは集計関数を使用して単一のテーブルをクエリします

集計関数データセットに作用し、そのデータセットの値を返します。 count: 統計結果のレコード数。...

React Hooksの詳細な説明

目次フックとは何ですか?クラスコンポーネント機能コンポーネントフックが作られた理由要約するフックとは...

DockerコンテナにNFS共有ディレクトリをマウントする実装

以前、https://www.jb51.net/article/205922.htm で、Docke...