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
张鑫旭大神多彩圆环的实现
张鑫旭大神矩阵的理解