বিল্ডিং Chrometober!

এই ক্রোমটোবারে মজাদার এবং ভীতিকর টিপস এবং কৌশলগুলি ভাগ করার জন্য স্ক্রোলিং বইটি কীভাবে প্রাণবন্ত হয়েছে৷

Designcember থেকে অনুসরণ করে, আমরা কমিউনিটি এবং Chrome টিমের ওয়েব বিষয়বস্তু হাইলাইট এবং শেয়ার করার উপায় হিসেবে এই বছর আপনার জন্য Chrometober তৈরি করতে চেয়েছিলাম। Designcember কন্টেইনার ক্যোয়ারী ব্যবহার প্রদর্শন করেছে, কিন্তু এই বছর আমরা CSS স্ক্রোল-লিঙ্কড অ্যানিমেশন API প্রদর্শন করছি।

web.dev/chrometober-2022- এ স্ক্রলিং বইয়ের অভিজ্ঞতা দেখুন।

ওভারভিউ

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

আমাদের দলের গঠন এই মত দেখায়:

একটি স্ক্রলিটেলিং অভিজ্ঞতার খসড়া তৈরি করা

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

প্রকল্পের সাথে সম্পর্কিত বিভিন্ন ডুডল এবং স্ক্রিবল সহ একটি নোটবুক একটি ডেস্কে রয়েছে।

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

ব্যবহারকারী যখন পাশ দিয়ে স্ক্রল করে, ব্লকগুলি ঘোরে এবং স্কেল করে। কিন্তু আমি কীভাবে সমস্ত আকারের ডিভাইসে ব্যবহারকারীদের জন্য এই অভিজ্ঞতাটিকে দুর্দান্ত করে তুলতে পারি সেই উদ্বেগের কারণে আমি এই ধারণা থেকে সরে যাওয়ার সিদ্ধান্ত নিয়েছি। পরিবর্তে, আমি অতীতে তৈরি করা কিছুর নকশার দিকে ঝুঁকেছি। 2020 সালে, রিলিজ ডেমো তৈরি করতে গ্রীনসকের স্ক্রোলট্রিগারে অ্যাক্সেস পেয়ে আমি ভাগ্যবান ছিলাম।

আমি যে ডেমোগুলি তৈরি করেছি তার মধ্যে একটি ছিল একটি 3D-CSS বই যেখানে আপনি স্ক্রোল করার সাথে সাথে পৃষ্ঠাগুলি উল্টে যায় এবং আমরা Chrometober এর জন্য যা চেয়েছিলাম তার জন্য এটি অনেক বেশি উপযুক্ত মনে হয়েছিল৷ স্ক্রোল-লিঙ্কড অ্যানিমেশন API সেই কার্যকারিতার জন্য একটি নিখুঁত অদলবদল। এটি scroll-snap সাথেও ভাল কাজ করে, যেমন আপনি দেখতে পাবেন!

প্রকল্পের জন্য আমাদের চিত্রকর, Tyler Reed , আমরা ধারণা পরিবর্তন করার সাথে সাথে নকশা পরিবর্তন করতে দুর্দান্ত ছিলেন। টাইলার তার প্রতি নিক্ষিপ্ত সমস্ত সৃজনশীল ধারণা গ্রহণ এবং সেগুলিকে জীবন্ত করার জন্য একটি দুর্দান্ত কাজ করেছিলেন। এটি একসাথে অনেক মজার চিন্তাভাবনা ছিল। আমরা কীভাবে এটি কাজ করতে চেয়েছিলাম তার একটি বড় অংশ ছিল বিচ্ছিন্ন ব্লকগুলিতে বিভক্ত বৈশিষ্ট্যগুলি। এইভাবে, আমরা সেগুলিকে দৃশ্যগুলিতে রচনা করতে পারি এবং তারপরে আমরা যা জীবন্ত এনেছি তা বাছাই করে বেছে নিতে পারি।

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

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

API এর সাথে পরিচিত হচ্ছেন

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

উচ্চ স্তরে, আপনি স্ক্রোল করার জন্য অ্যানিমেশন লিঙ্ক করতে এই API ব্যবহার করতে পারেন। এটা মনে রাখা গুরুত্বপূর্ণ যে আপনি স্ক্রলে একটি অ্যানিমেশন ট্রিগার করতে পারবেন না—এটি এমন কিছু যা পরে আসতে পারে। স্ক্রোল-লিঙ্কড অ্যানিমেশনগুলিও দুটি প্রধান বিভাগে পড়ে:

  1. যারা স্ক্রোল অবস্থানে প্রতিক্রিয়া.
  2. যারা তার স্ক্রলিং পাত্রে একটি উপাদান অবস্থান প্রতিক্রিয়া.

পরবর্তীটি তৈরি করতে, আমরা একটি animation-timeline সম্পত্তির মাধ্যমে প্রয়োগ করা একটি ViewTimeline ব্যবহার করি।

ViewTimeline ব্যবহার করে CSS-এ কেমন দেখায় তার একটি উদাহরণ এখানে দেওয়া হল:

.element-moving-in-viewport {
  view-timeline-name: foo;
  view-timeline-axis: block;
}

.element-scroll-linked {
  animation: rotate both linear;
  animation-timeline: foo;
  animation-delay: enter 0%;
  animation-end-delay: cover 50%;
}

@keyframes rotate {
 to {
   rotate: 360deg;
 }
}

আমরা view-timeline-name সহ একটি ViewTimeline তৈরি করি এবং এটির জন্য অক্ষ নির্ধারণ করি। এই উদাহরণে, block লজিক্যাল block বোঝায়। অ্যানিমেশনটি animation-timeline সম্পত্তির সাথে স্ক্রোল করার সাথে সংযুক্ত হয়। animation-delay এবং animation-end-delay (লেখার সময়) আমরা কীভাবে পর্যায়গুলি সংজ্ঞায়িত করি।

এই পর্যায়গুলি সেই পয়েন্টগুলিকে সংজ্ঞায়িত করে যেখানে অ্যানিমেশনটি তার স্ক্রলিং পাত্রে একটি উপাদানের অবস্থানের সাথে সংযুক্ত হওয়া উচিত। আমাদের উদাহরণে, আমরা বলছি অ্যানিমেশন শুরু করুন যখন উপাদানটি স্ক্রলিং কন্টেইনারে প্রবেশ করে ( enter 0% )। এবং এটি স্ক্রোলিং কন্টেইনারের 50% ( cover 50% ) ঢেকে গেলে শেষ করুন।

এখানে আমাদের কর্মের ডেমো:

আপনি ভিউপোর্টে চলমান উপাদানের সাথে একটি অ্যানিমেশন লিঙ্ক করতে পারেন। আপনি animation-timeline উপাদানটির view-timeline হিসাবে সেট করে এটি করতে পারেন। এটি তালিকা অ্যানিমেশনের মতো পরিস্থিতিগুলির জন্য ভাল। আচরণটি একই রকম যে আপনি IntersectionObserver ব্যবহার করে প্রবেশের সময় উপাদানগুলিকে অ্যানিমেট করতে পারেন।

element-moving-in-viewport {
  view-timeline-name: foo;
  view-timeline-axis: block;
  animation: scale both linear;
  animation-delay: enter 0%;
  animation-end-delay: cover 50%;
  animation-timeline: foo;
}

@keyframes scale {
  0% {
    scale: 0;
  }
}

এটির সাথে "মুভার" স্কেল বাড়ার সাথে সাথে এটি ভিউপোর্টে প্রবেশ করে, "স্পিনার" এর ঘূর্ণনকে ট্রিগার করে।

আমি পরীক্ষা করে যা পেয়েছি তা হল API স্ক্রোল-স্ন্যাপের সাথে খুব ভাল কাজ করে। ViewTimeline সাথে স্ক্রোল-স্ন্যাপ একটি বইতে পৃষ্ঠা ঘুরানোর জন্য একটি দুর্দান্ত ফিট হবে।

মেকানিক্সের প্রোটোটাইপিং

কিছু পরীক্ষা করার পরে, আমি একটি বইয়ের প্রোটোটাইপ কাজ করতে সক্ষম হয়েছি। বইয়ের পাতা উল্টাতে আপনি অনুভূমিকভাবে স্ক্রোল করুন।

ডেমোতে, আপনি ড্যাশ বর্ডার সহ হাইলাইট করা বিভিন্ন ট্রিগার দেখতে পাবেন।

মার্কআপটি কিছুটা এইরকম দেখাচ্ছে:

<body>
  <div class="book-placeholder">
    <ul class="book" style="--count: 7;">
      <li
        class="page page--cover page--cover-front"
        data-scroll-target="1"
        style="--index: 0;"
      >
        <div class="page__paper">
          <div class="page__side page__side--front"></div>
          <div class="page__side page__side--back"></div>
        </div>
      </li>
      <!-- Markup for other pages here -->
    </ul>
  </div>
  <div>
    <p>intro spacer</p>
  </div>
  <div data-scroll-intro>
    <p>scale trigger</p>
  </div>
  <div data-scroll-trigger="1">
    <p>page trigger</p>
  </div>
  <!-- Markup for other triggers here -->
</body>

আপনি স্ক্রোল করার সাথে সাথে বইয়ের পৃষ্ঠাগুলি উল্টে যায়, তবে স্ন্যাপ খোলা বা বন্ধ। এটি ট্রিগারগুলির স্ক্রোল-স্ন্যাপ প্রান্তিককরণের উপর নির্ভরশীল।

html {
  scroll-snap-type: x mandatory;
}

body {
  grid-template-columns: repeat(var(--trigger-count), auto);
  overflow-y: hidden;
  overflow-x: scroll;
  display: grid;
}

body > [data-scroll-trigger] {
  height: 100vh;
  width: clamp(10rem, 10vw, 300px);
}

body > [data-scroll-trigger] {
  scroll-snap-align: end;
}

এইবার, আমরা CSS-এ ViewTimeline সংযোগ করি না, কিন্তু JavaScript-এ ওয়েব অ্যানিমেশন API ব্যবহার করি। এটির অতিরিক্ত সুবিধা রয়েছে উপাদানগুলির একটি সেটের উপর লুপ করতে এবং প্রতিটি হাতে তৈরি করার পরিবর্তে আমাদের প্রয়োজনীয় ViewTimeline তৈরি করতে সক্ষম হওয়ার।

const triggers = document.querySelectorAll("[data-scroll-trigger]")

const commonProps = {
  delay: { phase: "enter", percent: CSS.percent(0) },
  endDelay: { phase: "enter", percent: CSS.percent(100) },
  fill: "both"
}

const setupPage = (trigger, index) => {
  const target = document.querySelector(
    `[data-scroll-target="${trigger.getAttribute("data-scroll-trigger")}"]`
  );

  const viewTimeline = new ViewTimeline({
    subject: trigger,
    axis: 'inline',
  });

  target.animate(
    [
      {
        transform: `translateZ(${(triggers.length - index) * 2}px)`
      },
      {
        transform: `translateZ(${(triggers.length - index) * 2}px)`,
        offset: 0.75
      },
      {
        transform: `translateZ(${(triggers.length - index) * -1}px)`
      }
    ],
    {
      timeline: viewTimeline,
      …commonProps,
    }
  );
  target.querySelector(".page__paper").animate(
    [
      {
        transform: "rotateY(0deg)"
      },
      {
        transform: "rotateY(-180deg)"
      }
    ],
    {
      timeline: viewTimeline,
      …commonProps,
    }
  );
};

const triggers = document.querySelectorAll('[data-scroll-trigger]')
triggers.forEach(setupPage);

প্রতিটি ট্রিগারের জন্য, আমরা একটি ViewTimeline তৈরি করি। তারপরে আমরা সেই ViewTimeline ব্যবহার করে ট্রিগারের সংশ্লিষ্ট পৃষ্ঠাটিকে অ্যানিমেট করি। এটি স্ক্রোল করার জন্য পৃষ্ঠার অ্যানিমেশনকে লিঙ্ক করে। আমাদের অ্যানিমেশনের জন্য, আমরা পৃষ্ঠার একটি উপাদানকে y-অক্ষে ঘুরিয়ে পৃষ্ঠাটি ঘুরিয়ে দিচ্ছি। এছাড়াও আমরা পৃষ্ঠাটিকে z-অক্ষে অনুবাদ করি যাতে এটি একটি বইয়ের মতো আচরণ করে।

সবগুলোকে একত্রে রাখ

একবার আমি বইটির মেকানিজম তৈরি করে ফেললে, আমি টাইলারের চিত্রগুলিকে জীবন্ত করার দিকে মনোনিবেশ করতে পারতাম।

অ্যাস্ট্রো

দলটি 2021 সালে ডিজাইনসেম্বারের জন্য Astro ব্যবহার করেছিল এবং আমি Chrometober-এর জন্য এটি আবার ব্যবহার করতে আগ্রহী। জিনিসগুলিকে উপাদানগুলিতে বিভক্ত করতে সক্ষম হওয়ার বিকাশকারীর অভিজ্ঞতা এই প্রকল্পের জন্য উপযুক্ত।

বই নিজেই একটি উপাদান. এটি পৃষ্ঠা উপাদানগুলির একটি সংগ্রহও। প্রতিটি পৃষ্ঠার দুটি দিক রয়েছে এবং তাদের ব্যাকড্রপ রয়েছে। একটি পৃষ্ঠার পাশের শিশুরা এমন উপাদান যা যোগ করা, সরানো এবং সহজে অবস্থান করা যায়।

একটি বই নির্মাণ

ব্লকগুলি পরিচালনা করা সহজ করা আমার জন্য গুরুত্বপূর্ণ ছিল। আমি দলের বাকিদের জন্য অবদান রাখা সহজ করতে চেয়েছিলাম।

একটি উচ্চ স্তরের পৃষ্ঠাগুলি একটি কনফিগারেশন অ্যারে দ্বারা সংজ্ঞায়িত করা হয়। অ্যারের প্রতিটি পৃষ্ঠা বস্তু একটি পৃষ্ঠার জন্য বিষয়বস্তু, ব্যাকড্রপ এবং অন্যান্য মেটাডেটা সংজ্ঞায়িত করে।

const pages = [
  {
    front: {
      marked: true,
      content: PageTwo,
      backdrop: spreadOne,
      darkBackdrop: spreadOneDark
    },
    back: {
      content: PageThree,
      backdrop: spreadTwo,
      darkBackdrop: spreadTwoDark
    },
    aria: `page 1`
  },
  /* Obfuscated page objects */
]

এই Book উপাদান পাস করা.

<Book pages={pages} />

Book উপাদান হল যেখানে স্ক্রলিং প্রক্রিয়া প্রয়োগ করা হয় এবং বইয়ের পৃষ্ঠাগুলি তৈরি করা হয়। প্রোটোটাইপ থেকে একই প্রক্রিয়া ব্যবহার করা হয়; কিন্তু আমরা বিশ্বব্যাপী তৈরি ViewTimeline একাধিক উদাহরণ শেয়ার করি।

window.CHROMETOBER_TIMELINES.push(viewTimeline);

এইভাবে, আমরা তাদের পুনরায় তৈরি করার পরিবর্তে অন্য কোথাও ব্যবহার করার জন্য টাইমলাইন শেয়ার করতে পারি। এই বিষয়ে পরে আরো.

পৃষ্ঠা রচনা

প্রতিটি পৃষ্ঠা একটি তালিকার মধ্যে একটি তালিকা আইটেম:

<ul class="book">
  {
    pages.map((page, index) => {
      const FrontSlot = page.front.content
      const BackSlot = page.back.content
      return (
        <Page
          index={index}
          cover={page.cover}
          aria={page.aria}
          backdrop={
            {
              front: {
                light: page.front.backdrop,
                dark: page.front.darkBackdrop
              },
              back: {
                light: page.back.backdrop,
                dark: page.back.darkBackdrop
              }
            }
          }>
          {page.front.content && <FrontSlot slot="front" />}    
          {page.back.content && <BackSlot slot="back" />}    
        </Page>
      )
    })
  }
</ul>

এবং সংজ্ঞায়িত কনফিগারেশন প্রতিটি Page উদাহরণে পাস হয়। পৃষ্ঠাগুলি প্রতিটি পৃষ্ঠায় বিষয়বস্তু সন্নিবেশ করার জন্য Astro এর স্লট বৈশিষ্ট্য ব্যবহার করে।

<li
  class={className}
  data-scroll-target={target}
  style={`--index:${index};`}
  aria-label={aria}
>
  <div class="page__paper">
    <div
      class="page__side page__side--front"
      aria-label={`Right page of ${index}`}
    >
      <picture>
        <source
          srcset={darkFront}
          media="(prefers-color-scheme: dark)"
          height="214"
          width="150"
        >
        <img
          src={lightFront}
          class="page__background page__background--right"
          alt=""
          aria-hidden="true"
          height="214"
          width="150"
        >
      </picture>
      <div class="page__content">
        <slot name="front" />
      </div>
    </div>
    <!-- Markup for back page -->
  </div>
</li>

এই কোডটি বেশিরভাগ কাঠামো সেট আপ করার জন্য। অবদানকারীরা এই কোডটি স্পর্শ না করেই বেশিরভাগ অংশের জন্য বইয়ের বিষয়বস্তুতে কাজ করতে পারে৷

ব্যাকড্রপ

একটি বইয়ের দিকে সৃজনশীল স্থানান্তরটি বিভাগগুলিকে বিভক্ত করা আরও সহজ করে তোলে এবং বইটির প্রতিটি স্প্রেড মূল নকশা থেকে নেওয়া একটি দৃশ্য।

পৃষ্ঠাটি বই থেকে চিত্র ছড়িয়েছে যাতে একটি কবরস্থানে একটি আপেল গাছ রয়েছে। কবরস্থানে একাধিক শিরোনাম রয়েছে এবং একটি বড় চাঁদের সামনে আকাশে একটি বাদুড় রয়েছে।

যেহেতু আমরা বইয়ের জন্য একটি আকৃতির অনুপাতের সিদ্ধান্ত নিয়েছিলাম, প্রতিটি পৃষ্ঠার ব্যাকড্রপে একটি ছবির উপাদান থাকতে পারে। সেই উপাদানটিকে 200% প্রস্থে সেট করা এবং পৃষ্ঠার পাশের উপর ভিত্তি করে object-position ব্যবহার করা কৌশলটি করে।

.page__background {
  height: 100%;
  width: 200%;
  object-fit: cover;
  object-position: 0 0;
  position: absolute;
  top: 0;
  left: 0;
}

.page__background--right {
  object-position: 100% 0;
}

পৃষ্ঠার বিষয়বস্তু

পৃষ্ঠাগুলির একটি তৈরি করা যাক। পৃষ্ঠা তিনে একটি পেঁচা যা একটি গাছে উঠে আসে।

কনফিগারেশনে সংজ্ঞায়িত হিসাবে এটি একটি PageThree উপাদান দিয়ে জনবহুল হয়। এটি একটি অ্যাস্ট্রো উপাদান ( PageThree.astro )। এই উপাদানগুলি দেখতে এইচটিএমএল ফাইলগুলির মতো তবে তাদের সামনের অংশের মতো শীর্ষে একটি কোড বেড়া রয়েছে৷ এটি আমাদের অন্যান্য উপাদান আমদানি করার মতো জিনিসগুলি করতে সক্ষম করে। পৃষ্ঠা তিনের উপাদানটি এইরকম দেখাচ্ছে:

---
import TreeOwl from '../TreeOwl/TreeOwl.astro'
import { contentBlocks } from '../../assets/content-blocks.json'
import ContentBlock from '../ContentBlock/ContentBlock.astro'
---
<TreeOwl/>
<ContentBlock {...contentBlocks[3]} id="four" />

<style is:global>
  .content-block--four {
    left: 30%;
    bottom: 10%;
  }
</style>

আবার, পৃষ্ঠাগুলি প্রকৃতিতে পরমাণু। তারা বৈশিষ্ট্য একটি সংগ্রহ থেকে নির্মিত হয়. পৃষ্ঠা তিনে একটি বিষয়বস্তু ব্লক এবং ইন্টারেক্টিভ পেঁচা রয়েছে, তাই প্রতিটির জন্য একটি উপাদান রয়েছে।

বিষয়বস্তু ব্লক হল বইয়ের মধ্যে দেখা সামগ্রীর লিঙ্ক। এগুলিও একটি কনফিগারেশন অবজেক্ট দ্বারা চালিত হয়।

{
 "contentBlocks": [
    {
      "id": "one",
      "title": "New in Chrome",
      "blurb": "Lift your spirits with a round up of all the tools and features in Chrome.",
      "link": "https://www.youtube.com/watch?v=qwdN1fJA_d8&list=PLNYkxOF6rcIDfz8XEA3loxY32tYh7CI3m"
    },
    …otherBlocks
  ]
}

এই কনফিগারেশনটি আমদানি করা হয় যেখানে সামগ্রী ব্লকের প্রয়োজন হয়। তারপর প্রাসঙ্গিক ব্লক কনফিগারেশন ContentBlock উপাদানে পাস হয়।

<ContentBlock {...contentBlocks[3]} id="four" />

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

<style is:global>
  .content-block--four {
    left: 30%;
    bottom: 10%;
  }
</style>

কিন্তু, একটি বিষয়বস্তু ব্লকের সাধারণ শৈলীগুলি উপাদান কোডের সাথে সহ-অবস্থিত থাকে।

.content-block {
  background: hsl(0deg 0% 0% / 70%);
  color: var(--gray-0);
  border-radius:  min(3vh, var(--size-4));
  padding: clamp(0.75rem, 2vw, 1.25rem);
  display: grid;
  gap: var(--size-2);
  position: absolute;
  cursor: pointer;
  width: 50%;
}

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

উচ্চ স্তরে, আমাদের পেঁচার উপাদান কিছু SVG আমদানি করে এবং Astro's Fragment ব্যবহার করে ইনলাইন করে।

---
import { default as Owl } from '../Features/Owl.svg?raw'
---
<Fragment set:html={Owl} />

এবং আমাদের পেঁচার অবস্থানের শৈলীগুলি উপাদান কোডের সাথে সহ-অবস্থিত।

.owl {
  width: 34%;
  left: 10%;
  bottom: 34%;
}

স্টাইলিংয়ের একটি অতিরিক্ত অংশ রয়েছে যা পেঁচার জন্য transform আচরণকে সংজ্ঞায়িত করে।

.owl__owl {
  transform-origin: 50% 100%;
  transform-box: fill-box;
}

transform-box ব্যবহার transform-origin প্রভাবিত করে। এটি এটিকে SVG-এর মধ্যে বস্তুর বাউন্ডিং বাক্সের সাথে আপেক্ষিক করে তোলে। পেঁচা নীচের কেন্দ্র থেকে উপরে উঠে আসে, তাই transform-origin: 50% 100%

মজার অংশ হল যখন আমরা পেঁচাটিকে আমাদের তৈরি করা ViewTimeline একটিতে লিঙ্ক করি:

const setUpOwl = () => {
   const owl = document.querySelector('.owl__owl');

   owl.animate([
     {
       translate: '0% 110%',
     },
     {
       translate: '0% 10%',
     },
   ], {
     timeline: CHROMETOBER_TIMELINES[1],
     delay: { phase: "enter", percent: CSS.percent(80) },
     endDelay: { phase: "enter", percent: CSS.percent(90) },
     fill: 'both' 
   });
 }

 if (window.matchMedia('(prefers-reduced-motion: no-preference)').matches)
   setUpOwl()

কোডের এই ব্লকে, আমরা দুটি জিনিস করি:

  1. ব্যবহারকারীর গতি পছন্দ জন্য পরীক্ষা করুন.
  2. যদি তাদের কোন পছন্দ না থাকে, পেঁচার একটি অ্যানিমেশন স্ক্রোল করতে লিঙ্ক করুন।

দ্বিতীয় অংশের জন্য, পেঁচা ওয়েব অ্যানিমেশন API ব্যবহার করে y-অক্ষে অ্যানিমেট করে। স্বতন্ত্র রূপান্তর সম্পত্তি translate ব্যবহার করা হয়, এবং একটি ViewTimeline সাথে লিঙ্ক করা হয়। এটি timeline প্রপার্টির মাধ্যমে CHROMETOBER_TIMELINES[1] এর সাথে লিঙ্ক করা হয়েছে। এটি একটি ViewTimeline যা পৃষ্ঠার পরিবর্তনের জন্য তৈরি করা হয়। এটি enter ফেজ ব্যবহার করে পেঁচার অ্যানিমেশনকে পেজ টার্নের সাথে লিঙ্ক করে। এটি সংজ্ঞায়িত করে যে, যখন পৃষ্ঠাটি 80% ঘুরিয়ে দেওয়া হয়, তখন পেঁচাটিকে সরানো শুরু করুন। 90% এ, পেঁচা তার অনুবাদ শেষ করা উচিত।

বই বৈশিষ্ট্য

এখন আপনি একটি পৃষ্ঠা তৈরি করার পদ্ধতি এবং প্রকল্পের আর্কিটেকচার কীভাবে কাজ করে তা দেখেছেন। আপনি দেখতে পারেন যে এটি কীভাবে অবদানকারীদের তাদের পছন্দের একটি পৃষ্ঠা বা বৈশিষ্ট্যে ঝাঁপিয়ে পড়তে এবং কাজ করতে দেয়৷ বইয়ের বিভিন্ন বৈশিষ্ট্যের সাথে তাদের অ্যানিমেশনগুলি বইয়ের পৃষ্ঠা ঘুরানোর সাথে যুক্ত রয়েছে; উদাহরণস্বরূপ, ব্যাট যেটি উড়ে যায় এবং পাতায় ঘুরতে থাকে।

এটিতে এমন উপাদান রয়েছে যা CSS অ্যানিমেশন দ্বারা চালিত হয়।

একবার বিষয়বস্তু ব্লকগুলি বইয়ে ছিল, অন্যান্য বৈশিষ্ট্যগুলির সাথে সৃজনশীল হওয়ার সময় ছিল। এটি কিছু ভিন্ন মিথস্ক্রিয়া তৈরি করার এবং জিনিসগুলি বাস্তবায়নের বিভিন্ন উপায় চেষ্টা করার একটি সুযোগ প্রদান করে।

জিনিষ প্রতিক্রিয়াশীল রাখা

প্রতিক্রিয়াশীল ভিউপোর্ট ইউনিট বই এবং এর বৈশিষ্ট্যের আকার দেয়। যাইহোক, ফন্ট প্রতিক্রিয়াশীল রাখা একটি আকর্ষণীয় চ্যালেঞ্জ ছিল. কন্টেইনার ক্যোয়ারী ইউনিট এখানে একটি ভাল ফিট. যদিও তারা এখনও সব জায়গায় সমর্থিত নয়। বইয়ের আকার সেট করা হয়েছে, তাই আমাদের একটি কন্টেইনার কোয়েরির প্রয়োজন নেই। একটি ইনলাইন কন্টেইনার ক্যোয়ারী ইউনিট CSS calc() দিয়ে তৈরি করা যেতে পারে এবং ফন্ট সাইজিংয়ের জন্য ব্যবহার করা যেতে পারে।


.book-placeholder {
  --size: clamp(12rem, 72vw, 80vmin);
  --aspect-ratio: 360 / 504;
  --cqi: calc(0.01 * (var(--size) * (var(--aspect-ratio))));
}

.content-block h2 {
  color: var(--gray-0);
  font-size: clamp(0.6rem, var(--cqi) * 4, 1.5rem);
}

.content-block :is(p, a) {
  font-size: clamp(0.6rem, var(--cqi) * 3, 1.5rem);
}

কুমড়ো রাতে জ্বলজ্বল করে

যারা তীক্ষ্ণ দৃষ্টি রাখেন তারা আগে পাতার ব্যাকড্রপ নিয়ে আলোচনা করার সময় <source> উপাদানের ব্যবহার লক্ষ্য করেছেন। উনা একটি মিথস্ক্রিয়া করতে আগ্রহী ছিল যা রঙের স্কিম পছন্দের প্রতিক্রিয়া জানায়। ফলস্বরূপ, ব্যাকড্রপগুলি বিভিন্ন রূপের সাথে হালকা এবং অন্ধকার উভয় মোড সমর্থন করে। যেহেতু আপনি <picture> উপাদানের সাথে মিডিয়া প্রশ্নগুলি ব্যবহার করতে পারেন, এটি দুটি ব্যাকড্রপ শৈলী প্রদান করার একটি দুর্দান্ত উপায়। রঙের স্কিম পছন্দের জন্য <source> উপাদান ক্যোয়ারী, এবং উপযুক্ত ব্যাকড্রপ দেখায়।

<picture>
  <source srcset={darkFront} media="(prefers-color-scheme: dark)" height="214" width="150">
  <img src={lightFront} class="page__background page__background--right" alt="" aria-hidden="true" height="214" width="150">
</picture>

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

.pumpkin__flame,
 .pumpkin__flame circle {
   transform-box: fill-box;
   transform-origin: 50% 100%;
 }

 .pumpkin__flame {
   scale: 0.8;
 }

 .pumpkin__flame circle {
   transition: scale 0.2s;
   scale: 0;
 }

@media(prefers-color-scheme: dark) {
   .pumpkin__flame {
     animation: pumpkin-flicker 3s calc(var(--index, 0) * -1s) infinite linear;
   }

   .pumpkin__flame circle {
     scale: 1;
   }

   @keyframes pumpkin-flicker {
     50% {
       scale: 1;
     }
   }
 }

এই প্রতিকৃতি আপনি দেখছেন?

আপনি পৃষ্ঠা 10 চেক আউট করলে, আপনি কিছু লক্ষ্য করতে পারেন। আপনাকে দেখা হচ্ছে! আপনি পৃষ্ঠার চারপাশে ঘোরাফেরা করার সাথে সাথে প্রতিকৃতির চোখ আপনার পয়েন্টারকে অনুসরণ করবে। এখানে কৌশলটি হল একটি অনুবাদ মানতে পয়েন্টার অবস্থান ম্যাপ করা, এবং এটি CSS-এ পাস করা।

const mapRange = (inputLower, inputUpper, outputLower, outputUpper, value) => {
   const INPUT_RANGE = inputUpper - inputLower
   const OUTPUT_RANGE = outputUpper - outputLower
   return outputLower + (((value - inputLower) / INPUT_RANGE) * OUTPUT_RANGE || 0)
 }

এই কোডটি ইনপুট এবং আউটপুট রেঞ্জ নেয় এবং প্রদত্ত মানগুলিকে ম্যাপ করে। উদাহরণস্বরূপ, এই ব্যবহারটি মান 625 দেবে।

mapRange(0, 100, 250, 1000, 50) // 625

প্রতিকৃতির জন্য, ইনপুট মান হল প্রতিটি চোখের কেন্দ্রবিন্দু, প্লাস বা বিয়োগ কিছু পিক্সেল দূরত্ব। আউটপুট পরিসীমা হল চোখ কতটা পিক্সেলে অনুবাদ করতে পারে। এবং তারপর x বা y অক্ষের পয়েন্টার অবস্থানটি মান হিসাবে পাস হয়। তাদের সরানোর সময় চোখের কেন্দ্রবিন্দু পেতে, চোখ নকল করা হয়। আসলগুলি সরানো হয় না, স্বচ্ছ এবং রেফারেন্সের জন্য ব্যবহৃত হয়।

তারপরে এটি একসাথে বেঁধে দেওয়া এবং চোখের উপর CSS কাস্টম সম্পত্তি মান আপডেট করার একটি কেস যাতে চোখ সরতে পারে। একটি ফাংশন window বিপরীতে pointermove ইভেন্টে আবদ্ধ। এই আগুনের সাথে সাথে, প্রতিটি চোখের সীমা কেন্দ্র বিন্দু গণনা করতে ব্যবহৃত হয়। তারপর পয়েন্টার অবস্থান মান ম্যাপ করা হয় যে চোখের উপর কাস্টম সম্পত্তি মান হিসাবে সেট করা হয়.

const RANGE = 15
const LIMIT = 80
const interact = ({ x, y }) => {
   // map a range against the eyes and pass in via custom properties
   const LEFT_EYE_BOUNDS = LEFT_EYE.getBoundingClientRect()
   const RIGHT_EYE_BOUNDS = RIGHT_EYE.getBoundingClientRect()

   const CENTERS = {
     lx: LEFT_EYE_BOUNDS.left + LEFT_EYE_BOUNDS.width * 0.5,
     rx: RIGHT_EYE_BOUNDS.left + RIGHT_EYE_BOUNDS.width * 0.5,
     ly: LEFT_EYE_BOUNDS.top + LEFT_EYE_BOUNDS.height * 0.5,
     ry: RIGHT_EYE_BOUNDS.top + RIGHT_EYE_BOUNDS.height * 0.5,
   }

   Object.entries(CENTERS)
     .forEach(([key, value]) => {
       const result = mapRange(value - LIMIT, value + LIMIT, -RANGE, RANGE)(key.indexOf('x') !== -1 ? x : y)
       EYES.style.setProperty(`--${key}`, result)
     })
 }

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

.portrait__eye--mover {
   transition: translate 0.2s;
 }

 .portrait__eye--mover.portrait__eye--left {
   translate:
     clamp(-10px, var(--lx, 0) * 1px, 4px)
     clamp(-4px, var(--ly, 0) * 0.5px, 10px);
 }

 .portrait__eye--mover.portrait__eye--right {
   translate:
     clamp(-4px, var(--rx, 0) * 1px, 10px)
     clamp(-4px, var(--ry, 0) * 0.5px, 10px);
 }

কাস্টিং বানান

আপনি যদি পৃষ্ঠা ছয়টি চেক আউট করেন, আপনি কি মন্ত্রমুগ্ধ বোধ করেন? এই পৃষ্ঠাটি আমাদের চমত্কার জাদুকরী শিয়ালের নকশাকে আলিঙ্গন করে। আপনি যদি আপনার পয়েন্টারটি চারপাশে সরান তবে আপনি একটি কাস্টম কার্সার ট্রেইল প্রভাব দেখতে পাবেন। এটি ক্যানভাস অ্যানিমেশন ব্যবহার করে। একটি <canvas> উপাদান pointer-events: none । এর মানে ব্যবহারকারীরা এখনও নীচের বিষয়বস্তু ব্লক ক্লিক করতে পারেন।

.wand-canvas {
  height: 100%;
  width: 200%;
  pointer-events: none;
  right: 0;
  position: fixed;
}

অনেকটা যেমন আমাদের পোর্ট্রেট window একটি pointermove ইভেন্টের জন্য শোনে, তেমনি আমাদের <canvas> উপাদানও। তবুও প্রতিবার ইভেন্ট ফায়ার হলে, আমরা <canvas> উপাদানে অ্যানিমেট করার জন্য একটি বস্তু তৈরি করছি। এই বস্তুগুলি কার্সার ট্রেইলে ব্যবহৃত আকারগুলিকে উপস্থাপন করে। তাদের স্থানাঙ্ক এবং একটি এলোমেলো রঙ আছে।

আগের থেকে আমাদের mapRange ফাংশনটি আবার ব্যবহার করা হয়েছে, কারণ আমরা এটিকে ব্যবহার করতে পারি পয়েন্টার ডেল্টাকে size এবং rate ম্যাপ করতে। বস্তুগুলিকে একটি অ্যারেতে সংরক্ষণ করা হয় যেটি লুপ হয়ে যায় যখন বস্তুগুলিকে <canvas> উপাদানে আঁকা হয়। প্রতিটি বস্তুর বৈশিষ্ট্য আমাদের <canvas> উপাদানকে বলে যেখানে জিনিসগুলি আঁকতে হবে।

const blocks = []
  const createBlock = ({ x, y, movementX, movementY }) => {
    const LOWER_SIZE = CANVAS.height * 0.05
    const UPPER_SIZE = CANVAS.height * 0.25
    const size = mapRange(0, 100, LOWER_SIZE, UPPER_SIZE, Math.max(Math.abs(movementX), Math.abs(movementY)))
    const rate = mapRange(LOWER_SIZE, UPPER_SIZE, 1, 5, size)
    const { left, top, width, height } = CANVAS.getBoundingClientRect()
    
    const block = {
      hue: Math.random() * 359,
      x: x - left,
      y: y - top,
      size,
      rate,
    }
    
    blocks.push(block)
  }
window.addEventListener('pointermove', createBlock)

ক্যানভাসে আঁকার জন্য, requestAnimationFrame দিয়ে একটি লুপ তৈরি করা হয়। পৃষ্ঠাটি দেখার সময় কার্সার ট্রেইল শুধুমাত্র রেন্ডার করা উচিত। আমাদের একটি IntersectionObserver আছে যা আপডেট করে এবং নির্ধারণ করে যে কোন পৃষ্ঠাগুলি দেখা যাচ্ছে৷ একটি পৃষ্ঠা দৃশ্যমান হলে, বস্তুগুলি ক্যানভাসে চেনাশোনা হিসাবে রেন্ডার করা হয়।

তারপরে আমরা blocks অ্যারের উপর লুপ করি এবং ট্রেইলের প্রতিটি অংশ আঁকি। প্রতিটি ফ্রেম আকার হ্রাস করে এবং rate দ্বারা বস্তুর অবস্থান পরিবর্তন করে। এটি পতনশীল এবং স্কেলিং প্রভাব তৈরি করে। বস্তুটি সম্পূর্ণ সঙ্কুচিত হলে, অবজেক্টটি blocks অ্যারে থেকে সরানো হয়।

let wandFrame
const drawBlocks = () => {
   ctx.clearRect(0, 0, CANVAS.width, CANVAS.height)
  
   if (PAGE_SIX.className.indexOf('in-view') === -1 && wandFrame) {
     blocks.length = 0
     cancelAnimationFrame(wandFrame)
     document.body.removeEventListener('pointermove', createBlock)
     document.removeEventListener('resize', init)
   }
  
   for (let b = 0; b < blocks.length; b++) {
     const block = blocks[b]
     ctx.strokeStyle = ctx.fillStyle = `hsla(${block.hue}, 80%, 80%, 0.5)`
     ctx.beginPath()
     ctx.arc(block.x, block.y, block.size * 0.5, 0, 2 * Math.PI)
     ctx.stroke()
     ctx.fill()

     block.size -= block.rate
     block.y += block.rate

     if (block.size <= 0) {
       blocks.splice(b, 1)
     }

   }
   wandFrame = requestAnimationFrame(drawBlocks)
 }

পৃষ্ঠাটি দৃশ্যের বাইরে চলে গেলে, ইভেন্ট শ্রোতাদের সরানো হয় এবং অ্যানিমেশন ফ্রেম লুপ বাতিল করা হয়। blocks অ্যারেও সাফ করা হয়েছে।

এখানে কার্সার ট্রেইল অ্যাকশন!

অ্যাক্সেসযোগ্যতা পর্যালোচনা

এটি অন্বেষণ করার জন্য একটি মজার অভিজ্ঞতা তৈরি করা ভাল, তবে এটি ব্যবহারকারীদের কাছে অ্যাক্সেসযোগ্য না হলে এটি ভাল নয়৷ রিলিজের আগে একটি অ্যাক্সেসিবিলিটি পর্যালোচনার জন্য Chrometober প্রস্তুত করার ক্ষেত্রে অ্যাডামের দক্ষতা এই ক্ষেত্রে অমূল্য প্রমাণিত হয়েছে৷

কভার করা উল্লেখযোগ্য কিছু এলাকা:

  • ব্যবহৃত HTML শব্দার্থিক ছিল তা নিশ্চিত করা। এটি বইয়ের জন্য উপযুক্ত ল্যান্ডমার্ক উপাদান যেমন <main> এর মতো বিষয়গুলি অন্তর্ভুক্ত করেছে; প্রতিটি বিষয়বস্তুর ব্লকের জন্য <article> উপাদানের ব্যবহার এবং <abbr> উপাদান যেখানে সংক্ষিপ্ত শব্দগুলি চালু করা হয়েছে। বইটি তৈরি হওয়ার সাথে সাথে সামনের দিকে চিন্তা করা জিনিসগুলিকে আরও অ্যাক্সেসযোগ্য করে তুলেছে। শিরোনাম এবং লিঙ্কগুলির ব্যবহার একজন ব্যবহারকারীকে নেভিগেট করা সহজ করে তোলে। পৃষ্ঠাগুলির জন্য একটি তালিকা ব্যবহার করার অর্থ হল সহায়ক প্রযুক্তি দ্বারা পৃষ্ঠাগুলির সংখ্যা ঘোষণা করা হয়৷
  • নিশ্চিত করা হচ্ছে যে সমস্ত ছবিতে উপযুক্ত alt বৈশিষ্ট্য ব্যবহার করা হয়েছে৷ ইনলাইন SVG-এর জন্য, যেখানে প্রয়োজন সেখানে title উপাদান উপস্থিত থাকে।
  • aria বৈশিষ্ট্য ব্যবহার করে যেখানে তারা অভিজ্ঞতা উন্নত করে। পৃষ্ঠা এবং তাদের পাশের জন্য aria-label ব্যবহার ব্যবহারকারীর কাছে যোগাযোগ করে যে তারা কোন পৃষ্ঠায় রয়েছে। "আরও পড়ুন" লিঙ্কগুলিতে aria-describedBy এর ব্যবহার বিষয়বস্তু ব্লকের পাঠ্যের সাথে যোগাযোগ করে। এটি লিঙ্কটি ব্যবহারকারীকে কোথায় নিয়ে যাবে সে সম্পর্কে অস্পষ্টতা দূর করে।
  • বিষয়বস্তু ব্লকের বিষয়ে, পুরো কার্ডে ক্লিক করার ক্ষমতা এবং শুধুমাত্র "আরও পড়ুন" লিঙ্কটি উপলব্ধ নয়।
  • কোন পৃষ্ঠাগুলি দৃশ্যমান রয়েছে তা ট্র্যাক করতে একটি IntersectionObserver এর ব্যবহার আগে এসেছে৷ এটির অনেক সুবিধা রয়েছে যা শুধুমাত্র কর্মক্ষমতা সম্পর্কিত নয়। যে পৃষ্ঠাগুলি দেখা যাচ্ছে না সেগুলির কোনও অ্যানিমেশন বা ইন্টারঅ্যাকশন বিরাম দেওয়া হবে৷ কিন্তু এই পৃষ্ঠাগুলিতেও inert বৈশিষ্ট্য প্রয়োগ করা হয়েছে। এর মানে হল যে ব্যবহারকারীরা স্ক্রিন রিডার ব্যবহার করে তারা একই বিষয়বস্তু অন্বেষণ করতে পারে যেমনটি দর্শনীয় ব্যবহারকারীদের। যে পৃষ্ঠাটি দেখা যাচ্ছে তার মধ্যেই ফোকাস থাকে এবং ব্যবহারকারীরা অন্য পৃষ্ঠায় ট্যাব করতে পারে না।
  • সবশেষে কিন্তু অন্তত নয়, গতির জন্য ব্যবহারকারীর পছন্দকে সম্মান করতে আমরা মিডিয়া কোয়েরি ব্যবহার করি।

এখানে কিছু ব্যবস্থা তুলে ধরার পর্যালোচনা থেকে একটি স্ক্রিনশট রয়েছে।

উপাদানটিকে পুরো বইয়ের চারপাশে চিহ্নিত করা হয়েছে, এটি নির্দেশ করে যে এটি সহায়ক প্রযুক্তি ব্যবহারকারীদের খুঁজে পাওয়ার জন্য প্রধান ল্যান্ডমার্ক হওয়া উচিত। স্ক্রিনশটে আরও বর্ণনা করা হয়েছে৷" width="800" height="465">৷

Chrometober বইয়ের স্ক্রিনশট খুলুন। সবুজ রূপরেখাযুক্ত বাক্সগুলি UI এর বিভিন্ন দিকগুলির চারপাশে সরবরাহ করা হয়েছে, উদ্দেশ্যযুক্ত অ্যাক্সেসিবিলিটি কার্যকারিতা এবং পৃষ্ঠাটি সরবরাহ করবে এমন ব্যবহারকারীর অভিজ্ঞতার ফলাফলগুলি বর্ণনা করে। উদাহরণ স্বরূপ, ইমেজে অল্ট টেক্সট আছে। আরেকটি উদাহরণ হল একটি অ্যাক্সেসিবিলিটি লেবেল যা ঘোষণা করে যে দৃশ্যের বাইরে থাকা পৃষ্ঠাগুলি নিষ্ক্রিয়। আরো স্ক্রিনশট রূপরেখা আছে.

আমরা যা শিখেছি

Chrometober-এর পিছনে অনুপ্রেরণা শুধুমাত্র সম্প্রদায়ের ওয়েব বিষয়বস্তু হাইলাইট করাই নয়, এটি আমাদের জন্য স্ক্রোল-লিঙ্কড অ্যানিমেশন API পলিফিল পরীক্ষা করার একটি উপায় ছিল যা বিকাশে রয়েছে।

নিউইয়র্কে আমাদের দলের শীর্ষ সম্মেলনের সময় আমরা প্রকল্পটি পরীক্ষা করতে এবং উদ্ভূত সমস্যাগুলি মোকাবেলা করার জন্য একটি সেশন আলাদা করে রেখেছিলাম। দলের অবদান ছিল অমূল্য। আমরা লাইভে যেতে পারার আগে যে সমস্ত জিনিসগুলি মোকাবেলা করতে হবে তা তালিকাভুক্ত করারও এটি একটি দুর্দান্ত সুযোগ ছিল।

CSS, UI, এবং DevTools টিম একটি কনফারেন্স রুমে টেবিলের চারপাশে বসে আছে। উনা একটি সাদা বোর্ডে দাঁড়িয়ে আছে যা স্টিকি নোটে আবৃত। দলের অন্যান্য সদস্যরা খাবার এবং ল্যাপটপ নিয়ে টেবিলের চারপাশে বসে আছে।

উদাহরণস্বরূপ, ডিভাইসে বই পরীক্ষা করা একটি রেন্ডারিং সমস্যা উত্থাপন করেছে। আমাদের বইটি iOS ডিভাইসে প্রত্যাশিতভাবে রেন্ডার করবে না। ভিউপোর্ট ইউনিট পৃষ্ঠার আকার, কিন্তু যখন একটি খাঁজ উপস্থিত ছিল, এটি বইটিকে প্রভাবিত করে। সমাধানটি ছিল meta ভিউপোর্টে viewport-fit=cover ব্যবহার করা:

<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />

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

Chrome এ খোলা একটি ডেমোর একটি স্ক্রিনশট৷ বিকাশকারী সরঞ্জামগুলি খোলা এবং একটি বেসলাইন কর্মক্ষমতা পরিমাপ দেখায়৷

Chrome এ খোলা একটি ডেমোর একটি স্ক্রিনশট৷ বিকাশকারী সরঞ্জামগুলি খোলা রয়েছে এবং একটি উন্নত কর্মক্ষমতা পরিমাপ দেখায়৷

এটাই!

এটি কাজ করার জন্য একটি সত্যিকারের মজাদার প্রজেক্ট হয়েছে, যার ফলে একটি বাতিকপূর্ণ স্ক্রোলিং অভিজ্ঞতা রয়েছে যা সম্প্রদায় থেকে আশ্চর্যজনক বিষয়বস্তু হাইলাইট করে। শুধু তাই নয়, পলিফিল পরীক্ষা করার জন্য, সেইসাথে পলিফিল উন্নত করতে সাহায্য করার জন্য ইঞ্জিনিয়ারিং টিমকে প্রতিক্রিয়া প্রদান করার জন্য এটি দুর্দান্ত।

Chrometober 2022 একটি মোড়ানো।

আমরা আশা করি আপনি এটি উপভোগ করেছেন! আপনার প্রিয় বৈশিষ্ট্য কি? আমাকে টুইট করুন এবং আমাদের জানান!

ক্রোমটোবার থেকে অক্ষরের একটি স্টিকার শীট ধারণ করছে ঝি।

এমনকি আপনি যদি কোনো ইভেন্টে আমাদের দেখেন তাহলে আপনি হয়তো দলের একজনের কাছ থেকে কিছু স্টিকার নিতে সক্ষম হবেন।

আনস্প্ল্যাশে ডেভিড মেনিড্রেয়ের হিরো ছবি