Masking shapes in HTML5 canvas?

怎甘沉沦 提交于 2019-12-30 00:07:44

问题


Apologies if this has been asked elsewhere but it's pretty hard to phrase as it is so I couldn't find anything.

Is there any way to implement masks in canvas?

For example, using shapes only (no images) I draw a house with a window. I also have a shape representing a person. I want that person to appear at the window - but obviously only so much as the window allows should be visible of the person. The rest would be masked.

I thought about emptying the part of the house occupied by the window, such that there was a genuine hole in the layer, which makes the problem easy to solve.

But I'm conscious you can't delete shapes or parts of shapes in canvas, only draw new stuff over old stuff. So in a multi-layered environment (I'm making a game in Kinetic.JS), what exactly can I do?

Sorry if any of this is poorly explained - new to the whole graphic thing.


回答1:


You should learn about clipping and compositing soon, but neither of these are what you actually need here.

Instead you need to learn how to make paths using the non-zero winding number rule, which is what HTML5 canvas uses.

If you draw part of your path clockwise and another part counter-clockwise, you can "cut out" shapes from your path.

Here's an example with a window:

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


edit: Here's a bit of a visualization for you of how the nonzero winding number rule works:

Subpaths are drawn in a direction, and where the paths cross you'll get filled (or not) spaces.

If you put your finger on any part of the figure, and imagine a line going from your finger out into the empty space, that line crosses the path a number of times. If you start at zero and add 1 for every clockwise path, and subtract 1 for every counterclockwise path, the filled areas are all of the areas that have a non-zero number. The numbers for the areas are given in the above diagram.




回答2:


You just need to create a clipping path and draw your shape in there. The Mozilla Developer Network is a great starting place for learning canvas. Here's the section on clipping.

I've created a basic fiddle with an example of what I think you are trying to create.

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);

Hope this helps, good luck with your project!



来源:https://stackoverflow.com/questions/12021219/masking-shapes-in-html5-canvas

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!