Konu Başlıkları
Yükleniyor...

SVG Arc Komutu: Yedi Parametre ve Sessiz Hatalar

SVG'de A Komutuyla Yay Çizmek: Bayraklar, Yarıçap Düzeltmesi, Tam Çember

SVG'de bir yayı A komutuyla çizersiniz, ama komut sizden yayın merkezini istemez. İki uç nokta, iki yarıçap ve üç ayar verirsiniz; merkezi tarayıcı hesaplar. İlk denemede arc'ı kafa karıştırıcı yapan şey bu ters kurgudur: elinizdeki sayılarla ekranda gördüğünüz eğri arasındaki ilişki doğrudan değil.

Yedi parametre, tek komut

Kaynaklarda sık geçen örnekle başlayalım:

<path d="M 0 0 A 100 100 0 1 1 200 0" />

M 0 0 kalemi başlangıç noktasına taşır. Sonrasındaki yedi sayı sırasıyla şunlar: x yarıçapı (100), y yarıçapı (100), elipsin kendi ekseni etrafındaki dönüşü (0 derece), büyük yay bayrağı (1), süpürme yönü bayrağı (1) ve bitiş noktası (200, 0).

Dikkat edin: merkez yok. Buna uç nokta parametrelendirmesi deniyor. Canvas API'sinde arc() çağrısı merkez, yarıçap ve iki açı ister; SVG'de tam tersi, uçları siz söylersiniz, merkez ve açılar türetilir. Bir yayı elle hesaplarken bu fark önemli, çünkü "90 derecelik bir dilim çiz" isteği SVG'de doğrudan yazılamaz. Önce o dilimin bittiği noktanın koordinatını bulmanız gerekir: x = cx + r·cos(θ), y = cy + r·sin(θ). Pasta grafiği çizen her kütüphanenin içinde bu iki satır vardır.

Dört yay her zaman dört tane değildir

İki bayrağın ikişer değeri var, dolayısıyla aynı iki uç nokta ve aynı yarıçaplarla dört ayrı yay üretilebilir. Büyük yay bayrağı 180 dereceden uzun parçayı mı yoksa kısa olanı mı istediğinizi, süpürme bayrağı da hangi yönde dolaşılacağını söyler.

Peki yukarıdaki örnekte hangisi çiziliyor? Hiçbiri, çünkü orada dört seçenek yok. Uçlar arası mesafe 200, iki yarıçap da 100. Yani uçlar tam olarak çapın iki ucunda duruyor ve her iki yay da 180 derece. Büyük yay bayrağını 1'den 0'a çevirdiğinizde ekranda hiçbir şey değişmez; geriye yalnızca süpürme yönünün ürettiği iki farklı şekil kalır. Arc'ı öğrenirken denemek için seçilebilecek en kötü örnek, bayrakların yarısının etkisiz kaldığı bu tam yarım çember durumu. Yarıçapı 120 yapıp tekrar deneyin, dördü de ayrışır.

Yarıçap yetmezse tarayıcı onu büyütür

Uçlar birbirinden 200 birim uzaktayken yarıçapı 50 verirseniz geometrik olarak böyle bir yay yoktur: 50 yarıçaplı bir çember o iki noktadan aynı anda geçemez. SVG bu durumda çizimi iptal etmez, hata da vermez. Spesifikasyon, yayın var olabileceği en küçük değere ulaşana kadar iki yarıçapı da aynı oranda büyütmeyi şart koşar. Örnekteki 50, sessizce 100 olur.

Bu davranış hayat kurtarır ama bir hatayı da gizler. Yarıçapı veriden hesaplayan bir grafikte değer beklenenin altına düştüğünde eğri bozulmaz, sadece "düzeltilir" ve siz haftalarca yanlış ölçekli bir görsele bakarsınız. Yarıçapı dinamik üretiyorsanız uçlar arası mesafenin yarısını alt sınır olarak kendiniz kontrol edin, tarayıcının düzeltmesine bırakmayın.

Tam çember tek yayla çizilmez

En sık takılınan yer burası. Başlangıç ve bitiş noktasını aynı koordinat yapıp "360 derece dönsün" beklersiniz, ekranda hiçbir şey çıkmaz. Spesifikasyona göre uç noktalar birebir aynıysa yay segmenti tamamen atlanır. Sebep de mantıklı: aynı iki nokta arasındaki sonsuz sayıda çemberden hangisinin kastedildiğini söyleyecek bir bilgi kalmıyor.

Çözüm, çemberi iki yaya bölmek:

<path d="M 0 -100 A 100 100 0 1 1 0 100 A 100 100 0 1 1 0 -100" />

Bir yükleme animasyonunun ya da ilerleme halkasının %100'e ulaştığı anda kaybolmasının nedeni de genelde budur: açı 359,9'dan 360'a çıkarken uçlar çakışır. Kütüphanelerin çoğu bunu 359,99 derecede durdurarak çözer, ki bu da tam kapanmayan bir halka bırakır. Halkanın gerçekten kapanması gerekiyorsa yolu <circle> elemanına çevirip stroke-dasharray ile ilerlemeyi sürmek daha temiz durur.

viewBox yayın nerede göründüğünü belirler

Arc koordinatları kullanıcı birimindedir, piksel değil. viewBox="-300 -300 600 600" yazdığınızda görünür alanın sol üst köşesi (-300, -300) olur ve merkez tam olarak (0, 0) noktasına gelir. Merkezi orijine oturtmak, açıdan koordinat hesaplayan formülleri epeyce sadeleştirir; cx ve cy terimleri düşer. Ayrıca y ekseninin aşağı doğru büyüdüğünü unutmayın, trigonometriden gelen alışkanlıkla yukarı beklerseniz çizim aynada gibi ters çıkar.

Arc mı, Bézier mi?

Dairesel bir parçayı gözle ayarlanmış C eğrisine bırakmaktansa A ile yazmayı daha güvenilir bulurum. Bézier ile çeyrek çember taklidi yapmak mümkün, kontrol noktalarını yarıçapın 0,5523 katına koyarsınız ve sapma yarıçapın binde biri mertebesinde kalır, gözle görülmez. Ama yarıçapı sonradan değiştirdiğinizde dört kontrol noktasını da yeniden hesaplamanız gerekir; arc'ta iki sayıyı düzeltmek yeter. Bézier'i gerçekten serbest formlu, dairesel olmayan eğriler için saklayın.

Kaynaktaki eskimiş bir uyarı

SVG anlatan metinlerde "gölge, degrade ve yansıma efektleri SVG'de tam desteklenmez" cümlesine hâlâ rastlanıyor. Bu bilgi yıllar önce doğruydu. Bugün linearGradient ve radialGradient formatın kendi parçası, gölge için feDropShadow filtresi var ve tarayıcı desteği geniş. Yayınız bir degradeyle boyanacaksa bunun için SVG'den çıkmanız gerekmiyor.

Geçerli olan sınır başka: SVG vektör tabanlı olduğu için fotoğraf benzeri, çok sayıda ayrıntı taşıyan görüntülerde yanlış araçtır. Birkaç yüz düğümlü bir yol dosyayı da tarayıcıyı da PNG'den daha fazla yorar.

Kaynak