画布context.arc()方法在放大上下文时绘制扭曲的弧。看起来弧线(差)用贝塞尔曲线近似。在Firefox中正常工作。 IE中未经测试。
前段时间我发现了这个问题,但最近似乎变得更糟(我不知道什么时候)。
我在StackOverflow上发现了一些画布问题,但不是这个问题。如果您知道它是已报告问题的表现形式,请转发链接。我已经通过Chrome的帮助/报告问题机制进行了报告。
在我自己编写之前,有没有人有解决方法? ......也许是一种过载或替代的'弧'方法?
可在此处查看以下演示:http://keveney.com/chrome_arc_bug.html
paint_canvas();
// simulate circle with line segments
//
function regular_polygon(ctx, segments, cx, cy, r) {
var i, a;
ctx.moveTo(cx + r, cy);
for (i = 0; i < segments; i++) {
a = (Math.PI * 2) * i / segments;
ctx.lineTo(cx + r * Math.cos(a), cy + r * Math.sin(a));
}
ctx.closePath();
ctx.stroke();
}
function paint_canvas() {
var ctx;
// draw unscaled circle using canvas 'arc' method
//
ctx = document.getElementById('canv').getContext('2d');
ctx.beginPath();
ctx.strokeStyle = "#000";
ctx.lineWidth = 1.25;
ctx.arc(250, 250, 200, 0, 2 * Math.PI, false);
ctx.stroke();
// draw enclosing polygons
//
ctx.beginPath();
ctx.strokeStyle = "#c00";
regular_polygon(ctx, 36, 250, 250, 215);
regular_polygon(ctx, 36, 250, 250, 185);
// the same but scaled up from smaller units
//
ctx = document.getElementById('canv2').getContext('2d');
ctx.beginPath();
ctx.strokeStyle = "#000";
ctx.scale(100, 100);
ctx.lineWidth = 1.25 / 100;
ctx.arc(2.5, 2.5, 2, 0, 2 * Math.PI, false);
ctx.stroke();
ctx.beginPath();
ctx.strokeStyle = "#c00";
regular_polygon(ctx, 36, 2.5, 2.5, 2.15);
regular_polygon(ctx, 36, 2.5, 2.5, 1.85);
}
body {
background-color: #F4F4F4;
width: 800px;
margin-left: auto;
margin-right: auto;
}
canvas {
background-color: #FFFFFF;
}
<p>Chrome arc scaling bug</p>
<canvas id="canv" height=500 width=500></canvas>
<canvas id="canv2" height=500 width=500></canvas>
<p>expected: Both images should be identical.</p>
<p>actual: Arc in second image is badly distorted.</p>
<p>Issue reported 6/17/2015.</p>
<p>tested with 43.0.2357.124 (64-bit)</p>
<p>This issue was observed some time ago, but has gotten worse in recent releases of Chrome. Not tested on Internet Explorer. If you find a convenient solution,
please notify Matt Keveney, matt@keveney.com</p>
答案 0 :(得分:1)
这种效果源于近似半径较小的圆形,看起来更像是一个正方形而不是一个圆形。
如果你故意制作这种圆圈,我建议制作一个绘制半径圆的函数,该圆将产生一个很好的近似圆形,可以很好地缩放(在我的例子中我选择了半径为10)在下面),然后调整参数以达到想要的圆圈。
function drawSmallArc(x,y,r,scale) {
var adjust = 10/r;
ctx.save();
ctx.beginPath();
ctx.strokeStyle = "#00f";
ctx.scale(scale/adjust, scale/adjust);
ctx.lineWidth = 1.25 / scale * adjust;
ctx.arc(x*adjust, y*adjust,r*adjust,0,2 * Math.PI, false);
ctx.stroke();
ctx.restore();
}
以下行动
var c = document.getElementById("canvas");
var ctx = c.getContext("2d");
//Two referense circles.
ctx.beginPath();
ctx.strokeStyle = "#0f0"; //green
ctx.lineWidth = 1.25;
ctx.arc(250, 250, 180, 0, 2 * Math.PI, false);
ctx.stroke();
ctx.beginPath();
ctx.strokeStyle = "#0f0"; //green
ctx.lineWidth = 1.25;
ctx.arc(250, 250, 220, 0, 2 * Math.PI, false);
ctx.stroke();
//Red circle using OP's original circle
ctx.save();
ctx.beginPath();
ctx.strokeStyle = "#f00"; //Red
ctx.lineWidth = 1.25 / 100;
ctx.scale(100,100);
ctx.arc(2.5, 2.5, 2, 0, 2 * Math.PI, false);
ctx.stroke();
ctx.restore();
//blue circle with better approximation of circle.
drawSmallArc(2.5,2.5,2,100);
function drawSmallArc(x,y,r,scale) {
var adjust = 10/r;
ctx.save();
ctx.beginPath();
ctx.strokeStyle = "#00f";
ctx.scale(scale/adjust, scale/adjust);
ctx.lineWidth = 1.25 / scale * adjust;
ctx.arc(x*adjust, y*adjust,r*adjust,0,2 * Math.PI, false);
ctx.stroke();
ctx.restore();
}
<canvas id="canvas" height=500 width=500></canvas>
答案 1 :(得分:0)
我现在使用高计数多边形解决了这个问题。我不是完全兼容的直接替代电弧,所以这里不再重复。它与上面示例代码中用于渲染红色参考多边形的函数非常相似。
我仍然对更好的解决方案或解决问题的Chrome更新感兴趣,以防有人发现。