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

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

给出以下代码

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

你会期望它会在画布上从点x:10,y:10开始渲染带有此图像的图案.

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

修复是翻译画布

ctx.translate(10,10);

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

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

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

所以我的问题是:

为什么在填充模式时,rect和fillRect的行为是这样的,考虑到大部分时间它是反直觉的?

最佳答案 模式(
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填充的简写,但使用的临时路径不影响当前的全局路径).

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

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

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

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

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

点赞