本篇介紹底部快捷控件的環(huán)形進(jìn)度條的實(shí)現(xiàn)方法:通過svg
繪制兩個(gè)環(huán)帝簇,線條模糊的環(huán)作為背景、線條明亮的環(huán)根據(jù)傳入的百分比繪制相應(yīng)長度(即進(jìn)度)残揉。該組件同樣屬于基礎(chǔ)組件芋浮,在src/base/progress-circle/目錄下新建progress-circle.vue
:
樣式部分
<style lang="stylus" rel="stylesheet/stylus">
// variable.styl傳送門:https://wy310.cn/2020/01/11/vue-build-basic-style-structure/
@import "~common/stylus/variable"
.progress-circle
position: relative
circle
stroke-width: 8px
transform-origin: center
&.progress-bg
transform: scale(0.9)
stroke: $color-theme-d
&.progress-bar
transform: scale(0.9) rotate(-90deg)
stroke: $color-theme
</style>
- 這里先貼出樣式代碼纸巷,circle統(tǒng)一設(shè)置了描邊寬度為8px(這里的8px會根據(jù)后面介紹的svg的寬高動態(tài)變化,不是絕對的8像素長度瘤旨,而是8%),背景圓的描邊顏色為
$color-theme-d
(rgba(255, 205, 49, 0.5))因宇,進(jìn)度圓的描邊顏色為$color-theme
(#ffcd32)祟偷,另外,還讓進(jìn)度圓環(huán)逆時(shí)針旋轉(zhuǎn)90度杭棵,以讓它的起始點(diǎn)在最高處(旋轉(zhuǎn)之前起始點(diǎn)在最右側(cè)),以實(shí)現(xiàn)歌曲環(huán)形進(jìn)度條以頂部為起點(diǎn)順時(shí)針旋轉(zhuǎn)的業(yè)務(wù)需求先舷。
DOM部分
<template>
<div class="progress-circle">
<svg :width="length" :height="length" viewBox="0 0 100 100" version="1.1" xmlns="http://www.w3.org/2000/svg">
<!--背景圓環(huán):線條模糊-->
<circle class="progress-bg" r="50" cx="50" cy="50" fill="transparent"></circle>
<!--進(jìn)度圓環(huán):線條明亮-->
<circle class="progress-bar" r="50" cx="50" cy="50" fill="transparent" :stroke-dasharray="dasharray" :stroke-dashoffset="dashoffset"></circle>
</svg>
</div>
</template>
- svg標(biāo)簽的
viewBox
的四個(gè)參數(shù)分別表示:最小橫坐標(biāo)值蒋川、最小縱坐標(biāo)值撩笆、寬度、高度夕冲。前面兩個(gè)參數(shù)歹鱼,個(gè)人覺得除非對svg的內(nèi)部做整體偏移,否則一般都是“0, 0”弥姻,即svg的左上角(為起點(diǎn));后面兩個(gè)參數(shù)疼进,我們暫時(shí)把它們理解成比例或者等份秧廉,“100, 100”代表寬和高都設(shè)置成100等份,注意它們的單位不是px,為什么這么說呢诞外?因?yàn)槲覀儼l(fā)現(xiàn),svg標(biāo)簽上還又兩個(gè)屬性:width和height茫虽,它們的單位才是px(length變量將在后面的代碼中被賦予80)既们,也是真正決定svg寬高的屬性(即svg真實(shí)寬高其實(shí)是length個(gè)像素的長度,也就是80px)号杏,那么viewBox
后兩個(gè)參數(shù)中的一份就表示length / 100個(gè)像素的長度(length為50,一份就等于0.5px主经;為80庭惜,就是0.8px;為100护赊,就是1px……)骏啰。所以一般為了方便計(jì)算,我們都會設(shè)置一個(gè)整數(shù)值器一,如100(等份),而不會是一個(gè)不能被任何數(shù)整除的質(zhì)數(shù)渺贤,如123(等份)请毛; - circle標(biāo)簽的
r
、cx
固棚、cy
分別表示半徑仙蚜、圓心橫坐標(biāo)、圓心縱坐標(biāo)呜师。它們的單位也都不是px贾节,而是和viewBox
一樣(以及之后的stroke-dasharray
、stroke-dashoffset
單位也是如此)知牌。100等份中的50份斤程,表示該圓的圓心就在svg的中心,它的半徑就是svg邊長的一半袭厂,也就是說該圓是svg正方形的內(nèi)切圓; -
stroke-dasharray
的數(shù)值我們設(shè)置成該圓的周長纹磺,也就是2πr橄杨,即Math.PI * 100
,現(xiàn)在這個(gè)淺黃色的背景圓環(huán)就能顯示出來了式矫; -
stroke-dashoffset
稍微有點(diǎn)不一樣,舉幾個(gè)測試?yán)訋椭蠹依斫猓荷厦嫣岬皆搱A的周長約等于314聪廉,那么我們把stroke-dashoffset
先后設(shè)置成0
故慈、100
、200
干签、314
之后看看效果(如下圖)拆撼,似乎與我們的預(yù)期相反:0
是滿的,314
卻是空的……所以竭贩,我們發(fā)現(xiàn)使用314 - x
倒是符合需求莺禁,于是引出下面的js部分。
JS部分
<script>
export default {
name: 'progress-circle',
data () {
return {
dasharray: Math.PI * 100
}
},
props: {
// svg邊長
length: {
type: Number,
default: 80
},
percent: {
type: Number,
default: 0
}
},
computed: {
dashoffset () {
return (1 - this.percent) * this.dasharray
}
}
}
</script>
- 對外暴露一個(gè)百分比props:
percent
(0到1的小數(shù))寝凌,調(diào)用組件時(shí)需要傳入一個(gè)小數(shù),就像這樣:<progress-circle :percent="percent"></progress-circle>
红符; - 傳入百分比,計(jì)算屬性
dashoffset
函數(shù)會計(jì)算出該persent
對應(yīng)的進(jìn)度偏移量预侯,然后賦值到DOM上的stroke-dashoffset
萎馅,完成進(jìn)度條渲染。