svg-圆形进度条

svg,js归纳笔记

Posted by Joubn on September 26, 2017 PV: -

“A little bit of progress every day. ”

前言

这篇文章主要讲一下使用<svg>里的<path>来画一个圆弧,并封装成我们想要方法供日后使用。

申明:这里只用到<path>的A命令,并没有涉及到贝塞尔曲线相关指令,后面文章会着重去解剖一下贝塞尔曲线相关指令!

path 指令概要

SVG中path的元素,也就是路径绘制,属性名称是d, 具体值是由专门的“指令字母+坐标值”实现的,例如下面这个简单代码示意:

<path d="M10 10L90 90" stroke="#000000" style="stroke-width: 5px;"></path>
命令 名称 参数
M moveto  移动到 (x y)+
Z closepath  关闭路径 (none)
L lineto  画线到 (x y)+
H horizontal lineto  水平线到 x+
V vertical lineto  垂直线到 y+
C curveto  三次贝塞尔曲线到 (x1 y1 x2 y2 x y)+
S smooth curveto  光滑三次贝塞尔曲线到 (x2 y2 x y)+
Q quadratic Bézier curveto  二次贝塞尔曲线到 (x1 y1 x y)+
T smooth quadratic Bézier curveto  光滑二次贝塞尔曲线到 (x y)+
A elliptical arc  椭圆弧 (rx ry x-axis-rotation large-arc-flag sweep-flag x y)+
R Catmull-Rom curveto*  Catmull-Rom曲线 x1 y1 (x y)+

这里我们只讨论A指令详细用法,其它CSQT贝塞尔曲线相关指令后面再探讨,MZLHV基本指令比较好上手就不去废话了

如果指令字母是大写的,例如M, 则表示坐标位置是绝对位置;如果指令字母小写的,例如m, 则表示坐标位置是相对位置。

其中Catmull-Rom曲线不是标准的SVG命令,我们不予以讨论!

A指令参数说明

A rx ry x-axis-rotation large-arc-flag sweep-flag x y

  1. rx x轴半径
  2. ry y轴半径
  3. x-axis-rotation 弧形的旋转情况
  4. large-arc-flag 角度大小
  5. sweep-flag 弧线方向
  6. x 终点x轴坐标
  7. y 终点y轴坐标

画静态圆孤

Joubn
<svg viewBox="0,0,250,250">
    <circle cx="125" cy="125" r="122" stroke="#d9d9d9" fill="none" stroke-width="3"></circle>
    <path class="path" id="pathss" stroke="#ff5256" fill="none" stroke-width="3" stroke-linecap="round" d="M 3 125 A 122,122 0 0 1 247,125"></path>
    <text x="86" y="130" fill="#ccc" font-size="30">Joubn</text>
</svg>

封装方法

function setRate(rate){
    var angle=rate/100*360
    var l,x,y;
    if(angle==360){angle=359.99}
    angle>180 ? l=1 : l=0;
    x=125+122*Math.cos((180-angle)*(2*Math.PI/360));
    y=125-122*Math.sin((180-angle)*(2*Math.PI/360));
    return 'M 3 125 A 122,122 0 '+l+' 1 '+x+','+y;
}

补充canvas

function draw(d){
    var canvas = document.getElementById('tutorial');
    if (canvas.getContext){
      var ctx = canvas.getContext('2d');

      ctx.fillStyle = '#fff';
      ctx.fillRect(0,0,canvas.width,canvas.height);

      //画圆形
      ctx.lineCap = "round"
      ctx.strokeStyle ="#d9d9d9"; //设置描边颜色
      ctx.lineWidth = 3 //设置描边宽度
      ctx.beginPath();
      ctx.arc(125,125,122,0,Math.PI*2,true);//画一个圆心坐标(125*125px)半径122px的圆弧,从0开始到Math.PI*2结束,按照顺时针方向。
      ctx.stroke();
      ctx.strokeStyle ="#ff5256";
      var path = new Path2D(d);
      ctx.stroke(path);
      ctx.fillStyle = "#ccc";
      ctx.font = "30px -apple-system";
      ctx.fillText("canvas", 80, 130);//实心文字

    }
}

最终效果

svg

后续

最近突然发现好像有更简单的方法去实现这个功能:

利用circle stroke-dashoffset属性来偏移描边

用到的属性:

  • stroke-dasharray 控制用来描边的点划线的图案范式(周长)
  • stroke-dashoffset 指定了dash模式到路径开始的距离
  • stroke-linecap 指定描边两端的形
svg