HarmonyOS JS UI 自定義icon組件
51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)
背景及簡介
在HarmonyOS JS UI官方提供的組件中沒有圖標(biāo)組件,要使用圖標(biāo)的話需要使用image組件引入圖片資源,如果圖標(biāo)狀態(tài)或者樣式需要改變時,就需要使用另一張圖片來替換,操作起來比較麻煩。移動端使用圖標(biāo)的場景會比較多,如果全部使用圖片來實現(xiàn)效果,會增加很多圖片資源引用,對于代碼開發(fā)也會有很多的不便,在此背景下想能實現(xiàn)一個圖標(biāo)的組件,能夠自定義樣式便于修改和引用,也能動態(tài)的切換圖標(biāo)樣式。
此項目使用官方的 badge 組件和 canvas 組件來實現(xiàn)圖標(biāo)的繪制,通過封裝自定義組件,可以對組件大小、樣式、背景、角標(biāo)、禁用等屬性進(jìn)行配置,從而實現(xiàn)圖標(biāo)的繪制,此自定義組件完全使用代碼實現(xiàn),沒有引用任何外部資源或文件,可以很方便的被各種項目引用。
項目介紹
- 項目名稱:OpenHarmony-JS-Icon
- 項目源地址:https://gitee.com/chenqiao002/open-harmony-js-icon
- 所屬系列:OpenHarmony下的的JS 自定義組件開發(fā)示例
- 開發(fā)版本:OpenHarmony-SDK-6,DevEco Studio 2.2.0.200
- 項目作者和維護(hù)人:陳喬
- 郵箱:chenqiao002@chinasoftinc.com
- 本示例基于OpenHarmony下的JavaScript UI框架,通過使用常用組件、畫布組件和自定義組件等來實現(xiàn)一個自定義的icon組件,通過本示例可以基本了解和使用該組件。
- 本項目是基于OpenHarmony項目而不是HarmonyOS項目,請注意運行環(huán)境。
- 請參考OpenHarmony項目配置方法進(jìn)行項目配置和運行。
- 如果你不熟悉OpenHarmony的JS開發(fā),請參考該項目的開發(fā)講解。
文件目錄
在Pages目錄下,只有一個index首頁,在首頁中展示了icon自定義組件的使用樣例。
在common文件夾下的icon文件夾是自定義的icon組件,在icon文件夾中js文件夾是icon繪制使用到的方法和數(shù)據(jù)。
使用說明
項目預(yù)覽
下載OpenHarmony-JS-Icon項目,啟動 DevEco Studio并打開工程。
進(jìn)入entry->src->main->js->default->pages->index,打開index.hml點擊Previewer進(jìn)行預(yù)覽。
引入
在index.hml的第一行,引用自定義組件,這里我們將name屬性設(shè)置為icon。
- <element src="../../common/icon/icon.hml" name="icon"></element>
基礎(chǔ)用法
通過設(shè)置icon組件的name屬性來展示不同的圖標(biāo)。
- <icon name="chat_o" size="48"></icon>
角標(biāo)提示
通過設(shè)置icon組件的badge-config屬性來對角標(biāo)信息進(jìn)行設(shè)置。
- <icon name="chat_o" size="48" badge-config="{{ badgeConfig }}"></icon>
- badgeConfig: {
- config: {
- badgeColor: "#0a59f7",
- textColor: "#ffffff",
- },
- count: 0,
- visible: true,
- },
圖標(biāo)顏色和背景顏色
通過設(shè)置icon組件的color屬性來設(shè)置,background-color可以設(shè)置圖標(biāo)的背景顏色。
- <icon name="chat_o" size="48" color="#ED6F21" background-color="#ddddddd" ></icon>
圖標(biāo)大小
通過設(shè)置icon組件的size屬性來控制圖標(biāo)的大小。
- <icon name="chat_o" size="24"></icon>
圖標(biāo)禁用
通過設(shè)置icon組件的disabled屬性控制圖標(biāo)是否禁用,disabled默認(rèn)為false,禁用狀態(tài)設(shè)置為true時圖標(biāo)為灰色,color和badge-config屬性只有在disabled為false時生效。
- <icon name="chat_o" disabled="true" onclick="iconClick" color="red" size="48" badge-config="{{ badgeConfig }}"></icon>
圖片繪制
通過設(shè)置icon組件的name屬性設(shè)置為圖片的地址。
- <icon name="common/images/huawei.png" size="48"></icon>
API
props
代碼示例:
- export default {
- props: {
- // icon 名稱
- name: {
- default: ''
- },
- // icon 樣式前綴
- classPrefix: {
- default: 'hos-icon'
- },
- // icon 尺寸
- size: {
- default: 24,
- },
- // icon 顏色
- color: {
- default: "#333333"
- },
- // icon 背景顏色
- backgroundColor: {
- default: "#ffffff"
- },
- // 角標(biāo)配置
- badgeConfig: {
- default: {
- config: {
- badgeColor: "#0a59f7",
- textColor: "#ffffff",
- },
- placement: "rightTop",
- count: 0,
- maxcount: 99,
- visible: false,
- label: "",
- }
- },
- // icon 圖標(biāo)禁用
- disabled: {
- default: false
- },
- // icon 點擊方法攜帶的參數(shù)
- dataClick: {
- default: null
- }
- }
- }
Events
代碼示例:
hml文件,icon組件綁定點擊事件和綁定點擊實現(xiàn)參數(shù):
- <icon name="fail" size="48" onclick="iconClick" data-click="點擊fail圖標(biāo)" ></icon>
js文件,在iconClick方法上接收參數(shù)的detail屬性為綁定的數(shù)據(jù):
- iconClick(data) {
- console.log("iconClick");
- console.log(data.detail);
- }
執(zhí)行結(jié)果:
繪制原理
所有的圖標(biāo)繪制均是基于HarmonyOS JS API 畫布組件 來實現(xiàn)的,根據(jù)官方提供的繪制方法自定義封裝繪制圖形,基本實現(xiàn)了以下幾種基礎(chǔ)圖形繪制的封裝。
繪制直線
直線的繪制主要用到了lineTo(x,y)方法,下面示例中的 ctx.beginPath() 是創(chuàng)建一個新的繪制路徑,ctx.moveTo(10, 10) 是當(dāng)前路徑起始點移動到指定點,ctx.lineTo(280, 160)則是繪制直線到終止點,ctx.stroke()是進(jìn)行邊框繪制操作,每次畫布繪制都是一條透明的路徑,沒有stroke的話是不會顯示繪制的路徑的;
參數(shù):
示例:

- ctx.beginPath();
- ctx.moveTo(10, 10);
- ctx.lineTo(280, 160);
- ctx.stroke();
繪制圓弧
繪制圓弧有兩個api,arc() 和 arcTo() ,其中我們主要看看arc(x,y,radius,startAngle,endAngle,anticlockwise)方法是如何繪制圓弧的。
參數(shù):
示例:

- ctx.beginPath();
- ctx.arc(100, 75, 50, 0, 6.28);
- ctx.stroke();
繪制橢圓弧
繪制橢圓弧使用 ellipse() ,下面示例中繪制了一段橢圓弧,但是在實際操作中我發(fā)現(xiàn),如果是繪制一個完整的橢圓,startAngle設(shè)置為Math.PI * 0,endAngle設(shè)置為Math.PI * 2 并不能繪制一個完整的橢圓,畫布上什么也沒畫,在此我是使用一個中間角度然后調(diào)用兩次ellipse()方法才得到一個完整的圓弧,不知道有沒有大佬遇到過相同的問題或者知道根本原因能交流一下。
參數(shù):
示例:

- ctx.beginPath();
- ctx.ellipse(200, 200, 50, 100, Math.PI * 0.25, Math.PI * 0.5, Math.PI, 1);
- ctx.stroke();
繪制矩形
官方繪制矩形使用rect()方法,此方法功能比較單一,一般我們在使用矩形的時候可能會有圓角的需求,在此項目中并沒有使用到官方的方法繪制,而是使用lineTo()直線和arc()圓弧兩個api封裝的一個可以繪制帶圓角的矩形,詳情可以查看源碼封裝
參數(shù):
示例:

- ctx.rect(20, 20, 100, 100); // Create a 100*100 rectangle at (20, 20)
- ctx.stroke(); // Draw it
繪制三次貝賽爾曲線
三次貝賽爾曲線的繪制主要用到了bezierCurveTo()
參數(shù):
- ctx.beginPath();
- ctx.moveTo(20, 20);
- ctx.quadraticCurveTo(100, 100, 200, 20);
- ctx.stroke();
繪制二次貝賽爾曲線
二次貝賽爾曲線的繪制主要用到了quadraticCurveTo() ,其實不管是三次的還是二次的都是使用額外的控制點來控制線條的走向,線條繪制用到了高階數(shù)學(xué)中的函數(shù)求導(dǎo)的方式來計算,因此控制點的具體值不能很快速的能得到精確的結(jié)果,只有不斷的使用和反復(fù)的嘗試才能熟練掌握控制點的設(shè)置。
參數(shù):
示例:
- ctx.beginPath();
- ctx.moveTo(20, 20);
- ctx.quadraticCurveTo(100, 100, 200, 20);
- ctx.stroke();
繪制圖片
繪制圖片會使用到 drawImage() ,單純的繪制圖片其實意義不大,因為有image組件,這個功能主要作用是能對圖片在前端進(jìn)行裁剪,而不需要使用到后臺服務(wù)來操作。
參數(shù):
示例:

- var test = this.$element('drawImage');
- var ctx = test.getContext('2d');
- var img = new Image();
- img.src = 'common/image/test.jpg';
- ctx.drawImage(img, 50, 80, 80, 80);
繪制文字
文字繪制使用fillText()方法,其中ctx.font主要是對文字的樣式、大小,粗細(xì),字體系列等進(jìn)行設(shè)置。
參數(shù):
示例:

- ctx.font = '35px sans-serif';
- ctx.fillText("Hello World!", 20, 60);
以上就是本項目主要使用到的幾種api,為了便于圖標(biāo)數(shù)據(jù)結(jié)構(gòu)的清晰配置,所有的api都經(jīng)過了二次封裝,數(shù)據(jù)結(jié)構(gòu)和封裝結(jié)果可以查看項目源碼。
注意事項
- 可以使用角標(biāo),使用時需將所有的badge屬性作為一個對象用badge-config名稱傳入,這個用法參考了官方badge組件。
- 可以繪制圖片,在name屬性上設(shè)置圖片路徑,路徑必須是絕對路徑或者云路徑,不能使用"./“或者”…/"等開頭的相對路徑,而且圖片尺寸需和icon的size值一樣,不然可能會導(dǎo)致繪制不完整,官方有image組件,這個功能有點雞肋。
- 雖然圖標(biāo)顏色可以設(shè)置透明色,但是不建議設(shè)置透明色,透明色可能會導(dǎo)致部分圖標(biāo)繪制的效果與預(yù)期相差較大。
- 圖標(biāo)的形式參考了市面上主流的圖標(biāo)形式,全部的圖標(biāo)繪制均為canvas繪制,無任何代碼參考,使用的api均為鴻蒙JS UI官方api。
- 圖標(biāo)繪制使用的是canvas,雖然在一些特別細(xì)節(jié)的地方可能還比不上矢量圖標(biāo)清晰度,但是此庫理論上可以實現(xiàn)任意圖標(biāo),大家有需求或者有新的圖標(biāo)需要繪制的請評論留言,謝謝。
- 目前圖標(biāo)已繪制了230+,已基本完成計劃實現(xiàn)的圖標(biāo),還會繼續(xù)更新,敬請關(guān)注。
- 此項目使用canvas繪制圖標(biāo),其實圖標(biāo)可以參考自定義字體樣式來實現(xiàn)字體圖標(biāo),相對來說字體圖標(biāo)文件更小、圖標(biāo)更清晰、也更利于更新管理,有需要的可以看看Vant Openharmony
51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)