在这篇文章[js高手之路]打造通用的匀速运动框架中,封装了一个匀速运动框架,我们在这个框架的基础之上,加上缓冲运动效果,然后用运动框架来做幻灯片(上下,左右),效果如下:【选择器用的是html5的,你的浏览器需要支持html5新选择器,才能看见效果额】
<script type="text/java script">// 0 ? Math.ceil(speed) : Math.floor(speed);
if (cur != target) {
bFlag = false;
if (key == 'opacity') {
obj.style.opacity = ( cur + speed ) / 100;
obj.style.filter = "alpha(opacity:" + ( cur + speed ) + ")";
} else {
obj.style[key] = cur + speed + "px";
}
}
}
if (bFlag) {
clearInterval(obj.timer);
fn && fn.call(obj);
}
}, 30 );
}
function Slide() {
this.oSlide = document.getElementById( 'slide' );
this.oImgContainer = this.oSlide.querySelector('#img-container');
this.aLi = this.oSlide.getElementsByTagName("li");
this.index = 0;
}
Slide.prototype.bind = function () {
var that = this;
for (var i = 0; i < this.aLi.length; i++) {
this.aLi[i].index = i;
this.aLi[i].onmouseover = function () {
that.moveTop(this.index);
}
}
}
Slide.prototype.moveTop = function (i) {
this.index = i;
for (var j = 0; j < this.aLi.length; j++) {
this.aLi[j].className = '';
}
this.aLi[this.index].className = 'active';
animate(this.oImgContainer, {
"top": -this.index * 450,
"left": 0
});
}
var oSlide = new Slide();
oSlide.bind();
// ]]>
缓冲运动通常有两种常见的表现:比如让一个div从0运动到500,一种是事件触发的时候,速度很快, 一种是事件触发的时候慢,然后慢慢加快.我们来实现先块后慢的,常见的就是开车,比如刚从高速路上下来的车,就是120km/小时,然后进入匝道,变成40km/时. 或者40km/小时进入小区,最后停车,变成0km/小时. 从120km/小时->40km/小时, 或者40km->0km/小时,都是速度先块后慢,这种运动怎么用程序来表示呢?
可以用目标距离( 500 ) - 当前距离( 200 ) / 一个系数( 比如12 ),就能达到速度由块而慢的变化,当前距离在起点,分子(500 - 0 )最大,所以速度最大,如果当前距离快要接近500,分子最小,除完之后的速度也是最小。
1 <style>
2 div{
3 width: 200px;
4 height: 200px;
5 background:red;
6 position: absolute;
7 left: 0px;
8 }
9 </style>
10 <script>
11 window.onload = function(){
12 var oBtn = document.querySelector( "input" ),
13 oBox = document.querySelector( '#box' ),
14 speed = 0, timer = null;
15 oBtn.onclick = function(){
16 timer = setInterval( function(){
17 speed = ( 500 - oBox.offsetLeft ) / 8;
18 oBox.style.left = oBox.offsetLeft + speed + 'px';
19 }, 30 );
20 }
21 }
22 </script>
23 </head>
24 <body>
25 <input type="button" value="动起来">
26 <div id="box"></div>
27 </body>
<script type="text/java script">//
但是,div并不会乖乖地停止在500px这个目标位置,最终却是停在497.375px,只要查看当前的速度,当前的值就知道原因了
你会发现,速度永远都在0.375这里停着,获取到的当前的距离停在497px? 这里有个问题,我们的div不是停在497.375px吗,怎么获取到的没有了后面的小数0.375呢?计算机在处理浮点数会有精度损失。我们可以单独做一个小测试:
1 <div id="box" style="position:absolute;left:30.2px;width:200px;height:300px;background:red;"></div>
2 <script>
3 var oBox = document.querySelector( '#box' );
4 alert( oBox.offsetLeft );
5 </script>
你会发现这段代码获取到左偏移是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 <style>
2 #box{
3 width: 200px;
4 height: 200px;
5 background:red;
6 position: absolute;
7 left: 900px;
8 }
9 </style>
10 <script>// <![CDATA[
11 window.onload = function(){
12 var oBtn = document.querySelector( "input" ),
13 oBox = document.querySelector( '#box' ),
14 speed = 0, timer = null;
15