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 );
  }
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 156,907评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,546评论 1 289
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,705评论 0 238
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,624评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,940评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,371评论 1 210
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,672评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,396评论 0 195
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,069评论 1 238
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,350评论 2 242
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,876评论 1 256
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,243评论 2 251
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,847评论 3 231
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,004评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,755评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,378评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,266评论 2 259

推荐阅读更多精彩内容

  • 1 Webpack 1.1 概念简介 1.1.1 WebPack是什么 1、一个打包工具 2、一个模块加载工具 3...
    Kevin_Junbaozi阅读 6,547评论 0 16
  • 一. Java基础部分.................................................
    wy_sure阅读 3,729评论 0 11
  • 文/新鲜Wendy 什么是隐形力量? 我自称它是你在做很多事情的时候一时之间看不到作用,做久了你都没有察觉的时候发...
    新鲜wendy阅读 515评论 6 3
  • 他在微博上被称作励志哥,被LOFTER里美食达人们封为男神。 不仅仅是因为三个月里他自己瘦了20多斤,还带着媳妇瘦...
    MIL开席阅读 21,116评论 58 501
  • 所谓特别,大概是一个人就是一个世界。走进去就会看到,他们的世界里有清泉也有玫瑰,远方有光,有你喜欢的一切。你想在这...
    Alice王志荣阅读 117评论 0 0