一、链式动画(下方有完整demo)
/**
* 链式动画
* @param{element} obj 需要动画的元素
* @param{number} target 属性值
* @param{string} attr 属性
* @param{function} fn 回调函数
*/
function chainAnimation(obj, target, attr, fn) {
//清空定时器
clearInterval(obj.timer);
obj.timer = setInterval(function() {
if(attr == 'opacity') {
// 如果属性值是opacity则执行数学方法
iCur = Math.round(parseFloat(getStyle(obj, attr)) * 100);
} else {
// 否则执行普通方法计算当前值
iCur = parseInt(getStyle(obj, attr));
}
if(iCur == target) {
//当属性到达了想要的属性,清除定时器,调用回调函数
clearInterval(obj.timer);
if(fn) {
fn();
}
} else {
//否则继续执行
dis = (target - iCur) / 20;
dis = dis > 0 ? Math.ceil(dis) : Math.floor(dis);
if(attr == 'opacity') {
// 如果属性值是opacity则执行数学方法
obj.style[attr] = parseFloat((iCur + dis) / 100);
} else {
// 否则执行普通方法计算当前值
obj.style[attr] = iCur + dis + 'px';
}
}
}, 10)
}
//获取元素的属性值
function getStyle(obj, attr) {
if(obj.currentStyle) {
return obj.currentStyle[attr];
} else {
return getComputedStyle(obj, false)[attr];
}
}
二、同时运动(下方有完整demo)
/**
* 同时运动
* @param{element} obj 需要动画的元素
* @param{number} target 属性值
* @param{string} attr 属性
* @param{function} fn 回调函数
*/
function simultaneousAnimation(obj, json, fn) {
clearInterval(obj.timer);
obj.timer = setInterval(function() {
// 设定一个状态,认定所有的动画均已完成
var flag = true;
// 使用for/in循环进行遍历所有json内的值
for(var attr in json) {
// 如果属性值是opacity则执行数学方法
if(attr == 'opacity') {
iCur = Math.round(parseFloat(getStyle(obj, attr)) * 100);
// 否则执行普通方法计算当前值
} else {
iCur = parseInt(getStyle(obj, attr));
}
// 设定一个变速运动的基准
dis = (json[attr] - iCur) / 20;
// 变速运动的值取整
dis = dis > 0 ? Math.ceil(dis) : Math.floor(dis);
// 如果有任意的属性值跟目标值不相同(还有动画未完成),则状态为false,继续向下循环
if(json[attr] !== iCur) {
flag = false;
};
// 如果属性值是opacity则执行数学方法进行计算
if(attr == 'opacity') {
obj.style[attr] = parseFloat((iCur + dis) / 100);
} else {
// 否则执行px方法
obj.style[attr] = iCur + dis + 'px';
}
}
// 状态为真:所有动画都已经完成了
if(flag) {
clearInterval(obj.timer);
//如果有回调函数则执行
if(fn) {
fn(obj);
};
};
}, 10)
}
//获取元素的属性值
function getStyle(obj, attr) {
if(obj.currentStyle) {
return obj.currentStyle[attr];
} else {
return getComputedStyle(obj, false)[attr];
}
}
三、demo
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>demo</title>
<style type="text/css">
div {
width: 200px;
height: 50px;
border: 1px solid black;
background: red;
margin: 30px auto;
color: #fff;
font-size: 20px;
font-weight: bold;
line-height: 50px;
text-align: center;
overflow: hidden;
}
</style>
</head>
<body>
<div id="demo1">链式动画</div>
<div id="demo2">同时运动</div>
<script type="text/javascript">
var demo1 = document.getElementById('demo1');
var demo2 = document.getElementById('demo2');
demo1.onmouseover = function() {
chainAnimation(this, 50, 'opacity', function() {
chainAnimation(demo1, 500, 'fontSize', function() {
chainAnimation(demo1, 200, 'height');
});
});
}
demo1.onmouseout = function() {
chainAnimation(this, 100, 'opacity', function() {
chainAnimation(demo1, 20, 'fontSize', function() {
chainAnimation(demo1, 50, 'height');
});
});
}
demo2.onmouseover = function() {
simultaneousAnimation(this, {
'fontSize': 500,
'height': 400,
'lineHeight': 400,
'opacity': 20
}, function() {
simultaneousAnimation(demo2, {
'width': 600
});
});
}
demo2.onmouseout = function() {
simultaneousAnimation(this, {
'fontSize': 20,
'height': 50,
'lineHeight': 50,
'opacity': 100
}, function() {
simultaneousAnimation(demo2, {
'width': 200
});
});
}
function chainAnimation(obj, target, attr, fn) {
clearInterval(obj.timer);
obj.timer = setInterval(function() {
if(attr == 'opacity') {
iCur = Math.round(parseFloat(getStyle(obj, attr)) * 100);
} else {
iCur = parseInt(getStyle(obj, attr));
}
if(iCur == target) {
clearInterval(obj.timer);
if(fn) {
fn();
}
} else {
dis = (target - iCur) / 20;
dis = dis > 0 ? Math.ceil(dis) : Math.floor(dis);
if(attr == 'opacity') {
obj.style[attr] = parseFloat((iCur + dis) / 100);
} else {
obj.style[attr] = iCur + dis + 'px';
}
}
}, 10)
}
function simultaneousAnimation(obj, json, fn) {
clearInterval(obj.timer);
obj.timer = setInterval(function() {
var flag = true;
for(var attr in json) {
if(attr == 'opacity') {
iCur = Math.round(parseFloat(getStyle(obj, attr)) * 100);
} else {
iCur = parseInt(getStyle(obj, attr));
}
dis = (json[attr] - iCur) / 20;
dis = dis > 0 ? Math.ceil(dis) : Math.floor(dis);
if(json[attr] !== iCur) {
flag = false;
};
if(attr == 'opacity') {
obj.style[attr] = parseFloat((iCur + dis) / 100);
} else {
obj.style[attr] = iCur + dis + 'px';
}
}
if(flag) {
clearInterval(obj.timer);
if(fn) {
fn(obj);
};
};
}, 10)
}
function getStyle(obj, attr) {
if(obj.currentStyle) {
return obj.currentStyle[attr];
} else {
return getComputedStyle(obj, false)[attr];
}
}
</script>
</body>
</html>
后记:此篇文章是做项目时,要求不能用第三方库,如有问题只能用js解决,需求是缩小渐隐得到效果,依稀记得以前学过纯js的动画效果 可是这都好几年没用过了,只能回忆一下,梳理一下逻辑先做什么然后做什么巴啦巴啦的,开始写呗,然后封装一下,现在在这里记录一下,以后再用到时就不用重新去写了
如有疑问或建议,欢迎给我留言,谢谢!