在map函数中实现随机动画 - Expo + Reanimated2
解决React Native随机单个View缩放动画问题
你的核心问题在于用了全局共享值控制所有View的动画,而且ref的存储方式有误,导致无法单独控制单个元素。下面是修复后的完整代码:
import { useRef, useEffect } from 'react' import { View, StyleSheet, TouchableOpacity } from 'react-native' import Animated, { useAnimatedStyle, useSharedValue, withTiming, withSpring, withRepeat } from 'react-native-reanimated' const SIZE = 65.0 const RandomZoomInScreen = ({ navigation }) => { // 页面挂载时的全局缩放动画 const scale = useSharedValue(0) // 给每个方块单独分配共享值,控制各自的弹跳动画 const bounceValues = useRef([ useSharedValue(1), useSharedValue(1), useSharedValue(1), useSharedValue(1), ]).current const itemEls = useRef([]) // 全局初始缩放样式 const reanimatedStyle = useAnimatedStyle(() => { return { transform: [{ scale: scale.value }] } }) // 生成单个方块的弹跳动画样式 const getBounceStyle = (index) => { return useAnimatedStyle(() => { return { transform: [{ scale: bounceValues[index].value }] } }) } // 页面挂载时的全局缩放动画 useEffect(() => { scale.value = withSpring(1, { stiffness: 200 }) return () => { scale.value = 0 } }, []) // 每4秒随机触发一个方块的弹跳动画 useEffect(() => { const intervalId = setInterval(() => { // 随机选一个方块的索引 const randomIndex = Math.floor(Math.random() * 4) // 只更新选中方块的共享值 bounceValues[randomIndex].value = withRepeat(withTiming(1.3), 2, true) }, 4000) return () => clearInterval(intervalId) }, []) return ( <View style={styles.container}> {[1, 2, 3, 4].map((square, index) => { return ( <TouchableOpacity activeOpacity={0.7} key={index}> <Animated.View ref={(el) => (itemEls.current[index] = el)} style={[styles.square, reanimatedStyle, getBounceStyle(index)]} /> </TouchableOpacity> ) })} </View> ) } export default RandomZoomInScreen const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'space-evenly', alignItems: 'center' }, square: { width: SIZE * 2, height: SIZE, backgroundColor: 'green', } })
关键改动说明:
- 单个元素的共享值:把原来的单个
bounce共享值改成数组bounceValues,每个元素对应一个方块的动画状态,这样就能单独控制每个方块的缩放。 - 修正ref存储:原来的
push会导致每次渲染都往数组里加元素,改成直接按索引赋值itemEls.current[index] = el,保证每个位置只存对应方块的引用。 - 独立的动画样式:用
getBounceStyle函数为每个方块生成专属的动画样式,绑定对应的共享值。 - 随机触发逻辑:定时器里生成随机索引,只更新对应索引的共享值,实现单个方块的动画效果。
内容的提问来源于stack exchange,提问作者4aLifeTime
相关产品推荐
相关产品推荐

