iOS 14下iPhone 8的HTML Canvas环形图渲染异常问题
iOS 14 iPhone 8 Canvas环形图渲染异常的排查与解决
我之前碰到过类似的iOS旧版本WebKit渲染Canvas圆弧的兼容性问题,结合你的描述和代码来看,这个异常大概率是iOS 14特定版本的WebKit引擎对Canvas大角度圆弧+边界贴合场景的精度处理bug。
问题触发的核心条件
从你的测试结果能清晰看出规律:
- 当
value>75时,对应的圆弧角度跨度超过270°(75*3.6=270),从起始的270°位置顺时针绘制270°以上的圆弧; - 当
circleRadius≥78时,圆弧线条的外边缘刚好贴合Canvas边界(你的Canvas宽高175,中心在87.5位置;circleRadius=80时,线条外边缘距离中心的距离是80 + 15/2 = 87.5,刚好和Canvas边缘重合)。
这两个条件叠加触发了WebKit的渲染bug,而Chrome开发者工具和iPhone 11 Pro的iOS版本更高,WebKit已经修复了这个问题。
可行的解决方案
1. 避免圆弧线条贴合Canvas边界
最简单的方法就是调整参数让线条边缘不触碰Canvas边界:
- 把Canvas的宽高从175改成176(或更大):
<canvas id='victories-canvas' width='176' height='176' />
- 或者保持
circleRadius在77及以下(你已经验证过这个有效); - 也可以减小
lineWidth,确保circleRadius + lineWidth/2 < canvas.width/2。
2. 给大角度圆弧添加微小角度偏移
针对大角度圆弧的端点处理bug,可以给endAngle减去一个极小的弧度值,避免引擎处理接近整圈的圆弧时出错:
// 原来的endAngle计算 endAngle = (Math.PI / 180) * (270 + degrees); // 修改为: endAngle = (Math.PI / 180) * (270 + degrees) - 0.001;
3. 调整绘制顺序
先绘制内部填充圆,再绘制外部圆弧,让填充圆覆盖可能出现异常的边缘区域:
// 先画内部填充圆 context.beginPath(); context.arc(positionX, positionY, innerCircleRadius, 0, 2 * Math.PI); context.fillStyle = "#D8FF53"; context.fill(); // 再画外部圆弧 context.lineCap = "butt"; context.beginPath(); context.strokeStyle = "#000"; context.lineWidth = "15"; context.arc(positionX, positionY, circleRadius, startAngle, endAngle); context.stroke();
总结
这个问题不是你的代码逻辑错误,而是旧版iOS WebKit的渲染兼容性bug。上面的几种方法都能避开触发条件,你可以根据自己的需求选择最合适的方案。
内容的提问来源于stack exchange,提问作者emish89




