Есть ли способ легко определить, что фигура, нарисованная на холсте, нажата? - PullRequest
2 голосов
/ 10 марта 2011

Я учусь использовать HTML5 canvas прямо сейчас. У меня есть простой скрипт, который рисует круги вдоль горизонтальной линии.

Я бы хотел сделать свой сценарий более интерактивным. Я хочу иметь возможность щелкнуть один из кружков вдоль линии, и это приведет к тому, что данные, связанные с этим кружком, будут отображаться в виде текста на холсте.

Это легко достижимо на холсте? Из уроков, на которые я смотрел, я понял, что мне нужно нанести клик на сам холст. Оттуда я догадывался, что мне нужно будет решить, где был нажат мой курсор мыши, и каким-то образом определить, какой круг содержит мою точку щелчка.

Есть какие-нибудь фрагменты кода или указатели, которые могут помочь мне в этом? Или же холст действительно не подходит для такого рода проблем? Любые комментарии очень ценятся.

Ответы [ 4 ]

3 голосов
/ 10 марта 2011

Вы можете добавить обработку событий мыши, используя метод isPointInPath canvas.Примерно так ниже (не проверено).

// add click event handler to canvas
// on click
var rect = canvas.getBoundingClientRect();
var mouseX = e.clientX - rect.left;
var mouseY = e.clientY - rect.top;

ctx.beginPath()
// draw stuff
if (ctx.isPointInPath(mouseX, mouseY)) {
  // handle click
}

Это распознает любую фигуру, что очень полезно, если вы рисуете что-то кроме прямоугольников и окружностей.Тем не менее, основным недостатком этого является то, что вы должны перерисовывать каждый щелчок (или перемещение мыши, если вы добавляете указатели мыши).По своему опыту я могу сойти с рисования по крайней мере 300 объектов, прежде чем я начну видеть проблемы с производительностью.

Я должен также отметить, что есть ошибка в реализации Firefoxes isPointInPath, которая остается незафиксированнойнекоторая причина.Но, к счастью, это достаточно просто

CanvasRenderingContext2D.prototype.isPointInPath_mozilla = function( x, y )
{
  if (navigator.userAgent.indexOf('Firefox') != -1){
    this.save();
    this.setTransform( 1, 0, 0, 1, 0, 0 );
    var ret = this.isPointInPath( x, y );
    this.restore();
  } else
    var ret = this.isPointInPath( x, y );

  return ret;
}

, просто замените ctx.isPointInPath (x, y) на ctx.isPointInPath_mozilla (x, y) и все работает

2 голосов
/ 10 марта 2011

Canvas использует растровую графику. После того как вы нарисовали круг, он больше не идентифицируется как круг - у вас просто есть куча пикселей. Вы должны отслеживать все формы самостоятельно.

Если вы используете векторную графику, например SVG, фигуры сохраняют идентичность и ими можно манипулировать. Наверное, так будет проще.

0 голосов
/ 08 марта 2012

Я сделал что-то подобное для рисования на холсте мобильного устройства, а затем сопоставил форму.

Моя процедура была.

Объявление двумерного массива на основе количества высоты и ширины холста в пикселях.

Заполните массив 0

Для события mousemove (Desktop browser) отследите положение. Вы получите значение X, Y. в вашем 2D-массиве поместите 1 в строку и столбец (значения X и Y).

После рисования вы получите двумерный массив бинарных изображений.

Теперь самое интересное:

Попробуйте Image Momentam или любой другой подходящий метод по этой ссылке. http://www.imageprocessingplace.com/downloads_V3/root_downloads/tutorials/Tutorial--Algorithms%20for%202-D%20Object%20Recognition.pdf

Если вы сохраните некоторый массив 2D нарисованных фигур и сопоставите его с текущим нарисованным изображением, вы сможете найти ближайшее совпадение. Попробуйте найти подходящий порог, если пользователь нарисовал совершенно другую форму.

Надеюсь, это поможет.

0 голосов
/ 10 марта 2011

Вы создаете событие щелчка для холста, и в обработчике вы должны вычислить (некоторую базовую математику), если пользователь нажмет на круг. Другой способ - не использовать canvas, а SVG. Существуют библиотеки типа Raphael , которые могут быть полезны.

...