HarmonyOS APP开发---"随手画"白板涂鸦App,需要用到这个库

HarmonyOS APP开发---"随手画"白板涂鸦App,需要用到这个库

做一个白板涂鸦 App,手指画线要跟手、双指缩放画布、长按选区------RN 自带 PanResponder 在 JS 线程处理手势,画线总是慢半拍。@react-native-ohos/react-native-gesture-handler 在原生层识别手势,零延迟跟手。
📦 仓库地址:gitcode.com/CPF-RN/rntp... | 安装:npm install @react-native-ohos/react-native-gesture-handler


写在前面

"随手画"是一个简易白板涂鸦 App,核心交互全靠手势:

  • 单指拖拽:画笔在画布上画线
  • 双指捏合:缩放画布,方便看细节或看全局
  • 双指拖拽:平移画布
  • 长按:选中已有笔画,可移动或删除

这些手势如果用 RN 自带的 PanResponder,问题很明显:手势事件走 JS Bridge 中转,画线延迟明显,双指操作更是灾难。而且画线手势和画布平移手势会冲突------想画线结果把画布拖走了。

react-native-gesture-handler 把手势识别下沉到原生层 ,在原生线程完成状态机管理,JS 只接收最终结果------零延迟跟手 ,还能用 Gesture.Exclusive / Gesture.Simultaneous 精确控制手势冲突。

这篇文章聊什么

  1. 画线手势------单指 Pan 驱动 SVG 路径绘制
  2. 缩放+平移------双指 Pinch + Pan 同时识别
  3. 手势冲突------Gesture.Exclusive 让画线和拖拽互不干扰
flowchart TD A[用户触摸画布] --> B{几根手指?} B -->|单指| C[Pan 手势: 画线] B -->|双指| D{手势类型} D -->|捏合| E[Pinch: 缩放画布] D -->|拖拽| F[Pan: 平移画布] E --> G[Simultaneous: 缩放+平移同时] F --> G C --> H[画线 + 添加到路径列表] H --> I[渲染 SVG Path] G --> J[变换画布坐标] J --> I

第一步:安装与根组件包裹

bash 复制代码
npm install @react-native-ohos/react-native-gesture-handler
tsx 复制代码
import { GestureHandlerRootView } from '@react-native-ohos/react-native-gesture-handler'

export default function App() {
  return (
    <GestureHandlerRootView style={{ flex: 1 }}>
      <Whiteboard />
    </GestureHandlerRootView>
  )
}

第二步:单指画线手势

用 Gesture.Pan() 驱动画笔轨迹,配合 react-native-svg 的 Path 渲染:

tsx 复制代码
import { GestureDetector, Gesture } from '@react-native-ohos/react-native-gesture-handler'
import { View } from 'react-native'
import { Path, Svg } from 'react-native-svg'
import { useSharedValue } from 'react-native-reanimated'

function Whiteboard() {
  const paths = useSharedValue<Array<string>>([])
  const currentPath = useSharedValue('')

  // 单指画线手势
  const drawGesture = Gesture.Pan()
    .minPointers(1)
    .maxPointers(1) // 只识别单指
    .onBegin((e) => {
      currentPath.value = `M ${e.x} ${e.y}`
    })
    .onUpdate((e) => {
      // 追加路径点
      currentPath.value += ` L ${e.x} ${e.y}`
    })
    .onEnd(() => {
      // 画完一条线,存入路径列表
      paths.value = [...paths.value, currentPath.value]
      currentPath.value = ''
    })

  return (
    <GestureDetector gesture={drawGesture}>
      <View style={{ flex: 1, backgroundColor: '#fff' }}>
        <Svg style={{ flex: 1 }}>
          {/* 已完成的笔画 */}
          {paths.value.map((d, i) => (
            <Path key={i} d={d} stroke="#333" strokeWidth={3} fill="none" />
          ))}
          {/* 当前正在画的笔画 */}
          {currentPath.value ? (
            <Path d={currentPath.value} stroke="#4ECDC4" strokeWidth={3} fill="none" />
          ) : null}
        </Svg>
      </View>
    </GestureDetector>
  )
}

手势在原生层识别,onUpdate 实时回调坐标------画线跟手零延迟,比 PanReceiver 快一个量级。


第三步:双指缩放 + 平移(同时识别)

双指操作画布:捏合缩放 + 拖拽平移,两个手势要同时识别:

tsx 复制代码
// 缩放手势
const pinchGesture = Gesture.Pinch()
  .onUpdate((e) => {
    scale.value = e.scale
  })

// 双指平移手势
const panGesture = Gesture.Pan()
  .minPointers(2) // 至少两指
  .onUpdate((e) => {
    translateX.value = e.translationX
    translateY.value = e.translationY
  })

// 关键:Simultaneous 让缩放和平移同时生效
const canvasGesture = Gesture.Simultaneous(pinchGesture, panGesture)

Gesture.Simultaneous 是核心------缩放和平移互不阻塞,用户可以一边捏合缩放一边拖拽平移画布,体验和原生画板一样流畅。


第四步:手势冲突------画线 vs 画布拖拽

单指画线 vs 双指拖拽,用 Gesture.Exclusive 确保互斥:

tsx 复制代码
// 组合:画线(单指)和画布操作(双指)互斥
const combinedGesture = Gesture.Exclusive(drawGesture, canvasGesture)

<GestureDetector gesture={combinedGesture}>
  <View style={{ flex: 1, backgroundColor: '#fff' }}>
    {/* 画布内容 */}
  </View>
</GestureDetector>

Exclusive 让手势按优先级判断------单指触发画线,双指触发画布操作,不会出现"想画线结果把画布拖走"的冲突。


为什么"随手画"选了 Gesture Handler?

需求 RN PanResponder @react-native-ohos/react-native-gesture-handler
手势延迟 JS 线程,慢半拍 ✅ 原生层,零延迟
多指手势 ❌ 难处理 ✅ Pan/Pinch 原生支持
手势同时 ❌ ✅ Simultaneous
手势互斥 ❌ 手动判断 ✅ Exclusive
与 SVG 联动 手动 ✅ 原生回调驱动

总结

"随手画"这个场景里,@react-native-ohos/react-native-gesture-handler 解决了三件事:

  1. 零延迟画线 ------Pan 手势在原生层识别,onUpdate 实时驱动 SVG Path
  2. 双指缩放+平移 ------Simultaneous 让 Pinch 和 Pan 同时生效
  3. 手势不冲突 ------Exclusive 让单指画线和双指操作互斥,各管各的

如果你也在做绘画、地图、卡片交互等需要复杂手势的 RN 鸿蒙应用,react-native-gesture-handler 是手势处理的基石。

相关推荐
donk13141 小时前
React Native for OpenHarmony 实战:三方库 react-native-toast-message 的鸿蒙化适配指南
react native·react.js·音视频·harmonyos
Flutter_OH2 小时前
Flutter OHOS Dart 堆栈符号化
harmonyos
Flutter_OH2 小时前
Flutter OHOS Flutter 多设备自适应 DPI 指导文档
harmonyos
SuperHeroWu72 小时前
【HarmonyOS 7】 应用 Agent 接入云 A2A 与端 A2A 的实践详解
ai·harmonyos·小艺
用户29469405448163 小时前
个人开发者上架鸿蒙 AI 应用,最后倒在安全评估实名制这一格
harmonyos·deepseek
Keya4 小时前
HarmonyOS 开发实战:用 util.Aspect 玩转 AOP 切面编程
harmonyos
威哥爱编程4 小时前
HarmonyOS 7 Agent 开发实战 03:Tool Calling 让 AI 查实时订单与库存
agent·harmonyos
威哥爱编程4 小时前
HarmonyOS 7 Agent 开发实战 02:Agent 工程脚手架与对话 UI 骨架
agent·harmonyos
Georgewu12 小时前
【HarmonyOS 7】 HarmonyOS 应用 Skill创建和编排详解
harmonyos
Georgewu15 小时前
【HarmonyOS 7】 应用 Agent 接入云 A2A 与端 A2A 的实践详解
harmonyos