美文网首页Vue.jsangular2与vue的那些事Vue.js 资料
vue自定义js图片碎片轮播图切换效果

vue自定义js图片碎片轮播图切换效果

作者: 阿踏 | 来源:发表于2019-01-11 13:55 被阅读4次

    定义一个banner.js文件,代码如下

    ;window.requestAnimationFrame = window.requestAnimationFrame||function(a){return setTimeout(a,1000/60)};
    window.cancelAnimationFrame = window.cancelAnimationFrame||clearTimeout;
    var FragmentBanner = function(option) {
    
        //实例化时,可传的参数
        this.whiteList = ['container','controller','size','imgs','size','grid','index','fnTime','boxTime','type'];
    
        //容器将包容控制器
        this.container = '.banner';
        
        //默认的控制器
        this.controller = {
            view : '.banner-view',
            btn : '.banner-btn',
            num : '.banner-number',
            progre : '.banner-progres'
        };
    
        //栅格 行*列
        this.grid = {
            line : 5,
            list : 10
        };
    
        //容器的大小
        this.size = {
            width : 1200,
            height : 675,
        };
    
        //切换类型
        this.type = 1;
    
        //索引位置
        this.index = 0;
    
        //函数每次切换时间
        this.fnTime = 5000;
    
        //栅格每次运动时间
        this.boxTime = 2000;
    
        //栅格运动结束的时间
        this.activeTime = new Date();
    
        for(var a = 0,attrLenght = this.whiteList.length; a < attrLenght;a++){
    
            var attr = this.whiteList[a];
            if(option[attr] != undefined){
    
                this[attr] = option[attr];
            }
        }
        for(var i in option){
    
            if(this.whiteList[i] !== undefined){ ; }
        }
    
        init();
    }
    function setIndex(){
    
        this.index %= this.imgs.length;
        
        this.index = (this.index < 0) ? this.imgs.length - 1 : this.index;
    
        this.elem.numFind[this.index].className = 'on'; 
    }
    function init(){
    
        this.container = document.querySelector(this.container)
        if(!this.container){
    
            return alert('获取banner容器失败');
        }else{
    
            this.container.style.width = this.size.width+'px';
            this.container.style.height = this.size.height+'px';
        }
        
        this.elem = {};
        for(var e in this.controller){
    
            this.elem[e] = this.container.querySelector(this.controller[e]);
            if(this.elem[e] == null){
    
                return alert('获取'+e+'容器');
            }
        }
    
        //栅格
        var w = this.size.width / this.grid.list,
            h = this.size.height / this.grid.line;
    
        this.elem.viewBox = new Array();
        for(var i = 0,iL = this.grid.line;i < iL;i++){
    
            for(var j = 0,jL = this.grid.list;j < jL;j++){
    
                var newI = document.createElement('i');
    
                setCss(newI,{
                    width : w+'px',
                    height : h+'px',
                    left : 0,
                    top : 0,
                    opacity : 1,
                    backgroundImage : 'url("'+this.imgs[this.index]+'")',
                    backgroundSize : this.size.width + 'px ' + this.size.height +'px',
                    backgroundPosition : w * -j+'px ' + h * -i+'px'
                });
                
                this.elem.view.appendChild(newI);
                this.elem.viewBox.push(newI);
            }
        }
    
        //按钮动作
        for (var b = 1; b >= 0; b--) {
            
            var oB = document.createElement('span');
            (b) ? oB.innerHTML = '&lt;' : oB.innerHTML = '&gt;';
            oB.setIndex = b;
            oB.onclick = function(obj){
    
                show({
                    switch : true,
                    change : obj.setIndex == 0
                });
    
            }.bind(this,oB);
            this.elem.btn.appendChild(oB);
        }
    
        //数量
        for(var n = 0,nL = this.imgs.length; n < nL;n++){
    
            var oI = document.createElement('i');
    
            oI.setIndex = n;
            oI.onclick = function(obj){
    
                //显示动画
                show({
                    switch : true,
                    change : obj.setIndex
                });
            }.bind(this,oI)
            this.elem.num.appendChild(oI);
        }
        this.elem.numFind = this.elem.num.querySelectorAll('i');
    
        //进度条
        this.progre = new Array;
        for(var p = 1;p >= 0;p--){
    
            var oP = document.createElement('i');
            setCss(oP,{
                width : 0,
                backgroundColor : p ? '#00c3ff' : '#ffc300'
            });
            this.elem.progre.appendChild(oP);
            this.progre.push(oP);
        }
    
        //显示动画
        show();
    
        this.elem.numFind[this.index].className = 'on';
    }
    function setCss(obj,json){
    
        for( c in json){
    
            if(c == 'opacity'){
    
                obj.style.opacity = c;
                obj.style.filter = "alpha(opacity="+ (json[c]*100) +")";
            }else{
    
                obj.style[c] = json[c];
            }
        }
    
        return this;
    }
    function show(order){
    
        order = order || {};
    
        if(new Date() >= this.activeTime){
    
            this.elem.numFind[this.index].className = '';
    
            // 下次播放动画时候的进度条
            setCss(this.progre[1],{width : 0})
            anime(this.progre[1],{
                    width : this.size.width
                },this.fnTime,function(){
    
                    show({
                        switch : true,
                        change : true
                    });
                }.bind(this));
            
            var status = true,
                activeTime = 0;
    
            for( var i = 0,iL = this.elem.viewBox.length;i < iL;i++ ){
    
                var startTime = getTypeTime(),
                    endTime = getTypeTime(),
                    obj = this.elem.viewBox[i];
    
                    activeTime = Math.max(activeTime,startTime[1] + endTime[1]);
                
                anime(obj,{
                    left :  Math.ceil(Math.random() * this.size.width * 2 - this.size.width),
                    top : Math.ceil(Math.random() * this.size.height * 2 - this.size.height),
                    opacity: 0
                }, startTime[0] ,function(obj){
    
                    if(order.switch && status){
                    
                        if(/number/i.test(typeof order.change)){
    
                            this.index = order.change;
                        }else{
    
                            (order.change) ? ++this.index : --this.index;
                        }
                        
                        setIndex();
                        this.elem.numFind[this.index].className = 'on';
                        status = false;
                    }
    
                    setCss(obj,{backgroundImage : 'url("'+this.imgs[this.index]+'")'})
                    anime(obj,{
                            left : 0,
                            top : 0,
                            opacity : 1
                        },endTime[0]);
                }.bind(this,obj));
            }
    
            //栅格结束运动的时间
            this.activeTime = new Date(new Date().getTime() + activeTime);
    
            setCss(this.progre[0],{width : 0})
            anime(this.progre[0],{width : this.size.width},activeTime);
        }
    }
    function getTypeTime(){
    
        var timer = new Array();
        switch(this.type){
    
            case 1:
    
                timer.push(this.boxTime / 4 + Math.random() * this.boxTime / 4);
                timer.push(timer[0]);
            break;
    
            default:
    
                timer.push([Math.random() * this.boxTime / 5,this.boxTime / 10 * 3]);
                timer.push(timer[0][0] + timer[0][1]);
            break;
        }
    
        return timer;
    }
    function anime(obj,attr,endTime,callback) {
    
        (obj.timer) && cancelAnimationFrame(obj.timer);
    
        var cssJosn = obj.currentStyle || getComputedStyle(obj,null),
            start = {},end = {},goTime;
    
        //设置初始属性值和结束属性值
        for(var key in attr){
    
            if(attr[key] != parseFloat(cssJosn[key])){
    
                start[key] = parseFloat(cssJosn[key]);
                end[key] = attr[key] - start[key];
            }
        }
    
        goTime = new Date();
    
        if(endTime instanceof Array){
    
             (function delayFn(){
    
                 if((new Date() - goTime) >= endTime[0]){
    
                     endTime = endTime[1];
                     goTime = new Date();
                     ref();
                 }else{
    
                     obj.timer = requestAnimationFrame(delayFn);
                 }
             })();
        }else{
    
            ref();
        }
        function ref(){
    
            var prop = (new Date() - goTime) / endTime;
            (prop >= 1) ? prop = 1 : obj.timer = requestAnimationFrame(ref);
            for(var key in start){
    
                var val = -end[key] * prop *(prop-2) + start[key];
    
                if(key == 'opacity'){
    
                    obj.style.opacity = val;
                    obj.style.filter = "alpha(opacity="+ (val*100) +")";
                }else{
    
                    obj.style[key] =  val+'px';
                }
            }
    
            (prop === 1) && callback && callback.call(obj);
        };
    }
    module.exports.FragmentBanner = FragmentBanner;
    
    
    

    在需要的组件里面引入改js
    import {FragmentBanner} from '../../../static/js/banner.js'
    使用方式如下

    // html代码
    <header class="js_header mod-header">
          <div class="banner" id="banner1" style="margin: 50px auto;margin-bottom:0px">
                <div class="banner-view"></div>
                <div class="banner-btn"></div>
                <div class="banner-number"></div>
                <div class="banner-progres"></div>
          </div>
      </header>
    
    //css样式
    <style>
    .banner{
        position: relative;
        overflow: hidden;
    }
    .banner-view{
        position: relative;
        height: 100%;
        z-index: 999;
        background-color: #090b22;
        background-repeat: no-repeat;
    }
    .banner-view i{
        position: relative;
        display: block;
        float: left;
        background-repeat: no-repeat;
    }
    .banner-btn{
        position: absolute;
        width: 100%;
        height: 0;
        top: 45%;
        font-family: "宋体";
        font-size: 20px;
        z-index: 999;
    }
    .banner-btn span{
        display: block;
        float: left;
        width: 50px;
        line-height: 50px;
        text-align: center;
        background-color: #27cfc3;
        color: white;
        cursor: pointer;
        font-weight: 800;
        /* position: absolute;
        right:-150px; */
        /* background-image: url(../../../static/images/style-index.d437fb5e.png);
      background-position: -268px -18px;
      width: 56px;
      height: 56px; */
    }
    /* 
    .banner-btn span:first-child{
        left: -150px;
    } */
    .banner-btn span:hover{
        background-color: rgba(0,0,0,0.6);
    }
    .banner-btn span + span{
        float: right;
    }
    .banner-number{
        position: absolute;
        bottom: 35px;
        width: 100%;
        height: 0;
        font-size: 0;
        text-align: center;
        z-index: 1000;
    }
    .banner-number > *{
        display: inline-block;
        border: 2px solid #fff;
        border-radius: 50%;
        margin: 0 8px;
        width: 10px;
        height: 10px;
        background-color: #00c3ff;
        cursor: pointer;
    }
    .banner-number  > *:hover,
    .banner-number  > *.on{
        background-color: #ffc300;
    }
    .banner-progres{
        width: 100%;
        position: absolute;
        bottom: 0;
        height: 3px;
        z-index: 1000;
    }
    .banner-progres i{
        position: absolute;
        left: 0;
        top: 0;
        border-radius: 3px;
        display: block;
        height: 100%;
        width: 0;
    }
    </style>
    
    // js的引用
    this.obj = {
                container : '#banner1',//选择容器 必选
                imgs : ['https://www.xuanfengge.com/wp-content/themes/lee3.0/dist/img/banner/1.0bd56759.jpg','https://www.xuanfengge.com/wp-content/themes/lee3.0/dist/img/banner/6.c6b4ec87.jpg'],//图片集合 必选
                size : {
                    width : 1200,
                    height : 300
                },//容器的大小 可选
                //行数与列数 可选
                grid : {
                    line : 12,
                    list : 14
                },
                index: 0,//图片集合的索引位置 可选
                type : 2,//切换类型 1 , 2 可选
                boxTime : 5000,//小方块来回运动的时长 可选
                fnTime : 10000//banner切换的时长 可选
          }
    mounted () {
        FragmentBanner(this.obj );
      }
    

    相关文章

      网友评论

        本文标题:vue自定义js图片碎片轮播图切换效果

        本文链接:https://www.haomeiwen.com/subject/qylxdqtx.html