वेब के लिए बनाए गए, स्टाइलस पर काम करने वाले ड्रॉइंग ऐप्लिकेशन में, लंबे समय से इंतज़ार की समस्याएं आ रही हैं. इसकी वजह यह है कि वेब पेज को ग्राफ़िक अपडेट को डीओएम के साथ सिंक करना पड़ता है. किसी भी ड्रॉइंग ऐप्लिकेशन में, 50 मिलीसेकंड से ज़्यादा इंतज़ार का समय, उपयोगकर्ता के हाथ-आंख के तालमेल में रुकावट डाल सकता है. इससे ऐप्लिकेशन का इस्तेमाल करना मुश्किल हो जाता है.
canvas.getContext()
के लिए desynchronized
हिंट, एक अलग कोड पाथ को ट्रिगर करता है. यह सामान्य DOM अपडेट करने के तरीके को बायपास करता है.
इसके बजाय, हिंट, सिस्टम को कम से कम कॉम्पोज़ करने के लिए कहता है. कुछ मामलों में, कैनवस के बुफ़र को सीधे स्क्रीन के डिसप्ले कंट्रोलर पर भेजा जाता है. इससे रेंडरर कंपोजिटर की सूची का इस्तेमाल करने से होने वाली देरी को खत्म किया जा सकता है.
यह कितना अच्छा है?
अगर आपको कोड देखना है, तो आगे स्क्रोल करें. इसे इस्तेमाल करने के लिए, आपके पास टच स्क्रीन वाला डिवाइस और स्टाइलस होना चाहिए. (उंगलियों से भी काम किया जा सकता है.) अगर आपके पास ऐसा डिवाइस है, तो 2d या webgl सैंपल आज़माएं. बाकी लोगों के लिए, मिगुएल कैसस का यह डेमो देखें. वह इस सुविधा को लागू करने वाले इंजीनियरों में से एक हैं. डेमो खोलें और चलाएं बटन दबाएं. इसके बाद, स्लाइडर को तेज़ी से और रैंडम तरीके से आगे-पीछे करें.
इस उदाहरण में, Blender के ओपन मूवी प्रोजेक्ट, Durian की शॉर्ट फ़िल्म Sintel की एक मिनट, बीस-एक सेकंड की क्लिप का इस्तेमाल किया गया है. इस उदाहरण में, फ़िल्म को <video>
एलिमेंट में चलाया गया है, जिसका कॉन्टेंट एक साथ <canvas>
एलिमेंट में रेंडर किया जाता है. कई डिवाइस, स्क्रीन पर फ़्रेम बदलने के दौरान, फ़्रेम के बीच में रुकावट आने की समस्या के बिना ऐसा कर सकते हैं. हालांकि, ChromeOS जैसे फ़्रंट बफ़र रेंडरिंग वाले डिवाइसों में, फ़्रेम के बीच में रुकावट आने की समस्या आ सकती है. (फ़िल्म शानदार है, लेकिन दिल दहलाने वाली है.
इसे देखने के बाद, मैं एक घंटे तक कुछ नहीं कर पाया. आपको चेतावनी दी जा रही है.)
हिंट का इस्तेमाल करना
desynchronized
को canvas.getContext()
में जोड़ने के अलावा, इंतज़ार का समय कम करने के और भी तरीके हैं. मैं एक-एक करके समस्याओं के बारे में बताऊंगा.
कैनवस बनाना
किसी दूसरे एपीआई के लिए, मैं सबसे पहले सुविधा का पता लगाने के बारे में बात करूंगा. desynchronized
सलाह पाने के लिए, आपको पहले कैनवस बनाना होगा. canvas.getContext()
को कॉल करें और उसे true
की वैल्यू के साथ नया desynchronized
हिंट पास करें.
const canvas = document.querySelector('myCanvas');
const ctx = canvas.getContext('2d', {
desynchronized: true,
// Other options. See below.
});
फ़ीचर का पता लगाना
इसके बाद, getContextAttributes()
पर कॉल करें. अगर दिखाए गए एट्रिब्यूट ऑब्जेक्ट में desynchronized
प्रॉपर्टी है, तो उसकी जांच करें.
if (ctx.getContextAttributes().desynchronized) {
console.log('Low latency canvas supported. Yay!');
} else {
console.log('Low latency canvas not supported. Boo!');
}
फ़्लिकर से बचना
कोड को सही तरीके से न लिखने पर, दो स्थितियों में फ़्लिकर हो सकता है.
Chrome के साथ-साथ कुछ अन्य ब्राउज़र, फ़्रेम के बीच WebGL कैनवस मिटा देते हैं. डिसप्ले कंट्रोलर, खाली बफ़र को पढ़ सकता है. इससे, इमेज फ़्लिकर कर सकती है. इससे बचने के लिए, preserveDrawingBuffer
को true
पर सेट करें.
const canvas = document.querySelector('myCanvas');
const ctx = canvas.getContext('webgl', {
desynchronized: true,
preserveDrawingBuffer: true
});
अपने ड्रॉइंग कोड में स्क्रीन कॉन्टेक्स्ट मिटाने पर भी फ़्लिकर हो सकता है. अगर आपको स्क्रीन को साफ़ करना है, तो ऑफ़स्क्रीन फ़्रेमबफ़र पर ड्रॉ करें. इसके बाद, उसे स्क्रीन पर कॉपी करें.
ऐल्फ़ा चैनल
पारदर्शी कैनवस एलिमेंट, जिसका अल्फा ट्रू पर सेट है, अब भी डिसिंक्रोनाइज़ किया जा सकता है. हालांकि, इसके ऊपर कोई दूसरा डीओएम एलिमेंट नहीं होना चाहिए.
सिर्फ़ एक
canvas.getContext()
को पहली बार कॉल करने के बाद, कॉन्टेक्स्ट एट्रिब्यूट में बदलाव नहीं किया जा सकता. यह बात हमेशा से सही रही है. हालांकि, अगर आपको इस बारे में पता नहीं है या आपने इसे भूल दिया है, तो इसे दोहराने से आपको कुछ परेशानी से बचने में मदद मिल सकती है.
उदाहरण के लिए, मान लें कि मुझे कोई कॉन्टेक्स्ट मिलता है और मैंने alpha को false के तौर पर सेट किया है. इसके बाद, अपने कोड में कहीं बाद में, मैंने alpha को true पर सेट करके canvas.getContext()
को दूसरी बार कॉल किया है, जैसा कि यहां दिखाया गया है.
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,
});
यह साफ़ तौर पर नहीं पता चलता कि ctx1
और ctx2
एक ही ऑब्जेक्ट हैं. Alpha अब भी false है और alpha के बराबर true वाला कोई कॉन्टेक्स्ट कभी नहीं बनाया जाता.
इस्तेमाल किए जा सकने वाले कैनवस टाइप
getContext()
में पास किया गया पहला पैरामीटर, contextType
है. अगर आपको getContext()
के बारे में पहले से पता है, तो आपको यह जानने में दिलचस्पी होगी कि क्या '2d' कॉन्टेक्स्ट टाइप के अलावा, किसी और कॉन्टेक्स्ट टाइप का इस्तेमाल किया जा सकता है. नीचे दी गई टेबल में, desynchronized
के साथ काम करने वाले कॉन्टेक्स्ट टाइप दिखाए गए हैं.
contextType | कॉन्टेक्स्ट टाइप ऑब्जेक्ट |
---|---|
|
|
|
|
|
|
नतीजा
अगर आपको इस बारे में ज़्यादा जानकारी चाहिए, तो सैंपल देखें. पहले से बताए गए वीडियो के उदाहरण के अलावा, यहां '2d' और 'webgl', दोनों कॉन्टेक्स्ट दिखाने वाले उदाहरण दिए गए हैं.