JavaScript. Подробное руководство, 6-е издание, стр. 370

Методы манипулирования пикселами могут пригодиться для реализации обработки изображений. Пример 21.10 демонстрирует, как создать простейший эффект размытия или «смазывания» быстро движущегося объекта в элементе

<b>&lt;canvas&gt;~</b>
Пример демонстрирует применение методов
<b>getlmageData()</b>
и
<b>putlmageData()</b>
и показывает, как выполнять итерации по пикселам в объекте
<b>ImageData</b>
и изменять их значения, но без подробного описания. Полная информация о методах
<b>getlmageData()</b>
и
<b>putlmageData()</b>
приводится в справочной статье
<b>CanvasRenderingContext2D</b>
, а подробное описание объекта
<b>ImageData</b>
- в его собственной справочной статье.

Пример 21.10. Создание эффекта размытия быстродвижущегося объекта с помощью объекта

<b>ImageData</b>

<b>// &quot;Смазать&quot; пикселы прямоугольной области вправо, чтобы воспроизвести эффект быстрого </b>

<b>// движения объекта справа налево. Значение п должно быть равно или больше 2. Нем больше </b>

<b>// значение, тем сильнее эффект смазывания. Координаты и размеры прямоугольной области </b>

<b>// задаются в системе координат по умолчанию, </b>

<b>function smear(c, п, х, у, w, h) {</b>

<b>  // Получить объект ImageData, представляющий пикселы области эффекта</b>

<b>  var pixels = c.getImageData(x,у,w,h);</b>

<b>  // Смазывание выполняется на месте, и потому требуется получить только</b>

<b>  // исходный объект ImageData. Некоторые алгоритмы обработки изображений требуют</b>

<b>  // использования дополнительного объекта ImageData для сохранения трансформированных</b>

<b>  // значений пикселов. Если бы потребовался промежуточный буфер вывода, можно было бы</b>

<b>  // создать новый объект ImageData с теми же размерами следующим способом:</b>

<b>  // var output_pixels = с.createlmageData(pixels):</b>

<b>  // Эти размеры могут отличаться от значений аргументов w и h: на каждый</b>

<b>  // CSS-пиксел может приходиться несколько аппаратных пикселов,</b>

<b>  var width = pixels.width,</b>

<b>      height = pixels.height:</b>

<b>  // Это массив байтов, хранящий информацию о пикселах, слева направо и сверху вниз.</b>

<b>  // Для каждого пиксела отводится 4 последовательных байта, в порядке R,G,В,А.</b>

<b>  var data = pixels.data;</b>

<b>  // Смазать каждый пиксел после первого в каждой строке, заменив его суммой</b>

<b>  // 1/n-й доли его собственного значения и m/n-й доли значения предыдущего пиксела</b>

<b>  var m = n-1;</b>

<b>  for(var row = 0; row &lt; height: row++) { // Для каждой строки</b>

<b>    var і = row*width*4 +4; // Индекс второго пиксела в строке</b>

<b>    for(var col = 1; col &lt; width; col++, і += 4) { // Для каждого столбца</b>

<b>      data[i] = (data[і] + data[i-4]*m)/n; // Красная составляющая</b>

<b>      data[i+1] = (data[i+1] + data[i-3]*m)/n; // Зеленая</b>

<b>      data[i+2] = (data[i+2] + data[i-2]*m)/n; // Синяя</b>

<b>      data[i+3] = (data[i+3] + data[i-1]*m)/n; // Альфа-составляющая</b>

<b>    }</b>

<b>  }</b>

<b>  // Скопировать смазанное изображение обратно в ту же позицию в холсте</b>

<b>  с.putImageData(pixels, х, у);</b>

<b>}</b>

Обратите внимание, что на метод getImageData() накладываются те же ограничения политики общего происхождения, что и на метод toDataURL(): он не будет работать с холстами, в которые вставлялись изображения (непосредственно, вызовом метода drawImage(), или косвенно, с помощью метода CanvasPattern), имеющие происхождение, отличное от происхождения документа, содержащего элемент <canvas>.

21.4.15. Определение попадания

Метод

<b>isPointInPath()</b>
позволяет узнать, находится ли указанная точка внутри (или на границе) текущего контура, и возвращает true, если это так, и false-в противном случае. Метод принимает координаты точки в не преобразованной системе координат по умолчанию. Это позволяет использовать метод для определения попадания: определения принадлежности точки, где был выполнен щелчок мышью, некоторой определенной фигуре.

Однако значения свойств

<b>clientX</b>
и
<b>clientY</b>
объекта
<b>MouseEvent</b>
нельзя передать непосредственно методу
<b>isPointlnPath().</b>
Во-первых, координаты события мыши следует преобразовать из координат объекта
<b>Window</b>
в относительные координаты элемента
<b>&lt;canvas&gt;.</b>
Во-вторых, если экранные размеры холста отличаются от его фактических размеров, координаты мыши необходимо перевести в соответствующий масштаб. В примере 21.11 показана вспомогательная функция, используемая для определения попадания точки события MouseEvent в текущий контур.

Пример 21.11. Проверка попадания точки события мыши в текущий контур

<b>// Возвращает true, если указанное событие мыши возникло в текущем контуре</b>

<b>// в указанном объекте CanvasRenderingContext2D.</b>