当我发现这种古怪时,我最近在画布上玩了一些代码。
给出以下代码
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
这种方式的行为,在填充模式时考虑到大部分时间都是反直觉的?
答案 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你还会找到一个能为你做任何事情的功能。