অস্পষ্টতা একটি ব্যবহারকারীর ফোকাস পুনর্নির্দেশ করার একটি দুর্দান্ত উপায়। অন্যান্য উপাদানগুলিকে ফোকাসে রেখে কিছু চাক্ষুষ উপাদানগুলিকে অস্পষ্ট দেখায় যা স্বাভাবিকভাবেই ব্যবহারকারীর ফোকাসকে নির্দেশ করে৷ ব্যবহারকারীরা অস্পষ্ট বিষয়বস্তু উপেক্ষা করে এবং পরিবর্তে তারা পড়তে পারে এমন সামগ্রীতে ফোকাস করে। একটি উদাহরণ হল আইকনগুলির একটি তালিকা যা হোভার করার সময় পৃথক আইটেমগুলির বিবরণ প্রদর্শন করে। সেই সময়ের মধ্যে, ব্যবহারকারীকে নতুন প্রদর্শিত তথ্যে পুনঃনির্দেশিত করতে অবশিষ্ট পছন্দগুলি অস্পষ্ট হতে পারে।
টিএল; ডিআর
একটি ব্লার অ্যানিমেটিং সত্যিই একটি বিকল্প নয় কারণ এটি খুব ধীর। পরিবর্তে, ক্রমবর্ধমান অস্পষ্ট সংস্করণের একটি সিরিজ প্রাক-গণনা করুন এবং তাদের মধ্যে ক্রস-ফেড করুন। আমার সহকর্মী Yi Gu আপনার জন্য সবকিছু যত্ন নিতে একটি লাইব্রেরি লিখেছেন! আমাদের ডেমো একবার দেখুন.
যাইহোক, এই কৌশলটি কোন ট্রানজিশনাল পিরিয়ড ছাড়াই প্রয়োগ করার সময় বেশ বিরক্তিকর হতে পারে। একটি ব্লার অ্যানিমেটিং — অস্পষ্ট থেকে অস্পষ্টে রূপান্তর — একটি যুক্তিসঙ্গত পছন্দ বলে মনে হয়, কিন্তু আপনি যদি কখনও ওয়েবে এটি করার চেষ্টা করে থাকেন তবে আপনি সম্ভবত দেখেছেন যে অ্যানিমেশনগুলি মসৃণ ছাড়া অন্য কিছু, যেমন এই ডেমোটি দেখায় যদি আপনার কাছে না থাকে একটি শক্তিশালী মেশিন। আমরা কি আরও ভাল করতে পারি?
সমস্যা
এখন পর্যন্ত, আমরা দক্ষতার সাথে একটি অস্পষ্ট কাজ অ্যানিমেটিং করতে পারি না। যাইহোক, আমরা এমন একটি কাজ খুঁজে পেতে পারি যা যথেষ্ট ভাল দেখায়, কিন্তু প্রযুক্তিগতভাবে বলতে গেলে, অ্যানিমেটেড ব্লার নয়। শুরু করার জন্য, আসুন প্রথমে বুঝতে পারি কেন অ্যানিমেটেড ব্লার ধীর। ওয়েবে উপাদানগুলিকে অস্পষ্ট করতে, দুটি কৌশল রয়েছে: CSS filter
বৈশিষ্ট্য এবং SVG ফিল্টার৷ বর্ধিত সমর্থন এবং ব্যবহারের সহজতার জন্য ধন্যবাদ, CSS ফিল্টারগুলি সাধারণত ব্যবহার করা হয়। দুর্ভাগ্যবশত, যদি আপনাকে ইন্টারনেট এক্সপ্লোরার সমর্থন করতে হয়, তাহলে আপনার কাছে SVG ফিল্টার ব্যবহার করা ছাড়া আর কোনো বিকল্প নেই কারণ IE 10 এবং 11 সেগুলিকে সমর্থন করে কিন্তু CSS ফিল্টার নয়৷ ভাল খবর হল যে ব্লার অ্যানিমেট করার জন্য আমাদের ওয়ার্কআউন্ড উভয় কৌশলের সাথে কাজ করে। তাই চলুন DevTools দেখে বাধা খুঁজে বের করার চেষ্টা করি।
আপনি DevTools-এ "পেইন্ট ফ্ল্যাশিং" সক্ষম করলে, আপনি কোনো ফ্ল্যাশ দেখতে পাবেন না। দেখে মনে হচ্ছে কোন রিপেইন্ট হচ্ছে না। এবং এটি প্রযুক্তিগতভাবে সঠিক কারণ একটি "রিপেইন্ট" বলতে সিপিইউকে একটি প্রচারিত উপাদানের টেক্সচার পুনরায় রং করতে হয়। যখনই একটি উপাদান প্রচারিত এবং ঝাপসা উভয়ই হয়, একটি শেডার ব্যবহার করে GPU দ্বারা অস্পষ্টতা প্রয়োগ করা হয়।
SVG ফিল্টার এবং CSS ফিল্টার উভয়ই একটি অস্পষ্টতা প্রয়োগ করতে কনভোলিউশন ফিল্টার ব্যবহার করে। কনভোলিউশন ফিল্টারগুলি মোটামুটি ব্যয়বহুল কারণ প্রতিটি আউটপুট পিক্সেলের জন্য বেশ কয়েকটি ইনপুট পিক্সেল বিবেচনা করতে হবে। ইমেজ যত বড় বা ব্লার ব্যাসার্ধ যত বড়, প্রভাব তত বেশি ব্যয়বহুল।
এবং সমস্যাটি এখানেই, আমরা প্রতিটি ফ্রেমে একটি বরং ব্যয়বহুল জিপিইউ অপারেশন চালাচ্ছি, আমাদের ফ্রেমের বাজেট 16 মি.সে. এবং তাই 60fps-এর নিচে শেষ হচ্ছে।
খরগোশের গর্তের নিচে
তাহলে আমরা এই রান মসৃণ করতে কি করতে পারি? আমরা হাতের কৌশল ব্যবহার করতে পারি! প্রকৃত ব্লার মান (ব্লারের ব্যাসার্ধ) অ্যানিমেট করার পরিবর্তে, আমরা কয়েকটি অস্পষ্ট কপির প্রাক-গণনা করি যেখানে অস্পষ্টতার মান দ্রুতগতিতে বৃদ্ধি পায়, তারপর opacity
ব্যবহার করে তাদের মধ্যে ক্রস-ফেড করুন।
ক্রস-ফেড হল ওভারল্যাপিং অস্বচ্ছতা ফেড-ইন এবং ফেইড-আউটগুলির একটি সিরিজ। উদাহরণস্বরূপ, যদি আমাদের চারটি অস্পষ্ট পর্যায় থাকে, আমরা একই সময়ে দ্বিতীয় পর্যায়ে বিবর্ণ হওয়ার সময় প্রথম পর্যায়টি বিবর্ণ হয়ে যাই। দ্বিতীয় পর্যায়টি 100% অস্বচ্ছতায় পৌঁছালে এবং প্রথমটি 0%-এ পৌঁছে গেলে, তৃতীয় পর্যায়ে বিবর্ণ হওয়ার সময় আমরা দ্বিতীয় পর্যায়টি বিবর্ণ হয়ে যাই। একবার এটি হয়ে গেলে, আমরা অবশেষে তৃতীয় পর্যায়টি বিবর্ণ হয়ে যাই এবং চতুর্থ এবং চূড়ান্ত সংস্করণে বিবর্ণ হয়ে যাই। এই পরিস্থিতিতে, প্রতিটি পর্যায়ে মোট কাঙ্ক্ষিত সময়কালের ¼ লাগবে। দৃশ্যত, এটি একটি বাস্তব, অ্যানিমেটেড ব্লারের মতো দেখায়।
আমাদের পরীক্ষা-নিরীক্ষায়, প্রতি ধাপে দ্রুতগতিতে অস্পষ্ট ব্যাসার্ধ বাড়ানোর ফলে সেরা চাক্ষুষ ফলাফল পাওয়া যায়। উদাহরণ: যদি আমাদের চারটি ব্লার স্টেজ থাকে, তাহলে আমরা filter: blur(2^n)
প্রতিটি স্টেজে, যেমন স্টেজ 0: 1px, স্টেজ 1: 2px, স্টেজ 2: 4px এবং স্টেজ 3: 8px। যদি আমরা will-change: transform
, এই উপাদানগুলিতে অস্বচ্ছতা পরিবর্তন করা সুপার-ডুপার দ্রুত হওয়া উচিত। তাত্ত্বিকভাবে, এটি আমাদের অস্পষ্ট করার ব্যয়বহুল কাজকে সামনে-লোড করার অনুমতি দেবে। দেখা যাচ্ছে, যুক্তি ত্রুটিপূর্ণ। আপনি যদি এই ডেমোটি চালান, আপনি দেখতে পাবেন যে ফ্রেমরেট এখনও 60fps-এর নিচে, এবং অস্পষ্টতা আসলে আগের চেয়ে খারাপ ।
DevTools-এ একটি দ্রুত নজর দিলে দেখা যায় যে GPU এখনও অত্যন্ত ব্যস্ত এবং প্রতিটি ফ্রেমকে ~90ms পর্যন্ত প্রসারিত করে। কিন্তু কেন? আমরা আর ব্লার মান পরিবর্তন করছি না, শুধুমাত্র অস্বচ্ছতা, তাই কি ঘটছে? সমস্যাটি আবারও, ব্লার এফেক্টের প্রকৃতিতে রয়েছে: যেমন আগে ব্যাখ্যা করা হয়েছে, যদি উপাদানটি প্রচারিত এবং ঝাপসা উভয়ই হয়, তাহলে প্রভাব GPU দ্বারা প্রয়োগ করা হয়। তাই যদিও আমরা আর ব্লার মান অ্যানিমেট করছি না, টেক্সচারটি এখনও অস্পষ্ট এবং GPU দ্বারা প্রতিটি ফ্রেমে পুনরায় ঝাপসা করা দরকার। ফ্রেম রেট আগের চেয়ে আরও খারাপ হওয়ার কারণ এই সত্য থেকে উদ্ভূত হয় যে নিষ্পাপ প্রয়োগের তুলনায়, GPU-তে আসলে আগের চেয়ে আরও বেশি কাজ রয়েছে, কারণ বেশিরভাগ সময় দুটি টেক্সচার দৃশ্যমান হয় যা স্বাধীনভাবে ঝাপসা করা দরকার।
আমরা যা নিয়ে এসেছি তা সুন্দর নয়, তবে এটি অ্যানিমেশনটিকে উজ্জ্বলভাবে দ্রুত করে তোলে। আমরা অস্পষ্ট উপাদানের প্রচার না করার জন্য ফিরে যাই, বরং একটি অভিভাবক মোড়কের প্রচার করি। যদি একটি উপাদান ঝাপসা এবং প্রচার উভয়ই হয়, তাহলে প্রভাব GPU দ্বারা প্রয়োগ করা হয়। এই কি আমাদের ডেমো ধীর করে তোলে. যদি উপাদানটি ঝাপসা করা হয় কিন্তু প্রচার না করা হয়, তাহলে ব্লারটিকে তার পরিবর্তে নিকটতম প্যারেন্ট টেক্সচারে রাস্টারাইজ করা হয়। আমাদের ক্ষেত্রে যে উন্নীত প্যারেন্ট র্যাপার উপাদান. অস্পষ্ট চিত্রটি এখন মূল উপাদানের টেক্সচার এবং ভবিষ্যতের সমস্ত ফ্রেমের জন্য পুনরায় ব্যবহার করা যেতে পারে। এটি শুধুমাত্র কাজ করে কারণ আমরা জানি যে অস্পষ্ট উপাদানগুলি অ্যানিমেটেড নয় এবং তাদের ক্যাশে করা আসলে উপকারী। এখানে একটি ডেমো যা এই কৌশলটি প্রয়োগ করে। আমি ভাবছি Moto G4 এই পদ্ধতি সম্পর্কে কি মনে করে? স্পয়লার সতর্কতা: এটি মনে করে এটি দুর্দান্ত:
এখন আমরা জিপিইউতে প্রচুর হেডরুম এবং একটি সিল্কি-মসৃণ 60fps পেয়েছি। আমরা এটা করেছি!
উৎপাদন করা
আমাদের ডেমোতে, বিভিন্ন শক্তিতে ঝাপসা করার জন্য বিষয়বস্তুর অনুলিপি পেতে আমরা একটি DOM কাঠামো একাধিকবার নকল করেছি। আপনি ভাবছেন যে এটি একটি উত্পাদন পরিবেশে কীভাবে কাজ করবে কারণ লেখকের সিএসএস শৈলী বা এমনকি তাদের জাভাস্ক্রিপ্টের সাথে কিছু অনিচ্ছাকৃত পার্শ্ব-প্রতিক্রিয়া থাকতে পারে। আপনি ঠিক বলেছেন। শ্যাডো ডোমে প্রবেশ করুন!
যদিও বেশিরভাগ লোকেরা তাদের কাস্টম উপাদানগুলির সাথে "অভ্যন্তরীণ" উপাদানগুলিকে সংযুক্ত করার উপায় হিসাবে শ্যাডো ডম সম্পর্কে ভাবেন, এটি একটি বিচ্ছিন্নতা এবং কর্মক্ষমতা আদিম! JavaScript এবং CSS ছায়া DOM সীমারেখা ভেদ করতে পারে না যা আমাদের ডেভেলপারের শৈলী বা অ্যাপ্লিকেশন যুক্তিতে হস্তক্ষেপ না করে কন্টেন্ট নকল করতে দেয়। রাস্টারাইজ করার জন্য আমাদের কাছে ইতিমধ্যেই প্রতিটি কপির জন্য একটি <div>
উপাদান রয়েছে এবং এখন এই <div>
গুলিকে ছায়া হোস্ট হিসাবে ব্যবহার করুন। আমরা attachShadow({mode: 'closed'})
ব্যবহার করে একটি ShadowRoot
তৈরি করি এবং <div>
এর পরিবর্তে ShadowRoot
এ বিষয়বস্তুর একটি অনুলিপি সংযুক্ত করি। আমাদের ShadowRoot
সমস্ত স্টাইলশীট অনুলিপি করা নিশ্চিত করতে হবে যাতে আমাদের কপিগুলি মূলের মতোই স্টাইল করা হয়।
কিছু ব্রাউজার শ্যাডো DOM v1 সমর্থন করে না, এবং তাদের জন্য, আমরা কেবল বিষয়বস্তুর অনুলিপি করতে এবং ভাল কিছুর আশায় ফিরে আসি যাতে কিছুই ভেঙে না যায়। আমরা ShadyCSS এর সাথে Shadow DOM পলিফিল ব্যবহার করতে পারি, কিন্তু আমরা আমাদের লাইব্রেরিতে এটি বাস্তবায়ন করিনি।
এবং সেখানে আপনি যান. Chrome এর রেন্ডারিং পাইপলাইনে আমাদের যাত্রার পর, আমরা বুঝতে পেরেছি কিভাবে আমরা ব্রাউজার জুড়ে দক্ষতার সাথে ব্লার অ্যানিমেট করতে পারি!
উপসংহার
এই ধরনের প্রভাব হালকাভাবে ব্যবহার করা উচিত নয়। এই কারণে যে আমরা DOM উপাদানগুলি অনুলিপি করি এবং সেগুলিকে তাদের নিজস্ব স্তরে জোর করে, আমরা লোয়ার-এন্ড ডিভাইসগুলির সীমা ঠেলে দিতে পারি। প্রতিটি ShadowRoot
এ সমস্ত স্টাইলশীট অনুলিপি করাও একটি সম্ভাব্য কর্মক্ষমতার ঝুঁকি, তাই আপনার সিদ্ধান্ত নেওয়া উচিত যে আপনি LightDOM
এর অনুলিপিগুলির দ্বারা প্রভাবিত না হওয়ার জন্য আপনার যুক্তি এবং শৈলীগুলি সামঞ্জস্য করবেন কিনা বা আমাদের ShadowDOM
কৌশলটি ব্যবহার করবেন। কিন্তু কখনও কখনও আমাদের কৌশল একটি সার্থক বিনিয়োগ হতে পারে. আমাদের GitHub সংগ্রহস্থলের কোডের পাশাপাশি ডেমোটি দেখুন এবং আপনার কোন প্রশ্ন থাকলে আমাকে টুইটারে হিট করুন!