pixi.jsで背景を(半)透明にする
pixi.jsが描画するcanvasをオーバーレイしたかったので背景色を半透明にしようとしてました。
これは一見簡単そう(&地味)ですが、実現するのに若干躓いたのでメモしておきます。
前提
pixi.jsはv5.2.0を使用。主にgoogle chromeで検証してます。(モダンブラウザなら大きな違いはない・・・はず)
以下のような雛形HTMLをベースにしています。
描画結果をわかりやすくするため、canvas背後に確認用divボックスをおいてます。
またpixi側には仮のスプライトを配置します。
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <meta http-equiv="x-ua-compatible" content="IE=Edge"> <meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no"> <title>pixi starter</title> <style type="text/css"> .container { position: relative; } canvas { border: 1px solid black; } .box { position: absolute; top: 100px; left: 100px; background: #FADC8D; width: 200px; height: 200px; z-index: -1; } </style> </head> <body> <div class="container"> <div class="box">このボックスは確認用</div> <canvas id="pixi-view"></canvas> </div> <script src='https://cdnjs.cloudflare.com/ajax/libs/pixi.js/5.2.0/pixi.min.js'></script> <script> /* 以降に表記するスクリプトはここに書いたもの */ const SCREEN_SIZE = 256 const app = new PIXI.Application({ width: SCREEN_SIZE, height: SCREEN_SIZE, view: document.getElementById("pixi-view"), }); // テスト用の星スプライト const star = new PIXI.Graphics(); star.lineStyle(2, 0xFFFFFF); star.beginFill(0x35CC5A, 1); star.drawStar(0, 0, 5, 50); star.endFill(); star.position.set(app.view.width/2, app.view.height/2) app.stage.addChild(star); // ループ処理 app.ticker.add((delta)=> { star.rotation -= 0.01 * delta; }); </script>
以降のコードはところどころ前後省略してますので、そのつもりで適宜補完してください。
背景を完全に透明にするには
はじめに思いつくのが、App(renderer)の生成時のオプションとしてbackgroundColorにアルファ値を渡すことですが、backgroundColorには6桁の16進数でRGB値までしか渡せません(*)。
var app = new PIXI.Application({ width: SCREEN_SIZE, height: SCREEN_SIZE, view: document.getElementById("pixi-view"), // アルファチャンネルは指定できない backgroundColor: 0xff00ff, // backgroundColor: 0xff00ff00, // これはうまくいかない });
(* 厳密には渡せますが、期待したような結果にはなりません)
背景を透明にするにはbackgroundColorではなくtransparentというオプションを指定します。
const app = new PIXI.Application({ width: 256, height: 256, view: document.getElementById("pixi-view"), transparent: true, });
ただし気をつけたいのがtransparentと同時にbackgroundColorを指定していると、背後にあるDOMがその設定の影響を(なぜか)受けます。
例えばbackgroundColorがピンクだったら、ピンク色のフィルターがかかったようになります。
const app = new PIXI.Application({ width: SCREEN_SIZE, height: SCREEN_SIZE, view: document.getElementById("pixi-view"), backgroundColor: 0xff00ff, transparent: true, });
これはこれで面白いと思いますが、意図してない場合はbackgroundColor
は無指定にします。
背景を半透明にするには
では半透明にするにはどうすればいいのでしょうか。
canvas全体の不透明度を変えるだけならCSSでopacityを変更すると言ったこともできますが、スプライト等はそのまま・背景だけを変えたい場合はその方法では駄目です。
これは今の所、スクリーン全体を覆うGraphicsを用意して、それを背景代わりに使う方法しか思いつきませんでした。
(ググっても出てこない)
const backgroundAlpha = 0.8; // 透明度設定 const app = new PIXI.Application({ width: SCREEN_SIZE, height: SCREEN_SIZE, view: document.getElementById("pixi-view"), // 本来の背景は透明にする transparent: true, }); // 背景代わりのGraphicsを設定 const backgroundVeil = new PIXI.Graphics(); backgroundVeil.beginFill(0x000000, backgroundAlpha); backgroundVeil.drawRect(0, 0, app.view.width, app.view.height); backgroundVeil.endFill(); app.stage.addChild(backgroundVeil); // テスト用の星スプライト const star = new PIXI.Graphics(); star.lineStyle(2, 0xFFFFFF); star.beginFill(0x35CC5A, 1); star.drawStar(0, 0, 5, 50); star.endFill();
これで冒頭のイメージ図を再現できます。
👇出力サンプル👇