マスク効果(またはクリッピング) – 日本語で書くアニメーションプログラム

このシリーズではアニメーションのためのプログラムを日本語に置き換えて解説します。
プログラムとして書かれた数式を日本語にすることで言語の仕様に依存しない「なぜそのように動くか?」という理解の一助となればと思います。

※私がWeb制作を生業にするフロントエンドエンジニアなのでプログラムの箇所はPixiJSで記述しています。

プログラムを日本語に(今回はPixiJS限定になります)

調べてみると、アニメーションするオブジェクトのマスク効果(またはクリッピング)の方法はプログラミング言語やライブラリによって差異が大きく一概にまとめられない事がわかりました。
なので今回はPixiJSの書き方の日本語訳になることをご了承ください。

描画コンテナにマスク用プロパティを追加 = マスクの形状パス

マスクやクリッピングの為の関数はその言語にもともと備わっている事が多いようです。
なので概ねの場合はどのような形状のマスクを登録するか、が大事になってくるでしょう。

一応、こちらを実際のプログラムで書くとこうなります。
ちなみに今回マスクの形は円に、アニメーションオブジェクトは円運動に記述しています。
※アニメーションに関係ない記述に関しては一部割愛しています。

const container = new PIXI.Container();

// 描画領域にマスクを設定
container.mask = new PIXI.Graphics()
	.beginFill(0xffffff)
	.drawCircle(400, 400, 200)
	.endFill();

// 動かすオブジェクトを定義
let obj = new PIXI.Graphics();
obj.beginFill(0xFFFFFF, 1);
obj.drawRoundedRect(0, 0, 100, 100, 16);
obj.endFill();
obj.pivot.x = 50;
obj.pivot.y = 50;

container.addChild(obj);

let radius = 10;
const speed = 3;
let angle = 0;

app.ticker.add((delta) => {
	angle += speed;
    obj.x = radius * Math.sin(angle * Math.PI / 180);
    obj.y = radius * Math.cos(angle * Math.PI / 180);
});

これを上から順番に日本語にするとこうなります。

描画領域 = 描画領域を設定

描画領域.マスクプロパティ = マスクの形状を登録

オブジェクト名 = オブジェクトの入れ物を作成
オブジェクト.色の塗りつぶし(白,透明度)
オブジェクト.角丸の四角を作成(x座標, y座標, 横幅, 縦幅, 角丸サイズ)
オブジェクト.色の塗りつぶし終了
オブジェクト.中心点x = オブジェクトの幅の半分
オブジェクト.中心点y = オブジェクトの高さの半分

描画領域にオブジェクトを追加

円運動の半径 = 200
速度 = 3
角度 = 0

アニメーションさせるためのループ処理{
 角度 += 速度
 オブジェクトのX座標 = 円運動の半径 * 三角関数sin(角度 * 円周率 / 180)
 オブジェクトのY座標 = 円運動の半径 * 三角関数cos(角度 * 円周率 / 180)
}

上述のサンプルを見ればわかるようにマスク効果に関わる箇所はかなり少ない記述で済みます。
これはPixiJSではContainerに対しmaskプロパティが用意されている事が大きく、他の言語でも同じことが多いようです。

例えばCanvas2Dではcontextにclipプロパティが、Swiftではレイヤーに対してmaskプロパティが、Processingではオブジェクトに対してmaskプロパティがetc…。
グラフィックやアニメーションを扱う言語ならだいたい常備されているもののようです。

マスク効果は汎用性が高くどんな表現でも使える可能性があります。
よく使われるのは矩形マスクの内側にタイトルなどのテキストがスライドインしたり、逆にテキストをマスクとして内側に動画を流したり…。

モーションに組み込む事でちょっと手間のかかった演出に見せる事が出来るかもしれません。