This documentation is available as Markdown for AI agents and LLMs. See the full Markdown index or append .md to any documentation URL.
添加手势
编辑页面
在本教程中,了解如何实现来自 React Native Gesture Handler 和 Reanimated 库的手势。
手势是在应用中提供直观用户体验的绝佳方式。React Native Gesture Handler 库提供了内置的原生组件来处理手势。它使用平台的原生触摸处理系统来识别平移、点击、旋转以及其他手势。在本章中,我们将使用这个库添加两种不同的手势:
- 双击以放大 emoji 贴纸的尺寸,并在再次双击时缩小尺寸。
- 平移以在屏幕上移动 emoji 贴纸,这样用户就可以将贴纸放置在图片中的任意位置。
我们还会使用 Reanimated 库在手势状态之间制作动画过渡。

使用 React Native Gesture Handler 和 Reanimated 为 emoji 贴纸添加双击和平移手势。
1
2
使用动画组件
Animated 组件会查看组件的 style 属性,并判断哪些值需要进行动画处理和更新,从而创建动画。Reanimated 导出了诸如 <Animated.View>、<Animated.Text> 或 <Animated.ScrollView> 之类的动画组件。我们将把动画应用到 <Animated.Image> 组件上,以实现双击手势效果。
- 打开 src/components 目录中的 emoji-sticker.tsx 文件。在文件中,从
react-native-reanimated库导入Animated,以使用动画组件。 - 将
Image组件替换为<Animated.Image>。
关于动画组件 API 的完整参考,请查看 React Native Reanimated 文档。
3
添加点击手势
React Native Gesture Handler 允许我们在检测到触摸输入时添加行为,比如双击事件。
在 src/components/emoji-sticker.tsx 文件中:
- 从
react-native-gesture-handler导入Gesture和GestureDetector。 - 为了识别贴纸上的点击,导入
useAnimatedStyle、useSharedValue和withSpring,以便为<Animated.Image>的样式添加动画。 - 在
EmojiSticker组件内部,使用useSharedValue()钩子创建一个名为scaleImage的引用。它会将imageSize的值作为初始值。
使用 useSharedValue() 钩子创建共享值有很多优点。它有助于修改数据,并基于当前值运行动画。我们可以使用 .value 属性来访问和修改共享值。我们将创建一个 doubleTap 对象来缩放初始值,并使用 Gesture.Tap() 在缩放贴纸图片时为过渡添加动画。为了确定所需的点击次数,我们会添加 numberOfTaps()。
在 EmojiSticker 组件中创建以下对象:
为了给过渡添加动画,我们来使用基于弹簧的动画。这会让它更有生命力,因为它基于现实世界中弹簧的物理特性。我们将使用 react-native-reanimated 提供的 withSpring() 函数。
在贴纸图片上,我们将使用 useAnimatedStyle() 钩子来创建一个样式对象。这将帮助我们在动画发生时使用共享值更新样式。我们还会通过修改 width 和 height 属性来缩放图片大小。这些属性的初始值设置为 imageSize。
创建一个 imageStyle 变量并将其添加到 EmojiSticker 组件中:
接下来,将 <Animated.Image> 组件包裹在 <GestureDetector> 中,并修改 <Animated.Image> 上的 style 属性以传入 imageStyle。
在上面的代码片段中,gesture 属性接收 doubleTap 的值,以便在用户双击贴纸图片时触发手势。
让我们看看我们在 Android、iOS 和 web 上的应用:
关于点击手势 API 的完整参考,请查看 React Native Gesture Handler 文档。
4
添加平移手势
为了识别贴纸上的拖动手势并跟踪其移动,我们将使用平移手势。在 src/components/emoji-sticker.tsx 中:
- 创建两个新的共享值:
translateX和translateY。 - 将
<View>替换为<Animated.View>组件。
让我们了解一下上面的代码做了什么:
- 定义的平移值会让贴纸在屏幕上移动。由于贴纸会沿着两个轴移动,我们需要跟踪 X 和 Y 值。
- 在
useSharedValue()钩子中,我们将两个平移变量的初始位置都设置为0。这是贴纸的初始位置和起点。该值会在手势开始时设置贴纸的初始位置。
在上一步中,我们为通过 Gesture.Tap() 方法链式调用的点击手势触发了 onStart() 回调。对于平移手势,请指定 onChange() 回调,它会在手势处于活动状态并移动时运行。
- 创建一个
drag对象来处理平移手势。onChange()回调接受event作为参数。changeX和changeY属性保存自上一个事件以来位置的变化,并更新存储在translateX和translateY中的值。 - 使用
useAnimatedStyle()钩子定义containerStyle对象。它将返回一个变换数组。对于<Animated.View>组件,我们需要将transform属性设置为translateX和translateY的值。当手势激活时,这将改变贴纸的位置。
接下来,在 JSX 代码中:
- 更新
<EmojiSticker>组件,使<GestureDetector>组件成为最顶层组件。 - 在
<Animated.View>组件上添加containerStyle,以应用变换样式。
让我们看看我们在 Android、iOS 和 web 上的应用:
摘要
Chapter 6: Add gestures
We've successfully implemented pan and tap gestures.
In the next chapter, we'll learn how to take a screenshot of the image and the sticker, and save it on the device's library.