<ViewTransition>
<ViewTransition> Transitions மற்றும் Suspense உடன் component tree ஒன்றை animate செய்ய அனுமதிக்கிறது.
import {ViewTransition} from 'react';
<ViewTransition>
<div>...</div>
</ViewTransition>- Reference
- View Transition-களை style செய்தல்
- Usage
- enter/exit-இல் ஒரு element-ஐ animate செய்தல்
- Activity உடன் enter/exit-ஐ animate செய்தல்
- shared element ஒன்றை animate செய்தல்
- list-இல் item-களின் reorder-ஐ animate செய்தல்
- Suspense content-இலிருந்து animate செய்தல்
- animation ஒன்றிலிருந்து opt out செய்தல்
- animation-களை customize செய்தல்
- type-களுடன் animation-களை customize செய்தல்
- JavaScript மூலம் animate செய்தல்
- JavaScript மூலம் transition type-களை animate செய்தல்
- View Transition enabled router-களை உருவாக்குதல்
- Troubleshooting
Reference
<ViewTransition>
ஒரு component tree-ஐ animate செய்ய அதை <ViewTransition>-இல் wrap செய்யுங்கள்:
<ViewTransition>
<Page />
</ViewTransition>மேலும் உதாரணங்களை கீழே பார்க்கவும்.
Deep Dive
உள்ளே, <ViewTransition> component-க்குள் nested ஆன மிக அருகிலுள்ள DOM node-ன் inline style-களுக்கு React view-transition-name-ஐப் பயன்படுத்துகிறது. <ViewTransition><div /><div /></ViewTransition> போன்ற பல sibling DOM node-கள் இருந்தால், ஒவ்வொன்றும் unique ஆக இருக்க React பெயருக்கு suffix சேர்க்கிறது; ஆனால் கருத்து ரீதியாக அவை அதே ஒன்றின் பகுதிகளாகும். React இவற்றை முன்கூட்டியே apply செய்யாது; அந்த boundary animation-இல் பங்கேற்க வேண்டிய நேரத்தில் மட்டுமே apply செய்யும்.
React பின்னணியில் தானாகவே startViewTransition-ஐ call செய்கிறது; எனவே அதை நீங்கள் நீங்களே ஒருபோதும் செய்யக்கூடாது. உண்மையில், page-இல் வேறு ஏதாவது ViewTransition ஓடிக்கொண்டிருந்தால் React அதை interrupt செய்யும். எனவே இவற்றை coordinate செய்ய React-ஐயே பயன்படுத்துவது பரிந்துரைக்கப்படுகிறது. முன்பு ViewTransition-களை trigger செய்ய வேறு வழிகளைப் பயன்படுத்தியிருந்தால், built-in வழிக்கு migrate செய்ய பரிந்துரைக்கிறோம்.
மற்ற React ViewTransition-கள் ஏற்கனவே ஓடிக்கொண்டிருந்தால், அடுத்ததைத் தொடங்கும் முன் அவை முடியும் வரை React காத்திருக்கும். ஆனால் முக்கியமாக, முதல் animation ஓடிக்கொண்டிருக்கும்போது பல update-கள் நடந்தால், அவை அனைத்தும் ஒன்றாக batch செய்யப்படும். நீங்கள் A->B-ஐத் தொடங்கினால், நடுவில் C-க்கும் பிறகு D-க்கும் செல்ல update கிடைத்தால், முதல் A->B animation முடிந்ததும் அடுத்தது B->D-ஐ animate செய்யும்.
startViewTransition-க்கு முன் getSnapshotBeforeUpdate lifecycle call செய்யப்படும்; அதே நேரத்தில் சில view-transition-name update ஆகும்.
பின்னர் React startViewTransition-ஐ call செய்கிறது. updateCallback-க்குள் React:
- DOM-க்கு அதன் mutation-களை apply செய்து
useInsertionEffect-ஐ invoke செய்யும். - font-கள் load ஆக காத்திருக்கும்.
componentDidMount,componentDidUpdate,useLayoutEffectமற்றும் ref-களை call செய்யும்.- pending Navigation ஏதேனும் முடியும் வரை காத்திருக்கும்.
- பிறகு எந்த boundary-கள் animate ஆக வேண்டும் என்பதைப் பார்க்க layout-இல் உள்ள மாற்றங்களை React measure செய்யும்.
startViewTransition-ன் ready Promise resolve ஆன பிறகு, React view-transition-name-ஐ revert செய்யும். பின்னர் animations மீது manual programmatic control வழங்க onEnter, onExit, onUpdate, மற்றும் onShare callback-களை React invoke செய்யும். built-in default animation-கள் ஏற்கனவே compute செய்யப்பட்ட பிறகு இது நடக்கும்.
இந்த sequence-ன் நடுவில் flushSync நடந்தால், synchronously முடிக்க முடிய வேண்டும் என்பதையே இது சார்ந்திருப்பதால் React Transition-ஐ skip செய்யும்.
startViewTransition-ன் finished Promise resolve ஆன பிறகு, React useEffect-ஐ invoke செய்யும். இது அவை animation performance-இல் குறுக்கிடுவதைத் தடுக்கிறது. ஆனால் இது ஒரு guarantee அல்ல; animation ஓடிக்கொண்டிருக்கும்போது இன்னொரு setState நடந்தால், sequential guarantee-களைப் பாதுகாக்க useEffect-ஐ முன்னதாகவே invoke செய்ய வேண்டியிருக்கும்.
Props
- optional
name: string அல்லது object. shared element transition-களுக்கு பயன்படுத்தப்படும் View Transition-ன் பெயர். இது வழங்கப்படாவிட்டால், எதிர்பாராத animation-களைத் தடுக்க ஒவ்வொரு View Transition-க்கும் React unique பெயரைப் பயன்படுத்தும். - View Transition Class props.
- View Transition Event props.
எச்சரிக்கைகள்
name-ஐ shared element transition-களுக்கு மட்டும் பயன்படுத்துங்கள். மற்ற எல்லா animation-களுக்கும், எதிர்பாராத animation-களைத் தடுக்க React தானாகவே unique பெயரை உருவாக்கும்.- இயல்பாக,
setStateஉடனடியாக update ஆகும்; அது<ViewTransition>-ஐ activate செய்யாது. Transition,<Suspense>, அல்லதுuseDeferredValue-இல் wrap செய்யப்பட்ட update-கள் மட்டுமே ViewTransition-ஐ activate செய்யும். <ViewTransition>நகர்த்தவும் scale செய்யவும் cross-fade செய்யவும் முடியும் image ஒன்றை உருவாக்குகிறது. React Native அல்லது Motion-இல் நீங்கள் பார்த்திருக்கக்கூடிய Layout Animation-களுக்கு மாறாக, இதன் உள்ளே இருக்கும் ஒவ்வொரு தனிப்பட்ட Element-மும் அதன் position-ஐ animate செய்யாது. ஒவ்வொரு தனிப்பட்ட துண்டையும் animate செய்வதைவிட, இது மேம்பட்ட performance-க்கும் தொடர்ச்சியான, smooth animation உணர்வுக்கும் வழிவகுக்கலாம். ஆனால் தனியே நகர வேண்டும் என எதிர்பார்க்கப்படும் விஷயங்களில் continuity இழக்கலாம். எனவே அதன் விளைவாக கூடுதல்<ViewTransition>boundary-களை கைமுறையாகச் சேர்க்க வேண்டியிருக்கும்.- தற்போது,
<ViewTransition>DOM-இல் மட்டுமே வேலை செய்கிறது. React Native மற்றும் பிற platform-களுக்கான support-ஐச் சேர்க்க நாங்கள் பணிபுரிகிறோம்.
Animation trigger-கள்
எந்த வகை View Transition animation-ஐ trigger செய்ய வேண்டும் என்பதை React தானாக தீர்மானிக்கும்:
enter: இந்த Transition-இல் insert செய்யப்படும் முதல் componentViewTransitionஆக இருந்தால், இது activate ஆகும்.exit: இந்த Transition-இல் delete செய்யப்படும் முதல் componentViewTransitionஆக இருந்தால், இது activate ஆகும்.update: React செய்யும் DOM mutation ஏதேனும்ViewTransition-க்குள் இருந்தால் (prop மாறுவது போன்றது), அல்லது immediate sibling காரணமாகViewTransitionboundary-யே size அல்லது position மாறினால். nestedViewTransitionஇருந்தால் mutation அவற்றுக்கு apply ஆகும்; parent-க்கு அல்ல.share: namedViewTransitionஒன்று deleted subtree-க்குள் இருந்து, அதே பெயருள்ள மற்றொரு namedViewTransitionஅதே Transition-இல் inserted subtree-ன் பகுதியாக இருந்தால், அவை Shared Element Transition உருவாக்கும்; அது deleted ஒன்றிலிருந்து inserted ஒன்றுக்குச் animate செய்கிறது.
இயல்பாக, <ViewTransition> smooth cross-fade உடன் animate ஆகும் (browser-ன் default view transition).
ஒவ்வொரு வகை trigger-க்கும் <ViewTransition> component-க்கு View Transition Class வழங்கி animation-ஐ customize செய்யலாம் (Styling View Transitions பார்க்கவும்), அல்லது ViewTransition Event-களை பயன்படுத்தி Web Animations API மூலம் JavaScript-இல் animation-ஐ control செய்யலாம்.
View Transition Class
எந்த animation-கள் trigger ஆக வேண்டும் என்பதை வரையறுக்க <ViewTransition> props வழங்குகிறது:
<ViewTransition
default="none"
enter="slide-up"
exit="slide-down"
/>Props
- optional
enter:"auto","none", a string, or an object. - optional
exit:"auto","none", a string, or an object. - optional
update:"auto","none", a string, or an object. - optional
share:"auto","none", a string, or an object. - optional
default:"auto","none", a string, or an object.
எச்சரிக்கைகள்
default"none"ஆக இருந்தால், வெளிப்படையாக பட்டியலிடப்படாத அனைத்து trigger-களும் off செய்யப்படும்.
மதிப்புகள்
View Transition class value-கள் இவையாக இருக்கலாம்:
auto: default. browser default animation-ஐப் பயன்படுத்தும்.none: இந்த வகைக்கான animation-களை disable செய்யும்.<classname>: View Transition-களை customize செய்ய பயன்படுத்தும் custom CSS class name.
Object value-கள் string key-களும் auto, none அல்லது custom className மதிப்பும் கொண்ட object ஆக இருக்கலாம்:
{[type]: value}: animation Transition Type-க்கு match ஆனால்value-ஐ apply செய்கிறது.{default: value}: எந்த Transition Type-மும் match ஆகாவிட்டால் apply செய்யப்படும் default value.
உதாரணமாக, ViewTransition-ஐ இவ்வாறு define செய்யலாம்:
<ViewTransition
/* turn off any animation not defined below */
default="none"
enter={{
/* apply slide-in for Transition Type `forward` */
"forward": 'slide-in',
/* otherwise use the browser default animation */
"default": 'auto'
}}
/* use the browser default for exit animations*/
exit="auto"
/* apply a custom `cross-fade` class for updates */
update="cross-fade"
>custom animation-களுக்கான CSS class-களை எப்படி define செய்வது என்பதை Styling View Transitions-இல் பார்க்கவும்.
View Transition Event
View Transition Event-கள் Web Animations API-யைப் பயன்படுத்தி JavaScript மூலம் animation-ஐ control செய்ய அனுமதிக்கின்றன:
<ViewTransition
onEnter={instance => {/* ... */}}
onExit={instance => {/* ... */}}
/>Props
- optional
onEnter: “enter” animation trigger ஆகும் போது call செய்யப்படும். - optional
onExit: “exit” animation trigger ஆகும் போது call செய்யப்படும். - optional
onShare: “share” animation trigger ஆகும் போது call செய்யப்படும். - optional
onUpdate: “update” animation trigger ஆகும் போது call செய்யப்படும்.
எச்சரிக்கைகள்
- ஒவ்வொரு Transition-க்கும் ஒவ்வொரு
<ViewTransition>-க்கு ஒரு event மட்டுமே fire ஆகும்.onEnterமற்றும்onExit-ஐ விடonShareமுன்னுரிமை பெறுகிறது. - ஒவ்வொரு event-மும் cleanup function ஒன்றை return செய்ய வேண்டும். View Transition முடிந்ததும் cleanup function call செய்யப்படும்; இதனால் எந்த animation-களையும் cancel அல்லது cleanup செய்ய முடியும்.
Argument-கள்
ஒவ்வொரு event-க்கும் இரண்டு argument-கள் கிடைக்கும்:
instance: view transition pseudo-element-களுக்கு அணுகலை வழங்கும் View Transition instance.old:::view-transition-oldpseudo-element.new:::view-transition-newpseudo-element.name: இந்த boundary-க்கானview-transition-namestring.group:::view-transition-grouppseudo-element.imagePair:::view-transition-image-pairpseudo-element.
types: animation-இல் உள்ள Transition Type-களின்Array<string>. type எதுவும் குறிப்பிடப்படவில்லை என்றால் காலியான array.
உதாரணமாக, JavaScript மூலம் animation-ஐ இயக்கும் onEnter event ஒன்றை define செய்யலாம்:
<ViewTransition
onEnter={(instance, types) => {
const anim = instance.new.animate([{opacity: 0}, {opacity: 1}], {
duration: 500,
});
return () => anim.cancel();
}}>
<div>...</div>
</ViewTransition>மேலும் உதாரணங்களுக்கு Animating with JavaScript பார்க்கவும்.
View Transition-களை style செய்தல்
<ViewTransition>-க்கான animation-ஐ customize செய்ய, activation prop-களில் ஒன்றுக்கு View Transition Class வழங்கலாம். View Transition activate ஆகும் போது child element-களுக்கு React apply செய்யும் CSS class name-தான் View Transition Class.
உதாரணமாக, “enter” animation-ஐ customize செய்ய, enter prop-க்கு class name ஒன்றை வழங்குங்கள்:
<ViewTransition enter="slide-in"><ViewTransition> “enter” animation-ஐ activate செய்யும்போது, React slide-in class name-ஐச் சேர்க்கும். பிறகு reusable animation-களை உருவாக்க view transition pseudo selector-களை பயன்படுத்தி இந்த class-ஐ refer செய்யலாம்:
::view-transition-group(.slide-in) {
}
::view-transition-old(.slide-in) {
}
::view-transition-new(.slide-in) {
}எதிர்காலத்தில், இதைப் பயன்படுத்த மேம்படுத்த CSS library-கள் View Transition Class-களைப் பயன்படுத்தி built-in animation-களைச் சேர்க்கலாம்.
Usage
enter/exit-இல் ஒரு element-ஐ animate செய்தல்
ஒரு transition-இல் component ஒன்று <ViewTransition>-ஐ சேர்க்கும்போது அல்லது நீக்கும்போது Enter/Exit Transition-கள் trigger ஆகும்:
function Child() {
return (
<ViewTransition enter="auto" exit="auto" default="none">
<div>வணக்கம்</div>
</ViewTransition>
);
}
function Parent() {
const [show, setShow] = useState();
if (show) {
return <Child />;
}
return null;
}setShow call செய்யப்படும் போது, show true ஆக மாறி Child component render ஆகும். startTransition-க்குள் setShow call செய்யப்படும்போது, மேலும் Child வேறு எந்த DOM node-க்கும் முன் ViewTransition-ஐ render செய்தால், enter animation trigger ஆகும்.
show மீண்டும் false ஆக மாறும்போது, exit animation trigger ஆகும்.
import {ViewTransition, useState, startTransition} from 'react'; import {Video} from './Video'; import videos from './data'; function Item() { return ( <ViewTransition enter="auto" exit="auto" default="none"> <Video video={videos[0]} /> </ViewTransition> ); } export default function Component() { const [showItem, setShowItem] = useState(false); return ( <> <button onClick={() => { startTransition(() => { setShowItem((prev) => !prev); }); }}> {showItem ? '➖' : '➕'} </button> {showItem ? <Item /> : null} </> ); }
Activity உடன் enter/exit-ஐ animate செய்தல்
ஒரு component-ன் state-ஐப் பாதுகாத்தபடி அதை உள்ளே/வெளியே animate செய்ய, அல்லது animation-க்காக content-ஐ pre-render செய்ய விரும்பினால், <Activity>-ஐப் பயன்படுத்தலாம். <Activity>-க்குள் உள்ள <ViewTransition> visible ஆகும்போது, enter animation activate ஆகும். அது hidden ஆகும்போது, exit animation activate ஆகும்:
<Activity mode={isVisible ? 'visible' : 'hidden'}>
<ViewTransition enter="auto" exit="auto">
<Counter />
</ViewTransition>
</Activity>இந்த உதாரணத்தில், Counter-க்கு internal state உடைய counter உள்ளது. counter-ஐ increment செய்து, அதை hide செய்து, பிறகு மீண்டும் show செய்து பாருங்கள். sidebar உள்ளே/வெளியே animate ஆகும்போது counter-ன் மதிப்பு பாதுகாக்கப்படுகிறது:
import { Activity, ViewTransition, useState, startTransition } from 'react'; export default function App() { const [show, setShow] = useState(true); return ( <div className="layout"> <Toggle show={show} setShow={setShow} /> <Activity mode={show ? 'visible' : 'hidden'}> <ViewTransition enter="auto" exit="auto" default="none"> <Counter /> </ViewTransition> </Activity> </div> ); } function Toggle({show, setShow}) { return ( <button className="toggle" onClick={() => { startTransition(() => { setShow(s => !s); }); }}> {show ? 'மறை' : 'காட்டு'} </button> ) } function Counter() { const [count, setCount] = useState(0); return ( <div className="counter"> <h2>எண்ணி</h2> <p>எண்ணிக்கை: {count}</p> <button onClick={() => setCount(count + 1)}> அதிகரி </button> </div> ); }
<Activity> இல்லாமல், sidebar மீண்டும் தோன்றும் ஒவ்வொரு முறையும் counter 0-க்கு reset ஆகும்.
shared element ஒன்றை animate செய்தல்
பொதுவாக, <ViewTransition>-க்கு பெயர் assign செய்வதை பரிந்துரைக்க மாட்டோம்; அதற்கு பதிலாக React தானாக பெயர் assign செய்ய அனுமதிக்கிறோம். continuity-ஐப் பாதுகாக்க, ஒரு tree unmount ஆகி மற்றொரு tree அதே நேரத்தில் mount ஆகும்போது முற்றிலும் வேறு component-களுக்கிடையே animate செய்ய வேண்டுமெனில் பெயர் assign செய்ய விரும்பலாம்.
<ViewTransition name={UNIQUE_NAME}>
<Child />
</ViewTransition>ஒரு tree unmount ஆகி மற்றொன்று mount ஆகும்போது, unmount ஆகும் tree-யிலும் mount ஆகும் tree-யிலும் அதே பெயர் இருக்கும் pair இருந்தால், அவை இரண்டிலும் “share” animation-ஐ trigger செய்யும். அது unmount ஆகும் பக்கத்திலிருந்து mount ஆகும் பக்கத்துக்கு animate செய்கிறது.
exit/enter animation-க்கு மாறாக, இது deleted/mounted tree-க்குள் ஆழமாக இருக்கலாம். ஒரு <ViewTransition> exit/enter-க்கும் eligible ஆக இருந்தால், “share” animation முன்னுரிமை பெறும்.
Transition முதலில் ஒரு பக்கத்தை unmount செய்து, பிறகு இறுதியில் புதிய பெயர் mount ஆகும் முன் <Suspense> fallback காட்டப்படுமாறு செய்தால், shared element transition நடக்காது.
import {ViewTransition, useState, startTransition} from 'react'; import {Video, Thumbnail, FullscreenVideo} from './Video'; import videos from './data'; export default function Component() { const [fullscreen, setFullscreen] = useState(false); if (fullscreen) { return ( <FullscreenVideo video={videos[0]} onExit={() => startTransition(() => setFullscreen(false))} /> ); } return ( <Video video={videos[0]} onClick={() => startTransition(() => setFullscreen(true))} /> ); }
list-இல் item-களின் reorder-ஐ animate செய்தல்
items.map((item) => <Component key={item.id} item={item} />);content-ஐ update செய்யாமல் list-ஐ reorder செய்யும்போது, அவை DOM node-க்கு வெளியே இருந்தால், list-இல் உள்ள ஒவ்வொரு <ViewTransition>-க்கும் “update” animation trigger ஆகும். enter/exit animation-களைப் போல.
இதன் பொருள், இது இந்த <ViewTransition>-இல் animation-ஐ trigger செய்யும்:
function Component() {
return (
<ViewTransition>
<div>...</div>
</ViewTransition>
);
}import {ViewTransition, useState, startTransition} from 'react'; import {Video} from './Video'; import videos from './data'; export default function Component() { const [orderedVideos, setOrderedVideos] = useState(videos); const reorder = () => { startTransition(() => { setOrderedVideos((prev) => { return [...prev.sort(() => Math.random() - 0.5)]; }); }); }; return ( <> <button onClick={reorder}>🎲</button> <div className="listContainer"> {orderedVideos.map((video, i) => { return ( <ViewTransition key={video.title}> <Video video={video} /> </ViewTransition> ); })} </div> </> ); }
ஆனால் இது ஒவ்வொரு தனிப்பட்ட item-ஐ animate செய்யாது:
function Component() {
return (
<div>
<ViewTransition>...</ViewTransition>
</div>
);
}அதற்கு பதிலாக, parent <ViewTransition> ஏதேனும் இருந்தால் அது cross-fade ஆகும். parent <ViewTransition> இல்லையெனில், அந்தச் சூழலில் animation இல்லை.
import {ViewTransition, useState, startTransition} from 'react'; import {Video} from './Video'; import videos from './data'; export default function Component() { const [orderedVideos, setOrderedVideos] = useState(videos); const reorder = () => { startTransition(() => { setOrderedVideos((prev) => { return [...prev.sort(() => Math.random() - 0.5)]; }); }); }; return ( <> <button onClick={reorder}>🎲</button> <ViewTransition> <div className="listContainer"> {orderedVideos.map((video, i) => { return <Video video={video} key={video.title} />; })} </div> </ViewTransition> </> ); }
Component தன் சொந்த reorder animation-ஐ control செய்ய அனுமதிக்க விரும்பும் list-களில் wrapper element-களைத் தவிர்க்கலாம் என்பதைக் குறிக்கிறது:
items.map(item => <div><Component key={item.id} item={item} /></div>)item-களில் ஒன்று resize ஆக update ஆகி, அதனால் sibling-களும் resize ஆகும் சூழலுக்கும் மேலுள்ள விதி பொருந்தும்; அவை immediate sibling-களாக இருந்தால் மட்டுமே அது sibling <ViewTransition>-ஐயும் animate செய்யும்.
அதாவது அதிக re-layout ஏற்படுத்தும் update-இன் போது, page-இல் உள்ள ஒவ்வொரு <ViewTransition>-யையும் தனித்தனியாக animate செய்யாது. அது உண்மையான மாற்றத்திலிருந்து கவனத்தைத் திருப்பும் பல noisy animation-களுக்கு வழிவகுக்கும். எனவே தனிப்பட்ட animation எப்போது trigger ஆக வேண்டும் என்பதில் React சற்றுக் கவனமாக இருக்கும்.
Suspense content-இலிருந்து animate செய்தல்
எந்த Transition போலவே, animation ஓடுவதற்கு முன் data மற்றும் புதிய CSS (<link rel="stylesheet" precedence="...">) க்காக React காத்திருக்கும். இதற்கு கூடுதலாக, புதிய font-கள் பின்னர் flicker ஆகாமல் இருக்க animation தொடங்குவதற்கு முன் ViewTransition-கள் அவை load ஆக 500ms வரை காத்திருக்கும். அதே காரணத்திற்காக, ViewTransition-இல் wrap செய்யப்பட்ட image, image load ஆக காத்திருக்கும்.
இது புதிய Suspense boundary instance-க்குள் இருந்தால், fallback முதலில் காட்டப்படும். Suspense boundary முழுமையாக load ஆன பிறகு, content reveal-ஐ animate செய்ய அது <ViewTransition>-ஐ trigger செய்கிறது.
<ViewTransition>-ஐ எங்கே வைக்கிறீர்கள் என்பதன் அடிப்படையில் Suspense boundary-களை animate செய்ய இரண்டு வழிகள் உள்ளன:
Update:
<ViewTransition>
<Suspense fallback={<A />}>
<B />
</Suspense>
</ViewTransition>இந்தச் சூழலில் content A-இலிருந்து B-க்கு மாறும்போது, அது “update” ஆக நடத்தப்படும்; பொருத்தமானால் அந்த class apply செய்யப்படும். A மற்றும் B இரண்டுக்கும் அதே view-transition-name கிடைக்கும், எனவே இயல்பாக அவை cross-fade போல செயல்படும்.
import {ViewTransition, useState, startTransition, Suspense} from 'react'; import {Video, VideoPlaceholder} from './Video'; import {useLazyVideoData} from './data'; function LazyVideo() { const video = useLazyVideoData(); return <Video video={video} />; } export default function Component() { const [showItem, setShowItem] = useState(false); return ( <> <button onClick={() => { startTransition(() => { setShowItem((prev) => !prev); }); }}> {showItem ? '➖' : '➕'} </button> {showItem ? ( <ViewTransition> <Suspense fallback={<VideoPlaceholder />}> <LazyVideo /> </Suspense> </ViewTransition> ) : null} </> ); }
Enter/Exit:
<Suspense fallback={<ViewTransition><A /></ViewTransition>}>
<ViewTransition><B /></ViewTransition>
</Suspense>இந்தச் சூழலில், இவை தத்தமுடைய view-transition-name கொண்ட இரண்டு தனித்தனி ViewTransition instance-கள். இது <A>-ன் “exit” மற்றும் <B>-ன் “enter” ஆக நடத்தப்படும்.
<ViewTransition> boundary-ஐ எங்கே வைக்கிறீர்கள் என்பதன் அடிப்படையில் வேறு effect-களைப் பெறலாம்.
animation ஒன்றிலிருந்து opt out செய்தல்
சில நேரங்களில் முழு page போன்ற பெரிய existing component ஒன்றை wrap செய்து, theme மாற்றம் போன்ற சில update-களை animate செய்ய விரும்பலாம். ஆனால் முழு page-க்குள் update ஆகும் எல்லா update-களும் cross-fade ஆக opt-in ஆக வேண்டாம் என்று நினைக்கலாம். குறிப்பாக நீங்கள் animation-களை படிப்படியாகச் சேர்க்கும்போது.
animation ஒன்றிலிருந்து opt out செய்ய “none” class-ஐப் பயன்படுத்தலாம். உங்கள் children-ஐ “none”-இல் wrap செய்வதன் மூலம், parent இன்னும் trigger ஆகினாலும் அவற்றின் update-களுக்கான animation-களை disable செய்யலாம்.
<ViewTransition>
<div className={theme}>
<ViewTransition update="none">{children}</ViewTransition>
</div>
</ViewTransition>theme மாறினால் மட்டுமே இது animate ஆகும்; children மட்டும் update ஆனால் அல்ல. children தங்களுடைய <ViewTransition> மூலம் மீண்டும் opt-in ஆகலாம், ஆனால் குறைந்தது அது மீண்டும் manual ஆக இருக்கும்.
animation-களை customize செய்தல்
இயல்பாக, <ViewTransition> browser-இலிருந்து default cross-fade-ஐ உட்கொண்டுள்ளது.
animation-களை customize செய்ய, <ViewTransition> எப்படி activate ஆகிறது என்பதன் அடிப்படையில் எந்த animation-களை பயன்படுத்த வேண்டும் என்பதை குறிப்பிட <ViewTransition> component-க்கு props வழங்கலாம்.
உதாரணமாக, default cross fade animation-ஐ மெதுவாக்கலாம்:
<ViewTransition default="slow-fade">
<Video />
</ViewTransition>மேலும் view transition class-களைப் பயன்படுத்தி CSS-இல் slow-fade-ஐ define செய்யலாம்:
::view-transition-old(.slow-fade) {
animation-duration: 500ms;
}
::view-transition-new(.slow-fade) {
animation-duration: 500ms;
}import {ViewTransition, useState, startTransition} from 'react'; import {Video} from './Video'; import videos from './data'; function Item() { return ( <ViewTransition default="slow-fade"> <Video video={videos[0]} /> </ViewTransition> ); } export default function Component() { const [showItem, setShowItem] = useState(false); return ( <> <button onClick={() => { startTransition(() => { setShowItem((prev) => !prev); }); }}> {showItem ? '➖' : '➕'} </button> {showItem ? <Item /> : null} </> ); }
default-ஐ அமைப்பதற்குப் கூடுதலாக, enter, exit, update, மற்றும் share animation-களுக்கான configuration-களையும் வழங்கலாம்.
import {ViewTransition, useState, startTransition} from 'react'; import {Video} from './Video'; import videos from './data'; function Item() { return ( <ViewTransition enter="slide-in" exit="slide-out"> <Video video={videos[0]} /> </ViewTransition> ); } export default function Component() { const [showItem, setShowItem] = useState(false); return ( <> <button onClick={() => { startTransition(() => { setShowItem((prev) => !prev); }); }}> {showItem ? '➖' : '➕'} </button> {showItem ? <Item /> : null} </> ); }
type-களுடன் animation-களை customize செய்தல்
குறிப்பிட்ட activation trigger-க்கு குறிப்பிட்ட transition type activate ஆகும்போது child element-களுக்கு class name சேர்க்க addTransitionType API-யைப் பயன்படுத்தலாம். இது ஒவ்வொரு transition type-க்கும் animation-ஐ customize செய்ய அனுமதிக்கிறது.
உதாரணமாக, அனைத்து forward மற்றும் backward navigation-களுக்கான animation-ஐ customize செய்ய:
<ViewTransition
default={{
'navigation-back': 'slide-right',
'navigation-forward': 'slide-left',
}}>
<div>...</div>
</ViewTransition>;
// in your router:
startTransition(() => {
addTransitionType('navigation-' + navigationType);
});ViewTransition “navigation-back” animation-ஐ activate செய்யும்போது, React “slide-right” class name-ஐச் சேர்க்கும். ViewTransition “navigation-forward” animation-ஐ activate செய்யும்போது, React “slide-left” class name-ஐச் சேர்க்கும்.
எதிர்காலத்தில், router-களும் பிற library-களும் standard view-transition type-களுக்கும் style-களுக்கும் support சேர்க்கலாம்.
import { ViewTransition, addTransitionType, useState, startTransition, } from 'react'; import {Video} from './Video'; import videos from './data'; function Item() { return ( <ViewTransition enter={{ 'add-video-back': 'slide-in-back', 'add-video-forward': 'slide-in-forward', }} exit={{ 'remove-video-back': 'slide-in-forward', 'remove-video-forward': 'slide-in-back', }}> <Video video={videos[0]} /> </ViewTransition> ); } export default function Component() { const [showItem, setShowItem] = useState(false); return ( <> <div className="button-container"> <button onClick={() => { startTransition(() => { if (showItem) { addTransitionType('remove-video-back'); } else { addTransitionType('add-video-back'); } setShowItem((prev) => !prev); }); }}> ⬅️ </button> <button onClick={() => { startTransition(() => { if (showItem) { addTransitionType('remove-video-forward'); } else { addTransitionType('add-video-forward'); } setShowItem((prev) => !prev); }); }}> ➡️ </button> </div> {showItem ? <Item /> : null} </> ); }
JavaScript மூலம் animate செய்தல்
View Transition Class-கள் CSS மூலம் animation-களை define செய்ய அனுமதித்தாலும், சில நேரங்களில் animation மீது imperative control தேவைப்படும். onEnter, onExit, onUpdate, மற்றும் onShare callback-கள் view transition pseudo-element-களுக்கு நேரடி அணுகலை வழங்குகின்றன; எனவே Web Animations API-யைப் பயன்படுத்தி அவற்றை animate செய்யலாம்.
ஒவ்வொரு callback-க்கும் view transition pseudo-element-களை பிரதிநிதித்துவப்படுத்தும் .old மற்றும் .new property-கள் கொண்ட instance கிடைக்கும். DOM element-இல் செய்வது போலவே அவற்றிலும் .animate()-ஐ call செய்யலாம்:
<ViewTransition
onEnter={(instance) => {
const anim = instance.new.animate(
[
{transform: 'scale(0.8)'},
{transform: 'scale(1)'},
],
{duration: 300, easing: 'ease-out'}
);
return () => anim.cancel();
}}>
<div>...</div>
</ViewTransition>இது CSS-driven animation-களையும் JavaScript-driven animation-களையும் இணைக்க அனுமதிக்கிறது.
பின்வரும் உதாரணத்தில், default cross-fade CSS மூலம் கையாளப்படுகிறது; slide animation-கள் onEnter மற்றும் onExit animation-களில் JavaScript மூலம் இயக்கப்படுகின்றன:
import {ViewTransition, useState, startTransition} from 'react'; import {Video} from './Video'; import videos from './data'; import {SLIDE_IN, SLIDE_OUT} from './animations'; function Item() { return ( <ViewTransition default="none" /* CSS driven cross fade defaults */ enter="auto" exit="auto" /* JS driven slide animations */ onEnter={(instance) => { const anim = instance.new.animate( SLIDE_IN, {duration: 500, easing: 'ease-out'} ); return () => anim.cancel(); }} onExit={(instance) => { const anim = instance.old.animate( SLIDE_OUT, {duration: 300, easing: 'ease-in'} ); return () => anim.cancel(); }}> <Video video={videos[0]} /> </ViewTransition> ); } export default function Component() { const [showItem, setShowItem] = useState(false); return ( <> <button onClick={() => { startTransition(() => { setShowItem((prev) => !prev); }); }}> {showItem ? '➖' : '➕'} </button> {showItem ? <Item /> : null} </> ); }
JavaScript மூலம் transition type-களை animate செய்தல்
Transition எப்படி trigger செய்யப்பட்டது என்பதன் அடிப்படையில் வேறு animation-களை conditionally apply செய்ய, ViewTransition event-களுக்கு pass செய்யப்படும் types-ஐப் பயன்படுத்தலாம்.
<ViewTransition
onEnter={(instance, types) => {
const duration = types.includes('fast') ? 150 : 2000;
const anim = instance.new.animate(
SLIDE_IN,
{duration: duration, easing: 'ease-out'}
);
return () => anim.cancel();
}}
>இந்த உதாரணம் Transition-ஐ “fast” என குறிக்க addTransitionType-ஐ call செய்து, பின்னர் animation duration-ஐ adjust செய்கிறது:
import {ViewTransition, useState, startTransition, addTransitionType} from 'react'; import {Video} from './Video'; import videos from './data'; import {SLIDE_IN, SLIDE_OUT} from './animations'; function Item() { return ( <ViewTransition onEnter={(instance, types) => { const duration = types.includes('fast') ? 150 : 2000; const anim = instance.new.animate( SLIDE_IN, {duration: duration, easing: 'ease-out'} ); return () => anim.cancel(); }} onExit={(instance, types) => { const duration = types.includes('fast') ? 150 : 500; const anim = instance.old.animate( SLIDE_OUT, {duration: duration, easing: 'ease-in'} ); return () => anim.cancel(); }}> <Video video={videos[0]} /> </ViewTransition> ); } export default function Component() { const [showItem, setShowItem] = useState(false); const [isFast, setIsFast] = useState(false); return ( <> <div> வேகம்: <input type="checkbox" onChange={() => {setIsFast(f => !f)}} value={isFast}></input> </div><br /> <button onClick={() => { startTransition(() => { if (isFast) { addTransitionType('fast'); } setShowItem((prev) => !prev); }); }}> {showItem ? '➖' : '➕'} </button> {showItem ? <Item /> : null} </> ); }
View Transition enabled router-களை உருவாக்குதல்
scroll restoration animation-க்குள் நடப்பதை உறுதிசெய்ய, pending Navigation ஏதேனும் முடியும் வரை React காத்திருக்கும். Navigation React-இல் blocked ஆக இருந்தால், useEffect deadlock-க்கு வழிவகுக்கும் என்பதால், உங்கள் router useLayoutEffect-இல் unblock செய்ய வேண்டும்.
legacy popstate event-இலிருந்து startTransition தொடங்கப்பட்டால், உதாரணமாக “back” navigation-இன் போது, scroll மற்றும் form restoration சரியாக வேலை செய்வதை உறுதிசெய்ய அது synchronously முடிக்கப்பட வேண்டும். இது View Transition animation ஓடுவதுடன் முரண்படும். எனவே React popstate-இலிருந்து வரும் animation-களை skip செய்யும்; back button-க்கு animation ஓடாது. உங்கள் router-ஐ Navigation API பயன்படுத்துமாறு upgrade செய்வதன் மூலம் இதைச் சரிசெய்யலாம்.
Troubleshooting
என் <ViewTransition> activate ஆகவில்லை
<ViewTransition> எந்த DOM node-க்கும் முன் வைக்கப்பட்டால் மட்டுமே activate ஆகும்:
function Component() {
return (
<div>
<ViewTransition>வணக்கம்</ViewTransition>
</div>
);
}சரிசெய்ய, <ViewTransition> மற்ற எந்த DOM node-க்கும் முன் வருவதை உறுதிசெய்யுங்கள்:
function Component() {
return (
<ViewTransition>
<div>வணக்கம்</div>
</ViewTransition>
);
}“There are two <ViewTransition name=%s> components with the same name mounted at the same time.” என்ற error வருகிறது
ஒரே name கொண்ட இரண்டு <ViewTransition> component-கள் ஒரே நேரத்தில் mount ஆனால் இந்த error ஏற்படும்:
function Item() {
// 🚩 All items will get the same "name".
return <ViewTransition name="item">...</ViewTransition>;
}
function ItemList({items}) {
return (
<>
{items.map((item) => (
<Item key={item.id} />
))}
</>
);
}இதனால் View Transition error ஆகும். development-இல், React இந்த issue-வை வெளிக்காட்ட detect செய்து இரண்டு error-களை log செய்கிறது:
<ViewTransition name=%s> components with the same name mounted at the same time. This is not supported and will cause View Transitions to error. Try to use a more unique name e.g. by using a namespace prefix and adding the id of an item to the name.
at Item
at ItemList<ViewTransition name=%s> duplicate has this stack trace.
at Item
at ItemListசரிசெய்ய, name unique என்பதை உறுதிசெய்தோ அல்லது பெயருக்கு id சேர்த்தோ, முழு app-இல் ஒரே நேரத்தில் அதே பெயருடன் ஒரே ஒரு <ViewTransition> மட்டுமே mount ஆகும் என்பதை உறுதிசெய்யுங்கள்:
function Item({id}) {
// ✅ All items will get a unique name.
return <ViewTransition name={`item-${id}`}>...</ViewTransition>;
}
function ItemList({items}) {
return (
<>
{items.map((item) => (
<Item key={item.id} item={item} />
))}
</>
);
}