aboutsummaryrefslogtreecommitdiffstats
path: root/apps/mobile/components/sharing/ErrorAnimation.tsx
blob: c5cc743a068eaff1e635cd4fe65b7d84d83d0677 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import { useEffect } from "react";
import { View } from "react-native";
import Animated, {
  useAnimatedStyle,
  useSharedValue,
  withSequence,
  withSpring,
  withTiming,
} from "react-native-reanimated";
import * as Haptics from "expo-haptics";
import { AlertCircle } from "lucide-react-native";

export default function ErrorAnimation() {
  const scale = useSharedValue(0);
  const shake = useSharedValue(0);

  useEffect(() => {
    Haptics.notificationAsync(Haptics.NotificationFeedbackType.Error);

    scale.value = withSpring(1, { damping: 12, stiffness: 200 });
    shake.value = withSequence(
      withTiming(-10, { duration: 50 }),
      withTiming(10, { duration: 100 }),
      withTiming(-10, { duration: 100 }),
      withTiming(10, { duration: 100 }),
      withTiming(0, { duration: 50 }),
    );
  }, []);

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

  return (
    <Animated.View style={style} className="items-center gap-4">
      <View className="h-24 w-24 items-center justify-center rounded-full bg-destructive">
        <AlertCircle size={48} color="white" strokeWidth={2} />
      </View>
    </Animated.View>
  );
}