最近羔巢,因?yàn)闃I(yè)務(wù)需要树碱,研究了一波圓形進(jìn)度條的實(shí)現(xiàn),最終采用了如下這種方式墅诡。
先上效果圖:
實(shí)現(xiàn)思路
- 重點(diǎn)參照了 詳解用CSS3制作圓形滾動(dòng)進(jìn)度條動(dòng)畫(huà)效果 的第三種效果。即采用兩個(gè)矩形截取完整的兩個(gè)圓桐智,利用
.progress_wrapper
的overflow: hidden;
屬性防止整圓溢出末早,表現(xiàn)為兩個(gè)半圓拼接為一個(gè)整圓。然后旋轉(zhuǎn)矩形里面的圓说庭,通過(guò)改變旋轉(zhuǎn)角度逐漸顯示隱藏的圓形部分然磷,表現(xiàn)為音頻進(jìn)度條的變化。 - 另外刊驴,這個(gè)圓形進(jìn)度條有點(diǎn)小bug姿搜,在兩個(gè)半圓下方接口處會(huì)有一像素的空隙,我采用了一像素背景圖配合絕對(duì)定位填補(bǔ)這個(gè)空隙
WXML代碼
核心圓形進(jìn)度條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代碼
圓形進(jìn)度條樣式
.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
格式化時(shí)間樣式,isPlay
控制音頻播放圖標(biāo)躲惰,isStop
控制播放懸浮框是否顯示,time
表示音頻當(dāng)前播放時(shí)間致份,duration
表示音頻總時(shí)長(zhǎng),percent
表示音頻進(jìn)度條礁扮,play
控制懸浮框音頻播放圖標(biāo)知举,title
表示音頻標(biāo)題,rightDeg
表示右側(cè)半圓旋轉(zhuǎn)角度太伊,leftDeg
表示左側(cè)半圓旋轉(zhuǎn)角度雇锡,visible
控制圓形進(jìn)度條空隙是否顯示
import wepy from 'wepy'
import {
formatNumber
} from '@/utils/util'
export default class Index extends wepy.page {
config = {
navigationBarTitleText: '測(cè)試'
}
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('音頻播放錯(cuò)誤', 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
// 右側(cè)半圓在進(jìn)度超過(guò)一半之后要保持旋轉(zhuǎn)225deg狀態(tài),未超過(guò)一半,左側(cè)半圓保持原始角度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
}
}
}