#javascript #html #canvas
#javascript #HTML #холст
Вопрос:
У меня есть игра, над которой я работаю, в которой будет несколько холстов. Один для карты, другой для пользовательского интерфейса, другой для игровых объектов и т.д. Холст пользовательского интерфейса будет самым верхним холстом, но мне интересно, если бы я хотел зарегистрировать событие щелчка, скажем, на слое карты, как бы я это сделал, если холст пользовательского интерфейса находится поверх любого другого холста? В нынешнем виде, когда я нажимаю, он регистрирует только щелчок на холсте пользовательского интерфейса, что и должно быть, поскольку он находится поверх других. Как мне зарегистрировать щелчок на одном из других холстов вместо этого?
CSS
canvas{
position: absolute;
}
#ui{
bottom: 0;
z-index: 5;
}
#basemap{
z-index: 0;
}
HTML
<canvas id="ui"></canvas>
<canvas id="basemap"></canvas>
JS
var canvases = document.getElementsByTagName("canvas");
for(var i = 0; i < canvases.length; i ){
canvases[i].onclick = function(){
console.log(this);
}
}
Ответ №1:
Установите pointer-events
значение для none
#ui
элемента. Это приведет к тому, что события, связанные с указателем, будут игнорироваться #ui
и передаваться базовому элементу:
#ui{
bottom: 0;
z-index: 5;
pointer-events: none;
}
Комментарии:
1. Возможно ли сделать это динамически? Например, если они не нажали на элемент пользовательского интерфейса и перемещают символ, но им все равно нужна возможность щелкнуть по слою пользовательского интерфейса в какой-то момент? Будет ли это лучше подходит как другой вопрос?
2. @Robert Вероятно, это было бы лучше подходит как другой вопрос. Однако учтите, что (
pointer-events
в стороне) верхний слой всегда поглощает события мыши. Имеет ли значение, с какого слоя происходят эти события? Обрабатывайте события для потенциального взаимодействия с пользовательским интерфейсом. Для тех событий, которые этого не делают, попросите логику пользовательского интерфейса передать их логике, которая обрабатывает потенциал для взаимодействия с базовой картой.3. подойдет. Спасибо за помощь
Ответ №2:
Установите pointer-events
для атрибута CSS none
значение on #ui
element, это отключит щелчок по нему.
#ui {
bottom: 0;
z-index: 5;
pointer-events: none;
}
значение none указывает событию мыши пройти «через» элемент и вместо этого нацелиться на то, что находится «под» этим элементом.
Ответ №3:
Холст не предоставляет пользовательский интерфейс, поэтому вам не нужно регистрировать оба события холста. Вам нужно будет сверить события щелчка, наведения курсора мыши, наведения курсора мыши с координатами пользовательского интерфейса и текущим состоянием мыши (перетаскивание). Если мышь наведена на графическое изображение пользовательского интерфейса, вы обрабатываете требования пользовательского интерфейса, если нет, вы обрабатываете потребности игровой карты. Поскольку координаты мыши будут одинаковыми для обоих холстов, нет смысла добавлять дополнительный избыточный прослушиватель событий, это только сделает код чрезмерно сложным.
Кроме того, вы не должны реагировать на события мыши в обработчиках событий. Обработчики событий мыши могут срабатывать гораздо чаще, чем будет обновляться холст. Вы должны использовать обработчики событий, чтобы просто записывать текущее состояние мыши (местоположение, кнопки вниз), а в основном игровом цикле вы обрабатываете взаимодействие с мышью. Это уменьшит объем кода, который необходимо выполнить для каждого события мыши, и значительно упростит код.
Обработчики событий мыши предназначены для упрощения взаимодействия с отдельными компонентами пользовательского интерфейса, canvas нарушает парадигму, поскольку не может определять компоненты пользовательского интерфейса / карты как отдельные регистрируемые элементы с событиями. Обработка холста так, как будто это DOM, будет недостатком для общего качества кода и производительности игры.