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

Solutions to Mysql index performance optimization problems

The optimization created by MySQL is to add index...

MySQL 5.7.21 installation and configuration tutorial

The simple installation configuration of mysql5.7...

Vue defines private filters and basic usage

The methods and concepts of private filters and g...

Setting up a proxy server using nginx

Nginx can use its reverse proxy function to imple...

Detailed explanation of how Node.js middleware works

Table of contents What is Express middleware? Req...

Detailed explanation of the group by statement in MySQL database group query

1: Statement order of grouping function 1 SELECT ...

Solution to the MySQL error "Every derived table must have its own alias"

MySQL reports an error when executing multi-table...

Usage of if judgment in HTML

In the process of Django web development, when wr...

Simple steps to write custom instructions in Vue3.0

Preface Vue provides a wealth of built-in directi...

Things to note when migrating MySQL to 8.0 (summary)

Password Mode PDO::__construct(): The server requ...

Detailed explanation of redundant and duplicate indexes in MySQL

MySQL allows you to create multiple indexes on th...

How to use multi-core CPU to speed up your Linux commands (GNU Parallel)

Have you ever had the need to compute a very larg...

How to forget the password of Jenkins in Linux

1.Jenkins installation steps: https://www.jb51.ne...

How to implement responsiveness in Vue source code learning

Table of contents Preface 1. Key Elements of a Re...

WeChat applet implements sorting function based on date and time

I recently took over a small program project, and...