美化login和home页面

This commit is contained in:
李宇奇 2025-07-05 20:04:41 +08:00
parent c0a0eed3c0
commit 8741ce913e
2 changed files with 88 additions and 166 deletions

View File

@ -5,7 +5,6 @@ import {
StyleSheet, StyleSheet,
TouchableOpacity, TouchableOpacity,
InteractionManager, InteractionManager,
Image,
Dimensions, Dimensions,
} from 'react-native'; } from 'react-native';
import {useNavigation, useIsFocused} from '@react-navigation/native'; import {useNavigation, useIsFocused} from '@react-navigation/native';
@ -14,10 +13,9 @@ import {RootStackParamList} from '../../navigation/types';
import {Screen} from '../../components/common/Screen'; import {Screen} from '../../components/common/Screen';
import {WaveBackground} from '../../components/common/WaveBackground'; import {WaveBackground} from '../../components/common/WaveBackground';
import LinearGradient from 'react-native-linear-gradient'; import LinearGradient from 'react-native-linear-gradient';
import Svg, {Path, Defs, LinearGradient as SvgLinearGradient, Stop} from 'react-native-svg';
import {useTheme} from '../../contexts/ThemeContext'; import {useTheme} from '../../contexts/ThemeContext';
const {width} = Dimensions.get('window'); const {width, height} = Dimensions.get('window');
type LoginScreenNavigationProp = NativeStackNavigationProp< type LoginScreenNavigationProp = NativeStackNavigationProp<
RootStackParamList, RootStackParamList,
@ -32,7 +30,6 @@ export const LoginScreen: React.FC = () => {
const handleLogin = useCallback(() => { const handleLogin = useCallback(() => {
if (!isFocused) return; if (!isFocused) return;
// 使用 InteractionManager 确保所有交互和动画完成
InteractionManager.runAfterInteractions(() => { InteractionManager.runAfterInteractions(() => {
if (isFocused) { if (isFocused) {
navigation.replace('Home'); navigation.replace('Home');
@ -41,107 +38,44 @@ export const LoginScreen: React.FC = () => {
}, [navigation, isFocused]); }, [navigation, isFocused]);
return ( return (
<Screen style={[styles.screen, {backgroundColor: theme.colors.background}]}> <Screen style={styles.screen}>
{/* 头部背景 */} {/* 背景区域 */}
<View style={styles.headerContainer}> <View style={styles.backgroundContainer}>
<LinearGradient <WaveBackground
colors={theme.colors.gradients.primary} height={height * 0.6}
style={[StyleSheet.absoluteFill, styles.gradientBackground]} gradientColors={theme.colors.gradients.primary}
start={{ x: 0, y: 0 }}
end={{ x: 1, y: 1 }}
>
{/* 半透明波浪效果 */}
<View style={styles.waveOverlay}>
<Svg height="100%" width={width} style={styles.waveSvg}>
<Path
d={`M0,50
C${width * 0.2},30
${width * 0.4},70
${width * 0.6},50
C${width * 0.8},30
${width},60
${width},50`}
fill="none"
stroke="rgba(255, 255, 255, 0.2)"
strokeWidth="2"
/>
<Path
d={`M0,70
C${width * 0.2},50
${width * 0.4},90
${width * 0.6},70
C${width * 0.8},50
${width},80
${width},70`}
fill="none"
stroke="rgba(255, 255, 255, 0.15)"
strokeWidth="2"
/>
</Svg>
</View>
</LinearGradient>
<View style={styles.headerContent}>
<Text style={[styles.headerTitle, { color: theme.colors.background }]}>
</Text>
<Text style={[styles.headerSubtitle, { color: theme.colors.background }]}>
</Text>
</View>
</View>
{/* 不规则曲线背景 */}
<View style={styles.curveContainer}>
<Svg height="120" width={width} style={styles.curve}>
<Defs>
<SvgLinearGradient id="contrastGradient" x1="0" y1="0" x2="1" y2="0">
<Stop offset="0" stopColor={theme.colors.gradients.contrast[0]} />
<Stop offset="1" stopColor={theme.colors.gradients.contrast[1]} />
</SvgLinearGradient>
</Defs>
<Path
d={`M0,120
L0,50
C${width * 0.3},20 ${width * 0.7},80 ${width},30
L${width},120
Z`}
fill="url(#contrastGradient)"
/>
</Svg>
</View>
{/* 主体内容 */}
<View style={[styles.contentWrapper]}>
<LinearGradient
colors={theme.colors.gradients.contrast}
style={StyleSheet.absoluteFill}
start={{x: 0, y: 0}}
end={{x: 1, y: 0}}
/> />
<View style={styles.content}> </View>
{/* Logo占位 */}
<View style={styles.logoContainer}> {/* 主内容区 */}
<LinearGradient <View style={styles.contentContainer}>
colors={theme.colors.gradients.contrast} {/* 标题区域 */}
style={[styles.logoCircle, theme.shadow.medium]}> <View style={styles.titleContainer}>
<Text style={styles.title}></Text>
<Text style={styles.subtitle}></Text>
</View>
{/* Logo和按钮区域 */}
<View style={styles.centerContent}>
{/* Logo */}
<View style={styles.logoWrapper}>
<View style={[styles.logoCircle, theme.shadow.medium]}>
<Text style={[styles.logoText, {color: theme.colors.primary}]}> <Text style={[styles.logoText, {color: theme.colors.primary}]}>
JW JW
</Text> </Text>
</LinearGradient> </View>
</View> </View>
{/* 登录按钮 */} {/* 登录按钮 */}
<TouchableOpacity <TouchableOpacity
style={[styles.loginButtonContainer, theme.shadow.medium]} style={[styles.loginButtonContainer, theme.shadow.small]}
onPress={handleLogin}> onPress={handleLogin}>
<LinearGradient <LinearGradient
colors={theme.colors.gradients.primary} colors={theme.colors.gradients.button}
start={{x: 0, y: 0}} start={{x: 0, y: 0}}
end={{x: 1, y: 0}} end={{x: 1, y: 0}}
style={styles.loginButton}> style={styles.loginButton}>
<Text style={[styles.loginButtonText, {color: theme.colors.background}]}> <Text style={styles.loginButtonText}></Text>
</Text>
</LinearGradient> </LinearGradient>
</TouchableOpacity> </TouchableOpacity>
</View> </View>
@ -160,63 +94,65 @@ export const LoginScreen: React.FC = () => {
const styles = StyleSheet.create({ const styles = StyleSheet.create({
screen: { screen: {
flex: 1, flex: 1,
backgroundColor: '#FFFFFF',
}, },
headerContainer: { backgroundContainer: {
height: 280,
position: 'relative',
overflow: 'hidden',
},
headerContent: {
position: 'absolute',
top: 60,
left: 0,
right: 0,
alignItems: 'center',
},
headerTitle: {
fontSize: 32,
fontWeight: 'bold',
textShadowColor: 'rgba(0, 0, 0, 0.2)',
textShadowOffset: {width: 1, height: 1},
textShadowRadius: 3,
},
headerSubtitle: {
fontSize: 18,
marginTop: 8,
opacity: 0.9,
},
curveContainer: {
position: 'absolute',
top: 200,
left: 0,
right: 0,
zIndex: 1,
},
curve: {
position: 'absolute', position: 'absolute',
top: 0, top: 0,
left: 0,
right: 0,
}, },
contentWrapper: { contentContainer: {
flex: 1, flex: 1,
marginTop: 160,
}, },
content: { titleContainer: {
flex: 1,
alignItems: 'center', alignItems: 'center',
paddingTop: 40, marginTop: height * 0.12,
}, },
logoContainer: { title: {
fontSize: 32,
fontWeight: 'bold',
color: '#FFFFFF',
marginBottom: 8,
},
subtitle: {
fontSize: 18,
color: '#FFFFFF',
opacity: 0.9,
},
centerContent: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
paddingBottom: height * 0.1,
},
logoWrapper: {
width: 90,
height: 90,
backgroundColor: '#F5F5F5',
borderRadius: 45,
justifyContent: 'center',
alignItems: 'center',
marginBottom: 40, marginBottom: 40,
}, },
logoCircle: { logoCircle: {
width: 120, width: 80,
height: 120, height: 80,
borderRadius: 60, borderRadius: 40,
backgroundColor: '#FFFFFF',
justifyContent: 'center', justifyContent: 'center',
alignItems: 'center', alignItems: 'center',
elevation: 2,
shadowColor: '#000',
shadowOffset: {
width: 0,
height: 1,
},
shadowOpacity: 0.2,
shadowRadius: 1.41,
}, },
logoText: { logoText: {
fontSize: 40, fontSize: 32,
fontWeight: 'bold', fontWeight: 'bold',
}, },
loginButtonContainer: { loginButtonContainer: {
@ -235,25 +171,16 @@ const styles = StyleSheet.create({
loginButtonText: { loginButtonText: {
fontSize: 18, fontSize: 18,
fontWeight: '600', fontWeight: '600',
color: '#FFFFFF',
}, },
footer: { footer: {
padding: 20, position: 'absolute',
bottom: 20,
left: 0,
right: 0,
alignItems: 'center', alignItems: 'center',
}, },
footerText: { footerText: {
fontSize: 12, fontSize: 12,
}, },
gradientBackground: {
opacity: 0.95,
},
waveOverlay: {
position: 'absolute',
width: '100%',
height: '100%',
opacity: 0.6,
},
waveSvg: {
position: 'absolute',
top: 0,
},
}); });

View File

@ -141,13 +141,7 @@ export const HomeScreen: React.FC = () => {
</View> </View>
{/* 主体内容 */} {/* 主体内容 */}
<View style={styles.mainContent}> <View style={[styles.mainContent, { backgroundColor: '#FFFFFF' }]}>
<LinearGradient
colors={theme.colors.gradients.contrast}
style={StyleSheet.absoluteFill}
start={{x: 0, y: 0}}
end={{x: 1, y: 0}}
/>
<ScrollView contentContainerStyle={styles.scrollContent}> <ScrollView contentContainerStyle={styles.scrollContent}>
{/* 快捷操作区 */} {/* 快捷操作区 */}
<View style={styles.quickActions}> <View style={styles.quickActions}>
@ -157,16 +151,14 @@ export const HomeScreen: React.FC = () => {
style={[styles.actionCard]} style={[styles.actionCard]}
onPress={() => navigation.navigate(item.route)}> onPress={() => navigation.navigate(item.route)}>
<LinearGradient <LinearGradient
colors={theme.colors.gradients.card} colors={theme.colors.gradients.contrast}
style={[StyleSheet.absoluteFill, {borderRadius: 12}]} style={[StyleSheet.absoluteFill, {borderRadius: 12}]}
start={{x: 0, y: 0}} start={{x: 0, y: 0}}
end={{x: 1, y: 1}} end={{x: 1, y: 0}}
/> />
<LinearGradient <View style={styles.iconContainer}>
colors={theme.colors.gradients.primary}
style={styles.iconGradient}>
<Icon name={item.icon} size={32} color={theme.colors.background} /> <Icon name={item.icon} size={32} color={theme.colors.background} />
</LinearGradient> </View>
<Text style={[styles.actionTitle, {color: theme.colors.background}]}> <Text style={[styles.actionTitle, {color: theme.colors.background}]}>
{item.title} {item.title}
</Text> </Text>
@ -176,7 +168,7 @@ export const HomeScreen: React.FC = () => {
{/* 图表区域 */} {/* 图表区域 */}
<View style={styles.chartSection}> <View style={styles.chartSection}>
<Text style={[styles.chartTitle, {color: theme.colors.background}]}> <Text style={[styles.chartTitle, {color: theme.colors.text}]}>
</Text> </Text>
<View style={styles.chartContainer}> <View style={styles.chartContainer}>
@ -300,18 +292,21 @@ const styles = StyleSheet.create({
}, },
actionCard: { actionCard: {
width: width / 2 - 24, width: width / 2 - 24,
height: 120,
borderRadius: 12, borderRadius: 12,
padding: 20, padding: 20,
alignItems: 'center', alignItems: 'center',
justifyContent: 'center',
overflow: 'hidden', overflow: 'hidden',
}, },
iconGradient: { iconContainer: {
width: 64, width: 48,
height: 64, height: 48,
borderRadius: 32, borderRadius: 24,
justifyContent: 'center', justifyContent: 'center',
alignItems: 'center', alignItems: 'center',
marginBottom: 12, marginBottom: 12,
backgroundColor: 'rgba(255, 255, 255, 0.2)',
}, },
actionTitle: { actionTitle: {
fontSize: 16, fontSize: 16,