美文网首页前端爱好者
小程序音频播放圆形进度条

小程序音频播放圆形进度条

作者: 胡卜萝须 | 来源:发表于2018-08-28 18:23 被阅读1016次

    最近,因为业务需要,研究了一波圆形进度条的实现,最终采用了如下这种方式。


    先上效果图:


    sound.gif

    实现思路

    • 重点参照了 详解用CSS3制作圆形滚动进度条动画效果 的第三种效果。即采用两个矩形截取完整的两个圆,利用.progress_wrapperoverflow: hidden;属性防止整圆溢出,表现为两个半圆拼接为一个整圆。然后旋转矩形里面的圆,通过改变旋转角度逐渐显示隐藏的圆形部分,表现为音频进度条的变化。
    • 另外,这个圆形进度条有点小bug,在两个半圆下方接口处会有一像素的空隙,我采用了一像素背景图配合绝对定位填补这个空隙

    WXML代码

    核心圆形进度条wxml代码

    <view class="circle_container">
      <view class="circle_wrapper">
        <view class="progress_wrapper circle_right">
          <view class="circle_progress right_circle" style="transform: rotate({{rightDeg}});"></view>
        </view>
        <view class="progress_wrapper circle_left">
          <view class="circle_progress left_circle" style="transform: rotate({{leftDeg}});"></view>
        </view>
        <image src="/images/{{play?'template_play03':'template_play'}}.png" class='play_audio' catchtap='pause_audio'></image>
        <view style="visibility: {{visible}}" class="circle_markup"></view>
      </view>
    </view>
    

    WXSS代码

    圆形进度条样式

    .circle_container {
      position: absolute;
      width: 56rpx;
      height: 56rpx;
      right: 30rpx;
      bottom: 20rpx;
    }
    
    .circle_wrapper {
      position: relative;
      width: 56rpx;
      height: 56rpx;
    }
    
    .progress_wrapper {
      width: 28rpx;
      height: 56rpx;
      position: absolute;
      top: 0;
      overflow: hidden;
    }
    
    .circle_right {
      right: 0;
    }
    
    .circle_left {
      left: 0;
    }
    
    .circle_progress {
      width: 48rpx;
      height: 48rpx;
      border: 4rpx solid #fff;
      border-radius: 50%;
      position: absolute;
      top: 0;
      transform: rotate(45deg);
    }
    
    .right_circle {
      border-top: 4rpx solid transparent;
      border-right: 4rpx solid transparent;
      right: 0;
    }
    
    .left_circle {
      border-bottom: 4rpx solid transparent;
      border-left: 4rpx solid transparent;
      left: 0;
    }
    
    .circle_markup {
      position: absolute;
      left: 28rpx;
      bottom: 0;
      width: 2rpx;
      height: 4rpx;
      background: #fff;
      visibility: hidden;
    }
    

    JS代码

    使用了WePY框架,其中,formatNumber格式化时间样式,isPlay控制音频播放图标,isStop控制播放悬浮框是否显示,time表示音频当前播放时间,duration表示音频总时长,percent表示音频进度条,play控制悬浮框音频播放图标,title表示音频标题,rightDeg表示右侧半圆旋转角度,leftDeg表示左侧半圆旋转角度,visible控制圆形进度条空隙是否显示

    import wepy from 'wepy'
      import {
        formatNumber
      } from '@/utils/util'
      export default class Index extends wepy.page {
        config = {
          navigationBarTitleText: '测试'
        }
        data = {
          isPlay: false,
          isStop: true,
          duration: '',
          percent: 0,
          play: true,
          title: '今日片尾',
          time: '',
          rightDeg: '',
          leftDeg: '',
          visible: 'hidden'
        }
        methods = {
          play_audio_func() {
            const audio = wx.getBackgroundAudioManager()
            audio.src = 'http://audio.heardtech.com/endAudio.mp3'
            audio.title = '今日片尾'
          }
        }
        onLoad() {
          let leftDeg = ''
          let rightDeg = ''
          let visible = ''
          let currentTime = 0
          let duration = 0
          const audio = wx.getBackgroundAudioManager()
          audio.onPlay(() => {
            this.isPlay = true
            this.isStop = false
          })
          audio.onPause(() => {
            this.isPlay = false
            this.isStop = false
          })
          audio.onStop(() => {
            this.isPlay = false
            this.isStop = true
          })
          audio.onEnded(() => {
            // audio.onTimeUpdate(() => {})
            this.percent = 0
            this.isPlay = false
            this.isStop = true
          })
          audio.onError((e) => {
            console.log('音频播放错误', e)
          })
          audio.onTimeUpdate(() => {
            let audioData = this.computePercent(audio)
            this.percent = audioData.percent
            this.time = audioData.time
            currentTime = audioData.currentTime
            duration = audioData.duration
            this.duration = audioData.dtime
            // 右侧半圆在进度超过一半之后要保持旋转225deg状态,未超过一半,左侧半圆保持原始角度45deg
            if (currentTime / duration <= 0.5) {
              leftDeg = '45deg'
              rightDeg = currentTime / duration * 360 + 45 + 'deg'
              visible = 'hidden'
            } else {
              leftDeg = currentTime / duration * 360 + 225 + 'deg'
              rightDeg = '225deg'
              visible = 'visible'
            }
    
            this.rightDeg = rightDeg
            this.leftDeg = leftDeg
            this.visible = visible
    
            this.$apply()
          })
        }
        computePercent(audio) {
          let currentTime = parseInt(audio.currentTime)
          let duration = parseInt(audio.duration)
          let min = parseInt(currentTime / 60)
          let sec = parseInt(currentTime % 60)
          let dmin = parseInt(duration / 60)
          let dsec = parseInt(duration % 60)
          let time = formatNumber(min) + ':' + formatNumber(sec)
          let dtime = formatNumber(dmin) + ':' + formatNumber(dsec)
          let percent = parseInt(currentTime / duration * 100)
          console.log('currentTime:', currentTime, 'percent:', percent, 'duration:', duration)
          return {
            time,
            dtime,
            percent,
            currentTime,
            duration
          }
        }
      }
    

    相关文章

      网友评论

        本文标题:小程序音频播放圆形进度条

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