uni-app App端Canvas圆环进度条不转动,主因是requestAnimationFrame被iOS WebView节流至10fps以下,应改用setTimeout(30ms);需确保canvas-id唯一、type="2d"、宽高用px单位、arc参数角度为弧度且startAngle=-Math.PI/2起始12点,进度更新后必须手动调ctx.draw()。

uni-app App端Canvas圆环进度条不转动?检查requestAnimationFrame是否被降频
App端(尤其是iOS)WebView对requestAnimationFrame有节流策略,动画帧率可能被压到10fps以下,导致圆环“卡顿”或“不动”。这不是代码写错了,是平台限制。
- 用
setTimeout替代requestAnimationFrame,设为setTimeout(() => {...}, 30)更可控(30ms ≈ 33fps) - 避免在
onReady里直接启动动画循环,先等uni.createCanvasContext返回真实canvas实例(真机上canvasId可能延迟就绪) - iOS App端
canvas的width/height必须用px单位硬编码,不能用rpx或百分比,否则绘图坐标错乱
drawArc参数传错顺序?记住ctx.arc(x, y, radius, startAngle, endAngle, anticlockwise)
圆环本质是画一段弧线再描边,startAngle和endAngle单位是弧度,不是度数——这是90%人第一次写就翻车的地方。
-
0对应3点钟方向,逆时针增加角度;想从12点开始顺时针走,得设startAngle = -Math.PI / 2,anticlockwise = false - 进度值0~100映射到弧度:用
endAngle = startAngle + Math.PI * 2 * (percent / 100)(完整圆是Math.PI * 2) - 描边宽度要手动加粗:调
ctx.setLineWidth(8),别指望CSS控制canvas内线条
Android真机canvas黑屏?确认type="2d"且canvas-id唯一
uni-app的<canvas>在App端必须显式声明type="2d",否则某些Android机型(尤其旧版Webview)会渲染失败,只留空白。
- 模板中写:
<canvas canvas-id="progressCanvas" type="2d" style="width: 200px; height: 200px;"></canvas> - 同一个页面多个canvas,
canvas-id绝不能重复,哪怕只是测试也容易漏查 - 首次获取context前,建议加个
if (!this.canvas)判空,App端初始化异步性高,直接调draw()会报"ctx is not a function"
进度更新后不重绘?别只改数据,要主动ctx.draw()
uni-app的canvas不是响应式DOM,data里存个percent: 60不会自动触发重绘——这和view层绑定完全无关。
- 每次进度变化后,必须手动调用
ctx.draw(false, () => { /* 可选回调 */ }),第二个参数是绘制完成回调 -
draw()第一个参数设false(默认true),避免清屏重绘时闪一下;但要注意:不清屏就得自己用ctx.clearRect()擦旧弧线 - 如果圆环带背景色(比如灰色底环),先画背景弧,再画前景弧,两次
ctx.stroke(),别试图用一个arc画两种颜色
真机调试时最容易忽略的是canvas尺寸单位和draw()调用时机——前者导致图形缩放变形,后者导致“明明逻辑对了却没动”。跑通第一帧比优化动画曲线重要得多。

















