码迷,mamicode.com
首页 > Web开发 > 详细

JS动画

时间:2016-08-21 07:32:50      阅读:406      评论:0      收藏:0      [点我收藏+]

标签:

http://www.imooc.com/video/2878


1、速度 (改变left、right、width、height、opacity)

2、缓冲运动

3、多物体运动

4、任意值变化

5、链式运动

6、同时运动


 

1.1 改变left值,也就是改变位置

举个栗子,例子1

布局代码

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<style type="text/css">
* {
    padding: 0px;
    margin: 0px;
}

#div1 {
    width: 100px;
    height: 100px;
    background: red;
    float: left;
    position: relative;
}

#share {
    width: 20px;
    height: 20px;
    background: blue;
    position: absolute;
    left: 100px;
}
</style>

<body>
    <div id="div1">
        <span id="share"></span>
    </div>
</body>

下面是实现更改div的left值的js代码

<script type="text/javascript">
window.onload = function() {
    var oDiv = document.getElementById("div1");
    oDiv.onmouseover = function() {
        startMove();//鼠标移入调用的函数
    }

    oDiv.onmouseout = function(){
        startMove1();//鼠标移出调用的函数
    }
    //
    var timer = null;//
    function startMove() {
        var oDiv = document.getElementById("div1");
        clearInterval(timer);//每次调用先清掉left加减的动作
        timer = setInterval(function() {
            if (oDiv.offsetLeft == 100) {//判断条件
                clearInterval(timer);
            } else {
                oDiv.style.left = oDiv.offsetLeft + 10 + "px";//当前对象的left值进行加减
            }
        }, 30);
    }
    //
    function startMove1() {
        var oDiv = document.getElementById("div1");
        clearInterval(timer);
        timer = setInterval(function() {
            if (oDiv.offsetLeft == 0) {
                clearInterval(timer);
            } else {
                oDiv.style.left = oDiv.offsetLeft - 10 + "px";
            }
        }, 30);
    }
    //

}
</script>

  通过,比较发现,右移动和左移动的函数基本一致。那么可以考虑整合为一个函数,只需要传入参数就可以了。

这个例子,就是传入两个参数,一个就是移动的速度加减的位移量,还有一个就是移动到的目标位置的值。也就是写成

function startMove(speed,iTarget){

//函数体中

}

当然如果只想传入一个参数那么,可以在函数体内做一个判断

var speed=0;

if(oDiv.offsetLeft>iTarget){

speed=-10;//当前位置大于目标值进行减法

}else{

speed=10;//当前位置小于目标值,进行加法

}

1.2改变透明度

类似于改变left值

但是因为没有offsetAlpha这个东西,我们需要首先定义alpha的值

例如:var alpha=30;

函数里面的判断语句写法如下:

var timer=null;

timer = setInterval(function(){
            var speed=0;
            if(alpha>iTarget){
                speed=-10;
            }else{
                speed=10;
            }
            if (alpha==iTarget) {
                clearInterval(timer)
            }else{
                alpha+=speed;
                oDiv.style.filter="alpha(opacity:"+alpha+")";//ie
                oDiv.style.opacity=alpha/100;//火狐
            }

        },30)


 

2 缓冲运动

还是用例子1

缓冲运动意思就是位置移动的速度,进行一个渐变。那么speed这个参数就是不断改变的。代码更改为:

timer = setInterval(function() {
            var speed=(iTarget-oDiv.offsetLeft)/10;//这里就是用目标值减去移动对象的当前值,因为移动对象的当前值不断改变,所以speed也不断改变
            if (oDiv.offsetLeft == iTarget) {//判断条件
                clearInterval(timer);
            } else {
                oDiv.style.left = oDiv.offsetLeft + speed + "px";//当前对象的left值进行加减
            }
        }, 30);

但是这么更改了还是会出现一些问题,就是代码运行完毕,有可能出现left值为小数点的现象,并且与预期效果还会出现误差。因为对象的left值等于当前的值加上一个

speed。

如何解决呢?

通过Math方法对speed进行取整。speed=speed>0?Math.ceil(speed):Math.floor(speed);

代码的意思就是,speed大于0,向上取整,小于0的时候,向下取整。


 

3.多物体运动

举个例子,例子2

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<style type="text/css">
* {
    padding: 0px;
    margin: 0px;
}

ul,
li {
    list-style: none;
}

ul li {
    width: 200px;
    height: 40px;
    margin-top: 20px;
    margin-left: 100px;
    background: red;
    filter: alpha(opacity: 30);
    opacity: 0.3;
}

ul li:first-child {
    background: blue;
}

ul li:last-child {
    background: yellow;
}
</style>

<body>
    <div id="div1">
        <ul>
            <li></li>
            <li></li>
            <li></li>
        </ul>
    </div>
</body>
<script type="text/javascript">
var aLi = document.getElementsByTagName("li");
for (var i = 0; i < aLi.length; i++) {
    aLi[i].timer = null;//定义每个对象,防止,运动函数发生冲突
    aLi[i].onmouseover = function() {
        startMove(this, 400);//鼠标移入目标值为400
    }
    aLi[i].onmouseout = function() {
        startMove(this, 200);//鼠标移出
    }
}

function startMove(obj, iTarget) {//传入2个参数,obj为this自身,iTarget为目标值
    clearInterval(obj.timer);//清除运动,防止函数无限调用
    obj.timer = setInterval(function() {
        var speed = (iTarget - obj.offsetWidth) / 8;
        speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);//speed取整
        if (obj.offsetWidth == iTarget) {
            clearInterval(obj.timer);
        } else {
            obj.style.width = obj.offsetWidth + speed + "px";//更改当前对象的width
        }
    }, 30)
}
</script>

</html>

这个例子就是取得对象集,对每个对象进行变换,遍历后,通过this取得鼠标移入的对象。

另外,如果要改变透明度,可以对每个对象的alpha赋值,例如:

for (var i = 0; i < aLi.length; i++){

oDiv[i].alpha=30;

}

另外值的一提的是,有时候,我们需要更改对象的样式不局限于宽高等,并且调用css样式的时候,有时候会出现一些小问题。

因为:

样式表有三种方式

内嵌样式(inline Style) :是写在Tag里面的,内嵌样式只对所有的Tag有效。

内部样式(internal Style Sheet):是写在HTML的里面的,内部样式只对所在的网页有效。

外部样式表(External Style Sheet):如果很多网页需要用到同样的样式(Styles),将样式(Styles)写在一个以.css为后缀的CSS文件里,然后在每个需要用到这些样式(Styles)的网页里引用这个CSS文件。 最常用的是style属性,在JavaScript中,通过document.getElementById(id).style.XXX就可以获取到XXX的值,但意外的是,这样做只能取到通过内嵌方式设置的样式值,即style属性里面设置的值。

那么解决方法,可以引入currentStyle,getComputedStyle 。currentStyle针对IE浏览器,getComputedStyle针对firefox。

style 标准的样式!可能是由style属性指定的! 
runtimeStyle 运行时的样式!如果与style的属性重叠,将覆盖style的属性! 
currentStyle 指 style 和 runtimeStyle 的结合! 
style 内联的样式 
currentStyle 代表了在全局样式表、内嵌样式和 HTML 标签属性中指定的对象格式和样式 
runtimeStyle 代表了居于全局样式表、内嵌样式和 HTML 标签属性指定的格式和样式之上的对象的格式和样式 
(火狐中没有currentStyle 和runtimeStyle) 
getStyle(元素id,获取属性); 
获取元素style标签内的样式 
elem.style[styles] || elem.style[styles.camelize()] 
支持传入"font-size"的写法 
但这并不是最终的样式 . 
获取最终样式 有两终办法 一个是 
document.defaultView.getComputedStyle //w3c的方法 
还有就是通过 elem.currentStyle["..."] //ie下的方法 
currentStyle 方法 需要将带"-"字符的属性 需要通过String.prototype.camelize转换成ie可识别的属性 

if(value=="auto" && ["width","height"].contains(styles) && elem.style.display!="none"){ 
value=elem["offset"+styles.capitalize()]+"px"; 
} ----什么鬼

  当然,我们可以写一个函数。

如下:

function getStyle(obj,attr){
    if(obj.currentStyle){
        return obj.currentStyle[attr];
    }else{
        return getComputerStyle(obj,false)[attr];
    }
}
//获取样式简洁版
function getStyle(obj, attr) {
    return obj.currentStyle ? obj.currentStyle[attr] : getComputedStyle(obj, false)[attr];
}
//opacity 设置透明度
function setOpacity(elem, value) {
    elem.filters ? elem.style.filter = ‘alpha(opacity=‘ + value + ‘)‘ : elem.style.opacity = value / 100;
}

使用方法,例如增加例子1的font-size:

oDiv.style.fontSize = parseInt(getStyle(oDiv,‘fontSize‘))+1+‘px‘;

那么就可以写一个例子了,如下:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<style type="text/css">
* {
    padding: 0px;
    margin: 0px;
}

ul,
li {
    list-style: none;
}

ul li {
    width: 200px;
    height: 40px;
    margin-top: 20px;
    margin-left: 100px;
    background: red;
    opacity: 0.3;
    filter: alpha(opacity: 30);
}

ul li:first-child {
    background: blue;
}

ul li:last-child {
    background: yellow;
}
</style>

<body>
    <div id="div1">
        <ul>
            <li id="li1"></li>
            <li id="li2"></li>
            <li></li>
        </ul>
    </div>
</body>
<script type="text/javascript">
var aLi = document.getElementsByTagName("li");
for (var i = 0; i < aLi.length; i++) {
    var Li1 = document.getElementById("li1");
    var Li2 = document.getElementById("li2");
    Li1.onmouseover = function() {
        startMove(this, width, 400);
    }
    Li1.onmouseout = function() {
        startMove(this, width, 200);
    }
    Li2.onmouseover = function() {
        startMove(this, opacity, 100);
    }
    Li2.onmouseout = function() {
        startMove(this, opacity, 30);
    }
}
//这个是getStyle函数
function getStyle(obj, attr) {
    return obj.currentStyle ? obj.currentStyle[attr] : getComputedStyle(obj, false)[attr];
}

function startMove(obj, attr, iTarget) { 
    clearInterval(obj.timer); 
    obj.timer = setInterval(function() {
        var icur = 0;
        if (attr == opacity) {
            icur = Math.round(parseFloat(getStyle(obj, attr)) * 100);//这里注意Math.round()用法,当attr透明度设置时,进行这种取值。
        } else {
            icur = parseInt(getStyle(obj, attr))//attr不是opacity时
        }
        var speed = (iTarget - icur) / 8;
        speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed); //speed取整
        if (icur == iTarget) {
            clearInterval(obj.timer);
        } else {
            if (attr == opacity) {
                obj.style.filter = alpha(opacity: + (icur + speed) + );//IE
                obj.style.opacity = (icur + speed) / 100;//火狐FF
            } else {
                obj.style[attr] = icur + speed + "px";
            }

        }
    }, 30)
}
</script>

4.链式运动

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<style type="text/css">
* {
    padding: 0px;
    margin: 0px;
}

ul,
li {
    list-style: none;
}

ul li {
    width: 200px;
    height: 100px;
    margin-top: 20px;
    margin-left: 100px;
    background: red;
}
</style>

<body>
    <div id="div1">
        <ul>
            <li id="li1"></li>
        </ul>
    </div>
</body>
<script type="text/javascript">
window.onload = function() {
    var Li = document.getElementById("li1");

    Li.onmouseover = function() {

        startMove(Li, {
            width: 400,
            height: 200
        }, function() {
            startMove(Li, {
                opacity: 30
            })
        });
    }
}

function getStyle(obj, attr) {
    return obj.currentStyle ? obj.currentStyle[attr] : getComputedStyle(obj, false)[attr];
}

function startMove(obj, json, fn) { //json用一个for-in,格式{属性名1:数值,属性名2:数值...}。

    clearInterval(obj.timer);
    obj.timer = setInterval(function() {
        var flag = true; //立个flag,
        for (var attr in json) {//这里forin

            //1.取当前值
            var icur = 0;
            if (attr == opacity) {
                icur = Math.round(parseFloat(getStyle(obj, attr)) * 100);
            } else {
                icur = parseInt(getStyle(obj, attr))
            }

            //2.算速度
            var speed = (json[attr] - icur) / 8;
            speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);

            //3.检测停止

            if (icur != json[attr]) { //当这个条件成立时,flag为false,所以clearInterval(obj.timer)还不能执行,当这个条件不成立时,就执行if(flag){这里面clearInterval(),之后再去判断有没没有fn传入}
                flag = false;
            }

            if (attr == opacity) {
                obj.style.filter = alpha(opacity: + (icur + speed) + ); //IE
                obj.style.opacity = (icur + speed) / 100; //火狐FF
            } else {
                obj.style[attr] = icur + speed + "px";
            }

            if (flag) {
                clearInterval(obj.timer);
                if (fn) {
                    fn();
                }
            }

        }
    }, 30)
}
</script>

这里注意的是,设置了个标识变量flag,用来作为控制一段语句是否运行的标志,当条件成立时,才去执行一段代码。

这例子解释为,当传入的所有属性的icur值都到达目标值json[attr]。那么才去执行clearInterval,

否则if (flag) { clearInterval(obj.timer); if (fn) { fn(); } }这段代码无法执行。

 

还有for..in用法。

for (变量 in 对象)
{
    在此执行代码
}

“变量”用来指定变量,指定的变量可以是数组元素,也可以是对象的属性。

这个例子中传入的对象为json={width:xx,

  height:xx,

  opacity:xx

}

 

举个例子:

var json={width:100,height:200}
for(attr in json){
console.log(i)
}
//运行结果  width  height
var json={width:100,height:200}
for(attr in json){
console.log(json[attr])
}
//运行结果 100 200

  


 


 


 


 


 


 


 


 

 

JS动画

标签:

原文地址:http://www.cnblogs.com/aixiao044/p/5792067.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!