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