React Native(Expo Go)初始随机中位向上循环动画实现问题
实现指定的循环动画方案
核心思路是把动画拆成初始单次动画和后续循环动画两部分,用withSequence组合执行:先完成第一次从中间随机位置移出的动作,再无限重复「从屏幕底部外向上移出」的循环。以下是Expo Go可直接运行的完整代码:
import React, { useEffect } from 'react'; import { View, Image, Dimensions } from 'react-native'; import Animated, { useSharedValue, useAnimatedStyle, withTiming, withSequence, withRepeat, Easing, } from 'react-native-reanimated'; const { height: SCREEN_HEIGHT } = Dimensions.get('window'); const IMAGE_HEIGHT = 100; // 替换为你的图片实际高度 export default function App() { // 生成屏幕中部±100范围内的随机初始Y坐标 const initialY = Math.random() * 200 + (SCREEN_HEIGHT / 2 - 100); const translateY = useSharedValue(initialY); useEffect(() => { translateY.value = withSequence( // 第一步:初始位置→向上移出屏幕顶部 withTiming(-IMAGE_HEIGHT, { duration: 1500, easing: Easing.linear, }), // 第二步:无限重复「瞬间回到屏幕底部外→向上移出」的循环 withRepeat( withSequence( // 瞬间把图片移到屏幕底部外(无过渡) withTiming(SCREEN_HEIGHT, { duration: 0 }), // 从底部外向上移动,直到移出屏幕顶部 withTiming(-IMAGE_HEIGHT, { duration: 1500, easing: Easing.linear, }) ), -1 // -1代表无限重复 ) ); }, []); const animatedStyle = useAnimatedStyle(() => { return { transform: [{ translateY: translateY.value }], }; }); return ( <View style={{ flex: 1, backgroundColor: '#f0f0f0' }}> <Animated.Image source={{ uri: 'https://picsum.photos/200/100' }} // 替换为你的图片链接 style={[ animatedStyle, { width: 200, height: IMAGE_HEIGHT, position: 'absolute', left: '50%', marginLeft: -100, // 水平居中 }, ]} /> </View> ); }
关键细节解释
- 初始随机位置:通过
Math.random()生成屏幕垂直中线上下100px范围内的随机Y值,保证每次启动的初始位置都有差异。 - 动画序列控制:
withSequence确保动画按顺序执行——先完成首次的「中间→移出」动画,再进入循环逻辑。 - 循环重置逻辑:在循环内部用
withSequence先通过duration:0的withTiming瞬间把图片移到屏幕底部外,再执行向上移出的动画,解决了循环时起点位置的问题。 - 适配屏幕高度:用
Dimensions.get('window')获取屏幕高度,保证动画在不同设备上的表现一致。
内容的提问来源于stack exchange,提问作者aspect
相关产品推荐
相关产品推荐

