Как добавить простой обработчик событий onClick в элемент canvas?
Я опытный программист Java, но я смотрю на некоторые вещи JavaScript/HTML5 впервые примерно за десятилетие. Я полностью озадачен тем, что должно быть самой простой вещью.
в качестве примера я просто хотел что-то нарисовать и добавить обработчик событий к нему. Я уверен, что делаю что-то глупое, но я искал повсюду, и ничего не предлагалось (например, ответ на этот вопрос: добавить свойство onclick для ввода с помощью JavaScript) работает. Я использую Firefox 10.0.1. Мой код следующий. Вы увидите несколько комментируемых строк, и в конце каждой из них есть описание того, что (или что не происходит) происходит.
каков правильный синтаксис здесь? Я схожу с ума!
<html>
<body>
<canvas id="myCanvas" width="300" height="150"/>
<script language="JavaScript">
var elem = document.getElementById('myCanvas');
// elem.onClick = alert("hello world"); - displays alert without clicking
// elem.onClick = alert('hello world'); - displays alert without clicking
// elem.onClick = "alert('hello world!')"; - does nothing, even with clicking
// elem.onClick = function() { alert('hello world!'); }; - does nothing
// elem.onClick = function() { alert("hello world!"); }; - does nothing
var context = elem.getContext('2d');
context.fillStyle = '#05EFFF';
context.fillRect(0, 0, 150, 100);
</script>
</body>
7 ответов:
когда вы рисуете на
canvasэлемент, вы просто чертеж растровое изображение, в мгновенном режиме.The элементов (фигуры, линии, изображения), которые рисуются, не имеют представления, кроме пикселей, которые они используют, и их цвета.
, чтобы получить клик событиеcanvasэлемент (форма), вам нужно захватить события щелчка наcanvasHTML-элемент и использовать математику, чтобы определить, какие элемент был нажат, если вы сохраняете ширину/высоту элементов и смещение x/y.добавить
clickсобытияcanvasэлемент, использовать...canvas.addEventListener('click', function() { }, false);чтобы определить, какие элемент была нажата...
var elem = document.getElementById('myCanvas'), elemLeft = elem.offsetLeft, elemTop = elem.offsetTop, context = elem.getContext('2d'), elements = []; // Add event listener for `click` events. elem.addEventListener('click', function(event) { var x = event.pageX - elemLeft, y = event.pageY - elemTop; // Collision detection between clicked offset and element. elements.forEach(function(element) { if (y > element.top && y < element.top + element.height && x > element.left && x < element.left + element.width) { alert('clicked an element'); } }); }, false); // Add element. elements.push({ colour: '#05EFFF', width: 150, height: 100, top: 20, left: 15 }); // Render elements. elements.forEach(function(element) { context.fillStyle = element.colour; context.fillRect(element.left, element.top, element.width, element.height); });этот код придает
clickсобытиеcanvasэлемент, а затем толкает одну форму (так называемыйelementв моем коде) кelementsмассив. Вы можете добавить столько, сколько вы хотите здесь.цель создания массива объектов заключается в том, чтобы мы могли запросить их свойства позже. После того, как все элементы были помещены в массив, мы выполняем цикл и визуализируем каждый из них на основе их свойств.
когда
clickсобытие запускается, код проходит через элементы и определяет, был ли щелчок по любому из элементов вelementsмассив. Если это так, он запускаетalert(), который может быть легко изменен, чтобы сделать что-то такое как удалить элемент массива, в этом случае вам понадобится отдельная оказать функция для обновленияcanvas.для полноты картины, почему ваши попытки не сработали...
elem.onClick = alert("hello world"); // displays alert without clickingэто присвоение возвращаемого значения
alert()доonClickсобственностьelem. Он сразу же вызываетalert().elem.onClick = alert('hello world'); // displays alert without clickingв JavaScript
'и"семантически идентичны, лексер, вероятно, использует['"]для двойные кавычки.elem.onClick = "alert('hello world!')"; // does nothing, even with clickingвы присваиваете строку
onClickсобственностьelem.elem.onClick = function() { alert('hello world!'); }; // does nothingJavaScript чувствителен к регистру. Элемент
onclickсвойство-это архаичный метод присоединения обработчиков событий. Он позволяет прикрепить только одно событие со свойством, и событие может быть потеряно при сериализации HTML.elem.onClick = function() { alert("hello world!"); }; // does nothingопять
' === ".
Я рекомендую следующую статью:хит обнаружения региона для HTML5 холст и как слушать нажмите события на холсте формы, который проходит через различные ситуации.
однако, это не покрывает
addHitRegionAPI, который должен быть лучшим способом (использование математических функций и/или сравнений довольно подвержено ошибкам). Этот подход подробно на застройщика.mozilla
в качестве альтернативы ответу Алекса:
вы можете использовать рисунок SVG вместо рисунка холста. Там вы можете добавлять события непосредственно к нарисованным объектам DOM.
например:
сделать объект изображения svg кликабельным с помощью onclick, избегая абсолютного позиционирования
вы также можете поместить элементы DOM, например
divповерх холста, который будет представлять ваши элементы холста и располагаться таким же образом.теперь вы можете присоединить прослушиватели событий к этим divs и выполнить необходимые действия.
как еще одна дешевая альтернатива на несколько статическом холсте, использование наложенного элемента img с определением usemap является быстрым и грязным. Особенно хорошо работает на полигональных элементах холста, таких как круговая диаграмма.
вероятно, очень поздно к ответу, но я просто прочитал это, готовясь к моему
70-480экзамен, и обнаружил, что это работает -var elem = document.getElementById('myCanvas'); elem.onclick = function() { alert("hello world"); }обратите внимание на событие как
onclickвместоonClick.JS Bin пример.
Алекс Ответ довольно аккуратно, но при использовании контекстного поворота может быть трудно проследить координаты x, y, поэтому я сделал демо показывает, как отслеживать это.
в основном я использую эту функцию и даю ей угол и количество пройденного расстояния в этом ангеле перед рисованием объекта.
function rotCor(angle, length){ var cos = Math.cos(angle); var sin = Math.sin(angle); var newx = length*cos; var newy = length*sin; return { x : newx, y : newy }; }
Comments