कंटेंट पर जाएँ
charmotion

React Native ऐप में एनिमेशन कैसे जोड़ें

Charmotion टीम द्वारा · अपडेट:

गाइड का कवर इलस्ट्रेशन: React Native ऐप में एनिमेशन कैसे जोड़ें, Charmotion के डेमो कैरेक्टर के साथ

React Native ऐप में एनिमेशन जोड़ने के लिए, आसान UI motion के लिए built-in Animated API को useNativeDriver: true के साथ इस्तेमाल करें, और gesture-आधारित या जटिल motion के लिए Reanimated। डिज़ाइनर के बनाए vector लूप के लिए lottie-react-native, इंटरैक्टिव कैरेक्टर के लिए @rive-app/react-native, और क्लिप के लिए react-native-video जोड़ें।

मुख्य बातें

  • useNativeDriver: true किसी Animated एनिमेशन को UI thread पर ले जाता है।
  • Reanimated 4 सिर्फ़ New Architecture पर काम करता है और इसे react-native-worklets चाहिए।
  • Rive के Nitro runtime के लिए React Native 0.78+, Expo SDK 53+, iOS 15.1+ और Android SDK 24+ ज़रूरी हैं।
  • Rive में स्टेट बदलाव useRiveNumber और useRiveTrigger जैसे data binding hooks से होते हैं।
  • लूप शुरू करने से पहले AccessibilityInfo.isReduceMotionEnabled() जाँचें।

पहले से कोई कैरेक्टर या लोगो है? अपने कैरेक्टर को असली ऐप स्क्रीन में देखें: स्प्लैश, ऑनबोर्डिंग, लोडिंग और एम्प्टी स्टेट स्क्रीन। यह फ़्री है, आपके ब्राउज़र में चलता है और कुछ भी अपलोड नहीं होता।

Animated API या Reanimated: कौन-सा इस्तेमाल करें?

React Native में Animated API पहले से मौजूद है। fade, slide और सामान्य spring के लिए यह काफ़ी है, और इसके लिए कोई अतिरिक्त dependency नहीं चाहिए। Software Mansion की Reanimated, gesture से चलने वाले मोशन, layout एनिमेशन और ऐसी हर चीज़ के लिए आम पसंद है जिसे JavaScript के व्यस्त होने पर भी स्मूद चलना चाहिए।

बाकी टूल्स ये हैं:

आप एनिमेट करना चाहते हैंइस्तेमाल
सामान्य UI फ़ीडबैकAnimated के साथ useNativeDriver: true
Gestures, जटिल sequencesReanimated
डिज़ाइनर का बनाया वेक्टर लूपlottie-react-native
ऐप की घटनाओं पर रिएक्ट करने वाला कैरेक्टर@rive-app/react-native
पहले से रेंडर की गई तय क्लिपreact-native-video

Reanimated का spring कुछ ऐसा दिखता है:

import Animated, { useSharedValue, useAnimatedStyle, withSpring } from "react-native-reanimated";

function Bouncy() {
  const scale = useSharedValue(1);
  const style = useAnimatedStyle(() => ({ transform: [{ scale: scale.value }] }));
  return (
    <Pressable onPressIn={() => (scale.value = withSpring(0.92))}
               onPressOut={() => (scale.value = withSpring(1))}>
      <Animated.View style={[styles.card, style]} />
    </Pressable>
  );
}

Reanimated 4 सिर्फ़ New Architecture (Fabric) के साथ काम करता है और इसके लिए react-native-worklets ज़रूरी है। legacy architecture पर चल रहे पुराने ऐप को पहले migrate करना होगा, या Reanimated के किसी पुराने version पर ही रहना होगा।

useNativeDriver असल में क्या करता है?

native driver के बिना JavaScript हर फ़्रेम की गणना करता है और उसे native code तक भेजता है। अगर JS thread व्यस्त है, जैसे कोई बड़ा response parse कर रहा है, तो फ़्रेम ड्रॉप होते हैं। useNativeDriver: true के साथ React Native पूरा एनिमेशन एक ही बार native code को भेज देता है, और वह हर फ़्रेम पर JavaScript से गुज़रे बिना UI thread पर चलता है।

const opacity = useRef(new Animated.Value(0)).current;

useEffect(() => {
  Animated.timing(opacity, {
    toValue: 1,
    duration: 300,
    useNativeDriver: true,
  }).start();
}, []);

return <Animated.View style={{ opacity }}>{children}</Animated.View>;

native driver opacity और transform जैसी non-layout properties को सपोर्ट करता है। width, height या margins को एनिमेट करने के लिए JS driver चाहिए, इसलिए मोशन को scale और translation के रूप में लिखना बेहतर है।

Reanimated का मूल विचार भी यही है: worklets एनिमेशन logic को UI thread पर चलाते हैं, इसलिए आपका JavaScript धीमा हो तब भी gestures और springs स्मूद रहते हैं।

एक कैरेक्टर की दस लूपिंग स्टेट, हर एक 0 से 9 तक के मूड नंबर से चुनी जाती है
एक Charmotion Rive file की दस लूपिंग स्टेट, जिन्हें मूड नंबर इनपुट से चुना जाता है।

Expo या bare React Native में Lottie एनिमेशन कैसे जोड़ें?

lottie-react-native इंस्टॉल करें। bare project में इसके बाद ios फ़ोल्डर में pod install चलाएँ; Expo में npx expo install lottie-react-native इस्तेमाल करें ताकि version आपके SDK से मेल खाए। पहले README की requirements देख लें: मौजूदा major version New Architecture पर हाल के React Native versions के लिए है, और पुराने versions के लिए 7.3.x line उपलब्ध है।

import LottieView from "lottie-react-native";

export function Loading() {
  return (
    <LottieView
      source={require("./assets/loading.json")}
      style={{ width: 160, height: 160 }}
      autoPlay
      loop
    />
  );
}

view को साफ़ dimensions दें, जैसा README के उदाहरण में किया गया है। React Native Web के लिए इस package को @lottiefiles/dotlottie-react भी चाहिए।

Lottie spinners, success checks और ऑनबोर्डिंग illustrations के लिए अच्छा है। अगर एनिमेशन को ऐप स्टेट के हिसाब से अपना बर्ताव बदलना है, तो Lottie फ़ाइलें बदलने की बजाय Rive स्टेट मशीन ज़्यादा आसान है।

Nitro runtime के साथ Rive कैरेक्टर कैसे जोड़ें?

Rive का मौजूदा React Native runtime Nitro Modules पर बना है। इसे इसकी peer dependency के साथ इंस्टॉल करें; Expo में npx expo install और development build इस्तेमाल करें, क्योंकि इसमें native code है:

npm install @rive-app/react-native react-native-nitro-modules

इसके लिए React Native 0.78+ (0.79+ सुझाया गया), Expo SDK 53+, iOS 15.1+ और Android SDK 24+ ज़रूरी है। पुराना rive-react-native package अब legacy है।

useRiveFile से फ़ाइल लोड करें, एक view model instance बनाएँ, और hooks से properties bind करें:

import { RiveView, useRiveFile, useViewModelInstance, useRiveNumber, useRiveTrigger } from "@rive-app/react-native";

export function Mascot({ loading }: { loading: boolean }) {
  const { riveFile } = useRiveFile(require("./assets/character.riv"));
  const { instance } = useViewModelInstance(riveFile, { async: true, viewModelName: "Character" });
  const { setValue: setMood } = useRiveNumber("mood", instance);
  const { trigger: success } = useRiveTrigger("success", instance);

  useEffect(() => { setMood(loading ? 5 : 0); }, [loading]);

  if (!riveFile) return null;
  return (
    <RiveView
      file={riveFile}
      stateMachineName="CharacterViewModelMachine"
      dataBind={instance}
      autoPlay={true}
      style={{ width: 220, height: 220 }}
    />
  );
}

कोई action पूरा होने पर success() कॉल करें। Rive के docs async: true की सलाह देते हैं और बताते हैं कि अगर स्टेट मशीन रुक चुकी है, तो properties बदलने के बाद view ref पर playIfNeeded() कॉल करना पड़ सकता है। इस runtime में स्टेट मशीन input methods deprecated हैं; migration timeline के लिए React Native पर Rive देखें।

muted, लूपिंग वीडियो कैसे चलाएँ?

किसी तय क्लिप के लिए react-native-video इस्तेमाल करें। मौजूदा major version और उसका न्यूनतम iOS version README में देख लें। muted लूप के लिए तीन props चाहिए:

import Video from "react-native-video";

<Video
  source={require("./assets/logo-reveal.mp4")}
  style={{ width: 240, height: 240 }}
  resizeMode="contain"
  repeat
  muted
/>

फ़ोटोग्राफ़िक या 3D क्लिप, जैसे launch reveal या marketing लूप, के लिए वीडियो सही टूल है। यह ऐप स्टेट पर रिएक्ट नहीं कर सकता, और हर variation आपके bundle में एक और फ़ाइल जोड़ता है। जिस कैरेक्टर को idle रहना, इंतज़ार करना और जश्न मनाना है, उसके लिए स्टेट मशीन वाली एक Rive फ़ाइल आमतौर पर छोटी और कहीं ज़्यादा flexible होती है।

जब स्क्रीन से focus हटे तो वीडियो pause करें, उदाहरण के लिए React Navigation के focus events से, ताकि वह background में decode होता न रहे।

Lottie, Rive या वीडियो: React Native में सबसे हल्का कौन है?

हर विकल्प के दो खर्च हैं: runtime library, जिसे आप एक बार जोड़ते हैं, और हर एनिमेशन के लिए ऐप के साथ भेजी जाने वाली फ़ाइलें।

  • वीडियो के लिए react-native-video चाहिए, और हर क्लिप एक अलग फ़ाइल है। साइज़ resolution, लंबाई और variations की संख्या के साथ बढ़ता है।
  • Lottie Lottie की native libraries जोड़ता है। Files JSON होती हैं, इसलिए एक सामान्य vector लूप छोटा होता है, लेकिन कई layers वाले जटिल After Effects exports जल्दी बड़े हो सकते हैं।
  • Rive अपना native runtime जोड़ता है। Rive के अनुसार iOS runtime का डाउनलोड करीब 1.67 MB और Android ARM-v8a runtime का डाउनलोड 2.40 MB है (जनवरी 2026)। इसके बाद हर .riv एक compact binary है जिसमें कैरेक्टर की हर स्टेट समा सकती है।

स्टेट बढ़ने के साथ समीकरण उलट जाता है। एक स्क्रीन पर एक सजावटी लूप अक्सर छोटे वीडियो या Lottie file के रूप में सबसे हल्का होता है। idle, loading, success, error और talking स्टेट वाले मैस्कॉट के लिए पाँच वीडियो या पाँच Lottie files चाहिए, जिनके बीच अचानक कट होंगे, जबकि एक Rive file स्मूद transitions के साथ इन सबको संभाल लेती है।

आप जो भी चुनें, असली आँकड़े मापें: library जोड़ने से पहले और बाद में अपने release bundle का साइज़ जाँचें, और vendor के उदाहरणों पर भरोसा करने के बजाय अपने आर्टवर्क की फ़ाइल साइज़ की तुलना करें।

ऑनबोर्डिंग मैस्कॉट या कैरेक्टर कैसे जोड़ें?

मैस्कॉट की स्टेट आर्टवर्क से नहीं, अपने ऐप के events से तय करें। एक आम mapping:

  • ऑनबोर्डिंग स्टेप दिखे: enter फ़ायर करें, फिर idle।
  • network का इंतज़ार: loading लूप (मूड 5)।
  • permission मिली या काम पूरा हुआ: success फ़ायर करें। विफलता: error फ़ायर करें।
  • Voice input: listening; जवाब चल रहा हो: talking।

यह mapping एक ही hook में रखें, जैसे useMascot(state), जो मूड सेट करे और ट्रिगर फ़ायर करे। स्क्रीन अपनी state भेजती हैं; Rive स्टेट मशीन transitions संभालती है ताकि रिएक्शन ठीक से पूरे हों।

success: एक ट्रिगर जो एक बार चलता है, फिर मौजूदा मूड पर लौट आता है।

Charmotion अपलोड किए गए मैस्कॉट या लोगो से इसी तरह की फ़ाइल बनाता है: CharacterViewModelMachine और Character व्यू मॉडल वाली एक .riv (0 से 9 तक का mood नंबर और success, error, enter और exit जैसे ट्रिगर), जो ऊपर दिए Nitro code से मेल खाती है। प्लानिंग के लिए मैस्कॉट एनिमेशन स्टेट देखें।

React Native एनिमेशन को स्मूद और accessible कैसे रखें?

एनिमेशन का काम JavaScript thread से दूर रखें:

  • useNativeDriver: true या Reanimated worklets इस्तेमाल करें, और transform और opacity को एनिमेट करें।
  • जिन स्क्रीन पर focus नहीं है, वहाँ लूप, Lottie views और वीडियो को unmount या pause करें।
  • एनिमेशन फ़ाइलों को पहली बार दिखने पर fetch करने के बजाय ऐप के साथ bundle करें।
  • release builds को किसी असली low-end Android device पर टेस्ट करें; dev mode धीमा होता है।

मोशन कम करें सेटिंग का सम्मान करें। सेटिंग चालू होने पर AccessibilityInfo.isReduceMotionEnabled() true पर resolve होता है, और इसके बदलने पर reduceMotionChanged event फ़ायर होता है। Android पर transition animation scale बंद होने पर भी यह true बताता है।

const [reduce, setReduce] = useState(false);

useEffect(() => {
  AccessibilityInfo.isReduceMotionEnabled().then(setReduce);
  const sub = AccessibilityInfo.addEventListener("reduceMotionChanged", setReduce);
  return () => sub.remove();
}, []);

return reduce ? <Image source={require("./assets/mascot-still.png")} /> : <Mascot loading={loading} />;

मोशन हटाते समय उसका अर्थ text में बनाए रखें। WCAG की जानकारी के लिए मोशन कम करने की गाइड देखें।

React Native ऐप में एनिमेशन जोड़ें

  1. पहले built-ins इस्तेमाल करें. Animated और useNativeDriver: true से opacity और transform को एनिमेट करें।
  2. gestures के लिए Reanimated जोड़ें. Reanimated और react-native-worklets इंस्टॉल करें; version 4 के लिए New Architecture ज़रूरी है।
  3. आर्टवर्क के लिए runtime जोड़ें. lottie-react-native इंस्टॉल करें, या react-native-nitro-modules के साथ @rive-app/react-native (Expo development build)।
  4. फ़ाइल render करें. <LottieView source autoPlay loop /> इस्तेमाल करें, या <RiveView file={riveFile} /> के साथ useRiveFile।
  5. ऐप की state bind करें. एक view model instance बनाएँ और उसे useRiveNumber और useRiveTrigger से चलाएँ।
  6. Reduce Motion सेटिंग का ध्यान रखें. AccessibilityInfo.isReduceMotionEnabled() जाँचें और true होने पर एक स्थिर इमेज दिखाएँ।

अक्सर पूछे जाने वाले सवाल

क्या Reanimated 4 के लिए New Architecture ज़रूरी है?

हाँ। Software Mansion के docs के अनुसार Reanimated 4.x सिर्फ़ React Native New Architecture (Fabric) के साथ काम करता है, और इसके लिए react-native-worklets package ज़रूरी है। अगर आपका ऐप अभी भी legacy architecture पर चलता है, तो पहले migrate करें, या जब तक migrate न कर पाएँ तब तक Reanimated के किसी पुराने major version पर रहें।

क्या मैं Expo Go में Rive इस्तेमाल कर सकता हूँ?

नहीं। Rive के React Native runtime में Nitro Modules के ज़रिए native code है, इसलिए यह standard Expo Go ऐप के अंदर नहीं चल सकता। Expo development build (Expo SDK 53 या बाद का) या bare React Native project इस्तेमाल करें, फिर @rive-app/react-native और react-native-nitro-modules इंस्टॉल करें।

क्या rive-react-native deprecated है?

Rive अब rive-react-native को legacy runtime मानता है और नए projects को Nitro पर आधारित @rive-app/react-native की ओर भेजता है। मौजूदा ऐप फ़िलहाल पुराने package पर चलते रह सकते हैं, लेकिन नए features और data binding का काम नए runtime के लिए हो रहा है, इसलिए migration की योजना बनाएँ।

सिंपल fade के लिए Animated इस्तेमाल करें या Reanimated?

बिल्ट-इन Animated API काफ़ी है। Animated.timing को useNativeDriver: true के साथ इस्तेमाल करें ताकि fade UI thread पर चले। Reanimated तब चुनें जब मोशन किसी gesture के साथ चलता हो, कई स्टेप एक के बाद एक जुड़े हों, या JavaScript thread के दूसरे काम में व्यस्त होने पर भी मोशन स्मूद रहना ज़रूरी हो।

इस गाइड से झटपट जवाब

स्रोत

संबंधित गाइड