Холст: drawImage не рисует изображение на холсте

Я использую холст для игры. У меня есть объект Sprite, который рисует себя на холсте, в классе Sprite я создаю элемент Image вместе с его атрибутом src при создании объекта.

Вот код, который не работает:

Sprite.prototype.draw = function(Context){
    this.Image.onLoad = function(){
    Context.drawImage(this.getImage(),this.getX(),this.getY());
    };
};

В конструкторе объектов я передаю строковый параметр, который является путем к файлу изображения - он сохраняется правильно.

У меня такое ощущение, что проблема заключается в функции setImage:

Sprite.prototype.setImage = function(){
    this.Image = document.createElement('img');
    this.Image.src = this.getImagePath(); //This just returns the path as a                                                                      
                                            string
};

Я не получаю ошибок во время выполнения... но изображение не выводится на экран?

Кто-нибудь может указать, что случилось? Я искал ответы на этот вопрос, но у всех все элементы создаются в html-документе, тогда как все мои создаются на лету, не знаю, имеет ли это какое-то значение.

Ваше здоровье


person Lee Brindley    schedule 23.10.2013    source источник
comment
Во-первых, это onload, а не onLoad. Во-вторых, ваша функция draw только прикрепляет прослушиватель к вашему объекту изображения. Если к моменту вызова draw событие load уже было запущено, код прослушивателя никогда не запустится.   -  person apsillers    schedule 23.10.2013


Ответы (1)


Ваш код построен на синхронной модели, но вы используете асинхронные вызовы, что означает, что это не будет работать, как вы могли ожидать.

Сначала вы устанавливаете URL-адрес вашего объекта изображения, что означает, что процесс загрузки вызывается немедленно. В то время, когда вы затем вызываете отрисовку, изображение может быть или не быть уже загруженным (если оно существует в кеше, этот процесс обычно происходит мгновенно), поэтому, когда вы затем устанавливаете свой обработчик загрузки (который должен быть в нижнем регистре), объект изображения, возможно, передается этот этап, и он никогда не будет вызван (браузер не ждет, пока он будет установлен).

Чтобы это работало, вам нужно использовать другую модель, например, обратные вызовы и/или обещания. Для простоты обратные вызовы подойдут.

Примером этого может быть:

Sprite.prototype.setImage = function(callback){
    this.Image = document.createElement('img');
    this.Image.onload = function() {
        callback(this); /// just for ex: passing image to callback (or other inf)
    }
    this.Image.src = this.getImagePath();
};
Sprite.prototype.draw = function(Context){
    Context.drawImage(this.getImage(), this.getX(), this.getY());
};

Таким образом, когда изображение загрузится, оно снова вызовет функцию, указанную вами как обратный вызов, например:

var sprite = new Sprite(); /// pseudo as I don't know you real code

sprite.setImagePath('someurl');
sprite.setImage(imageLoaded);

function imageLoaded() {
    sprite.draw(context);
}

(Лично я бы объединил setImagePath и setImage - не усложняйте.)

person Community    schedule 23.10.2013
comment
Ваше здоровье! Я из фона С#, поэтому асинхронность по умолчанию немного меня расстраивает - person Lee Brindley; 24.10.2013
comment
Еще раз спасибо, этот ответ действительно соединил для меня много точек - person Lee Brindley; 24.10.2013
comment
@Фендорио нет проблем! Рад, что смог помочь. - person ; 24.10.2013
comment
Благодарю вас! Я работаю на Java/Ruby, и вы очень помогли мне в этом! Я никогда не думал, что проблема заключается в выполнении асинхронных вызовов для модели синхронизации. Я чешу голову уже несколько дней! - person newguy; 13.06.2016