【SVG&requestAnimationFrame】圆环增长和数字增长

本文详细介绍如何使用SVG、CSS及JavaScript实现一个动态的圆环进度条,包括圆环从初始值增长到目标值的过程,以及数字同步增长的动画效果。文章深入探讨了SVG元素的属性设置、CSS动画应用及JavaScript的计时和动画控制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、前言

圆环和数字增长的场景我们经常能见到,下面先来看一下效果图:
在这里插入图片描述
从初始值350增长到750的一个过程,其中圆环增长和数字增长都是1s。

二、实现过程

Code Of HTML
从如下html代码中可以看出,svg中画了两个圆,不填充,但都进行了描边。

  • 第一个<circle>是较浅的背景色;
  • 第二个<circle>是较深颜色,记录圆环增长的路径,并且可以看到将stroke-dasharray属性设置为"0,10000"(短线长度,缺口长度),即第二个圆环初始状态为350(初始值);
  • text标签显示数字状态。
  • 由于我们希望圆环的下半部分是呈现缺口状态,所以通过设置SVG的高度来隐藏。
<div class="container">
    <svg xmlns="http://www.w3.org/200/svg" height="97" width="110">
        <circle cx="55" cy="55" r="50" fill="none" stroke="#ffd3c0" stroke-width="5" stroke-linecap="round"/>
        <circle class="demo2" id="J_demo2" cx="55" cy="55" r="50" fill="none" stroke="#fd620e" stroke-width="5" stroke-dasharray="0,10000"/>
        <text x="45" y="65" id="J_txt" class="txt" fill="#f95c06" stroke="#f95c06">0</text>
    </svg>
    <div class="control">
        <input id="J_btn_1" type="text" name="" value="750">
        <input id="J_btn_2" type="button" name="" value="set">
    </div>
</div>

Code Of CSS
由于我们需要第二个圆环从左下角开始顺时针增长,而它初始的增长状态是在3点钟方向顺时针,所以我们将第二个圆环旋转120°,使得增长起点在我们预期的位置。另外,我们希望在圆环增长时看到动态的过程,所以我们对stroke-dasharray属性添加了1
s动画(圆环增长的实质是控制圆环的stroke-dasharray属性)。

.demo2{
    transform-origin: 55px 55px;   /* 转换基点 */
    transform: rotate(120deg);     /* 转换120° */
    transition: stroke-dasharray 1s ease-in;
}

Code Of JavaScript
这里需要注意的一个点是,由于我们隐藏了圆的一部分,所以我们需要将圆的周长计算出来,并减去隐藏部分的弧长,这部分的弧长l = Θ*r,角度为60°。

const demo2 =  document.querySelector("#J_demo2");
const btn1 = document.querySelector("#J_btn_1");
const btn2 = document.querySelector("#J_btn_2");
const txt = document.querySelector("#J_txt");

let circleLength = Math.floor(2 * Math.PI * demo2.getAttribute("r")) - (demo2.getAttribute("r")*60*(Math.PI/180)).toFixed(2);    // 周长 

window.onload = rotateCircle;

btn2.onclick = rotateCircle;

function rotateCircle () {
   let val = parseFloat(btn1.value).toFixed(2);   // 四舍五入
   val = Math.max(350,val);
   val = Math.min(950,val);
   // 调用数字增长函数
   countUp(txt,val,350,1000,0);
   // 圆环增长
   demo2.setAttribute("stroke-dasharray","" + circleLength * (val - 350) / 600 + ",10000");
}

//数字增长函数
function countUp(elem, endVal, startVal, duration, decimal) {  
   //传入参数依次为 数字要变化的元素,最终显示数字,数字变化开始值,变化持续时间,小数点位数
   let startTime = 0;
   let dec = Math.pow(10, decimal);//返回10的decimal次幂
   let progress,value;
   function startCount(timestamp) {            // 参数是该回调函数被触发的时间
       if(!startTime) startTime = timestamp;
       progress = timestamp - startTime;
       value = startVal + (endVal - startVal) * (progress / duration);
       value = (value > endVal) ? endVal : value;
       value = Math.floor(value*dec) / dec;
       elem.innerHTML = value.toFixed(decimal);
       // requestAnimationFrame告诉浏览器——你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画
       if(progress < duration) requestAnimationFrame(startCount);
   }
   requestAnimationFrame(startCount)
}

三、requestAnimation()

以下MDN对该方法的介绍

window.requestAnimationFrame() 告诉浏览器——你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。该方法需要传入一个回调函数作为参数,该回调函数会在浏览器下一次重绘之前执行

该方法会给回调函数传入一个参数,就是该回调函数被调用的时间的时间戳。

数字增长的原理:记录第一个被回调函数被调用的时间戳,然后通过它跟之后每一次调用的时间戳进行比对,若还未到我们希望的时间间隔(1000ms),则通过requestAnimation()方法继续执行我们的回调函数countUp()

四、总结

SVG还有很多好玩和好用的用法,需要再深入学习探索。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值