当vars是全局的时,用javascript绘制图像将不起作用

时间:2014-02-12 22:53:52

标签: javascript image canvas

嘿我想绘制多个图像,一个是画布背景,两个是可以在画布上移动的玩家。这是我的问题:当我将var canvas和canvas属性全局放置时,它不起作用。但是当我把它放回到img.onload函数中时它会起作用!为什么这有以及我有哪些选择?

var canvas = document.getElementById("Canvas");
 canvas.width = 500;     
 canvas.height = 500;
 var g = canvas.getContext("2d");

var img = new Image();   
img.src = "Images/Grass Texture.png";

var player1 = new Image();   
player1.src = "Images/Players/Mignolet.png";

var player2 = new Image();   
player2.src = "Images/Players/De Gea.png";

var football = new Image();   
football.src = "Images/Football/Football.png";

img.onload = function()
{
   /* The rest of the code draws onto the graphics context */
   g.drawImage(img, 0, 0);
   g.drawImage(img,1200, 1200, 1200, 1200); 
};

1 个答案:

答案 0 :(得分:0)

了解图像加载是异步的很重要。这意味着在您的图片加载时,代码将继续尽管。

如果浏览器无法及时加载和解码图像,则无法绘制任何图像。

即使你使用onload处理程序(这是必要的),你需要考虑其余代码中的异步性质 - 也许代码会继续到其他因为依赖于图像而失败的部分

您可以像这样收集图像加载:

...

/// if you have many images an array could be considered    
var img = new Image();   
var player1 = new Image();   
var player2 = new Image();   
var football = new Image();   

/// number of images to load
var count = 4;

/// now share a load handler
img.onload      = loadHandler;
player1.onload  = loadHandler;
player2.onload  = loadHandler;
football.onload = loadHandler;

/// set sources to start loading
img.src      = "Images/Grass Texture.png";
player1.src  = "Images/Players/Mignolet.png";
player2.src  = "Images/Players/De Gea.png";
football.src = "Images/Football/Football.png";

function loadHandler() {

    /// decrement the counter
    count--;

    /// when 0 all images has loaded
    if (count === 0) startGame();
}

当所有图片都已加载后,脚本将继续startGame(),这也是您需要继续游戏的地方:

function startGame() {
    ...
    g.drawImage(img, 0, 0);
    g.drawImage(img,1200, 1200, 1200, 1200); 

    /// Important! continue your code from here
    nextStep();
}

因此,在通过设置源调用图像加载后,您的脚本在调用startGame()之前不会调用任何其他步骤。

现在,加载可能由于各种原因而失败。如果你没有处理错误,你的游戏可能会停止,你不会知道原因。在开发过程中,您当然应该始终检查控制台是否有错误(如果发生任何错误,请参阅控制台,网络等),但对于用户来说,这无济于事。

您应该始终为图像添加错误处理程序机制。您可以在设置onerror处理程序后使用onabortonload处理程序执行此操作:

var hasErrors    = false;

img.onerror      = errorHandler;
player1.onerror  = errorHandler;
player2.onerror  = errorHandler;
football.onerror = errorHandler;

img.onabort      = errorHandler;  /// or use a separate abort handler
player1.onabort  = errorHandler;
player2.onabort  = errorHandler;
football.onabort = errorHandler;

在错误处理程序中,您可以通知用户,或使用回退或任何可能解决问题的方法:

function errorHandler(err) {

    /// set error flag
    hasErrors = true;

    /// notify user, post an error message etc. something..
    console.log('Could not load image:', this.src, err);

    /// call loadHandler() from here to decrement counter and
    /// handle situation when all images has reported in for duty (or not)
    loadHandler();
}

然后将loadHandler修改为错误识别(这里只是一个警告,但替换为更有用的东西):

function loadHandler() {

    /// decrement the counter
    count--;

    /// when 0 all images has loaded
    if (count === 0) {
        if (hasErrors) {
            alert('Sorry mate! Error during image loading');
            return;
        }
        startGame();
    }
}

话虽这么说,您也可以通过使用可以处理所有设置和事件(加载,错误,进度等)的图像加载器来完成此操作。这些是制作,包括。如果可能的话,YAIL loader(还有其他人),为了节省开发人员的许多问题和头痛 - 他们是免费的。需要考虑的事情..

希望这有帮助!