HarmonyOS - 自定义组件之Slider滑块-51CTO.COM
source link: https://os.51cto.com/article/714155.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
HarmonyOS - 自定义组件之Slider滑块-51CTO.COM
最近在学习HarmonyOS开发相关知识,在项目开发过程中有用到slider滑块组件,本文主要结合HarmonyOS官网上的相关组件以及通用API,实现一个slider滑块组件。
1、触发条件
基于HarmonyOS通用事件touchstart和touchmove,通过手指刚触摸屏幕时触发、手指触摸屏幕后移动时触发事件。
2、实现slider滑块效果
通过touches触摸事件时的属性集合,返回屏幕触摸点的信息数组,拿到localX距离被触摸组件左上角横向距离,动态计算出子元素的宽度来实现slider滑块效果。
3、实现百分比显示
通过HarmonyOS通用方法getBoundingClientRect()获取元素自身的宽度;通过滑动的距离除去元素自身的宽度,来实现滑块移动的百分比。
使用到的官方API
getBoundingClientRect()
获取元素的大小及其相对于窗口的位置。
width | number | 该元素的宽度。 |
height | number | 该元素的高度。 |
number | 该元素左边界距离窗口的偏移。 | |
number | 该元素上边界距离窗口的偏移。 |
是否支持冒泡 | |||
touchstart | 手指刚触摸屏幕时触发该事件。 | ||
touchmove | 手指触摸屏幕后移动时触发该事件。 |
touches | Array<TouchInfo> | 触摸事件时的属性集合,包含屏幕触摸点的信息数组。 |
globalX | number | 距离屏幕左上角(不包括状态栏)横向距离。屏幕的左上角为原点。 |
globalY | number | 距离屏幕左上角(不包括状态栏)纵向距离。屏幕的左上角为原点。 |
localX | number | 距离被触摸组件左上角横向距离。组件的左上角为原点。 |
localY | number | 距离被触摸组件左上角纵向距离。组件的左上角为原点。 |
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部分:通过动态改变子元素width的宽度来实现slider滑块效果;给小圆dot相对于它父元素设置为绝对定位,通过动态改变left的值使圆块移动,把子元素width的宽度赋值给变量dotLeft,就可以实现小圆跟随滑块一起移动的效果。
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) // 根据步长计算每一步宽度
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
}
},
}
这篇文章是我对学习鸿蒙动画API的一个练习,也算是一个比较常用的组件,后续部分功能还需完善,比如在样式、功能方面等等,希望可以和大家共同学习鸿蒙更多的知识,一起进步。
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK