通过计算样式封装动画实例—多条动画结合,多个参数变化的动画

要点:

1.原来想写animate()的多态形式的,写到一半想起来,js不需要在声明变量时就声明数据类型,无法完成多态的性质,可以通过曲线方法完成多态效果,以后再说。

2.getComputerStyle计算样式属性,可以将setoff系列没能获取到的样式属性获取出来,getComputerStyle能返回所调用对象的所有样式键值对,形成一个样式对象

3.这个例子中有原来可以改变一个参数,到后面通过对象改变多个参数,理解对象即为键值对的意义,同时理解var-in遍历对象的

4.通过这个案例,里面有改变一个属性的动画函数,里面改变元素的样式的left用的是 ["字符串" ]方式来获取属性,因为字符串可以是变量,而点语法获取属性要是固定属性,不能是变量。

代码:

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
	<style type="text/css">
		*{
			padding: 0;
			margin: 0;
		}
		input{
			margin-top: 20px;
		}
		div{
			margin-top: 30px;
			width: 225px;
			height: 175px;
			background-color: #6D1F9B;
			position: absolute;
			/*一定要是相对定位,不然写的移动的位置不能改变而显示出来*/
		}
	</style>
</head>
<body>
	<input type="button" value="移动!" id="btn1">
	<input type="button" value="变变变" id="btn2">

	<div id="div"></div>


	<script type="text/javascript">
        function myGet(id){
        	return document.getElementById(id);
        }

        myGet("btn1").onclick = function(){
        	animate2(myGet("div"),"top",500);
        }
        myGet("btn2").onclick = function(){
        	animate(myGet("div"),{"top":200,"width":500,"height":500,"left":500,"opacity":0.3},function(){
        		animate(myGet("div"),{"top":100,"width":200,"height":200,"left":100,"opacity":0.9})});
        }


		function getStyle(element,attr){
			return window.getComputedStyle ? window.getComputedStyle(element,null)[attr]
			: element.currentStyle[attr];
			// 将原来的if-else语句进行判断也兼容代码的方式,进行简化,写成三目运算符的方式
			// 属性后面的[attr]是跟点语法的作用是一样的,但是这里不能使用点语法获取attr的对象属性,因为attr是变量只有用[]接收不同类型字符串
			// 获取的计算后的样式都是带有单位的
		}

	    function animate2(element,attr,target){
        	clearInterval(element.intervalName);
        	// 每次点击移动按钮的时候,清理定时器,将原来的定时器清理掉,不然会叠加多线程多个定时器,加快速度
        	element.intervalName = setInterval(function(){

	            var current = parseInt(getStyle(element,attr));
	            // 通过getStyle()获取的是带有单位的属性值,通过parseInt转换成值类型,不用number()是因为转换过后的可能是nun
	            
	            var step = 80;
	            // 每次增加80像素
	            step = current<target?step:-step;
	            // 判断是在目标的左边还是右边,从而判断是前进还是后退
	            current += step;	
	            if(Math.abs(target-current)>Math.abs(step)){
	            	element.style[attr] = current + "px";
	            }else{
	            	clearInterval(element.intervalName);
	            	element.style[attr] = target + "px";
	            	// 当执行到最后一步时,如果不满增加的长度,而再一次执行时,而又超过目标像素的距离,
	                // 所以设置直接一步到目标距离,而不会
	            }  	
            },300)
        }

        function animate(element,json,fn){
        	clearInterval(element.intervalName);
        	// 清理定时器

        	element.intervalName = setInterval(function(){
                var flag = true;
                // 哈哈哈,又是这个,因为遍历for循环遍历有先后顺序,要都到达指定位置才能清理计时器

        		for(var attr in json){
                    if(attr == "zIndex"){
                    	// css中的属性中间是连字符的属性,在js操作中,将下划线去掉同驼峰原则
                        // 层级的操作,直接赋值即可不需要其他的操作
                        element.style[attr] = json[attr];
                    }else if(attr == "opacity"){

                    	var current = getStyle(element,attr)*100;
	        			var target = json[attr]*100;
	        			// 将attr对应的值获取到,直接通过对象的键值获取,这个参数没有单位直接获取值
	        			var step = (target - current)/10;
	        			step = step>0 ? Math.ceil(step) : Math.floor(step);
	        			current += step;
	        			element.style[attr] = current/100;
	        			// 透明度不需要其他的参数,前面放大100倍,变回来
                    }else{
	    
	        			// 其他不同的属性
                        // 遍历json数组对象,每次将遍历的数组对象属性进行设置
	        			var current = parseInt(getStyle(element,attr));
	        			var target = json[attr];
	        			// 将attr对应的值获取到,直接通过对象的键值获取
	        			var step = (target - current)/10;
	        			// 将从当前位置到目标距离走十分之一
	        			step = step>0 ? Math.ceil(step) : Math.floor(step);
	        			// Math.ceil()和Math.floor()分别是向上和向下取整
	        			current += step;
	        			element.style[attr] = current + "px";
                    }

        			if(current != target){
                      flag = false;
                      // 也是类似于多线程,只有每个都为true才能到达指定位置
        			}
        		}   
        		    if(flag){
        		    	clearInterval(intervalName); 
        		    	// 所有的动画执行完成之后,可以再执行一个函数
        		    	if(fn){
        		    		fn();
        		    	}
                        // 这里调用的函数,也可以是本身这个函数,还可以 进行多次动画
        		    }
        		    
        	},300)
        }
	</script>
</body>
</html>

 效果:

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值