Поставьте зависимости:
npm install expo-blur react-native-reanimatedpnpm add expo-blur react-native-reanimatedyarn add expo-blur react-native-reanimatedbun add expo-blur react-native-reanimatedСкопируйте эти файлы в src/shared/components/organisms/animated-text/:
Проверьте алиас путей. Импорты в коде выше записаны так, как их пишет astra-rn add: @/shared/components, @/shared/utils и @/shared/hooks. Нужен алиас "@/*": ["./src/*"] в tsconfig.json — или поправьте импорты под свои пути.
import { View, StyleSheet } from "react-native";
import { GestureHandlerRootView } from "react-native-gesture-handler";
import { StatusBar } from "expo-status-bar";
import { useFonts } from "expo-font";
import AnimatedText from "@/shared/components/organisms/animated-text";
import { useEffect, useRef, useState } from "react";
import { Showcase, useCustomize } from "~/showcase";
const CUSTOMIZE = [
{ key: "text1", label: "Фраза 1", type: "text", default: "Do you like this?", maxLength: 32 },
{ key: "text2", label: "Фраза 2", type: "text", default: "Isn't it awesome?", maxLength: 32 },
{ key: "text3", label: "Фраза 3", type: "text", default: "Astra makes it easy.", maxLength: 32 },
{ key: "text4", label: "Фраза 4", type: "text", default: "Enjoy using Astra!", maxLength: 32 },
{ key: "interval", label: "Смена фразы", type: "slider", min: 600, max: 5000, step: 100, unit: "ms", default: 1500 },
{ key: "fontSize", label: "Размер", type: "slider", min: 16, max: 56, step: 1, unit: "px", default: 30 },
{ key: "color", label: "Цвет текста", type: "color", default: "#ffffff" },
{ key: "background", label: "Фон", type: "color", default: "#0a0a0a" },
{ key: "charDelay", label: "Задержка букв", type: "slider", min: 0, max: 80, step: 1, unit: "ms", default: 15 },
{ key: "blur", label: "Размытие", type: "slider", min: 0, max: 100, step: 1, default: 50 },
{ key: "rise", label: "Подъём", type: "slider", min: 0, max: 120, step: 1, unit: "px", default: 55 },
{ key: "startScale", label: "Начальный масштаб", type: "slider", min: 0, max: 1, step: 0.05, default: 0.2 },
{ key: "damping", label: "Затухание", type: "slider", min: 5, max: 40, step: 1, default: 15 },
{ key: "stiffness", label: "Жёсткость", type: "slider", min: 50, max: 500, step: 10, default: 210 },
] as const;
export default function App() {
const [fontLoaded] = useFonts({
SfProRounded: require("@/assets/fonts/sf-pro-rounded.ttf"),
HelveticaNowDisplay: require("@/assets/fonts/HelveticaNowDisplayMedium.ttf"),
StretchPro: require("@/assets/fonts/StretchPro.otf"),
});
const custom = useCustomize(CUSTOMIZE);
const TEXTS: string[] = [custom.text1, custom.text2, custom.text3, custom.text4];
const textsRef = useRef<string[]>(TEXTS);
textsRef.current = TEXTS;
const [index, setIndex] = useState<number>(0);
const text = TEXTS[index] ?? TEXTS[0];
useEffect(() => {
const interval = setInterval(() => {
setIndex((current) => (current + 1) % textsRef.current.length);
}, custom.interval);
return () => clearInterval(interval);
}, [custom.interval]);
return (
<Showcase>
<View style={[styles.container, { backgroundColor: custom.background }]}>
<StatusBar style="light" />
<View>
<AnimatedText
text={text}
animationConfig={{
spring: {
damping: custom.damping,
stiffness: custom.stiffness,
mass: 1,
},
characterDelay: custom.charDelay,
maxBlurIntensity: custom.blur,
}}
enterFrom={{
opacity: 0,
translateY: custom.rise,
scale: custom.startScale,
rotate: 0,
}}
exitFrom={{
opacity: 1,
translateY: 0,
scale: 1,
rotate: 0,
}}
style={{
color: custom.color,
fontSize: custom.fontSize,
fontFamily: fontLoaded ? "SfProRounded" : undefined,
}}
/>
</View>
</View>
</Showcase>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#0a0a0a",
justifyContent: "center",
alignItems: "center",
},
info: {
padding: 24,
backgroundColor: "rgba(0,0,0,0.5)",
},
year: {
fontSize: 13,
color: "rgba(255,255,255,0.6)",
marginBottom: 6,
},
name: {
fontSize: 20,
color: "#fff",
marginBottom: 4,
},
artist: {
fontSize: 15,
color: "rgba(255,255,255,0.7)",
},
});textТип string
style?Тип StyleProp<TextStyle>
animationConfig?Тип Partial<AnimationConfig>
enterFrom?Тип Partial<CharacterAnimationParams>
enterTo?Тип Partial<CharacterAnimationParams>
exitFrom?Тип Partial<CharacterAnimationParams>
exitTo?Тип Partial<CharacterAnimationParams>
charТип string
indexТип number
animationConfigТип AnimationConfig
enterFromТип CharacterAnimationParams
enterToТип CharacterAnimationParams
exitFromТип CharacterAnimationParams
exitToТип CharacterAnimationParams
style?Тип StyleProp<TextStyle>
totalChars?Тип number