6

HarmonyOS - 自定义组件之Slider滑块-51CTO.COM

 2 years ago
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.
neoserver,ios ssh client

HarmonyOS - 自定义组件之Slider滑块-51CTO.COM

HarmonyOS - 自定义组件之Slider滑块
作者:范乐乐 2022-07-15 16:45:35
本文主要结合HarmonyOS官网上的相关组件以及通用API,实现一个Slider滑块组件。
b89c5893075f26c7f0c83707e096d5bfd2d156.png

​想了解更多关于开源的内容,请访问:​

​51CTO 开源基础软件社区​

​https://ost.51cto.com​

最近在学习HarmonyOS开发相关知识,在项目开发过程中有用到slider滑块组件,本文主要结合HarmonyOS官网上的相关组件以及通用API,实现一个slider滑块组件。

#夏日挑战赛# HarmonyOS - 自定义组件之slider滑块-开源基础软件社区

1、触发条件

基于HarmonyOS通用事件touchstart和touchmove,通过手指刚触摸屏幕时触发、手指触摸屏幕后移动时触发事件。

2、实现slider滑块效果

通过touches触摸事件时的属性集合,返回屏幕触摸点的信息数组,拿到localX距离被触摸组件左上角横向距离,动态计算出子元素的宽度来实现slider滑块效果。

3、实现百分比显示

通过HarmonyOS通用方法getBoundingClientRect()获取元素自身的宽度;通过滑动的距离除去元素自身的宽度,来实现滑块移动的百分比。

使用到的官方API

getBoundingClientRect()

获取元素的大小及其相对于窗口的位置。

width

number

该元素的宽度。

height

number

该元素的高度。

number

该元素左边界距离窗口的偏移。

number

该元素上边界距离窗口的偏移。

是否支持冒泡

touchstart

​TouchEvent​

手指刚触摸屏幕时触发该事件。

touchmove

​TouchEvent​

手指触摸屏幕后移动时触发该事件。

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的一个练习,也算是一个比较常用的组件,后续部分功能还需完善,比如在样式、功能方面等等,希望可以和大家共同学习鸿蒙更多的知识,一起进步。

​想了解更多关于开源的内容,请访问:​

​51CTO 开源基础软件社区​

​https://ost.51cto.com​​。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK