3

キャンバスに円を描こうとしていますが、次のように生成されます。

奇妙な効果を持つ円、ズーム: ここに画像の説明を入力

なぜこれが起こっているのかはわかりませんが、以前にその効果を見たことがあり、部分的なピクセルに関係していると思われます(私はそうしていませんが)。実際の例は、このjsfiddleで見ることができます。

コードを要約すると、関数を使用して円を描画しています。内側と外側の両方のエッジを徐々に内側に描画し、アルファを調整します。コードは以下のとおりです。

function drawCircle(x, y, radius, startAngle, endAngle, antiClockwise, lineWidth, r, g, b, a) {
    c.beginPath(); 

    var w = Math.abs(lineWidth / 2);

    var alphaFactor = a / w;
    var alpha = alphaFactor;

    var outer = radius + w;
    var inner = radius - w;

    // draw centre line
    c.lineWidth = 1;
    c.strokeStyle = 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')';
    c.arc(x, y, radius, startAngle, endAngle, true); 
    c.stroke();

    for(i = 0; i < w; i++, inner++, outer--, alpha += alphaFactor) {
        // draw inner
        c.beginPath(); 
        c.strokeStyle = 'rgba(' + r + ',' + g + ',' + b + ',' + alpha + ')';
        c.arc(x, y, inner, startAngle, endAngle, true); 
        c.stroke();

        // draw outer
        c.beginPath(); 
        c.arc(x, y, outer, startAngle, endAngle, true); 
        c.stroke();
    }
};

放射状グラデーションを使用してこの問題を解決できると思いますが (線の幅によっては、より高速になると思います)、上記の影響が発生する理由を理解したいと思います。

4

2 に答える 2

1

これは、非直線(円に多く含まれる)のアンチエイリアシング/丸め効果によるものだと思います。特に、(非常に)小さい線幅で。私の推測では、これにより、円の線が部分的に重なり合ったり、線が部分的に隣り合ったり、線がいくつかの場所に隙間を残したりすることさえあると思います...

この問題は、線幅を増やすことで修正されたようです。

c.lineWidth = 1.4;

更新されたjsFiddle デモを参照してください。

于 2013-01-16T09:46:04.300 に答える
0

個々の線を描画せず、探している効果を再現する放射状グラデーションで 1 本の線を描画するだけで問題を解決しました。

ここに画像の説明を入力

これは、複数のストロークではなく 1 つの塗りつぶしのみを使用するため、(実際には) はるかに効率的であるように見えます。

コードは非常に小さいですが、解決策はこのJSFiddleで確認できます。

$(function () {
  draw(document.getElementById('canvas').getContext('2d'));

  function draw(ctx) {
    var radgrad = ctx.createRadialGradient(60, 60, 0, 60, 60, 60);
    radgrad.addColorStop(0.8, 'rgba(255,0,0,0)');
    radgrad.addColorStop(0.85, 'rgba(255,0,0,.6)');
    radgrad.addColorStop(0.9, 'rgba(255,0,0,1)');
    radgrad.addColorStop(0.95, 'rgba(255,0,0,.6)');
    radgrad.addColorStop(1, 'rgba(255,0,0,0)');

    ctx.fillStyle = radgrad;
    ctx.arc(60, 60, 60, 0, 2 * Math.PI, true);
    ctx.fill();
  }
});

別の質問の解決策から解決策を導き出しました。

于 2013-01-16T11:01:45.757 に答える