2つのこと。
まず、奇数のlineWidths(1、3、5、...)は、整数のピクセル値で描画された場合に正しく適用されることはありません。これは、XとYが中心ではなく、ピクセル間のスペースを参照しているためです。したがって、から実行される1のストロークは、ピクセルの左の列のピクセルに半分、右に半分[1,1]
をこぼします。代わりにからに[1,10]
その線を引くと、左半分と右半分が塗りつぶされ、ピクセル列全体が完全に塗りつぶされます。[1.5,1]
[1.5,10]
奇数の幅はこの動作を示しますが、偶数の数値は、両側のピクセル全体がきれいに見えるため、表示されません。
第二に、ボックスはキャンバスの上部によって隠されています。3pxのストロークを中央に配置すると、キャンバスの表示範囲外になる[0,0]
まで上下にこぼれます。[-1.5,-1.5]
そのため、本来の半分の厚さに見えます。
ここで違いの証明を参照してください:
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
// original box, eclipsed by canvas bounds
ctx.strokeStyle = "#CC0000";
ctx.lineWidth = 3;
ctx.strokeRect(0, 0, 20, 20);
// moved from canvas bounds
ctx.strokeStyle = "#CC0000";
ctx.lineWidth = 3;
ctx.strokeRect(25, 25, 20, 20);
// drawn on half pixel coordinated to precent blurry lines with odd integer line widths.
ctx.strokeStyle = "#CC0000";
ctx.lineWidth = 3;
ctx.strokeRect(50.5, 50.5, 20, 20);
body { margin: 10px }
<canvas id="canvas" width="100" height="100"></canvas>
これをレンダリングする必要があります:
最初のものはあなたのコードのようなものです。2つ目は左上の端から離れて移動し、幅が均一になっていることを示します。3つ目は、サブピクセルをぼかすことなく3pxのストロークをレンダリングする方法を示しています。