This commit is contained in:
albivkt
2025-08-06 06:04:23 +03:00
parent 4a11a6952a
commit 020682854d
8 changed files with 1460 additions and 642 deletions

View File

@ -0,0 +1,252 @@
import React from 'react';
import { View, StyleSheet, Dimensions } from 'react-native';
import { LinearGradient } from 'expo-linear-gradient';
import Animated, {
useSharedValue,
useAnimatedStyle,
withRepeat,
withTiming,
withSequence,
interpolate,
Easing,
} from 'react-native-reanimated';
const { width, height } = Dimensions.get('window');
interface BackgroundDesignProps {
variant?: 'default' | 'login' | 'chat';
children?: React.ReactNode;
}
export const BackgroundDesign: React.FC<BackgroundDesignProps> = ({
variant = 'default',
children
}) => {
const floatAnimation = useSharedValue(0);
const rotateAnimation = useSharedValue(0);
const pulseAnimation = useSharedValue(0);
React.useEffect(() => {
// Плавное движение вверх-вниз
floatAnimation.value = withRepeat(
withSequence(
withTiming(1, { duration: 4000, easing: Easing.inOut(Easing.ease) }),
withTiming(0, { duration: 4000, easing: Easing.inOut(Easing.ease) })
),
-1,
false
);
// Вращение элементов
rotateAnimation.value = withRepeat(
withTiming(360, { duration: 30000, easing: Easing.linear }),
-1,
false
);
// Пульсация
pulseAnimation.value = withRepeat(
withSequence(
withTiming(1, { duration: 2000, easing: Easing.inOut(Easing.ease) }),
withTiming(0, { duration: 2000, easing: Easing.inOut(Easing.ease) })
),
-1,
false
);
}, []);
const floatingStyle = useAnimatedStyle(() => {
const translateY = interpolate(floatAnimation.value, [0, 1], [0, -30]);
return {
transform: [{ translateY }],
};
});
const rotatingStyle = useAnimatedStyle(() => {
return {
transform: [{ rotate: `${rotateAnimation.value}deg` }],
};
});
const pulsingStyle = useAnimatedStyle(() => {
const scale = interpolate(pulseAnimation.value, [0, 1], [1, 1.1]);
const opacity = interpolate(pulseAnimation.value, [0, 1], [0.3, 0.6]);
return {
transform: [{ scale }],
opacity,
};
});
return (
<View style={styles.container}>
{/* Основной градиентный фон */}
<LinearGradient
colors={['#0a0a0a', '#1a1a1a', '#0f0f0f']}
style={StyleSheet.absoluteFillObject}
start={{ x: 0, y: 0 }}
end={{ x: 1, y: 1 }}
/>
{/* Декоративные элементы */}
<View style={styles.decorativeElements}>
{/* Большой круг с градиентом слева вверху */}
<Animated.View style={[styles.circle1, pulsingStyle]}>
<LinearGradient
colors={['rgba(255,255,255,0.03)', 'rgba(255,255,255,0.01)']}
style={styles.circleGradient}
start={{ x: 0, y: 0 }}
end={{ x: 1, y: 1 }}
/>
</Animated.View>
{/* Плавающий элемент справа */}
<Animated.View style={[styles.floatingElement1, floatingStyle]}>
<LinearGradient
colors={['rgba(255,255,255,0.05)', 'rgba(255,255,255,0.02)']}
style={styles.elementGradient}
/>
</Animated.View>
{/* Вращающийся квадрат */}
<Animated.View style={[styles.rotatingSquare, rotatingStyle]}>
<View style={styles.squareInner} />
</Animated.View>
{/* Сетка точек для login варианта */}
{variant === 'login' && (
<View style={styles.dotsGrid}>
{Array.from({ length: 10 }).map((_, i) =>
Array.from({ length: 15 }).map((_, j) => (
<View
key={`${i}-${j}`}
style={[
styles.dot,
{
left: i * (width / 9),
top: j * (height / 14),
opacity: 0.05 + Math.random() * 0.05,
}
]}
/>
))
)}
</View>
)}
{/* Градиентные блики */}
<View style={styles.glowContainer}>
<LinearGradient
colors={['rgba(255,255,255,0.1)', 'transparent']}
style={[styles.glow1]}
start={{ x: 0.5, y: 0 }}
end={{ x: 0.5, y: 1 }}
/>
<LinearGradient
colors={['rgba(255,255,255,0.08)', 'transparent']}
style={[styles.glow2]}
start={{ x: 0, y: 0.5 }}
end={{ x: 1, y: 0.5 }}
/>
</View>
</View>
{/* Контент поверх фона */}
<View style={styles.contentContainer}>
{children}
</View>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#0a0a0a',
},
decorativeElements: {
...StyleSheet.absoluteFillObject,
overflow: 'hidden',
},
contentContainer: {
flex: 1,
zIndex: 1,
},
circle1: {
position: 'absolute',
top: -width * 0.2,
left: -width * 0.2,
width: width * 0.6,
height: width * 0.6,
borderRadius: width * 0.3,
overflow: 'hidden',
},
circleGradient: {
flex: 1,
},
floatingElement1: {
position: 'absolute',
top: height * 0.2,
right: width * 0.1,
width: 80,
height: 80,
borderRadius: 40,
backgroundColor: 'rgba(255,255,255,0.02)',
borderWidth: 1,
borderColor: 'rgba(255,255,255,0.05)',
overflow: 'hidden',
},
elementGradient: {
flex: 1,
},
rotatingSquare: {
position: 'absolute',
bottom: height * 0.15,
left: width * 0.15,
width: 60,
height: 60,
backgroundColor: 'transparent',
borderWidth: 2,
borderColor: 'rgba(255,255,255,0.1)',
transform: [{ rotate: '45deg' }],
},
squareInner: {
flex: 1,
margin: 10,
backgroundColor: 'transparent',
borderWidth: 1,
borderColor: 'rgba(255,255,255,0.05)',
},
dotsGrid: {
position: 'absolute',
top: 0,
left: 0,
width: width,
height: height,
},
dot: {
position: 'absolute',
width: 2,
height: 2,
borderRadius: 1,
backgroundColor: '#666666',
},
glowContainer: {
...StyleSheet.absoluteFillObject,
},
glow1: {
position: 'absolute',
top: height * 0.1,
right: -width * 0.2,
width: width * 0.8,
height: width * 0.8,
borderRadius: width * 0.4,
},
glow2: {
position: 'absolute',
bottom: -height * 0.1,
left: -width * 0.1,
width: width * 0.7,
height: width * 0.7,
borderRadius: width * 0.35,
},
});