2015-06-18 50 views
-1

當上下文放大時,canvas context.arc()方法會繪製扭曲的弧線。看起來弧線(很差)用貝塞爾曲線近似。在Firefox中正常工作。在IE中未經測試。在Chrome中,放大時畫布弧線會變形

我前段時間觀察過這個問題,但最近它似乎變得更糟(我不知道什麼時候)。

我在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, [email protected]</p>

回答

1

這個效果從圓的半徑小的近似莖,它看起來更像一個圓方形。

enter image description here

如果你明知會做出這樣的圈子,我建議你做的是繪製一個圓的半徑,將產生一個圓圈,這將很好地擴展的一個很好的近似的功能(我選擇了一個在我的例子中,半徑爲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>

+0

我不認爲你的原始解釋是準確的;你已經說明了一個已經放大的低分辨率位圖再現......這不是這裏發生的事情。 (請注意,這只是Chrome中的一個錯誤,不是一般性問題)。您的解決方法僅僅反轉了縮放效果,我認爲這是該作業,但並不是我所希望的方法。但是,感謝您花時間! – mkeveney

0

我已經解決該問題,現在工作了,使用高支多邊形。礦井不是一個完全兼容的電弧替代品,所以在此不再重複。它非常類似於上面示例代碼中用於呈現紅色參考多邊形的函數。

我仍然對更好的解決方案感興趣,或者解決問題的Chrome更新,以防有人發現問題。