holodepth

HTML5 Canvas · Çizim & path

Composite operations: globalCompositeOperation ve katman birleştirme

Canvas 2D’de her çizim komutu — fill, stroke, drawImage — mevcut bitmap ile kaynak rengini işleme sokar; globalCompositeOperation bu işlemin hangi formülle yapılacağını belirler. Varsayılan source-over yeni pikseli hedefin üstüne yığar; diğer modlar çarpma, ekranlama, maskeleme veya silgi etkisi üretir. Bu sayfa mod ailelerini, çizim sırasının önemini ve üretimde save/restore ile izolasyonu canvas üreticisi gözüyle sabitler — WebGL blend state tablosunun web karşılığıdır.

Şeffaflık çarpanı State · alpha ile birlikte okunur; dolgu/kontur renkleri Stroke vs fill sayfasındadır. Geometri ve path Path sistemi ile kurulur — burada yalnızca piksel birleştirme mantığıdır.

Özet: Kompozit mod aileleri

Aile Örnek modlar Sezgisel etki
Normal üst üste source-over (varsayılan) Üst katman altta kalanı örter
Karanlık / aydınlık multiply, screen, overlay Renk kanalları birbirini çarpar veya güçlendirir
Eklemsel lighter (veya plus-lighter — tarayıcı) Işık toplanır, parlaklık artar
Maske / damga source-in, destination-in, source-atop Neresi görünür / silinir seçilir
Özel xor, copy XOR maske; kopya — hedefi yok sayar

Hedef ve kaynak: bitmap birleştirme modeli

Tek bir çizim adımında tarayıcı, çizim öncesi frame buffer’daki pikselleri hedef (destination) sayar; o anda üretilen kaynak pikselini kaynak (source) sayar. globalCompositeOperation bu ikisini hangi Porter-Duff benzeri kurala göre harmanlayacağını seçer — W3C spesifikasyonunda sabit isimler listelenir; tarayıcılar tam küme ve eşanlamlıları destekler.

Zihinsel model: Photoshop katman modu ile benzer, fakat katman nesnesi yoktur; her stroke bir «anlık fırça»: modu değiştirip unutursanız sonraki tüm fırçalar yanlış modda çalışır. Bu yüzden mod değişimi kısa ömürlü bir save/restore dalına sık sık tıkanır.

drawImage özel bir kaynakdır: görüntü pikseli doğrudan birleştirilir — mod, görüntünün şeffaf alanlarının hedefle nasıl etkileşeceğini de değiştirir. Video veya offscreen yüzey aynı mantıktadır.

Source-over: varsayılan ve tanıdık üst üste bindirme

Varsayılan source-over, kaynak rengi hedefin üstüne koyar; kaynak opaklığına göre alt katman «gösterilir». Çoğu oyun ve ara yüz tekniği bu modda çalışır farkında olmadan — başka mod denemeden önce bağlamın gerçekten buna döndüğünü doğrulamak iyi pratiktir.

Kare başında globalCompositeOperation = 'source-over' ayarlamak, önceki kareden taşınan sızıntı olasılığını azaltır — tam çözüm yine yığın disiplinidir ( §9 ).

Kaynak pikseli önceden çarpılmış alfa ( premultiplied) ile işlenir; yarı saydam kenarlarda beklenmedik gri halo birleşimi bazen mod değişiminde değil, renk + alfa kaynağında kökenlidir — özellikle düşük bit PNG veya video karesi çekerken drawImage sonrası üst üste lighter ile test edin.

Ters yığına «alta yazma» için destination-over kullanılır; nadir düzenlerde üstte zaten çizilmiş katmanın altına yeni bir leke yerleştirmek isterseniz sıra ve mod birlikte planlanır — çoğu sahne yine çağrı sırasını değiştirip source-over ile çözer.

Çizim sırası: altta ne kaldı, üstte ne bindi?

Kompozit işlem, anında uygulanır: önce arka planı boyayıp üstüne parlayan sprite çizerseniz lighter kullanmak tüm alt katmanı nötralize edebilir — çoğu vaka için önce normal katmanlar source-over, en sonda dar bir dalda özel mod tercih edilir.

Derinlik sırası yoktur; «z-index» yoktur. Derinlik illüzyonu yalnızca çağrı sıranızla üretilir. UI overlay dünya çiziminden sonra gelmelidir; parçacık ışıması dünya üstünde ama HUD altında kalacaksa sıra ve mod ayrı planlanır.

Bu sıra düşüncesi Clear & redraw ile birleşir: önce tamamını temizle veya arka planı çiz, sonra katman katman ilerle.

Zihinsel «iki geçişli» düzen sık kullanılır: birinci geçiş zemin + varlıklar ( source-over); ikinci geçiş yalnızca emissive / blend özeti ( §5 ). Tek geçişte modu her çizimde saldırmak, hem okunabilirliği hem profil izini kötüleştirir.

Kısmi kirli dikdörtgen ( dirty rect) optimizasyonu kullanıyorsanız hangi modların yalnızca o bölgeye güvenle uygulanabildiğini önceden kabul edin — global blend geçmişi taşıyan modlarda kısmi yeniden çizim, tam kare compositing ile aynı sonucu vermeyebilir.

Multiply, screen ve karanlık/aydınlık mod aileleri

multiply kanalları çarparak koyulaştırır — gölgelendirme ve kağıt dokusu üst üste bindirmede tanıdıktır. screen ters yönde aydınlatır; arka planı yıpratmadan «ışık lekesi» eklemek için kullanılır. overlay, soft-light, hard-light gibi modlar orta tonları koruyarak kontrast oynaması yapar — tema başına «tek mod seç, tutarlı kullan» kuralı şaşmayı azaltır.

Bu modlar renk doğrusallığından uzak olabilir; HDR hissi ararken banding ve doygunluk taşması görülebilir — tasarım önizlemesi üretim verisiyle aynı modda yapılmalıdır.

multiply’da beyaz kaynak nötrdir (altı fazla değiştirmez); screen’de siyah kaynak nötrdir — baz katman renginiz çok açık veya çok koyu ise etki «çalışmıyor»muş gibi görünür; önce ton eşitlemesi yapın. color-burn, color-dodge gibi ekstrem modlar uçları sıkıştırır; abartılı sonuçlar için kısa denemeler, üretimde mümkünse yumuşak alternatif.

Lighter ve eklemsel parlama: ışık üst üste binmesi

lighter (ve bazı motorlarda plus-lighter / screen aile yakını varyantlar) kaynak ve hedef renk bileşenlerini toplar — parlama, lazer, mermi izi ve yoğun partikül için sık seçilir. Aşırı parlaklık kanal taşmasıyla beyaza blurlanır; birkaç üst üste çizim tüm sahneyi «yıkabilir».

Bu yüzden efekt save → globalCompositeOperation = 'lighter' → dar geometri → restore ile kısılan bir dalda tutulmalıdır; dışarı çıkışta yine source-over varsayımı garanti edilir.

Yoğun parçacık için emissive sprite’ları atlas üzerinde ayrı kanal gibi düşünmek ve sahneye tek additive geçiş olarak çizmek, yüzlerce küçük sprite’ı her birinde mod çevirmekten daha öngörülebilir olabilir — atlas detayı Şekil · performans ile ilgili olsa da blend geçiş sayısı burada kritik tekrardır.

function drawGlowPass(ctx, drawEmissive) {
  ctx.save();
  ctx.globalCompositeOperation = 'lighter';
  ctx.globalAlpha = Math.min(1, ctx.globalAlpha * 0.45);
  drawEmissive(ctx);
  ctx.restore();
}

Source-in, destination-in ve mask benzeri damgalama

source-in kaynağı yalnızca hedefin opak bölgesiyle kesiştirir — maske damgalama gibidir. destination-in hedefi kaynağın alfa maskesiyle budar. source-atop kaynağı hedefin üstüne yazar fakat hedefin dışına taşmaz. UI’da yuvarlak portre içine fotoğraf sığdırmak veya seçili bölgeye renk tuzlamak için kullanılır.

Bu modlar clip() ile akrabadır fakat piksel düzeyinde farklıdır: clip bağlam durumunda kalır ( State · clip ), kompozit mod ise her vuruşta yeniden hesaplanır. Maske için hangi yol daha okunaklıysa ekibin sözleşmesine yazın.

Sıra önemlidir: önce maske geometrisini opak biçimde çizmek, sonra görüntüyü source-in ile geçirmek yaygın akıştır; tersine önce görüntü sonra mod, hedef alfa dağılımı beklentinizden farklı olur. Hedef tam şeffaf bölgelerde source-in sonucu görünmez — alttaki katmanı opak bir «kart zemin» olarak hazırlayın.

destination-in ile hedefi budadıktan sonra tekrar source-over ile üst rötuşları çizmek, çok adımlı ama izlenebilir bir «kilitli katman» oluşturur; ara adımlarda mod sızıntısı olmaması için §9 disiplinini koruyun.

Destination-out, xor ve copy: silgi ile ayıklama

destination-out kaynağın alfasıyla hedeften siler — yumuşak fırça silgi veya delik açma için kullanılır. Tam silgi için kaynak rengi genelde opak beyaz bile olabilir; önemli olan şeklin alfa dağılımıdır.

xor kesişim dışını tutar — seçim önizlemesi ve bazı debug overlay tekniklerinde görülür. copy hedefi yok sayıp kaynağı aynen yazar; çoğu üretim kodunda nadirdir, fakat bazı temizleme / doldurma senaryolarında farkı anlamak hata ayıklamayı hızlandırır.

copy ile clearRect / dolgu ile yapılan temizlik aynı sonucu vermez; biri pikseli kompozit kuralıyla yazar, diğeri buffer’ı şeffaflaştırır — hangi davranışın üst katmanlar için doğru olduğunu dokümante edin ( Clear & redraw ).

xor anti-alias kenarlarda beklenmedik ince çizgiler üretebilir; seçim aracı prototiplerinde önce düşük çözünürlükte deneyin, piksel ızgarasına kilitleme gerekebilir.

GlobalAlpha: birleştirme öncesi çarpan

globalAlpha birleştirmeye girmeden önce kaynak opaklığını ölçekler — düşük alfa ile multiply hafif gölgelik, lighter hafif ışık üflemesi üretir. Alfa ve mod birlikte bağlamda kalır; dal kapatılmazsa UI metni soluk kalır.

Opaklık hem dolgu hem görüntü çizimine uygulanır; katman bazlı farklı alfa istiyorsanız ya dal ya da komut öncesi manuel renk alfası gerekir ( Stroke vs fill · stil ).

rgba(...) içindeki alfa ile globalAlpha çarpılır; çift yarı saydamlık beklediğinizden daha soluk sonuç verir — solma animasyonunda hangi kolun sorumlu olduğunu tek yerde toplamak kodu sadeleştirir.

Özel mod + düşük globalAlpha bazen görsel olarak «hiç uygulanmıyor» gibi görünür; önce modu sabitleyip sonra alfayı ayırmak karşılaştırmayı kolaylaştırır.

Save ve restore: mod ve alfa sızıntısını kesmek

save() anlık bağlamın kompozit modunu da yığına alır; restore() önceki moda döner — bu, partikül, ışık ve özel blend katmanlarını güvenle izole etmenin standart yoludur. Uzun ömürlü mod değişimleri ekip içi kodlarda «hayalet blend» üretir.

Kütüphane yazıyorsanız «bu fonksiyon varsayılan modda çizer» taahhüdü veya giriş/çıkışta save/restore şarttır — reklam panosu State · anti-kalıplar ile örtüşür.

Erken return içeren çizim fonksiyonlarında restore’un finally bloğunda çağrılması yığın bütünlüğünü korur — mod sızıntısı sessizce birikir; konsola hata düşmez.

Mod dizesi yazım hatası ('lightre' gibi) tarayıcıda yine geçerli bir varsayılan veya sessiz düşüş üretebilir; kritik sahne başında sabit bir whitelist ile doğrulama üretim güvenliği sağlar.

Performans: mod değişimi ve dolgu maliyeti

Bazı modlar GPU yolunda ek okuma gerektirir; özellikle tam ekran + karma mod + her piksel gölge zinciri düşük cihazlarda düşüş gösterebilir. Profilde mod değişim sayısını azaltmak — aynı modda gruplanmış çizimler — sık kazanımdır.

Offscreen küçük buffer’da efekt uygulayıp sonra source-over ile ana yüzeye yapıştırmak, ana sahne üzerinde onlarca mod salınımından bazen daha ucuzdur — mimari tercih, bu sayfanın sınırı dışında kısa hatırlatma olarak not edilir.

Büyük canvas’ta blend yoğunluğu mobilde termal baskı ve gaz kesimi (throttle) ile birleşebilir; aynı estetiği düşük çözünürlüklü offscreen geçişle ve son büyütme ile yaklaşmak bazen kabul edilir — kalite vektörünü dokümante edin.

CPU profili getImageData ile birleştiğinde her kare okuma — birleştirme maliyetinden ayrı — bütçeyi deler; piksel okuma konuları bu sayfada yalnızca «blend ile birlikte planlayın» uyarısı olarak kalır.

Anti-kalıplar: kalıcı lighter ve gölgeli karmaşa

Modu değiştirip restore atlamak: Sonraki tüm sahne yanlış birleşir — dalı kapat veya kare başında source-over sıfırla.

Altta kalanı beklemeden multiply: Karanlık mod arka planı beklenenden çok yakar — sıra ve baz renk planı şart.

destination-out ile yanlış alfa: Yarı saydam silgi beklenmedik «hayalet» bırakır — maske geometrisi ve alfa birlikte test edilir.

Gölge + özel mod: Gölge üretimi ek bir birleştirme yoludur; State · alpha dalı ile sınırlamak okunabilirliği korur.

CSS mix-blend-mode ile karıştırmak: DOM üzerindeki karışım, canvas içi globalCompositeOperation ile aynı formül tablosuna sahip değildir — tasarımı tek dünyada kilitleyin.

Tek mod ile tüm sahneyi kurtarmak: Birleştirme kötü kontrastı veya renk seçimini düzeltmez; kök neden hâlâ sahne planı ve palettir.

Bu sayfanın sınırı

WebGL ve Three.js blend denklemleri ayrı API ve shader dünyasıdır. PDF baskı ve CMYK renk uzayı canvas ekran RGBA modelinden farklıdır — baskı önizlemesi için renk yönetimi ayrı konudur. Burada yalnızca HTML5 Canvas 2D globalCompositeOperation ve globalAlpha birlikte düşünülür.

Tarayıcı sürümleri arasında nadiren eşanlamlı mod adları veya kenar davranışı farkı olabilir; kritik görsel sözleşmeleri hedef platformlarda canlı örnek ile doğrulamak, spesifikasyon tablosunu ezberlemekten pratikte önce gelir — yine de kaynak gerçeği W3C / uygulama notlarıdır.

  • Bu çizim dalı hangi modda bitti?
  • Efekt tüm sahneyi mi yoksa küçük bölgeyi mi etkilemeliydi?
  • restore mod + alfa + clip üçlüsünü geri aldı mı?
  • Mod adı whitelist’te mi; yazım hatası sessiz kaldı mı?
  • CSS blend ile canvas blend aynı varsayıldı mı?

Sıradaki: kare döngüsü ve sürekli sahne

Birleştirme efektleri tek karede uygulanır; sürekli sahne için Clear & redraw ve zamanlama requestAnimationFrame sayfalarına geçilir. Önceki adımlar: Eğri mantığı, Stroke vs fill.