🎞️
giflerでgifをcanvas描画する [JavaScript]
giflerというライブラリを使用して、gifアニメーションをcanvasに描画する方法を備忘録的にまとめます。
使用
giflerのライブラリを読み込む
giflerのライブラリですが、npmで公開されているバージョン(v0.1.0)は古く、2022年9月現在、公式ドキュメントの記述通りに動作しないため公式ページよりコードをダウンロードしてくるのがいいかと思います。
▼公式ページ
gifアニメーションを描画
背景透過でないgifの場合
背景透過でないgifの場合、
gilferのanimate()
メソッドを使うことで以下のように短いコードで動かすことができます。
declare let gifler: any;
const addGif = () => {
let image = new Image();
image.onload = () => {
const canvas = document.createElement("canvas");
document.body.appendChild(canvas);
canvas.width = image.width / 2;
canvas.height = image.height / 2;
// giflerのアニメーション処理
gifler(image.src).animate(canvas);
};
image.src = "/static/image/image.gif";
};
window.onload = () => {
addGif();
};
背景透過のgifの場合
animate()
メソッドは、背景をリセットしないまま上書きで描画するので
背景が透明のgifの場合は、前のフレームの描画が残ってしまいます。
▼フレームが残っている例
この場合は、より高い自由度で制御できるget()
メソッドを使って処理を書くのが良さそうです。
const onDrawFrame = (ctx, frame) => {
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.drawImage(frame.buffer, 0, 0, ctx.canvas.width, ctx.canvas.height);
};
gifler(image.src)
.get()
.then((animator) => {
animator.onDrawFrame = onDrawFrame;
animator.animateInCanvas(canvas, false);
});
onDrawFrame
は毎秒呼ばれる処理で、このなかで毎秒canvasの描画をリセットするclearRect()
を実行。
▼フレーム残りなく動作している様子
アニメーションの停止
giflerのget()
メソッドの返り値animator
に対して、animator.stop()
とすることでアニメーションの停止ができます。
// animatorを入れておく変数を用意
let giflerAnimator;
gifler(image.src)
.get()
.then((animator) => {
// 上で用意した変数にanimatorを入れておく
giflerAnimator = animator;
animator.onDrawFrame = onDrawFrame;
animator.animateInCanvas(canvas, false);
});
const stopGif = () => {
// animator.stop() でアニメーション(毎秒呼ばれるonDrawFrame処理)が停止する
giflerAnimator.stop();
};
おまけ: ボタンで制御
以上を組み合わせると、gifのアニメーションをボタンで制御できるようにもできます。
declare let gifler: any;
let giflerAnimator;
const addGif = () => {
let image = new Image();
image.onload = () => {
const canvas = document.createElement("canvas");
document.body.appendChild(canvas);
canvas.width = image.width / 2;
canvas.height = image.height / 2;
const onDrawFrame = (ctx, frame) => {
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.drawImage(frame.buffer, 0, 0, ctx.canvas.width, ctx.canvas.height);
};
gifler(image.src)
.get()
.then((animator) => {
giflerAnimator = animator;
animator.onDrawFrame = onDrawFrame;
animator.animateInCanvas(canvas, false);
});
};
image.src = "/static/image/image.gif";
};
const startGif = () => {
giflerAnimator.start();
};
const stopGif = () => {
giflerAnimator.stop();
};
const addEvent = () => {
const start = document.getElementById("start");
start.addEventListener("click", startGif, false);
const stop = document.getElementById("stop");
stop.addEventListener("click", stopGif, false);
};
window.onload = () => {
addGif();
addEvent();
};
参考
giflerのメソッドの詳細は、ライブラリのgilfer.coffeeの中身を見ることで確認できます。
Discussion