svg画个圆形进度条

好记性不如烂笔头,记录一下~

效果:

代码:

<html>
    <head>
        <meta charset="UTF-8" />
        <title>Test</title>
        <style>
            .box {
                width: 120px;
                height: 120px;
        position: relative;
            }
      /*文本展示在svg外,通过position定位*/
      /* .text{
        position: absolute;
        left: 0;
        top: 0;
        width: 100%;
        height: 100%;
        display: flex;
        align-items: center;
        justify-content: center;
      } */
        </style>
    </head>
    <body>
        <div class="box">
            <!-- 将圆翻转90度,使进度条从顶部开始 -->
            <svg id="cirlceSvg" width="100%" height="100%">
                <circle id="baseCircle" class="circle" cx="50%" cy="50%" fill="none" />
                <circle id="progress" class="circle" cx="50%" cy="50%" fill="none" stroke-linecap="round"
        style="transform-origin: center; transform: rotate(-90deg);animation: circleProgress 1s 1;" />
                <text x="50%" y="60%" style="text-anchor: middle;">
                    <tspan id="text"></tspan>
                    <tspan>%</tspan>
                </text>
            </svg>
      <!-- <div class="text">
        <div>
          <span id="text"></span>%
        </div>
      </div> -->
    </div>
    
        <script>
            var rate = 50;
      var unit = '%';
            var strokeWidth = 10;
            var activeColor = "#3c9cff";
            var inActiveColor = "#eee";
            var svg = document.getElementById("cirlceSvg");
            var width = svg.clientWidth;
            var r = (100 - strokeWidth) / 2; // 计算半径百分比
            var dasharray = r * 2 * Math.PI; // 2πr  周长
            var end = r * 2 * Math.PI * (1 - rate / 100);
            // 底部圆环
            var circle1 = document.getElementById("baseCircle");
            // 设置属性
            circle1.setAttribute("r", r + unit);
            circle1.setAttribute("stroke-width", strokeWidth + unit);
            circle1.setAttribute("stroke", inActiveColor);

            var circle2 = document.getElementById("progress");
            // 设置属性
            circle2.setAttribute("r", r + unit);
            circle2.setAttribute("stroke-width", strokeWidth + unit);
            circle2.setAttribute("stroke", rate > 0 ? activeColor : inActiveColor);
            circle2.setAttribute("stroke-dasharray", dasharray + unit);
            circle2.setAttribute("stroke-dashoffset", end + unit);

            var text = document.getElementById("text");
            text.innerHTML = rate;

      // css动画设置
            document.styleSheets[0].insertRule(
                `
          @-webkit-keyframes circleProgress{ from{ stroke-dashoffset: ${dasharray}${unit}; } to { stroke-dashoffset: ${end}${unit}; }}
        `,
                0
            );
        </script>
    </body>
</html>

思路:大小由外部框子控制,里面全部使用百分比。

  1. 画两个大小相同的圆形,内部不填色,利用描边显示环形;

  1. 底层圆环设置灰色;

  1. 上层圆环设置需要的颜色,本例设置的蓝色;

  1. 需要知道的数据,百分比rate,描边宽度strokeWidth,需要计算的数据:

  1. 半径:(总宽 度 - 描边宽度) / 2;

  1. stroke-dasharray的破折号长度:周长2πr 2 * Math.PI * r

  1. stroke-dashoffset 偏移量,通过stroke-dasharray和stroke-dashoffset控制蓝边的显示:周长 - 百分比占的周长长度

  1. 动态效果用css的动画,控制stroke-dashoffset从最大值stroke-dasharray的值到stroke-dashoffset 偏移量

  1. 中间文本可以利用svg文本框添加,也可以直接在svg外加div,利用定位放在svg上;相对来说灵活一些

知识点记录:

  1. svg的circle属性:

  1. cx:圆心x坐标

  1. cy:圆形y坐标

  1. r: 圆半径

  1. fill:填充颜色,none不填充,

  1. stroke-width:描边宽度

  1. stroke:描边颜色

  1. stroke-dasharray:用于绘制以虚线呈现的SVG形状的笔触。之所以称为“破折号数组”,第一个值是破折号长度,第二个值是空白长度

  1. stroke-dashoffse:偏移量

  1. stroke-linecap:描边线帽,round圆角,因为有这个帽子(占一定宽度)的原因,rate为0的时候需要特殊处理一下,上层圈描边颜色改为和底层一致;

没帽

有圆帽

  1. css用到的属性

  1. transform-origin: center; 沿着中心选择

  1. transform: rotate(-90deg); 逆时针选择90度

不旋转之前

旋转之后

  1. animation: circleProgress 1s 1; 动画用1s执行circleProgress 1次

  1. @-webkit-keyframes circleProgress{ from{ stroke-dashoffset: ${dasharray}${unit}; } to { stroke-dashoffset: ${end}${unit}; }} 定义动画

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值