微信小程序slider抖动

Posted on 2023-04-01 19:31  Capterlliar  阅读(204)  评论(0编辑  收藏  举报

问题描述:做一个音乐播放器的UI,想要使用slider做歌曲进度条,能拖动那种。为了使进度条自动向前,设置了一个interval,每500ms更新一次,用audioctx.currentTime更新,有拖动的时候用拖动值更新。拖动进度条的时候发现:从B点拖到A点,小圆圈回先退回B点,然后弹回A点。声音播放没有回退现象,就是进度条piaji一下看得不爽。

解决方案:经过一系列尝试,最后在三个地方log:seek后的currentTime,拖动值,以及用来更新的currentTime:

        slider(e:any){
            let value=Number(e.detail.value);
            audioctx.seek(value);
            console.log("0:"+audioctx.currentTime);this.setData({
                isChanging:false, 
                timeId:setInterval(()=>{
                    if(this.data.isPlaying&&!this.data.isChanging){
                        this.update();
                    }
                },500)
            })
        },
        update(newVal?:Number){
            let value=newVal?newVal:audioctx.currentTime;
            console.log("1:"+value);
            console.log("2:"+audioctx.currentTime);
            let max=audioctx.duration;
            ......
        },

log结果如下:

 

 可以发现是seek后currentTime并没有立即更新导致的回退。但不知道为什么setTimeout并没有用,于是只能自己算时间了,拖动时清除上一个interval,拖动结束重新定时,反正误差不大:

        slider(e:any){
            let value=Number(e.detail.value);
            audioctx.seek(value);
            console.log("0:"+audioctx.currentTime);
            let i=0;
            this.setData({
                isChanging:false, 
                timeId:setInterval(()=>{
                    if(this.data.isPlaying&&!this.data.isChanging){
                        this.update(value+0.5*i);
                        i++;
                    }
                },500)
            })
        },
        update(newVal?:Number){
            let value=newVal?newVal:audioctx.currentTime;
            console.log("1:"+value);
            console.log("2:"+audioctx.currentTime);
            let max=audioctx.duration;
            while(value>lyricTime[lyricIndex]&&value>lyricTime[lyricIndex+1]){
                lyricIndex++;
                if(lyricIndex===lyricTime.length)
                    break;
            }
            while(value<lyricTime[lyricIndex]&&value<lyricTime[lyricIndex-1]){
                lyricIndex--;
                if(lyricIndex===0)
                    break;
            }
            this.setData({
                max:max,
                value:value,
                currentTop:lyricPos[lyricIndex]-lyricPos[0],
                currentIndex:lyricIndex
            });  
        },