PixiJS で以下のようにすると PIXI.Graphics
を使ってマスクすることができますが、このままではアルファ値が考慮されず使い勝手が悪かったので、やり方を調べてみました。
const sprite = new PIXI.Sprite(texture);
// マスク作成
const mask = new PIXI.Graphics();
sprite.mask = mask;
// マスク描画
// メモ: ここでアルファ値や色を指定しても適用されない
mask.beginFill();
mask.drawRect(50, 50, 100, 100);
mask.endFill();
1. 答え
答えから言うと、PIXI.Graphics
ではアルファ値を考慮しない仕様になっているので、代わりに PIXI.Sprite
を使います。ただし、ここでは画像を読み込んでマスクをしたいわけではなく、PIXI.Graphics
に描画したものをマスクとして使用したいので、PIXI.Graphics
から PIXI.Sprite
に変換して使います。
(ただし、現在の PixiJS では PIXI.CanvasRenderer
の場合に PIXI.Sprite
をサポートしていないようです。)
mask.generateTexture()
を使うのは動的にマスクをいじるときにスマートな方法ではないので、ここでは PIXI.RenderTexture
を使います。
// メモ: 以下の変数があると仮定
// texture: PIXI.Texture
// app: PIXI.Application
const sprite = new PIXI.Sprite(texture);
// マスク作成
// メモ: texture の読み込みが終わっていないと [sprite.width, sprite.height] === [1, 1] になる
// メモ: 代わりにサイズを直接指定しても良い
const renderTexture = PIXI.RenderTexture.create(sprite.width, sprite.height);
const renderTextureSprite = new PIXI.Sprite(renderTexture);
sprite.mask = renderTextureSprite;
const mask = new PIXI.Graphics();
// マスク描画
// メモ: アルファ値として RGB の R を使用
mask.beginFill(0xff0000);
mask.drawRect(50, 50, 100, 100);
mask.endFill();
app.renderer.render(mask, renderTexture, false);
マスクの内容を変更したいときは、mask
に書き込んでから app.renderer.render(mask, renderTexture, false);
とすれば更新できます。
RGB 値の R をアルファ値の代わりに使えるので、0x000000
のように色を指定して描画をすればその領域を透明にできます。
参考「Mask + renderTexture - PixiJS Examples」
参考「Graphics and masks don't work correctly · Issue #2770 · pixijs/pixi.js · GitHub」
参考「PixiJS API Documentation」(公式ドキュメントのトップページ)
2. その他
しっかりと理解できていないのですが、マスクそのものを app.stage.addChild()
する必要があるそうです。
(マスクをかけたいものに対してではなく、app.stage
に直接?)
公式の Examples を見ると、なぜか PIXI.Graphics
でアルファ値を指定していたり、逆に PIXI.RenderTexture
でアルファ値を指定していませんが、アルファ値を指定してマスクしたいときは PIXI.RenderTexture
を使います。