HTML5 Canvas · Render döngüsü
requestAnimationFrame ile kare planlama
RequestAnimationFrame,
tarayıcıya «bir sonraki boyama ile hizalı bir an çalış» dersiniz — özellikle
Canvas 2D gibi raster yollarında her karede clearRect + geometri
+ stil ile yüzeyi yeniden kuruyorsanız fiilen üretim tetikleyiciniz budur.
Bu sayfa, zaman damgasını nasıl okuyacağınızı, döngüyü nasıl güvenle açıp kapatacağınızı ve
görünürlük / yenileme hızı yüzünden beklenen kare sıklığını nasıl modellediğinizi canvas
üreticisi gözünden sabitler; genel game loop mimarisinin tamamı burada
anlatılmaz.
Piksel düzenini sıfırlama ve katman sırası Clear & redraw konusunda; bağlam stili ve kırpma State sistemi ile yönetilir — burada yalnızca ne zaman çizim fonksiyonunuzun çağrılacağı ve o çağrıya hangi zaman verisinin eşlik edeceği ön plandadır.
Özet: rAF ve yakın alternatifler
| Yol | Canvas ile ilişki | Dikkat |
|---|---|---|
requestAnimationFrame |
Ekran yenilemesiyle uyumlu kare; çoğu animasyonlu canvas için varsayılan | Sekme gizliyken sıklık düşer veya durur; tek başına iş garantisi vermez |
setInterval / setTimeout |
Sabit ms ile mantık güncellemesi; çizim hâlâ rAF ile senkronlamak iyidir | Görünür olmayan sekmede bile çalışabilir; pil ve CPU israfı |
| Tek seferlik çizim (olay tetikli) | Statik grafik veya kullanıcı etkileşimi sonrası tek draw |
Sürekli hareket için rAF veya benzeri zamanlama gerekir |
Tarayıcı zamanlayıcısı ve piksel tazeliği
Canvas hedefiniz ekranda olduğu sürece, kullanıcı hareketli bir gözlenti bekler — yeni kare
üretmeden önceki pikseller ekranda kalır. rAF, bu «tazelik» talebini tarayıcının ana
döngüsüne
bağlar: geri çağrınız genelde düzenleme ve boyama aşamalarına yakın çalışır, böylece
drawImage, yol doldurma ve stil güncellemeleri tek bir görsel atımında
toplanır.
Bu, ekran kartını sürekli kullanmama sözü değildir; yoğun çizim hâlâ GPU / kompozitör
maliyetini taşır. rAF’ın vaadi karelerin görüntüleme ritmiyle çarpışmama
ve gereksiz boş döngüleri azaltma eğilimidir — özellikle setInterval(16) ile
iki kez örnekleyip yarım kare gecikmesi yaratmaktan daha öngörülebilir bir tablo sunar.
Offscreen canvas veya transferControlToOffscreen senaryolarında
ana ileti dizisi hâlâ görünür yüzeyi sunar; worker tarafı ayrı planlanır — bu sayfada odak,
ana belgede çalışan klasik 2D bağlamındaki rAF kullanımıdır.
Callback, zaman damgası ve cancelAnimationFrame
requestAnimationFrame(callback) size bir kimlik döner; aynı
geri çağrı içinde veya durdurmak istediğiniz anda cancelAnimationFrame(id)
ile plan iptal edilir. Kimliği kaybetmek, uygulama yaşam döngüsünde (ör. rota değişimi,
bileşen unmount) «hayalet kare» bırakmanın yaygın nedenidir.
Tarayıcı, geri çağrınıza genelde DOM yüksek çözünürlüklü zaman damgası
(DOMHighResTimeStamp) iletir; bu değer milisaniye cinsinden monotonik bir
süredir ve kareler arası farkı alarak delta üretmek için uygundur. Tarih
nesnesi (Date.now) ile karıştırmayın — görsel simülasyon için monotonik süre
daha güvenilirdir.
Tek bir dizi içinde birden fazla kez rAF planlamak mümkündür fakat çoğu canvas uygulaması
tek aktif planlayıcı desenini seçer: dış döngü fonksiyonu sonunda yalnızca
bir requestAnimationFrame(loop) çağrısı; içeride o kareye özel çizim ve mantık.
Böylece eşzamanlı iki planlı döngü yarışı önlenir.
function startCanvasLoop(ctx, step) {
let rafId = 0;
let prev = 0;
const loop = (now) => {
const dt = prev ? (now - prev) / 1000 : 0;
prev = now;
step(ctx, dt, now);
rafId = requestAnimationFrame(loop);
};
return {
start() {
cancelAnimationFrame(rafId);
prev = 0;
rafId = requestAnimationFrame(loop);
},
stop() {
cancelAnimationFrame(rafId);
rafId = 0;
prev = 0;
},
};
}
Görünürlük ile kare sıklığı
Sekme arka planda veya pencere minimize olduğunda tarayıcı geri çağrınızı seyreltir veya durdurabilir; bu, canvas tabanlı oyun veya veri grafiği için pil dostu davranıştır; fakat simülasyonun «gerçek zamanlı» ilerlemesi gerekiyorsa mantıksal saati rAF dışında da ilerletmek (ör. ağ veya fizik düğümü) ayrı bir mimari karar olur — burada yalnızca çizimin sekme durumuna bağlı yavaşladığını hatırlatırız.
document.visibilityState ve visibilitychange olayı ile kullanıcı
arayüzünüzü dondurabilir, kare sayacını sıfırlayabilir veya ilk görünür olduğunuz karede
tek seferlik tam yeniden çizim planlayabilirsiniz. İlk karede ani sıçrama yaşamamak için
prev zaman damgasını sıfırlamak sık kullanılır.
Variable refresh rate (VRR) ve display
özellikleri cihaza göre değişir; 60 fps varsayımı artık evrensel değildir — delta tabanlı
hareket kodu, sabit 1/60 çarpanına göre daha az titreşim üretir.
Delta süre ve animasyon adımı
İlk geri çağrıda delta sıfır veya tanımsız kabul edilir; ikinci kareden
itibaren
now - prev farkı ölçeklenerek saniye cinsinden adım süresi elde edilir. Canvas
üzerinde yörünge, yayılma veya parçacık konumunu her karede += hız * dt
biçiminde
güncellemek, kare hızı 30 ile 120 arasında salındığında bile yaklaşık aynı fiziksel hızı
korur.
Uzun bir sekme donmasından sonra delta büyük gelebilir; simülasyonu patlatmamak
için üst sınır (
clamp) uygulamak interaktif canvaslarda yerleşik bir uygulamadır —
değer
seçimi oyun hissi ile ölçülür, API tarafında zorunlu kural yoktur.
rAF geri çağrısı içinde ağır senkron iş yükü (büyük JSON ayrıştırma, bloklayıcı döngü) ana iş parçacığını kilitleyip hem çizimi hem giriş olaylarını geciktirdiğinden, veri hazırlığını mümkün olduğunca kareden önce veya asenkron kanallara itmek canvas akıcılığı için aynı önemdedir; konu worker / mesajlaşma ayrıntısı bu sayfanın sınırı dışındadır.
Başlatma, durdurma ve tek planlayıcı kimliği
Aynı canvas’ı birden fazla modül «sahipleniyorsa» çift rAF zinciri oluşur; bu, aynı piksel yığınının iki kez temizlenmesi veya stil sızdırması gibi hatalara yol açar. Çözüm: tek bir orkestrasyon katmanında kare planlayın, alt sistemler yalnızca kare başına bir kez çağrılan arayüz fonksiyonları sunsun.
start çağrısından önce varsa eski kimliği iptal etmek, React / Vue gibi
çerçevelerde bileşen yeniden bağlandığında üst üste binen döngüleri engeller. Kütüphane
yazıyorsanız «açık döngü bırakmama» sözleşmesini belgeleyin.
Olay dinleyicisi içinde (ör. fare ile sürükleme) her hareket anında tam sahne çizmek yerine bazen yalnızca bir «kirli bayrağı» kaldırıp rAF içinde tekilleştirilmiş çizim yapmak, aynı karede onlarca çağrıyı tek composite yoluna indirger — bu desen hem girdi gecikmesini hem de işlemcinin gereksiz tekrarını azaltır.
Temizleme ve yeniden çizim sırası
Tipik animasyon karesi: arka planı temizle veya opak zemin çiz → dünya geometrisini çiz → HUD / ölçüm katmanını çiz. rAF geri çağrınız, bu sırayı tek bir atomik «görünür kare» halinde tamamlamalıdır; yarım bırakılmış ara durumları kullanıcı görmemelidir.
Boyut değişimi (geri çağrı dışında) piksel ölçeğini etkiler — resize sonrası ilk rAF
çağrısında tam yeniden kurulum sık pattern’dir (
Resize
mantığı
). Temizlik stratejisi (clearRect mi, tuvale dolgu mu) ayrıntısı
Clear & redraw sayfasında
tutulur; burada yalnızca «rAF içinde tek geçişte bitirin» kuralı özetlenir.
Çift tampon veya offscreen birleşimi kullanıyorsanız, ana yüzeye yapıştırma çağrısı da aynı karede tamamlanmalıdır; aksi halde ara karede eski ve yeni bitmap karışımı bir anlık görünür.
Anti-kalıplar: döngü ve zamanlama
rAF + setInterval çift motor: İki kaynak zamanı birleştirmeden aynı canvas’a yazmak yarış durumu üretir — ya tek motor seçin ya da biri yalnızca mantık, diğeri yalnızca çizim olsun ve sözleşmeyi yazın.
İptal atlamak: Bileşen yok olduğunda planlı geri çağrı devam ederse bellek ve hata konsolu «ghost» üretir; kimliği her zaman saklayın.
Sabit fps varsayımı: Kodda 1/60 sakızlamak, yüksek yenilemeli
ekranda yavaşlama, düşük yenilemede ise adım atlama hissi verir — tercihen ölçülen delta.
Aynı karede onlarca çizim: Olay fırtınası sırasında doğrudan
draw
çağırmak yerine kare içinde birleştirme (
§5 ) düşük gecikmeli his verir.
Bu sayfanın sınırı
WebGL veya WebGPU komut kuyruğu, tarayıcının kendi kare zamanlamasından farklı katmanlarda çalışabilir; burada anlatılan sözleşme özellikle CanvasRenderingContext2D ve ana iş parçacığında çalışan görsel güncelleme için yazılmıştır.
Ses zamanlaması (Web Audio), ağ gecikmesi ve sunucu otoritesi gibi konular sahne saati ile çakışabilir; tek bir rAF geri çağrısı tüm sistemin hakemliği değildir — yalnızca görüntü üretim zamanı için güçlü bir kancadır.
- Kare planlayıcı kimliği saklanıyor ve durumda iptal ediliyor mu?
deltailk kare ve uzun duraklamadan sonra sınırlanıyor mu?- Sekme gizliyken mantık ile çizim aynı varsayımla mı ilerliyor?
- Aynı yüzeye birden fazla bağımsız rAF zinciri var mı?
- Tek karede çizim atomik tamamlanıyor mu (yarım ara durum yok)?