纯js链式动画和同时运动

一、链式动画(下方有完整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的动画效果 可是这都好几年没用过了,只能回忆一下,梳理一下逻辑先做什么然后做什么巴啦巴啦的,开始写呗,然后封装一下,现在在这里记录一下,以后再用到时就不用重新去写了

如有疑问或建议,欢迎给我留言,谢谢!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

招来红月

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值