简体   繁体   English

为什么我的图像不显示在画布上?

[英]Why won't my image show on canvas?

I'm trying to make a simple bubble popping game, but I want a different image to show on the background of the canvas, it works sometimes but other times it just won't appear... to show the image I have the following... 我正在尝试制作一个简单的泡泡弹出游戏,但我希望在画布的背景上显示不同的图像,它有时可以工作,但有时却不会出现...以显示该图像,我有以下内容...

function theWeather(weather) {
    var c = document.getElementById("canvas");
    var ctx = c.getContext("2d");
    weather = "Rain";
    theImg(weather,ctx,c);
}

function theImg (weather,ctx,c) {
    var bg = new Image();
    if (weather === "Rain" || weather === "rain") {
        bg.src = "http://lukebarrier.co.uk/LukesPria/img/rain.jpg";
        ctx.drawImage(bg, 0, 0);
    } else if (weather === "Clouds" || weather === "clouds") {
        bg.src = "http://lukebarrier.co.uk/LukesPria/img/cloud.png";
        ctx.drawImage(bg, 0, 0);
    } else if (weather === "Clear" || weather === "clear") {
        bg.src = "http://lukebarrier.co.uk/LukesPria/img/sun.png";
        ctx.drawImage(bg, 0, 0);
    }
}

Here is a link to the game as it is... Bubble Popping 这里是游戏的链接。 泡泡弹出

Any help would be appreciated! 任何帮助,将不胜感激! and thanks in advance... 并预先感谢...

I can't replicate it locally but if you are saying it is only failing periodically then given the code you've posted I'd be inclined to suggest that it's related to the image not having finished loading before being passed to the canvas (resulting in a blank image) . 我无法在本地复制它,但是如果您说它只是定期失败,那么鉴于您已发布的代码,我倾向于建议它与图像传递到画布之前尚未完成加载有关(结果在空白图片中)

You could try adding an onload callback to the image: 您可以尝试向图像添加onload回调:

function theImg (weather,ctx,c) {
    var url = 'http://lukebarrier.co.uk/LukesPria/img/', 
        bg = new Image();

    bg.onload = function(){
        ctx.drawImage(this, 0, 0);
    }

    switch(weather.toLowerCase()){
        case 'rain': 
            bg.src = url+'rain.jpg'; break;
        case 'clouds':
            bg.src = url+'clouds.jpg'; break;
        case 'clear':
            bg.src = url+'clear.jpg'; break;
    }
}

You are trying to drawImage your images before you've given them time to load. 您需要先给图像加载时间,然后再对其绘制图像。

Demo: http://jsfiddle.net/m1erickson/6d5M4/ 演示: http//jsfiddle.net/m1erickson/6d5M4/

Here's an imageloader that preloads all your images so that they are available when needed: 这是一个预加载所有图像的图像加载器,以便在需要时可以使用它们:

// image loader

var imageURLs=[];  // put the paths to your images here
var imagesOK=0;
var imgs=[];
imageURLs.push("yourImage1.png");
imageURLs.push("yourImage2.png");
loadAllImages(start);

function loadAllImages(callback){
    for (var i=0; i<imageURLs.length; i++) {
        var img = new Image();
        imgs.push(img);
        img.onload = function(){ 
            imagesOK++; 
            if (imagesOK>=imageURLs.length ) {
                callback();
            }
        };
        img.onerror=function(){alert("image load failed");} 
        img.crossOrigin="anonymous";
        img.src = imageURLs[i];
    }      
}

function start(){

    // the imgs[] array holds fully loaded images
    // the imgs[] are in the same order as imageURLs[]

}

The reason is that your image(s) hasn't finished loading at the time you try to draw them as image loading is asynchronous. 原因是您尝试绘制图像时图像尚未完成加载,因为图像加载是异步的。

For a single image you can simply add an event handler for the onload on the image. 对于单个图像,您可以简单地为图像上的onload添加一个事件处理程序。

...
img.onload = function(e) {
    ctx.drawImage(this, 0, 0);
    /// continue game from here
}
img.src = '...';   /// set src last

In your code: 在您的代码中:

function theWeather(weather) {
    var c = document.getElementById("canvas");
    var ctx = c.getContext("2d");
    weather = "Rain";
    theImg(weather,ctx,c, startDraw);  /// add a callback here
}

function startDraw() {
    ctx.drawImage(this, 0, 0);
    /// continue game here
}    

function theImg (weather,ctx,c, callback) {
    var bg = new Image();
    bg.onload = callback;

    if (weather === "Rain" || weather === "rain") {
        bg.src = "http://lukebarrier.co.uk/LukesPria/img/rain.jpg";
    } else if (weather === "Clouds" || weather === "clouds") {
        bg.src = "http://lukebarrier.co.uk/LukesPria/img/cloud.png";
    } else if (weather === "Clear" || weather === "clear") {
        bg.src = "http://lukebarrier.co.uk/LukesPria/img/sun.png";
    }
}

I would recommend using a loader if you need to load several images such as YAIL . 如果您需要加载多个图像(例如YAIL),我建议使用加载器。

Simply set up your loader like this: 像这样简单地设置您的加载程序:

var loader = (new YAIL({
    done    : doneFunction,
    urls    : [url1, url2, url3]
})).load();

When the images has loaded it will then call doneFunction from where you continue your game, drawing of the images etc.: 加载图像后,它将在继续游戏,绘制图像等的地方调用doneFunction。

function doneFunction(e) {
    ctx.drawImage(e.images[0], 0, 0);  /// for example
}

The url list can be made in advance as you do, then just hand them to the loader when done. 可以像您一样预先创建URL列表,然后在完成后将它们交给加载程序。

Disclaimer: I am the author of YAIL. 免责声明:我是YAIL的作者。 YAIL is free open-source (MIT license). YAIL是免费的开源(MIT许可证)。 Please see link above for docs/more info 请参阅上面的链接以获得文档/更多信息

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM