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

定义一个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 );
  }

推荐阅读更多精彩内容