用canvas实现带动画的旋转圆环加载项,核心是画弧+描边+逐帧更新角度:先translate到中心,画浅灰底环和顶部起始的动态彩弧,用requestanimationframe匀速递增结束角,支持缓动、百分比文字、响应式及高清屏适配。

用 Canvas 实现带动画的旋转圆环加载项,核心是“画弧 + 描边 + 逐帧更新角度”,不依赖任何库,纯原生 JavaScript 即可完成。关键不在旋转整个 canvas,而是让一段彩色弧线从顶部开始、顺时针匀速增长,视觉上就形成流畅的旋转加载效果。
坐标系校准与基础设置
Canvas 默认原点在左上角,直接画圆会偏移。必须先将绘图原点移到中心:
- 获取 canvas 宽高(例如 200×200),算出圆心 cx = cy = 100
- 调用 ctx.translate(cx, cy),后续所有坐标以 (0, 0) 为中心
- 设半径(如 radius = 80),留出线宽空间,避免描边被裁切
- 设 lineWidth = 12,并启用 ctx.lineCap = 'round',让弧线两端更圆润
分层绘制底环与动态弧
加载环由静止背景和运动前景组成,需分开绘制:
- 底环:用 ctx.arc(0, 0, radius, 0, Math.PI * 2) 画完整一圈,颜色设为浅灰(如 #eee)
- 前景弧:起始角固定为 -Math.PI / 2(即顶部 12 点方向),结束角动态计算:-Math.PI / 2 + currentAngle,其中 currentAngle 随动画帧递增
- 每次绘制前务必调用 ctx.beginPath(),否则路径累积会导致异常
用 requestAnimationFrame 实现平滑动画
不用 setInterval,用 requestAnimationFrame 更高效、更同步:
- 定义目标角度(如满圈对应 2 * Math.PI),当前角度从 0 开始
- 每帧按固定步长(如 0.03 弧度)累加当前角度,直到达到目标
- 每次帧内执行:清空画布 → 绘底环 → 绘前景弧;注意清空范围要匹配 translate 后的坐标系(如 ctx.clearRect(-cx, -cy, width, height))
- 可加入缓动:用 easeOutCubic(t) = 1 - Math.pow(1 - t, 3) 控制角度增长节奏,开头快、结尾慢,更自然
增强实用性的小细节
让加载环真正可用,还需几个关键补充:
- 封装成函数,接收 canvas 元素、目标百分比、主色、线宽等参数,方便复用
- 支持文字居中显示:设 ctx.textAlign = 'center' 和 ctx.textBaseline = 'middle',再用 ctx.fillText(`${Math.round(percent)}%`, 0, 0)
- 响应式处理:监听 window.resize,重设 canvas 的 width/height 属性(不是 CSS 宽高),然后重绘
- 高清屏适配:获取 window.devicePixelRatio,缩放 canvas 内部绘图比例,避免模糊











