我们先来做一个简单的动画,让一个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()转换,如果这个字符串开头就是数字,那么便会转换这个数字,其他的字符被忽略。

JS 动画初探1

简单的动画制作完毕,但是我们进行优化。

超时调用的时间一般来说都是固定的,而且数值过时间久了,根本不知道都代表什么意思,这里就要用键对值的形式传参,然后还要判断是往左还是往右。

判断往左往右

如果当前元素的位置大于移动的终点,那么就说明要往左,如果移动的终点大于当前位置,就是往右。

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'];

这样每次只要填需要移动多久即可。

分类: JavaScript 标签: animation

评论

暂无评论数据

暂无评论数据

目录