【问题标题】:Canvas line behaviour when 0 < lineWidth < 10 < lineWidth < 1 时的画布线条行为
【发布时间】:2014-07-10 18:27:27
【问题描述】:

出于好奇,我想尝试设置lineWidth &lt; 1,因为即使我的分辨率设置正确,1px 的线条看起来也很胖。不出所料,它不起作用,但在 Chrome 和 Firefox 上存在这种奇怪的行为(未在其他地方测试过):

左边是lineWidth = 1,中间是lineWidth = 0.5,右边是lineWidth = 0.1

它们是使用以下代码生成的:

ctx.lineWidth = 0.1;

        lis.each(function(i) {

            sx = $(this).offset().left;
            sy = $(this).offset().top;

            ex = sx - (20 * (6-i));
            ey = wh - 80 - (20 * (i + 1));
            eey = ey - (20 * i);

            // Horizontal
            ctx.moveTo(sx,sy+7);
            ctx.lineTo(ex, sy+7);
            ctx.stroke();

            // Vertical
            ctx.moveTo(ex,sy+7);
            ctx.lineTo(ex, ey);
            ctx.stroke();

            // Horizontal
            ctx.moveTo(ex,ey);
            ctx.lineTo(ww - bg_img_width + 100, eey);
            ctx.stroke();
        });

它们按照子代的出现顺序打印,因此每次都以 Alpha 开头,以 Epsilon 结尾。

谁能解释为什么当0 &lt; lineWidth &lt; 1 时,随着循环的进行,线条会变细?这是故意的吗?可以用来做很酷的东西吗?

【问题讨论】:

  • 我猜这是因为抗锯齿和亚像素抗锯齿。它可能不依赖于使用的图形驱动程序/操作系统,因为我很确定画布线操作会加速。

标签: html canvas


【解决方案1】:

首先要提醒的是,画布中的点以 (0.5;0.5) 为中心,因此,要绘制干净的 1px 宽线,必须在整数坐标 + (0.5, 0.5) 处绘制。

然后为了模拟厚度,渲染器将在 opacity 上播放:0.5 的线将被渲染为不透明度,使其看起来“更弱”。
请注意,这也是抗锯齿的工作方式:它将点扩散到几个具有较低权重的相邻点上,以模拟线条的粗细。

如果我比较了几种绘制三角形的方法,您可以使用下面的小提琴。

例如,当我们使用 0.8 不透明度进行绘制时,我认为我们的视觉效果与 lineWidth=0.5 相同。

这里的前两行显示了使用整数坐标与使用整数 + 0.5 坐标时的渲染差异。我们看到,当使用整数坐标时,线条在两个像素上重叠并且看起来更宽。
我们还看到抗锯齿效果不是很好,因为对角线总是看起来更粗(在 Chrome 或 Firefox 上也是如此)。

http://jsbin.com/voqubexu/1/edit?js,output

【讨论】:

    猜你喜欢
    • 2011-11-28
    • 2022-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-14
    • 2020-04-22
    相关资源
    最近更新 更多