我正在研究一个动态画布动画,它将加载多个图像并为其设置动画。
似乎我遇到了竞争状态,我不知道如何解决它。
此对象构造函数加载图像,为它们创建对象,并将宽度和高度变量设置为自然图像大小的1/2。
window.imgWidth;
window.imgHeight;
//array to hold character objects
window.character = [];
window.characterPosition;
function Character(name, x, y){
//define the image object within the Character
this.imageObject = new Image();
this.imageObject.src = 'data:text/javascript;base64,'+name;
window.character.push(this);
window.characterPosition = window.character.indexOf(this);
//set natural width and natural height once the image is loaded
//conditional used by Chrome
if (this.imageObject.addEventListener){
this.imageObject.addEventListener('load', function(){
window.imgWidth = this.naturalWidth/2;
window.imgHeight = this.naturalHeight/2;
//set natural width and natural height to object
window.character[characterPosition]['imageObject']['w'] = window.character[characterPosition]['imageObject']['w0'] = window.imgWidth;
window.character[characterPosition]['imageObject']['h'] = window.character[characterPosition]['imageObject']['h0'] = window.imgHeight;
//set initial x and y position
window.character[characterPosition]['imageObject']['x1'] = x;
window.character[characterPosition]['imageObject']['y1'] = y;
//set loaded property for the object once loading is done
window.character[characterPosition]['imageObject']['loaded'] = true;
console.log(characterPosition);
console.log(window.character[characterPosition]['imageObject']);
function imageLoaded(element, index, array){
return element['imageObject']['loaded'] == true;
}
//test whether every object in array has the image loaded
if(character.every(imageLoaded)){
$('button#play').show();
};
});
}
} //end object constructor
准备好内部文档,我正在使用此对象构造函数创建两个对象。
var sun0 = new Character('iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAW0lEQVR42mL8//8/AzpgZGTcC6KBcs5wMRwK/0MVMsLEmLAoEmXAApiwiKUhaRJCltgLsQVsWwIQ/wTx0fBeRigD7B6Y24i1mj4Kn4KI7Uie2Y7FI8+B2AMgwABjRynfWgpcxQAAAABJRU5ErkJggg==', 12, 12);
var sun1 = new Character('R0lGODlhCgAKANUCAEKtP0StQf8AAG2/a97w3qbYpd/x3mu/aajZp/b79vT69MnnyK7crXTDcqraqcfmxtLr0VG0T0ivRpbRlF24Wr7jveHy4Pv9+53UnPn8+cjnx4LIgNfu1v///37HfKfZpq/crmG6XgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAIALAAAAAAKAAoAAAZIQIGAUDgMEASh4BEANAGAxRAaaHoYAAPCCZUoOIDPAdCAQhIRgJGiAG0uE+igAMB0MhYoAFmtJEJcBgILVU8BGkpEAwMOggJBADs=',0,0);
问题是,由于this.imageObject.addEventListener('load', function(){
是异步的,每次运行对象构造函数时运行的console.log
消息都显示来自第二个对象的信息。我希望第一组显示来自第一个对象的信息,第二组显示来自第二个对象的信息。
//First set, run by sun0
console.log(characterPosition); //1
console.log(window.character[characterPosition]['imageObject']); //info for sun1
//Second set, run by sun1
console.log(characterPosition); //1
console.log(window.character[characterPosition]['imageObject']); //info for sun1
我能够通过设置这样的计时器来解决它:
var sun0 = new Character('iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAW0lEQVR42mL8//8/AzpgZGTcC6KBcs5wMRwK/0MVMsLEmLAoEmXAApiwiKUhaRJCltgLsQVsWwIQ/wTx0fBeRigD7B6Y24i1mj4Kn4KI7Uie2Y7FI8+B2AMgwABjRynfWgpcxQAAAABJRU5ErkJggg==', 12, 12);
window.setTimeout(slowLoad, 2000);
function slowLoad(){
var sun1 = new Character('R0lGODlhCgAKANUCAEKtP0StQf8AAG2/a97w3qbYpd/x3mu/aajZp/b79vT69MnnyK7crXTDcqraqcfmxtLr0VG0T0ivRpbRlF24Wr7jveHy4Pv9+53UnPn8+cjnx4LIgNfu1v///37HfKfZpq/crmG6XgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAIALAAAAAAKAAoAAAZIQIGAUDgMEASh4BEANAGAxRAaaHoYAAPCCZUoOIDPAdCAQhIRgJGiAG0uE+igAMB0MhYoAFmtJEJcBgILVU8BGkpEAwMOggJBADs=',0,0);
}
这按预期工作。
//First set, run by sun0
console.log(characterPosition); //0
console.log(window.character[characterPosition]['imageObject']); //info for sun0
//Second set, run by sun1
console.log(characterPosition); //1
console.log(window.character[characterPosition]['imageObject']); //info for sun1
但显然,我不想引入手动延迟,以便在sun0完成后才能使sun1的功能运行。如何在sun0完成其功能(包括异步部分)后立即运行var sun1
?请记住,我将为几个(约15个)其他图像执行此操作。
答案 0 :(得分:0)
可能有更好的方法,但是我用一个函数来解决这个问题,该函数中包含一堆条件语句,以便在运行创建该对象的函数之前查看是否定义了一个对象。
function loadImages(){
if (!character[0]){
var sun0 = new Character('sun0', sunParent.x, sunParent.y);
} else if (!character[1]){
var sun1 = new Character('sun1', sunParent.x, sunParent.y);
} else if (!character[2]){
var sun2 = new Character('sun2', sunParent.x, sunParent.y);
} else if (!character[3]){
var bed = new Character('bed', 50, 500);
} else if (!character[4]){
var bed = new Character('plant1', 480, 490);
} else if(character.every(imageLoaded)){
$('button#play').show();
}
//test whether every object in array has the image loaded
function imageLoaded(element, index, array){
return element['imageObject']['loaded'] == true;
}
}
我最初在文档就绪时调用loadImages();
,并在加载图像的异步部分内的结尾处调用它。