holodepth

HTML5 Canvas · Canvas API & context

Canvas oluşturma: bitmap yüzeyini doğru kurmak

<canvas> öğesi, tarayıcıda piksel piksel boyanabilen şeffaf bir bitmap tahtasıdır. SVG gibi vektör değildir; Three.js veya WebGL gibi bir kütüphane de değildir — önce düz bir yüzey açarsınız, ardından ona bağlam (context) alırsınız. Bu sayfa, Holodepth HTML5 Canvas hattının ilk adımında yalnızca o yüzeyi: öğeyi nerede tanımlayacağınızı, boyutun hangi katmanda yazılacağını ve ilk çizime geçmeden önce hangi tuzaklardan kaçınacağınızı netleştirir.

Çizim komutları, koordinat dönüşümü ve döngü bir sonraki sayfalarda derinleşir; burada hedef «canvas var» demek değil, doğru çözünürlükte ve erişilebilir bir canvas var demektir.

Özet: canvas kurulumunun ana hatları

Konu Ne ifade eder? Pratik kural
Öğe DOM'da çizim yüzeyi taşıyıcısı İçerik yoksa bile anlamlı width/height ve yedek metin
Bitmap boyutu width / height nitelikleri (piksel sayısı) Çizim koordinatlarının gerçek sınırı budur; CSS ile karıştırma
Görünen boyut CSS width / height Yalnızca ekranda ne kadar yer kapladığını ölçekler; çözünürlük değildir
Bağlam getContext('2d') veya webgl2 vb. Aynı canvas'ta bağlam türü değişmez; seçim oluşturma anında yapılır

Canvas nedir — ve ne değildir?

HTML5 <canvas>, sayfada sabit boyutlu bir piksel ızgarası ayırır. Bu ızgara başlangıçta şeffaftır; siz (veya bağlam API'si) üzerine renk, çizgi veya görüntü yazar. DOM ağacında normal bir öğe gibi durur: stillenebilir, konumlandırılabilir, olay alabilir — fakat içindeki çizimler ayrı bir «sahne grafiği düğümü» olarak saklanmaz. Bir dikdörtgeni sildiğinizde arkası otomatik olarak «eski haline» dönmez; ya o bölgeyi yeniden boyarsınız ya da tüm yüzeyi temizlersiniz.

Bu yüzden Canvas, imperatif bir API ailesidir: «şunu çiz, sonra bunu çiz» dersiniz; sonuç bir bitmap'tir. SVG ise tanımlayıcıdır: şekiller belgede kalır, stil değişince yeniden düzenlenir. Oyun, partikül sistemi, özel grafik editörü veya hafif 2D arayüz için Canvas sık tercih edilir; sonsuz ölçeklenebilir ikon seti veya erişilebilir vektör diyagramı için çoğu zaman SVG veya DOM daha uygundur.

Holodepth haritasında Canvas aynı zamanda WebGL ve Three.js'e köprüdür: aynı öğe üzerinde webgl veya webgl2 bağlamı da alınabilir. 2D ve 3D yolları paylaşılan tek şey genelde bu DOM öğesidir; bu sayfa 2D çizimden önce ortak zemini kurar.

HTML'de tanımlamak: nitelikler ve yedek içerik

En sade kurulum, belgede canvas öğesini açıkça yazmaktır. width ve height nitelikleri (attribute) bitmap'in iç çözünürlüğünü piksel cinsinden belirler; yazılmazlarsa tarayıcı çoğu zaman 300×150 gibi küçük bir varsayılan kullanır — bu, «neden çizimim küçük ve bulanık?» şikâyetinin sık kaynağıdır.

<canvas id="game" width="800" height="450">
  Tarayıcınız canvas desteklemiyor veya JavaScript kapalı.
</canvas>

Öğe içindeki metin, bağlam alınamadığında veya script çalışmadığında görünen yedek içeriktir. Erişilebilirlik için yalnızca «canvas» yazmak yerine kısa bir açıklama ve gerekirse statik bir alternatif (ör. aynı veriyi özetleyen tablo) düşünün. Canvas'ın kendisi ekran okuyucuya «boş kutu» gibi davranabilir; üretim projelerinde role="img" ve anlamlı aria-label eklemek, özellikle oyun veya veri görselleştirmede kullanıcıyı bilgilendirir.

JavaScript ile dinamik oluşturmak da yaygındır: document.createElement('canvas'), nitelikleri atayıp bir kapsayıcıya eklemek. SPA ve bileşen çerçevelerinde (React, Vue) çoğu zaman bir ref ile öğeye erişilir; mantık aynıdır — önce DOM'da canvas vardır, sonra bağlam istenir.

İç boyut ile CSS boyutu: en kritik ayrım

Bitmap çözünürlüğü (width / height)

Attribute olarak verilen width ve height, tuvalin kaç piksel saklayacağını söyler. ctx.fillRect(0, 0, canvas.width, canvas.height) gibi çağrılar bu sayılara göre çalışır. Koordinat sistemi de bu ızgaraya oturur; bir sonraki sayfada (Koordinat sistemi) bu ekseni ayrıntılandıracağız.

CSS ile görünen kutu

Stil sayfasında canvas { width: 100%; height: auto; } yazdığınızda çoğu zaman yalnızca sayfadaki kutu büyür; bitmap hâlâ attribute'taki piksel sayısındadır. Tarayıcı içeriği kutuya sığdırmak için ölçekler — sonuç bulanık veya tırtıklı olabilir. Retina ekranlarda ek olarak devicePixelRatio ile bitmap'i büyütüp CSS'te küçük göstermek gerekir; bu kalıp Resize mantığı sayfasında adım adım işlenir.

Kısa kural: çizim kalitesi ve hit-test doğruluğu attribute (veya eşdeğer JS ataması) ile belirlenir; CSS yalnızca sunum katmanıdır. İkisini bilinçli eşleştirmediğiniz sürece «kod doğru ama görüntü yanlış» hataları sürer.

Aşağıdaki Canvas Resolution Lab ile attribute, CSS kutusu ve DPR simülasyonunu canlı ölçün; «CSS ile büyüt» modunda bulanıklığı doğrudan görün.

Sık tuzak: sadece CSS ile büyütmek

400×300 attribute + style="width:800px;height:600px" → 2× ölçeklenmiş, yumuşatılmış bitmap. Çözüm: attribute'u
(veya canvas.width = … atamasını) hedef çözünürlüğe çekmek; CSS'i isteğe bağlı aynı oranda tutmak.

Keskin

Canlı ölçümler

Bitmap 400 × 300
CSS kutu 400 × 300 px
DPR (sim) 1.00
Efektif bitmap 400 × 300
Bitmap → CSS 1.00× · 1.00×
Durum Doğru eşleşme · keskin
Bağlam 2d · smoothing on
Canvas Resolution Lab: Attribute width/height bitmap piksel sayısını, CSS ise sayfadaki kutuyu belirler. «CSS ile büyüt» modunda bitmap küçük kalırken kutu büyür — ızgara ve metin bulanıklaşır. Doğru modda bitmap ≈ CSS × DPR; tam piksel hizalı desen keskin kalır. Retina döngüsü için Resize mantığı.

JavaScript'ten erişim ve ilk bağlam

const canvas = document.getElementById('game');
if (!(canvas instanceof HTMLCanvasElement)) {
  throw new Error('Canvas öğesi bulunamadı.');
}

const ctx = canvas.getContext('2d');
if (!ctx) {
  // Eski tarayıcı veya bağlam engeli
  return;
}

ctx.fillStyle = '#1a1f2e';
ctx.fillRect(0, 0, canvas.width, canvas.height);

getContext ile istediğiniz API ailesini seçersiniz. '2d' bu hattın bir sonraki konusu (2D context); 'webgl2' veya 'webgl' ise Holodepth WebGL dizisine bağlanır. Aynı canvas'ta önce 2D alıp sonra WebGL almak güvenilir bir kalıp değildir; proje başında yolu seçin.

getContext başarısız olursa null döner — sessizce devam etmeyin. Özellikle gizli sekme, kurumsal politika veya eski gömülü tarayıcılarda 2D bile kapatılmış olabilir. Kullanıcıya yedek HTML içeriğini göstermek veya alternatif bir deneyim sunmak, «boş gri kutu»dan iyidir.

Modül ve type="module" kullanımı canvas oluşturmayı değiştirmez; önemli olan script'in DOM hazır olduktan sonra çalışması (DOMContentLoaded veya script'i öğenin altına koymak). Framework'lerde genelde useEffect / onMounted içinde ölçüm ve bağlam alınır — canvas henüz layout'ta yokken getBoundingClientRect ile boyut okumak yanıltıcı olabilir.

Birden fazla canvas ve katmanlama

Tek sayfada birden fazla canvas kullanmak normaldir: biri oyun dünyası, biri sabit HUD, biri arka plan paralaksı. Her canvas'ın kendi bitmap'i ve bağlamı vardır; bellek maliyeti toplanır. Üst üste bindirmek için genelde position: absolute ile aynı kapsayıcıda hizalarsınız; z-index hangi yüzeyin olayları alacağını etkiler.

Alternatif tek canvas + tüm katmanları her karede yeniden çizmektir — daha az bellek, daha fazla CPU işi. Hangi yolun uygun olduğu sahne karmaşıklığına bağlıdır; Holodepth'te «çok sayıda hareketli parça + statik arayüz» için çift canvas sık görülür. WebGL katmanı ile 2D HUD'u ayırmak da yaygın bir üretim kalıbıdır.

Güvenlik ve dış kaynak: kısa ön bilgi

Canvas'a çapraz kaynak (cross-origin) bir görüntü veya video çizdiğinizde bitmap kirlenmiş sayılabilir: getImageData, toDataURL gibi okuma işlemleri güvenlik nedeniyle hata verir. Bu, canvas «oluşturma»dan hemen sonraki konularda değil ama asset yüklerken kritiktir; ileride Image loading başlığında ayrıntılandırılacak.

Oluşturma aşamasında bilmeniz gereken: canvas bir veri yüzeyidir; içine ne koyarsanız o kurallara tabi olursunuz. Yerel dosya ve uzak CDN görsellerinde crossOrigin niteliğini bilinçli ayarlamak, sonradan «neden piksel okuyamıyorum?» sorusunu önler.

Three.js ve WebGL ile çakışmadan okumak

Çakışmayı önleyen çerçeve

Three.js projelerinde de sonuçta bir <canvas> görürsünüz; fakat boyut ve döngü çoğu zaman renderer tarafından yönetilir. Bu sayfadaki width/height disiplini, Three'te setSize ve setPixelRatio çağrılarının arkasındaki mantıkla aynı ailedendir. WebGL'de bağlamı siz açarsınız; Three'te soyutlanır — fakat bulanık canvas şikâyeti her iki dünyada da «bitmap ile görünen kutu eşleşmedi» anlamına gelir.

ByteOmi köprü içeriği Canvas vs WebGL karar vermenize yardım eder; bu sayfa ise «önce yüzeyi doğru kur» adımıdır.

  • Attribute boyutu hedef piksel çözünürlüğünüz mü?
  • CSS yalnızca sunum için mi, yanlışlıkla tek boyut kaynağı olarak mı kullanılıyor?
  • Yedek içerik ve aria-label düşünüldü mü?
  • Bağlam türü (2D / WebGL) proje başında seçildi mi?
  • Dispose / yeniden boyut ihtiyacı varsa resize sayfasına hazır mısınız?

Sıradaki: 2D rendering context

Yüzey ve boyut sözleşmesi netleştikten sonra çizim komutlarının dünyasına geçmek için 2D context sayfasına devam edebilirsiniz. Koordinat ekseni, durum yığını ve yeniden boyutlandırma sırası sonraki başlıklarda gelir.