[英]HTML5/Javascript Image loading method & passing to variable
我有一些用於加載圖像的代碼。
var assets = {
total:0,
success:0,
error:0
};
var stillLoading = true;
var img = {};
function LoadImage(name, path){
var toLoad = new Image();
toLoad.src = path;
assets.total++;
toLoad.addEventListener("load", function(){
assets.success++;
console.log(name + " loaded.");
img[name] = toLoad;
}, false);
toLoad.addEventListener("error", function(){
assets.error++;
}, false);
};
function Loading(){
if (assets.success == assets.total){
if (stillLoading){
console.log("All assets loaded. Starting game.");
};
stillLoading = false;
return false;
}else{
stillLoading = true;
return true;
};
};
自從我不熟悉javascript以來,可能仍然效率不高且很難看,建議不多。 它加載圖像並通過函數Loading()告訴主程序何時所有資產已完成加載,然后將圖像添加到對象img中。
我已經將它用於我的圖像已有一段時間了,並且可以使用。
例如,如果我這樣做。
LoadImage("Car", "imageOfCar.png");
ctx.drawImage(img.Car, 0, 0);
這樣可以將圖像繪制到畫布上。
但是,當我分配另一個變量圖像時,出於各種原因我想這樣做,例如將圖像分配給對象。 例如
var secondCar = img.Car
然后嘗試繪制它。
ctx.drawImage(secondCar, 0, 0);
我得到這個錯誤。
未捕獲到的TypeError:無法在'CanvasRenderingContext2D'上執行'drawImage':提供的值不是'(HTMLImageElement或HTMLVideoElement或HTMLCanvasElement或ImageBitmap)類型的值
如果它適用於初始變量,則應該對剛剛被分配了完全相同的對象的另一個變量以相同的方式起作用。 那么為什么我會收到此錯誤?
如果要加載圖像,則通常不檢查圖像是否已完成加載。
img.Car = new Image();
img.Car.src = "imageOfCar.png";
secondCar = img.Car;
ctx.drawImage(secondCar);
這會起作用。 這里的行為有點令人困惑,有人可以向我解釋正在發生的事情,也許會提出解決方法?
編輯:只是為了澄清。
這是html文件,稱為index.html。
<!DOCTYPE html>
<head>
<title>HTML5 Game Base</title>
<link rel = "stylesheet" type = "text/css" href = "styles.css">
</head>
<body>
<canvas id="screen" width="270" height="480" style="border:1px solid #000000;"></canvas>
<script src = "script.js"></script>
</body>
</html>
畫布設置為screen
。 我上面顯示的所有javascript代碼都發生在index.html中稱為script.js中。
這就是在script.js中調用screen
方式。
var canvas = document.getElementById("screen");
var ctx = canvas.getContext("2d");
這就是ctx.drawImage()
所引用的。
我意識到這不是最有用的答案,但是我對您的代碼進行了一些修改。 這是我使用的:
<!DOCTYPE html>
<head>
<title>HTML5 Game Base</title>
</head>
<body>
<canvas id="screen" width="270" height="480" style="border:1px solid #000000;"></canvas>
<script>
var stillLoading = true;
var img = {};
var canvas = document.getElementById("screen");
var ctx = canvas.getContext("2d");
assets = {};
assets.total = 0;
function LoadImage(name, path){
var toLoad = new Image();
toLoad.src = path;
assets.total++;
toLoad.addEventListener("load", function(){
//assets.success++;
console.log(name + " loaded.");
img[name] = toLoad;
}, false);
toLoad.addEventListener("error", function(){
assets.error++;
}, false);
}
</script>
</body>
</html>
然后在Chrome的控制台中輸入
LoadImage("Car", "map.png");
LoadImage("un", "Untitled.png");
ctx.drawImage(img.Car, 0, 0);
ctx.drawImage(img.un, 0, 0);
並獲得將圖像加載到畫布中的預期結果。 即使將img
圖像之一分配給新變量,這也可以按預期工作。
var second = img.Car
ctx.drawImage(second, 0, 0)
手動運行時,似乎一切正常,所以我想是時候了。 您什么時候運行這些命令? 它們在js文件中還是在控制台中?
看來您的LoadImage函數很好。 抱歉,這不是超級有用,但希望能幫助您排除不查找問題的地方。
一種方法可能是利用Promise
,因為new Image
load
事件是異步的,當在setInterval
用作參數時, secondCar
可能是undefined
,例如,當在調用LoadImage
之后應用var secondCar = img.Car
時, img
load
事件可能不完整; 還為setInterval
添加了變量引用,以便在需要時調用clearInterval()
var canvas = document.getElementById("screen"); var ctx = canvas.getContext("2d"); var interval = null; var assets = { total: 0, success: 0, error: 0 }; var stillLoading = true; var img = {}; function LoadImage(name, path) { return new Promise(function(resolve, reject) { var toLoad = new Image(); assets.total++; toLoad.addEventListener("load", function() { assets.success++; console.log(name + " loaded."); img[name] = toLoad; // resolve `img` , `assets` object resolve([img, assets]) }, false); toLoad.addEventListener("error", function() { assets.error++; reject(assets) }, false); toLoad.src = path; }) }; function Loading() { if (assets.success == assets.total) { if (stillLoading) { console.log("All assets loaded. Starting game."); }; stillLoading = false; return false; } else { stillLoading = true; return true; }; }; var promise = LoadImage("Car", "http://pngimg.com/upload/audi_PNG1736.png"); promise.then(function(data) { // `data` : array containing `img` , `assets` objects console.log(data); var secondCar = data[0].Car; interval = setInterval(function() { if (!(Loading())) { ctx.drawImage(secondCar, 0, 0); }; }, 1000 / 60); });
<canvas id="screen" width="1000" height="700" style="border:1px solid #000000;"></canvas>
解決了。 原來這是一個時間問題。 在我給出的示例中,當為secondCar
分配了img.Car
, img.Car
尚未加載。
相反,我創建了一個名為Initialise()
的新函數,並從Loading()
內部對其進行了Loading()
。 因此,從現在開始,我只需要初始化所有可能需要Initialise()
圖像的變量。 這樣,變量只能在加載后分配圖像。
新代碼:
var canvas = document.getElementById("screen");
var ctx = canvas.getContext("2d");
var assets = {
total:0,
success:0,
error:0
};
var stillLoading = true;
var img = {};
function LoadImage(name, path){
var toLoad = new Image();
toLoad.src = path;
assets.total++;
toLoad.addEventListener("load", function(){
assets.success++;
console.log(name + " loaded.");
img[name] = toLoad;
}, false);
toLoad.addEventListener("error", function(){
assets.error++;
}, false);
};
function Loading(){
if (assets.success == assets.total){
if (stillLoading){
console.log("All assets loaded. Starting game.");
Initialise();
};
stillLoading = false;
return false;
}else{
stillLoading = true;
return true;
};
};
LoadImage("Car", "http://pngimg.com/upload/audi_PNG1736.png");
function Initialise(){
window.secondCar = img.Car;
};
setInterval(function(){
if (!(Loading())) ctx.drawImage(secondCar, 0, 0);
}, 1000/60);
現在可以工作,感謝您的幫助,盡管我最終自己解決了問題。 我仍然希望您有任何改進建議。 或知道我是javascript新手,任何幫助我遵守javascript約定的nitpicks。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.