JS运动框架(动画)实现思路

运动框架实现思路

简单动画(改变值:left/right/width/height/opacity)

速度动画

1
<div id='div1'><span id='share'>分享</span></div>
1
2
3
4
5
body,div,span{margin:0;padding:0;}
#div1{width:200px;height:200px;background:red;
position:relative;left:-200px;top:0;}
#div1 span{width:20px;height:50px;background:blue;position:absolute;
left:200px;top:75px;}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
window.onload=function(){
var oDiv=document.getElementById('div1');
oDiv.onmouseover=function(){
startMove(0);
}
oDiv.onmouseout=function(){
startMove(-200);
}
}
var timer=null;
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;
}
*/

//将上面关于速度(缓冲)的代码进行优化
var speed=(iTarget-oDiv.offsetLeft)/20;
speed = speed>0?Math.ceil(speed):Math.floor(speed);

if(oDiv.offsetLeft==iTarget){
clearInterval(timer);
}else{
oDiv.style.left=oDiv.offsetLeft + speed + 'px';
}
},30)
}

透明度动画

1
<div id="animation-1"></div>
1
2
3
4
5
6
7
8
#animation-1{
width: 200px;
height: 200px;
border: 1px solid pink;
background: blue;
opacity: 0.3;
filter: alpha(opacity:30);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
window.onload=function() {
var oDiv=document.getElementById('animation-1');
oDiv.onmouseover=function(){
omove(100);
}
oDiv.onmouseout=function(){
omove(30);
}
}
var timer=null;
var opa=30;
function omove(iTarget){
var oDiv=document.getElementById('animation-1');
clearInterval(timer);
timer=setInterval(function(){
var speed=(iTarget-opa)/10;
if (opa==iTarget) {
clearInterval(timer);
}else{
opa+=speed;
oDiv.style.opacity=opa/100;
oDiv.style.filter="alpha(opacity:'+opa+')";
}

},30)

}

多物体运动

1
2
3
4
<ul>
<li id="li1"></li>
<li id="li2"></li>
</ul>
1
2
3
4
5
6
7
ul,li{list-style: none;}
ul li{
width: 200px;
height: 100px;
background: yellow;
margin-bottom: 20px;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
window.onload=function(){
var oLi=document.getElementsByTagName('li');
for (var i = 0; i < oLi.length; i++) {
oLi[i].timer=null;
oLi[i].onmouseover=function(){
startMove(this,400);
}
oLi[i].onmouseout=function(){
startMove(this,200);
}
}
}
function startMove(obj,iTarget){
clearInterval(obj.timer);
obj.timer=setInterval(function(){
var speed=(iTarget-obj.offsetWidth)/8;
speed=speed>0?Math.ceil(speed):Math.floor(speed);
if (obj.offsetWidth==iTarget) {
clearInterval(obj.timer);
}else{
obj.style.width=obj.offsetWidth+speed +"px";
}
},30)
}

任意值变化

上述代码仅实现元素宽度变化的函数,如果是元素其他属性的变化,例如高度、透明度等的变化,则需要对JS代码进行改动、封装。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
//获取元素obj的某一样式attr
function getStyle(obj,attr){
if(obj.currentStyle){
return obj.currentStyle[attr];
}else{
return getComputedStyle(obj,false)[attr];
}
}
//动画函数
function startMove(obj,attr,iTarget,fn){
clearInterval(obj.timer);
obj.timer=setInterval(function(){
//取当前的值
var icur=0;
//用if判断属性
if (attr=='opacity') {
icur=Math.round(parseFloat(getStyle(obj,attr))*100);
//由于opacity的值是小数,需要用parseFloat转为小数值,Math.round四舍五入。
}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);
if (fn) {
fn();
};
}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)
}

链式运动

想要实现元素宽度变化,然后实现元素高度/透明度,或其他样式的变化,则需要对动画函数进行改变,添加一个回调函数。上述代码改动部分如下:

1
2
3
4
5
6
7
8
9
10
......
function startMove(obj,attr,iTarget,fn){
..................
if (icur==iTarget) {
clearInterval(obj.timer);
if (fn) {
fn();
};
....................
}

代码示例:

1
2
3
4
<ul>
<li id="li1"></li>
<li id="li2"></li>
</ul>

1
2
3
4
5
6
7
8
9
10
ul,li{list-style: none;}
ul li{
width: 200px;
height: 100px;
background: yellow;
margin-bottom: 20px;
border: 4px solid green;
opacity: 0.3;
filter: alpha(opacity:30);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
window.onload=function(){
var Li1=document.getElementById('li1');
var Li2=document.getElementById('li2');
Li1.onmouseover=function(){
startMove(Li1,'width',400,function(){
startMove(Li1,'opacity',100);
});
}
Li1.onmouseout=function(){

startMove(Li1,'opacity',30,function(){
startMove(Li1,'width',200);
});
}
Li2.onmouseover=function(){
startMove(this,'height',400);
}
Li2.onmouseout=function(){
startMove(this,'height',100);
}
}
function getStyle(obj,attr){
if(obj.currentStyle){
return obj.currentStyle[attr];
}else{
return getComputedStyle(obj,false)[attr];
}
}
function startMove(obj,attr,iTarget,fn){
clearInterval(obj.timer);
obj.timer=setInterval(function(){
//取当前的值
var icur=0;
//用if判断属性
if (attr=='opacity') {
icur=Math.round(parseFloat(getStyle(obj,attr))*100);
//由于opacity的值是小数,需要用parseFloat转为小数值,Math.round四舍五入。
}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);
if (fn) {
fn();
};
}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)
}

同时运动

想要实现元素的许多样式同时运动,需要对前面的封装函数进行改动,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
function getStyle(obj,attr){
if(obj.currentStyle){
return obj.currentStyle[attr];
}else{
return getComputedStyle(obj,false)[attr];
}
}
//startMove(obj,{attr1:itarget1,attr2:itarget2},fn),object为一个对象,object为键值对格式
function startMove(obj,object,fn){
var flag =true; //假设
clearInterval(obj.timer);
obj.timer=setInterval(function(){
for(var attr in object)
{
var icur=0;
//用if判断属性
if (attr=='opacity') {
icur=Math.round(parseFloat(getStyle(obj,attr))*100);
//由于opacity的值是小数,需要用parseFloat转为小数值,Math.round四舍五入。
}else{
icur=parseInt(getStyle(obj,attr));
}
//算速度
var speed=(object[attr]-icur)/8;
speed=speed>0?Math.ceil(speed):Math.floor(speed);
//检测停止
if (icur!=object[attr]) {
flag = false;
}
if (attr=='opacity') {
obj.style.filter='alpha(opacity:"+(icur+speed)+")';
obj.style.opacity=(icur+speed)/100;
} else{
obj.style[attr]=icur+speed +"px";
}
if(flag){
clearInterval(obj.timer);
if(fn){
fn();
}
}
}
//取当前的值
},30)
}

坚持原创技术分享,您的支持将鼓励我继续创作!