Javascript:图片无法加载到画布上

时间:2018-10-15 23:31:48

标签: javascript events canvas

我正在尝试使用图像作为画布的背景。但是,我很难加载图像-它始终显示为空白:

<html> 
<script>
    var background = new Image();
    background.src = "img/map.png";
    var canvas = document.getElementById("myCanvas");
    var ctx = canvas.getContext("2d");    

    window.onload = function() {
        ctx.drawImage(background, 0, 0);
    } 
</script> 
<body>

<canvas id="myCanvas" width="400" height="400"> </canvas>

</body> 
</html>

但是,如果将以下两行放入window.onload函数中,则图像加载不会有任何问题。是什么原因导致此问题?因为我将在其他函数中使用canvas和ctx,所以我真的想全局定义它们,而不是在每个函数中分别定义它们。

    var canvas = document.getElementById("myCanvas");
    var ctx = canvas.getContext("2d");    

2 个答案:

答案 0 :(得分:1)

您仍然可以全局使用它们。由于无法立即使用画布,因此无法在加载之前绘制图片。

<script>
    var background = new Image();
    background.src = "img/map.png";
    var canvas;
    var ctx ;  

    window.onload = function() {
        canvas = document.getElementById("myCanvas");
        ctx = canvas.getContext("2d");    
        ctx.drawImage(background, 0, 0);
    } </script>

答案 1 :(得分:1)

1)第一个选项是声明画布和上下文,并在文档具有loaded

后为其分配值
<!DOCTYPE html>
<html lang="en">
<head>
    <title>Onload</title>
    <script>
        const background = new Image();
        background.src = "img/map.png";
        let canvas;
        let ctx;

        window.onload = function() {
            canvas = document.getElementById("myCanvas");
            ctx = canvas.getContext("2d");
            ctx.drawImage(background, 0, 0);
        }
    </script>
</head>
<body>
    <h1>Method One</h1>
    <p>Defined variables globally and assign then after the load event is fired</p>
    <canvas id="myCanvas" width="400" height="400"></canvas>
</body>
</html>

2)第二种方法是将脚本块放在canvas元素之后,以便当您的JavaScript尝试访问它时,该脚本块已经被加载到DOM中。

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Onload</title>
</head>
<body>
    <h1>Method Two</h1>
    <p>Put the script after the DOM element you wish to access</p>
    <canvas id="myCanvas" width="400" height="400"></canvas>

    <script>
        const background = new Image();
        background.src = "img/map.png";
        const canvas = document.getElementById("myCanvas");
        const ctx = canvas.getContext("2d");

        window.onload = function() {
            ctx.drawImage(background, 0, 0);
        }
    </script>
</body>
</html>

我使用了新的constlet关键字只是为了强调这两种方法之间的区别,尽管使用var也会很好。 (请参见letconst

如果您想avoid global variables,则可以这样构造代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Onload</title>
    <script>
        const background = new Image();
        background.src = "img/map.png";

        draw = context => {
            context.drawImage(background, 0, 0);
        }

        window.addEventListener('load', () => {
            const canvas = document.querySelector("#myCanvas");
            const ctx = canvas.getContext("2d");
            draw(ctx);
        });
    </script>
</head>
<body>
    <h1>Refactor</h1>
    <p>Add an event listener and pass in context to draw function</p>
    <canvas id="myCanvas" width="400" height="400"></canvas>
</body>
</html>

我使用arrow functionsquerySelector都没关系,我只喜欢这些更新的方法。关键是将画布上下文传递给需要它的任何函数draw(ctx)

创建Image()然后设置背景的两行代码必须在文档完成加载之前完成,这有点不正确。我们真正需要做的是在调用drawImage() Using images

之前,确保已加载要设置为背景的图像。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Onload</title>
    <script>
        draw = context => {
            const background = new Image();
            background.src = "img/map.png";
            background.addEventListener('load', () => {
                context.drawImage(background, 0, 0);
            });
        }

        window.addEventListener('load', () => {
            const canvas = document.querySelector("#myCanvas");
            const ctx = canvas.getContext("2d");
            draw(ctx);
        });
    </script>
</head>
<body>
    <h1>Final</h1>
    <p>Add an event listener to the image</p>
    <canvas id="myCanvas" width="400" height="400"></canvas>
</body>
</html>