VUE移动端音乐APP学习【十四】:播放器progress-circle 圆形进度条组件实现
给迷你播放器实现一个圆形进度条。圆形进度条主要是在圆上有个渐变的圈,颜色高亮
圆形进度条dom结构:
<template> <div class="progress-circle"> <svg width="32" height="32" viewBox="0 0 100 100" version="1.1" xmlns="http://www.w3.org/2000/svg"> <circle *class*="progress-background" *r*="50" *cx*="50" *cy*="50" *fill*="transparent"/> <circle *class*="progress-bar" *r*="50" *cx*="50" *cy*="50" *fill*="transparent" *stroke-dasharray*="100" /> </svg> <slot></slot> </div> </template>
在player应用这个组件:
<div class="control"> <progress-circle> <i @click.stop="togglePlaying" class="iconfont icon-play-mini" :class=" miniIcon"></i> </progress-circle> </div>
可以看到icon没有被circle包裹在里面,因为circle是相对定位的,需要给icon加个绝对定位
<i @click.stop="togglePlaying" class="iconfont icon-play-mini icon-mini" :class=" miniIcon"></i> .icon-mini { font-size: 32px; position: absolute; left: 0; top: 0; }
优化:在圆形进度条组件中可以看到svg包裹2个circle,viewbox表示的是视口的宽度和位置0 0 100 100表示的是从左上角(0,0)一直拉到(100,100)的区域,height和width是svg真正显示在屏幕上的大小。宽度和高度可以设置成props,从外部传入接收数据来控制svg的大小,加强组件的通用性。
这里不写死它的宽度高度,在调用这个组件的时候给它传递一个半径
props: { radius: { type: Number, default: 100, },
player.vue
<progress-circle radius="32">
在circle标签中,
<circle class="progress-bar" r="50" cx="50" cy="50" fill="transparent" :stroke-dasharray="dashArray"/> data() { return { dashArray: Math.PI * 100, }; },
②接收percent 使用计算属性做映射到stroke-dashoffset上
<circle class="progress-bar" r="50" cx="50" cy="50" fill="transparent" :stroke-dasharray="dashArray" :stroke-dashoffset="dashOffset" />
percent: {
type: Number,
default: 0,
},
computed: {
dashOffset() {
return (1 - this.percent) * this.dashArray;
},
},
③在player.vue传入percent给组件
<!-- 如果是个固定值则不需要加 : --> <progress-circle radius="32" :percent="percent">
运行后看到有个报错:
props接收的radius是个Number,但是因为传递的固定值32会被转换成String类型,所以还是得用一个变量表示
<progress-circle :radius="radius" :percent="percent"> data() { return { songReady: false, currentTime: 0, radius: 32, }; },
运行结果: 圆形进度条组件成功实现