Поставьте зависимости:
npm install react-native-reanimatedpnpm add react-native-reanimatedyarn add react-native-reanimatedbun add react-native-reanimatedСкопируйте эти файлы в src/shared/components/base/marquee/:
Проверьте алиас путей. Импорты в коде выше записаны так, как их пишет astra-rn add: @/shared/components, @/shared/utils и @/shared/hooks. Нужен алиас "@/*": ["./src/*"] в tsconfig.json — или поправьте импорты под свои пути.
import { View, StyleSheet, Text, Dimensions } from "react-native";
import { GestureHandlerRootView } from "react-native-gesture-handler";
import { StatusBar } from "expo-status-bar";
import Marquee from "@/shared/components/base/marquee";
import { useFonts } from "expo-font";
import { Showcase, useCustomize } from "~/showcase";
import { LinearGradient } from "expo-linear-gradient";
const WIDTH = Dimensions.get("window").width;
const CUSTOMIZE = [
{ key: "text", label: "Текст", type: "text", default: "Astra", maxLength: 32 },
{ key: "separator", label: "Разделитель", type: "text", default: "⋆ ✦ ⋆", maxLength: 12 },
{ key: "color", label: "Цвет текста", type: "color", default: "#ffffff" },
{ key: "fontSize", label: "Размер шрифта", type: "slider", min: 14, max: 72, step: 1, unit: "px", default: 35 },
{ key: "speed", label: "Скорость", type: "slider", min: 0, max: 300, step: 5, default: 50 },
{ key: "spacing", label: "Интервал", type: "slider", min: 0, max: 80, step: 1, unit: "px", default: 20 },
{ key: "reverse", label: "Обратно", type: "toggle", default: false },
{ key: "fade", label: "Затухание краёв", type: "toggle", default: true },
{ key: "holdToSpeedUp", label: "Ускорять удержанием", type: "toggle", default: false },
] as const;
export default function App() {
const [fontLoaded] = useFonts({
SfProRounded: require("@/assets/fonts/sf-pro-rounded.ttf"),
HelveticaNowDisplay: require("@/assets/fonts/HelveticaNowDisplayMedium.ttf"),
});
const custom = useCustomize(CUSTOMIZE);
const textStyle = [
styles.text,
{
fontFamily: "SfProRounded",
color: custom.color,
fontSize: custom.fontSize,
},
];
return (
<Showcase>
<GestureHandlerRootView style={styles.container}>
<StatusBar style="light" />
<View style={styles.marqueeContainer}>
{fontLoaded ? (
<Marquee
key={`${custom.text}|${custom.separator}|${custom.fontSize}`}
speed={custom.speed}
spacing={custom.spacing}
reverse={custom.reverse}
holdToSpeedUp={custom.holdToSpeedUp}
>
<Text style={textStyle}>{custom.separator}</Text>
<View style={styles.divider} />
<Text style={textStyle}>{custom.text}</Text>
</Marquee>
) : null}
{custom.fade ? (
<>
<LinearGradient
pointerEvents="none"
colors={["#0a0a0a", "transparent"]}
start={{ x: 0, y: 0 }}
end={{ x: 1, y: 0 }}
style={styles.leftGradient}
/>
<LinearGradient
pointerEvents="none"
colors={["transparent", "#0a0a0a"]}
start={{ x: 0, y: 0 }}
end={{ x: 1, y: 0 }}
style={styles.rightGradient}
/>
</>
) : null}
</View>
</GestureHandlerRootView>
</Showcase>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#0a0a0a",
alignItems: "center",
},
marqueeContainer: {
width: WIDTH,
alignItems: "center",
flex: 1,
justifyContent: "center",
overflow: "hidden",
},
leftGradient: {
position: "absolute",
left: 0,
top: 0,
bottom: 0,
width: 100,
zIndex: 2,
},
rightGradient: {
position: "absolute",
right: 0,
top: 0,
bottom: 0,
width: 100,
zIndex: 2,
},
divider: {
width: 20,
},
text: {
fontSize: 35,
color: "#fff",
},
});childrenТип React.ReactNode
speed?Тип number
spacing?Тип number
reverse?Тип boolean
pauseOnPress?Тип boolean
holdToSpeedUp?Тип boolean
speedUpMultiplier?Тип number