vue-music(13)进度条的实现

这里写图片描述

<template>
  <!-- 进度条 总体长度 -->
  <div  class="progress-bar" ref="progressBar" @click="progressClick">
    <div class="bar-inner">
      <!-- 进度条 已播放长度 -->
      <div class="progress" ref="progress"></div>
      <!-- 进度条 按钮 -->
      <div class="progress-btn-wrapper" ref="progressBtn"
        @touchstart.prevent="progressTouchStart"
        @touchmove.prevent="progressTouchMove"
        @touchend.prevent="progressTouchEnd"
      >
        <div class="progress-btn"></div>
      </div>
    </div>
  </div>
</template>

这里写图片描述
这里写图片描述

watch: {
    percent (newPercent) {
      if (newPercent >= 0 && !this.touch.initiated) {
        const progressBarWidth = this.$refs.progressBar.clientWidth - progressBtnWidth // 总宽度
        const progressWidth = newPercent * progressBarWidth
        this.$refs.progress.style.width = `${progressWidth}px`
        this.$refs.progressBtn.style[transform] = `translate3d(${progressWidth}px, 0, 0)`
      }
    }
  },

拖动小球而改变进度的实现

  created () {
    this.touch = {} // 将touch的数据挂在此对象下
  },
  methods: {
    progressTouchStart (e) {
      this.touch.initiated = true // 初始化 使用touchu必须先初始化
      this.touch.startX = e.touches[0].pageX // 记录触摸时的位置
      this.touch.left = this.$refs.progress.clientWidth // 记录已经进行的宽度 => 当前进度
    },
    progressTouchMove (e) {
      if (!this.touch.initiated) {
        return
      }
      const deltaX = e.touches[0].pageX - this.touch.startX // 实时得到移动的x位点 减去记录的x坐标  ==偏移量
      const progressWidth = Math.min(Math.max(0, deltaX + this.touch.left), this.$refs.progressBar.clientWidth - progressBtnWidth)
      this.$refs.progress.style.width = `${progressWidth}px`
      this.$refs.progressBtn.style[transform] = `translate3d(${progressWidth}px, 0, 0)`
    },
    progressTouchEnd () {
      this.touch.initiated = false
      this._trgglePercent()
    },
    progressClick (e) {
      const rect = this.$refs.progressBar.getBoundingClientRect()
      const offsetWidth = e.pageX - rect.left
      this.$refs.progress.style.width = `${offsetWidth}px` // e.offsetX 是点击后的偏移量
      this.$refs.progressBtn.style[transform] = `translate3d(${offsetWidth}px, 0, 0)`
      this._trgglePercent()
    },
    _trgglePercent () {
      const progressBarWidth = this.$refs.progressBar.clientWidth - progressBtnWidth // 总宽度
      const percent = this.$refs.progress.clientWidth / progressBarWidth
      this.$emit('percentChange', percent) // 派发事件
    }
  }

子组件继承父组件的数据是不能进行改变的,当子组件数据发生变化,最好的方法就是派发一个事件到父组件,然后在父组件中改变,在传回子组件

父组件

onPregressByChange (percent) {
      const onCurrentTime = this.currentSong.duration * percent // 改变时间显示
      this.$refs.audio.currentTime = onCurrentTime 
      if (!this.playing) {
        this.togglePlaying()
      }
      if (this.currentLyric) {
        this.currentLyric.seek(onCurrentTime * 1000) // *1000毫秒  seek歌词跳转 自带方法
      }
    },

点击进度条实现跳转

    progressClick (e) {
      const rect = this.$refs.progressBar.getBoundingClientRect()
      const offsetWidth = e.pageX - rect.left
      this.$refs.progress.style.width = `${offsetWidth}px` // e.offsetX 是点击后的偏移量
      this.$refs.progressBtn.style[transform] = `translate3d(${offsetWidth}px, 0, 0)`
      this._trgglePercent()
    },

getBoundingClientRect用于获取某个元素相对于视窗的位置集合。集合中有top, right, bottom, left等属性。

1.语法:这个方法没有参数。

rectObject = object.getBoundingClientRect();
2.返回值类型:TextRectangle对象,每个矩形具有四个整数性质( 上, 右 , 下,和左 )表示的坐标的矩形,以像素为单位。

 rectObject.top:元素上边到视窗上边的距离;

 rectObject.right:元素右边到视窗左边的距离;

 rectObject.bottom:元素下边到视窗上边的距离;

 rectObject.left:元素左边到视窗左边的距离;
 这里写图片描述

圆形进度条的实现
环形进度条是基于svg实现的
这里写图片描述


<template>
  <div class="progress-circle">
    <svg :width="radius" :height="radius" viewBox="0 0 100 100" version="1.1" xmlns="http://www.w3.org/2000/svg">
    <!-- width/height表示svg的宽高,viewBox表示根据svg的宽高拉出来的大小 -->
      <circle class="progress-background" r="50" cx="50" cy="50" fill="transparent" />
      <!-- r表示半径,cx 和 cy 属性定义圆点的 x 和 y 坐标 fill表示背景色 -->
      <circle class="progress-bar" r="50" cx="50" cy="50" fill="transparent" :stroke-dasharray="dashArray" :stroke-dashoffset="dashOffset"/>
    </svg>
    <slot></slot>
  </div>
</template>

<style lang="stylus" scoped>
  @import '~common/stylus/variable'

  .progress-circle
    position relative
    circle
      stroke-width 8px
      // stroke-width表示环形的宽度
      transform-origin center
      // 中心旋转
      &.progress-background
        transform scale(0.9)
        stroke $color-theme-d
      &.progress-bar
        transform scale(0.9) rotate(-90deg)
        stroke $color-theme
</style>

这里写图片描述
这里写图片描述

猜你喜欢

转载自blog.csdn.net/weixin_42372054/article/details/82466573