Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/465.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在javascript中绘制图像赢得';当变量是全局变量时不工作_Javascript_Image_Canvas - Fatal编程技术网

在javascript中绘制图像赢得';当变量是全局变量时不工作

在javascript中绘制图像赢得';当变量是全局变量时不工作,javascript,image,canvas,Javascript,Image,Canvas,嘿,我想画多个图像,一个是画布背景,两个是可以在画布上移动的播放器。我的问题是:当我全局放置var canvas和canvas属性时,它不起作用。但是当我把它放回img.onload函数时,它就工作了!!!为什么会这样?我有什么选择 var canvas = document.getElementById("Canvas"); canvas.width = 500; canvas.height = 500; var g = canvas.getContext("2d"); va

嘿,我想画多个图像,一个是画布背景,两个是可以在画布上移动的播放器。我的问题是:当我全局放置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); 
};

重要的是要理解图像加载是异步的。这意味着您的图像加载时,代码将继续

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

即使在使用
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
onabort
处理程序执行此操作-在设置
onload
处理程序后:

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
,使其具有错误意识(此处只是一个警报,但替换为更有用的内容):

也就是说,您也可以通过使用图像加载器来实现这一点,图像加载器可以为您处理所有设置和事件(加载、错误、进度等)。这些都是为了避免开发者遇到很多问题和头疼而制作的,包括我自己的(如果可以的话),它们是免费的。需要考虑的事情…< /P> 希望这有帮助

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();
    }
}