stroke-dasharray
border-radius rect rotate
css的步驟不少,能夠的話優先svg寫圓環。javascript
實線的長度 空白的長度 實線的長度 空白的長度 。。。
<!-- 本地或者線上跑個demo 修改 stroke-dasharray="0 1069"的第一個值就能看到圓環-->
<svg width="440" height="440">
<!-- 底部的灰色背景圓環 -->
<circle cx="220" cy="220" r="170" stroke-width="50" stroke="#D1D3D7" fill="none"></circle>
<!-- 須要顯示的圓環 經過修改 stroke-dasharray="0 1069"的0值那塊,(角度/360) = 圓弧長度/周長 這裏的圓弧長度就是第一個值-->
<circle cx="220" cy="220" r="170" stroke-width="50" stroke="#00A5E0" fill="none" transform="matrix(0,-1,1,0,0,440)" stroke-dasharray="0 1069"></circle>
<!-- transform="matrix(0,-1,1,0,0,440)"這個是讓實線從12點開始 須要研究的話 文章末尾有相關連接 -->
</svg>
複製代碼
<ring rate="0.6" size="60" stroke-width="10" stroke-color="#8C95FF" text="及格" text-size="30"/>
<template>
<div class="parent-element-center">
<svg :width="diameterShow" :height="diameterShow" :viewbox="viewbox">
<circle :cx="size" :cy="size" :r="raduisActual" :stroke-width="strokeWidth" stroke="#eee" fill="none"></circle>
<circle v-if="rate" :text="text" :cx="size" :cy="size" :r="raduisActual" :stroke-width="strokeWidth" :stroke="strokeColor" fill="none" :transform="transform" :stroke-dasharray="strokeDasharray" stroke-linecap="round"></circle>
</svg>
<div class="element-center" :style="textStyle">{{ text }}</div>
</div>
</template>
<script> export default { props: { // 圓環外圈的直徑 size: { default: 175 }, // 圓環的小寬度 strokeWidth: { default: 5 }, // 圓環的顏色 strokeColor: { default: '#00D476' }, // 圓環顯示的百分比 這邊是小數 rate: { default: 0.5 }, // 圓環裏面的文字 這裏的文字若是跟rate息息相關 能夠放到computed計算 text: { default: 50 }, // 圓環裏面的文字的fontSize大小 textSize: { default: 20 } }, computed: { raduisActual () { return this.size - this.strokeWidth }, diameterShow () { return 2 * this.size }, viewbox () { return `0 0 ${this.diameterShow} ${this.diameterShow}` }, strokeDasharray () { const perimeter = Math.PI * 2 * this.raduisActual const showLength = this.rate * perimeter - 3 return `${showLength} 1000` }, transform () { return `matrix(0,-1,1,0,0,${this.diameterShow})` }, textStyle () { let res = {} res.fontSize = `${this.textSize}px` return res } } } </script>
<style scoped> .parent-element-center{ position: relative;display: inline-block; } .element-center { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); font-size:40px; font-weight: bold; } </style>
複製代碼
邏輯有點複雜,因此按步驟拆分了css
so easy。設個寬高,設置radius,搞定。html
<div class="circle" style="width: 100px;height:100px;border-radius:100px;background-color: skyblue;">
複製代碼
有點難度。細細一想,加個border, 背景色幹掉,yeah~。 這個邏輯得記住,也就是圓變成圓環兩步:vue
<div class="ring" style="width: 100px;height:100px;border-radius:100px;border:4px solid skyblue;">
複製代碼
喲,嗯,拿個方塊,蓋住右邊不就好了。這邊想再升級下,試試用clip
屬性。java
<!-- 圓環用到了border,計算一半的時候老是計算border非常憋手,索性加個 box-sizing: border-box; -->
<div class="left-half-ring" style="width: 100px;height:100px;border-radius:100px;border:4px solid skyblue;position:absolute;clip:rect(0 50px 100px 0);box-sizing: border-box;"></div>
<div class="right-half-ring" style="width: 100px;height:100px;border-radius:100px;border:4px solid skyblue;position:absolute;clip:rect(0 100px 100px 50px);box-sizing: border-box;"></div>
<!-- 固然 若是不想用 box-sizing: border-box; 也能夠 代碼以下 注意計算的clip-->
<div class="left-half-ring" style="width: 100px;height:100px;border-radius:100px;border:4px solid skyblue;position:absolute;clip:rect(0 54px 108px 0);"></div>
複製代碼
想一想就是上面的拼一波唄~css3
<div style="width: 100px;height:100px;position: relative;">
<div class="left-half-ring" style="width: 100px;height:100px;border-radius:100px;border:4px solid blueviolet;position:absolute;clip:rect(0 50px 100px 0);box-sizing: border-box;"></div>
<div class="right-half-ring" style="width: 100px;height:100px;border-radius:100px;border:4px solid skyblue;position:absolute;clip:rect(0 100px 100px 50px);box-sizing: border-box;"></div>
</div>
複製代碼
就是兩個圓環有重疊的部分,其實就是將圓環旋轉下,這裏爲了後期的鋪墊,將左邊的旋轉,右邊的做爲底色。爲了突出層級關係,用到z-index
。svg
<div style="width: 100px;height:100px;position: relative;">
<div class="bg-right-half-ring" style="width: 100px;height:100px;border-radius:100px;border:4px solid #000;position:absolute;clip:rect(0 100px 100px 50px);box-sizing: border-box;z-index: 1;"></div>
<div class="front-left-half-ring" style="width: 100px;height:100px;border-radius:100px;border:4px solid rgba(0,200,0,0.7);position:absolute;clip:rect(0 50px 100px 0);box-sizing: border-box;z-index: 2;transform: rotate(60deg);"></div>
</div>
複製代碼
其實就是再拿個半圓放在左邊部分,這個半圓的顏色和底色一致,形成假象。 這時候,其實經過控制front-left-half-ring
的rotate能獲得小於180度之內的圓弧wordpress
<div style="width: 100px;height:100px;position: relative;">
<div class="bg-right-half-ring" style="width: 100px;height:100px;border-radius:100px;border:4px solid #000;position:absolute;clip:rect(0 100px 100px 50px);box-sizing: border-box;z-index: 1;"></div>
<div class="front-left-half-ring" style="width: 100px;height:100px;border-radius:100px;border:4px solid rgba(0,200,0,0.7);position:absolute;clip:rect(0 50px 100px 0);box-sizing: border-box;z-index: 2;transform: rotate(60deg);"></div>
<!-- 遮掉左邊的非重疊部分 -->
<div class="bg-left-half-ring" style="width: 100px;height:100px;border-radius:100px;border:4px solid #000;position:absolute;clip:rect(0 50px 100px 0);box-sizing: border-box;z-index: 3;"></div>
</div>
複製代碼
上面的超過180度就有毛病了,畢竟咱們只有半個圓弧。那怎麼辦呢。繼續製造假象! 提及來你可能不想相信,就是再寫個右半圓,旋轉,原來的保持不動。post
<div style="width: 100px;height:100px;position: relative;">
<div class="bg-right-half-ring" style="width: 100px;height:100px;border-radius:100px;border:4px solid #000;position:absolute;clip:rect(0 100px 100px 50px);box-sizing: border-box;z-index: 1;"></div>
<div class="front-left-half-ring" style="width: 100px;height:100px;border-radius:100px;border:4px solid rgba(0,200,0,0.7);position:absolute;clip:rect(0 50px 100px 0);box-sizing: border-box;z-index: 2;transform: rotate(180deg);"></div>
<div class="bg-left-half-ring" style="width: 100px;height:100px;border-radius:100px;border:4px solid #000;position:absolute;clip:rect(0 50px 100px 0);box-sizing: border-box;z-index: 3;"></div>
<!-- 想要240度圓環的話 這邊旋轉 240-180=60 -->
<div class="right-half-ring" style="width: 100px;height:100px;border-radius:100px;border:4px solid rgba(0,200,0,0.7);position:absolute;clip:rect(0 100px 100px 50px);box-sizing: border-box;z-index: 4;transform: rotate(60deg);"></div>
</div>
複製代碼
上面的顏色僅僅爲了理解,爲了顯示完美,請將rgba(0,200,0,0.7)
的透明度去掉,效果就很完美了。flex
其實直接寫個標籤在裏面,而後(旋轉的度數/360 = 百分比),以此求出旋轉的度數。
<div style="width: 100px;height:100px;position: relative;display: flex;justify-content: center;align-items: center;">
<div class="bg-right-half-ring" style="width: 100px;height:100px;border-radius:100px;border:4px solid #000;position:absolute;clip:rect(0 100px 100px 50px);box-sizing: border-box;z-index: 1;"></div>
<!-- 72/360=20% -->
<div class="front-left-half-ring" style="width: 100px;height:100px;border-radius:100px;border:4px solid rgba(0,200,0,0.7);position:absolute;clip:rect(0 50px 100px 0);box-sizing: border-box;z-index: 2;transform: rotate(72deg);"></div>
<div class="bg-left-half-ring" style="width: 100px;height:100px;border-radius:100px;border:4px solid #000;position:absolute;clip:rect(0 50px 100px 0);box-sizing: border-box;z-index: 3;"></div>
<!-- 想要240度圓環的話 這邊旋轉 240-180=60 -->
<div class="right-half-ring" style="width: 100px;height:100px;border-radius:100px;border:4px solid rgba(0,200,0,0.7);position:absolute;clip:rect(0 100px 100px 50px);box-sizing: border-box;z-index: 4;transform: rotate(60deg);"></div>
<span id="progress">20%</span>
</div>
複製代碼
無心中發現又是這個大神寫的,大神就是大神
張鑫旭大神的rect解釋
張鑫旭大神svg畫loading
張鑫旭大神多彩圓環的實現
張鑫旭大神矩陣的理解