碎化轮播图

效果参考最终王冠的官网 https://zzwg.xd.com/

JS

  1 ;window.requestAnimationFrame = window.requestAnimationFrame||function(a){return setTimeout(a,1000/60)};
  2 window.cancelAnimationFrame = window.cancelAnimationFrame||clearTimeout;
  3 function FragmentBanner(option) {
  4 
  5     //实例化时,可传的参数
  6     this.whiteList = ['container','controller','size','imgs','size','grid','index','fnTime','boxTime','type'];
  7 
  8     //容器将包容控制器
  9     this.container = '.banner';
 10     
 11     //默认的控制器
 12     this.controller = {
 13         view : '.banner-view',
 14         btn : '.banner-btn',
 15         num : '.banner-number',
 16         progre : '.banner-progres'
 17     };
 18 
 19     //栅格 行*列
 20     this.grid = {
 21         line : 5,
 22         list : 10
 23     };
 24 
 25     //容器的大小
 26     this.size = {
 27         width : 1200,
 28         height : 675,
 29     };
 30 
 31     //切换类型
 32     this.type = 1;
 33 
 34     //索引位置
 35     this.index = 0;
 36 
 37     //函数每次切换时间
 38     this.fnTime = 5000;
 39 
 40     //栅格每次运动时间
 41     this.boxTime = 2000;
 42 
 43     //栅格运动结束的时间
 44     this.activeTime = new Date();
 45 
 46     for(var a = 0,attrLenght = this.whiteList.length; a < attrLenght;a++){
 47 
 48         var attr = this.whiteList[a];
 49         if(option[attr] != undefined){
 50 
 51             this[attr] = option[attr];
 52         }
 53     }
 54     for(var i in option){
 55 
 56         if(this.whiteList[i] !== undefined){ ; }
 57     }
 58 
 59     this.init();
 60 }
 61 
 62 FragmentBanner.prototype = {
 63 
 64     constructor : FragmentBanner,
 65 
 66     init : function(){
 67 
 68         this.container = document.querySelector(this.container)
 69         if(!this.container){
 70 
 71             return alert('获取banner容器失败');
 72         }else{
 73 
 74             this.container.style.width = this.size.width+'px';
 75             this.container.style.height = this.size.height+'px';
 76         }
 77         
 78         this.elem = {};
 79         for(var e in this.controller){
 80 
 81             this.elem[e] = this.container.querySelector(this.controller[e]);
 82             if(this.elem[e] == null){
 83 
 84                 return alert('获取'+e+'容器');
 85             }
 86         }
 87 
 88         //栅格
 89         var w = this.size.width / this.grid.list,
 90             h = this.size.height / this.grid.line;
 91 
 92         this.elem.viewBox = new Array();
 93         for(var i = 0,iL = this.grid.line;i < iL;i++){
 94 
 95             for(var j = 0,jL = this.grid.list;j < jL;j++){
 96 
 97                 var newI = document.createElement('i');
 98 
 99                 this.setCss(newI,{
100                     width : w+'px',
101                     height : h+'px',
102                     left : 0,
103                     top : 0,
104                     opacity : 1,
105                     backgroundImage : 'url("'+this.imgs[this.index]+'")',
106                     backgroundSize : this.size.width + 'px ' + this.size.height +'px',
107                     backgroundPosition : w * -j+'px ' + h * -i+'px'
108                 });
109                 
110                 this.elem.view.appendChild(newI);
111                 this.elem.viewBox.push(newI);
112             }
113         }
114 
115         //按钮动作
116         for (var b = 1; b >= 0; b--) {
117             
118             var oB = document.createElement('span');
119             (b) ? oB.innerHTML = '&lt;' : oB.innerHTML = '&gt;';
120             oB.setIndex = b;
121             oB.onclick = function(obj){
122 
123                 this.show({
124                     switch : true,
125                     change : obj.setIndex == 0
126                 });
127 
128             }.bind(this,oB);
129             this.elem.btn.appendChild(oB);
130         }
131 
132         //数量
133         for(var n = 0,nL = this.imgs.length; n < nL;n++){
134 
135             var oI = document.createElement('i');
136 
137             oI.setIndex = n;
138             oI.onclick = function(obj){
139 
140                 //显示动画
141                 this.show({
142                     switch : true,
143                     change : obj.setIndex
144                 });
145             }.bind(this,oI)
146             this.elem.num.appendChild(oI);
147         }
148         this.elem.numFind = this.elem.num.querySelectorAll('i');
149 
150         //进度条
151         this.progre = new Array;
152         for(var p = 1;p >= 0;p--){
153 
154             var oP = document.createElement('i');
155             this.setCss(oP,{
156                 width : 0,
157                 backgroundColor : p ? '#00c3ff' : '#ffc300'
158             });
159             this.elem.progre.appendChild(oP);
160             this.progre.push(oP);
161         }
162 
163         //显示动画
164         this.show();
165 
166         this.elem.numFind[this.index].className = 'on';
167     },
168 
169     setIndex : function(){
170 
171         this.index %= this.imgs.length;
172         
173         this.index = (this.index < 0) ? this.imgs.length - 1 : this.index;
174 
175         this.elem.numFind[this.index].className = 'on'; 
176     },
177 
178     getTypeTime : function(){
179 
180         var timer = new Array();
181         switch(this.type){
182 
183             case 1:
184 
185                 timer.push(this.boxTime / 4 + Math.random() * this.boxTime / 4);
186                 timer.push(timer[0]);
187             break;
188 
189             default:
190 
191                 timer.push([Math.random() * this.boxTime / 5,this.boxTime / 10 * 3]);
192                 timer.push(timer[0][0] + timer[0][1]);
193             break;
194         }
195 
196         return timer;
197     },
198     
199     show : function(order){
200 
201         order = order || {};
202 
203         if(new Date() >= this.activeTime){
204 
205             this.elem.numFind[this.index].className = '';
206 
207             //下次播放动画时候的进度条
208             this.setCss(this.progre[1],{width : 0})
209                 .anime(this.progre[1],{
210                     width : this.size.width
211                 },this.fnTime,function(){
212 
213                     this.show({
214                         switch : true,
215                         change : true
216                     });
217                 }.bind(this));
218             
219             var status = true,
220                 activeTime = 0;
221 
222             for( var i = 0,iL = this.elem.viewBox.length;i < iL;i++ ){
223 
224                 var startTime = this.getTypeTime(),
225                     endTime = this.getTypeTime(),
226                     obj = this.elem.viewBox[i];
227 
228                     activeTime = Math.max(activeTime,startTime[1] + endTime[1]);
229                 
230                 this.anime(obj,{
231                     left :  Math.ceil(Math.random() * this.size.width * 2 - this.size.width),
232                     top : Math.ceil(Math.random() * this.size.height * 2 - this.size.height),
233                     opacity: 0
234                 }, startTime[0] ,function(obj){
235 
236                     if(order.switch && status){
237                     
238                         if(/number/i.test(typeof order.change)){
239 
240                             this.index = order.change;
241                         }else{
242 
243                             (order.change) ? ++this.index : --this.index;
244                         }
245                         
246                         this.setIndex();
247                         this.elem.numFind[this.index].className = 'on';
248                         status = false;
249                     }
250 
251                     this.setCss(obj,{backgroundImage : 'url("'+this.imgs[this.index]+'")'})
252                         .anime(obj,{
253                             left : 0,
254                             top : 0,
255                             opacity : 1
256                         },endTime[0]);
257                 }.bind(this,obj));
258             }
259 
260             //栅格结束运动的时间
261             this.activeTime = new Date(new Date().getTime() + activeTime);
262 
263             this.setCss(this.progre[0],{width : 0})
264                 .anime(this.progre[0],{
265                     width : this.size.width
266                 },activeTime);
267         }
268     },
269 
270     setCss : function(obj,json){
271 
272         for( c in json){
273 
274             if(c == 'opacity'){
275 
276                 obj.style.opacity = c;
277                 obj.style.filter = "alpha(opacity="+ (json[c]*100) +")";
278             }else{
279 
280                 obj.style[c] = json[c];
281             }
282         }
283 
284         return this;
285     },
286 
287     anime : function(obj,attr,endTime,callback) {
288 
289         (obj.timer) && cancelAnimationFrame(obj.timer);
290 
291         var cssJosn = obj.currentStyle || getComputedStyle(obj,null),
292             start = {},end = {},goTime;
293 
294         //设置初始属性值和结束属性值
295         for(var key in attr){
296 
297             if(attr[key] != parseFloat(cssJosn[key])){
298 
299                 start[key] = parseFloat(cssJosn[key]);
300                 end[key] = attr[key] - start[key];
301             }
302         }
303 
304         goTime = new Date();
305 
306         if(endTime instanceof Array){
307 
308              (function delayFn(){
309 
310                  if((new Date() - goTime) >= endTime[0]){
311 
312                      endTime = endTime[1];
313                      goTime = new Date();
314                      ref();
315                  }else{
316 
317                      obj.timer = requestAnimationFrame(delayFn);
318                  }
319              })();
320         }else{
321 
322             ref();
323         }
324 
325 
326         function ref(){
327 
328             var prop = (new Date() - goTime) / endTime;
329             (prop >= 1) ? prop = 1 : obj.timer = requestAnimationFrame(ref);
330             for(var key in start){
331 
332                 var val = -end[key] * prop *(prop-2) + start[key];
333 
334                 if(key == 'opacity'){
335 
336                     obj.style.opacity = val;
337                     obj.style.filter = "alpha(opacity="+ (val*100) +")";
338                 }else{
339 
340                     obj.style[key] =  val+'px';
341                 }
342             }
343 
344             (prop === 1) && callback && callback.call(obj);
345         };
346     }
347 }


CSS

*{
    margin: 0;
    padding: 0;
}
.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: 1000;
}
.banner-btn span{
    display: block;
    float: left;
    width: 50px;
    line-height: 50px;
    text-align: center;
    background-color: rgba(0,0,0,0.7);
    color: #74dcff;
    cursor: pointer;
    font-weight: 800;
    background-image: 
}
.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;
}

HTML

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <link rel="stylesheet" type="text/css" href="css/banner.css">
    <title>banner图碎片化</title>

</head>
<body style="background-color:#F1F1F1">
    
    <div class="banner" id="banner1" style="margin: 50px auto;">
        <div class="banner-view"></div>
        <div class="banner-btn"></div>
        <div class="banner-number"></div>
        <div class="banner-progres"></div>
    </div>

    
<script type="text/javascript" src="js/banner.js"></script>
<script type="text/javascript">

    var banner = new FragmentBanner({
        container : "#banner1",//选择容器 必选
        imgs : ['images/a1.png','images/a2.png','images/a3.png','images/a4.png','images/a5.png'],//图片集合 必选
        size : {
            width : 1000,
            height : 560
        },//容器的大小 可选
        //行数与列数 可选
        grid : {
            line : 12,
            list : 14
        },
        index: 0,//图片集合的索引位置 可选
        type : 2,//切换类型 1 , 2 可选
        boxTime : 5000,//小方块来回运动的时长 可选
        fnTime : 10000//banner切换的时长 可选
    });
        
    

</script>
</body>
</html>

 

posted @ 2019-03-11 13:46  雲天望垂墨傾池  阅读(266)  评论(0编辑  收藏  举报