सिद्धांत में ये सभी अच्छे विचार हैं, जब तक आप गहरे नहीं जाते। समस्या यह है कि आप इसे बिना डी-सिंक्रोनाइज़ किए बिना आरएएफ को थ्रॉटल नहीं कर सकते हैं, यह मौजूदा के लिए बहुत उद्देश्य है। तो आप इसे पूर्ण गति से चलाने के लिए, और एक अलग पाश में अपने डेटा को अपडेट करते हैं , या यहां तक कि एक अलग थ्रेड!
हाँ, मैंने कहा। आप ब्राउज़र में बहु-थ्रेडेड जावास्क्रिप्ट कर सकते हैं!
मुझे पता है कि दो तरीके हैं जो बिना अच्छी तरह से काम करते हैं, बहुत कम रस का उपयोग करते हैं और कम गर्मी पैदा करते हैं। सटीक मानव-स्केल समय और मशीन दक्षता शुद्ध परिणाम हैं।
माफ़ी अगर यह थोड़ी सी चिंताजनक है, लेकिन यहाँ जाता है ...
विधि 1: सेट इन्टरवल और आरएएफ के माध्यम से ग्राफिक्स अपडेट करें।
अनुवाद और रोटेशन मान, भौतिकी, टकराव, आदि को अद्यतन करने के लिए एक अलग सेट का उपयोग करें। प्रत्येक एनिमेटेड तत्व के लिए उन मानों को एक वस्तु में रखें। प्रत्येक सेट में एक चर में परिवर्तन स्ट्रिंग असाइन करेंइंटरवल 'फ्रेम'। इन वस्तुओं को एक सरणी में रखें। एमएस में अपने वांछित एफपीएस पर अपना अंतराल सेट करें: एमएस = (1000 / एफपीएस)। यह एक स्थिर घड़ी रखता है जो RAF गति की परवाह किए बिना किसी भी डिवाइस पर समान एफपीएस की अनुमति देता है। यहां तत्वों को रूपांतरित न करें!
एक requestAnimationFrame लूप में, लूप के लिए एक पुराने स्कूल के साथ अपने एरे के माध्यम से पुनरावृति - यहाँ नए रूपों का उपयोग न करें, वे धीमे हैं!
for(var i=0; i<sprite.length-1; i++){ rafUpdate(sprite[i]); }
अपने rafUpdate फ़ंक्शन में, सरणी में अपनी js ऑब्जेक्ट से ट्रांसफ़ॉर्म स्ट्रिंग प्राप्त करें और इसके एलिमेंट्स id। आपके पास पहले से ही आपके '' स्प्राइट '' तत्व होने चाहिए जो चर से जुड़े हों या अन्य माध्यमों से आसानी से सुलभ हों, ताकि आप समय न गवाएं '' उन्हें आरएएफ में शामिल करें। उन्हें अपने html id के काम के नाम पर एक ऑब्जेक्ट में रखना बहुत अच्छा है। इससे पहले कि वह हिस्सा आपके SI या RAF में चला जाए, सेट करें।
अपने रूपांतरण अद्यतन करने के लिए आरएएफ का उपयोग केवल , केवल 3 डी रूपांतरण (यहां तक कि 2 डी के लिए), और सेट सीएसएस का उपयोग करें "होगा परिवर्तन: बदलना," तत्वों पर जो बदल जाएगा। यह आपके परिवर्तनों को देशी रिफ्रेश रेट के अनुसार सिंक करता है, जितना संभव हो सके, GPU में किक करता है, और ब्राउज़र को बताता है कि सबसे अधिक ध्यान कहाँ लगाना है।
तो आपके पास कुछ इस तरह का छद्मकोड होना चाहिए ...
// refs to elements to be transformed, kept in an array
var element = [
mario: document.getElementById('mario'),
luigi: document.getElementById('luigi')
//...etc.
]
var sprite = [ // read/write this with SI. read-only from RAF
mario: { id: mario ....physics data, id, and updated transform string (from SI) here },
luigi: { id: luigi .....same }
//...and so forth
] // also kept in an array (for efficient iteration)
//update one sprite js object
//data manipulation, CPU tasks for each sprite object
//(physics, collisions, and transform-string updates here.)
//pass the object (by reference).
var SIupdate = function(object){
// get pos/rot and update with movement
object.pos.x += object.mov.pos.x; // example, motion along x axis
// and so on for y and z movement
// and xyz rotational motion, scripted scaling etc
// build transform string ie
object.transform =
'translate3d('+
object.pos.x+','+
object.pos.y+','+
object.pos.z+
') '+
// assign rotations, order depends on purpose and set-up.
'rotationZ('+object.rot.z+') '+
'rotationY('+object.rot.y+') '+
'rotationX('+object.rot.x+') '+
'scale3d('.... if desired
; //...etc. include
}
var fps = 30; //desired controlled frame-rate
// CPU TASKS - SI psuedo-frame data manipulation
setInterval(function(){
// update each objects data
for(var i=0; i<sprite.length-1; i++){ SIupdate(sprite[i]); }
},1000/fps); // note ms = 1000/fps
// GPU TASKS - RAF callback, real frame graphics updates only
var rAf = function(){
// update each objects graphics
for(var i=0; i<sprite.length-1; i++){ rAF.update(sprite[i]) }
window.requestAnimationFrame(rAF); // loop
}
// assign new transform to sprite's element, only if it's transform has changed.
rAF.update = function(object){
if(object.old_transform !== object.transform){
element[object.id].style.transform = transform;
object.old_transform = object.transform;
}
}
window.requestAnimationFrame(rAF); // begin RAF
यह डेटा ऑब्जेक्ट्स में आपके अपडेट को बनाए रखता है और एसआई में वांछित 'फ्रेम' दर के लिए सिंक किए गए स्ट्रिंग्स को बदल देता है, और आरएएफ में वास्तविक ट्रांसफॉर्म असाइनमेंट GPU रीफ्रेश रेट के लिए सिंक किया जाता है। तो वास्तविक ग्राफिक्स अपडेट केवल आरएएफ में होते हैं, लेकिन डेटा में परिवर्तन, और ट्रांसफॉर्मिंग स्ट्रिंग का निर्माण एसआई में होता है, इस प्रकार कोई भी jankies लेकिन वांछित फ्रेम-दर पर 'समय' बहती है।
बहे:
[setup js sprite objects and html element object references]
[setup RAF and SI single-object update functions]
[start SI at percieved/ideal frame-rate]
[iterate through js objects, update data transform string for each]
[loop back to SI]
[start RAF loop]
[iterate through js objects, read object's transform string and assign it to it's html element]
[loop back to RAF]
विधि 2. वेब-वर्कर में SI डालें। यह एक FAAAST और चिकनी है!
विधि 1 के समान है, लेकिन वेब-कार्यकर्ता में SI डाल दिया है। यह पूरी तरह से अलग थ्रेड पर चलेगा, पेज को केवल RAF और UI से निपटने के लिए छोड़ देगा। स्प्राइट एरे को 'ट्रांसफ़रेबल ऑब्जेक्ट' के रूप में आगे-पीछे करें। यह बुको तेजी से है। यह क्लोन या क्रमबद्ध होने में समय नहीं लेता है, लेकिन यह संदर्भ के माध्यम से गुजरने जैसा नहीं है कि दूसरी तरफ से संदर्भ नष्ट हो जाता है, इसलिए आपको दोनों पक्षों को दूसरी तरफ पास करने की आवश्यकता होगी, और वर्तमान में केवल उन्हें अपडेट करें, सॉर्ट करें हाई-स्कूल में अपनी प्रेमिका के साथ आगे और पीछे एक नोट पास करना पसंद करते हैं।
एक बार में एक ही पढ़ और लिख सकता है। यह तब तक ठीक है जब तक कि वे जाँच न कर लें कि कहीं त्रुटि तो नहीं है। आरएएफ फास्ट है और इसे तुरंत वापस लाएगा, फिर जीपीयू फ़्रेमों के एक गुच्छा से गुजरें, बस जाँच करें कि क्या इसे अभी तक वापस भेजा गया है। वेब-वर्कर में SI के पास ज्यादातर समय स्प्राइट एरे होगा, और पोजिशन, मूवमेंट और फिजिक्स डेटा को अपडेट करेगा, साथ ही नए ट्रांसफॉर्मेशन स्ट्रिंग को बनाएगा, फिर इसे पेज में RAF में वापस कर देगा।
यह स्क्रिप्ट के माध्यम से तत्वों को जानने का सबसे तेज़ तरीका है। दो कार्य दो अलग-अलग कार्यक्रमों के रूप में चल रहे हैं, दो अलग-अलग थ्रेड्स पर, मल्टी-कोर सीपीयू का लाभ इस तरह से लिया जा सकता है कि एक एकल जेएस स्क्रिप्ट नहीं करता है। मल्टी-थ्रेडेड जावास्क्रिप्ट एनीमेशन।
और यह बिना जंक के इतनी आसानी से करेगा, लेकिन वास्तविक निर्दिष्ट फ्रेम-दर पर, बहुत कम विचलन के साथ।
परिणाम:
या तो इन दो तरीकों से यह सुनिश्चित होगा कि आपकी स्क्रिप्ट किसी भी पीसी, फोन, टैबलेट आदि पर समान गति से चलेगी (डिवाइस और ब्राउज़र की क्षमताओं के भीतर, बिल्कुल)।
requestAnimationFrame
(जैसा कि नाम का सुझाव है) केवल एक एनीमेशन फ्रेम का अनुरोध करने के लिए जब यह आवश्यक हो। मान लीजिए कि आप एक स्थिर ब्लैक कैनवास दिखाते हैं, आपको 0 एफपीएस मिलना चाहिए क्योंकि किसी नए फ्रेम की आवश्यकता नहीं है। लेकिन यदि आप एक ऐसा एनीमेशन प्रदर्शित कर रहे हैं जिसकी आवश्यकता 60fps है, तो आपको वह भी प्राप्त करना चाहिए।rAF
बस बेकार तख्ते को "छोड़ना" और फिर सीपीयू को बचाने की अनुमति देता है।