HTML/CSS
アイキャッチ 猫

こんにちは。今回はJavaScriptでcanvas要素を使って、複数の画像を1つのimg要素へ出力する方法をご紹介します。

同じフォルダ構成+ファイル名の画像さえあれば、コピペで再現できます!

HTML

今回のHTMLは至ってシンプルです。
img要素を作成する親divを記述しています。

<body>
    <div id="result"></div>
</body>

CSS

今回はCSSは使用していないので、不要です。
※ その代わりJavaScriptがしっかり目です。

JavaScript

JavaScriptはこちらです。
今回はJQueryは使っていません。

要所要所で、解説用にコメントを記述してみました。

window.onload = function () {
    // 色々宣言・初期化
    var canvas = document.createElement("canvas");
    canvas.width = 0;
    canvas.height = 0;
    var images = [];
    var srcs = [
        'img/1.jpg',
        'img/2.jpg',
        'img/3.jpg',
        'img/4.jpg',
    ];
    var loadCount = 0;

    // Canvas上に画像を表示
    for (var i = 0; i < srcs.length; i++) {
        // Imageのインスタンスを生成し、それぞれの画像を設定
        images[i] = new Image();
        images[i].src = srcs[i];

        // 画像の読み込みが終わったら
        images[i].onload = function () {
            // カウントを取る
            loadCount++;

            // 画像全てloadが終わったら
            if (loadCount === images.length) {
                // ロード後の処理
                loadProcess(images, canvas);
            }
        };
    }
};

// ロード後の処理
function loadProcess(images, canvas) {
    // 画像それぞれのサイズを計算して、canvasのサイズを設定
    setCanvasSize(images, canvas);

    // canvasをクリアにする
    let ctx = canvas.getContext('2d');
    ctx.clearRect(0, 0, canvas.width, canvas.height);

    // カンバスに画像を描画
    drowImage(images, ctx);

    // canvasを画像に変換
    canvasToImage(canvas);
}

// カンバスサイズを設定
function setCanvasSize(images, canvas) {
    for (let i = 0; i < images.length; i++) {
        // 横幅は一番大きい画像に設定
        if (canvas.width < images[i].naturalWidth) {
            canvas.width = images[i].naturalWidth;
        }
        // 高さはプラスしていく
        canvas.height += images[i].naturalHeight;
    }
}

// カンバスに画像を描画
function drowImage(images, ctx) {
    var set_y = 0;
    for (let i = 0; i < images.length; i++) {
        ctx.drawImage(images[i], 0, set_y);
        // 前の画像分、高さをずらして表示させるため、set_yに現在の画像の高さを設定
        set_y += images[i].naturalHeight;
    }
}

// canvasからImgに変換
function canvasToImage(canvas) {
    // img要素を作成
    var outputImg = document.createElement('img');
    // canvasを画像に変換
    outputImg.src = canvas.toDataURL('image/png');
    // 変換したimg要素をdiv要素の中に追加
    document.getElementById('result').appendChild(outputImg);
}

デモ

デモページはこちらです。
サイズの取得を確認できるよう、さまざまな画像を使ってみました。

まとめ

いかがでしたでしょうか。
このようなcanvasの使い方もできるんですねぇ。。。
色んな描画の使い方ができるので、もっと!もっと!とできるようになりたいです。
(ちょっとしたミニゲームっぽいのもそろそろ作ってみたい。。。)

今回に限った話ではないですが、実務でC#をやっておきながら、JavaScriptでオブジェクト指向の書き方が全然できておらず、猛勉強中です。

可読性も上げたいと思っているので、近いうちに記事にできるようしっかり勉強していきます。