南大软院大神养成计划——第十三天

来源:互联网 发布:JSP删除数组 编辑:程序博客网 时间:2024/05/02 18:53

今天是南大软院大神养成计划实施的第十三天,今天学习的主要内容是JS动画效果。

在浏览网页时候,我们经常会看到一些动画,有一些是flash动画,有一些则是用js编写的js动画,比如我们鼠标移动在某一个区域时,这时候出现一个动画效果,这有可能就是js动画,在“JS动画”课程里,我们将这类动画称之为“运动”。

运动框架实现思路:

既然是运动,我们首要定义运动的速度,运动的速度我们可以设置:left,right,height,width,opacity等参数,然后通过SetInterval函数里的间隔时间,就可以设置相应的速度。然后我们就要定义运动的方式,运动方式包括:缓冲运动,多物体运动,任意值运动,链式运动,同时运动。

简单运动:

1.速度动画:速度通过是一种简单的运动,在课程中老师介绍的是横向的速度动画,就是将一个div通过触发mouseover事件,div移出,触发mouseout事件,div又回到原来的位置。通过观看完视频,实现原理就是:通过设置一个定时器setInterval(function,time),然后每个间隔根据移出还是回位,left参数增加或者减少,这样根据v=s/t,我们就可以构造出一个速度出来,也就是可以看到一个动画效果,实现原理非常简单。顺便提一下,老师在实现相关函数的过程中,先完成了粗略的函数,然后分析如何简化函数代码,这也是初学者与高手的区别,初学者在实现相关函数后就万事大吉,而高手在实现了相关函数后就考虑如何优化代码。

js代码:

/*1.3精简参数,
iTarget:偏移目标值
用当前offsetLeft的值与传入的目标值来判断增加和减少
*/
function startMove(iTarget){
clearInterval(timer);//记得每次建立一个新的定时器之前都要关闭以前定时器
var oDiv=document.getElementById('div1');
timer= setInterval(function(){
var speed=0;
//如果当前值大于目标就是正向运动
if(oDiv.offsetLeft > iTarget){
speed=-10;
}else{
//如果小于目标值就是反向运动
speed=10;
};
if(oDiv.offsetLeft==iTarget){
clearInterval(timer);
}else{
oDiv.style.left=oDiv.offsetLeft+speed+'px';
}
}, 30);
}

2.透明动画:透明动画就是通过触发mouseover和mouseout事件来改变一个块级元素的透明度,如鼠标在一张图片上,图片透明度就相应的改变了,鼠标移出,透明度又回归原来的样子,当然这个过程也是要设立一个改变透明度的一个速度。原理和速度动画的原理是一致的,但是这里肯定有人会感到疑问如何设定一个块级元素的透明度呢?下面是相关设立透明度的代码:

css定义透明度:
{filter:alpha(opacity:30);
opacity:0.3;}

JS 改变:
IE:style.filter=‘alpha(opactiy:’+值+')'
非IE .style.opactiy=值/100(火狐或者chrome关于透明度的满值1,IE是100)

透明度动画代码:

window.onload=function(){
var oDiv=document.getElementById("div1");
oDiv.onmouseover=function(){
startMove(100);
}
oDiv.onmouseout=function(){
startMove(30);
}
}
var timer=null;
var alpha=30;//设一个变量为div的透明度,这里时30%的透明度(根据IE浏览器的设定参数)
function startMove(iTarget){
var oDiv=document.getElementById("div1");
clearInterval(timer);//记得设立一个新的定时器之前一定要清除以前的定时器
timer=setInterval(function(){
var speed=0;
// 当 iTarget=30时
if(alpha>iTarget){
speed=-10;
}else{
// 当itarget=100的时候
speed=10;
}
if(alpha==iTarget){
clearInterval(timer);
}else{
alpha+=speed;
oDiv.style.filter='alpha(opacity:'+alpha+')';
oDiv.style.opacity=alpha/100;
}
},30)
}

缓冲运动:

缓冲运动与简单速度运动不一样的地方就是运动速度不是一成不变的,而是会慢慢减少,做匀减速运动,所以缓冲运动主要原理和速度动画是一样的,主要差别在于速度的定义,下面我们看看速度的定义和实现需要了解的知识:

1、速度的定义:
var speed=(目标值-当前值(offset))/参数;//参数越大,速度越慢,观察的效果越明显
2、取整函数:
向下取整:Math.floor(3.55);//3.55是取整的数值,结果为:3
向上取整:Math.ceil(3.35);//结果为:4
3、速度的取整判断:
speed=speed>0?Math.ceil(speed):Math.floor(speed);// 
条件操作位 这个表达式的意思是如果speed大于0(关系表达式返回true),则将Math.ceil(speed)向下去整赋值给 speed,反之则将Math.floor(speed)向上去整赋值给 speed

可以看出这里的速度是会随着left里目标值越来越近,速度也就会相应的减慢,缓冲效果相比较简单的速度动画给人的效果要好一些。

下面是实现代码:

var timer=null;
function startMove(iTarget){
var oDiv=document.getElementById('div1');
clearInterval(timer);
timer=setInterval(function(){
var speed=(iTarget-oDiv.offsetLeft)/10;//除法会使数值出现小数点,凡是操作速度的,就要做取整,不然会出问题
////如果speed大于0向下取整,如果speed小于0向上取整 .2ceil2 1.2floor2
speed=speed>0?Math.ceil(speed):Math.floor(speed);
if(oDiv.offsetLeft==iTarget){
clearInterval(timer);
}else{
oDiv.style.left=oDiv.offsetLeft+speed+'px';
}
},30);
}

多物体运动:

多物体运动顾名思义就是一个网页中有多个div会包含动画效果,每个div的动画可以相同也可以不同。在实现多物体运动,我们应该避免所有元素共用同一个东西,比如变量,否则可能会造成在快速鼠标移动时,动画效果会出现一些bug,带给用户不好的体验。

多物体运动的原理和缓冲运动类似,我们这里说的是多个div元素含有缓冲运动效果。

主要原理如下:

for循环来为每一个TagNameList[i]添加事件 并添加属性来区分各自的定时器(用于取消)
利用参数中的this来指定所选择的当前元素
多物体不要共用一个值,在对象上定义一个单独的属性保持值
存在多项共用一个值,并且这个值会发生改变时,最好单独给赋值,避免出现争用的情况。

js代码如下:

<script>
window.onload=function(){
var aLi=document.getElementsByTagName('li');
for(var i=0;i<aLi.length;i++){
// 给每一个li设置一个timer,才不会致使他们去抢timer
aLi[i].timer=null;
aLi[i].onmouseover=function(){
startMove(this,400);
};
aLi[i].onmouseout=function(){
startMove(this,200)
}
}
var oDivLi=document.getElementsByTagName('div');
for(var j=0;j<oDivLi.length;j++){
oDivLi[j].timer=null;
oDivLi[j].alpha=30;
oDivLi[j].onmouseover=function(){
startMove1(this,100);
};
oDivLi[j].onmouseout=function(){
startMove1(this,30);
}
}
};

获取样式:

为什么要获取样式呢?我们先看看dom.offsetWidth和dom.style.width的区别:

offsetWidth 包含了对象的边线的宽度
width 若你不在HTML里明确指定这个值,那它的返回值会不对。
从这里可以看出这两则有一点不同,这一点不同也决定了我们在不同场景下应该使用谁。在很多js代码中,为了实现一些动画效果,如改变css样式的效果,则需要获取相应的样式然后去改变,所以我们应该懂得如何去获取相应的样式。

作为初学者的我们,也许有这样的疑问dom.style和currentstyle获取样式有什么差别吗?这两个函数都可以获取对象。下面看看差别

两种方法差别:

1、dom.style.xxx 这种写法只能获取行内样式 例如 <div style="width:200px"></div>
div.style.width能获取到是200px,但是没有出现在style="" 引号中的样式是获取不到的.

但是假如我们要修改css样式时,我们用dom.style.xxx='参数'去修改相关css样式,按照个人理解就相当于加了一个行内样式,然后按照css样式优先级,行内样式优先级最高,所以这样就改变了css样式。
2、万能方法
getComputedStyle(div,null).xxx 这个是标准方法,需要做一下兼容
currentStyle 是IE的
所以看完以上的分析,我们可以自己封装一个兼容所有浏览器的获取任意的style的函数:
function getStyle(obj,style){
if(obj.currentStyle){
return obj.currentStyle[style];
}else{
return getComputedStyle(obj,null)[style];
}
}

使用方法如getStyle(obj,width).

任意值运动:

任意值运动就是任意属性的运动效果,如width,height,透明度的变化,这些我们只通过一个框架就可以实现了。实现的主要原理还是跟前面几类的运动差不多,设置定时器,然后设置改变属性的速度就能完成相应的动画效果了。

这里就简单说一下需要了解到的新知识:

传入的透明度和其他属性不一样,要与其他属性区分开来。
alert(0.07*100)输出的是一个小数,因为计算机无法准确的去存储某个小数值,所以要利用Math.round(四舍五入)来取整。

接下来看代码:

function startMove(obj,attr,iTarget){//obj是元素对象,attr是css样式,如‘height’,‘width’,itarget是目标值,如高度的目标值是100
clearInterval(obj.timer);//清除定时器,由于是多物体运动,所以要根据不同物体清除不同物体的定时器
obj.timer=setInterval(function(){//1给每个物体设置不同的定时器
var icur=null;
if(attr=='opacity'){
icur=Math.round(parseFloat(getStyle(obj,attr))*100);
}else{
icur=parseInt(getStyle(obj,attr));
}
var speed=(iTarget-icur)/8;
speed=speed>0?Math.ceil(speed):Math.floor(speed);
if(icur==iTarget){
clearInterval(obj.timer);//1.2+++
}else{
if(attr=='opacity'){
obj.style.filter='alpha(opacity:'+(icur+speed)+')';
obj.style.opacity=(icur+speed)/100;
}else{
obj.style[attr]=icur+speed+'px';
}

}
},30);
}
function getStyle(obj,attr){
if(obj.currentStyle){
return obj.currentStyle[attr];
}else{
return getComputedStyle(obj,false)[attr];
}
}

上面就是今天所学的知识,物体运动的基本原理还是设定定时器,,然后根据速度改变属性,这样就实现了我们想要的动画效果。

期待明天的,今天学习到的知识非常有趣,希望大家能够自己设计一种运动。

0 0