HarmonyOS - 自定義組件之Slider滑塊
??想了解更多關(guān)于開源的內(nèi)容,請訪問:??
前言
最近在學習HarmonyOS開發(fā)相關(guān)知識,在項目開發(fā)過程中有用到slider滑塊組件,本文主要結(jié)合HarmonyOS官網(wǎng)上的相關(guān)組件以及通用API,實現(xiàn)一個slider滑塊組件。
效果演示
實現(xiàn)原理
1、觸發(fā)條件
基于HarmonyOS通用事件touchstart和touchmove,通過手指剛觸摸屏幕時觸發(fā)、手指觸摸屏幕后移動時觸發(fā)事件。
2、實現(xiàn)slider滑塊效果
通過touches觸摸事件時的屬性集合,返回屏幕觸摸點的信息數(shù)組,拿到localX距離被觸摸組件左上角橫向距離,動態(tài)計算出子元素的寬度來實現(xiàn)slider滑塊效果。
3、實現(xiàn)百分比顯示
通過HarmonyOS通用方法getBoundingClientRect()獲取元素自身的寬度;通過滑動的距離除去元素自身的寬度,來實現(xiàn)滑塊移動的百分比。
使用到的官方API
通用方法
getBoundingClientRect()
獲取元素的大小及其相對于窗口的位置。
屬性 | 類型 | 描述 |
width | number | 該元素的寬度。 |
height | number | 該元素的高度。 |
left | number | 該元素左邊界距離窗口的偏移。 |
top | number | 該元素上邊界距離窗口的偏移。 |
通用事件
名稱 | 參數(shù) | 描述 | 是否支持冒泡 |
touchstart | 手指剛觸摸屏幕時觸發(fā)該事件。 | 是5+ | |
touchmove | 手指觸摸屏幕后移動時觸發(fā)該事件。 | 是5+ |
屬性 | 類型 | 說明 |
touches | Array<TouchInfo> | 觸摸事件時的屬性集合,包含屏幕觸摸點的信息數(shù)組。 |
屬性 | 類型 | 說明 |
globalX | number | 距離屏幕左上角(不包括狀態(tài)欄)橫向距離。屏幕的左上角為原點。 |
globalY | number | 距離屏幕左上角(不包括狀態(tài)欄)縱向距離。屏幕的左上角為原點。 |
localX | number | 距離被觸摸組件左上角橫向距離。組件的左上角為原點。 |
localY | number | 距離被觸摸組件左上角縱向距離。組件的左上角為原點。 |
實現(xiàn)過程
hml部分:
<div class="slider-wrapper">
<div class="progressBox">
<text>
<span>{{progress}}%</span>
</text>
</div>
<div class="content">
<div id="slider" @touchstart="boxChoose" @touchmove="boxChoose" style="width: 300px;">
<div class="slider-main" style="width: {{ width }}"></div>
</div>
<div class="dot" style ="left : {{dotLeft}}"></div>
</div>
<div class="progress" >
<text for="{{ (index,item) in stepArr }}">
{{item}}
</text>
</div>
</div>
css部分:
.slider-wrapper {
width: 100%;
display: flex;
align-items: center;
flex-direction: column;
background-color: bisque;
}
.progressBox{
margin-top:50px ;
display: flex;
justify-content: center;
align-items: center;
}
.content{
width: 300px;
display: flex;
align-items: center;
flex-direction: column;
position: relative;
margin-top: 50px;
}
#slider {
width: 300px;
height: 15px;
background-color: pink;
display: flex;
justify-content: center;
}
.slider-main {
background-color: aqua;
width: 0;
height: 100%;
position: absolute;
left: 0;
top: 0;
}
.dot {
border-radius: 50px;
width: 25px;
height: 25px;
background-color: #fff;
border: 1px solid #409eff;
position: absolute;
top: -5px;
}
.progress{
width: 300px;
display: flex;
justify-content: space-between;
align-items: flex-end;
font-size: 20px;
}
js部分:通過動態(tài)改變子元素width的寬度來實現(xiàn)slider滑塊效果;給小圓dot相對于它父元素設(shè)置為絕對定位,通過動態(tài)改變left的值使圓塊移動,把子元素width的寬度賦值給變量dotLeft,就可以實現(xiàn)小圓跟隨滑塊一起移動的效果。
export default {
data: {
progress:0,//百分比
width: 0,
step1: 1,//步長
stepArr:[0,20,40,60,80,100],
dotLeft:-10
},
boxChoose(e) {
let box = this.$element('slider')
let width = e.touches[0].localX // 獲取點擊時距離容器左邊位置
this.dotLeft = width
let elementWidth = box.getBoundingClientRect().width -10 //元素的寬度 - 小圓的偏移量
// 小圓的偏移量臨界值
if ( this.dotLeft >= elementWidth ) {
this.dotLeft = elementWidth
}
if ( this.dotLeft <= -10 ) {
this.dotLeft = -10
}
let compare = elementWidth / (100 / this.step1) // 根據(jù)步長計算每一步寬度
this.width = Math.ceil(width / compare) * compare
this.progress = Math.round(this.width / elementWidth *100)
//限制臨界值
if(this.progress >= 100){
this.progress = 100
};
if(this.progress <= 0){
this.progress = 0
}
},
}
總結(jié)
這篇文章是我對學習鴻蒙動畫API的一個練習,也算是一個比較常用的組件,后續(xù)部分功能還需完善,比如在樣式、功能方面等等,希望可以和大家共同學習鴻蒙更多的知識,一起進步。