HTML5 Canvas · Render döngüsü
Clear & redraw: piksel buffer’ını yenilemek
Canvas 2D yüzeyi, bellekte sabit boyutlu bir piksel ızgarasıdır — yeni bir
karede
eski çizimleri «üstüne boyamadan» önce hangi bölgeleri sileceğinize veya hangi arka planı
kuracağınıza karar verirsiniz. clearRect belirtilen dikdörtgende pikselleri
tam şeffaflığa döndürür; bu, sayfadaki düz renk CSS arka planının görünmesine
veya alt katman DOM öğelerinin etkisine yol açabilir. Bu sayfa, temizlemenin ne işe yaradığını,
tam yüzey ile kısmi temizlik ayrımını, opak zemin tercihini ve animasyon karesi içindeki sırayı
canvas üreticisi gözüyle sabitler.
Kare zamanlaması requestAnimationFrame ve Delta time konularında; bağlam dönüşümü ve kırpma State sistemi ile yönetilir — burada yalnızca piksel öncesi alanın nasıl sıfırlanacağı ön plandadır.
Özet: temizleme yolları
| Yöntem | Sonuç | Canvas’ta tipik kullanım |
|---|---|---|
clearRect |
Alan şeffaf olur (alfa 0) | Her kare tam sahne; parallax için transparan gökyüzü katmanı |
fillRect (tüm yüzey) |
Opak veya yarı saydam boya | Düz renk oyun zeminı; CSS arkası görünmez |
Kısmi clearRect |
Yalnız seçilen hücre temizlenir | Düşük maliyetli grafik güncellemesi, debug ızgarası |
| Boşluk: temizleme yok | Önceki kare pikselleri kalır | İz bırakan çizim, motion blur benzeri deney (bilinçli) |
Tam yüzey ve kısmi temizlik: ne siler, ne korunur
Temizlik komutu yalnızca hedeflediğiniz piksel alt örneklemini etkiler — yol nesnesi,
bağlam stili veya dönüşüm matrisi silinmez; bunlar
beginPath, save/restore veya açık özellik
atamalarıyla
ayrı yönetilir. Bu yüzden «sahneyi temizledim» dediğinizde kastınız çoğunlukla bitmap’i
sıfırlamaktır: geometri komutlarını tekrar vermek yine sizin görevinizdir.
Kısmi temizlik, büyük statik arka planı her karede yeniden çizmekten kaçınmak için kullanılır; fakat hareketli öğe eski piksel konumunu da terk ediyorsa, ya hareket alanını geniş bir dikdörtgende temizlersiniz ya da tam kare yenilersiniz — aksi halde eski çizimden piksel artığı («hayalet görüntü») kalır.
Global globalCompositeOperation ve globalAlpha aktifken
clearRect hâlâ hedef pikselleri şeffaflaştırır; yine de karışıklığı azaltmak
için
tam yüzey temizliğini çoğu projede nötr modda yapmak, hata ayıklamayı ve
bir sonraki çizim turunu öngörmeyi kolaylaştırır (
Composite · source-over kısa köprü).
clearRect sözleşmesi ve dönüşüm uzayı
clearRect(x, y, w, h) çağrısı geçerli dönüşüm matrisi altında
çalışır — önce translate/rotate/scale uyguladıysanız
temizlenen dikdörtgen ekranda dönmüş veya kaymış görünür. Tam yüzeyi ekran eksenine hizalı
silmek için temizlikten önce matrisi kimliğe çekmek veya ayrı bir save dalında
setTransform(1,0,0,1,0,0) kullanmak standart güvenli kalıptır.
Genişlik veya yükseklik negatifse dikdörtgen ters yönde büyür; bu, düzen hesaplarında
yararlı
olabilir fakat tam yüzey temizliğinde genelde pozitif width = canvas.width,
height = canvas.height ile çağrılır — boyutlar, CSS ile ölçeklenmiş görünse
bile
bağlamın dahili piksel boyutlarıdır (
Resize
mantığı
).
clearRect yolu açmaz; dolayısıyla hemen ardından gelen stroke
önceki path üzerinde beklenmedik segment üretmez — fakat path’i bilinçli sıfırlamıyorsanız
farklı modüller arasında sızıntı yaşanır (
Path
sistemi ).
/**
* Bağlam ölçüsünde tüm yüzeyi şeffaflaştırır. Dönüşümden bağımsız çalışır.
* canvas: HTMLCanvasElement, ctx: CanvasRenderingContext2D
*/
function clearFullSurface(ctx, canvas) {
ctx.save();
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.restore();
}
Şeffaf temizlik ve opak zemin seçimi
Her karede sadece clearRect kullanırsanız çizilmeyen pikseller şeffaf kalır;
tarayıcı tuvale, üstünde ve altında kalan katmanlarla birleştirir. Oyun dünyanız düz renkse,
bazen CSS’te background-color yeterli görünür — fakat canvas içinde üst üste
binmiş yarı saydam sprite’lar veya sonradan eklenen DOM overlay ile renk karışımı
beklediğiniz
gibi olmayabilir. Tam kontrol için çoğu ürün opak gövdeyi ilk iş olarak
fillRect ile kendisi boyar.
Yarı saydam zemin (rgba(..., 0.07) gibi) bilinçli «iz bırakma» efekti üretir —
bu, klasik temiz-redraw zincirinde sürpriz olabilir; ya tam şeffaf silip net yeniden çizin
ya
da iz efektini dokümante edin. İkisi birlikte yanlış sırada kullanılırsa arka planda eski
kareler birikir.
globalAlpha düşükken tam yüzey fillRect ile boyamak hâlâ her
piksele
biraz renk döşer; performans ve görsel beklenti ayrı ölçülür — alpha ile oynamayı state
dalına
kısıtlamak sızıntıyı azaltır.
function paintOpaqueBackdrop(ctx, canvas, cssColor) {
ctx.save();
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.globalAlpha = 1;
ctx.globalCompositeOperation = 'source-over';
ctx.fillStyle = cssColor;
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.restore();
}
Kirli bölgeler ve kısmi yeniden çizim
Tüm sahneyi sürekli çizmek yerine yalnız değişen dikdörtgenleri yenilemek, eski arcade ve
grafik editörü hissi veren klasik optimizasyondur. Şart: statik arka plan bir kez
üretilebilir
(arka tampon veya önbellekli bitmap) ve hareketli nesne dar bir kutuda kalır. Canvas’ta bu,
clearRect + sınırlı bölge için çizim komutları anlamına gelir; dünya geneli
karmaşıksa kirli kutu hesabı kod maliyeti tam boyama ile yarışabilir — ölçümle karar
verilir.
Karmaşık senaryoda bir önceki sprite dikdörtgenini ve yenisini birleştirip tek geniş
clearRect kullanmak, iki ayrı küçük temizlikten bazen daha verimli kompozit
yoluna
düşer. Parçacık sisleri gibi tüm yüzeyi bulanıklaştıran efektlerde bazı karelerde kısmi
temizlik
işe yaramaz; tam yenileme geri döner.
Kirli bölgeyi hesaplarken cihaz pikseli ve çizgi kalınlığını (stroke genişliği) unutmak, kenarlarda kirli piksel bırakır — minimum genişlik için tampon ( padding) eklemek yaygın düzeltmedir.
/**
* world-space içinde kirli kutuyu temizleyip yeniden çizer (örn. sprite).
* drawRegion: (ctx, rect) => void — çağıran sınırları bilir.
*/
function redrawRegion(ctx, rect, drawRegion) {
const pad = 2;
const x = Math.floor(rect.x - pad);
const y = Math.floor(rect.y - pad);
const w = Math.ceil(rect.w + pad * 2);
const h = Math.ceil(rect.h + pad * 2);
ctx.save();
ctx.clearRect(x, y, w, h);
drawRegion(ctx, { x, y, w, h });
ctx.restore();
}
Animasyon karesinde sıra ve atomik görünürlük
Tek bir requestAnimationFrame turunda kullanıcıya yansıyan bitmap, teorik olarak «o anın snapshot’ı»dır — bu yüzden önce temizlik / zemin, sonra dünya geometrisi ve en sonda HUD veya imleç katmanı gibi bir sözleşme çoğu ekipte çalışır. Ara durumda yarı çizilmiş sahneyi uzun süre ekranda bırakmak isterseniz bilinçli bir hata ayıklama modu olmalıdır; üretimde yarım kare kullanıcıya görünmemelidir.
Ağır çizimleri iki aşamada düşünmek yardımcıdır: dünya durumunu güncelle ( Delta time ile entegre), ardından tek geçişte çiz — çift tampon veya offscreen yüzey kullanıyorsanız ana tuvale aktarma adımı da aynı turun sonunda tamamlanır.
Özel birleştirme geçişleri (
lighter vb.) için kısa save/restore dalları, temel
zemin ve temizlikten sonra uygulanır; dal kapatılmazsa sonraki karenin temizliği
beklenmedik şeffaflık bırakır.
Resize, piksel yoğunluğu ve ilk boyama
Görüntü alanı yeniden boyutlandığında dahili canvas.width /
canvas.height ataması çoğu tarayıcıda içeriği sıfırlar veya tanımsız
hale getirir — pratikte tam sahneyi yeniden kurmanız gerekir. Bu olay,
genellikle
resize sonrası ilk rAF’ta veya ResizeObserver geri çağrısında opak zemin +
dünya
yeniden inşası ile çözülür.
devicePixelRatio ile iç piksel boyutu artırılıyorsa temizlik ve dolgu
dikdörtgeni hâlâ bağlamın width/height değerleriyle hizalanır; css
pikseli ile karıştırmamak için tek doğruluk kaynağı bağlam ölçüsünü seçin (
Resize
mantığı ).
İlk sayfa yüklemede bile boş canvas şeffaf olabilir; flaş önlemek için ilk boyamayı mümkün olduğunca erken veya boyut kesinleştikten hemen sonra planlayın — içerik yüklenene kadar düz renk yer tutucu yaygındır.
Anti-kalıplar: hayalet piksel ve sıra hataları
Dönüşümlü clearRect: Kimlik matrisine dönmeden tam yüzey sandığınız temizlik eksik kalır — en iyisi paylaşılan yardımcı fonksiyon kullanmak.
Kısmi temizlik + geniş hareket: İmgenin arkasında iz bırakırsınız; kirli kutu birleştirmeyi unutmayın.
clear yok, sürekli add: Bilinçli trail istemiyorsanız kare birikir; CPU ve görsel mantık bozulur.
Resize sonrası eski bitmap varsayımı: İçerik sıfırlandıktan sonra eski önbellekli görselleri çizmek hayalet sahne üretir.
Bu sayfanın sınırı
WebGL derinlik tamponu ve stencil «clear» komutları farklı API’dir; burada yalnızca CanvasRenderingContext2D bitmap temizliği ve yeniden çizim sırası anlatılmıştır.
OffscreenCanvas ve worker tarafı yüzey senkronizasyonu ayrı performans başlığıdır — bu sayfa ana belgede tek görünür canvas varsayar.
- Temizlik kimlik matrisinde ve doğru piksel boyutunda mı?
- Şeffaf mı opak zemin mi; CSS arka plana güveniliyor mu?
- Kısmi temizlikte hayalet piksel için kutu birleştirildi mi?
- Kare içinde dünya → HUD sırası atomik mi?
- Resize veya DPR değişiminde tam yeniden kuruldu mu?