PerfectVector
Yazan Irene Kim

Konva Tıklamalarında Şeffaf SVG Alanlarını Yok Sayın

Konva'da şeffaf SVG alanlarının tıklamaları geçirmesini sağlayın. Önbellek tabanlı isabeti, delikleri ve zeminleri test edip kaynak değişince alanı yeniden oluşturun.

11 dk okuma
Bu sayfada

Konva.Image şeffaf alanlarının tıklamaları yok sayması için kaynak görselin çözümlenmesini bekleyin, imageNode.cache() çağırın, ardından imageNode.drawHitFromCache(0) çağırıp katmanı yeniden çizin. Önbellekteki sahnenin alfa değeri, yani piksel opaklığı, hangi görsel piksellerinin isabet algılamasına katılacağını belirler.

Normal görsel düğümü, boş SVG deliği dahil tüm dikdörtgeninde olay alabilir. Konva'nın Image Events öğreticisi alfa temelli alternatifi gösterir. Bu makale, ayrı tıklanabilir zemin üzerinde delikli özgün SVG test eder; böylece görsel tıklamalarını yakalamayı bırakan deliğin altında bunları alabilecek gerçek hedef bulunur.

Bu, canvas etkileşim alanını değiştirir. SVG'den düzenlenebilir Konva.Path düğümleri oluşturmaz veya DOM SVG pointer-events kurallarını değiştirmez.

Görseli isabet alanından ayırın

İsabet alanı, Konva'nın olay hedefini seçmek için kullandığı alandır. Şekli görünür tasarımdan farklı olabilir. Bazı uygulamalarda geniş dikdörtgen hedef bilinçlidir; diğerlerinde şeffaf delikler kullanıcının alttaki nesneyi seçmesini sağlamalıdır.

Amaçlanan etkileşimBaşlangıç
Dikdörtgenindeki her yerden tüm görseli seçmekVarsayılan Image isabet davranışı
Şeffaf görsel piksellerinin alttaki düğüme ulaşmasını sağlamakGörseli önbelleğe alıp isabet alanını alfadan oluşturun
Tek tek vektör bölgelerini düzenlemek veya bağımsız eylem eklemekAyrı Konva yollarını seçin ve davranışlarını tanımlayın
Satır içi DOM SVG'de işaretçi hedeflerini kontrol etmekAyrı SVG pointer-events rehberini kullanın

Güncel Shape API, 0–255 arasında tam sayı alphaThreshold alır; varsayılanı 0'dır. Buraya geri çağırım değil sayı verin. Bu, görsel Threshold filtresinden ayrıdır. Örnek tam opak içler ve tam şeffaf deliklerle 0 kullanır; yumuşak gölgeler veya yumuşatılmış kenarlar için tercih edilen eşik belirlemez.

1. İki tam SVG girdisini kaydedin

Boş klasör oluşturun. Bu özgün delikli amblemi hollow.svg olarak kaydedin:

<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>

İç alt yol, even-odd dolgu kuralıyla delik oluşturur. Aynı dış şekli iç alt yol olmadan filled.svg olarak kaydedin:

<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>

İkinci dosya kaynak değişimi kontrolüdür. Önceden boş konumu boyar. İki dosya da beyaz arka plan dikdörtgeni veya gömülü bitmap içermez.

2. Yükleyin, önbelleğe alın ve gerçek hedefleri kaydedin

Örnek Konva 10.9.0 kullanır. Bu üç dosyayı iki SVG'nin yanına kaydedin. HTML sabitlenmiş tarayıcı derlemesini yükler; kontrollü projede aynı derlemeyi yerel sunabilirsiniz.

reader.html dosyasını kaydedin:

<!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 dosyasını kaydedin:

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 dosyasını kaydedin:

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}`;

HTML'yi yerel dosya olarak açmak yerine klasörü HTTP üzerinden sunun:

python -m http.server 8000

http://localhost:8000/reader.html adresini açıp dört sahnenin görünmesini bekleyin. 240 × 180 SVG, her 420 × 260 sahnede (80,40) sahne koordinatına yerleştirilir. Her zemin görselin altında kendi olay dinleyen Konva.Rect düğümüdür. Sahnenin tıklama dinleyicisi, yalnızca canvas DOM öğesini değil, seçilen Konva düğümünü belirten event.target.id() değerini bildirir.

await source.decode(), önbellek oluşturulmadan önce çalışır. Görsel yüklenirken değil, gerçek kaynak hazır olduktan sonra önbelleğe alın. Konva'nın Node API'si, önbellek ve önbellek temizleme yöntemlerini belgeler.

3. Dolu alana, deliğe, köşeye ve zemine tıklayın

Panellerin altında listelenen dört konumu test edin. Bunlar tarayıcı penceresinden ölçülen koordinatlar değil, her sahnenin iç koordinatlarıdır.

KonumSahne koordinatıTest ettiği
Dolu tasarım125,110Amblemin içindeki opak nokta
Özgün delik195,130hollow.svg içindeki şeffaf iç bölge
Şeffaf köşe305,55Görsel dikdörtgeninin içinde, boyalı siluetin dışında
Görselin dışı20,20Ayrı tıklanabilir zemin

Aşağıdaki tablo test edilen hedef türünü kaydeder. Günlükler alpha-background gibi her panelin önekini içerir.

YapılandırmaDolu alanÖzgün delikŞeffaf köşeGörselin dışı
Varsayılan görselGörselGörselGörselZemin
Önbellekten alfa isabet alanıGörselZeminZeminZemin
Opak beyaz dolgulu önbellek görseliGörselGörselGörselZemin
Değiştirilen kaynak ve yenilenen önbellekGörselGörselZeminZemin
Kaydedilen tıklama hedef kimlikleriyle varsayılan dikdörtgen isabetlerin, önbellek alfa isabetlerinin, opak görsel dolgusunun ve değiştirilen kaynağın gerçek Konva tarayıcı karşılaştırması
Özgün SVG tasarımı ve kaydedilmiş masaüstü tıklama hedefleriyle gerçek Konva 10.9.0 sahneleri. Alfa temelli delikli görsel, delik ve köşe tıklamalarını ayrı zemine geçirir. Opak görsel dolgusu ve boyalı yeni kaynak sonuçları değiştirir.

Tarayıcı testi 16 konumun tamamında gerçek işaretçi tıklamaları kullandı; yerel olay güvenilirliğini, sahne koordinatlarını ve hedef kimliklerini kaydetti. Kaynak dosya karmalarını, görsel çözümlemeyi, sahne ve görsel ölçülerini, genel kesişim sonuçlarını ve her görsel düğümünün çizilen canvas'ından yerel alfa örneklerini de kontrol etti.

Özgün delikte, delikli görsel düğümünün alfası 0'dı. Opak dolgu ve değiştirilmiş kaynak kontrollerinde orası alfa 255'ti. Ayrı sayfa zemini delikli görselin kendisini opak yapmadı; altındaki başka Konva düğümüne aitti. Bunlar yumuşatılmış sınırlardan uzaktaki iç örneklerdir.

Bu, basit özgün SVG'ler ve dönüşümsüz sahnelerle tek masaüstü tarayıcı testidir. Mobil/dokunmatik davranışı, klavye etkileşimini, tarayıcılar arası matrisi, performans artışını veya her yumuşak kenarlı görsele uyan eşiği kanıtlamaz. Tıklama testini uygulamanızın gerçek gösterim boyutunda ve dönüşümlerinde tekrarlayın.

4. Kaynak değiştiğinde önbelleği yeniden oluşturun

Dördüncü panel delikli kaynak ve alfa isabet alanıyla başlar. Ardından önbelleği temizler, zaten çözümlenmiş yeni görseli kurar, yeniden önbelleğe alır ve isabet alanını yeniden oluşturur. Bu diziden sonra özgün delik konumu zeminden görsele geçer.

Önbellek, görüntülenmiş anlık görüntüdür. Görüntülenen pikselleri etkileyen değişiklikten sonra önbellekteki sahneyi ve alfa temelli isabet alanını birlikte yenileyin. Farklı görsel atamanın mevcut önbellek isabet alanını güncellediğini varsaymayın. Asenkron yüklenen yeni görsel için örnekteki diziden önce çözümlemesini bekleyin.

Üçüncü panel farklı nedeni ayırır: artwork.fill('#ffffff'), aynı görsel düğümünün parçası olarak görselin arkasına opak dikdörtgen boyar. Bu önbellek sahnesinden isabet alanı oluşturmak boyalı alanı içerir. İstenmeyen görsel düğümü dolgusunu kaldırıp önbelleği ve isabet alanını yeniden oluşturun. Kaynakta beyaz görünen bölge de gerçek opak boya olabilir; isabet algılamasını suçlamadan önce şeffaflığı inceleyin.

Piksel okuma ve hedefleme hatalarını ayrı tanılayın

BelirtiÖnce kontrol edin
Delik hâlâ görseli kaydediyorÖnbelleğin çözümlemeden sonra oluşturulduğunu, isabet alanının yenilendiğini ve opak dolgu veya kaynak zeminin deliği kapatmadığını doğrulayın
Tasarım değişti ama tıklamalar eski şekli izliyorKaynak değişiminden sonra sahne önbelleğini ve alfa isabet alanını temizleyip yeniden oluşturun
Piksel okuma veya kirlenmiş canvas hatası çıkıyorİsabet sonucu yorumlamadan önce görsel kaynağını ve yanıt başlıklarını kontrol edin
Tüm görsel olay almayı bırakıyorlistening, görünürlük, katman sırası ve üstte başka düğüm olup olmadığını kontrol edin
Delik alt nesne yerine sahneye ulaşıyorO noktanın altında gerçekten amaçlanan olay dinleyen nesnenin bulunduğunu doğrulayın
Canvas tıklamaları çalışıyor ama klavye çalışmıyorKlavye denetimlerini ve anlam yapısını ayrı tasarlayın; alfa isabet pikselleri bunları sağlamaz

Bu örnek iki SVG'yi sayfayla aynı kaynaktan sunar. Kaynaklar arası görseller piksel okuma için temiz kaynaklı canvas gerektirir. Konva'nın kirlenmiş canvas rehberi, CORS isteğine izin veren sunucuyla birlikte crossOrigin kullanımını açıklar. Tek başına crossOrigin = 'anonymous' ayarlamak, sunucu izin vermiyorsa erişim sağlayamaz. Makale kaynaklar arası hata durumu çalıştırmadı.

Dış canvas'ta CSS pointer-events değiştirmek, Konva.Image içindeki hangi piksellerin iç düğümlere isabet edeceğini seçmez. Canvas hedeflemesini DOM SVG işaretçi hedeflemesinden ayrı tutun. SVG ana dosyasını da koruyun: önbellek isabet haritası piksel temelli etkileşim verisidir, vektör belgesinin yerine geçmez.

Tasarım geri kazanmayı olay bağlamadan ayırın

Uygulamanız yalnızca görsel yerleştirme ve alfa temelli isabet gerektiriyorsa uygun şeffaf raster görsel yeterli olabilir. Yalnızca PNG veya JPG kaldıysa ve uygulama düzenlenebilir yol geometrisi de istiyorsa PerfectVector'ın görselden vektöre iş akışı SVG adayı geri kazanmaya yardımcı olabilir. Silueti ve delikleri inceleyip Konva gösterimini seçin ve olaylarını uygulayın. Bu örnek özgün yerel SVG'ler kullandı, PerfectVector dönüşümü yapmadı.

Vektörleştirme dinleyici kurmaz, erişilebilir denetim oluşturmaz, tıklama hedefi seçmez veya önbellekleri eşzamanlı tutmaz. SVG ana dosyası varsa etkileşim kodunu doğrudan düzeltin. İçinde beklenmedik biçimde tam dikdörtgen görsel bulunan dosyada, içeriğin ayrı düzenlenebilir yollar olduğunu varsaymadan önce SVG gömülü raster kontrolünü kullanın.

Sık sorulan sorular

Konva görselimdeki şeffaf pikseller neden tıklama alıyor? Varsayılan Image düğümü isabet için dikdörtgen alanını kullanabilir. Kaynak hazır olduktan sonra önbelleğe alın ve uygun sayısal alfa eşiğiyle drawHitFromCache kullanın; yeniden çizip gerçek hedefleri test edin.

drawHitFromCache hangi argümanı alır? Güncel API, varsayılanı 0 olan isteğe bağlı 0–255 tam sayı alfa eşiği kabul eder. Test edilen örnek 0 geçirir. Geri çağırım geçirmez veya görsel Threshold filtresini kullanmaz.

Beyaz dolgu SVG deliğimi neden yeniden tıklanabilir yapıyor? Image düğümündeki opak dolgu önbellek sahnesinin parçası olur. Önbellek alfası bu boyalı alanı içerir. İstenmeyen dolguyu kaldırıp sahne önbelleğini ve isabet alanını yeniden oluşturun.

Alfa isabet alanı SVG yollarını bağımsız düzenlenebilir yapar mı? Hayır. Tasarım tek Image düğümü olarak kalır. Uygulamanız tek tek vektör bölgesi denetimleri istiyorsa uygun ayrı Path düğümleri ve açık sahne modeli kullanın.

Kaynaklar

  1. Konva: Image Events — Varsayılan görsel isabet davranışı ve önbellek tasarımından isabet alanı oluşturma.
  2. Konva: Shape API — Güncel sayısal alphaThreshold parametresi ve aralığı.
  3. Konva: Node API — Önbellek oluşturma, temizleme, olay hedefleri ve genel düğüm yöntemleri.
  4. Konva: Kirlenmiş canvas rehberi — Kaynak kısıtlamaları, CORS ve piksel okuma hataları.
  5. Konva: Canvas üzerinde SVG — Tüm görselin çizilmesi ile ayrı oluşturulan vektör yolları karşılaştırması.

Düzenlenebilir geometri eksikse PerfectVector ile SVG adayı hazırlayın, deliklerini inceleyin ve ardından amaçlanan Konva tıklama hedeflerini ve önbellek güncellemelerini ayrı test edin.

Bloga daha fazlası

PerfectVector

Düzenlemesi daha kolay,
daha temiz bir SVG ile başlayın

Kredi kartı gerekmez