1) Первый вариант - объявить холст и контекст и присвоить им значения после того, как документ загружен
<!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, чтобы он уже загружался в DOM , когда ваш javascript пытается получить к нему доступ.
<!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>
IМы использовали новые ключевые слова const
и let
только для того, чтобы подчеркнуть разницу между этими двумя подходами, хотя использование var
также будет работать нормально.(см. let и const )
Если вы хотите избегать глобальных переменных , тогда вы можете структурировать свой код следующим образом
<!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>
Неважно, что я использую функции стрелок или querySelector , я просто предпочитаю эти новые методы.Смысл в том, чтобы передать контекст холста любой функции, которая нуждается в этом draw(ctx)
.
Две строки кода, создающие Image()
и затем устанавливающие фон, должны были быть выполнены до завершения загрузки документаэто немного выдумки.Что нам действительно нужно сделать, это убедиться, что изображение, которое мы пытаемся установить в качестве загруженного фона, перед вызовом drawImage()
Использование изображений
<!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>