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 是手势处理的基石。

相关推荐
youyin3 天前
HarmonyOS ArkUI 组件与自定义组件零基础:从搭页面到组件化开发
华为·harmonyos
HwJack203 天前
【HarmonyOS开发小实践】ArkTS 从 TypeScript 到方舟语言的演进
华为·harmonyos
威哥爱编程3 天前
HarmonyOS 7 星盾机密风控实战:设备风险因子端侧融合计算,可用不可见
harmonyos·arkts
威哥爱编程3 天前
HarmonyOS 7 应用快启实战:关键资源预加载进内存,冷启告别白屏
华为·harmonyos·arkts
马剑威(威哥爱编程)3 天前
【共创稿事节】HarmonyOS 7 视觉 AI 进阶实战:人脸检测 + 通用文字识别(OCR)两步接入
华为·harmonyos·arkts
HMS Core4 天前
HarmonyOS智慧多窗,让应用在任意窗口都“恰到好处”
harmonyos
梦想不只是梦与想4 天前
鸿蒙 应用发布准备工作(一)
harmonyos·鸿蒙上架·鸿蒙应用发布
马剑威(威哥爱编程)4 天前
【共创稿事节】HarmonyOS 7 文搜图实战:自然语言检索本地图片,全流程端侧闭环
华为·harmonyos
李游Leo4 天前
HarmonyOS 7 HAR + HSP 工程化实战:模块复用、包体积控制与依赖边界
harmonyos