JavaScript strokeRect 或 fillRect 模糊取决于翻译

JavaScript either strokeRect or fillRect blurry depending on translation

早些时候我注意到 strokeRect(以及任何其他涉及描边的方法,例如 lineTo)创建了一条 2 px 宽的灰色线而不是 1px 宽的黑线。经过一些 Google 搜索后,我发现 context.translate(0.5, 0.5) 解决了这个问题。但现在 fillRect(和之前涉及 fill 的任何其他方法一样)创建了一个周围带有灰色边框的黑框。

有谁知道使 fillRect 和 strokeRect 都具有清晰边缘且没有灰色边框的好方法?我也不知道我是否应该对图像使用 context.translate(0.5, 0.5),因为无论我是否翻译,SVG 似乎都有清晰的边缘。

这是一个演示这一点的 jsfiddle:http://jsfiddle.net/Tysonzero/ydm21pkt/1/

请注意,底部的 strokeRect 清晰而顶部的模糊,顶部的 fillRect 清晰而底部的模糊。

笔画一半在 x,y 坐标内部,一半在外部。这就是为什么您会看到整数 x,y 的模糊,以及当 x,y 偏移半个像素时它会消失的原因。以下是关于为什么会出现模糊的更多信息:http://www.mobtowers.com/html5-canvas-crisp-lines-every-time/

使矩形更清晰的一种简单方法是向您的上下文实例添加方法以偏移 strokeRect 和 fillRect 以获得最佳外观:

var canvas=document.getElementById("canvas");
var context=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;

// add pixel aligned versions of strokeRect & fillRect to this context instance
context.sRect=function(x,y,w,h){
  x=parseInt(x)+0.50;
  y=parseInt(y)+0.50;
  this.strokeRect(x,y,w,h);
}
context.fRect=function(x,y,w,h){
  x=parseInt(x);
  y=parseInt(y);
  context.fillRect(x,y,w,h);
}

context.strokeStyle = "#000000";
context.fillStyle = "#000000";

context.strokeRect(100, 50, 100, 100);
context.fillRect(300.5, 50.5, 100, 100);


context.sRect(100,200,100,100);
context.fRect(300.5,200,100,100);

context.fillText('Unadjusted',20,100);
context.fillText('Adjusted',20,250);
body{ background-color: ivory; padding:10px; }
#canvas{border:1px solid red;}
<canvas id="canvas" width=500 height=500></canvas>