こんにちは。今回は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でオブジェクト指向の書き方が全然できておらず、猛勉強中です。
可読性も上げたいと思っているので、近いうちに記事にできるようしっかり勉強していきます。