feat: 首页支持风景图与纯色背景随滑动自动切换,优化点赞图标样式与交互
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { useEffect, useLayoutEffect, useMemo, useState, useCallback, useRef } from 'react';
|
||||
import { StyleSheet, View, Dimensions, Text, Pressable, PanResponder, Animated as RNAnimated } from 'react-native';
|
||||
import { StyleSheet, View, Dimensions, Text, Pressable, PanResponder, Animated as RNAnimated, ImageBackground } from 'react-native';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useNavigation, useFocusEffect } from 'expo-router';
|
||||
import Animated, {
|
||||
@@ -31,6 +31,40 @@ import LikeIcon from '@/assets/images/icon/like_icon.svg';
|
||||
|
||||
const { height: SCREEN_HEIGHT } = Dimensions.get('window');
|
||||
|
||||
// 预定义风景图列表
|
||||
const NATURE_IMAGES = [
|
||||
require('@/assets/theme/nature/1.png'),
|
||||
require('@/assets/theme/nature/2.png'),
|
||||
require('@/assets/theme/nature/3.png'),
|
||||
require('@/assets/theme/nature/4.png'),
|
||||
require('@/assets/theme/nature/5.png'),
|
||||
require('@/assets/theme/nature/6.png'),
|
||||
require('@/assets/theme/nature/7.png'),
|
||||
require('@/assets/theme/nature/8.png'),
|
||||
require('@/assets/theme/nature/9.png'),
|
||||
require('@/assets/theme/nature/10.png'),
|
||||
require('@/assets/theme/nature/11.png'),
|
||||
require('@/assets/theme/nature/12.png'),
|
||||
require('@/assets/theme/nature/13.png'),
|
||||
require('@/assets/theme/nature/14.png'),
|
||||
require('@/assets/theme/nature/15.png'),
|
||||
require('@/assets/theme/nature/17.png'),
|
||||
require('@/assets/theme/nature/18.png'),
|
||||
require('@/assets/theme/nature/19.png'),
|
||||
require('@/assets/theme/nature/20.png'),
|
||||
require('@/assets/theme/nature/22.png'),
|
||||
];
|
||||
|
||||
// 预定义颜色列表
|
||||
const THEME_COLORS = [
|
||||
'#F7D9BF',
|
||||
'#CBF2D8',
|
||||
'#F5CDDE',
|
||||
'#F2ECCB',
|
||||
'#E2CBF2',
|
||||
'#CBD9F2',
|
||||
];
|
||||
|
||||
export default function HomeScreen() {
|
||||
const { t } = useTranslation();
|
||||
const navigation = useNavigation();
|
||||
@@ -66,12 +100,26 @@ export default function HomeScreen() {
|
||||
}, [])
|
||||
);
|
||||
|
||||
const backgroundColor = themeMode === 'color' ? '#F3D0E1' : '#F4D6C2';
|
||||
const backgroundColor = useMemo(() => {
|
||||
if (themeMode === 'color') {
|
||||
const colorIndex = Math.floor(index / 10) % THEME_COLORS.length;
|
||||
return THEME_COLORS[colorIndex];
|
||||
}
|
||||
return '#F4D6C2'; // 风景模式下的默认底色(图片加载前显示)
|
||||
}, [themeMode, index]);
|
||||
|
||||
// 计算当前应该显示的风景图索引(滑动 10 次切换一张)
|
||||
const natureImageIndex = useMemo(() => {
|
||||
return Math.floor(index / 10) % NATURE_IMAGES.length;
|
||||
}, [index]);
|
||||
|
||||
const currentNatureImage = NATURE_IMAGES[natureImageIndex];
|
||||
|
||||
useLayoutEffect(() => {
|
||||
navigation.setOptions({
|
||||
headerShadowVisible: false,
|
||||
headerStyle: { backgroundColor },
|
||||
headerStyle: { backgroundColor: themeMode === 'scenery' ? 'transparent' : backgroundColor },
|
||||
headerTransparent: themeMode === 'scenery',
|
||||
headerRight: () => (
|
||||
<View style={styles.headerRight}>
|
||||
<CircleIconButton
|
||||
@@ -89,7 +137,7 @@ export default function HomeScreen() {
|
||||
</View>
|
||||
),
|
||||
});
|
||||
}, [backgroundColor, navigation, t]);
|
||||
}, [backgroundColor, themeMode, navigation, t]);
|
||||
|
||||
const textAnimatedStyle = useAnimatedStyle(() => ({
|
||||
transform: [{ translateY: translateY.value }],
|
||||
@@ -176,10 +224,11 @@ export default function HomeScreen() {
|
||||
|
||||
// 2. 保存到收藏夹,包含当前背景信息
|
||||
await addFavorite({
|
||||
favId: String(Date.now()), // 生成唯一 ID
|
||||
id: item.id,
|
||||
date: dateStr,
|
||||
themeMode: themeMode,
|
||||
background: backgroundColor, // 目前存储的是颜色值
|
||||
background: themeMode === 'scenery' ? String(natureImageIndex) : backgroundColor,
|
||||
});
|
||||
|
||||
// 3. 爱心缩放动画
|
||||
@@ -202,8 +251,15 @@ export default function HomeScreen() {
|
||||
|
||||
return (
|
||||
<View style={[styles.container, { backgroundColor }]} {...panResponder.panHandlers}>
|
||||
<Animated.View style={[styles.card, textAnimatedStyle]}>
|
||||
<Text style={styles.text}>{item.text}</Text>
|
||||
{themeMode === 'scenery' && (
|
||||
<ImageBackground
|
||||
source={currentNatureImage}
|
||||
style={StyleSheet.absoluteFill}
|
||||
resizeMode="cover"
|
||||
/>
|
||||
)}
|
||||
<Animated.View style={[styles.card, textAnimatedStyle, themeMode === 'scenery' && styles.sceneryCard]}>
|
||||
<Text style={[styles.text, themeMode === 'scenery' && styles.sceneryText]}>{item.text}</Text>
|
||||
</Animated.View>
|
||||
|
||||
<View style={styles.actions}>
|
||||
@@ -216,9 +272,13 @@ export default function HomeScreen() {
|
||||
style={styles.reactionInner}
|
||||
>
|
||||
{likeFilled ? (
|
||||
<LikeFilledIcon width={35} height={36} />
|
||||
<LikeFilledIcon width={35} height={36} style={{ color: '#EA6969' }} />
|
||||
) : (
|
||||
<LikeIcon width={35} height={36} />
|
||||
<LikeIcon
|
||||
width={35}
|
||||
height={36}
|
||||
style={{ color: themeMode === 'scenery' ? '#FFFFFF' : '#5E2A28' }}
|
||||
/>
|
||||
)}
|
||||
</Pressable>
|
||||
</Animated.View>
|
||||
@@ -277,9 +337,15 @@ const styles = StyleSheet.create({
|
||||
justifyContent: 'center',
|
||||
},
|
||||
card: {
|
||||
paddingHorizontal: 30,
|
||||
alignItems: 'center',
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
paddingHorizontal: 30,
|
||||
zIndex: 5, // 降低层级,防止遮挡底部按钮
|
||||
},
|
||||
text: {
|
||||
fontSize: 22,
|
||||
@@ -288,6 +354,16 @@ const styles = StyleSheet.create({
|
||||
fontWeight: '700',
|
||||
textAlign: 'center',
|
||||
},
|
||||
sceneryCard: {
|
||||
// 风景模式下稍微收窄文案宽度,增加呼吸感
|
||||
paddingHorizontal: 50,
|
||||
},
|
||||
sceneryText: {
|
||||
color: '#FFFFFF',
|
||||
textShadowColor: 'rgba(0, 0, 0, 0.5)',
|
||||
textShadowOffset: { width: 0, height: 1 },
|
||||
textShadowRadius: 4,
|
||||
},
|
||||
actions: {
|
||||
position: 'absolute',
|
||||
bottom: SCREEN_HEIGHT * 0.16,
|
||||
@@ -295,6 +371,7 @@ const styles = StyleSheet.create({
|
||||
right: 0,
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'center',
|
||||
zIndex: 20, // 提升层级,确保在最顶层可点击
|
||||
},
|
||||
reactionButton: {
|
||||
alignItems: 'center',
|
||||
|
||||
Reference in New Issue
Block a user