帆布/精确线条画

时间:2014-05-08 20:26:50

标签: javascript

我现在正在玩javascript和canvas。

我想画一个没有模糊线条的1像素边框。 我已经阅读了0.5 px的翻译。

var shift = 0.5;
if (x1 === x2) {
  var shiftX = shift;
  var shiftY = 0;
} else {
  var shiftX = 0;
  var shiftY = shift;
}

有什么问题? JSFiddle

为什么右下角会丢失一个像素?

2 个答案:

答案 0 :(得分:2)

这有效!!

ctx.line = function (x1, y1, x2, y2) {
    var shift = 0.5;

    if (x1 === x2) {
        var shiftX = x1 < 2 ? shift : -shift;
        var shiftY = 0;
    } else if (y1 === y2) {
        var shiftX = 0;
        var shiftY = y1 < 2 ? shift : -shift;
    } else {
        var shiftX = 0;
        var shiftY = 0;
    }

    ctx.translate(shiftX, shiftY);
    ctx.beginPath();
    ctx.moveTo(x1, y1);
    ctx.lineTo(x2, y2);
    ctx.stroke();
    ctx.translate(-shiftX, -shiftY);
};

您尝试的问题是太靠近边缘的像素可能会“偏离”画布。此方法确保如果该点位于边缘的2个像素内,则移位发生在距边缘的AWAY方向上。

答案 1 :(得分:0)

屏幕像素的中心位于其(+ 0.5,+ 0.5)context2d坐标。

真相是你不必为x OR y翻译0.5,但对于两个,无论是垂直还是水平线。

您的整个代码与此相同:

ctx.sline(0    , 0.5,      399,   0.5);
ctx.sline(399.5 ,0,        399.5, 399);
ctx.sline(0     ,399.5,    399,   399.5);
ctx.sline(0.5   ,399,      0.5,   0);
// With 'sline' a straight line function that just use provided coordinates.

很容易看出点不会相互连接。这里涉及8点,而不是4 永远不会达到右下角的最高点(399.5,399.5),而其他角落至少有2个点。

一劳永逸地解决问题的一种简单方法是在创建上下文时将画布转换为(0.5,0.5),然后使用舍入坐标。
显然 - 它应该始终完成 - 在使用转换时保存/恢复上下文。

http://jsfiddle.net/gamealchemist/xaxK4/6/

ctx.translate(0.5, 0.5);
ctx.lineWidth = 1;
ctx.strokeStyle = "#AAAAAA";

ctx.line = function (x1, y1, x2, y2) {
    x1 = 0 | x1 ;
    y1 = 0 | y1 ;
    x2 = 0 | x2 ;
    y2 = 0 | y2 ;
    ctx.beginPath();
    ctx.moveTo(x1, y1);
    ctx.lineTo(x2, y2);
    ctx.stroke();
};

ctx.line(1, 1, 399, 1);
ctx.line(399, 1, 399, 399);
ctx.line(399, 399, 1, 399);
ctx.line(1, 399, 1, 1);

并且不要使用css宽度/高度,或者可以在代码中设置它以确保你永远不会有canvas.width!= canvas.style.width或canvas.height!= canvas.style.height,除非你知道什么你当然在做不同的价值观。但是,如果您不打算使用分辨率,支持hiDpi设备或以较低分辨率渲染,请使用css大小调整退出。