目录
- 效果图
- 单向进度图
- 双向进度图
- 实现步骤
- 先画一圆环
- 再来一层渐变进度条圆环叠加
- 单向增加的进度条
- 双向增加的进度条
- 加入动画
- 进度条进度(jq)
- 代码
- 单向
- 双向
- 补充
- stroke-linecap
- stroke-linejoin
- stroke-miterlimit
- stroke-dasharray
- stroke-dashoffset
- stroke-opacity
效果图
单向进度图
双向进度图
实现步骤
先画一圆环
<svg xmlns="http://www.w3.org/2000/svg" style="width:100px; height:200px" viewBox="0 0 200 200">
<circle cx="50%" cy="50%" r="50" stroke-width="10" stroke="#5e5e5e" fill="none"></circle>
</svg>
注:如果只想要代码,直接看底部
viewBox的四个参数分别代表:最小X轴数值;最小y轴数值;宽度;高度。
想象一下viewBox是个100100的正方形,但是单位不是px,也不是任何一个css单位,就当是一个假的单位吧。在viewBox放了一个圆,这个圆的半径是50,单位也不是px,而是变成了和viewBox的单位一模一样的那个假的单位。为啥说是假的呢?因为这个单位代表的长度是会变的,接着看。
svg有个特点,在默认情况下,会调整这个viewBox的大小,让这个viewBox正好能被放进svg里去。拿上面例子来说,viewBox是个正方形,而svg的宽度比高度小,所以就把viewBox的大小缩小到和svg宽度一样,就能正好将viewBox放进svg里来了。所以现在viewBox的实际大小是个100px100px的正方形。
所以现在可以确定的是,viewBox的一个单位代表的长度 = 100px/200 = 0.5px。
圆定义在容器的中心处(cx=“50%”" cy=“50%”)画半径为50px的圆(r=“50”),圆的内容不着色(fill=“none”)。描边为10px,着描边色为#5e5e5e(stroke-width=“10” stroke="#5e5e5e")
再来一层渐变进度条圆环叠加
单向增加的进度条
<svg xmlns="http://www.w3.org/2000/svg" style="width:100px; height:200px" viewBox="0 0 200 200">
<linearGradient id="svg-gradient" gradientUnits="userSpaceOnUse" x1="100%" y1="100%" x2="0%" y2="0%">
<stop offset="0%" style="stop-color:#FCDF0A" />
<stop offset="100%" style="stop-color:#FF4646" />
</linearGradient>
<circle cx="50%" cy="50%" r="50" stroke-width="10" stroke="#5e5e5e" fill="none"></circle>
<circle id="ring" cx="50%" cy="50%" r="50" stroke-width="10" stroke="url(#svg-gradient)" fill="none"
transform="rotate(-90 50 50)"
stroke-dasharray="100, 314"></circle>
</svg>
linearGradient 背景色,stop的 offset=“位置”,style="stop-color:色号"
stroke-dasharray 属性参数的第一个数值表示dash,代表覆盖范围,后一个数字表示gap长度默认为circle的周长314。。
transform的rotate(-90 50 50) -90度让起点在0点的地方,如果想在6点钟开始则正改为rotate(90 55 55),不写此属性则从3点位置开始覆盖(rotate第一个参数为角度,第二个和第三个参数为旋转中心,这里为容器的中心,即viewBox后两值的一半)
双向增加的进度条
<svg xmlns="http://www.w3.org/2000/svg" style="width:100px; height:200px" viewBox="0 0 200 200">
<linearGradient id="svg-gradient" gradientUnits="userSpaceOnUse" x1="100%" y1="100%" x2="0%" y2="0%">
<stop offset="0%" style="stop-color:#FCDF0A" />
<stop offset="100%" style="stop-color:#FF4646" />
</linearGradient>
<circle cx="50%" cy="50%" r="50" stroke-width="10" stroke="#5e5e5e" fill="none"></circle>
<circle id="ring-left" cx="50%" cy="50%" r="50" stroke-width="10" stroke="url(#svg-gradient)" fill="none"
transform="rotate(90 50 50)"
stroke-dasharray="100, 314"></circle>
<circle id="ring-right" cx="50%" cy="50%" r="50" stroke-width="10" stroke="url(#svg-gradient)" fill="none"
transform="rotate(90 0 0) scale(1, -1)"
stroke-dasharray="100, 314"></circle>
</svg>
这里主要是比上面多了一个circle,其transform中变为水平翻转,开始点也变到了6点的位置
加入动画
这样效果就出来了再加上个css的动画效果
circle {
transition: all 2s ease-in-out;
transition: all 2s ease-in-out;
-webkit-transition: all 2s ease-in-out;
-moz-transition: all 2s ease-in-out;
-o-transition: all 2s ease-in-out;
}
因为后续进度的增加改动的只有circle对应的值,所以只需要加上circle 的动画就可以了。
进度条进度(jq)
//单向进度条
var targetRing = document.getElementById('ring');
var totalLength = targetRing.getTotalLength();
var progress = 10 //进度 按100来计算
targetRing.style.strokeDasharray = progress/100*totalLength + ', ' + totalLength;
//双向进度条
var targetRingLeft = document.getElementById('ring-left');
var targetRingRight = document.getElementById('ring-right');
var totalLength = targetRingLeft.getTotalLength(); //这里用targetRingRight.getTotalLength()也一样
var progress = 10 //进度 按100来计算
targetRingLeft.style.strokeDasharray = progress/100*totalLength/2 + ', ' + totalLength;
targetRingRight.style.strokeDasharray = progress/100*totalLength/2 + ', ' + totalLength;
也可以用jq代码实现
var val = 10 //进度 按100来计算 周长314
//单向进度条
$('#ring').attr('stroke-dasharray', `${314*val/100}, 314`)
//双向进度条
$('#ring-left').attr('stroke-dasharray', `${314*val/100/2}, 314`)
$('#ring-right').attr('stroke-dasharray', `${314*val/100/2}, 314`)
代码
单向
html
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 110 110">
<linearGradient id="svg-gradient" gradientUnits="userSpaceOnUse" x1="100%" y1="100%" x2="0%" y2="0%">
<stop offset="0%" style="stop-color:#FCDF0A" />
<stop offset="100%" style="stop-color:#FF4646" />
</linearGradient>
<circle cx="50%" cy="50%" r="50" stroke-width="10" stroke="#5e5e5e" fill="none"></circle>
<circle id="ring" cx="50%" cy="50%" r="50" stroke-width="10" stroke="url(#svg-gradient)" fill="none" transform="rotate(-90 50 50)" stroke-dasharray="100, 314"></circle>
</svg>
css
circle {
transition: all 2s ease-in-out;
transition: all 2s ease-in-out;
-webkit-transition: all 2s ease-in-out;
-moz-transition: all 2s ease-in-out;
-o-transition: all 2s ease-in-out;
}
js
//js
var targetRing = document.getElementById('ring');
var totalLength = targetRing.getTotalLength();
var progress = 10 //进度 按100来计算
targetRing.style.strokeDasharray = progress/100*totalLength + ', ' + totalLength;
//jq
var val = 10 //进度 按100来计算 周长314
$('#ring').attr('stroke-dasharray', `${314*val/100}, 314`)
双向
html
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 110 110">
<linearGradient id="svg-gradient" gradientUnits="userSpaceOnUse" x1="100%" y1="100%" x2="0%" y2="0%">
<stop offset="0%" style="stop-color:#FCDF0A" />
<stop offset="100%" style="stop-color:#FF4646" />
</linearGradient>
<circle cx="50%" cy="50%" r="50" stroke-width="10" stroke="#5e5e5e" fill="none"></circle>
<circle id="ring-left" cx="50%" cy="50%" r="50" stroke-width="6" fill="none" stroke="url(#svg-gradient)"
transform="rotate(90 55 55)" stroke-dasharray="3.14, 314"></circle>
<circle id="ring-right" cx="50%" cy="50%" r="50" stroke-width="6" fill="none" stroke="url(#svg-gradient)"
transform="rotate(90 0 0) scale(1, -1)" stroke-dasharray="3.14, 314"></circle>
</svg>
css
circle {
transition: all 2s ease-in-out;
transition: all 2s ease-in-out;
-webkit-transition: all 2s ease-in-out;
-moz-transition: all 2s ease-in-out;
-o-transition: all 2s ease-in-out;
}
js
//js
var targetRingLeft = document.getElementById('ring-left');
var targetRingRight = document.getElementById('ring-right');
var totalLength = targetRingLeft.getTotalLength(); //这里用targetRingRight.getTotalLength()也一样
var progress = 10 //进度 按100来计算
targetRingLeft.style.strokeDasharray = progress/100*totalLength/2 + ', ' + totalLength;
targetRingRight.style.strokeDasharray = progress/100*totalLength/2 + ', ' + totalLength;
//jq
var val = 10 //进度 按100来计算 周长314
$('#ring-left').attr('stroke-dasharray', `${314*val/100/2}, 314`)
$('#ring-right').attr('stroke-dasharray', `${314*val/100/2}, 314`)
补充
如果你想实现下图圆角的进度条可以在circle中增加一个属性
stroke-linecap
stroke-linecap 表示描边端点表现方式。可用值有:butt, round, square, inherit. 表现如下图:
另外再补充一些属性值的表现,你可以根据自己的需要进行改造
stroke-linejoin
stroke-linejoin 表示描边转角的表现方式。可用值有:miter, round, bevel, inherit. 表现如下图:
stroke-miterlimit
stroke-miterlimit 表示描边相交(锐角)的表现方式。默认大小是4. 什么斜角转斜面的角度损耗之类的意思,值越大,损耗越小。具体干嘛的,我自己也不确定。大家可查查其他资料。
stroke-dasharray
stroke-dasharray 表示虚线描边。可选值为:none, <dasharray>, inherit. 其中,none表示不是虚线; <dasharray>为一个逗号或空格分隔的数值列表。表示各个虚线端的长度。可以是固定的长度值,也可以是百分比值;inherit表继承。
stroke-dashoffset
stroke-dashoffset 表示虚线的起始偏移。可选值为:<percentage>, <length>, inherit. 百分比值,长度值,继承。
stroke-opacity
stroke-opacity 表示描边透明度。默认是1.
补充资料来源:https://www.zhangxinxu.com/wordpress/2014/04/animateion-line-drawing-svg-path-%e5%8a%a8%e7%94%bb-%e8%b7%af%e5%be%84/