Easy Pie Chart与计数器同步:实现二者时长一致到达目标值
解决Easy Pie Chart与计数器动画时长同步问题
要让计数器增长时长和Easy Pie Chart的动画时长完全一致,核心是让两者的总动画时长都等于animate.duration设置的5000ms,同时确保最终都到达目标值。以下是两种可行方案:
方案一:调整循环间隔时间(简单直接)
当前计数器循环99次(从0到99),每次间隔180ms,总时长为99*180=17820ms,远大于图表的5000ms。我们可以通过计算单次循环的间隔时间,让计数器总时长刚好等于5000ms:
单次间隔时间 = 动画总时长 / (目标值 + 1)
这里目标值是99,所以间隔时间 = 5000/(99+1)=50ms
修改后的JS代码:
$(function () { $(".percentile-value").easyPieChart({ size: 500, lineWidth: 6, barColor: "#055a82", animate: { duration: 5000, enabled: true, }, }); }); let targetValue = 99; let circlePara = document.querySelector(".circle"); const slowLoop = (time) => { return new Promise((resolve) => setTimeout(resolve, time)); }; const increaseCounter = async () => { // 计算单次循环间隔,确保总时长等于图表动画时长 const interval = 5000 / (targetValue + 1); for (let i = 0; i <= targetValue; i++) { await slowLoop(interval); circlePara.innerHTML = `${i}`; } }; increaseCounter();
方案二:用requestAnimationFrame精准同步(更可靠)
setTimeout存在精度误差,用requestAnimationFrame可以基于浏览器刷新帧来同步动画,和Easy Pie Chart的动画机制完全匹配,避免时间偏差:
修改后的JS代码:
$(function () { $(".percentile-value").easyPieChart({ size: 500, lineWidth: 6, barColor: "#055a82", animate: { duration: 5000, enabled: true, }, }); }); let targetValue = 99; let circlePara = document.querySelector(".circle"); const increaseCounter = () => { const startTime = Date.now(); const animationDuration = 5000; const updateCounter = () => { const elapsedTime = Date.now() - startTime; // 计算当前进度比例(0到1) const progress = Math.min(elapsedTime / animationDuration, 1); // 根据进度计算当前显示的数值 const currentValue = Math.floor(progress * targetValue); circlePara.innerHTML = `${currentValue}`; if (progress < 1) { requestAnimationFrame(updateCounter); } else { // 确保最终显示目标值,避免浮点计算误差 circlePara.innerHTML = `${targetValue}`; } }; requestAnimationFrame(updateCounter); }; increaseCounter();
说明
- 方案一简单易改,但受
setTimeout精度影响,可能存在轻微偏差; - 方案二基于浏览器动画帧同步,精度更高,完全匹配Easy Pie Chart的动画节奏,推荐使用。
内容的提问来源于stack exchange,提问作者dave
相关产品推荐
相关产品推荐

