原生JS带缓动效果的图片幻灯

开发 前端
朋友让帮忙找个原生JS写的带缓动效果的图片幻灯,类似Tmall首页的效果,找了一圈后发现网上JS写的图片幻灯很多,相关的jQuery插件也很多,但用原生JS写的带缓动效果的却不多。

朋友让帮忙找个原生JS写的带缓动效果的图片幻灯,类似Tmall首页的效果,找了一圈后发现网上JS写的图片幻灯很多,相关的jQuery插件也很多,但用原生JS写的带缓动效果的却不多。没办法只好自己动手,现在把代码分享给大家,希望对大家有用。

代码中的缓动公式用了司徒正美博客中整理的代码:http://www.cnblogs.com/rubylouvre/archive/2009/09/17/1567607.html

缓动公式的推导主要利用了物理中的加速度知识,推荐过程可以看看这篇文章:http://floatyears.info/javascript-animation-easing

HTML部分:

  1. <div id="J-Slide"> 
  2.     <ul class="JSlide-list"> 
  3.         <li><img src="http://images.cnblogs.com/cnblogs_com/artwl/357654/o_01.jpg" alt=""/></li> 
  4.         <li><img src="http://images.cnblogs.com/cnblogs_com/artwl/357654/o_02.jpg" alt=""/></li> 
  5.         <li><img src="http://images.cnblogs.com/cnblogs_com/artwl/357654/o_03.jpg" alt=""/></li> 
  6.         <li><img src="http://images.cnblogs.com/cnblogs_com/artwl/357654/o_04.jpg" alt=""/></li> 
  7.         <li><img src="http://images.cnblogs.com/cnblogs_com/artwl/357654/o_05.jpg" alt=""/></li> 
  8.     </ul> 
  9.     <ul class="JSlide-num"> 
  10.         <li class="current">1</li> 
  11.         <li>2</li> 
  12.         <li>3</li> 
  13.         <li>4</li> 
  14.         <li>5</li> 
  15.     </ul> 
  16.     <div class="JSlide-mask"></div> 
  17. </div> 

这部分比较简单,跟Tmall首页效果一样,几张图片,左下角是图片索引,并有一个半透明的遮罩层。

CSS部分:

  1. body,ul,li{  
  2.     margin:0;  
  3.     padding:0;  
  4. }  
  5. ul{  
  6.     list-style:none;  
  7. }  
  8. #J-Slide{  
  9.     width:600px;  
  10.     height:400px;  
  11.     position:relative;  
  12.     margin:50px auto;  
  13.     overflow:hidden;  
  14. }  
  15. #J-Slide .JSlide-list{  
  16.     position:absolute;  
  17.     width:3000px;  
  18.     left:0;  
  19.     top:0;  
  20. }  
  21. #J-Slide .JSlide-list li{  
  22.     float:left;  
  23. }  
  24. #J-Slide .JSlide-list li img{  
  25.     width:600px;  
  26.     height:400px;  
  27. }  
  28. #J-Slide .JSlide-num{  
  29.     position:absolute;  
  30.     left:0;  
  31.     bottom:0;  
  32.     height:30px;  
  33.     padding:5px;  
  34.     width:100%;  
  35.     z-index:10;  
  36. }  
  37. #J-Slide .JSlide-num li{  
  38.     width:30px;  
  39.     height:30px;  
  40.     margin-left:10px;  
  41.     float:left;  
  42.     font-size:16px;  
  43.     color:white;  
  44.     background:#716584;  
  45.     line-height:30px;  
  46.     text-align:center;  
  47.     cursor:pointer;  
  48.     border-radius:15px;  
  49. }  
  50. #J-Slide .JSlide-mask{  
  51.     position:absolute;  
  52.     left:0;  
  53.     background:black;  
  54.     bottom:0;  
  55.     width:100%;  
  56.     height:40px;  
  57.     opacity:0.3;  
  58.     filter:Alpha(opacity = 30);  
  59.     z-index:1;  
  60. }  
  61. #J-Slide .JSlide-num .current{  
  62.     background:#B91919;  

CSS部分比较简单,直接用absolute定位。

JavaScript库部分:

  1. (function(){  
  2.     /*  
  3.     *参数说明:  
  4.     *id 必须  
  5.     *picwidth 可选  
  6.     *speed 可选  
  7.     *  
  8.     *作者:artwl  
  9.     *出处:http://artwl.cnblogs.com  
  10.     */ 
  11.     var JCP_Slide=function(id,picwidth,speed){  
  12.         if(!(this instanceof JCP_Slide))  
  13.             return new JCP_Slide(id,picwidth,speed);  
  14.         var obj=document.getElementById(id),  
  15.             childs=obj.getElementsByTagName("ul");  
  16.         this.author="artwl";  
  17.         this.jslideList=childs[0];  
  18.         this.jslideNums=childs[1].children;  
  19.         this.speed= speed || 5000;  
  20.         this.picwidth= picwidth || (obj.currentStyle ? parseFloat(obj.currentStyle.width) : parseFloat(document.defaultView.getComputedStyle(obj,null).width));  
  21.         this.currentIndex=0;  
  22.         this.distance=this.picwidth;  
  23.         this.currentLeftPos=0;  
  24.         this.runHandle=null;  
  25.         this.len=this.jslideNums.length;  
  26.     }  
  27.  
  28.     JCP_Slide.prototype={  
  29.         bindMouse:function(){  
  30.             var self=this;  
  31.             for(var i=0;i<this.len;i++){  
  32.                 this.jslideNums[i].onmouseover=(function(index){  
  33.                     return function(){  
  34.                         self.currentIndex=index;  
  35.                         clearInterval(self.runHandle);  
  36.                         var prev=-1;  
  37.                         for(var k=0;k<self.len;k++){  
  38.                             if(self.jslideNums[k].className === "current")  
  39.                                 prev = k;  
  40.                             self.jslideNums[k].className = k === index ? "current" : "" ;  
  41.                         }  
  42.                         if(prev != index){  
  43.                             self.distance=(prev - index)*self.picwidth;  
  44.                             self.currentLeftPos = -prev * self.picwidth;  
  45.                             self.transition(self.jslideList,{field:'left',begin:self.currentLeftPos,change:self.distance,ease:self.easeOutCirc})  
  46.                         }  
  47.                     }  
  48.                 })(i);  
  49.                 this.jslideNums[i].onmouseout=function(){  
  50.                     self.autoRun();  
  51.                 }  
  52.             }  
  53.         },  
  54.         autoRun:function(){  
  55.             var self=this;  
  56.             this.runHandle=setInterval(function(){  
  57.                 self.distance=-self.picwidth;  
  58.                 for(var k=0;k<self.len;k++){  
  59.                     self.jslideNums[k].className = "" ;  
  60.                 }  
  61.                 self.currentIndex++;  
  62.                 self.currentIndex%=5;  
  63.                 self.jslideNums[self.currentIndex].className = "current";  
  64.                 self.currentLeftPos = -(self.currentIndex-1) * self.picwidth;  
  65.                 if(self.currentIndex == 0){  
  66.                     self.distance = (self.len-1)*self.picwidth;  
  67.                     self.currentLeftPos = -self.distance;  
  68.                 }  
  69.                 self.transition(self.jslideList,{field:'left',begin:self.currentLeftPos,change:self.distance,ease:self.easeOutCirc});  
  70.             },self.speed);  
  71.         },  
  72.         easeOutCirc:function(pos){  
  73.             return Math.sqrt(1 - Math.pow((pos-1), 2))  
  74.         },  
  75.         transition:function(el){  
  76.             el.style.position = "absolute";  
  77.             var options = arguments[1] || {},  
  78.             begin =  options.begin,//开始位置  
  79.             change = options.change,//变化量  
  80.             duration = options.duration || 500,//缓动效果持续时间  
  81.             field = options.field,//必须指定,基本上对top,left,width,height这个属性进行设置  
  82.             ftp = options.ftp || 50,  
  83.             onStart = options.onStart || function(){},  
  84.             onEnd = options.onEnd || function(){},  
  85.             ease = options.ease,//要使用的缓动公式  
  86.             end = begin + change,//结束位置  
  87.             startTime = new Date().getTime();//开始执行的时间  
  88.             onStart();  
  89.             (function(){  
  90.                 setTimeout(function(){  
  91.                     var newTime = new Date().getTime(),//当前帧开始的时间  
  92.                     timestamp = newTime - startTime,//逝去时间  
  93.                     delta = ease(timestamp / duration);  
  94.                     el.style[field] = Math.ceil(begin + delta * change) + "px";  
  95.                     if(duration <= timestamp){  
  96.                         el.style[field] = end + "px";  
  97.                         onEnd();  
  98.                     } else {  
  99.                         setTimeout(arguments.callee,1000/ftp);  
  100.                     }  
  101.                 },1000/ftp);  
  102.             })();  
  103.         },  
  104.         play:function(){  
  105.             this.bindMouse();  
  106.             this.autoRun();  
  107.         }  
  108.     };  
  109.  
  110.     window.JCP_Slide=JCP_Slide;  
  111. })(); 

这个JS库是核心,入口有三个参数,***个是最外层的div的id(必须),第二个参数是图片宽度(可选),默认为最外层DIV宽度,第三个参数为自动切换的时间间隔(可选),默认为5秒。

bindMouse是绑定鼠标的悬浮和移出事件,autoRun是让图片正动切换,play方法调用了这两个方法。

easeOutCirc是一个先快后慢的缓动公式,transition是缓动函数,这两个方法的用法请参考司徒正美的博客:

调用示例:

  1. window.onload=function(){  
  2.     JCP_Slide("J-Slide").play();  
  3. }; 

完整代码为:

  1. View Code   
  2.  
  3. <!DOCTYPE html> 
  4. <html> 
  5. <head> 
  6.     <meta charset="utf-8"/> 
  7.     <title> New Document </title> 
  8.     <style type="text/css"> 
  9.         body,ul,li{  
  10.             margin:0;  
  11.             padding:0;  
  12.         }  
  13.         ul{  
  14.             list-style:none;  
  15.         }  
  16.         #J-Slide{  
  17.             width:600px;  
  18.             height:400px;  
  19.             position:relative;  
  20.             margin:50px auto;  
  21.             overflow:hidden;  
  22.         }  
  23.         #J-Slide .JSlide-list{  
  24.             position:absolute;  
  25.             width:3000px;  
  26.             left:0;  
  27.             top:0;  
  28.         }  
  29.         #J-Slide .JSlide-list li{  
  30.             float:left;  
  31.         }  
  32.         #J-Slide .JSlide-list li img{  
  33.             width:600px;  
  34.             height:400px;  
  35.         }  
  36.         #J-Slide .JSlide-num{  
  37.             position:absolute;  
  38.             left:0;  
  39.             bottom:0;  
  40.             height:30px;  
  41.             padding:5px;  
  42.             width:100%;  
  43.             z-index:10;  
  44.         }  
  45.         #J-Slide .JSlide-num li{  
  46.             width:30px;  
  47.             height:30px;  
  48.             margin-left:10px;  
  49.             float:left;  
  50.             font-size:16px;  
  51.             color:white;  
  52.             background:#716584;  
  53.             line-height:30px;  
  54.             text-align:center;  
  55.             cursor:pointer;  
  56.             border-radius:15px;  
  57.         }  
  58.         #J-Slide .JSlide-mask{  
  59.             position:absolute;  
  60.             left:0;  
  61.             background:black;  
  62.             bottom:0;  
  63.             width:100%;  
  64.             height:40px;  
  65.             opacity:0.3;  
  66.             filter:Alpha(opacity = 30);  
  67.             z-index:1;  
  68.         }  
  69.         #J-Slide .JSlide-num .current{  
  70.             background:#B91919;  
  71.         }  
  72.     </style> 
  73.     <script> 
  74.         (function(){  
  75.             /*  
  76.             *参数说明:  
  77.             *id 必须  
  78.             *picwidth 可选  
  79.             *speed 可选  
  80.             *  
  81.             *作者:artwl  
  82.             *出处:http://artwl.cnblogs.com  
  83.             */  
  84.             var JCP_Slide=function(id,picwidth,speed){  
  85.                 if(!(this instanceof JCP_Slide))  
  86.                     return new JCP_Slide(id,picwidth,speed);  
  87.                 var obj=document.getElementById(id),  
  88.                     childs=obj.getElementsByTagName("ul");  
  89.                 this.author="artwl";  
  90.                 this.jslideList=childs[0];  
  91.                 this.jslideNums=childs[1].children;  
  92.                 this.speed= speed || 5000;  
  93.                 this.picwidth= picwidth || (obj.currentStyle ? parseFloat(obj.currentStyle.width) : parseFloat(document.defaultView.getComputedStyle(obj,null).width));  
  94.                 this.currentIndex=0;  
  95.                 thisthis.distance=this.picwidth;  
  96.                 this.currentLeftPos=0;  
  97.                 this.runHandle=null;  
  98.                 thisthis.len=this.jslideNums.length;  
  99.             }  
  100.  
  101.             JCP_Slide.prototype={  
  102.                 bindMouse:function(){  
  103.                     var self=this;  
  104.                     for(var i=0;i<this.len;i++){  
  105.                         this.jslideNums[i].onmouseover=(function(index){  
  106.                             return function(){  
  107.                                 self.currentIndex=index;  
  108.                                 clearInterval(self.runHandle);  
  109.                                 var prev=-1;  
  110.                                 for(var k=0;k<self.len;k++){  
  111.                                     if(self.jslideNums[k].className === "current")  
  112.                                         prev = k;  
  113.                                     self.jslideNums[k].className = k === index ? "current" : "" ;  
  114.                                 }  
  115.                                 if(prev != index){  
  116.                                     self.distance=(prev - index)*self.picwidth;  
  117.                                     self.currentLeftPos = -prev * self.picwidth;  
  118.                                     self.transition(self.jslideList,{field:'left',begin:self.currentLeftPos,change:self.distance,ease:self.easeOutCirc})  
  119.                                 }  
  120.                             }  
  121.                         })(i);  
  122.                         this.jslideNums[i].onmouseout=function(){  
  123.                             self.autoRun();  
  124.                         }  
  125.                     }  
  126.                 },  
  127.                 autoRun:function(){  
  128.                     var self=this;  
  129.                     this.runHandle=setInterval(function(){  
  130.                         self.distance=-self.picwidth;  
  131.                         for(var k=0;k<self.len;k++){  
  132.                             self.jslideNums[k].className = "" ;  
  133.                         }  
  134.                         self.currentIndex++;  
  135.                         self.currentIndex%=5;  
  136.                         self.jslideNums[self.currentIndex].className = "current";  
  137.                         self.currentLeftPos = -(self.currentIndex-1) * self.picwidth;  
  138.                         if(self.currentIndex == 0){  
  139.                             self.distance = (self.len-1)*self.picwidth;  
  140.                             self.currentLeftPos = -self.distance;  
  141.                         }  
  142.                         self.transition(self.jslideList,{field:'left',begin:self.currentLeftPos,change:self.distance,ease:self.easeOutCirc});  
  143.                     },self.speed);  
  144.                 },  
  145.                 easeOutCirc:function(pos){  
  146.                     return Math.sqrt(1 - Math.pow((pos-1), 2))  
  147.                 },  
  148.                 transition:function(el){  
  149.                     el.style.position = "absolute";  
  150.                     var options = arguments[1] || {},  
  151.                     begin =  options.begin,  
  152.                     change = options.change,  
  153.                     duration = options.duration || 500,  
  154.                     field = options.field,  
  155.                     ftp = options.ftp || 50,  
  156.                     onStart = options.onStart || function(){},  
  157.                     onEnd = options.onEnd || function(){},  
  158.                     ease = options.ease,  
  159.                     end = begin + change,  
  160.                     startTime = new Date().getTime();  
  161.                     onStart();  
  162.                     (function(){  
  163.                         setTimeout(function(){  
  164.                             var newnewTime = new Date().getTime(),  
  165.                             timestamp = newTime - startTime,  
  166.                             delta = ease(timestamp / duration);  
  167.                             el.style[field] = Math.ceil(begin + delta * change) + "px";  
  168.                             if(duration <= timestamp){  
  169.                                 el.style[field] = end + "px";  
  170.                                 onEnd();  
  171.                             } else {  
  172.                                 setTimeout(arguments.callee,1000/ftp);  
  173.                             }  
  174.                         },1000/ftp);  
  175.                     })();  
  176.                 },  
  177.                 play:function(){  
  178.                     this.bindMouse();  
  179.                     this.autoRun();  
  180.                 }  
  181.             };  
  182.  
  183.             window.JCP_Slide=JCP_Slide;  
  184.         })();  
  185.  
  186.         window.onload=function(){  
  187.             JCP_Slide("J-Slide").play();  
  188.         };  
  189.     </script> 
  190. </head> 
  191. <body> 
  192. <div id="J-Slide"> 
  193.     <ul class="JSlide-list"> 
  194.         <li><img src="http://images.cnblogs.com/cnblogs_com/artwl/357654/o_01.jpg" alt=""/></li> 
  195.         <li><img src="http://images.cnblogs.com/cnblogs_com/artwl/357654/o_02.jpg" alt=""/></li> 
  196.         <li><img src="http://images.cnblogs.com/cnblogs_com/artwl/357654/o_03.jpg" alt=""/></li> 
  197.         <li><img src="http://images.cnblogs.com/cnblogs_com/artwl/357654/o_04.jpg" alt=""/></li> 
  198.         <li><img src="http://images.cnblogs.com/cnblogs_com/artwl/357654/o_05.jpg" alt=""/></li> 
  199.     </ul> 
  200.     <ul class="JSlide-num"> 
  201.         <li class="current">1</li> 
  202.         <li>2</li> 
  203.         <li>3</li> 
  204.         <li>4</li> 
  205.         <li>5</li> 
  206.     </ul> 
  207.     <div class="JSlide-mask"></div> 
  208. </div> 
  209. </body> 
  210. </html> 

运行效果:

原文链接:http://www.cnblogs.com/artwl/archive/2012/09/06/2673649.html

责任编辑:张伟 来源: Artwl的博客
相关推荐

2009-09-16 11:32:26

Javascript缓

2022-11-03 07:49:52

JS原生元素

2013-06-25 11:21:35

Android开发幻灯片效果Gallery

2011-06-20 06:18:27

ibmdwjava

2022-06-21 11:23:15

API鸿蒙JS开发

2012-05-25 14:41:19

JavaScript

2012-05-17 13:17:26

HTML5

2011-04-11 14:14:29

checkboxlistviewAndroid

2012-05-02 13:53:00

JavaScript

2012-06-14 13:22:35

JavaScript

2012-06-01 10:12:39

2020-05-07 09:45:16

前端JS图片压缩

2011-07-08 15:08:16

iPhone 图片

2020-06-15 18:00:36

transformbannerJavascript

2024-03-15 09:27:35

函数数据懒加载FlowItem组件

2016-08-30 21:36:56

JavascriptCSSWeb

2022-07-07 08:30:50

类型注解原生JS

2011-05-30 13:23:11

Android 动画

2015-07-17 13:15:40

Swift版幻灯无限滚动

2013-12-24 09:38:50

asm.jsJavascript
点赞
收藏

51CTO技术栈公众号