sir-haver
sir-haver

Reputation: 3592

Creating a smooth progress bar in React

I created a very simple audio player and I'm using setInterval to create the effect of an advancing progress bar. The code of the component is as follows:

class AudioPlayer extends Component {
    constructor(props) {
        super(props)
        this.audio = new Audio(file);
    }
    state = {
        playButton: 'play',
        progress: 0,
    }
    componentDidMount = () => {
        this.currentTimeInterval = null;
        this.slider = 0;
        this.audio.onplay = () => {
            this.currentTimeInterval = setInterval( () => {
                this.slider = (this.audio.currentTime * 100) / this.audio.duration;
                this.setState({progress: this.slider})
            }, 100);
        };
    }
    playAudio = () => {
        if (this.state.playButton === 'play') {
            this.audio.play();
            this.setState({playButton: 'pause'});
        } else {
            clearInterval(this.currentTimeInterval);
            this.audio.pause();
            this.setState({playButton: 'play'});
        }
    }
    render() {
        return(
            <div>
                <button onClick={this.playAudio}><FontAwesomeIcon icon="step-backward" /></button>
                <button onClick={this.playAudio}><FontAwesomeIcon icon={this.state.playButton} /></button>
                <button onClick={this.stopAudio}><FontAwesomeIcon icon="stop" /></button>
                <button onClick={this.playAudio}><FontAwesomeIcon icon="step-forward" /></button>
                <div className="progress-bar" style={{width: this.state.progress + '%'}}></div>
            </div>
        )
    }
}

It looks quite alright when the interval is set to 100, but if I change it to 500 then the bar doesn't move smoothly. I tried to apply the following css code:

.progress-bar {
  background-color: blue;
  -webkit-transition: width 0.3s ease;
  -o-transition: width 0.3 ease;
  transition: width 0.3 ease;
  height: 20px;
}

But when the interval is set to 500, the css transition doesn't help unless I set the time to at least 5s, which is not good because it creates a delay.

So my question is about performance - is it a good practice to use an interval of 100, or even less? Doesn't it affect the performance that I cause a re-rendering of the component every 100 ms? I'm just wondering whether it's a good practice?

Thanks in advance

Upvotes: 1

Views: 4782

Answers (1)

Jitender
Jitender

Reputation: 7971

Try this one. The property which you want to get animated should be present on same class.

.progress-bar {
  width: 0; // try width: 0% if prior one do not work
  background-color: blue;
  -webkit-transition: width 0.3s ease;
  -o-transition: width 0.3 ease;
  transition: width 0.3 ease;
  height: 20px;
}

https://codesandbox.io/s/00qq6yj36w

Upvotes: 2

Related Questions