《鸿蒙纪元》 是 张风捷特烈 计划打造的一套 HarmonyOS 开发系列教程合集。致力于创作优质的鸿蒙原生学习资源,帮助开发者进入纯血鸿蒙的开发之中。本系列的所有代码将开源在 HarmonyUnit 项目中:
github
: github.com/toly1994328…
gitee
: gitee.com/toly1994328…
鸿蒙纪元 系列文章列表可在《文章总集》 或 【github 项目首页】 查看。
前面 10 篇,我们从环境搭建
、到计数器
、猜数字
、电子木鱼
,一路走来,应该对鸿蒙开发有了那么一丢丢的认知。接下来将进入另外一个篇章。在这里将充满创造力,来体验一下鸿蒙开发中 Canvas 自定义绘制的能力,实现一个简单的小画板。
1. 需求与交互介绍
白板绘制是本教程的第三个案例,相比于前两个项目,可操作性更强一些,也更有趣。适合新手朋友进一步了解 绘制相关知识,体会其创造性,绘制过程中练习语法也是个不错的选择。下面是两个最基础的交互:
- 通过监听用户的拖拽手势,让界面留下触点的线条痕迹。
- 可以选择绘制时线条的颜色和粗细两个配置项。
画板绘制 | 颜色和线宽选择 |
---|---|
对于界面绘制内容的管理,提供了两个功能:
- 当界面中存在绘制的线条时,可以回退上一步;在有回退历史时,可以撤销回退。
- 右上角的清除按钮,点击时会弹出对话框确认清除,完成清空绘制的功能。
回退和撤销 | 清除内容 |
---|---|
2. 从画点开始说起
鸿蒙 ArkUI 中的自定义绘制和 h5 基本上是一致的,所以有过绘制校验的小伙伴就不用太担心。首先搭建一个如下界面,画几个点在界面上:
回退和撤销 | 清除内容 |
---|---|
在 pages 中,创建 painter 文件夹,盛放画板绘制相关的代码。view 下的 Painter
文件将作为构建界面的场所:
构建代码如下,其中 AppBar 是我们之前封装的组件,前面也用过很多次了,这里就不赘述了。绘制主要使用 Canvas 组件,该组件在构造时需要传入 CanvasRenderingContext2D 对象;该对象就是绘制操作的核心:
import { AppBar } from "../../../components/AppBar"
@Component
export struct Painter {
private settings: RenderingContextSettings = new RenderingContextSettings(true);
private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings);
@Builder
title() { //略... 详见源码 }
@Builder
backButton() { //略... 详见源码 }
@Builder
actionsButton() { //略... 详见源码 }
build() {
Column() {
AppBar({
titleSlot: this.title,
tailing: () => {this.backButton()},
leading: () => {this.actionsButton()},
})
Canvas(this.context)
.width('100%')
.layoutWeight(1)
.backgroundColor('#fafafa')
.onReady(() => this.paint(this.context))
}
.width('100%').height('100%')
}
paint(canvas: CanvasRenderingContext2D) {
// TODO 绘制...
}
}
鸿蒙的绘制 api 并没有 Flutter 那样丰富,绘制点可以 fillRect
绘制矩形完成:
paint(canvas: CanvasRenderingContext2D) {
let strokeWidth = 10;
canvas.fillRect(100, 100, strokeWidth, strokeWidth)
canvas.fillRect(100, 150, strokeWidth, strokeWidth)
canvas.fillRect(150, 150, strokeWidth, strokeWidth)
canvas.fillRect(200, 100, strokeWidth, strokeWidth)
}
3. 边线粗细和颜色
鸿蒙绘制中 画板
、画笔
、路径
的操作全都集成到了 CanvasRenderingContext2D
身上。
边线粗细 | 边线颜色 |
---|---|
- 通过 lineWidth 可以控制线的宽度;
- 通过 strokeStyle 可以控制线的颜色;
- 通过 moveTo 可以移动路径;
- 通过 lineTo 可以在到某点形成直线路径;
- 通过 stroke 绘制出边线路径;
drawLine1(canvas: CanvasRenderingContext2D){
canvas.lineWidth = 10;
canvas.strokeStyle = '#000000';
canvas.beginPath();
canvas.moveTo(100, 100);
canvas.lineTo(100, 150);
canvas.lineTo(150, 150);
canvas.lineTo(200,100);
canvas.stroke();
}
4. 线的端点类型
线的端点类型有三种,如下所示:
- square: 方形头
- butt : 无头
- round: 圆头
canvas.lineCap = 'square';
canvas.lineCap = 'butt';
canvas.lineCap = 'round';
5. 简单的基础图形绘制
CanvasRenderingContext2D 中提供了一些基础图形的绘制,比如 圆形
、矩形
、圆角矩形
、椭圆
、圆弧
等,这里简单了解一下。Path2D 提供了路径的封装,可以构建基本图形路径:
arc 绘制弧形: 入参分别是圆心坐标、半径 、 起始弧度,终止弧度。
另外,fill 会填满内部;可以将stroke 是线型模式,如下右图:
paint(canvas: CanvasRenderingContext2D) {
let region = new Path2D();
region.arc(100, 100, 50, 0, 2*Math.PI);
canvas.fill(region)
canvas.translate(120,0)
canvas.stroke(region)
}
Path2D#rect 可以构建矩形路径:
// 矩形
let region = new Path2D();
region.rect(100, 100, 80, 60);
canvas.fill(region)
canvas.translate(120,0)
canvas.stroke(region)
圆角矩形并没有内置提供,我们可以简单封装一下,通过直线和圆弧的路径操作来实现:
this.roundedRect(canvas,100, 100, 80, 60,8);
canvas.stroke()
canvas.translate(120, 0)
canvas.fill()
// 绘制圆角矩形的函数
roundedRect(ctx: CanvasRenderingContext2D, x: number, y: number, width: number, height: number, radius: number) {
ctx.beginPath();
ctx.moveTo(x + radius, y); // 移动到左上角圆角的起始点
ctx.lineTo(x + width - radius, y); // 绘制上边直线
ctx.arcTo(x + width, y, x + width, y + height, radius); // 绘制右上角圆角
ctx.lineTo(x + width, y + height - radius); // 绘制右边直线
ctx.arcTo(x + width, y + height, x + width - radius, y + height, radius); // 绘制右下角圆角
ctx.lineTo(x + radius, y + height); // 绘制下边直线
ctx.arcTo(x, y + height, x, y + height - radius, radius); // 绘制左下角圆角
ctx.lineTo(x, y + radius); // 绘制左边直线
ctx.arcTo(x, y, x + radius, y, radius); // 绘制左上角圆角
ctx.closePath();
}
Path2D#ellipse 可以构建矩形路径:参数分别是: 原点坐标、长短轴长、旋转角度、起止弧度
let region = new Path2D();
region.ellipse(120, 450, 80, 120, 0, Math.PI * 0, Math.PI * 2)
canvas.fill(region)
canvas.translate(0, -260)
canvas.lineWidth = 5;
canvas.stroke(region)
这里提交一个小里程碑: v17-简单绘制
4. 本章小结
本章主要介绍了如何在鸿蒙中通过 CanvasRenderingContext2D 自定义绘制内容。界面就相当于一张白纸、绘制接口方法就相当于画笔,使用已经存在的组件固然简单,但学会自己控制画笔绘制内容可以创造更多的精彩。当然,想要精通绘制也不是一朝一夕可以达成的,但凡工艺技能,都是熟能生巧。
这里只是简单认识了绘制的方式,接下来将结合手势和绘制,完成在手指在界面上拖拽留下痕迹的绘制效果。
另外,现在的数据都是存储在内存中的,应用退出之后无论是选项,还是功德记录都会重置。想要数据持久化存储,在后面的 数据的持久化存储 章节会再继续完善,木鱼项目先告一段落。
更多文章和视频知识资讯,大家可以关注我的公众号、掘金和 B 站 。关注 公众号
并回复 鸿蒙纪元 可领取最新的 xmind 脑图电子版,让我们一起成长,变得更强。我们下次再见~