You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 12:52:38