为什么HTML5 Canvas rect / fillRect具有来自画布原点的图案渲染?

时间:2014-05-21 09:46:34

标签: javascript html5 canvas html5-canvas

当我发现这种古怪时,我最近在画布上玩了一些代码。

给出以下代码

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

你会期望它会在画布上从x:10, y:10开始渲染图像pattern

然而,实际上似乎发生的事情是它呈现的矩形从x:10, y:10开始,但模式从x:0, y:0开始。

offset illustration

修复是翻译画布

ctx.translate(10,10);

然后从x:0, y:0

开始渲染矩形
ctx.fillRect(0, 0, 500, 500);

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

所以我的问题是:

为什么rectfillRect这种方式的行为,在填充模式时考虑到大部分时间都是反直觉的?

2 个答案:

答案 0 :(得分:2)

模式(CanvasPattern)是单独的全局对象(在画布和上下文的意义上)没有绑定到使用它作为样式的方法。

由于模式不是"意识到"它是否被使用,如果它仅用于样式,并且它也不再与使用它的方法绑定,那么坐标系成为唯一的锚点。 - 说明在哪里绘制和平铺图案。

例如,执行一个rect(x,y,w,h)只会通知浏览器 要在哪里呈现矩形,而不是如何填充它,这是样式模式保存信息的内容,是在使用当前样式(可以是纯色,图案或渐变 - 合成/填充形状时)在下一步中执行的操作后者具有与模式类似的行为。

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

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

这两个rects中的哪一个应该是锚点进行填充操作? (fillRect只是rect + fill的简写,但使用的临时路径不影响当前的全局路径)。

rect(),arc()等仅创建路径,当您调用填充/描边时,这些路径将光栅化为画布,并设置任何填充/描边样式。

当调用填充/描边时,浏览器(或操作系统的图形子系统)可能会执行以下操作:

  • 使用变换矩阵为点(比例,方向和位置)栅格化形状/路径并创建内部遮罩/遮罩
  • 使用该遮罩/遮罩复合(填充)具有当前样式的遮罩
  • ..其他步骤

现在只有一个遮罩/遮罩,你不再有任何定义的锚点,坐标系是唯一剩下的东西。

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

答案 1 :(得分:0)

你是对的,你必须设置一个偏移量才能让模式从你的给定点开始。我认为这是因为大多数时间模式都要小得多,并且必须制作壁纸效果,而作为壁纸,中间区域很重要,而不是角落。< / p>

此外,您已经可以让模式从另一个点开始,因此此功能中并不需要更多功能。

在此:question你还会找到一个能为你做任何事情的功能。