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

相关推荐
lilian2332 小时前
HarmonyOS 7 新特性(二十六)|LazyLayoutAlgorithm 自定义懒布局
华为·harmonyos
lilian2333 小时前
HarmonyOS 7 新特性(二十九)|游戏伴随服务:悬浮协作与质量降级
游戏·语音识别·harmonyos
王二蛋与他的张大花3 小时前
让小艺替我回答“还有多久下班“——摸鱼鸭的 HarmonyOS 7 Skill 接入实战
harmonyos
用户0934077735144 小时前
HarmonyOS WPS Open SDK 实践:把水印与修订收成打开策略层
android·typescript·harmonyos
Veer Han6 小时前
DevEco CLI 实战:鸿蒙 App「宝贝日程表」从 0 开发到正式上架
华为·harmonyos
李游Leo6 小时前
【共创稿事节】 HarmonyOS 7 空间化 UI 实战:从平面布局到空间层级的界面重构
ui·平面·harmonyos
凡泰AI6 小时前
如何通过小程序多端框架,让一个小程序同时运行在iOS、安卓、鸿蒙和微信客户端,实现开发层面的降本增效
android·ios·微信小程序·小程序·harmonyos
less_121388 小时前
HarmonyOS WPS Open SDK:enableEdit 只读与可编辑打开模式
华为·sdk·harmonyos·wps·鸿蒙开发·文档编辑
贾伟康1 天前
【天体运行模拟|12】HarmonyOS ArkTS 本地数据文件实战:让离线资源读取失败可见可恢复
数据恢复·harmonyos·arkts·preferences·arkdata