HTML5 / Javascript图像加载方法和传递给变量
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的新手,对建议持开放态度。它加载图像并通过函数 Load(( 告诉主程序所有资产何时完成加载,然后将图像添加到对象 img 中。
我已经在我的图像中使用了一段时间,它可以工作。
例如,如果我这样做了。
LoadImage("Car", "imageOfCar.png");
ctx.drawImage(img.Car, 0, 0);
这样可以将图像很好地绘制到画布上。
但是,当我为图像分配另一个变量时,出于各种原因我想这样做,例如将图像分配给对象。
var secondCar = img.Car
然后尝试绘制它。
ctx.drawImage(secondCar, 0, 0);
我收到此错误。
未捕获的类型错误:无法在"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 代码都发生在脚本中.js在 index.html 中调用。
这就是在脚本中调用screen
的方式.js。
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 文件中还是从控制台中?
看起来您的加载图像函数很好。抱歉,这不是很有帮助,但希望能帮助您排除不查找问题的位置。
是利用Promise
,因为new Image
的事件是异步的load
secondCar
当用作setInterval
中的参数时可以undefined
,例如,load
img
的事件在调用LoadImage
后应用var secondCar = img.Car
时可能不完整;还为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()
中调用它。所以从现在开始,我只需要初始化所有可能需要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约定。
- 引用类变量中的原型方法
- 从Javascript方法返回全局变量
- 将方法从控制器注入到未使用右变量调用的指令
- 如何将javascript变量作为参数提供给asp.net方法
- 检查变量是否为字符串的简单方法
- 在javascript regexp中捕获多个变量的一种更简单的方法
- Javascript 方法看不到对象变量
- Chrome扩展:是否有一种方法可以运行JavaScript来获取页面上的内部html,并将其保存到扩展中的变量中
- 在变量中保存值的最佳方法是在应用程序关闭后使用,然后使用apachecordova在android中重新启动
- JavaScript对象范围-在对象方法中使用对象变量
- JavaScript:检查变量是否等于两个或多个值之一的简单方法
- 如何重用ajax工厂方法来设置$scoped变量
- 使用类/构造函数与变量方法时的作用域不同
- 如何在视图中呈现部分 js 或访问在应用程序/资产中的 js.erb 文件中的控制器操作中初始化的实例变量/方法
- 禁止特定变量/方法的esint规则
- 我应该以这种方式创建私有变量/方法吗?
- Javascript对象中的变量方法
- 如何用javascript从html文件中触发python中的变量/方法
- Javascript公共变量/方法
- Awesomium允许我在JS中调用/使用c++变量/方法吗?