OpenHarmony - ArkUI(TS)聲明式開發(fā)之畫板
??想了解更多關(guān)于開源的內(nèi)容,請(qǐng)?jiān)L問:??
項(xiàng)目介紹
本項(xiàng)目基于??OpenHarmony???的ArkUI框架:TS擴(kuò)展的聲明式開發(fā)范式,關(guān)于語法和概念直接看官網(wǎng)官方文檔地址:??基于TS擴(kuò)展的聲明式開發(fā)范式??,因?yàn)镺penHarmony的API相對(duì)于HarmonyOS的API,功能上比較完善和成熟的,有些新的技術(shù)也早早接觸到,所以本項(xiàng)目直接使用OpenHarmony SDK開發(fā)。
工具版本: DevEco Studio 3.0 Beta4。
SDK版本: 3.1.6.6(API Version 8 Release)。
項(xiàng)目功能: 1、畫筆功能:可設(shè)置畫筆粗細(xì)和顏色;2、橡皮擦功能:可設(shè)置粗細(xì);3、撤回和回撤功能;4:清空畫板功能。
文件說明
效果演示
用到的API
畫布組件canvas:畫布組件,用于自定義繪制圖形。
方法/屬性 | 解釋 |
beginPath() | 創(chuàng)建一個(gè)新的繪制路徑 |
moveTo() | 路徑從當(dāng)前點(diǎn)移動(dòng)到指定點(diǎn) |
lineTo() | 從當(dāng)前點(diǎn)到指定點(diǎn)進(jìn)行路徑連接 |
stroke() | 進(jìn)行邊框繪制操作 |
clearRect() | 清空畫布 |
strokeStyle | 屬性:設(shè)置描邊的顏色 |
lineWidth | 屬性:設(shè)置繪制線條的寬度 |
globalCompositeOperation | 屬性:設(shè)置合成操作的方式 |
實(shí)現(xiàn)思路
1、畫筆功能
使用onTouch方法,監(jiān)聽觸摸事件,手指按下:使用方法moveTo記錄起點(diǎn),手指移動(dòng):使用方法beginPath創(chuàng)建新的路徑,lineTo記錄移動(dòng)的點(diǎn),并繪制。
(代碼片段,詳細(xì)請(qǐng)查看源碼):
/**
* 觸摸事件
*/
onTouchEvent(event: TouchEvent) {
// x坐標(biāo)
const x = event.touches[0].x
// y坐標(biāo)
const y = event.touches[0].y
switch (event.type) {
case TouchType.Down: // 手指按下
{
// 創(chuàng)建一個(gè)新的繪制路徑
this.crc.beginPath()
// 設(shè)置起點(diǎn)坐標(biāo)
this.crc.moveTo(x, y)
}
break;
case TouchType.Move: // 手指移動(dòng)
case TouchType.Up: // 手指抬起
{
// 設(shè)置移動(dòng)點(diǎn)
this.crc.lineTo(x, y)
// 進(jìn)行路徑繪制
this.crc.stroke()
}
break;
default:
break;
}
}
2、橡皮擦功能
設(shè)置繪制屬性:globalCompositeOperation。
畫筆設(shè)置此屬性值: source-over (默認(rèn)值 在現(xiàn)有繪制內(nèi)容上顯示新繪制內(nèi)容),橡皮擦設(shè)置此屬性值: destination-out ( 在新繪制內(nèi)容外顯示現(xiàn)有繪制內(nèi)容)。
// 新內(nèi)容在之前內(nèi)容的之上
this.crc.globalCompositeOperation = 'source-over'
// 新內(nèi)容與之前內(nèi)容相交位置變透明
this.crc.globalCompositeOperation = 'destination-out'
3、撤回和回撤功能
數(shù)據(jù)類,記錄每次繪制的信息,線顏色、寬度、坐標(biāo)點(diǎn)集合,每次畫完保存到數(shù)組中。
/**
* 繪制信息
* @param lineColor 線顏色
* @param lineWidth 線寬度
* @param listCoord 坐標(biāo)點(diǎn)集合
*/
export class DrawInfoModel {
// 是否為畫筆,是:畫筆,否:橡皮擦
// 根據(jù)此字段設(shè)置繪制屬性:合成操作globalCompositeOperation
isPen: boolean;
// 線顏色
lineColor: string;
// 線寬度
lineWidth: number;
// 坐標(biāo)點(diǎn)集合
listCoord: Array<Coord>;
constructor(isPen: boolean, lineColor: string, lineWidth: number, listCoord: Array<Coord>) {
this.isPen = isPen;
this.lineColor = lineColor;
this.lineWidth = lineWidth;
this.listCoord = listCoord;
}
}
/**
* 坐標(biāo)點(diǎn)
* @param x 坐標(biāo)點(diǎn)x
* @param y 坐標(biāo)點(diǎn)y
*/
export class Coord {
// 坐標(biāo)點(diǎn)x
x: number;
// 坐標(biāo)點(diǎn)y
y: number;
constructor(x: number, y: number) {
this.x = x;
this.y = y;
}
}
每次繪制的信息,保存在數(shù)組中,在點(diǎn)擊撤回時(shí),撤回?cái)?shù)+1;回撤時(shí),撤回?cái)?shù)-1,并截取數(shù)組,清空畫布,遍歷數(shù)組繪制筆畫信息。
(代碼片段,詳細(xì)請(qǐng)查看源碼):
/**
* 撤回
*/
revocation() {
this.listTempXY = this.listAllXY
// 根據(jù)撤回的個(gè)數(shù),截取數(shù)組
this.listTempXY = this.listTempXY.slice(0, this.listTempXY.length - this.revocationNumber)
// 清空畫布
this.crc.clearRect(0, 0, this.canvasWidth, this.canvasHeight)
// 拼接筆畫路徑
for (const drawInfo of this.listTempXY) {
// 創(chuàng)建一個(gè)新的繪制路徑
this.crc.beginPath()
// 設(shè)置線顏色
this.crc.strokeStyle = drawInfo.lineColor
// 設(shè)置線寬度
this.crc.lineWidth = drawInfo.lineWidth
// 設(shè)置繪制的坐標(biāo)點(diǎn)
for (let i = 0;i < drawInfo.listCoord.length; i++) {
const coord = drawInfo.listCoord[i]
// 第一個(gè)設(shè)置為起點(diǎn)
if (i === 0) {
this.crc.moveTo(coord.x, coord.y)
} else {
this.crc.lineTo(coord.x, coord.y)
}
}
// 進(jìn)行路徑繪制
this.crc.stroke()
}
}
總結(jié)
此項(xiàng)目并沒有特別復(fù)雜的地方,注釋也很詳細(xì),以上列出的代碼都是實(shí)現(xiàn)主要的功能,其他細(xì)節(jié)請(qǐng)查看源碼,最后不得不感慨聲明式語法的強(qiáng)大和簡潔性,完成此功能相對(duì)于使用JS來實(shí)現(xiàn)效率提升很高,也希望鴻蒙社區(qū)越來越好,融入更多的熱愛者。