• 热门专题

JavaScript吉光片羽 滑动条

作者:stoneniqiu  发布日期:2016-12-26 20:23:26
Tag标签:JavaScript吉光片羽    滑动条  
  • 灯光的亮度控制需要一个滑动条,先借用lamp源码中Bar:

    var Bar = function (opt) {
        var defaults = {
            $id: '', // 进度条dom节点id
            min: 1, // 刻度最小值
            stepCount: 5, // 刻度步数
            step: 1, // 刻度步长
            $alpha: '',//显示亮度的id
            touchEnd: function () { } // 拖动完成回调
        };
        this.option = $.extend(defaults, opt);
        this.barNode = $('#' + this.option.$id);
        this.parentNode = this.barNode.parents('.J_slider_box');
        this.sliderNode = this.barNode.find('.J_slider');
        this.fillNode = this.barNode.find('.J_fill');
        this.valNode = this.barNode.find('.J_value');
        this.val = this.option.min;
        // this.valNode.text(this.val);
    
        this._init();
        return this;
    }
    Bar.prototype = {
        /**
         * 根据比例值来重新渲染进度条的位置
         * @param ratio 取值:0~1
         */
        refreshPos: function (ratio) {
            if (ratio >= 1 || ratio < 0) { // 等于1时,js的%取值有问题,故排除
                return;
            }
            // 根据触点位置更新进度条
            var percentage = ratio * 100;
            this.sliderNode.css('left', percentage + '%');
            this.fillNode.css('width', percentage + '%');
    
            var unit = 1 / this.option.stepCount,
                halfUnit = unit / 2,
                a = Math.floor(ratio / unit),
                b = ratio % unit,
                index = a + (b < halfUnit ? 0 : 1);
            this.val = this.option.min + index * this.option.step;
            if (this.option.$alpha) {
                $('#' + this.option.$alpha).html(this.val);
            } else {
                this.valNode.text(this.val);
            }
        },
        /**
         * 设置指定的进度值
         */
        setVal: function (val) {
            var ratio = (val - this.option.min) / (this.option.step * this.option.stepCount);
            this.refreshPos(ratio);
        },
        _init: function () {
            var bar = this;
            if (!(bar.barNode.width() > 0)) {
                setTimeout(function () {
                    bar._init();
                }, 100); // 直到vm渲染完成之后才能取得正确的dom高宽
                return;
            }
            bar.leftDis = bar.barNode.offset().left;
            bar.sliderWidth = bar.barNode.width();
    
            bar.barNode.on('touchmove', function (e) {
                e.preventDefault();
                // bar.parentNode.addClass('on');
                var touch = e.changedTouches ? e.changedTouches[0] : e;
                var ratio = (touch.pageX - bar.leftDis) / bar.sliderWidth;
                bar.refreshPos(ratio);
            });
    
            bar.barNode.on('touchend', function (e) {
                e.preventDefault();
                //bar.parentNode.removeClass('on');
                var touch = e.changedTouches ? e.changedTouches[0] : e;
                var ratio = (touch.pageX - bar.leftDis) / bar.sliderWidth;
                bar.refreshPos(ratio);
                bar.option.touchEnd(bar.val);
            });
    
            bar.refreshPos(this.val);
    
        }
    };

    html:

         <div class='lightsider'>
                    <div id='lightsider' class='slider_box J_slider_box'>
                        <i class='slider_box_icon icon dark'></i>
                        <div id='lightBar' class='slider_box_bar'>
                            <div class='slider_box_slider J_slider' style='left:0%'>
                                <p class='slider_box_slider_label J_value'></p>
                                <i class='slider_box_slider_touch'></i>
                            </div>
                            <div class='slider_box_line'>
                                <span class='slider_box_line_fill J_fill' style='width:0%'></span>
                            </div>
                        </div>
                        <i class='slider_box_icon icon light'></i>
                    </div>
                </div>  

    css:

    .slider_box {
      display: -webkit-box;
      display: -webkit-flex;
      display: -ms-flexbox;
      display: flex;
      -webkit-box-align: center;
      -webkit-align-items: center;
          -ms-flex-align: center;
              align-items: center;
    }
    
    .slider_box_icon {
      display: block;
      width: 35px;
      height: 35px;
    }
    .slider_box_bar {
      position: relative;
      margin: 0 10px;
      padding: 33px 0;
      -webkit-box-flex: 1;
      -webkit-flex: 1;
          -ms-flex: 1;
              flex: 1;
    }
    .slider_box_slider {
      position: absolute;
      height: 33px;
      top: 0;
      left: 0;
      z-index: 1;
      -webkit-transform: translate(-50%, 0);
          -ms-transform: translate(-50%, 0);
              transform: translate(-50%, 0);
    }
    
    .slider_box_slider_touch {
      position: absolute;
      left: 50%;
      bottom: -11px;
      margin-left: -8px;
      width: 20px;
      height: 20px;
      border-radius: 15px;
      background-color: white;
        border: 1px solid rgb(195, 194, 194);
    }
    .slider_box_line {
      position: relative;
      height: 4px;
      border-radius: 4px;
      background-color: rgb(195, 194, 194);
    }
    .slider_box_line_fill {
      position: absolute;
      top: 0;
      left: 0;
      height: 4px;
      background-color: gold;
      border-radius: 4px;
    }

    JavaScript 调用:

       var bar = new Bar({ $id: 'lightsider', stepCount: 100, min: 0, $alpha: 'alpha' });

    stepCount相当于最大长度。$alpha用来显示亮度值。效果如下

    主要的原理就是监听 touchmove事件,通过移动的pageX减去圆点左边的位置除以滑动条的总长度得到比率,最后换算成step

       bar.leftDis = bar.barNode.offset().left;
            bar.sliderWidth = bar.barNode.width();
    
            bar.barNode.on('touchmove', function (e) {
                e.preventDefault();
                // bar.parentNode.addClass('on');
                var touch = e.changedTouches ? e.changedTouches[0] : e;
                var ratio = (touch.pageX - bar.leftDis) / bar.sliderWidth;
                bar.refreshPos(ratio);
            });

    如果是竖着的滑动条呢? 暂且定义一个UpBar对象:

    var UpBar = function (opt) {
        var defaults = {
            $id: '', // 进度条dom节点id
            min: 1, // 刻度最小值
            stepCount: 5, // 刻度步数
            step: 1, // 刻度步长
            $alpha: '',//显示亮度的id
            touchEnd: function () { } // 拖动完成回调
        };
        this.option = $.extend(defaults, opt);
        this.barNode = $('#' + this.option.$id);
        this.parentNode = this.barNode.parents('.J_slider_box');
        this.sliderNode = this.barNode.find('.J_slider');
        this.fillNode = this.barNode.find('.J_fill');
        this.valNode = this.barNode.find('.J_value');
        this.val = this.option.min;
        // this.valNode.text(this.val);
    
        this._init();
        return this;
    }
    UpBar.prototype = {
        /**
         * 根据比例值来重新渲染进度条的位置
         * @param ratio 取值:0~1
         */
        refreshPos: function (ratio) {
            if (ratio >= 1 || ratio < 0) { // 等于1时,js的%取值有问题,故排除
                return;
            }
            // 根据触点位置更新进度条
            var percentage = ratio * 100;
            this.sliderNode.css('bottom', percentage + '%');
            this.fillNode.css('height', percentage + '%');
    
            var unit = 1 / this.option.stepCount,
                halfUnit = unit / 2,
                a = Math.floor(ratio / unit),
                b = ratio % unit,
                index = a + (b < halfUnit ? 0 : 1);
            this.val = this.option.min + index * this.option.step;
            if (this.option.$alpha) {
                $('#' + this.option.$alpha).html(this.val);
            } else {
              //  this.valNode.text(this.val);
            }
        },
        /**
         * 设置指定的进度值
         */
        setVal: function (val) {
            var ratio = (val - this.option.min) / (this.option.step * this.option.stepCount);
            this.refreshPos(ratio);
        },
        _init: function () {
            var bar = this;
            if (!(bar.barNode.height() > 0)) {
                setTimeout(function () {
                    bar._init();
                }, 100); // 直到vm渲染完成之后才能取得正确的dom高宽
                return;
            }
            bar.topDis = bar.barNode.offset().top;
            bar.sliderHeight = bar.barNode.height();
    
            bar.barNode.on('touchmove', function (e) {
                e.preventDefault();
                var touch = e.changedTouches ? e.changedTouches[0] : e;
                var ratio =1- (touch.pageY - bar.topDis) / bar.sliderHeight;
                bar.refreshPos(ratio);
            });
    
            bar.barNode.on('touchend', function (e) {
                e.preventDefault();
                var touch = e.changedTouches ? e.changedTouches[0] : e;
                var ratio =1- (touch.pageY - bar.topDis) / bar.sliderHeight;
                bar.refreshPos(ratio);
                bar.option.touchEnd(bar.val);
            });
    
            bar.refreshPos(this.val);
    
        }
    };

    css:

    .slider_box_slider_up {
      position: absolute;
      width: 33px;
      top: 0;
      right: -20px;
      z-index: 1;
      -webkit-transform: translate(-50%, 0);
          -ms-transform: translate(-50%, 0);
              transform: translate(-50%, 0);
    }
    .slider_box_slider_touch_up {
      position: absolute;
      width: 20px;
      height: 20px;
        bottom: -10px;
        left: 0;
      border-radius: 15px;
      background-color: white;
        border: 1px solid rgb(195, 194, 194);
    }
    .slider_box_line_up {
      width: 4px;
        height: 100%;
      border-radius: 4px;
      position: relative;
        margin: 0 auto;
      background-color: rgb(195, 194, 194);
    }
    .slider_box_line_fill_up {
      position: absolute;
      bottom:0;
      left: 0;
      width: 4px;
      background-color: gold;
      border-radius: 4px;
    }

    html:

     <div class='soundBar'>
                    <div id='soundBar' class='slider_box_up J_slider_box'>
                        <div class='slider_box_line_up'>
                            <span class='slider_box_line_fill_up J_fill' style='height: 0%'></span>
                        </div>
                        <div class='slider_box_slider_up J_slider' style='bottom: 0%'>
                            <i class='slider_box_slider_label J_value'></i>
                            <i class='slider_box_slider_touch_up'></i>
                        </div>
                    </div>
                </div>

    调用:

      var bar = new UpBar({ $id: 'soundBar', stepCount: 100, min: 0 });

    效果如下:

    主要的区别是left-->bottom,width-->height,另外一个因为y轴是以左上角为0,0的,touch.pageY越往下越大,所以算比率的时候用要这样:

     bar.topDis = bar.barNode.offset().top;
            bar.sliderHeight = bar.barNode.height();
            bar.barNode.on('touchmove', function (e) {
                e.preventDefault();
                var touch = e.changedTouches ? e.changedTouches[0] : e;
                var ratio =1- (touch.pageY - bar.topDis) / bar.sliderHeight;
                bar.refreshPos(ratio);
            });

    有兴趣也可以合二为一。

About IT165 - 广告服务 - 隐私声明 - 版权申明 - 免责条款 - 网站地图 - 网友投稿 - 联系方式
本站内容来自于互联网,仅供用于网络技术学习,学习中请遵循相关法律法规