holodepth

HTML5 Canvas · Çizim & path

Path sistemi: alt yol, alt yollar ve geometri sözleşmesi

Canvas 2D’de çoğu şekil önce path (alt yol) olarak tanımlanır: düz çizgiler, yaylar ve kapalı bölgeler bir «taslak» halinde CanvasRenderingContext2D içinde birikir; piksel üzerine boyama ise fill, stroke veya clip ile ayrı adımda gelir. Bu sayfa path’in nasıl kurulduğunu, ne zaman sıfırlandığını, alt yolların nasıl davrandığını ve Path2D ile yeniden kullanımı canvas üreticisi gözüyle anlatır.

Bağlam yığını ve kırpma State sistemi ile; koordinat ve dönüşüm Koordinat sistemi ile kesişir. Dolgu ve çizgi boyamasının farkı Stroke vs fill sayfasında; Bézier ve yumuşak eğriler Eğri mantığı başlığında derinleşir — burada yalnızca path komutları ve geometri disiplini.

Özet: path yaşam döngüsü

Adım Komut / kavram Not
Sıfırla beginPath() Geçerli path’i boşaltır; önceki alt yollar unutulur
Kur moveTo, lineTo, arc Alt yol ve segment ekler; henüz piksel yazılmaz
Kapat (isteğe bağlı) closePath() Son noktayı alt yolun başına bir segmentle bağlar
Uygula fill / stroke / clip Path tüketilir veya clip ile kalıcı mask olur

Path nedir: taslak geometri, henüz boya yok

2D context sayfasında bağlamın «çizim kalemi» olduğu geçmişti; path ise kalemin izleyeceği rotadur. lineTo(100, 50) çağırdığınızda ekranda anında çizgi görünmez — yalnızca mevcut alt yola bir kenar eklenir. Görünür sonuç için stroke() veya içi dolu alan için fill() gerekir; bu ayrım, vektör editörlerindeki «yol / boya» ikiliğinin canvas karşılığıdır ve hata ayıklamada sık karıştırılır.

Tarayıcı path’i dahili bir yapıda tutar; siz doğrudan path nesnesine erişemezsiniz (standart API’de), yalnızca komutlarla güncellersiniz. Zihinsel model: tek bir «aktif taslak»; beginPath taslak defterini yırtıp yenisine başlar. Önceki taslaktaki şekiller kaybolmaz — zaten boyanmış pikseller bitmap’te kalır — fakat henüz boyanmamış path tanımı silinir; dolgu veya stroke atlamadan önce path’i unutursanız beklenmedik boş kareler alırsınız.

Path, bağlam durumunun parçası değildir: State sistemi sayfasında geçtiği gibi save() stil ve matrisi saklar; geçerli alt yol tanımı save ile otomatik korunmaz. Dal açıp path kurup restore ettiğinizde stil geri gelir; path ise restore öncesi ne ise öyle kalır veya siz beginPath ile sıfırlamış olursunuz. Karmaşık sahnelerde «path’i hangi fonksiyon kurdu?» sorusunu fonksiyon sınırına kilitlemek, state sızıntısından bağımsız bir hata sınıfıdır.

Path komutları sırayla işlenir; «son nokta» kavramı lineTo ve eğri komutları için referanstır. Aynı karede arka plan, maske ve içerik için ayrı path döngüleri düşünün — hepsi aynı ctx üzerinde olsa bile her biri kendi beginPath ile başlamalıdır. Boyama sırası bitmap katman sırasıdır; path tanımı sırası değildir.

beginPath ve closePath: temiz sayfa, kapalı kontur

Her bağımsız şekil veya her çizim geçişi öncesinde beginPath() alışkanlığı üretim kodunun omurgasıdır. Aksi halde önceki karenin veya önceki modülün segmentleri aktif path’e eklenir; fill birden devasa bir «leke» üretir. Kare başında tek beginPath + tüm dünya geometrisi tek path’te toplanabilir; çoğu ekip ise «şekil başına beginPath» veya «katman başına beginPath» tercih eder — ikincisi hata izolasyonu sağlar, birincisi çok sayıda küçük path’te biraz daha çağrı maliyeti getirir.

closePath() son noktayı mevcut alt yolun ilk noktasına düz bir segmentle bağlar; yay veya eğri ile başlamış olsanız bile kapanış segmenti düzdür. Kapalı kontur, dolguda iç/dış ayrımı için önemlidir; açık polyline’da fill yine çalışır fakat tarayıcı sanal bir kapanış uygular — davranışı Stroke vs fill ile birlikte test etmek gerekir. Stroke tarafında closePath son kenarı çizer; açık path’te son lineTo ile biten çizgi stroke edilir, kapanış segmenti yoktur.

function drawTriangle(ctx, x1, y1, x2, y2, x3, y3) {
  ctx.beginPath();
  ctx.moveTo(x1, y1);
  ctx.lineTo(x2, y2);
  ctx.lineTo(x3, y3);
  ctx.closePath();
  // fill veya stroke ayrı adımda
}

moveTo, lineTo ve rect: segment ve kutu

moveTo(x, y) kalemi taşır, yeni bir alt yol başlatır; bir sonraki lineTo bu noktadan çizilir. Aynı path içinde birden fazla kopuk şekil için desen: moveTo → segmentler → moveTo (yeni alt yol) → segmentler. Her moveTo önceki alt yolu bitirmez; path içinde birden fazla alt yol bir arada durur — dolgu kuralları alt yolları ayrı ayrı değerlendirir.

lineTo mevcut noktadan hedefe düz kenar ekler. Dönüşüm matrisi ( Koordinat sistemi ) uygulanmışsa segmentler dönük/ölçekli uzayda hesaplanır; path komutları her zaman bağlam uzayında verilir, ekran pikseli değil (CSS ölçeklemesi ayrı katmandır).

rect(x, y, w, h) tek çağrıda dikdörtgen alt yolu ekler; ardından strokeRect / fillRect path kurmadan doğrudan boyayan kısayollardır. Karmaşık sahnede rect + fill ile fillRect eşdeğer sonuç verir; fakat path’e bağlı clip veya özel stroke birleşimleri için rect + path tabanlı boyama tercih edilir. Hazır şekil kataloğu Şekil çizimi sayfasında genişler; burada dikdörtgenin path zincirine nasıl eklendiği yeterli.

lineJoin ve lineCap path ile ilişkisi

Köşe birleşimi (lineJoin) ve uç stili (lineCap) bağlam stilidir; path geometrisinden bağımsızdır fakat stroke() anında path üzerinde görünür. Kalın çizgili HUD çerçevelerinde önce path’i doğru kurup sonra stroke stilini set etmek sırası hatayı azaltır — stil save/restore dalında da güvenle sıfırlanabilir.

Alt yollar ve dolgu kuralı: nonzero ve evenodd

Tek bir beginPath içinde birden fazla kapalı kontur tanımlayabilirsiniz — örneğin harf «O» için dış halka ve iç delik. fill() hangi bölgelerin «iç» sayılacağını fillRule ile çözer: 'nonzero' (varsayılan) sarma yönüne göre, 'evenodd' ışın kesişim sayısına göre. Delikli şekiller ve karmaşık SVG benzeri silüetlerde evenodd sık tercih edilir; yanlış kural seçimi dolgunun tersine dönmesine yol açar.

fill(path, fillRule) ve clip(path, fillRule) overload’ları aynı kuralı path nesnesine uygular. Stroke, iç/dış ayrımını winding ile değil path’in merkez çizgisi üzerinden yapar — ince halka stroke’unda delik davranışı farklıdır; detay Stroke vs fill sayfasında kalır.

arc, ellipse ve arcTo: yay tabanlı path

arc(x, y, radius, startAngle, endAngle, anticlockwise) merkez ve yarıçapla yay ekler; açılar radyandır (Math.PI = yarım tur). Tam daire için başlangıç/bitiş açılarını 0 ve 2 * Math.PI (veya eşdeğeri) seçin; küçük yaylar gösterge veya progress ring için kullanılır. Yay, mevcut noktaya doğrudan bağlanmaz — önceki lineTo ile merkez arasında istenmeyen kiriş segmenti oluşabilir; daire öncesi moveTo ile başlangıç noktasını kontrol edin.

ellipse(...) elips ve yarı eksen döndürmesini tek komutta verir; arcTo ise iki teğet doğru arasına yuvarlatılmış köşe ekler — UI panellerinde sık görülür. Yüksek eğrilikli spline’lar ( quadraticCurveTo, bezierCurveTo) Eğri mantığı konusudur; path sisteminde yalnızca «eğri de path segmentidir, boyama yine fill/stroke ile» bağını kuruyoruz.

function addArcSegment(ctx, cx, cy, r, startRad, endRad) {
  ctx.beginPath();
  ctx.arc(cx, cy, r, startRad, endRad);
  // stroke() ile halka; fill() ile dilim — stroke-vs-fill sayfasında
}

Path2D: yeniden kullanılabilir geometri

new Path2D() veya SVG path dizesi ile oluşturulan Path2D, geometriyi bağlamdan ayırır. Aynı silüeti farklı konumlarda ctx.fill(path), ctx.stroke(path) veya ctx.clip(path) ile tekrar kullanırsınız; her kullanımda bağlamın mevcut transformu uygulanır — path kendi içinde dünya koordinatı taşımaz, «şablon»dur.

Path2D üzerinde addPath ile birleştirme mümkündür; animasyonda önceden hesaplanmış karmaşık konturları her karede yeniden lineTo zinciri yazmak yerine bir kez oluşturup çizmek CPU’yu rahatlatır. Path2D, bağlam path’inden bağımsızdır; beginPath ctx’teki taslağı etkilemez. Hit test ( isPointInPath(path, x, y)) için de kullanılır.

const badge = new Path2D();
badge.rect(0, 0, 48, 24);

function drawBadgeAt(ctx, x, y) {
  ctx.save();
  ctx.translate(x, y);
  ctx.fill(badge);
  ctx.restore();
}

clip, isPointInPath ve etkileşim köprüsü

clip() mevcut path’i (veya verilen Path2D) kırpma maskesi yapar; sonraki çizimler kesişim dışında görünmez. Maskeli dal aç-kapa State · clip ile örtüşür: path’i burada kurarsınız, save → clip → çiz → restore orada yönetilir. Path kurulmadan clip çağrısı etkisiz veya hatalı sonuç üretir.

isPointInPath(x, y) ve isPointInStroke(x, y) fare konumunun path içinde veya stroke bandında olup olmadığını döner — canvas tarafında basit seçim ve hover için yeterlidir; karmaşık sahnelerde bounding box ön elemesi + path testi birlikte kullanılır. Oyun çarpışması ve fizik bu API’nin yerine geçmez; yalnızca 2D hit test katmanıdır.

Anti-kalıplar: unutulan beginPath ve hayalet segment

beginPath atlamak: Önceki şeklin segmentleri yeni fill ile birleşir; «neden tüm ekran boyandı?» sorusunun klasik cevabıdır. Kare başında veya her public çizim fonksiyonunda açıkça sıfırlayın.

moveTo unutmak: İlk lineTo (0,0) veya önceki şeklin son noktasından çizgi çeker — istenmeyen kiriş. Her yeni kopuk şekilde önce moveTo.

Path ile stil karıştırmak: fillStyle path’ten önce/sonra fark etmez; path geometrisidir. Stil sızıntısı State anti-kalıplar konusudur.

clip sonrası path: clip path’i tüketmez ama mask kalır; mask olmadan çizmek için restore veya yeni dal şart.

Bu sayfanın sınırı

Path burada geometri taslağıdır; piksel birleştirme modları Composite operations, animasyon döngüsü ise Clear & redraw klasöründedir. SVG DOM path’i veya WebGL mesh üretimi bu API’nin dışındadır.

  • Bu fonksiyon beginPath ile mi giriyor?
  • Kopuk şekillerde her alt yol öncesi moveTo var mı?
  • fill / stroke çağrılmadan path bekleniyor mu?

Sıradaki: stroke, fill ve şekil kataloğu

Path’i kurduktan sonra görünür sonuç Stroke vs fill ve hazır Şekil çizimi sayfalarında netleşir. Önceki bağlam hattı: State sistemi.