Html5 canvas 为什么重叠的画布线条会变暗?

Html5 canvas 为什么重叠的画布线条会变暗?,html5-canvas,Html5 Canvas,我画了一组线,每一条线的宽度都是1。整个画布都有一个缩放比例,这样它们就可以相互叠加渲染 如果它们都是纯绿色(#00ff00),为什么重叠部分会变暗?屏幕截图和代码样本附件 这是因为直线是在其中心绘制的,因此每侧0.5个像素都会出血,从而强制进行子像素化,因此两条半透明直线会相邻绘制 要通过使用平移或向x位置添加偏移量来解决x位置偏移0.5像素的问题,请执行以下操作: var ctx=c.getContext(“2d”); ctx.strokeStyle=“#00ff00”; //画一些随

我画了一组线,每一条线的宽度都是1。整个画布都有一个缩放比例,这样它们就可以相互叠加渲染

如果它们都是纯绿色(#00ff00),为什么重叠部分会变暗?屏幕截图和代码样本附件


这是因为直线是在其中心绘制的,因此每侧0.5个像素都会出血,从而强制进行子像素化,因此两条半透明直线会相邻绘制

要通过使用平移或向x位置添加偏移量来解决x位置偏移0.5像素的问题,请执行以下操作:

var ctx=c.getContext(“2d”);
ctx.strokeStyle=“#00ff00”;
//画一些随机重叠的线
对于(变量i=0,x,y;i<500;i++){
x=(Math.random()*150)| 0;
y=数学随机()*100+50;
ctx.moveTo(x,y>>1);//非偏移
ctx.lineTo(x,y);
ctx.moveTo(x+150+0.5,y>>1);//偏移量0.5(忽略150)
ctx.lineTo(x+150+0.5,y);
}
ctx.stroke();
ctx.fillStyle=“#fff”;
ctx.fillRect(150,0,1150);
ctx.fillText(“整数位置”,5,10);
ctx.fillText(“偏移量+0.5”,155,10)

这是因为该线是在其中心绘制的,因此每侧0.5个像素都会出血,从而强制进行亚像素化,因此两条半透明线相邻绘制

要通过使用平移或向x位置添加偏移量来解决x位置偏移0.5像素的问题,请执行以下操作:

var ctx=c.getContext(“2d”);
ctx.strokeStyle=“#00ff00”;
//画一些随机重叠的线
对于(变量i=0,x,y;i<500;i++){
x=(Math.random()*150)| 0;
y=数学随机()*100+50;
ctx.moveTo(x,y>>1);//非偏移
ctx.lineTo(x,y);
ctx.moveTo(x+150+0.5,y>>1);//偏移量0.5(忽略150)
ctx.lineTo(x+150+0.5,y);
}
ctx.stroke();
ctx.fillStyle=“#fff”;
ctx.fillRect(150,0,1150);
ctx.fillText(“整数位置”,5,10);
ctx.fillText(“偏移量+0.5”,155,10)

哇,感谢您的快速响应,解决了我的问题!这是否意味着如果我将线宽设为2,它就不会变暗,因为它不需要亚像素渲染?@Andrewramussen在这种情况下应该可以,但更多的是位置。当一个点不再完全覆盖网格单元,独立于填充宽度时,子像素开始生效。根据您的场景,您还可以在绘制线条之前使用全局变换(
ctx.translate(0.5,0.5);
)。宽度为1+的rect()也可以使用,并且它们的填充在边界内,因此位置采用整数值。哇,感谢您的快速响应解决了我的问题!这是否意味着如果我将线宽设为2,它就不会变暗,因为它不需要亚像素渲染?@Andrewramussen在这种情况下应该可以,但更多的是位置。当一个点不再完全覆盖网格单元,独立于填充宽度时,子像素开始生效。根据您的场景,您还可以在绘制线条之前使用全局变换(
ctx.translate(0.5,0.5);
)。宽度为1+的rect()也可以使用,它们的位置采用整数值,因为它们的填充在边界内。
render(props) {
  const {
    context,
    x, y,
  } = props;

  context.lineWidth = 1;
  context.fillStyle = '#000';
  this._pings.forEach((ping, i) => {
    context.beginPath();
    context.moveTo(x + i, y);
    context.lineTo(x + i, Math.max(y - ping, y - 100));
    context.strokeStyle = pingToColor(ping);
    context.stroke();
  });
}