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

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

问题描述

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

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>

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

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 的线宽,您将应用 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.5 像素的线宽进行绘制,因此没有偏移量将能够摆脱这种抗锯齿.

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

因此,如果您想要完美的颜色,请选择正确的线宽.

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

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

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