Pixi.js Brings Canvas and webGL Masking

James Walker
Goodboy Digital
Published in
3 min readJul 2, 2013

Mat Groves brings Canvas and webGL Masking to pixi.js

Hello Pixi pushers! I am pleased to announce that we have added another new feature to Pixi.js. As you may have guessed from the title, it’s masking!

Masking (like primitives) is another one of those not so fancy but oh so essential features that all good libraries should have. So I’m super glad that we have finally got round to adding it in. Now any displayObject can now be masked by a PIXI.Graphics object.

We spent lots of time making sure that the masking looks and behaves pretty much exactly the same in both the webGL and Canvas rendererers :) Want to know more? Here’s a little run down on how we got it all working and what not:

Canvas Masking

The canvas renderer makes use of the canvas’ “clip” method. This is cool for a few reasons, the main one being that the clip method is defintely the fastest way to apply a mask in Canvas. The only other way of achieving masking is by using pixel level calculations. This second method allows for things such as alpha masking but comes at a pretty big performance cost.

The clip method is as fast as you can get. This is also why a mask must be a PIXI.Graphics object. The reason for this is that the graphics object is a collection af paths — the kind of paths that Canvas can use its clip method with. Perfecto!

WebGL Masking

The webGL renderer as always works completely differently :) So, how to implement masking in webGL? Enter the stencil buffer! The stencil buffer is another buffer that allow you to store custom information per pixel in addition to the color properties.

Its a little tricky to explain in depth but we essentially draw the “mask” image to the stencil buffer. Then during rendering each pixel is compared to its stencil buffer counterpart. If the stencil value is 1 then the pixel is drawn to the screen and if it is 0 then it is ignored. Boom! Masking in webGL.

This process is pretty fast too as it’s all super hardware accelerated and to keep things Pixi fast the stencil buffer is disabled / enabled as required. So if you’re not masking then its not used.

How to mask?

Masking in Pixi.js is super easy to use! First thing you need to do is create a graphics object that you would like to use as your mask, like so:

var myMask = new PIXI.Graphics();
myMask.beginFill();
myMask.drawCircle(0, 0, 300);
myMask.endFill();
stage.addChild(myMask)
The next step is to then set the graphics object to be the mask of you item. Its probably good to know that any PIXI.DisplayObject can be masked. Containers, Sprites, Cats, the lot!
var myMask = new PIXI.Graphics();
myMask.beginFill();
myMask.drawCircle(0, 0, 300);
myMask.endFill();
stage.addChild(myMask)// create something to be masked..
var mySprite = PIXI.Sprite.fromImage("testImage.png");
stage.addChild(mySprite)
// the magic line!
mySprite.mask = myMask
And there we have it! Masking made easy for your creative endeavours :)
Hopefully this basic level of masking will prove handy for people, but rest assured that more detailed masking methods will be available further down the line including alpha masking.You can get your hands on all this over on the github dev branch of Pixi.js It also includes the slightly trippy example above (example 14 -masking) so you can get your hands dirty and learn by example if ya fancy. You can also grap the src files for the example here.Happy Masking!Follow @Doormat23

--

--