72
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

posted at

updated at

HTML5のcanvas内に複数の画像を任意の順序で表示する

概説

HTML5のcanvas内に1枚の画像を表示するのは簡単です。
複数の画像を表示するのも結構簡単なのですが、これを任意の順序で表示しようとするとちょっと工夫が必要でした。

まずは1枚の画像を表示してみます。

JavaScript
<body>
<canvas id="canvas" width="600" height="400"></canvas>
<script>
(function() {
    var canvas = document.getElementById('canvas');
    var context = canvas.getContext('2d');

    var image = new Image();
    image.src = '1.png';
    image.addEventListener('load', function() {
        context.drawImage(image, 0, 0, 150, 100);
    }, false);
})();
</script>
</body>

問題なく表示されます。

1枚のみ

次に同じ要領で、4枚の画像を左上から順にちょっとずつずらして重なるように表示してみたいと思います。

JavaScript
<body>
<canvas id="canvas" width="600" height="400"></canvas>
<script>
(function() {
    var canvas = document.getElementById('canvas');
    var context = canvas.getContext('2d');

    var image1 = new Image();
    image1.src = '1.png';
    image1.addEventListener('load', function() {
        context.drawImage(image1, 0, 0, 150, 100);
    }, false);

    var image2 = new Image();
    image2.src = '2.png';
    image2.addEventListener('load', function() {
        context.drawImage(image2, 50, 70, 150, 100);
    }, false);

    var image3 = new Image();
    image3.src = '3.png';
    image3.addEventListener('load', function() {
        context.drawImage(image3, 100, 140, 150, 100);
    }, false);

    var image4 = new Image();
    image4.src = '4.png';
    image4.addEventListener('load', function() {
        context.drawImage(image4, 150, 210, 150, 100);
    }, false);
})();
</script>
</body>

単純に同じ処理を連続で書くと、画像のサイズによって読み込み順が保証されないため、うまくいかないパターンが発生します。どうやら、2枚目、4枚目よりも1枚目と3枚目が後に読み込まれたため、このような表示になっているようです。

4枚でうまくいってないパターン

画像サイズによって読み込み順が変わることがあるということが分かったので、今度は4枚の画像の読み込みが終わった時点で、表示を行うようしてみます。

JavaScript
<body>
<canvas id="canvas" width="600" height="400"></canvas>
<script>
(function() {
    var canvas = document.getElementById('canvas');
    var context = canvas.getContext('2d');

    var srcs = [
        '1.png',
        '2.png',
        '3.png',
        '4.png',
    ];
    var images = [];
    for (var i in srcs) {
        images[i] = new Image();
        images[i].src = srcs[i];
    }

    var loadedCount = 1;
    for (var i in images) {
        images[i].addEventListener('load', function() {
            if (loadedCount == images.length) {
                var x = 0;
                var y = 0;
                for (var j in images) {
                    context.drawImage(images[j], x, y, 150, 100);
                    x += 50;
                    y += 70;
                }
            }
            loadedCount++;
        }, false);
    }
})();
</script>
</body>

期待する表示になりました。

4枚でうまくいったパターン

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
72
Help us understand the problem. What are the problem?