পারফরম্যান্ট প্যারালাক্সিং

এটিকে ভালোবাসুন বা ঘৃণা করুন, প্যারালাক্সিং এখানে থাকার জন্য। সুবিবেচনার সাথে ব্যবহার করা হলে, এটি একটি ওয়েব অ্যাপে গভীরতা এবং সূক্ষ্মতা যোগ করতে পারে। সমস্যা, যাইহোক, একটি কার্যকরী উপায়ে প্যারালাক্সিং বাস্তবায়ন করা চ্যালেঞ্জিং হতে পারে। এই নিবন্ধে, আমরা একটি সমাধান নিয়ে আলোচনা করব যা উভয়ই কার্যকরী এবং একইভাবে গুরুত্বপূর্ণভাবে, ক্রস-ব্রাউজার কাজ করে।

প্যারালাক্স ইলাস্ট্রেশন।

টিএল; ডিআর

  • প্যারালাক্স অ্যানিমেশন তৈরি করতে স্ক্রোল ইভেন্ট বা background-position ব্যবহার করবেন না।
  • আরও সঠিক প্যারালাক্স প্রভাব তৈরি করতে CSS 3D রূপান্তর ব্যবহার করুন।
  • মোবাইল সাফারির জন্য position: sticky

আপনি যদি ড্রপ-ইন সমাধান চান, তাহলে UI এলিমেন্ট স্যাম্পলস GitHub রেপোতে যান এবং প্যারালাক্স হেল্পার JS ! আপনি GitHub রেপোতে প্যারালাক্স স্ক্রলারের একটি লাইভ ডেমো দেখতে পারেন।

সমস্যা parallaxers

শুরু করার জন্য, আসুন প্যারালাক্স প্রভাব অর্জনের দুটি সাধারণ উপায় এবং বিশেষ করে, কেন সেগুলি আমাদের উদ্দেশ্যে অনুপযুক্ত তা দেখে নেওয়া যাক।

খারাপ: স্ক্রোল ইভেন্ট ব্যবহার করে

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

তথ্যের এই গুরুত্বপূর্ণ অংশটি আমাদের বলে যে কেন আমাদের একটি জাভাস্ক্রিপ্ট-ভিত্তিক সমাধান এড়াতে হবে যা স্ক্রোল ইভেন্টগুলির উপর ভিত্তি করে উপাদানগুলিকে সরিয়ে দেয়: জাভাস্ক্রিপ্ট গ্যারান্টি দেয় না যে প্যারালাক্সিং পৃষ্ঠার স্ক্রোল অবস্থানের সাথে ধাপে থাকবে । মোবাইল সাফারির পুরোনো সংস্করণগুলিতে, স্ক্রোল ইভেন্টগুলি আসলে স্ক্রলের শেষে বিতরণ করা হয়েছিল, যা জাভাস্ক্রিপ্ট-ভিত্তিক স্ক্রোল প্রভাব তৈরি করা অসম্ভব করে তুলেছিল। আরও সাম্প্রতিক সংস্করণগুলি অ্যানিমেশনের সময় স্ক্রোল ইভেন্টগুলি সরবরাহ করে , তবে একইভাবে ক্রোমের মতো, "সর্বোত্তম প্রচেষ্টা" ভিত্তিতে। যদি মূল থ্রেড অন্য কোন কাজে ব্যস্ত থাকে, তাহলে স্ক্রোল ইভেন্টগুলি অবিলম্বে বিতরণ করা হবে না, যার অর্থ প্যারালাক্স প্রভাব হারিয়ে যাবে।

খারাপ: background-position আপডেট করা হচ্ছে

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

আমরা যদি প্যারালাক্স গতির প্রতিশ্রুতি দিতে চাই, আমরা এমন কিছু চাই যা একটি ত্বরিত সম্পত্তি হিসাবে প্রয়োগ করা যেতে পারে (যা আজকে রূপান্তর এবং অস্বচ্ছতার সাথে লেগে থাকা) এবং যা স্ক্রোল ইভেন্টের উপর নির্ভর করে না।

3D-এ CSS

স্কট কেলাম এবং কিথ ক্লার্ক উভয়ই প্যারালাক্স মোশন অর্জনের জন্য CSS 3D ব্যবহার করার ক্ষেত্রে উল্লেখযোগ্য কাজ করেছেন এবং তারা যে কৌশলটি ব্যবহার করেন তা কার্যকরভাবে এই:

  • overflow-y: scroll (এবং সম্ভবত overflow-x: hidden ) দিয়ে স্ক্রোল করার জন্য একটি ধারণকারী উপাদান সেট আপ করুন।
  • সেই একই উপাদানটিতে একটি perspective মান প্রয়োগ করুন, এবং একটি perspective-origin top left দিকে সেট করুন বা 0 0
  • সেই উপাদানটির শিশুদের জন্য Z-এ একটি অনুবাদ প্রয়োগ করুন এবং পর্দায় তাদের আকারকে প্রভাবিত না করে প্যারালাক্স গতি প্রদানের জন্য তাদের ব্যাক আপ করুন।

এই পদ্ধতির জন্য CSS দেখতে এরকম দেখাচ্ছে:

.container {
  width: 100%;
  height: 100%;
  overflow-x: hidden;
  overflow-y: scroll;
  perspective: 1px;
  perspective-origin: 0 0;
}

.parallax-child {
  transform-origin: 0 0;
  transform: translateZ(-2px) scale(3);
}

যা এই মত HTML এর একটি স্নিপেট অনুমান করে:

<div class="container">
    <div class="parallax-child"></div>
</div>

দৃষ্টিকোণ জন্য স্কেল সামঞ্জস্য

শিশু উপাদানটিকে পিছনে ঠেলে তা দৃষ্টিকোণ মানের সাথে ছোট আনুপাতিক হতে পারে। আপনি এই সমীকরণের সাথে কতটা স্কেল আপ করতে হবে তা গণনা করতে পারেন: (দৃষ্টিকোণ - দূরত্ব) / দৃষ্টিকোণ । যেহেতু আমরা সম্ভবত প্যারালাক্সিং উপাদানটিকে প্যারালাক্স করতে চাই তবে আমরা যে আকারে এটি রচনা করেছি তাতে উপস্থিত হতে চাই, তাই এটিকে এভাবে রেখে না দিয়ে এইভাবে স্কেল করা দরকার।

উপরের কোডের ক্ষেত্রে, দৃষ্টিকোণ হল 1px , এবং parallax-child Z দূরত্ব হল -2px । এর মানে হল যে উপাদানটিকে 3x দ্বারা স্কেল করতে হবে, যা আপনি দেখতে পাচ্ছেন যে কোডটিতে প্লাগ করা মান হল: scale(3)

যে কোনো সামগ্রীতে translateZ মান প্রয়োগ করা হয়নি, আপনি শূন্যের মান প্রতিস্থাপন করতে পারেন। এর মানে হল স্কেলটি (দৃষ্টিকোণ - 0) / পরিপ্রেক্ষিত , যা 1 এর একটি মান ধরেছে, যার মানে এটি উপরে বা নীচে স্কেল করা হয়নি। বেশ সহজ, সত্যিই.

এই পদ্ধতি কিভাবে কাজ করে

কেন এটি কাজ করে তা পরিষ্কার হওয়া গুরুত্বপূর্ণ, যেহেতু আমরা শীঘ্রই সেই জ্ঞান ব্যবহার করতে যাচ্ছি। স্ক্রোলিং কার্যকরভাবে একটি রূপান্তর, যে কারণে এটি ত্বরান্বিত হতে পারে; এটি বেশিরভাগই জিপিইউ এর সাথে স্তরগুলিকে স্থানান্তরিত করে। একটি সাধারণ স্ক্রলে, যা দৃষ্টিভঙ্গির কোনো ধারণা ছাড়াই একটি, স্ক্রোলিং উপাদান এবং এর বাচ্চাদের তুলনা করার সময় স্ক্রলিং 1:1 পদ্ধতিতে ঘটে। আপনি যদি একটি উপাদানকে 300px দ্বারা নিচে স্ক্রোল করেন, তাহলে এর বাচ্চারা একই পরিমাণে রূপান্তরিত হয়: 300px

যাইহোক, স্ক্রলিং এলিমেন্টে একটি পরিপ্রেক্ষিত মান প্রয়োগ করা এই প্রক্রিয়ার সাথে গোলমাল করে; এটি স্ক্রোল ট্রান্সফর্মকে আন্ডারপিন করে এমন ম্যাট্রিকে পরিবর্তন করে। এখন 300px-এর একটি স্ক্রল বাচ্চাদের শুধুমাত্র 150px দ্বারা সরাতে পারে, আপনার পছন্দের perspective এবং translateZ মানগুলির উপর নির্ভর করে। যদি একটি উপাদানের translateZ মান 0 থাকে, তবে এটি 1:1 এ স্ক্রোল করা হবে (যেমন এটি আগে ছিল), তবে একটি শিশুকে Z এ ঠেলে দৃষ্টিকোণ থেকে দূরে স্ক্রোল করা হবে ভিন্ন হারে! নেট ফলাফল: প্যারালাক্স গতি। এবং, অত্যন্ত গুরুত্বপূর্ণভাবে, এটি ব্রাউজারের অভ্যন্তরীণ স্ক্রোল যন্ত্রপাতির অংশ হিসাবে স্বয়ংক্রিয়ভাবে পরিচালনা করা হয়, যার অর্থ scroll ইভেন্টগুলি শোনার বা background-position পরিবর্তন করার কোন প্রয়োজন নেই৷

মলমের মধ্যে একটি মাছি: মোবাইল সাফারি

প্রতিটি প্রভাবের জন্য সতর্কতা রয়েছে এবং রূপান্তরের জন্য একটি গুরুত্বপূর্ণ বিষয় হল শিশু উপাদানগুলিতে 3D প্রভাবগুলি সংরক্ষণ করা। যদি একটি দৃষ্টিকোণ সহ উপাদান এবং এর সমান্তরাল শিশুদের মধ্যে অনুক্রমের উপাদান থাকে, তাহলে 3D দৃষ্টিকোণটি "চ্যাপ্টা" হয়, যার অর্থ প্রভাব হারিয়ে যায়।

<div class="container">
    <div class="parallax-container">
    <div class="parallax-child"></div>
    </div>
</div>

উপরের HTML-এ, .parallax-container নতুন, এবং এটি কার্যকরভাবে perspective মানকে সমতল করবে এবং আমরা প্যারালাক্স প্রভাব হারাবো। সমাধান, বেশিরভাগ ক্ষেত্রে, মোটামুটি সহজবোধ্য: আপনি উপাদানটিতে transform-style: preserve-3d যোগ করেন, যার ফলে এটি গাছের উপরে প্রয়োগ করা যেকোন 3D প্রভাব (যেমন আমাদের দৃষ্টিকোণ মান) প্রচার করে।

.parallax-container {
  transform-style: preserve-3d;
}

মোবাইল সাফারির ক্ষেত্রে, তবে জিনিসগুলি একটু বেশি জটিল। overflow-y: scroll প্রযুক্তিগতভাবে কাজ করে, তবে স্ক্রলিং উপাদানটি ফ্লাইং করতে সক্ষম হওয়ার মূল্যে। সমাধান হল -webkit-overflow-scrolling: touch যোগ করা, কিন্তু এটি perspective সমতল করবে এবং আমরা কোনো সমান্তরাল পাব না।

প্রগতিশীল বর্ধনের দৃষ্টিকোণ থেকে, এটি সম্ভবত খুব বেশি সমস্যা নয়। আমরা যদি প্রতিটি পরিস্থিতিতে প্যারালাক্স করতে না পারি, তবে আমাদের অ্যাপটি এখনও কাজ করবে, তবে একটি সমাধান বের করা ভাল হবে।

position: sticky !

প্রকৃতপক্ষে, position: sticky , যা উপাদানগুলিকে ভিউপোর্টের শীর্ষে বা স্ক্রোল করার সময় একটি প্রদত্ত মূল উপাদানকে "স্টিক" করার অনুমতি দেওয়ার জন্য বিদ্যমান। স্পেক, তাদের অধিকাংশের মত, মোটামুটি ভারী, কিন্তু এটির মধ্যে একটি সহায়ক সামান্য রত্ন রয়েছে:

এটি প্রথম নজরে খুব বেশি বোঝা নাও হতে পারে, তবে সেই বাক্যটির একটি মূল বিষয় হল যখন এটি নির্দেশ করে যে কীভাবে, সঠিকভাবে, একটি উপাদানের আঠালোতা গণনা করা হয়: "অফসেটটি নিকটতম পূর্বপুরুষের রেফারেন্সের সাথে গণনা করা হয় স্ক্রলিং বক্স" । অন্য কথায়, স্টিকি উপাদানটি সরানোর দূরত্ব (এটি অন্য উপাদান বা ভিউপোর্টের সাথে সংযুক্ত দেখানোর জন্য) অন্য কোনো রূপান্তর প্রয়োগ করার আগে গণনা করা হয়, পরে নয়। এর মানে হল, আগের স্ক্রোলিং উদাহরণের মতো, যদি অফসেটটি 300px-এ গণনা করা হয়, তাহলে 300px অফসেট মানটি যে কোনও স্টিকি উপাদানগুলিতে প্রয়োগ করার আগে এটিকে ম্যানিপুলেট করার জন্য দৃষ্টিকোণ (বা অন্য কোনও রূপান্তর) ব্যবহার করার একটি নতুন সুযোগ রয়েছে৷

position: -webkit-sticky , আমরা কার্যকরভাবে -webkit-overflow-scrolling: touch সমতল প্রভাবকে "বিপরীত" করতে পারি। এটি নিশ্চিত করে যে প্যারালাক্সিং উপাদানটি একটি স্ক্রলিং বাক্সের সাথে নিকটতম পূর্বপুরুষকে উল্লেখ করে, যা এই ক্ষেত্রে .container । তারপর, আগের মতই, .parallax-container একটি perspective মান প্রয়োগ করে, যা গণনাকৃত স্ক্রোল অফসেট পরিবর্তন করে এবং একটি প্যারালাক্স প্রভাব তৈরি করে।

<div class="container">
    <div class="parallax-container">
    <div class="parallax-child"></div>
    </div>
</div>
.container {
  overflow-y: scroll;
  -webkit-overflow-scrolling: touch;
}

.parallax-container {
  perspective: 1px;
}

.parallax-child {
  position: -webkit-sticky;
  top: 0px;
  transform: translate(-2px) scale(3);
}

এটি মোবাইল সাফারির জন্য প্যারালাক্স প্রভাব পুনরুদ্ধার করে, যা সর্বত্র চমৎকার খবর!

স্টিকি পজিশনিং সতর্কতা

তবে এখানে একটি পার্থক্য রয়েছে : position: sticky প্যারালাক্স মেকানিক্সকে পরিবর্তন করে । স্টিকি পজিশনিং উপাদানটিকে স্ক্রোলিং পাত্রে আটকে রাখার চেষ্টা করে, যেখানে একটি নন-স্টিকি সংস্করণ তা করে না। এর মানে হল যে স্টিকি সহ প্যারালাক্সটি বিহীনটির বিপরীতে পরিণত হয়:

  • অবস্থানের সাথে position: sticky , উপাদানটি z=0 এর যত কাছাকাছি হবে এটি তত কম সরবে।
  • অবস্থান ছাড়া position: sticky , উপাদানটি z=0 এর যত কাছাকাছি হবে এটি তত বেশি সরবে।

যদি সেগুলি কিছুটা বিমূর্ত বলে মনে হয় তবে রবার্ট ফ্ল্যাকের এই ডেমোটি দেখুন , যা দেখায় কিভাবে উপাদানগুলি স্টিকি অবস্থানের সাথে এবং ছাড়াই ভিন্নভাবে আচরণ করে। পার্থক্য দেখতে, আপনার প্রয়োজন Chrome Canary (যা লেখার সময় সংস্করণ 56) বা Safari।

প্যারালাক্স দৃষ্টিকোণ স্ক্রিনশট

রবার্ট ফ্ল্যাকের একটি ডেমো দেখানো হয়েছে কিভাবে position: sticky প্যারালাক্স স্ক্রলিংকে প্রভাবিত করে।

বিভিন্ন বাগ এবং সমাধান

যেকোন কিছুর মতই, যদিও, এখনও গলদ এবং বাম্প রয়েছে যা মসৃণ করা দরকার:

  • স্টিকি সমর্থন অসঙ্গত। সমর্থন এখনও ক্রোমে প্রয়োগ করা হচ্ছে, এজ-এ সম্পূর্ণরূপে সমর্থন নেই, এবং ফায়ারফক্সের পেইন্টিং বাগ রয়েছে যখন স্টিকিকে দৃষ্টিকোণ রূপান্তরের সাথে একত্রিত করা হয় । এই ধরনের ক্ষেত্রে, এটি শুধুমাত্র position: sticky ( -webkit- প্রিফিক্সড সংস্করণ) যখন এটি প্রয়োজন হয়, যা শুধুমাত্র মোবাইল সাফারির জন্য।
  • প্রভাব এজ এ "শুধু কাজ করে না"। এজ ওএস স্তরে স্ক্রলিং পরিচালনা করার চেষ্টা করে, যা সাধারণত একটি ভাল জিনিস, তবে এই ক্ষেত্রে এটি স্ক্রোল করার সময় দৃষ্টিকোণ পরিবর্তনগুলি সনাক্ত করতে বাধা দেয়। এটি ঠিক করতে, আপনি একটি নির্দিষ্ট অবস্থানের উপাদান যোগ করতে পারেন, কারণ এটি এজকে একটি নন-OS স্ক্রোলিং পদ্ধতিতে স্যুইচ করে বলে মনে হয় এবং এটি দৃষ্টিকোণ পরিবর্তনের জন্য দায়ী তা নিশ্চিত করে।
  • "পৃষ্ঠার বিষয়বস্তু সবেমাত্র বিশাল হয়েছে!" অনেক ব্রাউজার পৃষ্ঠার বিষয়বস্তু কতটা বড় তা নির্ধারণ করার সময় স্কেলের জন্য অ্যাকাউন্ট করে, কিন্তু দুঃখজনকভাবে Chrome এবং Safari দৃষ্টিকোণকে বিবেচনা করে না । সুতরাং যদি সেখানে থাকে - বলুন - একটি উপাদানে 3x এর একটি স্কেল প্রয়োগ করা হয়, আপনি স্ক্রোল বার এবং এর মতো দেখতে পারেন, এমনকি যদি perspective প্রয়োগ করার পরে উপাদানটি 1x হয়। নীচের ডানদিকের কোণে ( transform-origin: bottom right ) থেকে উপাদানগুলিকে স্কেলিং করে এই সমস্যাটির সমাধান করা সম্ভব, যা কাজ করে কারণ এটি বড় আকারের উপাদানগুলির "নেতিবাচক অঞ্চল" (সাধারণত উপরের বাম দিকে) বৃদ্ধির কারণ হবে। স্ক্রোলযোগ্য এলাকা; স্ক্রোলযোগ্য অঞ্চলগুলি আপনাকে কখনই নেতিবাচক অঞ্চলের সামগ্রী দেখতে বা স্ক্রোল করতে দেয় না।

উপসংহার

প্যারালাক্সিং একটি মজাদার প্রভাব যখন চিন্তা করে ব্যবহার করা হয়। আপনি দেখতে পাচ্ছেন, এটি কার্যকরী, স্ক্রোল-কাপল্ড এবং ক্রস-ব্রাউজার এমনভাবে বাস্তবায়ন করা সম্ভব। যেহেতু কাঙ্খিত প্রভাব পেতে এটির জন্য কিছুটা গাণিতিক ঘেউ ঘেউ এবং অল্প পরিমাণে বয়লারপ্লেট প্রয়োজন, তাই আমরা একটি ছোট সহায়ক লাইব্রেরি এবং নমুনা তৈরি করেছি, যা আপনি আমাদের UI উপাদান নমুনা GitHub রেপোতে পাবেন।

একটি নাটক আছে, এবং আপনি কিভাবে পেতে আমাদের জানান.