JS 动画基础
获取元素的样式
getStyle函数
1 function getStyle(element, attr) { 2 if(element.currentStyle) { 3 //针对IE 4 return element.currentStyle[attr]; 5 } else { 6 //针对Firefox 7 return getComputedStyle(element, false)[attr]; 8 } 9 }
此函数返回的是一个字符串,需要调用 parseInt() 或者 parseFloat() 将返回的结果转换为数字值。
简单动画
HTML
1 <!doctype html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title>简单动画</title> 6 <link rel="stylesheet" href="css/style.css"> 7 <script type="text/javascript" src="js/script.js"></script> 8 </head> 9 <body> 10 <div id="box"> 11 <img src="http://pic1.win4000.com/wallpaper/c/537b28b60619b.jpg" alt="A picture" style="width:240px;height:180px" /> 12 <span>萌萌哒</span> 13 </div> 14 </body> 15 </html>
CSS
1 * { 2 margin: 0; 3 padding: 0; 4 } 5 6 #box { 7 padding: 5px; 8 margin: 10px; 9 border: 1px solid #aaa; 10 border-radius: 5px; 11 width: 240px; 12 box-shadow: 0 0 1px #aaa, 0 0 2px #aaa; 13 position: absolute; 14 top: 0; 15 left: -260px; 16 cursor: pointer; 17 } 18 19 #box span { 20 position: absolute; 21 display: block; 22 width: 20px; 23 background-color: black; 24 color: white; 25 margin-left: 245px; 26 margin-top: -125px; 27 }
JavaScript
1 window.onload = function() { 2 move(); 3 } 4 5 function move() { 6 var box = document.getElementById("box"); 7 box.timer = null; 8 box.onmouseover = function() { 9 animation(box, "left", 0, 1, 10); 10 }; 11 box.onmouseout = function() { 12 animation(box, "left", -260, 1, 10); 13 }; 14 } 15 16 17 // 简单动画,接收5个参数:动画元素、动画属性、目标值、变化速度、定时器时间 18 function animation(element, attr, target, speed, timing) { 19 clearInterval(element.timer); 20 element.timer = setInterval(function() { 21 var curValue = parseInt(getStyle(element, attr)); 22 var count = speed; 23 if(curValue < target) { 24 count = speed; 25 } else if(curValue > target) { 26 count = -speed; 27 } else { 28 count = 0; 29 } 30 if(curValue == target) { 31 clearInterval(element.timer); 32 } else { 33 element.style[attr] = curValue + count + "px"; 34 console.log(curValue); 35 } 36 }, timing) 37 } 38 39 function getStyle(element, attr) { 40 if(element.currentStyle) { 41 return element.currentStyle[attr]; 42 } else { 43 return getComputedStyle(element, false)[attr]; 44 } 45 }
缓冲动画
HTML
1 <!doctype html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title>缓冲动画</title> 6 <link rel="stylesheet" href="css/style.css"> 7 <script type="text/javascript" src="js/script.js"></script> 8 </head> 9 <body> 10 <div id="box"> 11 <img src="http://pic1.win4000.com/wallpaper/c/537b28b60619b.jpg" alt="A picture" style="width:240px;height:180px" /> 12 <span>萌萌哒</span> 13 </div> 14 </body> 15 </html>
CSS
1 * { 2 margin: 0; 3 padding: 0; 4 } 5 6 #box { 7 padding: 5px; 8 margin: 10px; 9 border: 1px solid #aaa; 10 border-radius: 5px; 11 width: 240px; 12 box-shadow: 0 0 1px #aaa, 0 0 2px #aaa; 13 position: absolute; 14 top: 0; 15 left: -260px; 16 } 17 18 #box span { 19 position: absolute; 20 display: block; 21 width: 20px; 22 background-color: black; 23 color: white; 24 margin-left: 245px; 25 margin-top: -125px; 26 cursor: pointer; 27 }
JavaScript
1 window.onload = function() { 2 move(); 3 } 4 5 function move() { 6 var box = document.getElementById("box"); 7 box.timer = null; 8 box.onmouseover = function() { 9 animation(box, "left", 0, 10, 50); 10 }; 11 box.onmouseout = function() { 12 animation(box, "left", -260, 10, 50); 13 }; 14 } 15 16 // 缓冲动画,接收5个参数:动画元素、动画属性、目标值、变化速度、定时器时间 17 function animation(element, attr, target, speed, timing) { 18 clearInterval(element.timer); 19 element.timer = setInterval(function() { 20 var curValue = parseInt(getStyle(element, attr)); 21 var count = (target - curValue) / speed; 22 count = (count > 0) ? Math.ceil(count) : Math.floor(count); 23 if(curValue == target) { 24 clearInterval(element.timer); 25 } else { 26 element.style[attr] = curValue + count + "px"; 27 } 28 }, timing) 29 } 30 31 function getStyle(element, attr) { 32 if(element.currentStyle) { 33 return element.currentStyle[attr]; 34 } else { 35 return getComputedStyle(element, false)[attr]; 36 } 37 }
透明度动画
HTML
1 <!doctype html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title>透明度动画</title> 6 <link rel="stylesheet" href="css/style.css"> 7 <script type="text/javascript" src="js/script.js"></script> 8 </head> 9 <body> 10 <div id="box"></div> 11 </body> 12 </html>
CSS
1 #box { 2 width: 100px; 3 height: 100px; 4 background-color: blue; 5 border: 5px solid #333; 6 border-radius: 5px; 7 opacity: 0.5; 8 }
JavaScript
1 window.onload = function() { 2 var box = document.getElementById("box"); 3 box.timer = null; 4 box.onmouseover = function() { 5 changeOpacity(box, 100, 2, 10, 100); 6 } 7 box.onmouseout = function() { 8 changeOpacity(box, 30, 2, 10, 100); 9 } 10 } 11 12 function changeOpacity(element, target, method, speed, timing) { 13 clearInterval(element.timer); 14 element.timer = setInterval(function() { 15 var curValue = Math.round(parseFloat(getStyle(element, "opacity")) * 100); 16 switch(method) { 17 case 1: 18 var count = speed; 19 if(curValue < target) { 20 count = speed; 21 } else if(curValue > target) { 22 count = -speed; 23 } else { 24 count = 0; 25 } 26 break; 27 case 2: 28 var count = (target - curValue) / speed; 29 count = (count > 0) ? Math.ceil(count) : Math.floor(count); 30 break; 31 default: 32 var count = (target - curValue) / speed; 33 count = (count > 0) ? Math.ceil(count) : Math.floor(count); 34 35 } 36 if(curValue == target) { 37 clearInterval(element.timer); 38 } else { 39 console.log(curValue); 40 element.style.opacity = (curValue + count) / 100; 41 } 42 }, timing) 43 } 44 45 function getStyle(element, attr) { 46 if(element.currentStyle) { 47 return element.currentStyle[attr]; 48 } else { 49 return getComputedStyle(element, false)[attr]; 50 } 51 }
【1】使用 getStyle 函数获取的 opacity 属性是一个浮点数,不能使用 parseInt() 对其进行转化,应该使用 parseFloat() 。
将 opacity 的值乘以 100 ,然后调用 Math.round() ,将浮点数变成整数。(永远不要比较两个浮点数是否相等,结局绝对会出人意料。)
基础动画框架
HTML
1 <!doctype html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title>动画框架演示</title> 6 <link rel="stylesheet" href="css/style.css"> 7 <script type="text/javascript" src="js/script.js"></script> 8 </head> 9 <body> 10 <div id="box"></div> 11 </body> 12 </html>
CSS
1 #box { 2 margin: 10px; 3 border: 5px solid #333; 4 border-radius: 5px; 5 box-shadow: 0 0 1px #333, 0 0 2px #333; 6 width: 100px; 7 height: 100px; 8 background-color: blue; 9 opacity: 0.3; 10 position: absolute; 11 left: 0; 12 top: 0; 13 }
JavaScript
1 window.onload = function() { 2 move(); 3 } 4 5 function move() { 6 var box = document.getElementById("box"); 7 box.timer = null; 8 box.onmouseover = function() { 9 animation(box, {left:300}, 2, 20, 50, function() { 10 animation(box, {width:200, height:200, opacity:100}, 2, 20, 50) 11 }) 12 } 13 box.onmouseout = function() { 14 animation(box, {left:0}, 2, 20, 50, function() { 15 animation(box, {width:100, height:100, opacity:50}, 2, 20, 50) 16 }) 17 } 18 } 19 20 // 动画函数接收 6 个参数:动画元素、json 数据、运动方式、变化速度、定时器时间、回调函数 21 // 其中,json 数据的格式为 {attr1: target1, attr2: target2} 22 // method 参数传入 1 则表示匀速运动,传入 2 则表示缓冲运动 23 function animation(element, json, method, speed, timing, fn) { 24 clearInterval(element.timer); 25 element.timer = setInterval(function() { 26 var flag = true; 27 for(var attr in json) { 28 var curValue = 0; 29 if(attr == "opacity") { 30 curValue = Math.round(parseFloat(getStyle(element, attr)) * 100); 31 } else { 32 curValue = parseInt(getStyle(element, attr)); 33 } 34 switch(method) { 35 case 1: 36 var count = speed; 37 if(curValue < json[attr]) { 38 count = speed; 39 } else if(curValue > json[attr]) { 40 count = -speed; 41 } else { 42 count = 0; 43 } 44 break; 45 case 2: 46 var count = (json[attr] - curValue) / speed; 47 count = (count > 0) ? Math.ceil(count) : Math.floor(count); 48 break; 49 default: 50 var count = (json[attr] - curValue) / speed; 51 count = (count > 0) ? Math.ceil(count) : Math.floor(count); 52 } 53 54 if(curValue != json[attr]) { 55 flag = false; 56 } 57 if(attr == "opacity") { 58 element.style.opacity = (curValue + count) / 100; 59 console.log(curValue); 60 } else { 61 element.style[attr] = curValue + count + "px"; 62 } 63 } 64 if(flag) { 65 clearInterval(element.timer); 66 if(fn) { 67 fn(); 68 } 69 } 70 }, timing); 71 } 72 73 function getStyle(element, attr) { 74 if(element.currentStyle) { 75 return element.currentStyle[attr]; 76 } else { 77 return getComputedStyle(element, false)[attr]; 78 } 79 }
【1】如果需要将元素恢复到动画之前的样子,动画的运动方式应该一致,否则在特殊情况下会出一些 bug 。