requestAnimationFrame API - এখন সাব-মিলিসেকেন্ড নির্ভুলতা সহ

Ilmari Heikkinen

আপনি যদি requestAnimationFrame ব্যবহার করে থাকেন তবে আপনি আপনার পেইন্টগুলিকে স্ক্রিনের রিফ্রেশ হারে সিঙ্ক্রোনাইজ করা দেখে উপভোগ করেছেন, যার ফলে সর্বাধিক উচ্চ-বিশ্বস্ত অ্যানিমেশন সম্ভব। এছাড়াও, আপনি যখন আপনার ব্যবহারকারীরা অন্য ট্যাবে স্যুইচ করেন তখন আপনি তাদের CPU ফ্যানের শব্দ এবং ব্যাটারি-পাওয়ার সংরক্ষণ করছেন।

যদিও API এর অংশে একটি পরিবর্তন হতে চলেছে । আপনার কলব্যাক ফাংশনে পাস করা টাইমস্ট্যাম্পটি একটি সাধারণ Date.now() এর মতো টাইমস্ট্যাম্প থেকে পৃষ্ঠাটি খোলার পর থেকে ফ্লোটিং পয়েন্ট মিলিসেকেন্ডের উচ্চ-রেজোলিউশন পরিমাপে পরিবর্তিত হচ্ছে৷ আপনি যদি এই মানটি ব্যবহার করেন, তাহলে নীচের ব্যাখ্যার উপর ভিত্তি করে আপনাকে আপনার কোড আপডেট করতে হবে

শুধু পরিষ্কার হওয়ার জন্য, আমি যা বলছি তা এখানে:

// assuming requestAnimationFrame method has been normalized for all vendor prefixes..
requestAnimationFrame(function(timestamp){
    // the value of timestamp is changing
});

আপনি যদি এখানে প্রদত্ত সাধারণ requestAnimFrame শিম ব্যবহার করেন, তাহলে আপনি টাইমস্ট্যাম্প মান ব্যবহার করছেন না। আপনি হুক বন্ধ করছি. :)

কেন

কেন? ভাল rAF আপনাকে চূড়ান্ত 60 fps পেতে সাহায্য করে যা আদর্শ, এবং 60 fps প্রতি ফ্রেমে 16.7ms অনুবাদ করে৷ কিন্তু পূর্ণসংখ্যা মিলিসেকেন্ড দিয়ে পরিমাপ করার অর্থ হল আমরা যা পর্যবেক্ষণ করতে চাই এবং লক্ষ্য করতে চাই তার জন্য আমাদের কাছে 1/16 এর নির্ভুলতা রয়েছে।

16 ms বনাম 16 পূর্ণসংখ্যা ms গ্রাফ তুলনা।

আপনি উপরে দেখতে পাচ্ছেন, একটি নতুন ফ্রেম (60fps এ) আঁকার আগে আপনাকে আপনার সমস্ত কাজ করতে হবে এমন সর্বোচ্চ সময় নীল বার প্রতিনিধিত্ব করে। আপনি সম্ভবত 16 টিরও বেশি জিনিস করছেন, কিন্তু পূর্ণসংখ্যা মিলিসেকেন্ডের সাথে আপনার কেবলমাত্র সেই খুব ছোট বৃদ্ধির সময়সূচী এবং পরিমাপ করার ক্ষমতা রয়েছে। যে যথেষ্ট ভাল না.

উচ্চ রেজোলিউশন টাইমার আরও সুনির্দিষ্ট চিত্র প্রদান করে এটি সমাধান করে:

Date.now()         //  1337376068250
performance.now()  //  20303.427000007

উচ্চ রেজোলিউশন টাইমার বর্তমানে Chrome-এ window.performance.webkitNow() হিসাবে উপলব্ধ, এবং এই মানটি সাধারণত RAF কলব্যাকে পাস করা নতুন আর্গুমেন্ট মানের সমান। স্পেকটি স্ট্যান্ডার্ডের মাধ্যমে আরও অগ্রসর হলে, পদ্ধতিটি উপসর্গটি বাদ দেবে এবং performance.now() এর মাধ্যমে উপলব্ধ হবে।

আপনি উপরের দুটি মানগুলিও লক্ষ্য করবেন যেগুলি বিভিন্ন মাত্রার অনেকগুলি অর্ডার। performance.now() হল ফ্লোটিং পয়েন্ট মিলিসেকেন্ডের একটি পরিমাপ যেহেতু সেই নির্দিষ্ট পৃষ্ঠাটি লোড হতে শুরু করে ( performance.navigationStart নির্দিষ্ট হতে)।

ব্যাবহৃত হচ্ছে

মূল সমস্যাটি হল অ্যানিমেশন লাইব্রেরি যা এই নকশা প্যাটার্ন ব্যবহার করে:

function MyAnimation(duration) {
    this.startTime = Date.now();
    this.duration = duration;
    requestAnimFrame(this.tick.bind(this));
}
MyAnimation.prototype.tick = function(time) {
    var now = Date.now();
    if (time > now) {
        this.dispatchEvent("ended");
        return;
    }
    ...
    requestAnimFrame(this.tick.bind(this));
}

এটি ঠিক করার জন্য একটি সম্পাদনা বেশ সহজ... startTime বৃদ্ধি করুন এবং now window.performance.now() ব্যবহার করুন।

this.startTime = window.performance.now ?
                    (performance.now() + performance.timing.navigationStart) :
                    Date.now();

এটি একটি মোটামুটি নির্বোধ বাস্তবায়ন, এটি একটি প্রিফিক্সড now() পদ্ধতি ব্যবহার করে না এবং Date.now() সমর্থনও অনুমান করে, যা IE8 এ নেই।

বৈশিষ্ট্য সনাক্তকরণ

আপনি যদি উপরের প্যাটার্নটি ব্যবহার না করেন এবং আপনি কোন ধরণের কলব্যাক মান পাচ্ছেন তা সনাক্ত করতে চান তাহলে আপনি এই কৌশলটি ব্যবহার করতে পারেন:

requestAnimationFrame(function(timestamp){

    if (timestamp < 1e12){
        // .. high resolution timer
    } else {
        // integer milliseconds since unix epoch
    }

    // ...

if (timestamp < 1e12) তা পরীক্ষা করা হচ্ছে আমরা কত বড় সংখ্যা নিয়ে কাজ করছি। প্রযুক্তিগতভাবে এটি মিথ্যা ইতিবাচক হতে পারে তবে শুধুমাত্র যদি একটি ওয়েবপেজ 30 বছর ধরে খোলা থাকে। কিন্তু এটি একটি ফ্লোটিং পয়েন্ট নম্বর কিনা তা আমরা পরীক্ষা করতে সক্ষম নই (একটি পূর্ণসংখ্যার পরিবর্তে)। পর্যাপ্ত উচ্চ রেজোলিউশন টাইমারের জন্য জিজ্ঞাসা করুন এবং আপনি কিছু সময়ে পূর্ণসংখ্যার মান পেতে বাধ্য

আমরা Chrome 21-এ এই পরিবর্তনটি পুশ করার পরিকল্পনা করছি, তাই আপনি যদি ইতিমধ্যেই এই কলব্যাক প্যারামিটারের সুবিধা নিচ্ছেন, তাহলে আপনার কোড আপডেট করতে ভুলবেন না!