美文网首页
歌曲快进和后退功能

歌曲快进和后退功能

作者: sweetBoy_9126 | 来源:发表于2019-01-24 00:43 被阅读19次

1.首先:要实现,当前歌曲播放到的时间和总的歌曲时间,以及进度条跟着时间变化
思路:通过audio.duration获取总的歌曲时间,然后监听歌曲的timeupdate获取当前的播放时间audio.currentTime,最后通过audio.currentTime/audio.duration的得到的百分比值设置为滚动条高亮的宽度,另外audio.duration需要监听canplay才能得到准确的值,然后在歌曲播放结束后监听ended事件,将当前播放时间和高亮进度条都还原

<audio src="#"></audio>
<div class="progress-wrapper">
  <div class="current-time">00:00</div>
    <div class="progress-bottom">
    <span class="progress-dot"></span>
      <div class="progress-top"></div>
    </div>
  <div class="songs-time">04:00</div>
</div>
.progress-wrapper{
    padding: 14px;
    display: flex;
    align-items: center;
}
.current-time,.songs-time{
    color: #fff;
}
.current-time{
    margin-right: 10px;
}
.songs-time{
    margin-left: 10px;
}
.progress-bottom{
    flex: 1;
    height: 0.4vh;
    background: rgba(255, 255, 255, 0.8);
    position: relative;
}
.progress-top{
    height: 100%;
    position: absolute;
    left: 0;
    top: 0;
    background: #D43B32;
    transition: all .3s linear;
}
.progress-dot{
    width: 1vw;
    height: 16px;
    width: 16px;
    border-radius: 50%;
    position: absolute;
    left: 0;
    top: 50%;
    transform: translateY(-50%);
    background: #fff;
}
let view = {
  audioListener(song){
    //重新渲染的时候如果audio里的src是#就让它等于当前的song.url否则,就不去重新渲染
    if(this.$el.find('audio').attr('src') !== song.url){
        this.audio = this.$el.find('audio').attr('src',song.url)
        this.audio.on('canplay',()=>{
            this.getSongLength()
        })
        this.audio.on('ended',()=>{
            window.eventHub.emit('songEnd')
        })
        this.audio.on('timeupdate',()=>{
            this.updateProgress()
            this.lyricProgress(this.audio[0].currentTime)
            
        })
    }
},
getSongLength(){
    this.time = this.audio[0].duration
    this.timeFormat()
    this.$el.find('.songs-time').text(this.time)
},
timeFormat(){
    let minuter = parseInt(this.time / 60)
    let second = Math.floor(this.time % 60)
    minuter = (minuter < 10) ? ('0' + minuter) : minuter
    second = (second < 10) ? ('0' + second) : second
    this.time = `${minuter}:${second}` 
},
  getCurrentTime(){
    this.time = this.audio[0].currentTime
    this.timeFormat()
    this.$el.find('.current-time').text(this.time)   
},
updateProgress(){
    this.value = this.audio[0].currentTime / this.audio[0].duration
    this.$el.find('.progress-top').css('width',`${this.value * 100}%`)
    this.$el.find('.progress-dot').css('left',`${this.value * 100}%`)
    this.getCurrentTime()
},
audioEnd(){
    this.$el.find('.progress-top').css('width',0)
    this.$el.find('.progress-dot').css('left',0)
    this.$el.find('.current-time').text('00:00')
},
}
let controller = {
  init(view,model){
    this.view = view
    this.model = model
    thsi.view.audioListener()
  },
bindEventHub(){
    window.eventHub.on('songEnd',()=>{
        this.model.data.status = 'pause'
        this.view.render(this.model.data)
        this.view.lyricMove(24)
        this.view.audioEnd()
    })
}
}

2.点击某一位置让当前播放时间跳到那个位置
思路:通过监听最外层的总的进度条的mousedown事件,通过e.offsetX获取点击位置距离进度条开始的位置的距离,然后载获取进度条的总长度,通过当前距离/进度条总长度然后再乘以当前歌曲的总时长(duration)就能得到当前位置的时长让后把它赋值给audio.currentTime即可

this.view.$el.on('mousedown','.progress-bottom',(e)=>{
    this.current = $(e.currentTarget)
    let left = e.offsetX
    let motallength = this.current.width()
    let audio = this.view.$el.find('audio')[0]
    // 只有音乐开始播放后才可以调节,已经播放过但暂停了的也可以
    if (!audio.paused || audio.currentTime != 0) {
      audio.currentTime = audio.duration * (left/motallength)
    }   
})

3.拖动当前滑块到对应位置,歌曲播放到对应位置
实现思路:通过mosedown/mousemove/mouseup来监听电脑端的拖动,通过touchstart/touchmove/touchend来监听手机端的拖动,只要写三个方法,然后在方法里判断touch是否存在,之后也是获取到当前拖动到的位置的长度/总的进度条*歌曲时间duration就可以

preventDefaultEvent(){
    // 禁止默认事件(避免鼠标拖拽进度点的时候选中文字)
    if (this.event && this.event.preventDefault) {
        this.event.preventDefault();
    } else {
        this.event.returnValue = false;
    }
    // 禁止事件冒泡
    if (this.event && this.event.stopPropagation) {
        this.event.stopPropagation();
    } else {
        window.event.cancelBubble = true;
    }
},
down(e){
    this.flag = true
    this.event = e || window.event
    this.clientX = this.event.touches ? this.event.touches[0].clientX : this.event.clientX
    this.dot = this.view.$el.find('.progress-dot')[0]
    this.progress = this.view.$el.find('.progress-bottom')[0]
    this.left = this.clientX - this.dot.offsetLeft
    this.preventDefaultEvent()
    
},
moveLength(){
    this.maxRightLength = this.progress.offsetWidth
    if(this.left1 < 0){
        this.left1 = 0
    }else if(this.left1 > this.maxRightLength){
        this.left1 = this.maxRightLength
    }
},
move(e){
    this.event = e || window.event
    if(this.flag){
        this.clientX = this.event.touches ? this.event.touches[0].clientX : this.event.clientX
        this.left1 = this.clientX - this.left
        this.moveLength()
        this.motalLeft = this.left1/this.progress.offsetWidth
        let audio = this.view.$el.find('audio')[0]
        audio.currentTime = this.motalLeft *audio.duration
    }
},
end(){
    this.flag = false
},
bindEvent(){
  this.view.$el.on('mousedown','.progress-dot',this.down.bind(this))
this.view.$el.on('touchstart','.progress-dot',this.down.bind(this))
this.$document.on('mousemove','.progress-dot',this.move.bind(this))
this.$document.on('touchmove','.progress-dot',this.move.bind(this))
this.$document.on('mouseup','.progress-dot',this.end.bind(this))
this.$document.on('touchend','.progress-dot',this.end.bind(this))
}

相关文章

网友评论

      本文标题:歌曲快进和后退功能

      本文链接:https://www.haomeiwen.com/subject/pkisjqtx.html