Kodax

Animations و Reanimated — React Native المتقدم

الحركات في React Native

1. Animated API (المدمج)

import { Animated } from 'react-native';

function FadeInView() {
  const fadeAnim = useRef(new Animated.Value(0)).current;

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

  return (
    <Animated.View style={{ opacity: fadeAnim }}>
      <Text>Fade In!</Text>
    </Animated.View>
  );
}

2. React Native Reanimated (الأفضل)

npm install react-native-reanimated
import Animated, {
  useSharedValue,
  useAnimatedStyle,
  withSpring,
  withTiming,
  withRepeat,
  withSequence,
  Easing,
} from 'react-native-reanimated';

function AnimatedBox() {
  const offset = useSharedValue(0);
  const scale = useSharedValue(1);

  const animatedStyle = useAnimatedStyle(() => ({
    transform: [
      { translateX: offset.value },
      { scale: scale.value },
    ],
  }));

  const moveRight = () => {
    offset.value = withSpring(200);
  };

  const pulse = () => {
    scale.value = withRepeat(
      withSequence(
        withTiming(1.2, { duration: 150 }),
        withTiming(1, { duration: 150 })
      ),
      3 // تكرار 3 مرات
    );
  };

  return (
    <View>
      <Animated.View style={[styles.box, animatedStyle]} />
      <TouchableOpacity onPress={moveRight}>
        <Text>تحريك</Text>
      </TouchableOpacity>
      <TouchableOpacity onPress={pulse}>
        <Text>نبض</Text>
      </TouchableOpacity>
    </View>
  );
}

3. Entering & Exiting Animations

import Animated, {
  FadeIn,
  FadeOut,
  SlideInLeft,
  SlideOutRight,
  BounceIn,
  ZoomIn,
} from 'react-native-reanimated';

function AnimatedList() {
  const [items, setItems] = useState([1, 2, 3]);

  const addItem = () => setItems([...items, items.length + 1]);
  const removeItem = (id) => setItems(items.filter(i => i !== id));

  return (
    <View>
      {items.map((item, index) => (
        <Animated.View
          key={item}
          entering={FadeIn.delay(index * 100).springify()}
          exiting={SlideOutRight}
          style={styles.listItem}
        >
          <Text>Item {item}</Text>
          <TouchableOpacity onPress={() => removeItem(item)}>
            <Text>حذف</Text>
          </TouchableOpacity>
        </Animated.View>
      ))}
      <TouchableOpacity onPress={addItem}>
        <Text>إضافة عنصر</Text>
      </TouchableOpacity>
    </View>
  );
}

4. Gesture Handler مع Reanimated

npm install react-native-gesture-handler
import { Gesture, GestureDetector } from 'react-native-gesture-handler';
import Animated, {
  useSharedValue,
  useAnimatedStyle,
  withSpring,
} from 'react-native-reanimated';

function DraggableBox() {
  const translateX = useSharedValue(0);
  const translateY = useSharedValue(0);

  const gesture = Gesture.Pan()
    .onUpdate((event) => {
      translateX.value = event.translationX;
      translateY.value = event.translationY;
    })
    .onEnd(() => {
      translateX.value = withSpring(0);
      translateY.value = withSpring(0);
    });

  const animatedStyle = useAnimatedStyle(() => ({
    transform: [
      { translateX: translateX.value },
      { translateY: translateY.value },
    ],
  }));

  return (
    <GestureDetector gesture={gesture}>
      <Animated.View style={[styles.box, animatedStyle]} />
    </GestureDetector>
  );
}

5. مثال: زر Like مع حركة

function LikeButton() {
  const [liked, setLiked] = useState(false);
  const scale = useSharedValue(1);

  const animatedStyle = useAnimatedStyle(() => ({
    transform: [{ scale: scale.value }],
  }));

  const handlePress = () => {
    scale.value = withSequence(
      withSpring(0.8),
      withSpring(1.3),
      withSpring(1)
    );
    setLiked(!liked);
  };

  return (
    <TouchableOpacity onPress={handlePress}>
      <Animated.View style={animatedStyle}>
        <Ionicons
          name={liked ? 'heart' : 'heart-outline'}
          size={32}
          color={liked ? '#ef4444' : '#888'}
        />
      </Animated.View>
    </TouchableOpacity>
  );
}
اختبر فهمك