Что произойдет, если я попытаюсь использовать drawImage () для изображения, которое еще не загружено полностью? - PullRequest
1 голос
/ 08 сентября 2011

Если я передам ссылку на изображение в drawImage API HTML canvas, но изображение все еще загружается, что произойдет?Получит исключение, или API продолжит работу с частичными данными, или API будет блокироваться до загрузки изображения?

Ответы [ 4 ]

3 голосов
/ 08 сентября 2011

Спецификация говорит, что ничто не должно быть нарисовано.

Если первый аргумент не является элементом img, canvas или video, генерируется исключение TYPE_MISMATCH_ERR. Если изображение не содержит данных изображения, генерируется исключение INVALID_STATE_ERR. Если один из размеров исходного прямоугольника равен нулю, генерируется исключение INDEX_SIZE_ERR. Если изображение еще не полностью декодировано, то ничего не рисуется.

Я попробовал это просто ради этого. Вы можете посмотреть результаты здесь.

Я в основном использовал PHP для замедления загрузки изображения.

slowimage.php

<?php
    sleep(3);

    header('Content-type: image/png');
    echo file_get_contents('stackoverflow-logo-300.png');
?>

index.html

<canvas id="canvas" width="512" height="512">

<script>
    var img = new Image();
    img.onload = function() {
        alert("image loaded");
    };
    img.src = "slowimage.php";

    var ctx = document.getElementById("canvas").getContext("2d");
    ctx.drawImage(img, 0, 0);
</script>

Как было установлено, и, как вы можете видеть, ничего не нарисовано.

3 голосов
/ 08 сентября 2011

Спецификация canvas требует, чтобы ничто не рисовалось, даже если оно загружено на 99%.Это не выдает ошибку.

Так что если вы делаете:

var img = new Image();
img.src = 'http://placekitten.com/300/300';
// Might occur before the image is done loading (bad!)
ctx.drawImage(img, 0, 0);

Вот почему большинство людей делают что-то похожее на:

var img = new Image();
img.onload = function() {
  // Will occur only once the image is done loading
  ctx.drawImage(img, 0, 0);
}
img.src = 'http://placekitten.com/300/300';

Чтобы гарантировать, чтоизображение будет нарисовано.

1 голос
/ 08 сентября 2011

Я однажды наткнулся на это;проблема заключалась в том, что я не видел ничего нарисованного, потому что я не использовал img.onload.

. Вы можете подтвердить это: http://jsfiddle.net/pimvdb/eGjak/100/. Скорее всего, он сначала не будет отображаться, но появитсяперезагрузите из-за кеша.

Лучше всего всегда использовать onload.

0 голосов
/ 08 сентября 2011

API ничего не будет рисовать на холсте. Если вы не используете цикл, который перерисовывает холст с включенным в него изображением, пользователь никогда не увидит изображение. Обычной практикой является использование onload с изображениями для canvas - все браузеры, поддерживающие canvas, поддерживают img.onload. В циклической ситуации вы можете избежать добавления изображений на лету, но знаете, что до тех пор, пока они не будут загружены, они не будут видны.

...