> [Site index](https://perfectvector.com/llms.txt) — available pages and descriptions.

# Как исключить прозрачные области SVG из кликов Konva

> Исключите прозрачные области SVG из кликов Konva. Повторите проверку попаданий через кеш, испытайте отверстия и фон и обновите карту после замены источника.

Source: https://perfectvector.com/ru/blog/konva-alpha-hit-region

Language: ru
Author: Irene Kim
Published: 2026-10-11T08:00:00+09:00
Updated: 2026-10-11T08:00:00+09:00

Чтобы прозрачные области `Konva.Image` игнорировали клики, дождитесь декодирования исходного изображения, вызовите `imageNode.cache()`, затем `imageNode.drawHitFromCache(0)` и перерисуйте слой. После этого альфа-канал кешированной сцены, то есть непрозрачность пикселей, определяет, какие пиксели участвуют в проверке попаданий.

Обычный узел изображения может получать события по всему прямоугольнику, включая пустое отверстие SVG. [Учебник Konva Image Events](https://konvajs.org/docs/events/Image_Events.html) показывает альтернативу по альфа-каналу. Здесь мы проверяем собственный SVG с отверстием над отдельно кликабельным фоном: у отверстия, переставшего перехватывать клики изображения, есть настоящий нижний объект, который их получит.

Это меняет область взаимодействия на canvas. Способ не создаёт из SVG редактируемые узлы `Konva.Path` и не меняет правила DOM SVG `pointer-events`.

## Отделите изображение от области попаданий

**Область попаданий** — область, по которой Konva выбирает цель события. Её форма может отличаться от видимого рисунка. В одних приложениях широкая прямоугольная цель намеренна, в других прозрачные отверстия должны позволять выбрать нижний объект.

| Нужное взаимодействие                                                           | Отправная точка                                                                                                  |
| ------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
| Выбирать целое изображение из любой точки прямоугольника                        | Стандартная обработка попаданий Image                                                                            |
| Пропускать прозрачные пиксели к нижнему узлу                                    | Кешировать изображение и строить область попаданий по альфа-каналу                                               |
| Редактировать отдельные векторные области или назначать им независимые действия | [Выбрать отдельные контуры Konva](https://perfectvector.com/ru/blog/konva-svg-import) и определить поведение     |
| Управлять целями указателя внутри встроенного DOM SVG                           | Использовать отдельное [руководство по SVG pointer-events](https://perfectvector.com/ru/blog/svg-pointer-events) |

Актуальный [Shape API](https://konvajs.org/api/Konva.Shape.html#drawHitFromCache) принимает целое `alphaThreshold` от 0 до 255, по умолчанию 0. Передавайте число, а не функцию обратного вызова. Это отличается от визуального фильтра Threshold. В примере используется 0 с полностью непрозрачной внутренней областью и полностью прозрачными отверстиями; он не определяет лучший порог для мягких теней или сглаженных краёв.

## 1. Сохраните два полных исходника SVG

Создайте пустую папку. Сохраните эту собственную эмблему с отверстием как `hollow.svg`:

```xml
<svg xmlns="http://www.w3.org/2000/svg" width="240" height="180" viewBox="0 0 240 180">
  <path fill="#315d6f" fill-rule="evenodd"
        d="M20 30 L180 20 L215 60 L195 150 L35 160 L10 110 Z
           M80 65 L145 55 L160 110 L95 125 Z"/>
</svg>
```

Внутренний подконтур создаёт отверстие по правилу заливки even-odd. Сохраните ту же внешнюю фигуру без внутреннего подконтура как `filled.svg`:

```xml
<svg xmlns="http://www.w3.org/2000/svg" width="240" height="180" viewBox="0 0 240 180">
  <path fill="#315d6f" d="M20 30 L180 20 L215 60 L195 150 L35 160 L10 110 Z"/>
</svg>
```

Второй файл — контроль замены источника. Он закрашивает ранее пустую точку. Ни один файл не содержит белого фонового прямоугольника или встроенного растра.

## 2. Загрузите, кешируйте и записывайте настоящие цели

Пример использует Konva 10.9.0. Сохраните эти три файла рядом с обоими SVG. HTML загружает закреплённую браузерную сборку; в контролируемом проекте ту же сборку можно раздавать локально.

Сохраните `reader.html`:

```html
<!doctype html>
<html lang="en">
<meta charset="utf-8">
<title>Konva transparent image hit comparison</title>
<link rel="stylesheet" href="reader.css">
<main>
<h1>Transparent artwork: which node gets the click?</h1>
<p class="banner"><strong id="version">Loading Konva…</strong>. Original same-origin SVGs, actual Konva.Image nodes, and a separately clickable background. These are canvas hit pixels, not editable SVG path nodes. Desktop click test only; no mobile or accessibility audit.</p>
<div class="grid">
<section class="panel"><h2>1. Default rectangular hit</h2><div class="stage" id="default"></div><p>The hollow image still catches its transparent center and corner.</p><pre class="log" id="default-log"></pre></section>
<section class="panel"><h2>2. Cached alpha hit region</h2><div class="stage" id="alpha"></div><p>cache() then drawHitFromCache(0): the center and corner reach the background.</p><pre class="log" id="alpha-log"></pre></section>
<section class="panel"><h2>3. Opaque image fill</h2><div class="stage" id="fill"></div><p>A white fill behind this image is part of its cached scene. Its formerly empty pixels receive image hits.</p><pre class="log" id="fill-log"></pre></section>
<section class="panel"><h2>4. Replaced source, rebuilt cache</h2><div class="stage" id="updated"></div><p>The original hole is painted in filled.svg. Clear, replace, cache, and rebuild the hit region.</p><pre class="log" id="updated-log"></pre></section>
</div>
<p>Click these stage coordinates in each panel: solid (125,110), hole (195,130), transparent corner (305,55), and outside the image (20,20). The corner is inside the image viewport but outside its painted shape. Logs report actual click targets.</p>

</main>
<script src="https://unpkg.com/konva@10.9.0/konva.min.js"></script>
<script type="module" src="reader.js"></script>
</html>
```

Сохраните `reader.css`:

```css
body { margin: 32px; font: 16px/1.55 Arial, sans-serif; color: #183a42; background: #edf2ef; }
main { max-width: 1080px; margin: auto; }
h1 { font-size: 32px; margin-bottom: 12px; }
h2 { margin: 0 0 12px; font-size: 22px; }
p { margin: 10px 0; }
.banner { background: #dce8e4; padding: 18px; border-left: 5px solid #315d6f; }
.grid { display: grid; grid-template-columns: repeat(2, minmax(460px, 1fr)); gap: 20px; margin: 24px 0; }
.panel { background: white; padding: 20px; border: 1px solid #d1dbd5; border-radius: 12px; }
.stage { width: 420px; height: 260px; }
pre { white-space: pre-wrap; overflow-wrap: anywhere; background: #f8faf7; padding: 12px; }
table { border-collapse: collapse; width: 100%; margin-top: 20px; }
th, td { border-bottom: 1px solid #c9d5ce; padding: 10px; text-align: left; }
.log { min-height: 88px; margin-bottom: 0; font-size: 13px; }
```

Сохраните `reader.js`:

```javascript
const source = new Image();
source.src = './hollow.svg';
await source.decode();
const replacement = new Image();
replacement.src = './filled.svg';
await replacement.decode();

const clicks = [];
const scenes = [];
function makeScene(id, mode) {
  const stage = new Konva.Stage({ container: id, width: 420, height: 260 });
  const layer = new Konva.Layer();
  stage.add(layer);
  const background = new Konva.Rect({
    id: `${id}-background`, width: 420, height: 260, fill: '#eadfcd'
  });
  const artwork = new Konva.Image({
    id: `${id}-image`, image: source, x: 80, y: 40, width: 240, height: 180
  });
  if (mode === 'fill') artwork.fill('#ffffff');
  layer.add(background, artwork);
  if (mode !== 'default') {
    artwork.cache();
    artwork.drawHitFromCache(0);
  }
  layer.draw();
  const beforeUpdate = stage.getIntersection({ x: 195, y: 130 }).id();
  if (mode === 'update') {
    artwork.clearCache();
    artwork.image(replacement);
    artwork.cache();
    artwork.drawHitFromCache(0);
    layer.draw();
  }
  stage.on('click', (event) => {
    const point = stage.getPointerPosition();
    const record = {
      scene: id, x: point.x, y: point.y,
      target: event.target.id(), trusted: event.evt.isTrusted
    };
    clicks.push(record);
    document.getElementById(`${id}-log`).textContent +=
      `(${Math.round(point.x)}, ${Math.round(point.y)}) → ${record.target}\n`;
    document.dispatchEvent(new CustomEvent('fixture-click-recorded'));
  });
  const scene = { id, stage, artwork, beforeUpdate };
  scenes.push(scene);
  return scene;
}
makeScene('default', 'default');
makeScene('alpha', 'alpha');
makeScene('fill', 'fill');
makeScene('updated', 'update');
document.getElementById('version').textContent = `Konva ${Konva.version}`;
```

Раздавайте папку через HTTP вместо открытия HTML как локального файла:

```bash
python -m http.server 8000
```

Откройте `http://localhost:8000/reader.html` и дождитесь четырёх сцен. SVG 240 × 180 размещён в координатах (80,40) каждой сцены 420 × 260. Каждый фон — отдельный принимающий события `Konva.Rect` под изображением. Обработчик клика сцены сообщает `event.target.id()`: это выбранный узел Konva, а не просто DOM-элемент canvas.

`await source.decode()` выполняется до создания кеша. Кешируйте после готовности настоящего источника, а не во время загрузки изображения. [Node API Konva](https://konvajs.org/api/Konva.Node.html#cache) описывает создание и очистку кеша.

## 3. Нажмите на сплошную область, отверстие, угол и фон

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

| Место              | Координата сцены | Что проверяется                                                |
| ------------------ | ---------------- | -------------------------------------------------------------- |
| Сплошной рисунок   | 125,110          | Непрозрачная точка глубоко внутри эмблемы                      |
| Исходное отверстие | 195,130          | Прозрачная внутренняя область hollow\.svg                      |
| Прозрачный угол    | 305,55           | Внутри прямоугольника изображения, но вне закрашенного силуэта |
| Вне изображения    | 20,20            | Отдельно кликабельный фон                                      |

Следующая таблица фиксирует проверенный тип цели. Журналы включают префикс панели, например `alpha-background`.

| Конфигурация                                           | Сплошная область | Исходное отверстие | Прозрачный угол | Вне изображения |
| ------------------------------------------------------ | ---------------- | ------------------ | --------------- | --------------- |
| Стандартное изображение                                | Изображение      | Изображение        | Изображение     | Фон             |
| Кешированная область по альфа-каналу                   | Изображение      | Фон                | Фон             | Фон             |
| Кешированное изображение с непрозрачной белой заливкой | Изображение      | Изображение        | Изображение     | Фон             |
| Заменённый источник и перестроенный кеш                | Изображение      | Изображение        | Фон             | Фон             |

![Реальное сравнение Konva в браузере: прямоугольные попадания по умолчанию, попадания по альфа-кешу, непрозрачная заливка и замена источника с записанными ID целей](https://perfectvector.com/blog/konva-alpha-hit-region/alpha-hit.webp)

*Реальные сцены Konva 10.9.0 с собственными SVG и записанными целями настольных кликов. Изображение с отверстием по альфа-каналу пропускает клики отверстия и угла к отдельному фону. Непрозрачная заливка и закрашенный новый источник меняют результат.*

Браузерный тест использовал настоящие клики указателя во всех 16 точках и записывал нативный признак доверенного события, координаты сцены и ID целей. Также проверялись хеши исходных файлов, декодирование, размеры сцены и изображения, публичные результаты пересечений и нативные альфа-образцы из отрисованного canvas каждого узла изображения.

В исходном отверстии альфа узла с отверстием была 0. У контроля с непрозрачной заливкой и заменённым источником там было 255. Отдельный фон страницы не делал само изображение непрозрачным: он принадлежал другому узлу Konva ниже. Точки находятся внутри областей, вдали от сглаженных границ.

Это один тест настольного браузера с простыми собственными SVG и сценами без преобразований. Он не подтверждает мобильное и сенсорное поведение, клавиатурное взаимодействие, матрицу браузеров, прирост производительности или порог для любых мягких краёв. Повторите клики с настоящими размерами отображения и преобразованиями приложения.

## 4. Перестройте кеш при изменении источника

Четвёртая панель начинается с источника с отверстием и его области по альфа-каналу. Затем очищает кеш, устанавливает уже декодированную замену, снова кеширует и перестраивает область попаданий. После этой последовательности цель в исходном отверстии меняется с фона на изображение.

Кеш — снимок отрисованного состояния. После изменения отрисованных пикселей обновляйте вместе кеш сцены и область попаданий по альфа-каналу. Не считайте, что назначение другого изображения обновило существующую кешированную область. Для асинхронной замены дождитесь её декодирования до выполнения показанной последовательности.

Третья панель выделяет другую причину: `artwork.fill('#ffffff')` рисует непрозрачный прямоугольник позади изображения как часть того же узла. Область попаданий, созданная из кеша сцены, включает эту краску. Удалите ненужную заливку узла, затем перестройте кеш и область. Белая на вид область исходного файла тоже может быть настоящей непрозрачной краской: проверьте прозрачность до обвинения проверки попаданий.

## Раздельно проверяйте ошибки чтения пикселей и выбора целей

| Симптом                                         | Что проверить сначала                                                                                              |
| ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
| Отверстие всё ещё записывает изображение        | Кеш создан после декодирования, область перестроена, непрозрачная заливка или фон источника не закрывают отверстие |
| Рисунок изменился, а клики следуют старой форме | Очистить и перестроить кеш сцены и область по альфа-каналу после изменения источника                               |
| Ошибка чтения пикселей или загрязнённого canvas | Источник изображения и заголовки ответа до интерпретации результатов попадания                                     |
| Всё изображение перестало получать события      | `listening`, видимость, порядок слоёв и наличие верхнего узла                                                      |
| Отверстие ведёт к сцене, а не нижнему объекту   | Под точкой действительно есть нужный принимающий события объект                                                    |
| Клики canvas работают, клавиатура — нет         | Клавиатурное управление и семантика проектируются отдельно; альфа-пиксели попаданий их не предоставляют            |

Образец раздаёт оба SVG с того же источника, что и страницу. Для чтения пикселей изображений другого источника нужен незагрязнённый canvas. [Руководство Konva по загрязнённому canvas](https://konvajs.org/docs/posts/Tainted_Canvas.html) объясняет использование `crossOrigin` вместе с сервером, разрешающим запрос CORS. Одно `crossOrigin = 'anonymous'` не даёт доступа без разрешения сервера. В статье не запускался случай ошибки другого источника.

Изменение CSS `pointer-events` внешнего canvas не выбирает пиксели внутри `Konva.Image`, попадающие в его внутренние узлы. Отделяйте цели canvas от [целей указателя DOM SVG](https://perfectvector.com/ru/blog/svg-pointer-events). Сохраните также оригинал SVG: кешированная карта — пиксельные данные взаимодействия, а не замена векторного документа.

## Отделяйте восстановление рисунка от подключения событий

Если приложению нужны лишь размещение изображения и попадания по альфа-каналу, подходящего прозрачного растра может быть достаточно. Если остался только PNG или JPG и нужна также редактируемая геометрия, [процесс изображения в вектор PerfectVector](https://perfectvector.com/ru/image-to-vector) поможет восстановить кандидат SVG. Проверьте силуэт и отверстия, затем выберите представление Konva и реализуйте события. Здесь использованы собственные исходные SVG без преобразования PerfectVector.

Векторизация не устанавливает обработчики, не создаёт доступные элементы управления, не выбирает цели кликов и не синхронизирует кеши. Если оригинал SVG уже есть, исправляйте код взаимодействия напрямую. Если внутри файла неожиданно обнаруживается полное прямоугольное изображение, выполните [проверку встроенного растра SVG](https://perfectvector.com/ru/blog/svg-contains-raster-image), прежде чем считать содержимое отдельными редактируемыми контурами.

## Частые вопросы

**Почему прозрачные пиксели изображения Konva получают клики?**
Стандартный узел Image может использовать прямоугольник для попаданий. После готовности источника кешируйте его, примените drawHitFromCache с подходящим числовым порогом, перерисуйте и проверьте настоящие цели.

**Какой аргумент принимает drawHitFromCache?**
Текущий API принимает необязательный целочисленный порог альфа-канала от 0 до 255, по умолчанию 0. Проверенный пример передаёт 0. Он не передаёт функцию обратного вызова и не использует визуальный фильтр Threshold.

**Почему белая заливка снова делает отверстие SVG кликабельным?**
Непрозрачная заливка узла Image входит в кешированную сцену. Альфа кеша включает эту краску. Удалите ненужную заливку и перестройте кеш сцены и область попаданий.

**Делает ли область по альфа-каналу контуры SVG независимо редактируемыми?**
Нет. Рисунок остаётся одним узлом Image. Если нужны отдельные векторные области, используйте подходящие отдельные узлы Path и явную модель сцены.

## Источники

1. [Konva: Image Events](https://konvajs.org/docs/events/Image_Events.html) — Стандартные попадания изображения и создание области из кешированного рисунка.
2. [Konva: Shape API](https://konvajs.org/api/Konva.Shape.html#drawHitFromCache) — Текущий числовой alphaThreshold и его диапазон.
3. [Konva: Node API](https://konvajs.org/api/Konva.Node.html#cache) — Создание и очистка кеша, цели событий и публичные методы узлов.
4. [Konva: Руководство по загрязнённому canvas](https://konvajs.org/docs/posts/Tainted_Canvas.html) — Ограничения источников, CORS и ошибки чтения пикселей.
5. [Konva: SVG на canvas](https://konvajs.org/docs/sandbox/SVG_On_Canvas.html) — Отрисовка целого изображения и отдельно построенные векторные контуры.

Если редактируемой геометрии нет, [подготовьте кандидат SVG в PerfectVector](https://perfectvector.com/ru/image-to-vector), проверьте отверстия, затем отдельно испытайте нужные цели кликов Konva и обновления кеша.

## Explore

- [Read the HTML article](https://perfectvector.com/ru/blog/konva-alpha-hit-region)
- [Маркеры SVG в Matplotlib scatter: проверьте контур](https://perfectvector.com/ru/blog/matplotlib-svg-scatter-marker.md)
- [Как добавить водяной знак SVG в готовый PDF через Python](https://perfectvector.com/ru/blog/svg-watermark-existing-pdf.md)
- [Product facts](https://perfectvector.com/product-facts.md)
- [FAQ](https://perfectvector.com/faq.md)
- [Pricing and credits](https://perfectvector.com/pricing.md)
