html - 为什么在缩放的 html5 画布中可以看到工件?
问题描述
我已经看过这个和这个关于在画布中删除抗锯齿的讨论,但我不认为这是一回事。
在将 html5 画布缩放任意值(即使其具有响应性)之后,我注意到如果我在相同位置绘制两个相同大小的矩形,第一个矩形的缩放边的边缘仍然可见。
我包含了一个示例片段,我在其中绘制了一个灰色矩形,然后在其顶部绘制了一个红色矩形。灰色矩形的左右边缘有一条 1 像素的红色垂直线。我知道这可能看起来微不足道,但在我的情况下它非常明显。
我该如何解决?谢谢!
var example = document.getElementById("example");
var ctx = example.getContext('2d');
ctx.scale(1.13,1);
ctx.fillStyle = "LightGrey";
ctx.fillRect(10,10,50,30);
ctx.fillStyle = "Black";
ctx.font = "20px Arial";
ctx.fillText("< Looks good.",70,30);
ctx.fillStyle = "Red";
ctx.fillRect(10,50,50,30);
// This light grey rectangle should completely cover the previous red one, but it doesn't!
ctx.fillStyle = "LightGrey";
ctx.fillRect(10,50,50,30);
ctx.fillStyle = "Black";
ctx.font = "20px Arial";
ctx.fillText("< Do you see red?",70,70);
<canvas id="example"></canvas>
解决方案
您在 X 轴上将变换矩阵缩放 1.13 倍。
所以你的坐标 10,实际上最终会在真实像素矩阵上的坐标 11.3 上结束。
你不能在一小部分像素上绘制,所以抗锯齿确实会在这里发挥作用。
那么为什么第一个看起来更好呢?
因为灰色和白色*之间的混合比红灰色和白色之间的混合更中性。但即使你的第一个矩形也是抗锯齿的。
只要放大你的画布,你就会看到它,两边都有一个像素带,实际上是半透明的。
* 这里的“白色”是页面的背景之一
var example = document.createElement("canvas");
var ctx = example.getContext('2d');
ctx.scale(1.13,1);
ctx.fillStyle = "LightGrey";
ctx.fillRect(10,10,50,30);
ctx.fillStyle = "Red";
ctx.fillRect(10,50,50,30);
ctx.fillStyle = "LightGrey";
ctx.fillRect(10,50,50,30);
// draw bigger with no antialiasing
var z_ctx = zoomed.getContext('2d');
zoomed.width = example.width * 10;
zoomed.height = example.height * 10;
z_ctx.imageSmoothingEnabled = false;
z_ctx.drawImage(example, 0,0, zoomed.width, zoomed.height);
<canvas id="zoomed"></canvas>
那么如何避免这种情况呢?
那么简单地避免在非整数像素坐标处填充。这意味着您也必须不断了解您的上下文转换矩阵,而不仅仅是您传递给绘图函数的值。
(Ps:还要记住,stroke 是一个更邪恶的野兽,因为它从线条的中间开始绘制,所以在这种情况下,你甚至必须考虑 lineWidth,请参阅这个Q/A关于此事的问题)。
推荐阅读
- javascript - 当复选框选择为否时禁用必填字段
- python - Python递归 - 矩阵中子序列的最大长度未更新
- bash - 是否可以使用 xmlstarlet 或其他 bash 工具在 xml 文件中注释/取消注释标签
- vba - 使用 VBA 在 CATIA 中删除重叠的相同曲面
- ios - Moya - 如何启用样本数据?
- sql-server - SQL fetch 正在工作,但在触发器中不起作用
- python - WxPython将选择转换为数值TypeError
- scala - 找不到参数 F 的隐式值:cats.Applicative[F]
- linux - 无法在 linux 机器上的 chrome 浏览器中运行 nightwatch.js 测试
- c# - 使用 [X] 按钮打开/显示其他表单单击 C#