Поставьте зависимости:
npm install react-native-reanimated react-native-svgpnpm add react-native-reanimated react-native-svgyarn add react-native-reanimated react-native-svgbun add react-native-reanimated react-native-svgСкопируйте эти файлы в src/shared/components/molecules/pulsing-dots/:
Проверьте алиас путей. Импорты в коде выше записаны так, как их пишет astra-rn add: @/shared/components, @/shared/utils и @/shared/hooks. Нужен алиас "@/*": ["./src/*"] в tsconfig.json — или поправьте импорты под свои пути.
import { View, StyleSheet, useWindowDimensions } from "react-native";
import { GestureHandlerRootView } from "react-native-gesture-handler";
import { StatusBar } from "expo-status-bar";
import { useFonts } from "expo-font";
import { PulsingDots } from "@/shared/components/molecules/pulsing-dots";
import { Showcase, useCustomize } from "~/showcase";
const CUSTOMIZE = [
{ key: "color", label: "Цвет", type: "color", default: "#ffffff" },
{ key: "dotCount", label: "Количество", type: "slider", min: 1, max: 8, step: 1, default: 3 },
{ key: "radius", label: "Радиус", type: "slider", min: 2, max: 20, step: 1, unit: "px", default: 10 },
{ key: "spacing", label: "Интервал", type: "slider", min: 8, max: 60, step: 1, unit: "px", default: 36 },
{ key: "duration", label: "Длительность", type: "slider", min: 200, max: 3000, step: 50, unit: "ms", default: 800 },
{ key: "background", label: "Фон", type: "color", default: "#0a0a0a" },
] as const;
export default function App() {
const custom = useCustomize(CUSTOMIZE);
const { width: screenWidth } = useWindowDimensions();
const spacing =
custom.dotCount > 1
? Math.min(custom.spacing, Math.floor((screenWidth - 24 - custom.radius * 2) / (custom.dotCount - 1)))
: custom.spacing;
return (
<Showcase>
<GestureHandlerRootView style={[styles.container, { backgroundColor: custom.background }]}>
<StatusBar style="light" />
<View style={styles.content}>
<PulsingDots
key={`${custom.dotCount}-${custom.duration}`}
color={custom.color}
dotCount={custom.dotCount}
radius={custom.radius}
spacing={spacing}
duration={custom.duration}
/>
</View>
</GestureHandlerRootView>
</Showcase>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#0a0a0a",
justifyContent: "center",
alignItems: "center",
},
content: {},
title: {
fontSize: 28,
fontWeight: "700",
color: "#fff",
},
subtitle: {
fontSize: 15,
color: "#555",
},
card: {
backgroundColor: "#141414",
borderRadius: 16,
overflow: "hidden",
marginTop: 20,
},
triggerContent: {
padding: 16,
},
triggerLeft: {
flexDirection: "row",
alignItems: "center",
gap: 12,
},
triggerText: {
fontSize: 16,
fontWeight: "500",
color: "#fff",
},
item: {
flexDirection: "row",
alignItems: "center",
gap: 12,
padding: 14,
backgroundColor: "#1a1a1a",
borderRadius: 12,
marginBottom: 6,
},
itemText: {
fontSize: 15,
color: "#fff",
},
destructiveText: {
color: "#ff453a",
},
});dotCount?Тип number
radius?Тип number
spacing?Тип number
duration?Тип number
color?Тип string
gradient?Тип Gradient[]