Canvas image masking / overlapping

The question as it stands is a bit unclear IMO. To give a more general answer that you can apply to a scenario where you need clipping you can use (at least) two approaches:

Method 1 – Using composite mode to clip

Composite mode is the simplest way but also the least flexible as you need to pre-define the clipping mask as an image with a transparent background (usually PNG).

You can either use the solid parts of the image to clip the next drawn thing, or use the transparent areas to fill in.

Here is an approach where we use the solid parts to clip the next drawn shape/image:

/// draw the shape we want to use for clipping
ctx1.drawImage(imgClip, 0, 0);

/// change composite mode to use that shape
ctx1.globalCompositeOperation = 'source-in';

/// draw the image to be clipped
ctx1.drawImage(img, 0, 0);

Here the globalCompositeOperation is changed to source-in which means that the source image (the one we are gonna draw next to destination) will be drawn inside the existing solid data. Nothing will be drawn to transparent areas.

If our clipping mask looks like this (random fair-use from the net):

Clip mask

And our image like this:

Main image

The result will be this:

Composited image

Method 2 – Using a Path to clip

You can also define a Path for the clipping. This is very flexible as you can adjust the path or animate it if you desire.

Note: Just have in mind that clipping using Path is currently a bit “fragile” in the browsers so you should consider using save() and restore() before and after setting and using a clip path as the browsers are unable to reset clip at the moment (restore will restore the default clip = full canvas);

Lets define a simple zig-zag path (this will be your waves in your case):

/// use save when using clip Path
ctx2.save();

ctx2.beginPath();
ctx2.moveTo(0, 20);
ctx2.lineTo(50,0);
/// ... more here - see demo
ctx2.lineTo(400, 20);
ctx2.lineTo(400, 100);
ctx2.lineTo(0, 100);
ctx2.closePath();

/// define this Path as clipping mask
ctx2.clip();

/// draw the image
ctx2.drawImage(img, 0, 0);

/// reset clip to default
ctx2.restore();

Now that we have set the clipping mask using clip anything drawn to the canvas next will be clipped to fit inside that shape (note that we make sure the shape can end where it begun):

Path clipped image

Leave a Comment