目录

  • 效果图
  • 单向进度图
  • 双向进度图
  • 实现步骤
  • 先画一圆环
  • 再来一层渐变进度条圆环叠加
  • 单向增加的进度条
  • 双向增加的进度条
  • 加入动画
  • 进度条进度(jq)
  • 代码
  • 单向
  • 双向
  • 补充
  • stroke-linecap
  • stroke-linejoin
  • stroke-miterlimit
  • stroke-dasharray
  • stroke-dashoffset
  • stroke-opacity


效果图

单向进度图

渐变色圆环progressBar android css渐变圆环_javascript

双向进度图

渐变色圆环progressBar android css渐变圆环_css3_02

渐变色圆环progressBar android css渐变圆环_html5_03

实现步骤

先画一圆环

<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的实际大小是个100px
100px的正方形。
所以现在可以确定的是,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中增加一个属性

渐变色圆环progressBar android css渐变圆环_svg_04

stroke-linecap

stroke-linecap 表示描边端点表现方式。可用值有:butt, round, square, inherit. 表现如下图:

渐变色圆环progressBar android css渐变圆环_svg_05


另外再补充一些属性值的表现,你可以根据自己的需要进行改造

stroke-linejoin

stroke-linejoin 表示描边转角的表现方式。可用值有:miter, round, bevel, inherit. 表现如下图:

渐变色圆环progressBar android css渐变圆环_css3_06

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/