js实现动画效果

用js实现动画效果的主要思想是利用setInterval()函数.此函数可按照指定的周期(以毫秒计)来调用函数或表达式,并且该方法会不停地调用函数,直到clearInterval()被调用或窗口被关闭。由setInterval()返回的ID值可用作clearInterval()方法的参数。

1.单个元素匀速运动

以匀速水平方向运动的元素为例,该方法传入三个参数,分别为要移动元素,要移动到的目标和移动的速度。其中,若速度大于0,表示元素从左向右移动;若速度小于0,表示元素从右向左移动
function startMove(ele,iTarget,speed){
	var timer=null;
	clearInterval(timer);//防止方法重复执行时,计时器的重复使用

	timer=setInterval(function(){
		if(ele.offsetLeft!=iTarget){
			ele.style.left=ele.offsetLeft+speed+"px";}
		},100);
	}

实现当鼠标在元素上移动时,使元素从左向右移动的效果
	var move=document.getElementById("move");
	move.onmousemove=function(){startMove(move,500,10);}

2.单个元素透明度的匀速变化

设元素的初始透明度为opacity:0.3或filter:alpha(opacity:30),透明度匀速变化的方法如下
function startOpacity(ele,iTarget,speed){
	var timer=null;
	var alpha=30;//元素透明度的值获取较难,这里直接给出
	clearInterval(timer);
	timer=setInterval(function(){
	if(alpha!=iTarget){
		alpha+=speed;
		ele.style.filter='alpha(opacity:'+alpha+')'; //设置IE的透明度
		ele.style.opacity= alpha/100; //设置fierfox等透明度,注意透明度值是小数
	}
	},50);
    }
实现当鼠标在元素上移动时,使元素透明度从0.3变为1,或从30变为100
        var move=document.getElementById("move");
	move.onmousemove=function(){
		startOpacity(move,100,10);}

3.单个元素的缓冲运动

缓冲运动的本质是速度的不断变化,元素运动时越靠近目标其速度越小,实现方法如下
function bufferMove(ele,iTarget){
	var timer=null;
	clearInterval(timer);
	timer=setInterval(function(){
		var speed=(iTarget-ele.offsetLeft)/200;
		if(speed>0){
			speed=Math.ceil(speed);//避免速度值出现小数的状况,因为元素有关的像素值必须为整数
			speed=Math.floor(speed);
		}
		if(ele.offsetLeft!=iTarget){
			ele.style.left=ele.offsetLeft+speed+"px";}
		},100);
	}
实现当鼠标在元素上移动时,元素做缓冲运动到达目标值
	var move=document.getElementById("move");
	move.onmousemove=function(){
		bufferMove(move,500);
	}

4.多物体的缓冲运动

多物体的运动需要注意的是物体之间公共的变量或计时器,为了防止多物体之间的共用,需要将物体之共用的部分私有化
本例所实现的功能时,当鼠标移动到三个li元素中的一个时,其宽度从200px变为500px,移出时宽度从500px变为200px
        var container=document.getElementById("container");
	var iLi=container.getElementsByTagName("li");
	for(var i=0,length=iLi.length;i<length;i++){
		iLi[i].timer=null;//将计时器私有
		iLi[i].onmouseover=function(){
			bufferMove(this,500);//注意,这里用到了闭包的知识,this并不等于iLi[i],因为变量i即使bufferMove的活动对象,同时也是其父方法的活动对象,二者共用一个内存空间,所以如果在这里用<span style="font-family: Arial, Helvetica, sans-serif;">iLi[i],该值就相当于iLi[3]</span>

		}
		iLi[i].onmouseout=function(){
			bufferMove(this,200);
		}
	}
	function bufferMove(ele,iTarget){
	
	clearInterval(ele.timer);

	ele.timer=setInterval(function(){
		var speed=(iTarget-ele.offsetWidth)/10;
		if(speed>0){
			speed=Math.ceil(speed);
		}else{
			speed=Math.floor(speed);
		}
		if(ele.offsetWidth!=iTarget){
			ele.style.width=ele.offsetWidth+speed+"px";}
		},100);
	}

当li元素中没有边框和内边距样式时,此方法有效,但当含有边框和内边距样式时,由于offsetWidth属性包含元素的宽度、内边距和元素的边框,其运行后的元素宽度和预定的宽度不同,为了解决这个问题,我们需要将offsetWidth属性变改为width属性,但是当width属性不是在行内样式定义时,获取width属性值需要调用currentStyle方法(IE)或getComputedStyle()方法(火狐和Chrome)。本文假设为li元素设置了边框属性,相关代码如下
                function getStyle(ele,attr){
		if(ele.currentStyle){
			return ele.currentStyle[attr];
		}else{
			return getComputedStyle(ele,false)[attr];

		}
	}
	var container=document.getElementById("container");
	var iLi=container.getElementsByTagName("li");
	for(var i=0,length=iLi.length;i<length;i++){
		iLi[i].timer=null;
		iLi[i].onmouseover=function(){
			bufferMove(this,500);
		}
		iLi[i].onmouseout=function(){
			bufferMove(this,200);
		}
	}
	function bufferMove(ele,iTarget){
	
	clearInterval(ele.timer);

	ele.timer=setInterval(function(){
		var speed=(iTarget-parseInt(getStyle(ele,"width")))/10;
		if(speed>0){
			speed=Math.ceil(speed);
		}else{
			speed=Math.floor(speed);
		}
		if(parseInt(getStyle(ele,"width"))!=iTarget){
			ele.style.width=parseInt(getStyle(ele,"width"))+speed+"px";}
		},100);
	}
 
  

编写方法,使该方法能够对不同的元素的不同属性改变,以产生运动效果。该方法传入三个值,分别为要操作的元素、要操作的元素属性和属性的目标值,由于透明度的属性值与其他属性值不同,需要单独考虑

function bufferMove(ele,attr,iTarget){
	
	clearInterval(ele.timer);
	
    
	ele.timer=setInterval(function(){
		console.log(ele);
		//获取当前的属性值
		var icur=0;
    if(attr=="opacity"){
		icur=Math.round(parseFloat(getStyle(ele,attr))*100);
		
	}else{
		icur=parseInt(getStyle(ele,attr));
	}
		var speed=(iTarget-icur)/2;
		if(speed>0){
			speed=Math.ceil(speed);
		}else{
			speed=Math.floor(speed);
		}
		if(icur==iTarget){
				clearInterval(ele.timer);
				
		}else{
			if(attr=="opacity"){
			ele.style[attr]=(icur+speed)/100;
			ele.style.filter="filter:alpha(opacity"+(icur+speed)+")";
			console.log(getStyle(ele,"opacity"));
			console.log(speed);
			}else{
			ele.style[attr]=icur+speed+"px";}
		
		
		}},50);
	}

5. 多物体的链式运动

链式运动就是元素一次运动完成后,随后触发第二次运动。

for(var i=0,length=iLi.length;i<length;i++){
		iLi[i].timer=null;
	    iLi[i].icur=0;
		iLi[i].onmouseover=function(){
		
			 bufferMove(this,"opacity",100,function(){
				
				 bufferMove(this,"height",100);
			})
		}
		iLi[i].onmouseout=function(){
			bufferMove(this,"height",80,function(){
				bufferMove(this,"opacity",30)
			});
		}
	}
	function bufferMove(ele,attr,iTarget,fn){
		clearInterval(ele.timer);
	ele.timer=setInterval(function(){
		//获取当前的属性值
		
    if(attr=="opacity"){
		ele.icur=Math.round(parseFloat(getStyle(ele,attr))*100);
	}else{
		ele.icur=parseInt(getStyle(ele,attr));
	}

		var speed=(iTarget-ele.icur)/2;
		if(speed>0){
			speed=Math.ceil(speed);
		}else{
			speed=Math.floor(speed);
		}

		if(ele.icur==iTarget){
			
				clearInterval(ele.timer);
				//传入返回的ele元素,实现函数的回调
				if(fn){fn.call(ele);}
		}else{
			if(attr=="opacity"){
			ele.style[attr]=(ele.icur+speed)/100;
			ele.style.filter="filter:alpha(opacity"+(ele.icur+speed)+")";
			}else{
			ele.style[attr]=ele.icur+speed+"px";}
		
		
		}},50);

		return ele;
	}

6 多物体同时运动

多物体同时运动,需引入json

<span style="font-size:12px;font-weight: normal;">var container=document.getElementById("container");
	var iLi=container.getElementsByTagName("li");
	
	for(var i=0,length=iLi.length;i<length;i++){
		iLi[i].timer=null;
		iLi[i].onmouseover=function(){
		
			 bufferMove(this,{opacity:100,height:81});
		}
		iLi[i].onmouseout=function(){
			bufferMove(this,{height:80,opacity:30});
			
		}
	}
	function bufferMove(ele,json,fn){
		var flag=true;
		
			
		clearInterval(ele.timer);
	    ele.timer=setInterval(function(){

		//获取当前的属性值
		for(var attr in json){
    if(attr=="opacity"){
		ele.icur=Math.round(parseFloat(getStyle(ele,attr))*100);
	}else{
		ele.icur=parseInt(getStyle(ele,attr));
	}

		var speed=(json[attr]-ele.icur)/2;
		if(speed>0){
			speed=Math.ceil(speed);
		}else{
			speed=Math.floor(speed);
		}

		if(ele.icur!=json[attr]){
			flag=false;
		}
			
				
			if(attr=="opacity"){
			ele.style[attr]=(ele.icur+speed)/100;
			ele.style.filter="filter:alpha(opacity"+(ele.icur+speed)+")";
			}else{
			ele.style[attr]=ele.icur+speed+"px";
			}
		
		if (flag) {
			clearInterval(ele.timer);
				//回调函数
				
			if(fn){fn.call(ele);}
		} }},50);

		return ele;
	}</span>



你可能感兴趣的:(JavaScript,动画)