javascript - 为什么 HTML5 Canvas rect/fillRect 具有来自 Canvas 来源的图案渲染?

标签 javascript html canvas html5-canvas

当我发现这个奇怪之处时,我最近在 Canvas 上摆弄了一些代码。

给定以下代码

var pattern = ctx.createPattern(image, 'repeat');
ctx.fillStyle = pattern;
ctx.fillRect(10, 10, 500, 500);

您会期望它会使用此图像呈现图案 pattern在 Canvas 上从点 x:10, y:10 开始。

然而,实际发生的事情似乎是它渲染了从 x:10, y:10 开始的矩形,但是从 x:0, y:0 开始的模式>.

offset illustration

修复是翻译 Canvas

ctx.translate(10,10);

然后从x:0, y:0开始渲染矩形

ctx.fillRect(0, 0, 500, 500);

我已经在 jsfiddle 设置了一个演示来说明问题。只需更改 x 和 y 偏移量即可查看默认情况下发生的情况,然后使用复选框启用翻译以“修复”问题。

所以我的问题是:

为什么 rectfillRect 的行为在填充模式时是这样的,考虑到大多数时候它是违反直觉的?

最佳答案

模式 ( CanvasPattern ) 是单独的全局对象(在 Canvas 上下文的意义上),未绑定(bind)到使用它作为样式的方法。

由于模式不“知道”它是否被使用,如果它仅用于样式,也没有绑定(bind)到按位置使用它的方法,坐标系统变为可以说是在哪里绘制和平铺图案的唯一 anchor 。

例如,做一个 rect(x, y, w, h) 只会通知浏览器在哪里您要渲染矩形本身,而不是如何填充它,这是样式模式保存的信息,并且是在使用当前样式(可以是任何纯色、图案或渐变 -后者具有与模式相似的行为)。

另一方面是路径可以累积。例如,如果您这样做了:

ctx.fillStyle = myPattern;
ctx.rect(x1, y1, w, h);
ctx.rect(x2, y2, w, h);
ctx.fill();

两个矩形中的哪一个应该作为填充操作的 anchor ? (fillRect 只是 rect+fill 的简写,只是使用了一个不影响当前全局路径的临时路径)。

rect()、arc() 等仅创建路径,当您调用填充/描边时,这些路径将被栅格化到具有设置的任何填充/描边样式的 Canvas 。

当调用填充/描边时,浏览器(或操作系统的图形子系统)可能会做这样的事情:

  • 使用点的变换矩阵(比例、方向和位置)栅格化形状/路径,并创建内部 mask / mask
  • 使用该蒙版/ mask 以当前样式合成(填充)该蒙版
  • ..其他步骤

现在只有一个 mask / mask ,您不再有任何定义的 anchor ,坐标系是唯一剩下的东西。

(远离使用不同算法的可能性,即多边形填充,路径仍然存在等 - 但性能和图形系统会影响这些决策以及规范,其目标是实现相同的跨浏览器行为和跨平台)。我在写这篇文章时半睡半醒,所以我希望我没有让它变得更加模糊......

关于javascript - 为什么 HTML5 Canvas rect/fillRect 具有来自 Canvas 来源的图案渲染?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23779575/

相关文章:

javascript - 为什么这个函数不返回 css 规则?

javascript - 无法从网络服务获取响应

javascript - 使用警告框请求用户输入

php - 如何在 WordPress 中启用图片库

javascript - 在 switch 语句中使用 ViewBag

html - IE中的Textarea滚动条重叠圆形边框

javascript - 在 Javascript 中使用按钮引用 Canvas

Java Canvas 绘图套接字

canvas - 有没有办法在 R/exams 的 exams2canvas 中使用 LaTeX 包?

javascript - Mouseup 事件未使用函数内部代码触发