holodepth

HTML5 Canvas · Çizim & path

Eğri mantığı: Bézier, kontrol noktaları ve yumuşak path

Düz çizgi lineTo ile yeterli olduğunda geometri basittir; arayüz eğrileri, oyun yolları ve organik silüetler ise düz segmentlerle «dizilmiş kırık» görünür. Canvas 2D, yolu yumuşatmak için Bézier tabanlı komutlar sunar: quadraticCurveTo tek kontrol noktası, bezierCurveTo iki kontrol noktası ile uç noktalar arasında sürekli eğri tanımlar. Bu sayfa kontrol noktası mantığını, segment birleşimini ve çizim pratiğini canvas üreticisi gözüyle sabitler — spline matematiğinin tam türetimi değil, API ile üretim disiplinidir.

Path kurulumu Path sistemi sayfasında; yaylar için arc / ellipse Path · arc bölümünde özetlenmiştir. Dolgu ve kontur boyaması Stroke vs fill sayfasındadır. Hazır dikdörtgen ve kart şekilleri Şekil çizimi konusudur — burada yalnızca eğri segmentleri ve birleştirme.

Özet: Eğri komutları

Komut Kontrol Tipik kullanım
quadraticCurveTo(cpx, cpy, x, y) 1 kontrol noktası Köşe yumuşatma, basit kemer
bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y) 2 kontrol noktası Esnek S‑eğrisi, tipografi benzeri hat
arc / ellipse Merkez + açı Tam daire, yay, oval

Eğri segmentleri: önce moveTo, sonra kontrol

Bézier komutları mevcut noktadan başlar; bu yüzden eğri öncesinde bir moveTo veya önceki segmentin son noktası tanımlı olmalıdır. İlk çağrı öncesi konum yoksa sonuç belirsizdir — birçok hata «ilk moveTo’yu unuttum» kökenlidir. Zincir: moveTo → quadraticCurveTo → quadraticCurveTo şeklinde uzar; her eğri bir önceki uç noktadan bir sonrakine bağlanır.

Kontrol noktası çizilmez; eğrinin «çektiği ip» gibi davranır. Görsel olarak kontrolü sürükleyerek yolu oynatırsınız — canlı editörlerde sürüklenen küçük noktalar bu mantığın kullanıcı arayüzü karşılığıdır. Canvas’ta sayılar elle veya ara nesneler üzerinden verilir.

closePath ile eğri zincirini kapalı bölgeye çevirebilirsiniz; dolgu ( fill) iç/dış kararı winding kuralıyla çözülür ( Path · dolgu kuralı ).

QuadraticCurveTo: tek kontrol ve hafif kemer

İkinci derece Bézier, başlangıç ve bitiş teğetlerinin kesiştiği kontrol noktasında toplanır; parabolik bir kemer üretir. UI’da düğme köşesini kırmadan yumuşatmak, mini grafikte yumuşak tepe veya haritada nehir «genel hat»sı için yeterli olur. Tek kontrol ile düşük parametre boyutu: oyun araçlarında ve runtime’de iki koordinat ekseni.

Kontrol noktası segmentin dışına taşındıkça eğri daha «keskin» bir S yapar; uçlara yaklaştıkça düz çizgiye yaklaşır. Köşe (x,y) etrafında simetrik yumuşatma istiyorsanız kontrolü köşenin iki kenarı boyunca aynı uzaklıkta koymayı hedefleyin — görsel simetri böyle kurulur.

// (x,y)'den (x+r,y)'ye giderken üst kemeri
function quadTopRound(ctx, x, y, r, w) {
  ctx.moveTo(x, y + r);
  ctx.quadraticCurveTo(x, y, x + r, y);
  ctx.lineTo(x + w - r, y);
}

BezierCurveTo: çift kontrol ve esnek S‑hatları

Üçüncü derece Bézier, uçlardaki teğet yönünü bağımsız seçmenizi sağlar — bu yüzden «S» veya cıvık viraj tek segmentte mümkündür. İki kontrol, birincisi başlangıca, ikincisi bitişe «çekim» uygular. SVG ve vektör tasarım araçlarıyla aynı matematik; Path2D ile SVG dizesi aktarımında sık karşılaşırsınız.

Birbirine bağlı C1 süreklilik (kaymayan teğet) istiyorsanız ardışık segmentlerde kontrol noktalarını hizalamak gerekir — pratikte ara nokta paylaşımı veya aynı doğrultuda ikinci kontrol seçimi kullanılır. Üretim kodunda «görsel yeterli» ile «matematiksel süreklilik» farklıdır; oyun yolu için küçük kırılma kabul edilebilir, ikon outline için gerekmeyebilir.

Çok sayıda küçük kübik parça, kaba bir polyline’dan daha az «titreme» ile düzgün hat verir; fakat CPU’da çok segment pahalı olabilir — uzun ömürlü yollar için nokta önbelleği veya önceden üretilmiş Path2D tercih edilir ( Şekil · Path2D ).

function addRoughS(ctx, x0, y0, x1, y1) {
  ctx.moveTo(x0, y0);
  ctx.bezierCurveTo(
    x0 + (x1 - x0) * 0.35, y0,
    x1 - (x1 - x0) * 0.35, y1,
    x1, y1
  );
}

Segment örüntüsü: polyline’dan spline’e geçiş

Nokta dizisi P0…Pn için en basit yol: her aralıkta lineTo. Eğri hissi için her aralığı bir Bézier ile değiştirmek veya Catmull-Rom benzeri bir şema ile ara kontrol üretmek gerekir — canvas doğrudan Catmull-Rom komutu sunmaz; kontrol üretimini siz yaparsınız. Sık desen: her köşede yön vektörüne göre kısa quadraticCurveTo veya çift kübik kulp ( handle).

Üretimde «kolay» yol, her düğüm için teğet tahmini çıkarmak ve bir önceki/bir sonraki segmente bakan vektörlerden kulp uzunluğu vermektir; gerginlik ( tension) parametresi çok düşükse eğri düzleşir, çok yüksekse köşelerde «wobble» ve kendine kesişim riski artar. Sert köşe ile yumuşak köşeyi aynı dizide karıştırıyorsanız düğüm başına bir bayrak tutup bazı noktaları düz lineTo ile bağlamak daha kontrollü kalır.

moveTo ile yeni alt yol başlattığınızda önceki eğri ile bağ kopar; uzun multi-segment hat için sadece başta moveTo, ortada sürekli quadratic/line kullanın. Aksi halde dolgu içi beklenmedik boşluklar oluşur.

Kapalı kontur çizmek için son noktadan başa lineTo yerine closePath tercih edin; dolgu kuralı ( Path · winding ) özellikle öz-kesişen eğri bölgelerde beklenmedik sonuç verir — tasarımda «şeker paket» halka gibi silüetlerde 'evenodd' düşünmek Stroke vs fill · fillRule ile örtüşür.

Arc ve Bézier: daire parçası mı, yaklaşık eğri mi?

Gerçek daire yayı için arc veya ellipse doğrudur — parametrize kolaydır ve zoom’da matematiksel olarak dairedir. Bézier ile yayı yaklaşıklamak mümkündür fakat birden fazla segment veya yüksek hassasiyet gerekir; birçok vektör motoru arkasında yine arc kullanır.

Yaklaşık Bézier parçaları birleştirildiğinde birikim hatası — birleşim noktalarında mikro «dirsek» veya hafif yarıçap kayması — özellikle kalın stroke ve büyük zoom’da seçilebilir. Semantik olarak tam daire veya tam elips gerekiyorsa API’yi doğru seçmek üretim maliyetinden ucuzdur; «görsel olarak yuvarlak» yeterli diyorsanız düşük segment sayısı bilinçli bir kompromi olur.

Rounded rectangle için roundRect ( Şekil · roundRect ) pratik çözümdür; arc veya dört köşede dört arc eski yöntemdir. Özel «asimetrik» köşe ovalleri ise Bézier veya elips parçası ister.

Yayın başlangıç açısı ile önceki segment uçunun tam teğet olması zorunlu değildir — tarayıcı yeni yay alt yoluna geçer; fakat lineJoin ve stroke ile birleşimde küçük köşe artefaktı oluşabilir. Kritik görsel birleşimlerde ya tek sürekli path stratejisi ya da uygun join/cap seçimi gerekir.

Eğride stroke: kalınlık, teğet ve dashes

stroke eğrinin merkez hattı boyunca şerit çizer; keskin teğet köşelerde lineJoin ve miterLimit taşması ince eğrileri bile sivri uçlu gösterebilir ( Stroke vs fill · lineWidth ). Yüksek eğrilikte 'round' join genelde daha temiz görünür.

Açık eğri uçlarında lineCap: 'round' veya 'square', kısa yay parçası görünümü verir; bağlantısız nokta salt moveTo ile stroke edilmez — en az iki farklı noktaya ihtiyaç vardır ( Stroke vs fill · stroke ).

setLineDash kesik desen eğri boyunca uzar; uzunluğu path’e göre tekrarlanır — animasyonlu kesik seçim halkaları ve navigasyon çizgileri için uygundur. Dolgu, eğrinin iç «damla» bölgesini doldurur; açık spline’da dolgu alanı yoksa sonuç beklenmedik olabilir — kapalı path tasarlayın ya da yalnızca stroke kullanın.

Öz-kesişen Bézier ile fill bir «yaprak» gibi iç içe bölgeler üretebilir; hangi bölgelerin dolacağı fillRule ile ayrışır. Tasarım olarak «şerit dolgu» istiyorsanız stroke kullanın veya konturu bilinçli kapayın — geometrik belirsizlik composite ile düzeltilemez.

Path2D ve SVG dizesi: eğriyi önbelleğe almak

Karmaşık eğri silüeti new Path2D(svgPathString) ile içe aktarılabilir; her karede komut dizisi yazmazsınız. Transform ile tek silüeti çok yerde çizmek dünya simgeleri veya tekrar eden dekor için verimlidir.

Path2D üzerinde addPath(path, transform) ile birleştirme ve yerel matris uygulama mümkündür; tekrar eden motifleri tek kerede ölçekleyip çoğaltmak için kullanılır. SVG dizesi hatalıysa path boş veya beklenmedik kalır — tasarım kaynağını validate etmek üretimde sessiz hatalardan korur.

Hit test ve clip(path) overload’ları eğri içeren path ile de çalışır — maske kenarı yumuşak görünür; piksel birleştirme ise Composite operations başlığında kalır.

Hit test ve sınırlayıcı kutu: ön eleme

isPointInPath doğru ama eğri için hesap maliyetli olabilir; çoklu nesnede önce eksen hizalı bounding box ile ön eleme, sonra nadir path testi yapın. Kontrol noktaları eğrinin dışında dolaşabileceği için bbox, kontrol noktalarını içerecek şekilde genişlemelidir — aksi halde tıklama kaçırılır.

Kalın stroke için alan genişler; «çizgi üzeri» seçimde isPointInStroke Stroke vs fill · hit ile birlikte düşünülür. Bbox da minimum yarım lineWidth kadar genişletilmelidir.

Fare koordinatı canvas iç uzayına dönüştürülmeli (Koordinat sistemi ); dönüşüm altındaki eğli yol için test aynı matriste yapılmalıdır.

Binlerce küçük eğri ikonunda hiyerarşik seçim (önce kaba grid hücreleri, sonra aday küme) path testini ucuzlatır — saf isPointInPath brute-force mobilde yüzü olur.

State ve clip: eğri maskede

Yumuşak kenarlı cam panelde içerik göstermek için önce Bézier veya roundRect ile path kurup clip, sonra içerik çizimi klasik State · clip desenidir. Gölge ve yarı saydam stroke aynı dalda üst üste binirse kenar bulanıklaşır — gölgeyi kısa bir State · alpha dalında sınırlandırmak okunabilirliği artırır.

Eğri clip öncesi path’i beginPath ile temiz zeminde kurun; önceki modülün segmentleri kesişince maske «taşar». İç içe iki yumuşak maske gerekiyorsa iki save → clip → çiz → restore katmanı düşünün — dış maske içerik sınırını, iç maske detay pencereyi kısar.

Yumuşak clip kenarı piksel düzeyinde anti-alias üretir; üstüne sert çizgi çizmek görsel çelişki yaratabilir; panel tasarımında içerik stilini maske ile uyumlu tutmak tutarlıdır.

Anti-kalıplar: kaymış başlangıç ve kontrol kaosu

moveTo unutkanlığı: Eğri ilk komut olarak çağrılırsa başlangıç (0,0) veya çürük nokta kullanılır — garip sıçrama üretir.

Kontrol noktasını uç sanmak: (x,y) son parametre uçtur; (cpx,cpy) ara çekimdir — parametre sırası karışırsa sonuç ters çevrilmiş gibi olur.

Dolgu ile açık spline: İçi dolu «şerit» beklemek yerine alan yok; çizgi olarak stroke kullanın veya path’i kapatın.

Tam daire için yalnızca Bézier: Hassas yay için arc tercih edin; yaklaşık segmentler birikim hatası verir.

SVG path’i hiç kontrol etmeden çizmek: Tasarımcı birimleri px değil «tasarım birimi» olarak export etmiş olabilir — ölçek ve öteleme sonrası eğriler taşar; ctx.scale/translate ile uyumlayın veya kaynağı normalize edin.

Tüm eğriye aynı tension: Seyrek noktalı uzun düz bölümde gereksiz kemer; düğüm başına eşik değerle düz tutulup yalnızca gerçek köşelerde Bézier üretin.

Bu sayfanın sınırı

Nurbs, subdivision surfaces ve fizik tabanlı tel simülasyonu bu API dışındadır. Animasyon ease fonksiyonları (zaman eğrisi) Delta time ve ilgili döngü başlıklarında ayrı ele alınır; burada yalnızca uzaysal path geometrisi vardır.

Bu klasörde odak CanvasRenderingContext2D komutlarıdır: quadraticCurveTo, bezierCurveTo ve arkadaşları. SVG dosyasında canlı DOM düğümleri veya tipografi satır kırılımı düzenleyicileri ayrı ekosistemlerdir — burada sadece path’i nasıl besleyeceğiniz ve canvas’ta nasıl boyayacağınız işlenir.

  • İlk nokta moveTo ile sabit mi?
  • Yay mı gerekiyor, Bézier yaklaşımı mı kabul?
  • Hit test öncesi bbox genişletildi mi?
  • Düğüm başına düz mu eğri mi; tension tutarlı mı?

Sıradaki: piksel birleştirme ve özel modlar

Eğriyi çizdikten sonra üst üste bindirme, ışıma ve maskeleme Composite operations sayfasında derinleşir. Önceki adımlar: Stroke vs fill, Şekil çizimi.