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

React Native中实现带衰减效果的循环弹跳球动画问题

React Native弹跳球衰减动画实现方案

你当前用Animated.loop固定高度往返的方式,自然没法实现高度衰减。Animated.decay是基于速度的衰减动画,不适合这种需要每次弹跳高度按指数降低的场景,正确的做法是手动递归控制动画循环,每次更新弹跳目标高度并乘以衰减系数。

以下是修改后的代码:

import { useRef, useEffect } from 'react';
import { Animated } from 'react-native';

const FALL_HEIGHT = 200;
// 衰减系数,值越小衰减越快,建议0.7-0.9之间
const DECAY_RATE = 0.8;
// 最小停止高度,低于这个值就停止动画
const MIN_HEIGHT = 10;

export default function BouncingBall() {
  const translateY = useRef(new Animated.Value(-FALL_HEIGHT)).current;
  // 保存当前弹跳的目标高度
  const currentHeight = useRef(FALL_HEIGHT).current;

  const bounce = () => {
    // 下落到底部
    Animated.spring(translateY, {
      toValue: 0,
      useNativeDriver: true,
      overshootClamping: true,
      bounciness: 20,
    }).start(() => {
      // 更新下一次弹跳的高度
      currentHeight *= DECAY_RATE;
      if (currentHeight < MIN_HEIGHT) {
        // 高度太小,停止动画
        return;
      }
      // 弹起至新高度
      Animated.spring(translateY, {
        toValue: -currentHeight,
        useNativeDriver: true,
        overshootClamping: true,
        bounciness: 20, // 保持弹起的弹性一致,不用改1
      }).start(bounce); // 递归调用,实现循环衰减
    });
  };

  useEffect(() => {
    bounce();
  }, []);

  // 这里返回你的球组件,示例如下:
  return (
    <Animated.View
      style={{
        transform: [{ translateY }],
        width: 50,
        height: 50,
        borderRadius: 25,
        backgroundColor: 'red',
        position: 'absolute',
        bottom: 100,
        left: 100,
      }}
    />
  );
}

关键修改说明:

  • 去掉Animated.loop,改用递归函数bounce()控制动画流程,灵活调整每次弹跳的高度
  • 用currentHeight保存实时目标高度,每次弹起后乘以DECAY_RATE实现指数衰减效果
  • 添加MIN_HEIGHT阈值,避免动画无限循环到极小高度
  • 弹起阶段的bounciness保持和下落一致,让弹跳的弹性反馈更自然

内容的提问来源于stack exchange,提问作者Naveen Kumar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 12:39:59