html 5 canvas LineTo()线颜色问题 [英] html 5 canvas LineTo() line color issues

查看:295
本文介绍了html 5 canvas LineTo()线颜色问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在向HMTL 5 2D画布绘制五条水平线:

I am drawing five horizontal lines to an HMTL 5 2D canvas:

var canvas_ctx = my_canvas.getContext("2d");
    canvas_ctx.lineWidth = 0.5;
    canvas_ctx.strokeStyle = "black";

    {
        let line_x = 0;
        let line_length = canvas_ctx.width;
        let offset = 5;
        let numLines = 5;
        let numYincrement = 10;
        for (let i=0;i<numLines * numYincrement;i+=numYincrement) {
            //canvas_ctx.beginPath();
            canvas_ctx.moveTo(line_x,i + offset);
            canvas_ctx.lineTo(line_length,i + offset);
            canvas_ctx.stroke();
            //canvas_ctx.closePath();
        }
    }

理想情况下,这应该会产生5条黑线。相反,线条的颜色似乎随每条新线条淡化(好像它是一个渐变!),因此第5行是灰色的。如果我取消注释 canvas_ctx.beginPath(); canvas_ctx.closePath(); ,则所有行都变为灰色。为什么会发生这种情况?

This should, ideally result in 5 black lines. Instead, the color of the lines seems to fade with each new line (as if it's a gradient!), so that line 5 is gray. If I uncomment canvas_ctx.beginPath(); and canvas_ctx.closePath();, all lines become gray. Why is this happening??

推荐答案

笔划从坐标的两边重叠。

Strokes do overlap from both sides of the coordinates.

var ctx = c.getContext('2d');
ctx.strokeStyle="red";
// draw big
ctx.scale(30, 30);
ctx.beginPath();
ctx.moveTo(5, 0);
ctx.lineTo(5, 10);
ctx.stroke();

drawPixelGrid();


function drawPixelGrid() {
  // simply renders where the pixel bounds are
  ctx.beginPath();
  // remove the zoom
  ctx.setTransform(1,0,0,1,0,0);
  ctx.strokeStyle = 'gray';
  ctx.lineWidth = 2; // avoid the problem we are demonstrating by using a perfect lineWidth ;-)

  for(let y=0; y<=300; y+=30) {
    ctx.moveTo(0, y);
    ctx.lineTo(300, y);
    for(let x=0; x<=300; x+=30) {
      ctx.moveTo(x, 0);
      ctx.lineTo(x, 300);
    }
  }
  ctx.stroke();
}

<canvas id="c" height=300></canvas>

但显然,像素不能同时设置为两种颜色。所以浏览器应用 antialiasing ,这会淡化你的像素颜色另一种颜色,是混合背景和前景色的结果。
因此,对于白色或透明背景上的黑色笔划,这会导致呈现实际的灰色像素。在这里我将继续使用红色作为示例:

But obviously, a pixel can't be set to two colors at the same time. So browsers apply antialiasing, which will fade your pixel color to an other color, being the result of mixing the background and the foreground color. So for a black stroke over a white or transparent background, this leads to actual gray pixels being rendered. Here I'll keep using red as an example:

var ctx = c.getContext('2d');
ctx.strokeStyle="red";
// first draw as on a 10*10 canvas
ctx.beginPath();
ctx.moveTo(5, 0);
ctx.lineTo(5, 10);
ctx.stroke();

// zoom it
ctx.imageSmoothingEnabled = 0;
ctx.globalCompositeOperation = 'copy';
ctx.drawImage(c, 0,0,9000,9000);

drawPixelGrid();

// this is not red...

function drawPixelGrid() {
  ctx.globalCompositeOperation = 'source-over';
  ctx.beginPath();
  ctx.setTransform(1,0,0,1,0,0);
  ctx.strokeStyle = 'gray';
  ctx.lineWidth = 2;

  for(let y=0; y<=300; y+=30) {
    ctx.moveTo(0, y);
    ctx.lineTo(300, y);
    for(let x=0; x<=300; x+=30) {
      ctx.moveTo(x, 0);
      ctx.lineTo(x, 300);
    }
  }
  ctx.stroke();
}

<canvas id="c" height=300></canvas>

避免它的一种方法通常是在坐标上应用偏移量,以使线在像素边界上正确延伸。例如,对于1px lineWidth,您将应用0.5偏移量:

One way to avoid it is generally to apply an offset on your coordinates so that the line extends correctly on pixels boundaries. E.g for a 1px lineWidth, you would apply a 0.5 offset:

var ctx = c.getContext('2d');
ctx.strokeStyle="red";
// first draw as on a 10*10 canvas
ctx.beginPath();
ctx.moveTo(5.5, 0); // offset +0.5px
ctx.lineTo(5.5, 10);
ctx.stroke();

// zoom it
ctx.imageSmoothingEnabled = 0;
ctx.globalCompositeOperation = 'copy';
ctx.drawImage(c, 0,0,9000,9000);

drawPixelGrid();
// now we've got a real red

function drawPixelGrid() {
  ctx.globalCompositeOperation = 'source-over';
  ctx.beginPath();
  ctx.setTransform(1,0,0,1,0,0);
  ctx.strokeStyle = 'gray';
  ctx.lineWidth = 2;

  for(let y=0; y<=300; y+=30) {
    ctx.moveTo(0, y);
    ctx.lineTo(300, y);
    for(let x=0; x<=300; x+=30) {
      ctx.moveTo(x, 0);
      ctx.lineTo(x, 300);
    }
  }
  ctx.stroke();
}

<canvas id="c" height=300></canvas>

但是在你的情况下,你绘制的是0.5px lineWidth,所以没有偏移就能摆脱这种抗锯齿。

But in your case, you are drawing at 0.5px lineWidth, so no offset will be able to get rid of this antialiasing.

所以如果你想要完美的颜色,选择一个正确的lineWidth。

So if you want perfect color, choose a correct lineWidth.

这篇关于html 5 canvas LineTo()线颜色问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆