在 HTML5 画布中隐藏形状?

Posted

技术标签:

【中文标题】在 HTML5 画布中隐藏形状?【英文标题】:Masking shapes in HTML5 canvas? 【发布时间】:2012-08-14 19:30:25 【问题描述】:

抱歉,如果在其他地方问过这个问题,但很难说清楚,所以我找不到任何东西。

有没有办法在画布中实现遮罩?

例如,仅使用形状(无图像)我画了一栋带窗户的房子。我也有一个代表一个人的形状。我希望那个人出现在窗口 - 但显然只有窗口允许的那个人才能看到。其余部分将被屏蔽。

我想过把房子被窗户占用的部分清空,这样层上有一个真正的洞,这样问题就容易解决了。

但我知道你不能删除画布中的形状或形状的一部分,只能在旧的东西上绘制新的东西。那么在多层环境中(我正在用 Kinetic.JS 制作游戏),我究竟能做什么?

很抱歉,如果其中任何内容解释不当 - 对整个图形来说都是新事物。

【问题讨论】:

这里可能给出一些建议link 【参考方案1】:

您应该很快了解剪辑和合成,但这些都不是您真正需要的。

相反,您需要学习如何使用非零缠绕数规则创建路径,这是 html5 画布使用的。

如果您顺时针绘制路径的一部分,而逆时针绘制另一部分,则可以从路径中“切出”形状。

这是一个带有窗口的示例:

http://jsfiddle.net/simonsarris/U5bXf/


编辑:以下是非零缠绕数规则如何工作的可视化:

子路径是按一个方向绘制的,路径交叉的地方会填充(或不填充)空格。

如果您将手指放在图形的任何部分,并想象一条线从您的手指伸到空白处,那条线会多次穿过路径。如果从零开始,每条顺时针路径加 1,每条逆时针路径减 1,则填充区域是所有具有非零数字的区域。这些区域的数字如上图所示。

【讨论】:

感谢您的帮助和小提琴。剪掉的东西对我来说是一种启示。从来没有意识到您可以通过在开放路径上绘制形状而不是填充它们来有效地将某些区域标记为透明(这似乎是您正在做的事情)。这背后的设计选择是什么,或者它是一个黑客?稍微偏离主题的问题:my edit of your Fiddle 怎么来,我不能简单地得到一个描边的矩形 - 它坚持要被填充(目前是橙色)? 另外,这种剪裁技术是否仅适用于线条绘制的路径? I updated your Fiddle 尝试通过rect() 而不是使用lineTo() 命令绘制初始蓝色方块,但切口不再出现。 这不是开放路径和封闭路径,而是绘制路径的方向。让我再举几个例子 给你:jsfiddle.net/simonsarris/zGQTA 你知道当你在纸上画一个圆时,你可以顺时针或逆时针画它吗?所有的路径都是这样的。任何时候顺时针路径和逆时针路径交叉,都会留下未填充的区域。查看可视化的编辑 这很有趣——因为这种行为似乎没有逻辑基础。如果你用笔做同样的事情,你就不会得到同样的结果,那么这个功能纯粹是为了方便帮助解决像我这样的情况而设计的吗?还是我错过了它发生的一些数学、逻辑原因?我知道它很有用,只是不知道为什么会发生这种情况。【参考方案2】:

您只需要创建一个剪切路径并在其中绘制您的形状。 Mozilla 开发者网络是学习画布的绝佳起点。这是clipping的部分。

我创建了一个基本的fiddle,其中包含我认为您正在尝试创建的示例。

var ctx = document.getElementById('canvas').getContext('2d');
ctx.fillRect(0, 0, 150, 150);

// create a clipping path
ctx.beginPath();
ctx.moveTo(20, 20);
ctx.lineTo(20, 130);
ctx.lineTo(130, 130);
ctx.lineTo(130, 20);
ctx.clip();

// backgroud in clipped area
ctx.fillStyle = "#11c";
ctx.fillRect(0, 0, 150, 150);

// draw shapes inside clipped area
ctx.translate(75, 90);

ctx.fillStyle = '#f00';

ctx.fillRect(-15, -40, 40, 40);
ctx.fillRect(0, 0, 10, 10);
ctx.fillRect(-25, 10, 60, 60);

希望这会有所帮助,祝你的项目好运!

【讨论】:

我接受了另一个答案,只是因为他让我看到了非零绕组数规则概念,这是一个启示,但我很感谢你的回答和详细的小提琴 -这是最有帮助的。 +1 给你。 哈哈,谢谢,很高兴您找到了解决方案。我也不知道非零缠绕规则的概念,所以我也设法学到了一些东西。

以上是关于在 HTML5 画布中隐藏形状?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 HTML5 画布中剪辑 INSIDE 形状?

如何在 HTML5 画布中剪辑多个形状的 INSIDE union?

更改在 HTML5 画布 Adob​​e Animate 中单击的形状的颜色

使用 javascript 从 HTML5 画布镜像形状

如何在 html5 画布中绘制椭圆?

如何处理在 HTML5 画布上绘制的形状并更改其属性?