js怎样实现环形进度条 js环形进度条的5种绘制方法

js怎样实现环形进度条 js环形进度条的5种绘制方法
最新回答
魅影狂杀

2021-05-15 09:49:51

JS实现环形进度条的5种方法包括Canvas、SVG、CSS(conic-gradient)、CSS(border-radius+clip-path)及混合方案(CSS+JS动态控制)。 以下是具体实现方式及代码示例:

1. Canvas方案

特点:适合高性能需求,支持像素级控制,但缩放可能失真。实现原理:通过arc()方法绘制圆形路径,利用stroke()填充颜色,动态调整进度角度。

<canvas id="myCanvas" width="100" height="100"></canvas><script> const canvas = document.getElementById('myCanvas'); const ctx = canvas.getContext('2d'); const centerX = canvas.width / 2; const centerY = canvas.height / 2; const radius = 40; const lineWidth = 10; let progress = 0.75; // 进度值(0-1) function drawCircle(color, startAngle, endAngle) { ctx.beginPath(); ctx.arc(centerX, centerY, radius, startAngle, endAngle, false); ctx.lineWidth = lineWidth; ctx.strokeStyle = color; ctx.stroke(); } // 绘制底色轨道 drawCircle('#eee', 0, 2 * Math.PI); // 绘制进度条(从-90度开始,符合视觉习惯) drawCircle('blue', -Math.PI / 2, -Math.PI / 2 + progress * 2 * Math.PI);</script>

2. SVG方案

特点:矢量图形缩放不失真,支持CSS样式控制,但复杂图形性能可能下降。实现原理:使用<circle>元素结合stroke-dasharray和stroke-dashoffset模拟进度,通过transform调整起始角度。

<svg width="100" height="100"> <!-- 底色轨道 --> <circle cx="50" cy="50" r="40" stroke="#eee" stroke-width="10" fill="none" /> <!-- 进度条(周长251.2=2πr,偏移量62.8=251.2*(1-0.75)) --> <circle cx="50" cy="50" r="40" stroke="blue" stroke-width="10" fill="none" stroke-dasharray="251.2" stroke-dashoffset="62.8" transform="rotate(-90 50 50)" /></svg>

3. CSS方案(conic-gradient)

特点:代码简洁,适合静态进度展示,但兼容性较差(IE不支持)。实现原理:利用conic-gradient创建锥形渐变,通过百分比控制进度区域。

<div class="circle-progress"></div><style> .circle-progress { width: 100px; height: 100px; border-radius: 50%; background: conic-gradient(blue 75%, #eee 0); /* 75%进度 */ }</style>4. CSS方案(border-radius + clip-path)

特点:兼容性较好,但需额外元素模拟进度,代码稍复杂。实现原理:通过clip-path裁剪圆形区域,结合transform旋转模拟进度。

<div class="progress-container"> <div class="progress-bg"></div> <div class="progress-bar" style="--progress: 75%"></div></div><style> .progress-container { width: 100px; height: 100px; border-radius: 50%; position: relative; overflow: hidden; } .progress-bg, .progress-bar { position: absolute; width: 100%; height: 100%; border-radius: 50%; clip-path: polygon(50% 50%, 50% 0, 100% 0, 100% 100%, 50% 100%); } .progress-bg { background: #eee; transform: rotate(0deg); } .progress-bar { background: blue; transform: rotate(calc(var(--progress) * 3.6deg)); /* 百分比转角度 */ transform-origin: center; }</style>5. 混合方案(CSS + JS动态控制)

特点:结合CSS样式与JS动态更新,兼顾灵活性与性能。实现原理:通过JS修改CSS变量(如--progress)或SVG属性,实现动态进度更新。

<div class="hybrid-progress" style="--progress: 0.75"></div><style> .hybrid-progress { width: 100px; height: 100px; border-radius: 50%; background: conic-gradient(blue calc(var(--progress) * 100%), #eee 0); }</style><script> // 动态更新进度 function updateProgress(newProgress) { document.querySelector('.hybrid-progress').style.setProperty('--progress', newProgress); } updateProgress(0.5); // 更新为50%</script>方案选择建议
  • 高性能需求:优先选择Canvas,适合游戏或数据可视化场景。
  • 矢量缩放需求:选择SVG,适合响应式设计。
  • 简单静态展示:使用CSS conic-gradient,代码最简洁。
  • 兼容性要求高:考虑CSS border-radius + clip-path或混合方案。
性能优化策略
  • 减少重绘:Canvas中避免频繁调用clearRect(),SVG中减少DOM操作。
  • 使用requestAnimationFrame:确保动画流畅性。
  • CSS变量控制:通过修改CSS变量而非直接操作DOM更新进度。
应用场景扩展
  • 数据可视化:展示任务完成率、资源利用率等。
  • 加载动画:提升页面加载体验。
  • 游戏开发:显示角色生命值、能量值等。

通过结合动画、触摸事件及自定义样式,可进一步增强环形进度条的交互性。