0

2 つの for loopsを使用してグリッドを描画しようとしています。このような:

for(var i=1;i<10;i++){
  context.moveTo(0,i*b/10);
  context.lineTo(a,i*b/10);
  context.stroke();
}

したがって、描かれた線は幅が異なり、ぼやけています.. moveTo() メソッドと lineTo() メソッドの両方に 0.5 を追加することを読みましたが、どちらも機能しません。10 行すべてを同じにする比例的な方法はありません。まず、なぜそうなのか、どうすればよいのでしょうか。


それは本当に奇妙です。ここに書かれていることはすべてテストしましたが、結果は同じでした。今、私は必死にFirefoxを開いて、すべてが完璧に見えます. それで、それはクロムについてだけです。

4

2 に答える 2

2

描画を開始する前に、この行を追加します

context.translate(0.5, 0.5);

位置に整数を使用すると、線は非常にシャープになります。

具体的には、提供するコードで:

context.translate(0.5, 0.5);
....
context.moveTo(0, (i * b / 10)|0); /// y is rounded to integer

または翻訳する代わりに:

context.moveTo(0.5, (i * b / 10)|0);

キャンバスでは、ピクセルの中心が画面上の絶対ピクセル上にありません。したがって、実際のピクセルに合わせてピクセルを半分オフセットする必要があります。そうしないと、ピクセルがサブピクセル化され、アンチエイリアスされた線になります。

変換を行う代わりに、各位置に 0.5 を追加することもできますが、変換はより簡単です。グリッドが完成したら、元に戻すだけです。

デモのスナップショット
デモからのスナップショット

コードには 2 番目の問題もあります。行をストロークしてから同じパスに追加し続けると、以前に追加されたすべての行が蓄積され、パフォーマンスが低下します。

すべての線が同じ特性 (色、太さなど) を持つ場合、各線に使用する必要がないのと同じようにbeginPath()、各線をストロークする必要もありません。

moveToすべての行をとlineToでパスに追加するだけで(moveTo行が接続されていないことを確認します)、ループが終了したら、共通の を実行しstroke()ます。

オンラインデモはこちら

/// translate 0.5
ctx.translate(0.5, 0.5);

/// create grid
ctx.beginPath();

/// add all grid lines to Path
for(;pos < width; pos += step) {
    ctx.moveTo(pos, 0);
    ctx.lineTo(pos, height);
    ctx.moveTo(0, pos);
    ctx.lineTo(width, pos);
}

/// common stroke = higher performance
ctx.stroke();
于 2013-09-11T18:33:28.407 に答える
1

ぼやけはアンチエイリアシングであり、描画位置を整数で指定することで部分的に回避できます。

ここに画像の説明を入力

また、lineWidth=.5 で描画し、描画オフセットを .5 に指定すると、より鮮明な線になります。

ここにコードとフィドルがあります: http://jsfiddle.net/m1erickson/4gduD/

<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>

<style>
    body{ background-color: ivory; }
    #canvas{border:1px solid red;}
</style>

<script>
$(function(){

    var canvas=document.getElementById("canvas");
    var ctx=canvas.getContext("2d");
    var w=canvas.width;
    var h=canvas.height;


    drawGrid("black", 20,20);


    function drawGrid(color, stepx, stepy) {
       ctx.save()

       ctx.strokeStyle = color;
       ctx.lineWidth = 0.5;
       ctx.clearRect(0, 0, w, h);

       for (var i = stepx + 0.5; i < w; i += stepx) {
         ctx.beginPath();
         ctx.moveTo(i, 0);
         ctx.lineTo(i, h);
         ctx.stroke();
       }

       for (var i = stepy + 0.5; i < h; i += stepy) {
         ctx.beginPath();
         ctx.moveTo(0, i);
         ctx.lineTo(w, i);
         ctx.stroke();
       }

       ctx.restore();
    }


}); // end $(function(){});
</script>

</head>

<body>
    <canvas id="canvas" width=300 height=300></canvas>
</body>
</html>
于 2013-09-11T18:08:56.950 に答える