Проблема здесь в том, что загрузка обоих изображений обрабатывается неправильно.
Оба будут загружаться асинхронно, и пока ваши коды ожидают каждое событие load
, ваш код предполагает, что первое изображение всегда будет загружатьсяfirst.
Но, учитывая природу этих изображений, кажется, что второе изображение (sig
) будет более светлым (большинство пикселей прозрачным) и, следовательно, на самом деле, вероятно, будет загружаться быстрее.
Возможно, вы не сталкивались с этой проблемой в браузере, поскольку браузер уже имел эти изображения в кеше, и, следовательно, для загрузки обоих изображений потребуется одинаковое время.
В эпоху доОбещания, распространенный способ справиться с этим - использовать счетчик, который будет увеличиваться при загрузке каждого изображения и который вызовет обратный вызов oncomplete :
function loadImages(urls, onsuccess, onerror) {
var counter = 0;
var imgs = urls.map(function load(url) {
var img = new Image();
img.onload = incrementCounter;
img.src = url;
img.onerror = onerror;
return img;
});
function incrementCounter(evt) {
if(++counter === urls.length) {
onsuccess(imgs);
}
}
}
var canvas = document.body.appendChild(document.createElement('canvas'));
var ctx = canvas.getContext('2d');
loadImages([
// a quite big 3000 x 2000 picture by Arturo Mann
'https://upload.wikimedia.org/wikipedia/commons/6/65/Sunset_over_The_Pacific_Ocean_at_Acapulco_1.jpg',
// a small 32x32 image
'https://dl.dropboxusercontent.com/s/4e90e48s5vtmfbd/aaa.png'
], oncomplete, onerror);
function loadImages(urls, onsuccess, onerror) {
var counter = 0;
var imgs = urls.map(function load(url) {
var img = new Image();
img.onload = incrementCounter;
img.src = url;
img.onerror = onerror;
return img;
});
function incrementCounter(evt) {
if(++counter === urls.length) {
onsuccess(imgs);
}
// only for demo
console.log('successfully loaded', evt.target.src);
}
}
// our callback
// in here we receive the img elements,
// in the order we did set the urls
// whatever was the first to load
function oncomplete(imgs) {
canvas.width = imgs[0].width/8;
canvas.height = imgs[0].height/8;
ctx.scale(0.125, 0.125);
ctx.drawImage(imgs[0], 0,0);
ctx.imageSmoothingEnabled = false;
ctx.scale(8, 8);
ctx.drawImage(imgs[1], 176, 100);
}
function onerror(err) {
console.error('failed to load resources');
}
Но так как вы, похоже, находитесь в контексте, который поддерживает Promises и ES6, вы можете просто обещать загрузку и ждать Promise.all из этих нагрузок.
Promise.all([loadImage(url1), loadImage(url2)])
.then(oncomplete)
.catch(onerror);
function loadImage(url) {
return new Promise((res, rej) => Object.assign(
new Image(),
{
onload: (evt)=>res(evt.target),
onerror: rej,
src: url
}
)
);
}
var canvas = document.body.appendChild(document.createElement('canvas'));
var ctx = canvas.getContext('2d');
// a quite big 3000 x 2000 picture by Arturo Mann
var url1 = 'https://upload.wikimedia.org/wikipedia/commons/6/65/Sunset_over_The_Pacific_Ocean_at_Acapulco_1.jpg';
// a small 32x32 image
var url2 = 'https://dl.dropboxusercontent.com/s/4e90e48s5vtmfbd/aaa.png';
Promise.all([loadImage(url1), loadImage(url2)])
.then(oncomplete)
.catch(onerror);
function loadImage(url) {
return new Promise((res, rej) => Object.assign(
new Image(),
{
onload: (evt)=>res(evt.target),
onerror: rej,
src: url
}
)
);
}
// our callback
// in here we receive the img elements,
// in the order we did set the urls
// whatever was the first to load
function oncomplete(imgs) {
canvas.width = imgs[0].width/8;
canvas.height = imgs[0].height/8;
ctx.scale(0.125, 0.125);
ctx.drawImage(imgs[0], 0,0);
ctx.imageSmoothingEnabled = false;
ctx.scale(8, 8);
ctx.drawImage(imgs[1], 176, 100);
}
function onerror(err) {
console.error('failed to load resources');
}