博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[js高手之路]封装运动框架实战左右与上下滑动的焦点轮播图
阅读量:6044 次
发布时间:2019-06-20

本文共 9017 字,大约阅读时间需要 30 分钟。

在这篇文章中,封装了一个匀速运动框架,我们在这个框架的基础之上,加上缓冲运动效果,然后用运动框架来做幻灯片(上下,左右),效果如下:【选择器用的是html5的,你的浏览器需要支持html5新选择器,才能看见效果额

 

  • 1
  • 2
  • 3
  • 4
  • 5

 

缓冲运动通常有两种常见的表现:比如让一个div从0运动到500,一种是事件触发的时候,速度很快, 一种是事件触发的时候慢,然后慢慢加快.我们来实现先块后慢的,常见的就是开车,比如刚从高速路上下来的车,就是120km/小时,然后进入匝道,变成40km/时.  或者40km/小时进入小区,最后停车,变成0km/小时.  从120km/小时->40km/小时,  或者40km->0km/小时,都是速度先块后慢,这种运动怎么用程序来表示呢?

可以用目标距离( 500 ) - 当前距离( 200 ) / 一个系数( 比如12 ),就能达到速度由块而慢的变化,当前距离在起点,分子(500 - 0 )最大,所以速度最大,如果当前距离快要接近500,分子最小,除完之后的速度也是最小。

1     10     23 24 25     26     
27

 

 
 
但是,div并不会乖乖地停止在500px这个目标位置,最终却是停在497.375px,只要查看当前的速度,当前的值就知道原因了

 

 

你会发现,速度永远都在0.375这里停着,获取到的当前的距离停在497px? 这里有个问题,我们的div不是停在497.375px吗,怎么获取到的没有了后面的小数0.375呢?计算机在处理浮点数会有精度损失。我们可以单独做一个小测试:

1 
2

你会发现这段代码获取到左偏移是30px而不是行间样式中写的30.2px。因为在获取当前位置的时候,会舍去小数,所以速度永远停在0.375px, 位置也是永远停在497,所以,为了到达目标,我们就得把速度变成1,对速度向上取整( Math.ceil ),我们就能把速度变成1,div也能到达500

1 oBtn.onclick = function(){ 2     timer = setInterval( function(){ 3         speed = ( 500 - oBox.offsetLeft ) / 8; 4         if( speed > 0 ) { 5             speed = Math.ceil( speed ); 6         } 7         console.log( speed, oBox.offsetLeft ); 8         oBox.style.left = oBox.offsetLeft + speed + 'px'; 9     }, 30 );10 }

第二个问题,如果div的位置是在900,也就是说从900运动到500,有没有这样的需求呢? 肯定有啊,轮播图,从右到左就是这样的啊。

1     10     26 27 28     29     
30

 

 

 
 
最后目标停在503.5px,速度这个时候是负值,最后速度停在-0.5,对于反方向的速度,我们就要把它变成-1,才能到达目标,所以用向下取整(Math.floor)
1 oBtn.onclick = function(){ 2     timer = setInterval( function(){ 3         speed = ( 500 - oBox.offsetLeft ) / 8; 4         if( speed > 0 ) { 5             speed = Math.ceil( speed ); 6         }else { 7             speed = Math.floor( speed ); 8         } 9         console.log( speed, oBox.offsetLeft );10         oBox.style.left = oBox.offsetLeft + speed + 'px';11     }, 30 );12 }

然后我们把这个缓冲运动整合到匀速运动框架,就变成:

1 function css(obj, attr, value) { 2     if (arguments.length == 3) { 3         obj.style[attr] = value; 4     } else { 5         if (obj.currentStyle) { 6             return obj.currentStyle[attr]; 7         } else { 8             return getComputedStyle(obj, false)[attr]; 9         }10     }11 }12 13 function animate(obj, attr, fn) {14     clearInterval(obj.timer);15     var cur = 0;16     var target = 0;17     var speed = 0;18     obj.timer = setInterval(function () {19         var bFlag = true;20         for (var key in attr) {21             if (key == 'opacity ') {22                 cur = css(obj, 'opacity') * 100;23             } else {24                 cur = parseInt(css(obj, key));25             }26             target = attr[key];27             speed = ( target - cur ) / 8;28             speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);29             if (cur != target) {30                 bFlag = false;31                 if (key == 'opacity') {32                     obj.style.opacity = ( cur + speed ) / 100;33                     obj.style.filter = "alpha(opacity:" + ( cur + speed ) + ")";34                 } else {35                     obj.style[key] = cur + speed + "px";36                 }37             }38         }39         if (bFlag) {40             clearInterval(obj.timer);41             fn && fn.call(obj);42         }43     }, 30 );44 }

有了这匀速运动框架,我们就来做幻灯片:

上下幻灯片的html样式文件:

1  2  3  4     
5 slide - by ghostwu 6
7 8 9 10 11
12
13
14
15
16
17
18
19
20
21
22
    23
  • 24
  • 25
  • 26
  • 27
  • 28
29
30
31 32
View Code

slide3.css文件:

1 * { 2     margin: 0; 3     padding: 0; 4 } 5 li { 6     list-style-type: none; 7 } 8 #slide { 9     width: 800px;10     height: 450px;11     position: relative;12     margin:20px auto;13 }14 #slide-img {15     position: relative;16     width: 800px;17     height: 450px;18     overflow: hidden;19 }20 #img-container {21     position: absolute;22     left: 0px;23     top: 0px;24     height: 2250px;25     /*font-size:0px;*/26 }27 #img-container img {28     display: block;29     float: left;30 }31 #slide-nums {32     position: absolute;33     right:10px;34     bottom:10px;35 }36 #slide-nums li {37     float: left;38     margin:0px 10px;39     background: white;40     width: 20px;41     height: 20px;42     text-align: center;43     line-height: 20px;44     border-radius:10px;45     text-indent:-999px;46     opacity:0.6;47     filter:alpha(opacity:60);48     cursor:pointer;49 }50 #slide-nums li.active {51     background: red;52 }
View Code

animate.js文件:

1 function css(obj, attr, value) { 2     if (arguments.length == 3) { 3         obj.style[attr] = value; 4     } else { 5         if (obj.currentStyle) { 6             return obj.currentStyle[attr]; 7         } else { 8             return getComputedStyle(obj, false)[attr]; 9         }10     }11 }12 13 function animate(obj, attr, fn) {14     clearInterval(obj.timer);15     var cur = 0;16     var target = 0;17     var speed = 0;18     obj.timer = setInterval(function () {19         var bFlag = true;20         for (var key in attr) {21             if (key == 'opacity ') {22                 cur = css(obj, 'opacity') * 100;23             } else {24                 cur = parseInt(css(obj, key));25             }26             target = attr[key];27             speed = ( target - cur ) / 8;28             speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);29             if (cur != target) {30                 bFlag = false;31                 if (key == 'opacity') {32                     obj.style.opacity = ( cur + speed ) / 100;33                     obj.style.filter = "alpha(opacity:" + ( cur + speed ) + ")";34                 } else {35                     obj.style[key] = cur + speed + "px";36                 }37             }38         }39         if (bFlag) {40             clearInterval(obj.timer);41             fn && fn.call(obj);42         }43     }, 30 );44 }
View Code

slide.js文件:

1 window.onload = function () { 2     function Slide() { 3         this.oImgContainer = document.getElementById("img-container"); 4         this.aLi = document.getElementsByTagName("li"); 5         this.index = 0; 6     } 7  8     Slide.prototype.bind = function () { 9         var that = this;10         for (var i = 0; i < this.aLi.length; i++) {11             this.aLi[i].index = i;12             this.aLi[i].onmouseover = function () {13                 that.moveTop( this.index );14             }15         }16     }17 18     Slide.prototype.moveTop = function (i) {19         this.index = i;20         for( var j = 0; j < this.aLi.length; j++ ){21            this.aLi[j].className = '';22         }23         this.aLi[this.index].className = 'active';24         animate( this.oImgContainer, {25             "top" : -this.index * 450,26             "left" : 027         });28     }29     30     var oSlide = new Slide();31     oSlide.bind();32 33 }
View Code
 
左右幻灯片只需要改下样式即可
样式文件:
1 * { 2     margin: 0; 3     padding: 0; 4 } 5 li { 6     list-style-type: none; 7 } 8 #slide { 9     width: 800px;10     height: 450px;11     position: relative;12     margin:20px auto;13 }14 #slide-img {15     position: relative;16     width: 800px;17     height: 450px;18     overflow: hidden;19 }20 #img-container {21     position: absolute;22     left: 0px;23     top: 0px;24     width: 4000px;25 }26 #img-container img {27     display: block;28     float: left;29 }30 #slide-nums {31     position: absolute;32     right:10px;33     bottom:10px;34 }35 #slide-nums li {36     float: left;37     margin:0px 10px;38     background: white;39     width: 20px;40     height: 20px;41     text-align: center;42     line-height: 20px;43     border-radius:10px;44     text-indent:-999px;45     opacity:0.6;46     filter:alpha(opacity:60);47     cursor:pointer;48 }49 #slide-nums li.active {50     background: red;51 }
View Code

js调用文件:

1 window.onload = function () { 2     function Slide() { 3         this.oImgContainer = document.getElementById("img-container"); 4         this.aLi = document.getElementsByTagName("li"); 5         this.index = 0; 6     } 7  8     Slide.prototype.bind = function () { 9         var that = this;10         for (var i = 0; i < this.aLi.length; i++) {11             this.aLi[i].index = i;12             this.aLi[i].onmouseover = function () {13                 that.moveLeft( this.index );14             }15         }16     }17 18     Slide.prototype.moveLeft = function (i) {19         this.index = i;20         for( var j = 0; j < this.aLi.length; j++ ){21            this.aLi[j].className = '';22         }23         this.aLi[this.index].className = 'active';24         animate( this.oImgContainer, {25             "left" : -this.index * 80026         });27     }28     29     var oSlide = new Slide();30     oSlide.bind();31 32 }
View Code

 

转载地址:http://ysnex.baihongyu.com/

你可能感兴趣的文章
深度学习博客
查看>>
Android总结篇系列:Android Service
查看>>
Android dumpsys命令的使用
查看>>
Linux Kernel系列一:开篇和Kernel启动概要
查看>>
Android如何实现超级棒的沉浸式体验
查看>>
使用node打造自己的命令行工具方法教程
查看>>
Express代理中间件问题与解决方案
查看>>
||和&&返回什么?
查看>>
linux在文件中查找指定字符串,然后根据查找结果来做进一步的处理
查看>>
在Oracle中删除所有强制性外键约束
查看>>
【R】R语言使用命令行参数 - [编程技巧(Program Skill)]
查看>>
经典算法题每日演练——第二题 五家共井
查看>>
存储过程中拼接的变量和点的问题
查看>>
ASP.NET那点不为人知的事(一)
查看>>
3.16
查看>>
表单文件上传与文件下载
查看>>
下午考
查看>>
创建字符设备的三种方法
查看>>
走在网页游戏开发的路上(六)
查看>>
nginx 配置的server_name参数(转)
查看>>