描画を開始する前に、この行を追加します
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();