Отображение сетки Canvas 2d не будет отображаться - PullRequest
0 голосов
/ 27 апреля 2018

У меня есть следующий код, который не выдает никаких ошибок в консоли. Я пытаюсь отобразить 2D-массив в виде сетки. Изображения определены с правильным путем. Тем не менее, в настоящее время будет отображаться только контур холста.

   <!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>Document</title>

  <style>
    canvas { border: 2px solid black;}
  </style>
</head>
<body>
  <canvas id="canvas" width="1000" height="400"></canvas>
</body>

<script>
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var arrayN = [
[0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0],
[0,0,0,2,0,0,0,0],
[0,0,0,2,0,0,0,0],
[0,0,0,2,0,0,0,0],
[0,0,0,2,0,0,0,0],
[0,0,0,2,0,0,0,0],
[0,0,0,2,0,0,0,0]
];


var grey = new Image(32,32);
var forrest = new Image(32,32);

grey.src = '1.PNG';
forrest.src = '2.PNG';

var posX = 0;
var posY = 0;

for (let i = 0; i < arrayN.length; i++){
for (let j = 0; j < arrayN[i].length; j++){
  if (arrayN[i][j] === 0){
    ctx.drawImage(grey, posX, posY, 32,32);
  }
  if (arrayN[i][j] !== 0){
    ctx.drawImage(forrest, posX, posY, 32,32);
  }
  posX +=32;
}
posX = 0;
posY +=32;
}

</script>
</html>

https://jsfiddle.net/orangegoat/swLabv43/

1 Ответ

0 голосов
/ 27 апреля 2018

У меня такое чувство, что главная причина - асинхронная природа JavaScript. То есть мы склонны думать, что каждая строка идет после предыдущей, это только половина истории. Каждая строка будет начинаться по порядку, но не будет ждать окончания предыдущей строки. Поэтому я считаю, что ваши циклы for пытаются нарисовать изображения до того, как они закончили загрузку. Я попытался поместить их в setTimeout() функцию, и она работает.

window.setTimeout(function() {
    // your for-loops here
}, 1000);    // 1000 ms = 1 second of delay

Конечно, это предполагает, что изображения загружаются в течение 1 секунды, что не всегда будет иметь место. Поэтому вместо этого я рекомендую использовать window.onload

window.onload = function() {
    for (let i = 0; i < arrayN.length; i++) {
        for (let j = 0; j < arrayN[i].length; j++) {
            if (arrayN[i][j] === 0) {
                ctx.drawImage(grey, posX, posY, 32, 32);
            }
            if (arrayN[i][j] !== 0) {
                ctx.drawImage(forrest, posX, posY, 32, 32);
            }
            posX += 32;
        }
        posX = 0;
        posY += 32;
    }
};

Этого должно быть достаточно, чтобы это исправить. Но лично я бы сделал

window.onload = () => {
    for (let i = 0; i < arrayN.length; i++) {
        for (let j = 0; j < arrayN[i].length; j++) {
            ctx.drawImage(arrayN[i][j] === 0 ? grey : forrest, 32 * j, 32 * i, 32, 32);
        }
    }
};

Это намного лаконичнее. Несколько объяснений:

  • window.onload = () => { совпадает с window.onload = function() {. Он просто использует новый синтаксис ES6, о котором, как я полагаю, у вас есть хоть какие-то знания, так как вы используете ключевое слово let. И на этом примечании вы можете рассмотреть возможность замены all ваших var ключевых слов на let или const.
  • Излишне использовать posX и posY, потому что они увеличиваются только на 32 каждый раз, а i и j автоматически увеличиваются циклом for, так что вы можете также просто используйте i * 32 и j * 32. Затем вы можете полностью удалить переменные posX и posY.
  • Я бы не советовал использовать два оператора if, которые проверяют противоположные условия. Лучше использовать оператор if-else. Еще лучше использовать троичный оператор (? :), когда различия в том, что вы хотите изменить, невелики. В этом случае вы изменяете только первый параметр в drawImage, поэтому я подумал, что это подходящая ситуация.

Надеюсь, что все помогло!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...