JS 动画初探(上)
我们先来做一个简单的动画,让一个div横向移动。
既然是要横向移动,我们就要对这个div的left属性进行设置,那么这里就可以使用间歇调用的方式不断的去增加left的值,然后到了某一个指定的位置时停止。
html部分:
<div id="box"></div>
css部分:
#box {
width: 100px;
height: 100px;
background-color: red;
position: absolute;
top: 300px;
left: 300px;
}
js部分:
//调用代码
$(function(){
$('#box').animation('left',10,600,50);
});
//封装库
Base.prototype.animation = function(attr,step,end,time) {
for(var i = 0;i<this.arr.length;i++){
var element = this.arr[i];
var timer = setIntarval(function(){
element.style[attr] = parseInt(getStyle(element,attr)) + step + 'px';
if(parseInt(getStyle(element,attr)) >= end) {
element.style[attr] = end + 'px';
clearInterval(timer);
}
},time);
}
return this;
}
//获取计算后的style
function getStyle(arr,attr) {
if(typeof window.getComputedStyle != 'undefined') {
return window.getComputedStyle(arr,null)[attr];
}else if(typeof arr.currentStyle != 'undefined') {
return arr.currentStyle[attr];
}
}
通过传入方向,每次移动多少,最终的位置,超时调用的间隔时间,来进行移动,这样形成了一个初步的移动。
其中,在if判断当前位置已经>=最终位置时,我们让他的style[attr] = end,这样可以防止,当移动的距离超出一点的时候不会停在那里不动,导致有一些差异,而且这个超出部分移动的时间是和 element.style[attr] = parseInt(getStyle(element,attr)) + step + 'px';共用的,也就是说同时完成,这样不会造成div移动超出后会有一个往回走的不自然感。
为什么会超出,那是因为你不可能每次设置的都是可以相加然后等于end的值吧,就好像你每次移动7px,你能最终通过7+7+7+7....这样加下去,最终等于50吗,这明显不可能的事情,所以if判断后才会需要重新设置style[attr] = end。
重新设置后再将超时调用删除。
getStyle(arr,attr)返回的是计算后的值,但是他会带单位,返回的是300px,这是一个string类型,我们要将其转为数值,可以通过正则的方式匹配数字,然后Number(正则匹配的数字),转换为num类型,这里直接使用parseInt()转换,如果这个字符串开头就是数字,那么便会转换这个数字,其他的字符被忽略。
简单的动画制作完毕,但是我们进行优化。
超时调用的时间一般来说都是固定的,而且数值过时间久了,根本不知道都代表什么意思,这里就要用键对值的形式传参,然后还要判断是往左还是往右。
判断往左往右
如果当前元素的位置大于移动的终点,那么就说明要往左,如果移动的终点大于当前位置,就是往右。
if(parseInt(getStyle(element,attr)) > end) step = -step;
通过键对值的方式传参
//调用代码
$(function(){
$('#box').animation({
'attr' : 'left',
'step' : 7,
'start' : 300,
'end' : 50,
'time' : 30
})
});
//封装库
Base.prototype.animation = function(obj) {
for(var i = 0;i<this.arr.length;i++){
var element = this.arr[i];
var attr = obj['attr'] != undefined ? obj['attr'] : 'left';
var step = obj['step'] != undefined ? obj['step'] : 10;
var start = obj['start'] != undefined ? obj['start'] : parseInt(getStyle(element,attr));
var time = obj['time'] != undefined ? obj['time'] : 50;
var end = obj['end'];
element.style[attr] = start + 'px';
if(start > end) step = -step;
var timer = setInterval(function(){
element.style[attr] = parseInt(getStyle(element,attr)) + step + 'px';
if(step > 0 && parseInt(getStyle(element,attr)) >= end) {
element.style[attr] = end + 'px';
clearInterval(timer);
}else if(step < 0 && parseInt(getStyle(element,attr)) <= end) {
element.style[attr] = end + 'px';
clearInterval(timer);
}
},time)
}
return this;
}
//获取计算后的style
function getStyle(arr,attr) {
if(typeof window.getComputedStyle != 'undefined') {
return window.getComputedStyle(arr,null)[attr];
}else if(typeof arr.currentStyle != 'undefined') {
return arr.currentStyle[attr];
}
}
通过键对值的方式传值,end的值是必须的,其他都通过三元的方式设置了备用的值,然后还添加了一个start的起始位置值,我们可以设置元素的起始位置。
然后就是考虑到往左移动的时候,step是负值,如果一直减下去会超出边框外,所以也要做个if判断,如果元素的位置已经小于end的值,说明已经往左移动过头了,所以也和上面一样, element.style[attr] = end + 'px';然后删除这个超时调用。
上面虽然都差不多了,但是end的设置还是差点意思,因为你要算好元素要移动到那个位置,而不能直接增加,比如我要移动20个像素,那么你就要计算一下,当前位置+20再填到end中去,这样太麻烦了。
增量移动
将end的判断改为:
var end = start + obj['end'];
这样每次只要填需要移动多久即可。
本文系作者 @木灵鱼儿 原创发布在木灵鱼儿站点。未经许可,禁止转载。
暂无评论数据