creating-reanimated-animations
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseReact Native Reanimated Code Generator
React Native Reanimated代码生成器
Generate performant animation code using React Native Reanimated. Supports both v3 and v4.
使用React Native Reanimated生成高性能动画代码,同时支持v3和v4版本。
Version Detection
版本检测
Check the project's to determine the version:
package.json- v4 (New Architecture only): requires as separate dependency
react-native-worklets - v3 (supports Legacy and New Architecture): single package install
查看项目的以确定版本:
package.json- v4(仅支持新架构):需要单独安装依赖
react-native-worklets - v3(支持旧架构和新架构):只需安装单个包
Setup
设置
Reanimated v4 (latest)
Reanimated v4(最新版)
bash
npm install react-native-reanimated react-native-workletsBabel plugin: (must be last in plugins list).
For Expo: no Babel config needed. Run after install.
'react-native-worklets/plugin'npx expo prebuildbash
npm install react-native-reanimated react-native-workletsBabel插件:(必须位于插件列表的最后一位)。
对于Expo项目:无需配置Babel,安装后运行即可。
'react-native-worklets/plugin'npx expo prebuildReanimated v3
Reanimated v3
bash
npm install react-native-reanimatedBabel plugin: (must be last in plugins list).
'react-native-reanimated/plugin'bash
npm install react-native-reanimatedBabel插件:(必须位于插件列表的最后一位)。
'react-native-reanimated/plugin'Core Pattern
核心模式
Every animation follows three steps:
tsx
import Animated, { useSharedValue, useAnimatedStyle, withTiming } from 'react-native-reanimated';
function Component() {
// 1. Create shared value (lives on UI thread)
const offset = useSharedValue(0);
// 2. Bind to style
const animatedStyle = useAnimatedStyle(() => ({
transform: [{ translateX: offset.value }],
}));
// 3. Trigger animation
const handlePress = () => {
offset.value = withTiming(200, { duration: 500 });
};
return (
<Animated.View style={[styles.box, animatedStyle]}>
<Pressable onPress={handlePress}><Text>Move</Text></Pressable>
</Animated.View>
);
}所有动画都遵循以下三个步骤:
tsx
import Animated, { useSharedValue, useAnimatedStyle, withTiming } from 'react-native-reanimated';
function Component() {
// 1. 创建共享值(运行在UI线程)
const offset = useSharedValue(0);
// 2. 绑定到样式
const animatedStyle = useAnimatedStyle(() => ({
transform: [{ translateX: offset.value }],
}));
// 3. 触发动画
const handlePress = () => {
offset.value = withTiming(200, { duration: 500 });
};
return (
<Animated.View style={[styles.box, animatedStyle]}>
<Pressable onPress={handlePress}><Text>移动</Text></Pressable>
</Animated.View>
);
}Animation Selection
动画选择
| User wants | Function | Key params |
|---|---|---|
| Smooth fixed-duration transition | | Default: 300ms, |
| Natural bouncy feel | | Default: mass=1, damping=10, stiffness=100 |
| Momentum after fling | | Needs initial velocity from gesture |
| Clamp spring range | | v4: limits spring overshoot |
| Loop/pulse/shake | | |
| Multi-step choreography | | Runs in order |
| Delayed start | | Delays any animation |
Spring tuning: lower (5–8) = more bounce, higher (150–200) = snappier, higher (2–3) = heavier.
dampingstiffnessmass| 用户需求 | 函数 | 关键参数 |
|---|---|---|
| 平滑的固定时长过渡 | | 默认值:300ms, |
| 自然的弹性效果 | | 默认值:mass=1, damping=10, stiffness=100 |
| 拖拽后的动量效果 | | 需要从手势获取初始速度 |
| 限制弹簧范围 | | v4:限制弹簧过冲 |
| 循环/脉冲/震动 | | v4中 |
| 多步骤编排 | | 按顺序执行 |
| 延迟启动 | | 延迟任意动画的启动 |
弹簧参数调整: 降低(5–8)= 弹性更强,提高(150–200)= 响应更灵敏,提高(2–3)= 质感更厚重。
dampingstiffnessmassQuick Patterns
快速实现模式
Fade
淡入淡出
tsx
const opacity = useSharedValue(0);
const style = useAnimatedStyle(() => ({ opacity: opacity.value }));
// Show: opacity.value = withTiming(1);
// Hide: opacity.value = withTiming(0);tsx
const opacity = useSharedValue(0);
const style = useAnimatedStyle(() => ({ opacity: opacity.value }));
// 显示:opacity.value = withTiming(1);
// 隐藏:opacity.value = withTiming(0);Slide from side
侧边滑入
tsx
const translateX = useSharedValue(-SCREEN_WIDTH);
const style = useAnimatedStyle(() => ({
transform: [{ translateX: translateX.value }],
}));
// Enter: translateX.value = withSpring(0);tsx
const translateX = useSharedValue(-SCREEN_WIDTH);
const style = useAnimatedStyle(() => ({
transform: [{ translateX: translateX.value }],
}));
// 进入:translateX.value = withSpring(0);Scale on press
按压缩放
tsx
const scale = useSharedValue(1);
const style = useAnimatedStyle(() => ({
transform: [{ scale: scale.value }],
}));
// In: scale.value = withSpring(0.95);
// Out: scale.value = withSpring(1);tsx
const scale = useSharedValue(1);
const style = useAnimatedStyle(() => ({
transform: [{ scale: scale.value }],
}));
// 按下:scale.value = withSpring(0.95);
// 松开:scale.value = withSpring(1);Interpolation
插值
tsx
import { interpolate, Extrapolation } from 'react-native-reanimated';
const style = useAnimatedStyle(() => ({
opacity: interpolate(scrollY.value, [0, 100], [1, 0], Extrapolation.CLAMP),
transform: [{
scale: interpolate(scrollY.value, [0, 100], [1, 0.8], Extrapolation.CLAMP),
}],
}));tsx
import { interpolate, Extrapolation } from 'react-native-reanimated';
const style = useAnimatedStyle(() => ({
opacity: interpolate(scrollY.value, [0, 100], [1, 0], Extrapolation.CLAMP),
transform: [{
scale: interpolate(scrollY.value, [0, 100], [1, 0.8], Extrapolation.CLAMP),
}],
}));Scroll-linked animation
滚动联动动画
tsx
const scrollY = useSharedValue(0);
const scrollHandler = useAnimatedScrollHandler({
onScroll: (event) => { scrollY.value = event.contentOffset.y; },
});
<Animated.ScrollView onScroll={scrollHandler}>{children}</Animated.ScrollView>Or simpler with (v4) / (v3):
useScrollOffsetuseScrollViewOffsettsx
const ref = useAnimatedRef<Animated.ScrollView>();
const scrollOffset = useScrollOffset(ref); // auto-tracks scroll position
<Animated.ScrollView ref={ref}>{children}</Animated.ScrollView>tsx
const scrollY = useSharedValue(0);
const scrollHandler = useAnimatedScrollHandler({
onScroll: (event) => { scrollY.value = event.contentOffset.y; },
});
<Animated.ScrollView onScroll={scrollHandler}>{children}</Animated.ScrollView>或者使用更简洁的(v4)/(v3):
useScrollOffsetuseScrollViewOffsettsx
const ref = useAnimatedRef<Animated.ScrollView>();
const scrollOffset = useScrollOffset(ref); // 自动跟踪滚动位置
<Animated.ScrollView ref={ref}>{children}</Animated.ScrollView>Layout Animations (Mount/Unmount)
布局动画(挂载/卸载)
Built-in presets — no shared values needed:
tsx
import Animated, { FadeIn, SlideInRight, SlideOutLeft } from 'react-native-reanimated';
<Animated.View entering={FadeIn.duration(400).delay(100)} exiting={SlideOutLeft.duration(300)}>
{content}
</Animated.View>Presets: , , , , , , , , , .
FadeIn/OutSlideIn/OutLeft/Right/Up/DownZoomIn/OutBounceIn/OutFlipInEasyX/YLightSpeedIn/OutPinwheelIn/OutRollIn/OutRotateIn/OutStretchIn/OutModifiers: , , , , , , , .
.duration(ms).delay(ms).springify().damping(n).stiffness(n).randomDelay().reduceMotion().withCallback()内置预设动画——无需使用共享值:
tsx
import Animated, { FadeIn, SlideInRight, SlideOutLeft } from 'react-native-reanimated';
<Animated.View entering={FadeIn.duration(400).delay(100)} exiting={SlideOutLeft.duration(300)}>
{content}
</Animated.View>预设动画:、、、、、、、、、。
FadeIn/OutSlideIn/OutLeft/Right/Up/DownZoomIn/OutBounceIn/OutFlipInEasyX/YLightSpeedIn/OutPinwheelIn/OutRollIn/OutRotateIn/OutStretchIn/Out修饰符:、、、、、、、。
.duration(ms).delay(ms).springify().damping(n).stiffness(n).randomDelay().reduceMotion().withCallback()Layout Transitions (position/size changes)
布局过渡(位置/尺寸变化)
Animate when component position or size changes:
tsx
import { LinearTransition, SequencedTransition } from 'react-native-reanimated';
<Animated.View layout={LinearTransition.springify().damping(15)} />Transitions: , , , , , .
LinearTransitionSequencedTransitionFadingTransitionJumpingTransitionCurvedTransitionEntryExitTransition当组件位置或尺寸变化时触发动画:
tsx
import { LinearTransition, SequencedTransition } from 'react-native-reanimated';
<Animated.View layout={LinearTransition.springify().damping(15)} />过渡类型:、、、、、。
LinearTransitionSequencedTransitionFadingTransitionJumpingTransitionCurvedTransitionEntryExitTransitionKeyframe Animations (complex entering/exiting)
关键帧动画(复杂的进入/退出)
tsx
import { Keyframe } from 'react-native-reanimated';
const enteringAnimation = new Keyframe({
0: { opacity: 0, transform: [{ translateY: -50 }] },
50: { opacity: 0.5, transform: [{ translateY: -25 }], easing: Easing.out(Easing.quad) },
100: { opacity: 1, transform: [{ translateY: 0 }] },
}).duration(500);
<Animated.View entering={enteringAnimation}>{content}</Animated.View>For custom animations, layout transitions, and list animations, read .
references/layout-animations.mdtsx
import { Keyframe } from 'react-native-reanimated';
const enteringAnimation = new Keyframe({
0: { opacity: 0, transform: [{ translateY: -50 }] },
50: { opacity: 0.5, transform: [{ translateY: -25 }], easing: Easing.out(Easing.quad) },
100: { opacity: 1, transform: [{ translateY: 0 }] },
}).duration(500);
<Animated.View entering={enteringAnimation}>{content}</Animated.View>如需自定义动画、布局过渡和列表动画,请查看。
references/layout-animations.mdCSS Animations (v4 only)
CSS动画(仅v4支持)
Declarative CSS-like animations using style props directly:
tsx
<Animated.View style={{
animationName: {
from: { opacity: 0, transform: [{ translateY: -20 }] },
to: { opacity: 1, transform: [{ translateY: 0 }] },
},
animationDuration: '500ms',
animationTimingFunction: 'ease-out',
}} />Supported props: , , , , , , , .
animationNameanimationDurationanimationDelayanimationIterationCountanimationDirectionanimationFillModeanimationPlayStateanimationTimingFunction直接通过样式属性声明类CSS动画:
tsx
<Animated.View style={{
animationName: {
from: { opacity: 0, transform: [{ translateY: -20 }] },
to: { opacity: 1, transform: [{ translateY: 0 }] },
},
animationDuration: '500ms',
animationTimingFunction: 'ease-out',
}} />支持的属性:、、、、、、、。
animationNameanimationDurationanimationDelayanimationIterationCountanimationDirectionanimationFillModeanimationPlayStateanimationTimingFunctionCSS Transitions (v4 only)
CSS过渡(仅v4支持)
Automatic transitions when style values change:
tsx
<Animated.View style={{
width: isExpanded ? 200 : 100,
transitionProperty: 'width',
transitionDuration: '300ms',
transitionTimingFunction: 'ease-in-out',
}} />Multiple properties: with matching .
transitionProperty: ['width', 'opacity', 'transform']transitionDuration: ['300ms', '200ms', '500ms']For detailed CSS animations/transitions reference (keyframes, timing functions, examples), read .
references/css-animations-detailed.md当样式值变化时自动触发过渡动画:
tsx
<Animated.View style={{
width: isExpanded ? 200 : 100,
transitionProperty: 'width',
transitionDuration: '300ms',
transitionTimingFunction: 'ease-in-out',
}} />多个属性:,可搭配对应的。
transitionProperty: ['width', 'opacity', 'transform']transitionDuration: ['300ms', '200ms', '500ms']如需详细的CSS动画/过渡参考(关键帧、计时函数、示例),请查看。
references/css-animations-detailed.mdShared Element Transitions (Experimental)
共享元素过渡(实验性)
Animate components between screens during navigation:
tsx
// Screen A
<Animated.Image sharedTransitionTag={`photo-${id}`} source={...} />
// Screen B (same tag)
<Animated.Image sharedTransitionTag={`photo-${id}`} source={...} />Requires and feature flag. For setup and customization, read .
@react-navigation/native-stackreferences/shared-element-transitions.md在导航过程中实现组件在屏幕间的动画过渡:
tsx
// 屏幕A
<Animated.Image sharedTransitionTag={`photo-${id}`} source={...} />
// 屏幕B(使用相同标签)
<Animated.Image sharedTransitionTag={`photo-${id}`} source={...} />需要依赖和功能开关。如需设置和自定义,请查看。
@react-navigation/native-stackreferences/shared-element-transitions.mdGesture Integration
手势集成
For drag, pinch, fling, and other gesture-driven animations, read .
references/gesture-patterns.mdRequires: + at app root.
react-native-gesture-handler<GestureHandlerRootView>如需实现拖拽、捏合、抛掷等手势驱动的动画,请查看。
references/gesture-patterns.md依赖: + 在应用根节点添加。
react-native-gesture-handler<GestureHandlerRootView>Full API Reference
完整API参考
For complete hook signatures, animation parameters, v3↔v4 differences, and advanced APIs, read .
references/api-reference.md如需完整的钩子签名、动画参数、v3与v4的差异以及高级API,请查看。
references/api-reference.mdWorklets & Advanced APIs
Worklets与高级API
For understanding worklets, directive, /, , , , , and performance tips, read .
'worklet'runOnJSrunOnUIuseAnimatedReactionuseFrameCallbackmeasuredispatchCommandreferences/worklets-advanced.md如需理解Worklets、指令、/、、、、以及性能优化技巧,请查看。
'worklet'runOnJSrunOnUIuseAnimatedReactionuseFrameCallbackmeasuredispatchCommandreferences/worklets-advanced.mdReal-World Component Patterns
真实场景组件模式
For full implementations of accordion, bottom sheet, flip card, and FAB, read .
references/component-patterns.md如需折叠面板、底部弹窗、翻转卡片和FAB的完整实现,请查看。
references/component-patterns.mdTesting, Colors & Supported Properties
测试、颜色与支持的属性
For testing animations with Jest, animating colors with , and the full list of animatable properties by platform, read .
interpolateColorreferences/testing-and-properties.md如需使用Jest测试动画、使用实现颜色动画,以及各平台支持的可动画属性完整列表,请查看。
interpolateColorreferences/testing-and-properties.mdRules
规则
- Always use — never animate plain RN components
Animated.View/Text/Image/ScrollView/FlatList - v4: use /
runOnJS(re-exported), or importrunOnUI/scheduleOnRNfromscheduleOnUIreact-native-worklets - v3: use for heavy JS-thread logic
runOnJS(fn)() - Always use with
Extrapolation.CLAMPunless you explicitly want extrapolationinterpolate - Combine:
withSequence(withTiming(1.2, {duration: 100}), withSpring(1)) - Use to respect accessibility settings
useReducedMotion() - Test on real devices — simulator performance differs significantly
- v4: is deprecated → use
useAnimatedKeyboardreact-native-keyboard-controller
Based on react-native-reanimated by Software Mansion (MIT License)
- 始终使用——永远不要为原生RN组件添加动画
Animated.View/Text/Image/ScrollView/FlatList - v4:使用/
runOnJS(已重导出),或从runOnUI导入react-native-worklets/scheduleOnRNscheduleOnUI - v3:使用处理耗时的JS线程逻辑
runOnJS(fn)() - 除非明确需要外推,否则在使用时始终搭配
interpolateExtrapolation.CLAMP - 组合使用:
withSequence(withTiming(1.2, {duration: 100}), withSpring(1)) - 使用以遵循无障碍设置
useReducedMotion() - 在真实设备上测试——模拟器的性能与真实设备差异显著
- v4:已废弃 → 使用
useAnimatedKeyboardreact-native-keyboard-controller
基于react-native-reanimated(MIT许可证)