前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >js动画效果大全_jquery 动画

js动画效果大全_jquery 动画

作者头像
全栈程序员站长
发布2022-09-27 16:14:54
12.2K0
发布2022-09-27 16:14:54
举报
文章被收录于专栏:全栈程序员必看

在一些动画设置中,我们可以用CSS中已有的动画属性方便的设置动画效果,比如说animation动画,transition过渡,它们结合一些2D,3D变换可以达到可观的动画效果,但是涉及到更多更加复杂的动画这个时候我们还要基于JavaScript实现。在这里我们定义一个JavaScript中一个实用的函数以便今后的设置。

在这里插入图片描述
在这里插入图片描述

动画基础

(1)定时器setTimeout

动画的设置是在一个连续间隔的时间内,变换关键帧,在人眼的视觉暂留下连续起来。这个时间间隔如何实现?时间间隔的实现依赖于setTimeout定时器API,今后的动画设置也将基于这个API。

setTimeout能够让某个函数在经过一段预定时间之后才开始执行,带有两个参数。第一个参数是要执行函数的名字,第二个参数则是一个数值,表示间隔的时间长短:
使用方法:setTimeout(“function()”,interval)
代码语言:javascript
复制
window.onload=setTimeout("changeNumber()",2000);//2s后调用此函数
function changeNumber()
{ 
   
	var test=document.getElementById("test");
	test.innerHTML="warning!";
}
定时器解除clearTimeout

我们可以像清除浮动那样清除定时器,用clearTimeout(variable). 使用方法:先将定时器赋值给一个变量,然后将这个变量作为clearTimeout的参数:

代码语言:javascript
复制
window.onload=function()
{ 
   
	var timer=setTimeout("changeNumber()",2000);
	clearTimeout(timer);
}
function changeNumber()
{ 
   
	var test=document.getElementById("test");
	test.innerHTML="warning!";
}

这样一来定时就被解除了.

(2)递归函数

既然有了定时器,我们就能基于定时器API来设置动画了。如何设置动画?我们需要在间隔时刻改变目标的位置,直到到达终点,只要这个间隔足够小,人眼就会将其视为连续的平滑动画。我决定定义一个moveElement函数,在间隔时刻改变目标的位置直到到达终点:

代码语言:javascript
复制
function moveElement(elementId,final_x,final_y,interval)
{ 
   
	if(!document.getElementById) return false;
	if(!document.getElementById(elementId)) return false;
	var elem=document.getElementById(elementId);
	var x=parseInt(elem.style.left);
	var y=parseInt(elem.style.top);
	if(x==final_x&&y==final_y) return true;//边界条件
	if(x<final_x){ 
   x++;}
	if(x>final_x){ 
   x--;}
	if(y<final_y){ 
   y++;}
	if(y>final_y){ 
   y--;}
	elem.style.left=x+"px";
	elem.style.top=y+"px";
	var repeat="moveElement('"+elementId+"',"+final_x+","+final_y+","+interval+")";
	timer=setTimeout(repeat,interval);//定时器设置,递归调用
}

这个函数用简单的递归调用实现。我们要注意一个问题,就是elem.style属性是elem标签的内联样式,而不是css中的id,class中的属性。一旦想使用style未初始化那么这个时候style中变量的值为NAN,所以想使用style中变量的值,有两个办法: (1)行内初始化:

代码语言:javascript
复制
<p id="test" style="top: 0px;left:0px;" >Hello World!</p>
<script src="test.js"></script>

(2)DOM初始化 我们定义一个初始化的函数,用这个函数给style属性初始化,或者直接在moveElement函数内部初始化:

代码语言:javascript
复制
function positionessage(elementId,first_x,first_y)
{ 
   
	if(!document.getElementById) return false;
	var elem=document.getElementById(elementId);
	elem.style.position="absoluate";
	elem.style.left=first_x+"px";
	elem.style.top=first_y+"px";
}

用动画增强网页效果

以上我们得到了一个动画函数,这个函数可以使我们的元素沿着任意方向移动,现在我们利用这个函数做一些更加是用的应用来增强我们的网页。 我们仍然看图片库这个例子:图片库 我们想当鼠标悬停在某个图片上时,下方的图片会更新,这样一来我们就能有一个预览效果。有一个简单的处理方法——将onclick改为onmouseover这样鼠标悬停就会得到响应。

代码语言:javascript
复制
function prepareGallery()
{ 
   
	if(!document.getElementsByTagName) return false;
	if(!document.getElementById) return false;
	if(!document.getElementById("photoGallery")) return false;
	var gallery=document.getElementById("photoGallery");
	var links=gallery.getElementsByTagName("a");
	for(var i=0;i<links.length;i++)
	{ 
   
		links[i].onmouseover=function()
		{ 
   
			return !showPic(this);//调用showPic函数
		}
		links[i].onkeypress=links[i].onmouseover;
	}                                                         
}

但是这样处理的缺点是响应不够顺畅,因为需要将新的图片加载上去难免会花费时间,我们想要的是更快更流畅的效果:

  • 设置一张长图,这张长图将所有的图片横向包含
  • 隐藏这张长图的绝大部分
  • 当鼠标悬浮时,显示这张图的相应子图
在这里插入图片描述
在这里插入图片描述

(1)用CSS隐藏其他部分

现在整张图片都是可见的,我们想只展示一个400px宽,300px高的固定区域,而隐藏其他区域。用JavaScript无法做到这一点,但是我们可以用CSS的overflow属性来设置: 盒子模型溢出处理overflow

分量

描述

visible

溢出全部可见

hidden

隐藏,超出部分不可见

scroll

显示滚动条

auto

如果有超出,显示滚动条

(2) 设置偏移动画

现在我们可以将其余部分隐藏了,但是要达到浏览的效果,我们必须能够将其他部分展现出来。可以给图片设置一个偏移的效果,这样一来就能浏览到其他区域了,如何设置偏移呢?也许你会想到style.backgroundPositionX属性,但是这里我们用前面定义的动画函数moveElement. HTML

代码语言:javascript
复制
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>Photo Gallery</title>
	<link rel="stylesheet" type="text/css" href="photo gallery.css">
	<script src="photo gallery.js"></script>
</head>
<body>
	<h1>Photo Gallery</h1>
	<ul id="linkList">
		<li><a href="images/1.png" title="基普乔格1"><img src="images/1.png" width="55" height="45"></a></li>
		<li><a href="images/2.png" title="基普乔格2"><img src="images/2.png" width="55" height="45"></a></li>
		<li><a href="images/3.png" title="基普乔格3"><img src="images/3.png" width="55" height="45"></a></li>
		<li><a href="images/4.png" title="贝克勒1"><img src="images/4.png" width="55" height="45"></a></li>
		<li><a href="images/5.png" title="贝克勒2"><img src="images/5.png" width="55" height="45"></a></li>
		<li><a href="images/6.png" title="贝克勒3"><img src="images/6.png" width="55" height="45"></a></li>
	</ul>
	<div id="slidShow">
		<img src="images/test.jpg" alt="Choos a picture" id="preview" />		
	</div>
</body>
</html>

JavaScript:

代码语言:javascript
复制
function addLoadEvent(func)
{ 
   
	var oldonload=window.onload;
	if(typeof window.onload!='function')//未被绑定
	{ 
   
		window.onload=func;
	}
	else
	{ 
   
		window.onload=function()//匿名函数添加
		{ 
   
			oldonload();
			func();
		}
	}
}
addLoadEvent(prepareSlidshow);
function prepareSlidshow()
{ 
   
	if(!document.getElementById) return false;
	if(!document.getElementsByTagName) return false;
	if(!document.getElementById("linkList")) return false;
	if(!document.getElementsByTagName("preview")) return false;
	var preview=document.getElementById("preview");
	preview.style.position="absolute";
	preview.style.left="0px";
	preview.style.top="0px";
	var list=document.getElementById("linkList");
	var links=list.getElementsByTagName("a");
/* for(var i=0;i<links.length;i++) { links[i].οnmοuseοver=function() { var move=-(i+1)*400; moveElement("preview",move,0,10); } } */
		links[0].onmouseover=function()
		{ 
   
			var move=0;   
			moveElement("preview",move,0,0.01);
		}
		links[1].onmouseover=function()
		{ 
   
			var move=-400;
			moveElement("preview",move,0,0.01);
		}
		links[2].onmouseover=function()
		{ 
   
			var move=-800;
			moveElement("preview",move,0,0.01);
		}
		links[3].onmouseover=function()
		{ 
   
			var move=-1200;
			moveElement("preview",move,0,0.01);
		}
		links[4].onmouseover=function()
		{ 
   
			var move=-1600;
			moveElement("preview",move,0,0.01);
		}
		links[5].onmouseover=function()
		{ 
   
			var move=-2000;
			moveElement("preview",move,0,0.01);
		}
		links[6].onmouseover=function()
		{ 
   
			var move=-2400;
			moveElement("preview",move,0,0.01);
		}
}

function moveElement(elementId,final_x,final_y,interval)
{ 
   
	if(!document.getElementById) return false;
	if(!document.getElementById(elementId)) return false;
	var elem=document.getElementById(elementId);
	var x=parseInt(elem.style.left);
	var y=parseInt(elem.style.top);
	if(x==final_x&&y==final_y) return true;//边界条件
	if(x<final_x){ 
   x++;}
	if(x>final_x){ 
   x--;}
	if(y<final_y){ 
   y++;}
	if(y>final_y){ 
   y--;}
	elem.style.left=x+"px";
	elem.style.top=y+"px";
	var repeat="moveElement('"+elementId+"',"+final_x+","+final_y+","+interval+")";
	timer=setTimeout(repeat,interval);//定时器设置,递归调用
}

(3)累积事件处理

在上面的过程中我们历遍所有超链接,并且当鼠标悬浮在图片上方时,给长图设置偏移的动画moveElement,注意不能用循环处理,因为循环是一次性的,不能达到任意时刻悬浮都能移动的效果!乍一看移动效果是实现了,但是似乎有一些问题,当两个方向的图片都被悬浮的时候,图片没有移动而是来回振动,问题出在哪? 积累事件: 当图片被鼠标悬停时,moveElement函数被调用,movement计时器执行,而另一张图片被悬停时,第二个movement计时器也被执行,这个时候图片就无法确定执行谁,从而出现了错乱。 清除积累事件 我们想在moveElement函数内部添加一些东西,moveElement执行的时候,要将已有的timer清除:

方法1:定义全局变量
代码语言:javascript
复制
var timer;//定义全局变量
function moveElement(elementId,final_x,final_y,interval)
{ 
   
	if(!document.getElementById) return false;
	if(!document.getElementById(elementId)) return false;
	var elem=document.getElementById(elementId);
	var x=parseInt(elem.style.left);
	var y=parseInt(elem.style.top);
	if(timer) clearTimeout(timer);
	if(x==final_x&&y==final_y) return true;//边界条件
	if(x<final_x){ 
   x++;}
	if(x>final_x){ 
   x--;}
	if(y<final_y){ 
   y++;}
	if(y>final_y){ 
   y--;}
	elem.style.left=x+"px";
	elem.style.top=y+"px";
	var repeat="moveElement('"+elementId+"',"+final_x+","+final_y+","+interval+")";
	timer=setTimeout(repeat,interval);//定时器设置,递归调用
}
方法二:增加属性值

JavaScript允许我们创建新的属性:elem.property=value 我们可以给元素设置属性timer,如果存在属性那么就清除,否则直接执行:

代码语言:javascript
复制
function moveElement(elementId,final_x,final_y,interval)
{ 
   
	if(!document.getElementById) return false;
	if(!document.getElementById(elementId)) return false;
	var elem=document.getElementById(elementId);
	var x=parseInt(elem.style.left);
	var y=parseInt(elem.style.top);
	if(elem.timer) clearTimeout(elem.timer);
	if(x==final_x&&y==final_y) return true;//边界条件
	if(x<final_x){ 
   x++;}
	if(x>final_x){ 
   x--;}
	if(y<final_y){ 
   y++;}
	if(y>final_y){ 
   y--;}
	elem.style.left=x+"px";
	elem.style.top=y+"px";
	var repeat="moveElement('"+elementId+"',"+final_x+","+final_y+","+interval+")";
	elem.timer=setTimeout(repeat,interval);//定时器设置,递归调用
}

添加属性值的方法似乎更为安全,封装好的moveElement函数非常具有使用意义。

在这里插入图片描述
在这里插入图片描述

(4)改进变化趋势

我们的moveElement函数每次前进1px,你是否感觉太过于单调?现在我想给它设置一些变化,根据区域到目标的距离来变换,距离越远变化越快,越近变化越慢:

代码语言:javascript
复制
function moveElement(elementId,final_x,final_y,interval)
{ 
   
	if(!document.getElementById) return false;
	if(!document.getElementById(elementId)) return false;
	var elem=document.getElementById(elementId);
	var x=parseInt(elem.style.left);
	var y=parseInt(elem.style.top);
	if(elem.timer) clearTimeout(elem.timer);
	if(x==final_x&&y==final_y) return true;//边界条件
	var dis_x,dis_y;
	dis_x=Math.ceil((final_x-x)/10);//向上取整
	x+=dis_x;
	//round向下取整
	dis_y=Math.ceil((final_y-y)/10);//向上取整
	y+=dis_y;
	elem.style.left=x+"px";
	elem.style.top=y+"px";
	var repeat="moveElement('"+elementId+"',"+final_x+","+final_y+","+interval+")";
	elem.timer=setTimeout(repeat,interval);//定时器设置,递归调用
}

这将会是一个不错的选择

在这里插入图片描述
在这里插入图片描述

(5)生成HTML标记添加安全检查

前面的slidShow区域是专门为JavaScript服务的,考虑平稳退化时,JavaScript如果不被支持那么网页是否能够平稳退化?但暗示不会,当网页禁用JavaScript,我们的区域将会是一个不可更改的区域,这样的区域将毫无用处因为他的图片是固定的,这意味着我们未能平稳退化,所以我们要将JavaScript完全分离: HTML:

代码语言:javascript
复制
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>Photo Gallery</title>
	<link rel="stylesheet" type="text/css" href="photo gallery.css">
	<script src="photo gallery.js"></script>
</head>
<body>
	<h1>Photo Gallery</h1>
	<ul id="linkList">
		<li><a href="images/1.png" title="基普乔格1"><img src="images/1.png" width="55" height="45"></a></li>
		<li><a href="images/2.png" title="基普乔格2"><img src="images/2.png" width="55" height="45"></a></li>
		<li><a href="images/3.png" title="基普乔格3"><img src="images/3.png" width="55" height="45"></a></li>
		<li><a href="images/4.png" title="贝克勒1"><img src="images/4.png" width="55" height="45"></a></li>
		<li><a href="images/5.png" title="贝克勒2"><img src="images/5.png" width="55" height="45"></a></li>
		<li><a href="images/6.png" title="贝克勒3"><img src="images/6.png" width="55" height="45"></a></li>
	</ul>

</body>
</html>

JavaScript:

代码语言:javascript
复制
function prepareSlidshow()
{ 
   
	if(!document.getElementById) return false;
	if(!document.getElementsByTagName) return false;
	if(!document.getElementById("linkList")) return false;
	if(!document.getElementsByTagName("preview")) return false;
	var slideShow=document.createElement("div");
	slideShow.setAttribute("id","slideShow");
	var preview=document.createElement("img");
	preview.setAttribute("src","images/test.jpg");
	preview.setAttribute("alt","Choose a picture");
	preview.setAttribute("id","preview");
	slideShow.appendChild(preview);
	var list=document.getElementById("linkList");
	insertAfter(slideShow,list);
	var preview=document.getElementById("preview");
	preview.style.position="absolute";
	preview.style.left="0px";
	preview.style.top="0px";
	
	var links=list.getElementsByTagName("a");
/* for(var i=0;i<links.length;i++) { links[i].οnmοuseοver=function() { var move=-(i+1)*400; moveElement("preview",move,0,10); } } */
		links[0].onmouseover=function()
		{ 
   
			var move=0;   
			moveElement("preview",move,0,15);
		}
		links[1].onmouseover=function()
		{ 
   
			var move=-400;
			moveElement("preview",move,0,15);
		}
		links[2].onmouseover=function()
		{ 
   
			var move=-800;
			moveElement("preview",move,0,15);
		}
		links[3].onmouseover=function()
		{ 
   
			var move=-1200;
			moveElement("preview",move,0,15);
		}
		links[4].onmouseover=function()
		{ 
   
			var move=-1600;
			moveElement("preview",move,0,15);
		}
		links[5].onmouseover=function()
		{ 
   
			var move=-2000;
			moveElement("preview",move,0,15);
		}

}

可以达到同样的效果:

在这里插入图片描述
在这里插入图片描述

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/184857.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 动画基础
    • (1)定时器setTimeout
      • setTimeout能够让某个函数在经过一段预定时间之后才开始执行,带有两个参数。第一个参数是要执行函数的名字,第二个参数则是一个数值,表示间隔的时间长短:
      • 定时器解除clearTimeout
    • (2)递归函数
    • 用动画增强网页效果
      • (1)用CSS隐藏其他部分
        • (2) 设置偏移动画
          • (3)累积事件处理
            • 方法1:定义全局变量
            • 方法二:增加属性值
          • (4)改进变化趋势
            • (5)生成HTML标记添加安全检查
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档