JS implements a detailed plan for the smooth version of the progress bar

JS implements a detailed plan for the smooth version of the progress bar

The progress bar is not smooth

I believe that most front-end students have written audio and video players by themselves, and the implementation is not complicated. Recently, a requirement similar to watching videos on Weibo was created in a mini program. Some of the functions require the implementation of a custom progress bar. After completing the first version, I found that the progress bar was not smooth. Then I wanted to check online to see if there were any good solutions, but I didn’t find a suitable one in the end. So I wanted to see what the "Weibo" progress bar in the WeChat mini program looked like, and the result was also a very stiff animation. I put a GIF below. You can also search for Weibo in the WeChat mini program yourself and find a video to see the effect.

Conventional solution

Finally, we decided to optimize this problem. Let's first review our existing conventional solutions.

  • Listening for TimeUpdate events
  • Get the current playback time and calculate the progress percentage based on the total time (currentTime / duration * 100)
  • The progress bar width property sets the progress percentage

The existing solution relies on events to obtain the current playback time, and this event is triggered approximately once every 100 to 350 milliseconds. The following is the event object queue of the applet I recorded.

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

The current problem is that every time an event is obtained, the progress bar is updated without any transition animation, which is very abrupt. The following is a progress bar change process with a total duration of 5s:

Core code:

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

transition

We can quickly think of using CSS animation properties for optimization. If we want flexible control, I choose to use transition. Transition can define the execution duration of the animation. When we change the width, transition will change the width of the progress bar in an animated way within the specified time. First of all, the animation execution duration must be fixed, and it is best not to change the width before the previous execution duration ends, otherwise it will cause conflicts and the animation will become strange.

  • Choose a reasonable transition execution time: 0.5s
  • According to the current total duration, find out the percentage of 0.5s in the progress bar (100/duration/2)
  • The first TimeUpdate event executes the width change and sets the progress bar to the 0.5s position: width = 100/duration/2
  • Not the first TimeUpdate event, whenever currentTime exceeds the previous progress bar position, the current progress bar percentage is updated

It sounds a bit hard to understand, let's draw a picture:

  1. When the TimeUpdate event is triggered for the first time, at 0.1336 seconds (of course this value is random and may be between 0.1 and 0.3), we set the width to 0.5s, so that the progress bar moves in sync with the video, with a slight difference of 0.1 seconds from the actual progress. During the 0.5s of animation execution, UpdateTime will be triggered multiple times.
  2. When the currentTime (0.7123s, this value is also random) of a certain UpdateTime is greater than the 0.5s of the last execution, the position of the progress bar is also around 0.5s. We trigger the next 0.5s animation again, that is, set the width to the progress bar position of 1s.
  3. Then in the next iteration, currentTime>1s, width is set to 1.5s, and the cycle continues.

Core code:

const playControl = {
  percent: 0,
  time: 0,
  duration: 0,
  first: true
}
const onProgress = (e, $dom) => {
    const updateFunc = (percent) => {
        playControl.percent = percent
        playControl.time = e.detail.currentTime
        $dom.style.width = percent+'%'
    }
    //The current video progress is updated for the first time if (playControl.first) {
        playControl.duration = e.detail.duration
        playControl.first = false
        updateFunc(100 / e.detail.duration / 2)
    } else {
        let percent = ((e.detail.currentTime / e.detail.duration) * 100).toFixed(1)
        if (percent - playControl.percent > 0 || e.detail.currentTime >= e.detail.duration) {
            updateFunc(percent)
        }
    }
}

Final effect comparison (PS: the gif image effect is compromised)

The 60s version looks similar to the regular version? Block the other 60s and compare them back and forth, and you will find that there are still some differences.

It’s still a bit hard to explain, or you still don’t understand? Go directly to the github repository code, the code can be run directly: https://github.com/zimv/smooth-progress

This solution will have a short delay in some scenarios, such as pausing, dragging, etc. Personally, I think the advantages outweigh the disadvantages.

This is the end of this article about the detailed solution for implementing the smooth version of the progress bar with JS. For more relevant content about the smooth version of the JS progress bar, please search for previous articles on 123WORDPRESS.COM or continue to browse the related articles below. I hope you will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • JS implements a controllable progress bar
  • vue.js+ElementUI realizes the effect of progress bar prompting password strength
  • JS+html5 to achieve asynchronous upload of pictures and display the upload file progress bar function example
  • Detailed explanation of the mobile draggable progress bar plug-in function implemented by native js
  • js+HTML5 canvas to implement a simple loading bar (progress bar) function example
  • Code for implementing a download progress bar and a playback progress bar in JS
  • Implementing a process progress bar with animation effects based on JS

<<:  How to choose the right index in MySQL

>>:  How to configure Linux firewall and open ports 80 and 3306

Recommend

Alibaba Cloud Ubuntu 16.04 builds IPSec service

Introduction to IPSec IPSec (Internet Protocol Se...

Introduction to setting up Tomcat to start automatically on Linux system

1. Enter the /etc/init.d directory: cd /etc/init....

How to Communicate with Other Users on the Linux Command Line

It's easy to send messages to other users in ...

JavaScript implements cool mouse tailing effects

After watching this, I guarantee that you have ha...

Detailed explanation of uniapp painless token refresh method

When the front-end requests the interface, it is ...

The latest 36 high-quality free English fonts shared

01. Infinity Font Download 02. Banda Font Download...

Vue2.x configures routing navigation guards to implement user login and exit

Table of contents Preface 1. Configure routing na...

What is the length of a function in js?

Table of contents Preface Why How much is it? Num...

HTML css js implements Tab page sample code

Copy code The code is as follows: <html xmlns=...

Common browser compatibility issues (summary)

Browser compatibility is nothing more than style ...

Mysql implements three functions for field splicing

When exporting data to operations, it is inevitab...