Aplikasi menggambar berbasis stilus yang dibangun untuk web telah lama mengalami masalah latensi karena halaman web harus menyinkronkan update grafis dengan DOM. Dalam aplikasi gambar apa pun, latensi yang lebih lama dari 50 milidetik dapat mengganggu koordinasi tangan-mata pengguna, sehingga sulit untuk digunakan.
Petunjuk desynchronized
untuk canvas.getContext()
memanggil jalur kode berbeda yang mengabaikan mekanisme pembaruan DOM biasa.
Sebagai gantinya, petunjuk memberi tahu sistem dasar untuk melewati pengomposisian sebanyak
yang dapat dilakukannya dan dalam beberapa kasus, buffer dasar kanvas akan dikirim langsung ke
pengontrol tampilan layar. Tindakan ini akan menghilangkan latensi yang akan disebabkan oleh penggunaan antrean perender compositor.
Seberapa bagus produk tersebut?
Jika Anda ingin sampai ke kodenya, scroll ke depan. Untuk melihatnya cara kerjanya, Anda memerlukan perangkat dengan layar sentuh, dan sebaiknya stilus. (Jari jari juga bisa.) Jika Anda memilikinya, coba sampel 2d atau webgl. Untuk Anda yang lainnya, lihat demo oleh Miguel Casas ini, salah satu engineer yang menerapkan fitur ini. Buka demo, tekan putar, lalu gerakkan {i>slider<i} bolak-balik secara acak dan cepat.
Contoh ini menggunakan klip berdurasi satu menit dua puluh satu detik dari film pendek
Sintel karya Durian, project film
terbuka Blender. Dalam contoh ini, film diputar di elemen <video>
yang
kontennya dirender secara bersamaan ke elemen <canvas>
. Banyak perangkat dapat
melakukannya tanpa menimbulkan kerusakan, meskipun perangkat dengan rendering buffer depan seperti
ChromeOS misalnya, mungkin mengalami kerusakan. (Filmnya bagus, tapi patah hati.
Aku tidak berguna selama satu jam setelah melihatnya. Anggap diri Anda sudah diberi peringatan.)
Menggunakan petunjuk
Ada lebih banyak hal dalam menggunakan latensi rendah daripada menambahkan desynchronized
ke
canvas.getContext()
. Saya akan membahas
masalah ini satu per satu.
Membuat kanvas
Di API lain saya akan membahas deteksi fitur terlebih dahulu. Untuk petunjuk desynchronized
,
Anda harus membuat kanvas terlebih dahulu. Panggil canvas.getContext()
dan teruskan
petunjuk desynchronized
baru dengan nilai true
.
const canvas = document.querySelector('myCanvas');
const ctx = canvas.getContext('2d', {
desynchronized: true,
// Other options. See below.
});
Deteksi fitur
Selanjutnya, panggil getContextAttributes()
. Jika objek atribut yang ditampilkan memiliki
properti desynchronized
, ujilah.
if (ctx.getContextAttributes().desynchronized) {
console.log('Low latency canvas supported. Yay!');
} else {
console.log('Low latency canvas not supported. Boo!');
}
Menghindari kedipan
Ada dua kasus yang dapat menyebabkan Anda berkedip jika tidak membuat kode dengan benar.
Beberapa browser termasuk Chrome menghapus kanvas WebGL di antara frame. Pengontrol tampilan
dapat membaca buffer saat kosong yang menyebabkan
gambar digambar berkedip. Untuk menghindari hal ini, tetapkan
preserveDrawingBuffer
ke true
.
const canvas = document.querySelector('myCanvas');
const ctx = canvas.getContext('webgl', {
desynchronized: true,
preserveDrawingBuffer: true
});
Flicker juga dapat terjadi saat Anda menghapus konteks layar dalam kode gambar Anda sendiri. Jika Anda harus menghapus, gambar ke framebuffer offscreen, lalu salin ke layar.
Saluran alfa
Elemen kanvas transparan, dengan alfa yang disetel ke benar (true), masih dapat didesinkronisasi, tetapi tidak boleh memiliki elemen DOM lain di atasnya.
Hanya boleh ada satu
Anda tidak dapat mengubah atribut konteks setelah panggilan pertama ke
canvas.getContext()
. Hal ini selalu benar, tetapi mengulanginya dapat
menghilangkan rasa frustrasi jika Anda tidak menyadarinya atau lupa .
Misalnya, saya mendapatkan konteks dan menetapkan alfa sebagai false, lalu
di suatu tempat dalam kode saya, saya akan memanggil canvas.getContext()
untuk kedua kalinya dengan alfa
ditetapkan ke true seperti yang ditunjukkan di bawah ini.
const canvas = document.querySelector('myCanvas');
const ctx1 = canvas.getContext('2d', {
alpha: false,
desynchronized: true,
});
//Some time later, in another corner of code.
const ctx2 = canvas.getContext('2d', {
alpha: true,
desynchronized: true,
});
Tidak jelas bahwa ctx1
dan ctx2
adalah objek yang sama. Alfa masih salah dan
konteks dengan alfa yang sama dengan benar tidak akan pernah dibuat.
Jenis kanvas yang didukung
Parameter pertama yang diteruskan ke getContext()
adalah contextType
. Jika Anda
sudah terbiasa dengan getContext()
, Anda pasti bertanya-tanya apakah ada
hal lain selain jenis konteks '2d' yang didukung. Tabel di bawah menunjukkan jenis konteks
yang mendukung desynchronized
.
contextType | Objek jenis konteks |
---|---|
|
|
|
|
|
|
Kesimpulan
Jika Anda ingin melihat lebih banyak lagi, lihat contohnya. Selain contoh video yang sudah dijelaskan ada contoh yang menampilkan konteks '2d' dan 'webgl'.