本文将从 ArkUI + Canvas + Touch 事件 出发,完整实现一个 HarmonyOS 5 手写板应用,包括基础绘制、平滑曲线、橡皮擦、撤销重做、保存图片、多点触控优化等功能,适合 HarmonyOS NEXT 开发者深入学习。


一、最终效果

最终实现一个完整的手写板:

✅ 手指自由书写

✅ 支持不同颜色

✅ 支持不同画笔粗细

✅ 贝塞尔曲线平滑

✅ 橡皮擦

✅ 撤销(Undo)

✅ 重做(Redo)

✅ 清空画板

✅ 保存图片

✅ 支持高刷新率

效果类似:


---------------------------------------
|                                     |
|      手写区域                       |
|                                     |
|       ***********                   |
|    ***************                  |
|       ******                        |
|                                     |
---------------------------------------

颜色  粗细  橡皮  撤销 重做 清空 保存

二、实现思路

HarmonyOS 中没有现成的 SignatureView。

一般都是:


TouchEvent
        │
        ▼
记录坐标 Point
        │
        ▼
CanvasRenderingContext2D
        │
        ▼
drawLine()

整体流程:


手指移动
      │
      ▼
TouchMove
      │
      ▼
记录Point
      │
      ▼
Canvas绘制
      │
      ▼
刷新Canvas

三、创建项目

DevEco Studio


Stage Model

ArkTS

API 18

HarmonyOS 5

页面:


pages

    Index.ets

四、准备Canvas

首先创建 Canvas。


Canvas(this.context)
    .width('100%')
    .height('100%')

需要:


private context = new CanvasRenderingContext2D();

完整:


@State
private context: CanvasRenderingContext2D =
new CanvasRenderingContext2D();

五、定义Point


class Point{

    x:number

    y:number

    constructor(x:number,y:number){

        this.x=x

        this.y=y

    }

}

保存轨迹:


private points:Array<Point>=[]

六、监听Touch

Canvas 支持:


Touch Down

Touch Move

Touch Up

例如:


Canvas(this.context)
.onTouch((event)=>{

})

判断事件:


switch(event.type){

case TouchType.Down:

break;

case TouchType.Move:

break;

case TouchType.Up:

break;

}

七、开始绘制

按下:


case TouchType.Down:

this.points=[]

this.points.push(
new Point(
event.touches[0].x,
event.touches[0].y
))

八、移动绘制

Move:


this.points.push(
new Point(
event.touches[0].x,
event.touches[0].y
))

然后:


this.draw()

九、Canvas画线


draw(){

    if(this.points.length<2){

        return

    }

    let p1=this.points[this.points.length-2]

    let p2=this.points[this.points.length-1]

    this.context.beginPath()

    this.context.moveTo(
        p1.x,
        p1.y
    )

    this.context.lineTo(
        p2.x,
        p2.y
    )

    this.context.stroke()

}

即可实现最基础手写。


十、设置画笔

颜色:


this.context.strokeStyle="blue"

宽度:


this.context.lineWidth=6

圆角:


this.context.lineCap="round"

连接:


this.context.lineJoin="round"

效果提升很多。


十一、平滑曲线

普通 lineTo 会有锯齿。

推荐:


QuadraticCurve

使用:


quadraticCurveTo()

例如:


context.quadraticCurveTo(
cx,
cy,
x,
y
)

这样可以实现圆润书写。


十二、贝塞尔算法

实际开发一般采用:


P0

P1

P2

计算:


中点

↓

控制点

↓

Bezier

公式:


M=(P1+P2)/2

然后:


quadraticCurveTo(
P1,
M
)

手感接近微信签名板。


十三、动态粗细

速度越快:


线越细

速度慢:


线越粗

计算:


distance

/

time

得到:


velocity

例如:


width=maxWidth-velocity

再限制:


Math.max(
2,
Math.min(
8,
width
))

十四、颜色切换

定义:


@State

private color="black"

绘制前:


context.strokeStyle=this.color

按钮:


Button("红色")

点击:


this.color="red"

即可。


十五、画笔粗细

例如:


Slider({

value:5,

min:1,

max:20

})

改变:


this.lineWidth=value

十六、橡皮擦

橡皮其实不是:


删除

而是:


画白线

例如:


strokeStyle="white"

或者:


globalCompositeOperation

设置:


destination-out

即可真正擦除。


十七、Undo撤销

保存每一笔:


Array<Path>

例如:


paths.push(
currentPath
)

撤销:


paths.pop()

然后:


重新绘制所有Path

十八、Redo重做

准备:


undoStack

redoStack

撤销:


undo

↓

redoStack.push()

恢复:


redo

↓

undoStack.push()

即可。


十九、清空画板

Canvas:


clearRect(
0,
0,
width,
height
)

同时:


paths.clear()

二十、保存图片

HarmonyOS 可以导出 PixelMap。

一般流程:


Canvas

↓

ImageBitmap

↓

PixelMap

↓

File

↓

相册

保存:


save()

即可生成 PNG。


二十一、多点触控

建议:


仅响应第一根手指

例如:


event.touches[0]

避免双指造成轨迹混乱。


二十二、性能优化

推荐:

1、减少 redraw

不要 Move 一次:


clear

↓

全部重画

而是:


新增一段

↓

直接绘制

效率更高。


2、对象复用

不要:


new Point()

几万次。

可以对象池。


3、requestAnimationFrame

统一刷新。

不要:


TouchMove

↓

立即刷新

而:


TouchMove

↓

缓存

↓

下一帧刷新

4、路径缓存

保存:


Path2D

减少 CPU。


5、GPU 加速

HarmonyOS Canvas 默认支持 GPU。

无需自己处理。


二十三、项目目录


entry
│
├──pages
│      Index.ets
│
├──model
│      Point.ets
│      Path.ets
│
├──viewmodel
│      DrawManager.ets
│
├──utils
│      BezierUtil.ets
│
├──common
│      ColorUtil.ets
│
└──resources

二十四、完整架构


TouchEvent
        │
        ▼
DrawManager
        │
        ▼
Point
        │
        ▼
Bezier
        │
        ▼
Canvas
        │
        ▼
Render

采用这种分层后,可以方便扩展:

  • 手写签名

  • 涂鸦板

  • 白板协作

  • 批注工具

  • 图片标注

  • PDF 批注

  • 教学画板


二十五、总结

HarmonyOS 5 实现手写板的核心在于 Touch 事件 + Canvas 绘制 + 路径管理。一个完整的高质量手写板通常包含以下能力:

功能 推荐实现方式
手写绘制 TouchEvent + Canvas
平滑笔迹 quadraticCurveTo() 或贝塞尔曲线
动态笔锋 根据书写速度动态调整线宽
橡皮擦 destination-out 或背景色覆盖
撤销/重做 路径栈(Undo/Redo)管理
清空画板 clearRect() + 清空路径数据
保存图片 导出 PixelMap 后保存为 PNG
性能优化 增量绘制、对象复用、按帧刷新、路径缓存

对于生产级项目,建议将 绘制逻辑、路径模型、贝塞尔算法、工具栏状态、Canvas 渲染 解耦,实现 MVC 或 MVVM 架构,这样更易维护,也便于后续扩展签名、批注、协作白板等高级功能。

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐