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
相关产品推荐
相关产品推荐

