একক-পৃষ্ঠার অ্যাপ্লিকেশনের জন্য একই-নথি দৃশ্য রূপান্তর

প্রকাশিত: আগস্ট 17, 2021, শেষ আপডেট: সেপ্টেম্বর 25, 2024

যখন একটি ভিউ ট্রানজিশন একটি একক নথিতে চলে তখন একে একই-ডকুমেন্ট ভিউ ট্রানজিশন বলে। এটি সাধারণত একক-পৃষ্ঠা অ্যাপ্লিকেশন (এসপিএ) এর ক্ষেত্রে হয় যেখানে জাভাস্ক্রিপ্ট DOM আপডেট করতে ব্যবহৃত হয়। একই-ডকুমেন্ট ভিউ ট্রানজিশনগুলি Chrome 111-এর মতো Chrome-এ সমর্থিত।

একই-ডকুমেন্ট ভিউ ট্রানজিশন ট্রিগার করতে, document.startViewTransition কল করুন:

function handleClick(e) {
  // Fallback for browsers that don't support this API:
  if (!document.startViewTransition) {
    updateTheDOMSomehow();
    return;
  }

  // With a View Transition:
  document.startViewTransition(() => updateTheDOMSomehow());
}

যখন আহ্বান করা হয়, ব্রাউজার স্বয়ংক্রিয়ভাবে সমস্ত উপাদানের স্ন্যাপশট ক্যাপচার করে যেগুলির উপর একটি view-transition-name CSS সম্পত্তি রয়েছে।

এটি তারপরে পাস করা কলব্যাকে কার্যকর করে যা DOM আপডেট করে, তারপরে এটি নতুন অবস্থার স্ন্যাপশট নেয়।

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


ডিফল্ট রূপান্তর: ক্রস-ফেইড

ডিফল্ট ভিউ ট্রানজিশন একটি ক্রস-ফেড, তাই এটি API-এর একটি সুন্দর ভূমিকা হিসেবে কাজ করে:

function spaNavigate(data) {
  // Fallback for browsers that don't support this API:
  if (!document.startViewTransition) {
    updateTheDOMSomehow(data);
    return;
  }

  // With a transition:
  document.startViewTransition(() => updateTheDOMSomehow(data));
}

যেখানে updateTheDOMSomehow DOM কে নতুন অবস্থায় পরিবর্তন করে। যেটা আপনি চাইলেই করা যেতে পারে। উদাহরণস্বরূপ, আপনি উপাদান যোগ করতে বা সরাতে পারেন, শ্রেণির নাম পরিবর্তন করতে পারেন বা শৈলী পরিবর্তন করতে পারেন।

এবং ঠিক সেই মত, পৃষ্ঠাগুলি ক্রস-ফেড:

ডিফল্ট ক্রস ফেইড. ন্যূনতম ডেমোউৎস

ঠিক আছে, একটি ক্রস-ফেড যে চিত্তাকর্ষক নয়। সৌভাগ্যক্রমে, রূপান্তরগুলি কাস্টমাইজ করা যেতে পারে, তবে প্রথমে, আপনাকে বুঝতে হবে কিভাবে এই মৌলিক ক্রস-ফেড কাজ করে।


কিভাবে এই রূপান্তর কাজ

আগের কোড নমুনা আপডেট করা যাক.

document.startViewTransition(() => updateTheDOMSomehow(data));

যখন .startViewTransition() কল করা হয়, API পৃষ্ঠার বর্তমান অবস্থা ক্যাপচার করে। এর মধ্যে একটি স্ন্যাপশট নেওয়া অন্তর্ভুক্ত।

একবার সম্পূর্ণ হলে, .startViewTransition() এ পাস করা কলব্যাক বলা হয়। যে যেখানে DOM পরিবর্তন করা হয়. তারপর, API পৃষ্ঠার নতুন অবস্থা ক্যাপচার করে।

একবার নতুন অবস্থা ক্যাপচার করা হলে, API এই মত একটি ছদ্ম-উপাদান গাছ তৈরি করে:

::view-transition
└─ ::view-transition-group(root)
   └─ ::view-transition-image-pair(root)
      ├─ ::view-transition-old(root)
      └─ ::view-transition-new(root)

::view-transition পৃষ্ঠার অন্য সব কিছুর উপরে একটি ওভারলেতে বসে। আপনি যদি রূপান্তরের জন্য একটি পটভূমির রঙ সেট করতে চান তবে এটি কার্যকর।

::view-transition-old(root) হল পুরানো ভিউ এর একটি স্ক্রিনশট, এবং ::view-transition-new(root) হল নতুন ভিউ এর একটি লাইভ উপস্থাপনা৷ উভয়ই CSS 'প্রতিস্থাপিত সামগ্রী' হিসাবে রেন্ডার করে (যেমন একটি <img> )।

পুরানো ভিউ opacity: 1 থেকে opacity: 0 , যখন নতুন ভিউ opacity: 0 থেকে opacity: 1 , একটি ক্রস-ফেড তৈরি করে।

সমস্ত অ্যানিমেশন সিএসএস অ্যানিমেশন ব্যবহার করে সঞ্চালিত হয়, তাই সেগুলি সিএসএস দিয়ে কাস্টমাইজ করা যায়।

রূপান্তর কাস্টমাইজ করুন

সমস্ত ভিউ ট্রানজিশন সিউডো-এলিমেন্ট CSS দিয়ে টার্গেট করা যেতে পারে এবং যেহেতু অ্যানিমেশনগুলি CSS ব্যবহার করে সংজ্ঞায়িত করা হয়েছে, আপনি বিদ্যমান CSS অ্যানিমেশন বৈশিষ্ট্যগুলি ব্যবহার করে সেগুলি পরিবর্তন করতে পারেন। যেমন:

::view-transition-old(root),
::view-transition-new(root) {
  animation-duration: 5s;
}

সেই একটি পরিবর্তনের সাথে, বিবর্ণ এখন সত্যিই ধীর:

দীর্ঘ ক্রস-বিবর্ণ. ন্যূনতম ডেমোউৎস

ঠিক আছে, এটি এখনও চিত্তাকর্ষক নয়। পরিবর্তে, নিম্নলিখিত কোডটি মেটেরিয়াল ডিজাইনের ভাগ করা অক্ষ পরিবর্তনকে প্রয়োগ করে:

@keyframes fade-in {
  from { opacity: 0; }
}

@keyframes fade-out {
  to { opacity: 0; }
}

@keyframes slide-from-right {
  from { transform: translateX(30px); }
}

@keyframes slide-to-left {
  to { transform: translateX(-30px); }
}

::view-transition-old(root) {
  animation: 90ms cubic-bezier(0.4, 0, 1, 1) both fade-out,
    300ms cubic-bezier(0.4, 0, 0.2, 1) both slide-to-left;
}

::view-transition-new(root) {
  animation: 210ms cubic-bezier(0, 0, 0.2, 1) 90ms both fade-in,
    300ms cubic-bezier(0.4, 0, 0.2, 1) both slide-from-right;
}

এবং এখানে ফলাফল:

ভাগ করা অক্ষ পরিবর্তন। ন্যূনতম ডেমোউৎস

রূপান্তর একাধিক উপাদান

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

এটি এড়াতে, আপনি বাকি পৃষ্ঠা থেকে শিরোনামটি বের করতে পারেন যাতে এটি আলাদাভাবে অ্যানিমেট করা যায়। এটি উপাদানটিতে একটি view-transition-name বরাদ্দ করে করা হয়।

.main-header {
  view-transition-name: main-header;
}

view-transition-name মান আপনি যা চান তা হতে পারে ( none ছাড়া, যার মানে কোনও পরিবর্তনের নাম নেই)। এটি রূপান্তর জুড়ে উপাদানটিকে অনন্যভাবে সনাক্ত করতে ব্যবহৃত হয়।

এবং এর ফলাফল:

স্থির শিরোনাম সহ ভাগ করা অক্ষ পরিবর্তন। ন্যূনতম ডেমোউৎস

এখন হেডার জায়গায় থাকে এবং ক্রস-বিবর্ণ হয়।

সেই CSS ঘোষণার ফলে ছদ্ম-উপাদান গাছটি পরিবর্তন হয়েছে:

::view-transition
├─ ::view-transition-group(root)
│  └─ ::view-transition-image-pair(root)
│     ├─ ::view-transition-old(root)
│     └─ ::view-transition-new(root)
└─ ::view-transition-group(main-header)
   └─ ::view-transition-image-pair(main-header)
      ├─ ::view-transition-old(main-header)
      └─ ::view-transition-new(main-header)

এখন দুটি ট্রানজিশন গ্রুপ আছে। শিরোনাম জন্য একটি, এবং বাকি জন্য অন্য. এগুলোকে CSS দিয়ে স্বাধীনভাবে টার্গেট করা যায় এবং বিভিন্ন ট্রানজিশন দেওয়া যায়। যদিও, এই ক্ষেত্রে main-header ডিফল্ট রূপান্তর সহ বাকি ছিল, যা একটি ক্রস-ফেড।

আচ্ছা, ঠিক আছে, ডিফল্ট ট্রানজিশন শুধু ক্রস ফেইড নয়, ::view-transition-group ও ট্রানজিশন করে:

  • অবস্থান এবং রূপান্তর (একটি transform ব্যবহার করে)
  • প্রস্থ
  • উচ্চতা

এটি এখন পর্যন্ত গুরুত্বপূর্ণ নয়, কারণ শিরোনামটি একই আকার এবং DOM পরিবর্তনের উভয় দিকে অবস্থান। তবে আপনি শিরোনামে পাঠ্যটিও বের করতে পারেন:

.main-header-text {
  view-transition-name: main-header-text;
  width: fit-content;
}

fit-content ব্যবহার করা হয় তাই উপাদানটি বাকি প্রস্থে প্রসারিত না হয়ে পাঠ্যের আকার। এটি ছাড়া, পিছনের তীরটি উভয় পৃষ্ঠায় একই আকারের পরিবর্তে হেডার পাঠ্য উপাদানের আকার হ্রাস করে।

সুতরাং এখন আমাদের সাথে খেলতে তিনটি অংশ রয়েছে:

::view-transition
├─ ::view-transition-group(root)
│  └─ …
├─ ::view-transition-group(main-header)
│  └─ …
└─ ::view-transition-group(main-header-text)
   └─ …

কিন্তু আবার, শুধু ডিফল্টের সাথে যাচ্ছে:

স্লাইডিং হেডার টেক্সট। ন্যূনতম ডেমোউৎস

এখন হেডিং টেক্সট পিছনের বোতামের জন্য জায়গা তৈরি করতে একটু সন্তোষজনক স্লাইড করে।


view-transition-class সাথে একইভাবে একাধিক সিউডো-এলিমেন্ট অ্যানিমেট করুন

ব্রাউজার সমর্থন

  • ক্রোম: 125।
  • প্রান্ত: 125।
  • ফায়ারফক্স: সমর্থিত নয়।
  • সাফারি প্রযুক্তি পূর্বরূপ: সমর্থিত।

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

h1 {
    view-transition-name: title;
}
::view-transition-group(title) {
    animation-timing-function: ease-in-out;
}

#card1 { view-transition-name: card1; }
#card2 { view-transition-name: card2; }
#card3 { view-transition-name: card3; }
#card4 { view-transition-name: card4; }
…
#card20 { view-transition-name: card20; }

::view-transition-group(card1),
::view-transition-group(card2),
::view-transition-group(card3),
::view-transition-group(card4),
…
::view-transition-group(card20) {
    animation-timing-function: var(--bounce);
}

20টি উপাদান পেয়েছেন? যে 20 নির্বাচক আপনার লিখতে হবে. একটি নতুন উপাদান যোগ করা হচ্ছে? তারপরে আপনাকে নির্বাচক বাড়াতে হবে যা অ্যানিমেশন শৈলীগুলি প্রয়োগ করে। ঠিক মাপযোগ্য নয়।

একই শৈলীর নিয়ম প্রয়োগ করতে view-transition-class ভিউ ট্রানজিশন সিউডো-এলিমেন্টগুলিতে ব্যবহার করা যেতে পারে।

#card1 { view-transition-name: card1; }
#card2 { view-transition-name: card2; }
#card3 { view-transition-name: card3; }
#card4 { view-transition-name: card4; }
#card5 { view-transition-name: card5; }
…
#card20 { view-transition-name: card20; }

#cards-wrapper > div {
  view-transition-class: card;
}
html::view-transition-group(.card) {
  animation-timing-function: var(--bounce);
}

নিম্নলিখিত কার্ডের উদাহরণ পূর্ববর্তী সিএসএস স্নিপেটটি ব্যবহার করে। সমস্ত কার্ড-সদ্য যোগ করাগুলি সহ-একটি নির্বাচকের সাথে একই সময় প্রয়োগ করুন: html::view-transition-group(.card)

কার্ড ডেমো রেকর্ডিং. view-transition-class ব্যবহার করে এটি যোগ করা বা সরানো ছাড়া সমস্ত কার্ডে একই animation-timing-function প্রয়োগ করে।

ডিবাগ ট্রানজিশন

যেহেতু ভিউ ট্রানজিশনগুলি CSS অ্যানিমেশনগুলির উপরে তৈরি করা হয়, তাই Chrome DevTools-এর অ্যানিমেশন প্যানেলটি ডিবাগিং ট্রানজিশনের জন্য দুর্দান্ত৷

অ্যানিমেশন প্যানেল ব্যবহার করে, আপনি পরবর্তী অ্যানিমেশন থামাতে পারেন, তারপর অ্যানিমেশনের মাধ্যমে সামনে পিছনে স্ক্রাব করতে পারেন। এই সময়, রূপান্তর ছদ্ম-উপাদান উপাদান প্যানেলে পাওয়া যাবে.

Chrome DevTools দিয়ে ডিবাগিং ভিউ ট্রানজিশন।

রূপান্তর উপাদান একই DOM উপাদান হতে হবে না

এখন পর্যন্ত আমরা হেডার এবং হেডারের পাঠ্যের জন্য পৃথক রূপান্তর উপাদান তৈরি করতে view-transition-name ব্যবহার করেছি। এগুলি ধারণাগতভাবে DOM পরিবর্তনের আগে এবং পরে একই উপাদান, তবে আপনি পরিবর্তনগুলি তৈরি করতে পারেন যেখানে এটি হয় না।

উদাহরণস্বরূপ, প্রধান ভিডিও এম্বেডকে একটি view-transition-name দেওয়া যেতে পারে:

.full-embed {
  view-transition-name: full-embed;
}

তারপর, থাম্বনেইলে ক্লিক করা হলে, এটিকে একই view-transition-name দেওয়া যেতে পারে, শুধুমাত্র ট্রানজিশনের সময়কালের জন্য:

thumbnail.onclick = async () => {
  thumbnail.style.viewTransitionName = 'full-embed';

  document.startViewTransition(() => {
    thumbnail.style.viewTransitionName = '';
    updateTheDOMSomehow();
  });
};

এবং ফলাফল:

একটি উপাদান অন্যটিতে রূপান্তরিত হচ্ছে। ন্যূনতম ডেমোউৎস

থাম্বনেইল এখন মূল ছবিতে রূপান্তরিত হয়। যদিও তারা ধারণাগতভাবে (এবং আক্ষরিক অর্থে) ভিন্ন উপাদান, ট্রানজিশন API তাদের একই জিনিস হিসাবে বিবেচনা করে কারণ তারা একই view-transition-name ভাগ করেছে।

এই রূপান্তরের আসল কোডটি পূর্ববর্তী উদাহরণের তুলনায় একটু বেশি জটিল, কারণ এটি থাম্বনেইল পৃষ্ঠায় রূপান্তরটি পরিচালনা করে। সম্পূর্ণ বাস্তবায়নের জন্য উৎস দেখুন


কাস্টম এন্ট্রি এবং প্রস্থান ট্রানজিশন

এই উদাহরণ দেখুন:

সাইডবারে প্রবেশ এবং প্রস্থান করা। ন্যূনতম ডেমোউৎস

সাইডবারটি রূপান্তরের অংশ:

.sidebar {
  view-transition-name: sidebar;
}

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

::view-transition
├─ …other transition groups…
└─ ::view-transition-group(sidebar)
   └─ ::view-transition-image-pair(sidebar)
      ├─ ::view-transition-old(sidebar)
      └─ ::view-transition-new(sidebar)

যাইহোক, যদি সাইডবার শুধুমাত্র নতুন পৃষ্ঠায় থাকে, তাহলে ::view-transition-old(sidebar) ছদ্ম-উপাদান সেখানে থাকবে না। যেহেতু সাইডবারের জন্য কোনো 'পুরানো' ছবি নেই, তাই ইমেজ-পেয়ারে শুধুমাত্র একটি ::view-transition-new(sidebar) থাকবে। একইভাবে, যদি সাইডবার শুধুমাত্র পুরানো পৃষ্ঠায় থাকে, তাহলে ইমেজ-পেয়ারে শুধুমাত্র একটি ::view-transition-old(sidebar) থাকবে।

পূর্ববর্তী ডেমোতে, সাইডবারটি ভিন্নভাবে রূপান্তরিত হয় তা নির্ভর করে যে এটি উভয় অবস্থায় প্রবেশ করছে, প্রস্থান করছে বা উপস্থিত রয়েছে। এটি ডান দিক থেকে স্লাইড করে প্রবেশ করে এবং ভিতরে বিবর্ণ হয়ে যায়, এটি ডানদিকে স্লাইড করে এবং বিবর্ণ হয়ে প্রস্থান করে এবং উভয় অবস্থায় উপস্থিত থাকলে এটি অবস্থানে থাকে।

নির্দিষ্ট এন্ট্রি এবং এক্সিট ট্রানজিশন তৈরি করতে, আপনি :only-child pseudo-class ব্যবহার করতে পারেন পুরনো বা নতুন ছদ্ম-উপাদানগুলিকে লক্ষ্য করার জন্য যখন এটি ইমেজ-জোড়ার একমাত্র সন্তান হয়:

/* Entry transition */
::view-transition-new(sidebar):only-child {
  animation: 300ms cubic-bezier(0, 0, 0.2, 1) both fade-in,
    300ms cubic-bezier(0.4, 0, 0.2, 1) both slide-from-right;
}

/* Exit transition */
::view-transition-old(sidebar):only-child {
  animation: 150ms cubic-bezier(0.4, 0, 1, 1) both fade-out,
    300ms cubic-bezier(0.4, 0, 0.2, 1) both slide-to-right;
}

এই ক্ষেত্রে, উভয় অবস্থায় সাইডবার উপস্থিত থাকার জন্য কোন নির্দিষ্ট পরিবর্তন নেই, যেহেতু ডিফল্টটি নিখুঁত।

Async DOM আপডেট, এবং বিষয়বস্তুর জন্য অপেক্ষা করছে

.startViewTransition() এ পাস করা কলব্যাক একটি প্রতিশ্রুতি ফিরিয়ে দিতে পারে, যা DOM আপডেটগুলিকে অ্যাসিঙ্ক করার অনুমতি দেয় এবং গুরুত্বপূর্ণ বিষয়বস্তু প্রস্তুত হওয়ার জন্য অপেক্ষা করে৷

document.startViewTransition(async () => {
  await something;
  await updateTheDOMSomehow();
  await somethingElse;
});

প্রতিশ্রুতি পূরণ না হওয়া পর্যন্ত স্থানান্তর শুরু হবে না। এই সময়ের মধ্যে, পৃষ্ঠাটি হিমায়িত হয়, তাই এখানে বিলম্ব একটি সর্বনিম্ন রাখা উচিত। বিশেষত, .startViewTransition() .startViewTransition() কলব্যাকের অংশ হিসাবে না করে কল করার আগে করা উচিত৷

আপনি যদি ছবি বা ফন্ট প্রস্তুত হওয়ার জন্য অপেক্ষা করার সিদ্ধান্ত নেন, তাহলে একটি আক্রমনাত্মক টাইমআউট ব্যবহার করতে ভুলবেন না:

const wait = ms => new Promise(r => setTimeout(r, ms));

document.startViewTransition(async () => {
  updateTheDOMSomehow();

  // Pause for up to 100ms for fonts to be ready:
  await Promise.race([document.fonts.ready, wait(100)]);
});

যাইহোক, কিছু ক্ষেত্রে বিলম্বকে সম্পূর্ণভাবে এড়িয়ে যাওয়া এবং আপনার ইতিমধ্যেই থাকা সামগ্রী ব্যবহার করা ভাল।


আপনার ইতিমধ্যেই রয়েছে এমন সামগ্রীর সর্বাধিক ব্যবহার করুন৷

যে ক্ষেত্রে থাম্বনেইল একটি বড় ছবিতে রূপান্তরিত হয়:

থাম্বনেইলটি একটি বড় ছবিতে রূপান্তরিত হচ্ছে৷ ডেমো সাইট চেষ্টা করুন .

ডিফল্ট ট্রানজিশন হল ক্রস-ফেড, যার মানে থাম্বনেইলটি এখনও লোড করা হয়নি এমন পূর্ণ চিত্রের সাথে ক্রস-বিবর্ণ হতে পারে।

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

::view-transition-old(full-embed),
::view-transition-new(full-embed) {
  /* Prevent the default animation,
  so both views remain opacity:1 throughout the transition */
  animation: none;
  /* Use normal blending,
  so the new view sits on top and obscures the old view */
  mix-blend-mode: normal;
}

এখন থাম্বনেইলটি বিবর্ণ হয় না, এটি সম্পূর্ণ চিত্রের নীচে বসে থাকে। এর মানে হল যদি নতুন ভিউ লোড না হয়, থাম্বনেইলটি ট্রানজিশন জুড়ে দৃশ্যমান। এর অর্থ হল রূপান্তরটি সরাসরি শুরু হতে পারে এবং সম্পূর্ণ চিত্রটি তার নিজস্ব সময়ে লোড হতে পারে।

নতুন ভিউতে স্বচ্ছতা থাকলে এটি কাজ করবে না, কিন্তু এই ক্ষেত্রে আমরা জানি এটি নেই, তাই আমরা এই অপ্টিমাইজেশানটি করতে পারি।

আকৃতির অনুপাতের পরিবর্তনগুলি পরিচালনা করুন

সুবিধাজনকভাবে, এখন পর্যন্ত সমস্ত রূপান্তর একই অনুপাতের উপাদানগুলিতে হয়েছে, তবে এটি সর্বদা হবে না। থাম্বনেইল 1:1 হলে এবং প্রধান চিত্রটি 16:9 হলে কী হবে?

আকৃতির অনুপাত পরিবর্তন সহ একটি উপাদান অন্যটিতে স্থানান্তরিত হচ্ছে। ন্যূনতম ডেমোউৎস

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

এটি একটি ভাল ডিফল্ট, কিন্তু এই ক্ষেত্রে যা চাই তা নয়। তাই:

::view-transition-old(full-embed),
::view-transition-new(full-embed) {
  /* Prevent the default animation,
  so both views remain opacity:1 throughout the transition */
  animation: none;
  /* Use normal blending,
  so the new view sits on top and obscures the old view */
  mix-blend-mode: normal;
  /* Make the height the same as the group,
  meaning the view size might not match its aspect-ratio. */
  height: 100%;
  /* Clip any overflow of the view */
  overflow: clip;
}

/* The old view is the thumbnail */
::view-transition-old(full-embed) {
  /* Maintain the aspect ratio of the view,
  by shrinking it to fit within the bounds of the element */
  object-fit: contain;
}

/* The new view is the full image */
::view-transition-new(full-embed) {
  /* Maintain the aspect ratio of the view,
  by growing it to cover the bounds of the element */
  object-fit: cover;
}

এর অর্থ হল থাম্বনেইলটি উপাদানটির কেন্দ্রে থাকে প্রস্থ বাড়ার সাথে সাথে, কিন্তু 1:1 থেকে 16:9 পর্যন্ত রূপান্তরিত হওয়ার সাথে সাথে সম্পূর্ণ চিত্রটি 'আন-ক্রপ' হয়।

আরও বিশদ তথ্যের জন্য, রূপান্তরগুলি দেখুন: দৃষ্টিভঙ্গি অনুপাত পরিবর্তনগুলি পরিচালনা করুন


বিভিন্ন ডিভাইসের অবস্থার জন্য ট্রানজিশন পরিবর্তন করতে মিডিয়া কোয়েরি ব্যবহার করুন

আপনি মোবাইল বনাম ডেস্কটপে বিভিন্ন ট্রানজিশন ব্যবহার করতে চাইতে পারেন, যেমন এই উদাহরণটি যা মোবাইলের পাশ থেকে একটি সম্পূর্ণ স্লাইড সম্পাদন করে, কিন্তু ডেস্কটপে আরও সূক্ষ্ম স্লাইড:

একটি উপাদান অন্যটিতে রূপান্তরিত হচ্ছে। ন্যূনতম ডেমোউৎস

এটি নিয়মিত মিডিয়া প্রশ্ন ব্যবহার করে অর্জন করা যেতে পারে:

/* Transitions for mobile */
::view-transition-old(root) {
  animation: 300ms ease-out both full-slide-to-left;
}

::view-transition-new(root) {
  animation: 300ms ease-out both full-slide-from-right;
}

@media (min-width: 500px) {
  /* Overrides for larger displays.
  This is the shared axis transition from earlier in the article. */
  ::view-transition-old(root) {
    animation: 90ms cubic-bezier(0.4, 0, 1, 1) both fade-out,
      300ms cubic-bezier(0.4, 0, 0.2, 1) both slide-to-left;
  }

  ::view-transition-new(root) {
    animation: 210ms cubic-bezier(0, 0, 0.2, 1) 90ms both fade-in,
      300ms cubic-bezier(0.4, 0, 0.2, 1) both slide-from-right;
  }
}

আপনি কোন উপাদানগুলিকে view-transition-name বরাদ্দ করবেন তা পরিবর্তন করতে চাইতে পারেন মিডিয়া ক্যোয়ারীগুলির উপর নির্ভর করে।


'হ্রাস গতি' পছন্দ প্রতিক্রিয়া

ব্যবহারকারীরা নির্দেশ করতে পারে যে তারা তাদের অপারেটিং সিস্টেমের মাধ্যমে কম গতি পছন্দ করে এবং সেই পছন্দটি CSS-এ প্রকাশ করা হয়।

আপনি এই ব্যবহারকারীদের জন্য কোনো রূপান্তর প্রতিরোধ করতে বেছে নিতে পারেন:

@media (prefers-reduced-motion) {
  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) {
    animation: none !important;
  }
}

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


ভিউ ট্রানজিশন প্রকার সহ একাধিক ভিউ ট্রানজিশন শৈলী পরিচালনা করুন

ব্রাউজার সমর্থন

  • ক্রোম: 125।
  • প্রান্ত: 125।
  • ফায়ারফক্স: সমর্থিত নয়।
  • সাফারি: 18।

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

পেজিনেশন ডেমোর রেকর্ডিং। আপনি কোন পৃষ্ঠায় যাচ্ছেন তার উপর নির্ভর করে এটি বিভিন্ন রূপান্তর ব্যবহার করে।

এর জন্য আপনি ভিউ ট্রানজিশনের ধরন ব্যবহার করতে পারেন, যা আপনাকে একটি সক্রিয় ভিউ ট্রানজিশনে এক বা একাধিক প্রকার বরাদ্দ করতে দেয়। উদাহরণস্বরূপ, একটি পৃষ্ঠা সংখ্যা ক্রমানুসারে একটি উচ্চ পৃষ্ঠায় স্থানান্তর করার সময় forwards টাইপ ব্যবহার করুন এবং একটি নিম্ন পৃষ্ঠায় যাওয়ার সময় backwards টাইপ ব্যবহার করুন৷ এই প্রকারগুলি শুধুমাত্র একটি ট্রানজিশন ক্যাপচার বা সম্পাদন করার সময় সক্রিয় থাকে এবং প্রতিটি প্রকার বিভিন্ন অ্যানিমেশন ব্যবহার করার জন্য CSS এর মাধ্যমে কাস্টমাইজ করা যেতে পারে।

একই-ডকুমেন্ট ভিউ ট্রানজিশনে টাইপ ব্যবহার করতে, আপনি startViewTransition পদ্ধতিতে types পাস করেন। এটিকে অনুমতি দেওয়ার জন্য, document.startViewTransition একটি অবজেক্টও গ্রহণ করে: update হল কলব্যাক ফাংশন যা DOM আপডেট করে এবং types হল প্রকারগুলির সাথে একটি অ্যারে।

const direction = determineBackwardsOrForwards();

const t = document.startViewTransition({
  update: updateTheDOMSomehow,
  types: ['slide', direction],
});

এই ধরনের প্রতিক্রিয়া জানাতে, :active-view-transition-type() নির্বাচক ব্যবহার করুন। নির্বাচক মধ্যে আপনি লক্ষ্য করতে চান type পাস. এটি আপনাকে একাধিক ভিউ ট্রানজিশনের স্টাইলগুলিকে একে অপরের থেকে আলাদা রাখতে দেয়, একটির ঘোষণা অন্যটির ঘোষণায় হস্তক্ষেপ না করে।

যেহেতু ধরনগুলি শুধুমাত্র ট্রানজিশন ক্যাপচার করার সময় বা সম্পাদন করার সময় প্রযোজ্য হয়, আপনি শুধুমাত্র সেই টাইপের সাথে ভিউ ট্রানজিশনের জন্য একটি এলিমেন্টে একটি view-transition-name সেট–বা আনসেট করতে সিলেক্টর ব্যবহার করতে পারেন৷

/* Determine what gets captured when the type is forwards or backwards */
html:active-view-transition-type(forwards, backwards) {
  :root {
    view-transition-name: none;
  }
  article {
    view-transition-name: content;
  }
  .pagination {
    view-transition-name: pagination;
  }
}

/* Animation styles for forwards type only */
html:active-view-transition-type(forwards) {
  &::view-transition-old(content) {
    animation-name: slide-out-to-left;
  }
  &::view-transition-new(content) {
    animation-name: slide-in-from-right;
  }
}

/* Animation styles for backwards type only */
html:active-view-transition-type(backwards) {
  &::view-transition-old(content) {
    animation-name: slide-out-to-right;
  }
  &::view-transition-new(content) {
    animation-name: slide-in-from-left;
  }
}

/* Animation styles for reload type only (using the default root snapshot) */
html:active-view-transition-type(reload) {
  &::view-transition-old(root) {
    animation-name: fade-out, scale-down;
  }
  &::view-transition-new(root) {
    animation-delay: 0.25s;
    animation-name: fade-in, scale-up;
  }
}

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

যেকোনো সক্রিয় ভিউ ট্রানজিশন টার্গেট করতে, প্রকার নির্বিশেষে, আপনি এর পরিবর্তে :active-view-transition pseudo-class সিলেক্টর ব্যবহার করতে পারেন।

html:active-view-transition {
    …
}

ভিউ ট্রানজিশন রুটে একটি ক্লাস নাম সহ একাধিক ভিউ ট্রানজিশন শৈলী পরিচালনা করুন

কখনও কখনও একটি বিশেষ ধরনের দৃশ্য থেকে অন্য একটি রূপান্তর একটি বিশেষভাবে উপযোগী রূপান্তর থাকা উচিত। অথবা, একটি 'ব্যাক' নেভিগেশন একটি 'ফরোয়ার্ড' নেভিগেশন থেকে ভিন্ন হওয়া উচিত।

'ফিরে' যাওয়ার সময় বিভিন্ন পরিবর্তন। ন্যূনতম ডেমোউৎস

ট্রানজিশন টাইপ করার আগে এই কেসগুলি পরিচালনা করার উপায় ছিল অস্থায়ীভাবে ট্রানজিশন রুটে একটি ক্লাস নাম সেট করা। document.startViewTransition কল করার সময়, এই ট্রানজিশন রুট হল <html> উপাদান, JavaScript এ document.documentElement ব্যবহার করে অ্যাক্সেসযোগ্য:

if (isBackNavigation) {
  document.documentElement.classList.add('back-transition');
}

const transition = document.startViewTransition(() =>
  updateTheDOMSomehow(data)
);

try {
  await transition.finished;
} finally {
  document.documentElement.classList.remove('back-transition');
}

ট্রানজিশন শেষ হওয়ার পরে ক্লাসগুলি সরাতে, এই উদাহরণটি transition.finished ব্যবহার করে, একটি প্রতিশ্রুতি যা একবার রূপান্তর শেষ অবস্থায় পৌঁছে গেলে সমাধান করে। এই বস্তুর অন্যান্য বৈশিষ্ট্য API রেফারেন্সে আচ্ছাদিত করা হয়েছে।

এখন আপনি রূপান্তর পরিবর্তন করতে আপনার CSS-এ সেই শ্রেণীর নাম ব্যবহার করতে পারেন:

/* 'Forward' transitions */
::view-transition-old(root) {
  animation: 90ms cubic-bezier(0.4, 0, 1, 1) both fade-out,
    300ms cubic-bezier(0.4, 0, 0.2, 1) both slide-to-left;
}

::view-transition-new(root) {
  animation: 210ms cubic-bezier(0, 0, 0.2, 1) 90ms both fade-in, 300ms
      cubic-bezier(0.4, 0, 0.2, 1) both slide-from-right;
}

/* Overrides for 'back' transitions */
.back-transition::view-transition-old(root) {
  animation-name: fade-out, slide-to-right;
}

.back-transition::view-transition-new(root) {
  animation-name: fade-in, slide-from-left;
}

মিডিয়া ক্যোয়ারীগুলির মতো, এই ক্লাসগুলির উপস্থিতি কোন উপাদানগুলি একটি view-transition-name পায় তা পরিবর্তন করতেও ব্যবহার করা যেতে পারে।


অন্যান্য অ্যানিমেশন জমা না করে ট্রানজিশন চালান

একটি ভিডিও রূপান্তর অবস্থানের এই ডেমোটি দেখুন:

ভিডিও রূপান্তর। ন্যূনতম ডেমোউৎস

আপনি এটা সঙ্গে কিছু ভুল দেখেছেন? আপনি না হলে চিন্তা করবেন না. এখানে এটিকে ধীর করা হয়েছে:

ভিডিও রূপান্তর, ধীর। ন্যূনতম ডেমোউৎস

ট্রানজিশনের সময়, ভিডিওটি হিমায়িত হতে দেখা যায়, তারপর ভিডিওটির প্লে ভার্সন ফিকে হয়ে যায়। এর কারণ হল ::view-transition-old(video) হল পুরানো ভিউ এর একটি স্ক্রিনশট, যেখানে ::view-transition-new(video) হল নতুন ভিউ এর একটি লাইভ ইমেজ।

আপনি এটি ঠিক করতে পারেন, তবে প্রথমে নিজেকে জিজ্ঞাসা করুন যে এটি ঠিক করা উপযুক্ত কিনা। আপনি যদি 'সমস্যা' দেখতে না পান যখন ট্রানজিশনটি তার স্বাভাবিক গতিতে বাজছিল, আমি এটি পরিবর্তন করতে বিরক্ত করব না।

আপনি যদি সত্যিই এটি ঠিক করতে চান, তাহলে ::view-transition-old(video) দেখাবেন না; সরাসরি ::view-transition-new(video) এ স্যুইচ করুন। আপনি ডিফল্ট শৈলী এবং অ্যানিমেশন ওভাররাইড করে এটি করতে পারেন:

::view-transition-old(video) {
  /* Don't show the frozen old view */
  display: none;
}

::view-transition-new(video) {
  /* Don't fade the new view in */
  animation: none;
}

আর এটাই!

ভিডিও রূপান্তর, ধীর। ন্যূনতম ডেমোউৎস

এখন ভিডিওটি ট্রানজিশন জুড়ে চলে।


নেভিগেশন এপিআই (এবং অন্যান্য ফ্রেমওয়ার্ক) এর সাথে ইন্টিগ্রেশন

ভিউ ট্রানজিশনগুলি এমনভাবে নির্দিষ্ট করা হয়েছে যাতে সেগুলি অন্যান্য ফ্রেমওয়ার্ক বা লাইব্রেরির সাথে একত্রিত করা যায়। উদাহরণস্বরূপ, যদি আপনার একক-পৃষ্ঠা অ্যাপ্লিকেশন (SPA) একটি রাউটার ব্যবহার করে, আপনি একটি ভিউ ট্রানজিশন ব্যবহার করে বিষয়বস্তু আপডেট করতে রাউটারের আপডেট প্রক্রিয়া সামঞ্জস্য করতে পারেন।

এই পেজিনেশন ডেমো থেকে নেওয়া নিম্নলিখিত কোড স্নিপেটে ন্যাভিগেশন API-এর ইন্টারসেপশন হ্যান্ডলারকে document.startViewTransition startViewTransition কলে সামঞ্জস্য করা হয় যখন ভিউ ট্রানজিশন সমর্থিত হয়।

navigation.addEventListener("navigate", (e) => {
    // Don't intercept if not needed
    if (shouldNotIntercept(e)) return;

    // Intercept the navigation
    e.intercept({
        handler: async () => {
            // Fetch the new content
            const newContent = await fetchNewContent(e.destination.url, {
                signal: e.signal,
            });

            // The UA does not support View Transitions, or the UA
            // already provided a Visual Transition by itself (e.g. swipe back).
            // In either case, update the DOM directly
            if (!document.startViewTransition || e.hasUAVisualTransition) {
                setContent(newContent);
                return;
            }

            // Update the content using a View Transition
            const t = document.startViewTransition(() => {
                setContent(newContent);
            });
        }
    });
});

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

তাই, যখন ব্রাউজারটি তার নিজস্ব ভিজ্যুয়াল ট্রানজিশন প্রদান করে তখন একটি ভিউ ট্রানজিশন শুরু হতে বাধা দেওয়ার পরামর্শ দেওয়া হয়। এটি অর্জন করতে, NavigateEvent উদাহরণের hasUAVisualTransition বৈশিষ্ট্যের মান পরীক্ষা করুন। যখন ব্রাউজার একটি ভিজ্যুয়াল ট্রানজিশন প্রদান করে তখন প্রপার্টিটি true হিসেবে সেট করা হয়। এই hasUIVisualTransition সম্পত্তি PopStateEvent দৃষ্টান্তেও বিদ্যমান।

পূর্ববর্তী স্নিপেটে যে চেকটি নির্ধারণ করে যে ভিউ ট্রানজিশন চালানো হবে কিনা তা এই সম্পত্তিটিকে বিবেচনা করে। যখন একই-ডকুমেন্ট ভিউ ট্রানজিশনের জন্য কোন সমর্থন না থাকে বা যখন ব্রাউজার ইতিমধ্যেই নিজস্ব ট্রানজিশন প্রদান করে, তখন ভিউ ট্রানজিশন এড়িয়ে যায়।

if (!document.startViewTransition || e.hasUAVisualTransition) {
  setContent(newContent);
  return;
}

নিম্নলিখিত রেকর্ডিংয়ে, ব্যবহারকারী পূর্ববর্তী পৃষ্ঠায় ফিরে যেতে সোয়াইপ করে। বাম দিকে ক্যাপচার hasUAVisualTransition পতাকার জন্য একটি চেক অন্তর্ভুক্ত করে না। ডানদিকে রেকর্ডিং চেক অন্তর্ভুক্ত করে, যার ফলে ম্যানুয়াল ভিউ ট্রানজিশন এড়িয়ে যায় কারণ ব্রাউজার একটি ভিজ্যুয়াল ট্রানজিশন প্রদান করে।

hasUAVisualTransition এর জন্য চেক (বাম) এবং প্রস্থ (ডান) ছাড়া একই সাইটের তুলনা

জাভাস্ক্রিপ্ট দিয়ে অ্যানিমেটিং

এখন পর্যন্ত, সমস্ত রূপান্তর CSS ব্যবহার করে সংজ্ঞায়িত করা হয়েছে, কিন্তু কখনও কখনও CSS যথেষ্ট নয়:

বৃত্তের রূপান্তর। ন্যূনতম ডেমোউৎস

এই পরিবর্তনের কয়েকটি অংশ একা সিএসএস দিয়ে অর্জন করা যাবে না:

  • অ্যানিমেশন ক্লিক অবস্থান থেকে শুরু হয়.
  • অ্যানিমেশনটি বৃত্তের দূরতম কোণে একটি ব্যাসার্ধের সাথে শেষ হয়। যদিও, আশা করি এটি ভবিষ্যতে CSS দিয়ে সম্ভব হবে।

সৌভাগ্যক্রমে, আপনি ওয়েব অ্যানিমেশন API ব্যবহার করে রূপান্তর তৈরি করতে পারেন!

let lastClick;
addEventListener('click', event => (lastClick = event));

function spaNavigate(data) {
  // Fallback for browsers that don't support this API:
  if (!document.startViewTransition) {
    updateTheDOMSomehow(data);
    return;
  }

  // Get the click position, or fallback to the middle of the screen
  const x = lastClick?.clientX ?? innerWidth / 2;
  const y = lastClick?.clientY ?? innerHeight / 2;
  // Get the distance to the furthest corner
  const endRadius = Math.hypot(
    Math.max(x, innerWidth - x),
    Math.max(y, innerHeight - y)
  );

  // With a transition:
  const transition = document.startViewTransition(() => {
    updateTheDOMSomehow(data);
  });

  // Wait for the pseudo-elements to be created:
  transition.ready.then(() => {
    // Animate the root's new view
    document.documentElement.animate(
      {
        clipPath: [
          `circle(0 at ${x}px ${y}px)`,
          `circle(${endRadius}px at ${x}px ${y}px)`,
        ],
      },
      {
        duration: 500,
        easing: 'ease-in',
        // Specify which pseudo-element to animate
        pseudoElement: '::view-transition-new(root)',
      }
    );
  });
}

এই উদাহরণটি transition.ready ব্যবহার করে, একটি প্রতিশ্রুতি যা ট্রানজিশন ছদ্ম-উপাদান সফলভাবে তৈরি হয়ে গেলে সমাধান করে। এই বস্তুর অন্যান্য বৈশিষ্ট্য API রেফারেন্সে আচ্ছাদিত করা হয়েছে।


একটি বর্ধন হিসাবে রূপান্তর

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

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

করবেন না
async function switchView(data) {
  // Fallback for browsers that don't support this API:
  if (!document.startViewTransition) {
    await updateTheDOM(data);
    return;
  }

  const transition = document.startViewTransition(async () => {
    await updateTheDOM(data);
  });

  await transition.ready;

  document.documentElement.animate(
    {
      clipPath: [`inset(50%)`, `inset(0)`],
    },
    {
      duration: 500,
      easing: 'ease-in',
      pseudoElement: '::view-transition-new(root)',
    }
  );
}

এই উদাহরণের সমস্যা হল যে পরিবর্তনটি একটি ready অবস্থায় পৌঁছাতে না পারলে switchView() প্রত্যাখ্যান করবে, কিন্তু এর মানে এই নয় যে ভিউটি স্যুইচ করতে ব্যর্থ হয়েছে। DOM সফলভাবে আপডেট হতে পারে, কিন্তু সেখানে ডুপ্লিকেট view-transition-name ছিল, তাই ট্রানজিশনটি এড়িয়ে গেছে।

পরিবর্তে:

করবেন
async function switchView(data) {
  // Fallback for browsers that don't support this API:
  if (!document.startViewTransition) {
    await updateTheDOM(data);
    return;
  }

  const transition = document.startViewTransition(async () => {
    await updateTheDOM(data);
  });

  animateFromMiddle(transition);

  await transition.updateCallbackDone;
}

async function animateFromMiddle(transition) {
  try {
    await transition.ready;

    document.documentElement.animate(
      {
        clipPath: [`inset(50%)`, `inset(0)`],
      },
      {
        duration: 500,
        easing: 'ease-in',
        pseudoElement: '::view-transition-new(root)',
      }
    );
  } catch (err) {
    // You might want to log this error, but it shouldn't break the app
  }
}

এই উদাহরণটি DOM আপডেটের জন্য অপেক্ষা করতে transition.updateCallbackDone ব্যবহার করে এবং এটি ব্যর্থ হলে প্রত্যাখ্যান করতে। রূপান্তর ব্যর্থ হলে switchView আর প্রত্যাখ্যান করে না, DOM আপডেট সম্পূর্ণ হলে এটি সমাধান করে এবং ব্যর্থ হলে প্রত্যাখ্যান করে।

আপনি যদি চান যে switchView নতুন ভিউ 'সেটেল' হয়ে গেলে সমাধান করতে, যেমন যেকোন অ্যানিমেটেড ট্রানজিশন শেষ হয়ে গেছে বা শেষ পর্যন্ত এড়িয়ে গেছে, transition.updateCallbackDone transition.finished দিয়ে প্রতিস্থাপন করুন।


পলিফিল নয়, তবে…

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

function transitionHelper({
  skipTransition = false,
  types = [],
  update,
}) {

  const unsupported = (error) => {
    const updateCallbackDone = Promise.resolve(update()).then(() => {});

    return {
      ready: Promise.reject(Error(error)),
      updateCallbackDone,
      finished: updateCallbackDone,
      skipTransition: () => {},
      types,
    };
  }

  if (skipTransition || !document.startViewTransition) {
    return unsupported('View Transitions are not supported in this browser');
  }

  try {
    const transition = document.startViewTransition({
      update,
      types,
    });

    return transition;
  } catch (e) {
    return unsupported('View Transitions with types are not supported in this browser');
  }
}

এবং এটি এই মত ব্যবহার করা যেতে পারে:

function spaNavigate(data) {
  const types = isBackNavigation ? ['back-transition'] : [];

  const transition = transitionHelper({
    update() {
      updateTheDOMSomehow(data);
    },
    types,
  });

  // …
}

যেসব ব্রাউজারে ভিউ ট্রানজিশন সমর্থন করে না, updateDOM এখনও কল করা হবে, কিন্তু অ্যানিমেটেড ট্রানজিশন হবে না।

ট্রানজিশনের সময় <html> এ যোগ করার জন্য আপনি কিছু classNames প্রদান করতে পারেন, যা নেভিগেশনের ধরনের উপর নির্ভর করে ট্রানজিশন পরিবর্তন করা সহজ করে তোলে।

আপনি যদি কোনো অ্যানিমেশন না চান, এমন কি ভিউ ট্রানজিশন সমর্থন করে এমন ব্রাউজারেও আপনি skipTransition true পাস করতে পারেন। ট্রানজিশন অক্ষম করার জন্য আপনার সাইটে ব্যবহারকারীর পছন্দ থাকলে এটি কার্যকর।


ফ্রেমওয়ার্ক নিয়ে কাজ করা

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

  • প্রতিক্রিয়া — এখানে কী হল flushSync , যা সিঙ্ক্রোনাসভাবে স্টেট পরিবর্তনের একটি সেট প্রয়োগ করে। হ্যাঁ, সেই API ব্যবহার করার বিষয়ে একটি বড় সতর্কতা রয়েছে, কিন্তু ড্যান আব্রামভ আমাকে আশ্বস্ত করেছেন যে এটি এই ক্ষেত্রে উপযুক্ত। যথারীতি প্রতিক্রিয়া এবং অ্যাসিঙ্ক কোডের সাথে, startViewTransition দ্বারা প্রত্যাবর্তিত বিভিন্ন প্রতিশ্রুতি ব্যবহার করার সময়, আপনার কোডটি সঠিক অবস্থার সাথে চলছে কিনা সেদিকে খেয়াল রাখুন।
  • Vue.js —এখানে কী হল nextTick , যা একবার DOM আপডেট হয়ে গেলে পূরণ করে।
  • Svelte — Vue-এর মতোই, কিন্তু পরবর্তী পরিবর্তনের জন্য অপেক্ষা করার পদ্ধতি হল tick
  • লিট —এখানে মূল বিষয় হল উপাদানগুলির মধ্যে this.updateComplete প্রতিশ্রুতি, যা একবার DOM আপডেট করার পরে পূরণ করে।
  • কৌণিক — এখানে কী হল applicationRef.tick , যা মুলতুবি থাকা DOM পরিবর্তনগুলিকে ফ্লাশ করে। কৌণিক সংস্করণ 17 হিসাবে আপনি withViewTransitions ব্যবহার করতে পারেন যা @angular/router এর সাথে আসে

API রেফারেন্স

const viewTransition = document.startViewTransition(update)

একটি নতুন ViewTransition শুরু করুন।

update হল একটি ফাংশন যা একবার ডকুমেন্টের বর্তমান অবস্থা ক্যাপচার করা হলে বলা হয়।

তারপর, যখন updateCallback দ্বারা প্রত্যাবর্তিত প্রতিশ্রুতি পূরণ হয়, তখন পরবর্তী ফ্রেমে রূপান্তর শুরু হয়। updateCallback দ্বারা প্রত্যাবর্তিত প্রতিশ্রুতি প্রত্যাখ্যান করলে, রূপান্তর পরিত্যক্ত হয়।

const viewTransition = document.startViewTransition({ update, types })

নির্দিষ্ট প্রকারের সাথে একটি নতুন ViewTransition শুরু করুন

নথির বর্তমান অবস্থা ক্যাপচার করা হলে update বলা হয়।

রূপান্তর ক্যাপচার বা সঞ্চালন করার সময় types পরিবর্তনের জন্য সক্রিয় প্রকারগুলি সেট করে। এটি প্রাথমিকভাবে খালি। আরও তথ্যের জন্য আরও নীচে viewTransition.types দেখুন।

ViewTransition ট্রানজিশনের সদস্যদের উদাহরণ:

viewTransition.updateCallbackDone

একটি প্রতিশ্রুতি যা পরিপূর্ণ হয় যখন updateCallback দ্বারা প্রত্যাবর্তিত প্রতিশ্রুতি পূর্ণ হয়, বা প্রত্যাখ্যান করলে তা প্রত্যাখ্যান করে।

ভিউ ট্রানজিশন এপিআই একটি DOM পরিবর্তন মোড়ানো এবং একটি ট্রানজিশন তৈরি করে। যাইহোক, কখনও কখনও আপনি ট্রানজিশন অ্যানিমেশনের সাফল্য বা ব্যর্থতার বিষয়ে চিন্তা করেন না, আপনি শুধু জানতে চান যে DOM পরিবর্তন কখন ঘটবে। updateCallbackDone সেই ব্যবহারের ক্ষেত্রে।

viewTransition.ready

একটি প্রতিশ্রুতি যা পূর্ণ হয় একবার রূপান্তরের জন্য ছদ্ম-উপাদানগুলি তৈরি হয়ে গেলে এবং অ্যানিমেশন শুরু হতে চলেছে৷

রূপান্তর শুরু করতে না পারলে এটি প্রত্যাখ্যান করে। এটি ভুল কনফিগারেশনের কারণে হতে পারে, যেমন ডুপ্লিকেট view-transition-name s, অথবা যদি updateCallback একটি প্রত্যাখ্যান প্রতিশ্রুতি প্রদান করে।

এটি জাভাস্ক্রিপ্টের সাথে ট্রানজিশন সিউডো-এলিমেন্ট অ্যানিমেট করার জন্য দরকারী।

viewTransition.finished

একটি প্রতিশ্রুতি যা ব্যবহারকারীর কাছে শেষ অবস্থা সম্পূর্ণরূপে দৃশ্যমান এবং ইন্টারেক্টিভ হওয়ার পরে পূরণ করে।

এটি শুধুমাত্র প্রত্যাখ্যান করে যদি updateCallback একটি প্রত্যাখ্যাত প্রতিশ্রুতি প্রদান করে, কারণ এটি ইঙ্গিত করে যে শেষ অবস্থা তৈরি করা হয়নি।

অন্যথায়, যদি একটি ট্রানজিশন শুরু হতে ব্যর্থ হয়, বা ট্রানজিশনের সময় এড়িয়ে যাওয়া হয়, তাহলেও শেষ অবস্থায় পৌঁছে যায়, তাই finished হয়।

viewTransition.types

একটি Set -সদৃশ বস্তু যা সক্রিয় ভিউ ট্রানজিশনের ধরন ধারণ করে। এন্ট্রি ম্যানিপুলেট করতে, এর ইনস্ট্যান্স পদ্ধতি ব্যবহার করুন clear() , add() , এবং delete()

CSS-এ একটি নির্দিষ্ট ধরনের প্রতিক্রিয়া জানাতে, ট্রানজিশন রুটে :active-view-transition-type(type) pseudo-class সিলেক্টর ব্যবহার করুন।

ভিউ ট্রানজিশন শেষ হলে প্রকারগুলি স্বয়ংক্রিয়ভাবে পরিষ্কার হয়ে যায়।

viewTransition.skipTransition()

ট্রানজিশনের অ্যানিমেশন অংশটি এড়িয়ে যান।

এটি updateCallback কলিং এড়িয়ে যাবে না, কারণ DOM পরিবর্তনটি ট্রানজিশনের জন্য আলাদা।


ডিফল্ট শৈলী এবং ট্রানজিশন রেফারেন্স

::view-transition
রুট ছদ্ম-উপাদান যা ভিউপোর্ট পূরণ করে এবং প্রতিটি ::view-transition-group ধারণ করে।
::view-transition-group

একেবারে অবস্থান.

'আগে' এবং 'পরে' অবস্থার মধ্যে width এবং height পরিবর্তন করে।

রূপান্তরগুলি 'আগে' এবং 'পরে' ভিউপোর্ট-স্পেস কোয়াডের মধ্যে transform

::view-transition-image-pair

গ্রুপ পূরণ করার জন্য একেবারে অবস্থান.

isolation: isolate পুরানো এবং নতুন ভিউতে mix-blend-mode প্রভাব সীমিত করতে আইসোলেট করুন।

::view-transition-new এবং ::view-transition-old

একেবারে র‍্যাপারের উপরের-বামে অবস্থান।

গোষ্ঠীর প্রস্থের 100% পূরণ করে, কিন্তু একটি স্বয়ংক্রিয় উচ্চতা রয়েছে, তাই এটি গোষ্ঠীটি পূরণ করার পরিবর্তে তার আকৃতির অনুপাত বজায় রাখবে।

mix-blend-mode: plus-lighter

পুরানো ভিউ opacity: 1 opacity: 0 তে। নতুন ভিউ opacity: 0 থেকে opacity: 1


প্রতিক্রিয়া

বিকাশকারী প্রতিক্রিয়া সবসময় প্রশংসা করা হয়. এটি করার জন্য, পরামর্শ এবং প্রশ্ন সহ GitHub-এ CSS ওয়ার্কিং গ্রুপের সাথে একটি সমস্যা ফাইল করুন[css-view-transitions] এর সাথে আপনার সমস্যাটি উপসর্গ করুন।

আপনি একটি বাগ চালাতে হবে, তারপর পরিবর্তে একটি Chromium বাগ ফাইল করুন .