React Native / Animated API үндэс

Animated API үндэс

Animation нь аппыг амьд болгодог. Товч дарахад шахагдах, дэлгэц нээгдэхэд element гарч ирэх, карт арилах — энэ бүгд animation. React Native-д суурь animation хийхэд Animated API хангалттай. Эхлэгчдэд маш ойлгомжтой, судалчихвал аппаа огт өөр харагдуулж чадна.

Animated.Value — animation-н суурь

Бүх animation Animated.Value-с эхэлдэг. Энэ нь цаг хугацааны явцад өөрчлөгдөх тоон утга:

typescript
import { useRef } from 'react';
import { Animated, View, TouchableOpacity, Text, StyleSheet } from 'react-native';

export default function FadeExample() {
  const opacity = useRef(new Animated.Value(1)).current;

  function fadeOut() {
    Animated.timing(opacity, {
      toValue: 0,        // 1-ээс 0 болтол
      duration: 500,     // 500 миллисекунд
      useNativeDriver: true,
    }).start();
  }

  function fadeIn() {
    Animated.timing(opacity, {
      toValue: 1,
      duration: 500,
      useNativeDriver: true,
    }).start();
  }

  return (
    <View style={styles.container}>
      <Animated.View style={[styles.box, { opacity }]}>
        <Text style={styles.text}>Би мөхөж байна 👻</Text>
      </Animated.View>

      <TouchableOpacity style={styles.button} onPress={fadeOut}>
        <Text style={styles.buttonText}>Арилгах</Text>
      </TouchableOpacity>

      <TouchableOpacity style={styles.button} onPress={fadeIn}>
        <Text style={styles.buttonText}>Харуулах</Text>
      </TouchableOpacity>
    </View>
  );
}

const styles = StyleSheet.create({
  container: { flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: '#0b1120' },
  box: { width: 160, height: 160, backgroundColor: '#22d3ee', borderRadius: 12, justifyContent: 'center', alignItems: 'center', marginBottom: 24 },
  text: { color: '#0b1120', fontWeight: 'bold' },
  button: { backgroundColor: '#1e293b', padding: 12, borderRadius: 8, marginTop: 8, width: 160, alignItems: 'center' },
  buttonText: { color: '#f1f5f9' },
});

Animated.View, Animated.Text, Animated.Image — эдгээр нь animation-д зориулсан тусгай component-үүд. Энгийн View-г animation болгохгүй, заавал Animated.View ашиглана.

Хөдөлгөөн — translateX, translateY

Элементийг хөдөлгөхөд transform style ашиглана:

typescript
export default function SlideExample() {
  const slideX = useRef(new Animated.Value(-300)).current;

  function slideIn() {
    Animated.spring(slideX, {
      toValue: 0,
      tension: 50,    // Хатуулаг
      friction: 7,    // Зогсолтын хурд
      useNativeDriver: true,
    }).start();
  }

  return (
    <View style={{ flex: 1, backgroundColor: '#0b1120', justifyContent: 'center' }}>
      <Animated.View
        style={{
          transform: [{ translateX: slideX }],
          backgroundColor: '#818cf8',
          padding: 20,
          margin: 16,
          borderRadius: 12,
        }}
      >
        <Text style={{ color: '#fff', fontSize: 18 }}>Гүйж ирлээ! 🏃</Text>
      </Animated.View>

      <TouchableOpacity
        style={{ margin: 16, backgroundColor: '#1e293b', padding: 14, borderRadius: 8 }}
        onPress={slideIn}
      >
        <Text style={{ color: '#f1f5f9', textAlign: 'center' }}>Ажиллуулах</Text>
      </TouchableOpacity>
    </View>
  );
}

Animated.timing нь жигд хөдөлгөөн, Animated.spring нь дэвших ("bouncy") хөдөлгөөн хийдэг.

Sequence ба Parallel — animation дараалал

Хэд хэдэн animation-г дараалан эсвэл зэрэг ажиллуулж болно:

typescript
export default function SequenceExample() {
  const scale = useRef(new Animated.Value(1)).current;
  const opacity = useRef(new Animated.Value(1)).current;

  function playAnimation() {
    // Дараалан ажиллуулах
    Animated.sequence([
      Animated.timing(scale, { toValue: 1.3, duration: 200, useNativeDriver: true }),
      Animated.timing(scale, { toValue: 1, duration: 200, useNativeDriver: true }),
    ]).start();

    // Зэрэг ажиллуулах
    // Animated.parallel([
    //   Animated.timing(scale, { toValue: 1.3, duration: 300, useNativeDriver: true }),
    //   Animated.timing(opacity, { toValue: 0.5, duration: 300, useNativeDriver: true }),
    // ]).start();
  }

  return (
    <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: '#0b1120' }}>
      <TouchableOpacity onPress={playAnimation}>
        <Animated.View
          style={{
            transform: [{ scale }],
            opacity,
            backgroundColor: '#4ade80',
            width: 100,
            height: 100,
            borderRadius: 50,
            justifyContent: 'center',
            alignItems: 'center',
          }}
        >
          <Text style={{ fontSize: 36 }}>❤️</Text>
        </Animated.View>
      </TouchableOpacity>
    </View>
  );
}

useNativeDriver: true — JavaScript thread-ийг тойрч, UI thread дээр шууд animation хийдэг тул заавал true болгоно. Зөвхөн opacity болон transform property-д ажилладаг гэдгийг санаарай.

Дараагийн хичээлд:

React Native Reanimated — илүү хүчирхэг, гөлгөр animation хийх орчин үеийн арга. Gesture-тэй хослуулах, worklet ашиглах, 60fps animation хангах боломжийг авч үзнэ.