パンジェンシーの「汗だく開発日誌」

システム開発の備忘録です。

【Javascriptライブラリ】canvasを使ったアニメーションを作成できる「ugoke.js」を作ってみました。

どうも、パンジェンシーでございます。

 

f:id:x-fieldatts:20150502134035p:plain

 

今回は、自分が作成したライブラリの紹介です。

 

HTML5を使えば、ブラウザ上にリッチなコンテンツを作成することができます。

その中でも、canvasはプログラムだけで様々な画像を作成でき、アニメーションも作成可能ということで注目されています。

 

しかし、アニメーションをするには、タイマーを使って定期的にcanvasをリフレッシュして、また新たに座標をずらした図形を書き込んで…と、少々面倒くさいです。

 

なので、基本的な処理をやってくれるライブラリ「ugoke(ウゴーク).js」を作成してみました。

 

コード

ugoke.js

function ugoke(id) {
    var JOB_INTERVAL = 30;
    var AFTERIMAGE_RATE = 0.9;
    var timerId;
    var canvas, ctx;

    var process = {
        pre: function() {},
        main: function() {},
        post: function() {}
    };

    var bg = {
        r: 0,
        g: 0,
        b: 0
    };

    function job() {
        process.pre(ctx);
        process.main(ctx);
        process.post(ctx);
        timerId = setTimeout(job, JOB_INTERVAL);
    }

    function setBg() {
        var color = "rgb("+bg.r+","+bg.g+","+bg.b+")";
        canvas.style.backgroundColor = color;
    }

    function clearCanvas() {
        ctx.clearRect(0, 0, canvas.width, canvas.height);
    }

    function afterimageEffect() {
        ctx.save();
        ctx.globalAlpha = 1 - AFTERIMAGE_RATE;
        ctx.fillStyle = "rgb("+bg.r+","+bg.g+","+bg.b+")";
        ctx.fillRect(0, 0, canvas.width, canvas.height);
        ctx.restore();
    }

    canvas = document.getElementById(id);
    if (!canvas || !canvas.getContext) {
        return false;
    }
    ctx = canvas.getContext("2d");

    canvas.width = canvas.clientWidth;
    canvas.height = canvas.clientHeight;

    setBg();

    window.onresize = function() {
        canvas.width = canvas.clientWidth;
        canvas.height = canvas.clientHeight;
    };

    return {
        width: function() {
            return canvas.width;
        },
        height: function() {
            return canvas.height;
        },
        bgColor: function(r, g, b) {
            bg.r = r;
            bg.g = g;
            bg.b = b;
            setBg();
        },
        interval: function(interval) {
            JOB_INTERVAL = interval;
        },
        afterimageRate: function(rate) {
            if (0 <= rate && rate <= 1) {
                AFTERIMAGE_RATE = rate;
            }
        },
        preProcess: function(pre) {
            if ("clear" === pre) {
                process.pre = clearCanvas;
            } else if ("afterimage" === pre) {
                process.pre = afterimageEffect;
            }
        },
        mainProcess: function(func) {
            process.main = func;
        },
        run: function() {
            job();
        },
        stop: function() {
            clearTimeout(timerId);
        },
        clear: function() {
            clearCanvas();
        },
        drawText: function(text, x, y, size, color) {
            ctx.save();
            ctx.font = "bold " + size + "px Century Gothic";
            ctx.fillStyle = color;
            ctx.lineJoin = "round";
            ctx.fillText(text, x, y);
            ctx.restore();
        }
    };
}


以上が、作ったライブラリです。


テスト用のHTMLは以下です。


test.html

<!doctype html>
<html lang='ja'>

<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>ugoke test</title>
</head>

<body>
    <canvas id="ugoke1" width="500" height="500"></canvas>
    <canvas id="ugoke2" width="500" height="500"></canvas>
</body>
<script src="ugoke.js"></script>
<script type="text/javascript">
var x = 0;

//**********************************************************
// ugoke(ウゴーク).jsは、
// canvasで動画を簡単に作成するためのライブラリです。
//**********************************************************
var ugoke1 = ugoke("ugoke1");
// まず、ugokeオブジェクトを作成します。
// この時、canvas要素のidを引数にします。

// ugokeの設定をします。

ugoke1.bgColor(100, 200, 100);
// bgColorは、canvasの背景色の設定です

ugoke1.interval(60);
// intervalは、canvasのフレームレートの設定です

ugoke1.preProcess("clear");
// preProcessは、フレーム毎の前処理を選択します。
// "clear"     : 前フレームの内容を全て削除します
// "afterimage": 前フレームの内容を少し残したままにします(残像効果)
// afterimageを選択した場合、afterimageRate(0〜1)を設定することで残像の具合を調整できます

ugoke1.mainProcess(function(ctx) {
    ctx.save();
    ctx.beginPath();
    ctx.fillStyle = "blue";
    ctx.rect(x, 20, 100, 100);
    ctx.fill();
    ctx.restore();
    if (x < ugoke1.width()) {
        x += 10;
    } else {
        x = 0;
    }
});
// フレーム毎のメインプロセスを設定します
// 引数には関数を設定でき、関数は第一引数として
// canvasのコンテキストオブジェクトをとります
// 図形を描画したりする処理はここに記述します

ugoke1.run();
// run()で、動画をスタートします

// stop()で、動作を一時停止することができます
// clear()で、canvasに書き込んだものをリセットします

var ugoke2 = ugoke("ugoke2");
var y = 0;
ugoke2.bgColor(200, 100, 100);
ugoke2.interval(60);
ugoke2.preProcess("afterimage");
ugoke2.mainProcess(function(ctx) {
    ctx.save();
    ctx.beginPath();
    ctx.fillStyle = "yellow";
    ctx.arc(100, y, 50, 0 * Math.PI / 180, 180 * Math.PI / 180, false);
    ctx.fill();
    ctx.restore();
    if (y < ugoke2.height()) {
        y += 10;
    } else {
        y = 0;
    }
});
ugoke2.run();
</script>

</html>

まとめ

自作のライブラリを紹介しました。

自分が使いやすいように作ったものなので、もしかしたら他の人の役に立たないかもしれませんが…。


ではまた。