基於VUE和JS手寫的移動端H5自定義音樂播放器(直線進度條和圓形滾動進度條)

1. 先上效果圖,能夠嵌合在H5移動端頁面,可拖拽點擊顏色進度條的小白色圓圈快進~下面就是圓形的進度條哦~(請尊重勞動成果,轉載請注出處~)css

P.S(在這裏說下圓形進度條的效果,一開始也是用canvas,可是發現canvas不支持淘寶適配方案,因而想着本身寫一個,思路是控制圓邊的顯示。後來突然看到園友-- JR93 的一篇文章思路一會兒完全就打通了。用度數逐步增長來控制圓邊的顯示比控制周長來得好。在此感謝)canvas

 

 

2. HTML代碼部分app

<template>
  <div>
    <div class="bar">
      <div class="progressbar" @click="playMusic" ref="runfatbar">
        <div class="greenbar" ref="runbar">
          <span class="yuan" draggable="true"></span>
        </div>
      </div>
    </div>
    <div class="time-text">{{cTime}}</div>
    <div class="right-time time-text">{{dTime}}</div>
    <div class="audio-btn">
      <i class="icon icon-left" @click="switchAudio('top')"></i>
      <i :class="play ? 'icon icon-stop' : 'icon icon-play'" @click="audioState"></i>
      <i class="icon icon-right2" @click="switchAudio('bottom')"></i>
    </div>
    <div>
      <audio ref="player" :src="audioHttp">
      </audio>
    </div>
        <!-- 這裏是圓形進度條 -->
    <div class="circleProgress_wrapper">
            <div class="wrapper right">
                <div class="circleProgress rightcircle" ref="yuanright"></div>
            </div>
            <div class="wrapper left">
                <div class="circleProgress leftcircle" ref="yuanleft"></div>
            </div>
    </div>
  </div>
</template>

 

3. SCSS部分 P.S(這裏的icon用的是scss特色,能夠直接在HTML裏面用img標籤,只是我習慣這樣寫,由於後期判斷切換方便。關於deg度數的兼容性能夠自行百度泳-wekbit-之類的解決)this

.circleProgress_wrapper{
    width: px2rem(80);
    height: px2rem(80);
    margin: px2rem(50) auto;
    position: relative;
    border:1px solid #ddd;
}

.wrapper{
    width: px2rem(40);
    height: px2rem(80);
    position: absolute;
    top:0;
    overflow: hidden;
}

.right{
    right:0;
}

.left{
    left:0;
}

.circleProgress{
    width: px2rem(70);
    height: px2rem(70);
    border:px2rem(5) solid transparent;
    border-radius: 50%;
    position: absolute;
    top:0;
}

.rightcircle{
    border-top:px2rem(5) solid #1296db;
    border-right:px2rem(5) solid #1296db;
    right:0;
    transform: rotate(-135deg);
    display: none;
}

.leftcircle{
    border-bottom:px2rem(5) solid #1296db;
    border-left:px2rem(5) solid #1296db;
    left:0;
    transform: rotate(-135deg);
    display: none;
}

.bar {
  width: 100%;
  height: px2rem(30);
  line-height:  px2rem(30);

  .progressbar {
    width: 100%;
    height: px2rem(10);
    background-color: #999999;
    margin-top: px2rem(10);
    border-radius: px2rem(30);
    position: relative;
  }

  .greenbar {
    width: 0%;
    height: px2rem(10);
    border-radius: px2rem(30);
    position: absolute;
    top: 0;
    left: 0;
    background-color: #1296db;

    .yuan {
      display: inline-block;
      padding: px2rem(10);
      background-color: #ffffff;
      border-radius: 50%;
      position: absolute;
      top: px2rem(-5);
      right: px2rem(-20);
    }
  }
}

.time-text {
  display: inline-block;
  width: 50%;
  padding: 0 px2rem(30);
  box-sizing: border-box;
}

.right-time {
  text-align: right;
}

.audio-btn {
  width: 100%;
  text-align: center;
}

.icon {
  @include size(80, 80);

  display: inline-block;
  margin-right: px2rem(20);
  vertical-align: middle;

  $icon-list: right2 left play stop;
  @each $icon in $icon-list {
     &.icon-#{$icon} {
        @include background-cover("icon-#{$icon}.png");
    }
  }
}

 

 

4. JS部分spa

export default {
  name: 'music-view',

  components: {

  },

  props: {
    type: '',
  },

  data () {
    return {
      cTime: '00:00', // 已播放時間
      dTime: '00:00', // 總播放時間
      play: false, // 播放暫停按鈕
      audioHttp: 'http://up.mcyt.net/?down/46426.mp3', // 音頻連接
    }
  },

  mounted () {
    const music = this.$refs.player  // 音頻所在對象
    const musicBar = this.$refs.runbar  // 顏色進度條所在對象
    const musicWidth = this.$refs.runfatbar.offsetWidth // 底部進度條總寬
    const rightCircle = this.$refs.yuanright.style // 圓形滾動進度條右邊
    const leftCircle = this.$refs.yuanleft.style // 圓形滾動進度條左邊

    // 得到音頻加載完成可播放時的處理
    music.addEventListener('canplay', () => {
      const musicTime = music.duration // 得到音頻時長
      const branch = Math.floor(musicTime / 60) // 計算音頻分鐘
      const second = Math.ceil(musicTime % 60) // 計算音頻秒
      if (branch < 10 && second < 10) { // 四種狀況判斷音頻總時間
        this.dTime = `0${branch}:0${second}`
      } else if (branch < 10) {
        this.dTime = `0${branch}:${second}`
      } else if (second < 10) {
        this.dTime = `${branch}:0${second}`
      } else {
        this.dTime = `${branch}:${second}`
      }
    })

     // 得到音頻正在播放時的處理
    music.addEventListener('timeupdate', () => {
      const musicTime = music.duration // 得到音頻時長
      const circleTime = musicTime / 360 // 計算總時長佔據360度每一度的比例
      const stopTime = music.currentTime // 得到已播放的音頻時長
      const rightDeg = -135 + (stopTime / circleTime) // 計算出當前旋轉度數
      if (rightDeg < 45) { // 若是當前度數小於45就證實在右邊
        rightCircle.display = 'block' // 顯示右邊圓
        rightCircle.transform = `rotate(${rightDeg}deg)` // 賦值給CSS右邊圓旋轉度數
        leftCircle.display = 'none' // 隱藏左邊園(預防切歌的時候右邊已清除)
      } else if (rightDeg === 45 || rightDeg > 45) { // 若是當前度數等於或大於45就證實在左邊
        rightCircle.display = 'block' // 顯示右邊圓(預防直接點擊快進的時候右邊無顯示)
        leftCircle.display = 'block'  // 顯示左邊圓
        rightCircle.transform = 'rotate(45deg)' // 固定右邊旋轉度數
        const leftDeg = -135 + ((stopTime - (musicTime / 2)) / circleTime) // 計算出當前左邊旋轉度數
        leftCircle.transform = `rotate(${leftDeg}deg)` // 賦值給CSS右邊圓旋轉度數
      }
      musicBar.style.width = `${(stopTime / musicTime) * 100}%` // 計算進度條所在比例寬度
      const branch = Math.floor(stopTime / 60) // 計算已播放的音頻分鐘
      const second = Math.floor(stopTime % 60) // 計算已播放的音頻秒
      if (branch < 10 && second < 10) { // 四種狀況判斷顯示音頻以播放時間
        this.cTime = `0${branch}:0${second}`
      } else if (branch < 10) {
        this.cTime = `0${branch}:${second}`
      } else if (second < 10) {
        this.cTime = `${branch}:0${second}`
      } else {
        this.cTime = `${branch}:${second}`
      }
    })
// 監聽顏色進度條是否觸摸拖動 musicBar.addEventListener('touchmove', (event) => { const events = event.targetTouches[0].pageX // 得到觸摸拖動的距離 musicBar.style.width = `${(events / musicWidth) * 100}%` // 計算進度條所在比例寬度 music.pause() // 觸摸拖動時中止播放 }) // 監聽顏色進度條是否觸摸拖動結束 musicBar.addEventListener('touchend', () => { const touwidth = (musicBar.offsetWidth / musicWidth) // 計算進度條所在比例 music.currentTime = music.duration * touwidth // 經過所在比例賦值給音頻應在的播放時間 music.play() // 根據播放時間開始播放 this.play = true // 更改播放暫停按鈕爲播放 }) // 這裏順便寫的,適用於PC端。鼠標事件 // musicBar.addEventListener('drag', (e) => { // const events = e.pageX // musicBar.style.width = `${(events / musicWidth) * 100}%` // }) // musicBar.addEventListener('dragend', (e) => { // const events = e.pageX // musicBar.style.width = `${(events / musicWidth) * 100}%` // this.playMusic() // }) }, computed: { }, methods: { // 點擊進度條事件 playMusic (e) { const music = this.$refs.player // 音頻所在對象 const barWidth = e.pageX / this.$refs.runfatbar.offsetWidth // 計算點擊位置相對父元素總寬的比例 this.$refs.runbar.style.width = `${barWidth * 100}%` // 進度條應所在的比例總寬 music.currentTime = music.duration * barWidth // 計算點擊時應播放所在的時間 music.play() // 播放音頻 this.play = true // 更改播放暫停按鈕爲播放 }, // 點擊播放暫停按鈕時間 audioState () { this.play = !this.play // 更改播放暫停按鈕狀態 const music = this.$refs.player // 音頻所在對象 if (this.play) { music.play() // 播放音樂 } else { music.pause() // 暫停音樂 } }, // 切換歌曲按鈕 switchAudio (value) { if (value === 'top') { this.audioHttp = 'http://mp3.henduoge.com/mp3/2018-04-19/1524135488.mp3' } else if (value === 'bottom') { this.audioHttp = 'http://mp3.henduoge.com/mp3/2018-04-20/1524234022.mp3' } this.play = false // 播放按鈕爲暫停 this.$refs.runbar.style.width = 0 // 清空顏色進度條 this.$refs.yuanright.style.display = 'none' // 清空圓形顏色進度條 this.$refs.yuanleft.style.display = 'none' // 清空圓形顏色進度條 }, }, }
相關文章
相關標籤/搜索