Как добавить простой обработчик событий 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>


844   7  

7 ответов:

когда вы рисуете на canvas элемент, вы просто чертеж растровое изображение, в мгновенном режиме.

The элементов (фигуры, линии, изображения), которые рисуются, не имеют представления, кроме пикселей, которые они используют, и их цвета.

, чтобы получить клик событие canvasэлемент (форма), вам нужно захватить события щелчка на canvas HTML-элемент и использовать математику, чтобы определить, какие элемент был нажат, если вы сохраняете ширину/высоту элементов и смещение 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);
});​

jsFiddle.

этот код придает 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 nothing

JavaScript чувствителен к регистру. Элемент onclick свойство-это архаичный метод присоединения обработчиков событий. Он позволяет прикрепить только одно событие со свойством, и событие может быть потеряно при сериализации HTML.

elem.onClick = function() { alert("hello world!"); }; // does nothing

опять ' === ".

Я рекомендую следующую статью:хит обнаружения региона для HTML5 холст и как слушать нажмите события на холсте формы, который проходит через различные ситуации.

однако, это не покрывает addHitRegion API, который должен быть лучшим способом (использование математических функций и/или сравнений довольно подвержено ошибкам). Этот подход подробно на застройщика.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

    Ничего не найдено.