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

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

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

- ctx.beginPath();
 - ctx.ellipse(200, 200, 50, 100, Math.PI * 0.25, Math.PI * 0.5, Math.PI, 1);
 - ctx.stroke();
 
繪制矩形
官方繪制矩形使用rect()方法,此方法功能比較單一,一般我們?cè)谑褂镁匦蔚臅r(shí)候可能會(huì)有圓角的需求,在此項(xiàng)目中并沒(méi)有使用到官方的方法繪制,而是使用lineTo()直線和arc()圓弧兩個(gè)api封裝的一個(gè)可以繪制帶圓角的矩形,詳情可以查看源碼封裝
參數(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í)不管是三次的還是二次的都是使用額外的控制點(diǎn)來(lái)控制線條的走向,線條繪制用到了高階數(shù)學(xué)中的函數(shù)求導(dǎo)的方式來(lái)計(jì)算,因此控制點(diǎn)的具體值不能很快速的能得到精確的結(jié)果,只有不斷的使用和反復(fù)的嘗試才能熟練掌握控制點(diǎn)的設(shè)置。
參數(shù):
示例:
- ctx.beginPath();
 - ctx.moveTo(20, 20);
 - ctx.quadraticCurveTo(100, 100, 200, 20);
 - ctx.stroke();
 
繪制圖片
繪制圖片會(huì)使用到 drawImage() ,單純的繪制圖片其實(shí)意義不大,因?yàn)橛衖mage組件,這個(gè)功能主要作用是能對(duì)圖片在前端進(jìn)行裁剪,而不需要使用到后臺(tái)服務(wù)來(lái)操作。
參數(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主要是對(duì)文字的樣式、大小,粗細(xì),字體系列等進(jìn)行設(shè)置。
參數(shù):
示例:

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



































 
 
 














 
 
 
 