最终动画效果
动画开始前

动画结束后

代码如下
xml
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.0/gsap.min.js"></script>
<title>Document</title>
<style>
body {
box-sizing: border-box;
margin: 0;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
.circle-progress {
position: relative;
width: 200px;
height: 200px;
}
.circle-progress svg {
transform: rotate(-90deg);
}
.circle-progress .track {
fill: none;
stroke: #f0f0f0;
stroke-width: 8;
}
.circle-progress .progress {
fill: none;
stroke: #4CAF50;
stroke-width: 8;
stroke-linecap: round;
stroke-dasharray: 0 314; /* 314 是周长 2 * π * 50 */
transition: stroke-dasharray 0.5s ease;
}
.progress-percentage {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 24px;
font-weight: bold;
}
</style>
</head>
<body>
<div class="circle-progress">
<svg width="100%" height="100%">
<circle class="track" cx="50%" cy="50%" r="50"></circle>
<circle class="progress" cx="50%" cy="50%" r="50"></circle>
</svg>
<!-- 添加显示百分比的元素 -->
<div class="progress-percentage" id="progressPercentage">0%</div>
</div>
<script>
document.addEventListener("DOMContentLoaded", () => {
const progressCircle = document.querySelector('.circle-progress .progress');
const progressPercentage = document.getElementById('progressPercentage');
const circleCircumference = 314; // 2 * π * 50
gsap.to(progressCircle, {
duration: 5,
strokeDasharray: `${circleCircumference} ${circleCircumference}`,
ease: "linear",
// repeat: -1,
yoyo: true,
// 在动画更新时触发回调函数
onUpdate: () => {
const computedDasharray = gsap.getProperty(progressCircle, "strokeDasharray");
const currentDash = parseFloat(computedDasharray.split(' ')[0]);
let progress = currentDash / circleCircumference;
// 处理精度误差,当进度接近 1 时,直接设置为 1
if (progress > 0.99) {
progress = 1;
}
const percentage = Math.round(progress * 100);
progressPercentage.textContent = `${percentage}%`;
}
});
});
</script>
</body>
</html>