如何在<canvas>中绘制一条在Safari / Chrome / Firefox中看起来相同的对角线?

时间:2016-03-24 23:20:32

标签: javascript html5 canvas safari

在支持HTML5的浏览器中,此代码绘制了一条对角线:

<!DOCTYPE html><html><body><script>
var canvas = document.createElement('canvas');
canvas.width = 100;
canvas.height = 100;
var ctx = canvas.getContext('2d');
ctx.strokeStyle = 'black';
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.lineTo(100, 100);
ctx.lineWidth = 1;
ctx.stroke();
document.body.appendChild(canvas);
</script></body></html>

然而,在Safari中渲染看起来完全不同:

Comparison of diagonal line in Chrome, Firefox, Safari

(Chrome 49.0,Firefox 45.0,Safari 9.0从左到右。)

即,在Safari中,该线看起来大约是其他线的两倍。

我可以做任何事情让所有三种浏览器的线条看起来都相同吗?

1 个答案:

答案 0 :(得分:2)

不同之处在于浏览器对您的线路进行反锯齿的不同方式。

您无法覆盖或关闭canvas元素上的抗锯齿功能,因此您可以在浏览器中使用不同的线条效果图。

唯一可靠的解决方法是逐个像素地绘制自己的线条。您可以使用Bresenham's line algorithm创建自己的行。

以下是示例代码和演示:

&#13;
&#13;
List<Book> listBook = new ArrayList<>();
listBook.add( whateveryouwant  );
listBook.add( anothermedium  );

System.out.println( "Enter the name of a book to see its details  " );
System.out.println( "or input Catalog to see the catalog." );
Scanner scan = new Scanner( System.in );
String input = scan.nextLine();

for( Book book : listBook )
{
    if( "catalog".equalsIgnoreCase( input ) )
    {
        System.out.println( "Title: " + book.getTitle() );
    }
    else if( book.getTitle().equalsIgnoreCase( input ) )
    {
        System.out.println( book.toString() );
    }
}
&#13;
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");

var imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);
var data = imgData.data;

bresnehamLine(25,25, 250, 125);
ctx.putImageData(imgData, 0, 0);


function setPixel(x, y) {
  var n = (y * canvas.width + x) * 4;
  data[n] = 0;
  data[n + 1] = 0;
  data[n + 2] = 255;
  data[n + 3] = 255;
}

// Attribution: https://www.cs.helsinki.fi/group/goa/mallinnus/lines/bresenh.html
function bresnehamLine(x0, y0, x1, y1) {
  var dx = Math.abs(x1 - x0),
      sx = x0 < x1 ? 1 : -1;
  var dy = Math.abs(y1 - y0),
      sy = y0 < y1 ? 1 : -1;
  var err = (dx > dy ? dx : -dy) / 2;
  while (true) {
    var n = (y0*canvas.width+x0)*4;
    data[n] = 0;
    data[n + 1] = 0;
    data[n + 2] = 255;
    data[n + 3] = 255;
    if (x0 === x1 && y0 === y1) break;
    var e2 = err;
    if (e2 > -dx) {
      err -= dy;
      x0 += sx;
    }
    if (e2 < dy) {
      err += dx;
      y0 += sy;
    }
  }
}
&#13;
body{ background-color: ivory; }
#canvas{border:1px solid red; margin:0 auto; }
&#13;
&#13;
&#13;