常見的長按事件onlongpress不能設(shè)定長按的時(shí)間,除此之外,綁定了長按事件的按鈕在完成長按操作前后并沒有明顯的樣式變化,用戶無法從中得到長按操作進(jìn)行的反饋,在有此類需求的場(chǎng)景時(shí)是無法滿足的。

??想了解更多關(guān)于開源的內(nèi)容,請(qǐng)?jiān)L問:??
??51CTO 開源基礎(chǔ)軟件社區(qū)??
??https://ost.51cto.com??
前言
今天給大家分享下我個(gè)人在學(xué)習(xí)鴻蒙應(yīng)用開發(fā)初期寫的一個(gè)小組件,希望能幫助大家學(xué)習(xí)如何完成一個(gè)自定義組件。
組件介紹
常見的長按事件onlongpress不能設(shè)定長按的時(shí)間,除此之外,綁定了長按事件的按鈕在完成長按操作前后并沒有明顯的樣式變化,用戶無法從中得到長按操作進(jìn)行的反饋,在有此類需求的場(chǎng)景時(shí)是無法滿足的。因此我根據(jù)這些需求開發(fā)一個(gè)自定義長按按鈕組件,同時(shí)兼顧按鈕和進(jìn)度條兩個(gè)功能。最初的設(shè)計(jì)圖如下:

項(xiàng)目結(jié)構(gòu)

組件開發(fā)
頁面布局:使用stack棧布局,以canvas畫布做背景,button按鈕組件在上。
<stack class="stack-parent">
<canvas ref="canvas1" class="my-canvas"></canvas>
<button type="circle" style="radius: ` divR `; background-color: ` btnColor `;"
disabled="` disabled `" ontouchstart="Show" ontouchend="Erase"></button>
</stack>
組件屬性參數(shù)設(shè)置
參數(shù)名
| 描述
| 參數(shù)類型
| 默認(rèn)值
|
duration
| 長按事件觸發(fā)時(shí)長
| Number
| 2000
|
btnColor
| 按鈕顏色
| String
| #9D9D9D
|
ringColor
| 長按過程中外圈顏色
| String
| #82D900
|
finishColor
| 事件就緒時(shí)外圈陰影顏色
| String
| #FFFF37
|
動(dòng)作拆解:在按鈕上綁定ontouchstart事件和ontouchend事件,以實(shí)現(xiàn)長按操作。
- 點(diǎn)擊動(dòng)作:點(diǎn)擊時(shí)顯示外圈,按鈕逐漸變大,直至達(dá)到設(shè)定時(shí)長膨脹至最大。
Show() {
//打印按鈕當(dāng)前狀態(tài)為“正在點(diǎn)擊”
this.$emit('btnType', {btnstate: '點(diǎn)擊'});
console.log("————按鈕狀態(tài):點(diǎn)擊中————");
const el = this.$refs.canvas1;
const ctx = el.getContext('2d', { antialias: true });
//畫外圈,用于提示長按進(jìn)度
ctx.lineWidth = 5;
ctx.strokeStyle = this.ringColor;
ctx.beginPath();
ctx.arc(150, 150, 100, 0, 6.28);
ctx.stroke();
console.log("外圈顯現(xiàn),按鈕膨脹");
//膨脹動(dòng)畫
let options1 = {
duration: this.duration, //運(yùn)行時(shí)間
easing: 'linear', //動(dòng)畫時(shí)間曲線
fill: 'forwards', //指定動(dòng)畫起始態(tài)或終止態(tài)
iterations: 1, //播放次數(shù)
begin: 50.0, //播放起點(diǎn)
end: 100.0, //播放終點(diǎn)
}
this.animator.update(options1);
let _this = this;
this.animator.onframe = function(value) {
_this.divR = value;
//外部色圈顯現(xiàn),提示啟動(dòng)事件準(zhǔn)備就緒
if(100 == _this.divR) {
ctx.beginPath();
ctx.arc(150, 150, 120, 0, 6.28);
ctx.shadowBlur = 1;
ctx.shadowColor = _this.finishColor;
ctx.stroke();
console.log("準(zhǔn)備就緒,松開觸發(fā)");
}
};
this.animator.play();
},- 松開動(dòng)作:長按達(dá)到設(shè)定時(shí)間,生成外圈陰影,松開即可啟動(dòng)事件;若中途松開,按鈕瞬間恢復(fù)到初始狀態(tài)。
Erase() {
//打印按鈕當(dāng)前狀態(tài)為“松開”
this.$emit('btnType', {btnstate: '松開'});
console.log("————按鈕狀態(tài):松開————");
//重置動(dòng)畫
let options2 = {
duration: 0, //運(yùn)行時(shí)間
easing: 'linear', //動(dòng)畫時(shí)間曲線
fill: 'forwards', //指定動(dòng)畫起始態(tài)或終止態(tài)
iterations: 1, //播放次數(shù)
end: 50.0, //播放終點(diǎn)為初始起點(diǎn)
}
this.animator.update(options2);
let _this = this;
this.animator.onframe = function(value) {
_this.divR = value;
};
//成功啟動(dòng)事件
if(100 == _this.divR) {
this.disabled = true; //按鈕失效,不可點(diǎn)擊
//向父組件傳遞事件的狀態(tài)值為true
this.$emit('eventType', {eventstate: true});
console.log("啟動(dòng)成功");
}
//啟動(dòng)失敗,擦除提示外圈
else {
const el = this.$refs.canvas1;
const ctx = el.getContext('2d');
ctx.clearRect(45, 45, 210, 210);
console.log("啟動(dòng)失敗")
console.log("外圈擦除,按鈕重置");
}
},組件引用
<element name="swellbtn" src='common/swellbtn/swellbtn.hml'></element>
<swellbtn duration="1000" btn-color="#A39CC9" ring-color="#FFD800" finish-color="#FFFF37"
@btn-type="btnClicked" @event-type="eventState"></swellbtn>
- 注意,在官方文檔中對(duì)在父組件中綁定子組件的事件方法或?qū)傩悦麜r(shí),有以下要求:

最終效果

結(jié)語
自定義組件開發(fā)的意義在于解決某些特定場(chǎng)景的需求,該組件的開發(fā)難度較低,希望這篇文章能幫助大家理解自定義組件設(shè)計(jì)和開發(fā)的流程。
文章相關(guān)附件可以點(diǎn)擊下面的原文鏈接前往下載:
https://ost.51cto.com/resource/2353。
??想了解更多關(guān)于開源的內(nèi)容,請(qǐng)?jiān)L問:??
??51CTO 開源基礎(chǔ)軟件社區(qū)??
??https://ost.51cto.com??。