React Native Reanimated 弹跳动画:Bounce 类实现弹性效果
【免费下载链接】react-native-reanimated React Native's Animated library reimplemented 项目地址: https://gitcode.***/GitHub_Trending/re/react-native-reanimated
在移动应用开发中,流畅自然的动画是提升用户体验的关键因素。特别是弹跳效果(Bounce Animation),能为界面交互注入生动的物理特性,让按钮点击、元素加载等操作更具反馈感。React Native Reanimated(以下简称 Reanimated)库通过 Bounce 系列动画类,为开发者提供了开箱即用的弹性动画解决方案。本文将深入解析 Reanimated 中弹跳动画的实现原理,并通过实战案例展示如何在项目中快速集成这一效果。
Bounce 动画类的核心实现
Reanimated 的弹跳动画系统封装在 Bounce.ts 文件中,通过多个类实现不同方向和场景的弹性效果。这些类均继承自 ***plexAnimationBuilder,核心逻辑集中在 build 方法中,通过组合时间序列动画(withSequence)和时序动画(withTiming)模拟物理弹跳过程。
BounceIn 类解析
以 BounceIn 类为例,其实现了元素从无到有、带有弹性缩放的入场动画。关键代码如下:
// packages/react-native-reanimated/src/layoutReanimation/defaultAnimations/Bounce.ts
export class BounceIn extends ***plexAnimationBuilder implements IEntryExitAnimationBuilder {
static presetName = 'BounceIn';
build = (): EntryExitAnimationFunction => {
return () => {
'worklet';
return {
animations: {
transform: [
{
scale: withSequence(
withTiming(1.2, { duration: duration * 0.55 }), // 过度放大
withTiming(0.9, { duration: duration * 0.15 }), // 收缩
withTiming(1.1, { duration: duration * 0.15 }), // 再次放大
withTiming(1, { duration: duration * 0.15 }) // 稳定到目标大小
)
}
]
},
initialValues: { transform: [{ scale: 0 }] } // 初始缩放为0
};
};
};
}
上述代码通过四次 withTiming 动画的序列组合,模拟了物体落地时的弹性衰减过程:从初始缩放 0 开始,快速放大到 1.2 倍,随后小幅收缩到 0.9 倍,再反弹至 1.1 倍,最终稳定在 1 倍大小。整个动画周期为 600ms,各阶段时长按 55%、15%、15%、15% 分配,形成自然的弹性曲线。
多方向弹跳动画
除基础的缩放弹跳外,Reanimated 还提供了方向特异性的弹跳动画,如:
-
BounceInDown:从屏幕顶部向下弹跳入场(修改
translateY属性) -
BounceInLeft:从屏幕左侧向右弹跳入场(修改
translateX属性) - BounceOutRight:向屏幕右侧弹跳退场
这些类的实现逻辑与 BounceIn 类似,仅初始位置和变换属性不同。例如 BounceInLeft 的初始位置为 translateX: -values.windowWidth(屏幕左侧外),通过水平方向的位移序列实现从左至右的弹跳效果。
实战应用:按钮点击弹跳效果
以下是在 React Native 组件中集成 BounceIn 动画的示例。假设我们需要为一个按钮添加点击后的弹性反馈:
import Animated, { useAnimatedStyle, useSharedValue } from 'react-native-reanimated';
import { BounceIn } from 'react-native-reanimated/lib/typescript/src/layoutReanimation/defaultAnimations/Bounce';
const BounceButton = () => {
const isPressed = useSharedValue(false);
// 应用BounceIn动画到样式
const animatedStyle = useAnimatedStyle(() => ({
transform: [{ scale: isPressed.value ? 0.9 : 1 }],
}));
return (
<Animated.TouchableOpacity
style={[{ width: 100, height: 100, backgroundColor: 'blue' }, animatedStyle]}
onPressIn={() => (isPressed.value = true)}
onPressOut={() => (isPressed.value = false)}
/>
);
};
更简便的方式是直接使用 Reanimated 提供的 Animated 组件,并通过 entering 属性指定动画:
import { Animated } from 'react-native-reanimated';
import { BounceIn } from 'react-native-reanimated';
const AnimatedView = () => (
<Animated.View
entering={BounceIn.duration(800).delay(200)} // 自定义时长和延迟
style={{ width: 200, height: 200, backgroundColor: 'red' }}
/>
);
上述代码中,BounceIn.duration(800) 将动画时长从默认 600ms 调整为 800ms,并添加 200ms 延迟后执行。
动画原理:物理曲线与时间分配
Reanimated 的弹跳动画之所以逼真,核心在于对物理运动规律的模拟。以 BounceIn 的缩放序列为例:
| 阶段 | 目标值 | 时长占比 | 物理意义 |
|---|---|---|---|
| 1 | 1.2x | 55% | 快速膨胀(接触地面前的加速) |
| 2 | 0.9x | 15% | 撞击后的收缩(地面反作用力) |
| 3 | 1.1x | 15% | 弹性回弹(物体自身弹性) |
| 4 | 1.0x | 15% | 稳定衰减(能量耗散) |
这种非均匀的时间分配符合现实中物体弹跳的能量变化规律:初始阶段能量最大,运动幅度最大;后续弹跳逐渐衰减,直至稳定。开发者可通过修改 duration 参数调整动画总时长,或通过 withSpring 函数自定义弹性系数。
性能优化与调试
Reanimated 动画通过 UI 线程执行,避免了 JavaScript 桥接的性能瓶颈。对于复杂场景,可使用以下技巧优化:
-
使用
worklet关键字:确保动画逻辑在 UI 线程执行 -
共享值复用:通过
useSharedValue存储动画状态,避免重复创建 -
启用调试模式:在
package.json中添加REANIMATED_DEBUG=1查看动画帧率
若需调试动画序列,可使用 Reanimated 提供的 Flipper 插件,实时可视化动画曲线和性能指标。
扩展阅读与资源
- 官方文档:Reanimated 布局动画指南
- 动画源码:Bounce.ts 完整实现
-
示例项目:
apps/fabric-example目录下包含多种弹跳动画的演示页面
通过合理运用 Reanimated 的 Bounce 类,开发者可以轻松为 React Native 应用添加符合物理规律的弹性动画,显著提升界面交互质感。建议结合具体场景调整动画参数,如通过 .delay(300) 实现组件间的序列动画,或通过 .callback 在动画结束后执行额外逻辑。
【免费下载链接】react-native-reanimated React Native's Animated library reimplemented 项目地址: https://gitcode.***/GitHub_Trending/re/react-native-reanimated