Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 05.02.2018, 11:00
Новичок на форуме
Отправить личное сообщение для micronic Посмотреть профиль Найти все сообщения от micronic
 
Регистрация: 05.02.2018
Сообщений: 2

Image.onload() не загружает изображение в canvas
Добрый день, форумчане!

Измучился уже весь, не могу решить проблему, вся надежда только на вас...

Я пытаюсь построить средствами JS на элементе canvas некий граф с изображениями. Каждый узел графа содержит свой набор изображений, которые необходимо вывести. Поэтому я создаю класс, представляющий собой узел, и пытаюсь вывести изображения, пути к которым хранятся в его свойствах.

Получился следующий код:
function Schema()
    {
        //Массив путей к файлам изображений, которые необходимо вывести на canvas в рамках текущего объекта
        this.Characters = [["11985_32.png"], ["22470_32.png"]];

        //Функция вывода изображений для объекта
        this.Show = function()
        {
            this.canvas = document.querySelector("canvas")
            this.cx = this.canvas.getContext("2d");

            this.i = 0;
            while (this.i<this.Characters.length)
            {
                this.Characters[this.i][1] = new Image();
                this.Characters[this.i][1].onload = function(parent)
                {
                    console.log(parent.i+": "+parent.Characters[parent.i][1].src);
                    parent.cx.drawImage(parent.Characters[parent.i][1], 100, 100 + parent.i*40);
                }(this)
                this.Characters[this.i][1].src = "Types/"+this.Characters[this.i][0];
                this.cx.fillText(this.Characters[this.i][0], 100, 100 + this.i*40);
                this.i++;
            }
        }
    }

    //В тестовых целях создаем один единственный объект
    var schema = new Schema();
    //И пытаемся его отобразить на canvas
    schema.Show();

Я постарался его немного сделать более читабельным, поэтому не пинайте сильно за не оптимальность.
В поле this.Characters хранится массив путей к файлам изображений. Точнее даже массив массивов, потому что я хотел бы сохранить напротив каждого пути еще и ссылку на соответствующий объект Image(), но суть не в этом.
Далее в цикле выводим все изображения. Здесь я постарался использовать замыкание для того чтобы событие onload отработало корректно.
Но у меня ничего не получается... Код исполняется, но console.log() выводит пустые пути к файлам. То есть получается что onload срабатывает ДО того как файл будет реально загружен.

Я уже всю голову сломал. Подскажите пожалуйста, как правильно загружать изображения в цикле? Да еще внутри метода класса...
Ответить с цитированием
  #2 (permalink)  
Старый 05.02.2018, 13:28
Профессор
Отправить личное сообщение для Nexus Посмотреть профиль Найти все сообщения от Nexus
 
Регистрация: 04.12.2012
Сообщений: 3,795

Сообщение от micronic
Здесь я постарался использовать замыкание для того чтобы событие onload отработало корректно.
Вы, вероятно, не понимаете что это такое.
У вас в свойстве "onload" undefined, т.к. вы присваиваете результат работы функции, не её саму.
Между строк 12 и 13 создайте переменную, которая будет хранить ссылку на контекст (слово "this"), в функции-callback'е onload созданная переменная и будет вашим "parent".
Ответить с цитированием
  #3 (permalink)  
Старый 05.02.2018, 13:31
Профессор
Отправить личное сообщение для Nexus Посмотреть профиль Найти все сообщения от Nexus
 
Регистрация: 04.12.2012
Сообщений: 3,795

function Schema() {
	//Массив путей к файлам изображений, которые необходимо вывести на canvas в рамках текущего объекта
	this.Characters = [
		["11985_32.png"],
		["22470_32.png"]
	];
	//Функция вывода изображений для объекта
	this.Show = function() {
		this.canvas = document.querySelector("canvas")
		this.cx = this.canvas.getContext("2d");
		var parent = this;
		for(var i = 0; i < this.Characters.length; i++) {
			(function(i) {
				parent.Characters[i][1] = new Image();
				parent.Characters[i][1].onload = function() {
					console.log(i + ": " + parent.Characters[i][1].src);
					parent.cx.drawImage(parent.Characters[i][1], 100, 100 + i * 40);
				};
				parent.Characters[i][1].src = "Types/" + parent.Characters[i][0];
				parent.cx.fillText(parent.Characters[i][0], 100, 100 + i * 40);
			})(i);
		}
	}
}
//В тестовых целях создаем один единственный объект
var schema = new Schema();
//И пытаемся его отобразить на canvas
schema.Show();
Ответить с цитированием
  #4 (permalink)  
Старый 05.02.2018, 14:07
Новичок на форуме
Отправить личное сообщение для micronic Посмотреть профиль Найти все сообщения от micronic
 
Регистрация: 05.02.2018
Сообщений: 2

Сообщение от Nexus
Вы, вероятно, не понимаете что это такое.
Да, мое понимание механизма замыканий весьма ограничено, кроме того явно имеются проблемы с синтаксисом. JS - не мой родной язык...

Большое спасибо, все сразу заработало!

А подскажите такой момент: если таким образом все объекты начнут загружать изображения, то будут ли они кешироваться браузером? Если у меня 2 разных объекта должны будут загрузить 2 раза одно и то же изображение, будет ли оно браться из кеша браузера или же каждый объект скачает свою копию файла картинки, и чтобы это избежать, мне надо организовывать отдельный класс, кеширующий динамически загружаемые изображения?
Ответить с цитированием
  #5 (permalink)  
Старый 05.02.2018, 14:28
Профессор
Отправить личное сообщение для Nexus Посмотреть профиль Найти все сообщения от Nexus
 
Регистрация: 04.12.2012
Сообщений: 3,795

micronic, по идее изображение должно кешироваться браузером, точно ответить не могу.

Сообщение от micronic
JS - не мой родной язык...
Для населения какого субъекта JS - родной язык?)
Можно не отвечать.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
JS загружает изображение всегда с локального кэша - почему? buhpro Общие вопросы Javascript 4 02.10.2013 21:01
Как открыть большое canvas изображение в IE10 function Internet Explorer 1 22.09.2013 19:24
Как в canvas нарисовать одно изображение на другом? Dimaz Общие вопросы Javascript 0 29.07.2013 20:11
canvas img draw проблема max0n Общие вопросы Javascript 2 04.07.2013 21:31
Canvas импорт изображение из папки! Severtain Общие вопросы Javascript 1 13.06.2011 16:27