Loading

JavaScript的运动框架学习总结

一、目录

  1. 入门案例——实现匀速运动

  2. 入门案例——实现缓冲运动

  3. 实现任意值的运动框架v.1

  4. 改进任意值的运动框架v.2  

  5. 改进任意值的运动框架v.3

  6. 实现链式运动框架

  7. 实现完美运动框架

二、内容

  1. 入门案例——实现匀速运动

  ①. 要求:只要简单的实现传入的对象和运动的最终目标,便能操作该对象的left属性的大小匀速的变化到目标大小。

  ②. 具体代码:

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title></title>
 6     <style>
 7         #div1 {
 8             width: 100px;
 9             height: 100px;
10             background: red;
11             margin: 10px;
12             position:absolute;
13         }
14     </style>
15     <script>
16         var timer = null; //定时器
17         var speed = 10; //运动速度
18         function uniformMotion(obj,iTarget) {
19             if (obj.offsetLeft > iTarget) { //判断当前left属性的值与最终目标的值之间的位置
20                 speed = -10;                //说明当前对象的位置在目标值的右边
21             } else {
22                 speed = 10;
23             }
24             clearInterval(timer);                   //先关闭之前的定时器
25             timer = setInterval(function () {       //开启定时器,并保存返回的定时器对象
26                 if (obj.offsetLeft == iTarget) {
27                     clearInterval(timer);           //运动到目标后关闭定时器
28                 } else if (Math.abs(obj.offsetLeft - iTarget) < Math.abs(speed)) {
29                     obj.style.left = iTarget + 'px'; //如果当前位置与目标的位置不足10,那么就让它直接跳到目标位置上
30                     clearInterval(timer);            //关闭定时器
31                 } else {
32                     obj.style.left = obj.offsetLeft + speed + 'px'; //让当前位置向目标位置移动
33                 }
34             }, 30);
35         }
36         window.onload = function () {
37             var btn = document.getElementsByTagName("input")[0];
38             var oDiv = document.getElementById("div1");
39             btn.onclick = function(){
40                 uniformMotion(oDiv,300);
41             }
42         }
43     </script>
44 </head>
45 <body>
46 <input type="button" value="匀速运动"/>
47 <div id="div1"></div>
48 </body>
49 </html>

   2. 入门案例——实现缓冲运动

    ①. 要求:只要简单的实现传入的对象和运动的最终目标,便能操作该对象的left属性的大小由大到小的变化到目标大小。

    ②. 具体代码:

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title></title>
 6 
 7     <style>
 8         div {
 9             width: 100px;
10             height: 100px;
11             position: absolute;
12             background: red;
13             margin: 10px;
14             left: 100px;
15         }
16 
17         #div2{
18             width: 1px;
19             height:300px;
20             background-color: black;
21             position: absolute;
22             left:600px;
23         }
24     </style>
25     <script>
26         /*缓冲运动*/
27         var timer = null;
28         var speed = 0;
29         function UnUniformModition(obj,iTarget) {
30             clearInterval(timer);
31             timer = setInterval(function () {
32                 if (parseInt(getStyle(obj, "left")) == iTarget) {
33                     clearInterval(timer);
34                 } else {
35                     speed = (iTarget - parseInt(getStyle(obj, "left"))) / 10;
36                     speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
37                     obj.style.left = parseInt(getStyle(obj, "left")) + speed + "px";
38                 }
39             }, 30);
40         }
41         /* 用来获取样式的值 obj-对象,name-样式名*/
42         function getStyle(obj, name) {
43             if (obj.currentStyle) {
44                 return obj.currentStyle[name];
45             } else {
46                 return getComputedStyle(obj, false)[name];
47             }
48         }
49         window.onload = function () {
50             var btn = document.getElementsByTagName("input")[0];
51             var oDiv = document.getElementsByTagName("div")[0];
52             btn.onclick = function () {
53                 UnUniformModition(oDiv,600);
54             }
55         }
56     </script>
57 </head>
58 <body>
59 <input type="button" value="缓冲运动">
60 <div></div>
61 <div id="div2"></div>
62 </body>
63 </html>

   3. 实现任意值的运动框架v.1

    ①. 要求:只要简单的实现传入的对象、要变化的属性名和运动的最终目标,便能操作该对象的传入要变花属性的值由大到小的变化到目标大小。(基于缓冲运动)

    ②. 具体代码:

  1 <!DOCTYPE html>
  2 <html lang="en">
  3 <head>
  4     <meta charset="UTF-8">
  5     <title>任意值运动框架version 1.0</title>
  6     <style>
  7         div {
  8             width: 100px;
  9             height: 100px;
 10             background: green;
 11             margin: 10px;
 12         }
 13         #div2 {
 14             border: 1px solid black;
 15         }
 16         #div3{
 17             -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=30);
 18             filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=30);
 19             opacity: 0.3;
 20         }
 21     </style>
 22     <script>
 23         /**
 24          *
 25          * @param obj 操作对象
 26          * @param attr  属性名
 27          * @param iTarget  目标值
 28          */
 29         var timer = null;
 30         function startMove(obj, attr, iTarget) {
 31             clearInterval(timer);
 32             timer = setInterval(function () {
 33                 var cur = 0;
 34                 if (attr == 'opacity') { //单独处理透明度问题,因为只有透明度一定要小数
 35                     cur = parseFloat(getStyle(obj, attr)) * 100;//乘以100是让透明度的0~1之间的度数扩大,方便后面的使用
 36                 } else {
 37                     cur = parseInt(getStyle(obj, attr));
 38                 }
 39                 var speed = (iTarget - cur) / 6; //让速度与当前位置离ITarget的距离成正比。除数越大那么缓冲就越大
 40                 speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
 41                 if (cur == iTarget) {
 42                     clearInterval(timer);
 43                 } else {
 44                     if (attr == 'opacity') {
 45                         obj.style.filter = 'alpha(opacity:' + (cur + speed) + ')';
 46                         obj.style.opacity = (cur + speed) / 100;//把范围重新缩小为0~1之间
 47                     } else {
 48                         obj.style[attr] = cur + speed + 'px';
 49                     }
 50                 }
 51             }, 30);
 52         }
 53         /**
 54          * 获取样式属性的值。代替offset。
 55          * @param obj   操作对象
 56          * @param name  属性名
 57          * @returns {*}
 58          */
 59         function getStyle(obj, name) {
 60             if (obj.currentStyle) {
 61                 return obj.currentStyle[name];
 62             } else {
 63                 return getComputedStyle(obj, false)[name];
 64             }
 65         }
 66 
 67         /**
 68          * 测试:
 69          * 下面的例子只能一个一个进行测试,因为在这里没有设置多对象动作,
 70          *  也就是说定时器此时是共有的,如果同时使用这个定时器,会出错。
 71          */
 72         window.onload = function () {
 73             //测试width的变化(未设置border等其他影响width的属性)
 74             var oDiv1 = document.getElementById("div1");
 75             oDiv1.onmouseover = function () {
 76                 startMove(this, "width", 500);
 77             }
 78             oDiv1.onmouseout = function () {
 79                 startMove(this, "width", 100);
 80             }
 81             //测试width的变化(设置了影响width值得元素)
 82             /*
 83             var oDiv2 = document.getElementById("div2");
 84             oDiv2.onmouseover = function () {
 85                 startMove(this, "width", 500);
 86             }
 87             oDiv2.onmouseout = function () {
 88                 startMove(this, "width", 100);
 89             }
 90             */
 91 
 92             //测试width的变化(设置了影响width值得元素)
 93             /*
 94             var oDiv3 = document.getElementById("div3");
 95             oDiv3.onmouseover = function () {
 96                 startMove(this, "opacity", 100);
 97             }
 98             oDiv3.onmouseout = function () {
 99                 startMove(this, "opacity", 30);
100             }
101             */
102         }
103     </script>
104 </head>
105 <body>
106 <div id="div1"></div>
107 <div id="div2"></div>
108 <div id="div3"></div>
109 </body>
110 </html>

    4. 改进任意值的运动框架v.2

    ①. 要求:在ie低版本测试下,透明度的值因为是小数,会出现一些特殊的情况,所以对此进行改进。

    ②. 具体代码:

  1 <!DOCTYPE html>
  2 <html lang="en">
  3 <head>
  4     <!-- 2.o版本对透明度的算法进行了改进,加进了round方法 具体内容在39行-->
  5     <meta charset="UTF-8">
  6     <title>任意值运动框架version 2.0</title>
  7     <style>
  8         div {
  9             width: 100px;
 10             height: 100px;
 11             background: green;
 12             margin: 10px;
 13         }
 14 
 15         #div2 {
 16             border: 1px solid black;
 17         }
 18         #div3{
 19             -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=30);
 20             filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=30);
 21             opacity: 0.3;
 22         }
 23     </style>
 24     <script>
 25         /**
 26          *
 27          * @param obj 操作对象
 28          * @param attr  属性名
 29          * @param iTarget  目标值
 30          */
 31         var timer = null;
 32         function startMove(obj, attr, iTarget) {
 33             clearInterval(timer);
 34             timer = setInterval(function () {
 35                 var cur = 0;
 36                 if (attr == 'opacity') { //单独处理透明度问题,因为只有透明度一定要小数
 37                     //因为parseFloat会得到一个带小数的值,因为计算机会有误差,所以会得到一些奇怪的数值。
 38                     //因此在这里使用round()方法对其值进行四舍五入,去除掉小数
 39                     cur = Math.round(parseFloat(getStyle(obj, attr)) * 100);
 40                 } else {
 41                     cur = parseInt(getStyle(obj, attr));
 42                 }
 43                 var speed = (iTarget - cur) / 6; //让速度与当前位置离ITarget的距离成正比。除数越大那么缓冲就越大
 44                 //如果attr的值是0~1之间的话,下面这句代码将不可用,如果是0~100之间的话,那么就没问题
 45                 speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
 46                 if (cur == iTarget) {
 47                     clearInterval(timer);
 48                 } else {
 49                     if (attr == 'opacity') {
 50                         obj.style.filter = 'alpha(opacity:' + (cur + speed) + ')';
 51                         obj.style.opacity = (cur + speed) / 100;//把范围重新缩小为0~1之间
 52                     } else {
 53                         obj.style[attr] = cur + speed + 'px';
 54                     }
 55                 }
 56             }, 30);
 57         }
 58         /**
 59          * 获取样式属性的值。代替offset。
 60          * @param obj   操作对象
 61          * @param name  属性名
 62          * @returns {*}
 63          */
 64         function getStyle(obj, name) {
 65             if (obj.currentStyle) {
 66                 return obj.currentStyle[name];
 67             } else {
 68                 return getComputedStyle(obj, false)[name];
 69             }
 70         }
 71 
 72         /**
 73          * 测试:
 74          * 下面的例子只能一个一个进行测试,因为在这里没有设置多对象动作,
 75          *  也就是说定时器此时是共有的,如果同时使用这个定时器,会出错。
 76          */
 77         window.onload = function () {
 78             //测试width的变化(未设置border等其他影响width的属性)
 79             var oDiv1 = document.getElementById("div1");
 80             oDiv1.onmouseover = function () {
 81                 startMove(this, "width", 500);
 82             }
 83             oDiv1.onmouseout = function () {
 84                 startMove(this, "width", 100);
 85             }
 86             //测试width的变化(设置了影响width值得元素)
 87             /*
 88             var oDiv2 = document.getElementById("div2");
 89             oDiv2.onmouseover = function () {
 90                 startMove(this, "width", 500);
 91             }
 92             oDiv2.onmouseout = function () {
 93                 startMove(this, "width", 100);
 94             }
 95             */
 96 
 97             //测试width的变化(设置了影响width值得元素)
 98             /*
 99             var oDiv3 = document.getElementById("div3");
100             oDiv3.onmouseover = function () {
101                 startMove(this, "opacity", 100);
102             }
103             oDiv3.onmouseout = function () {
104                 startMove(this, "opacity", 30);
105             }
106             */
107         }
108     </script>
109 </head>
110 <body>
111 <div id="div1"></div>
112 <div id="div2"></div>
113 <div id="div3"></div>
114 </body>
115 </html>

 

    5. 改进任意值的运动框架v.3

    ①. 要求:在任意值的运动框架的1/2版本中,都没有实现多物体运动,也就是同时多个物体进行运动,在第三版本中加入了多物体运动的功能。

    ②. 具体代码:

    

  1 <!DOCTYPE html>
  2 <html lang="en">
  3 <head>
  4     <!-- 3.o版本 支持多物体运动 下面的三个例子可以同时测试-->
  5     <meta charset="UTF-8">
  6     <title>任意值运动框架version 2.0</title>
  7     <style>
  8         div {
  9             width: 100px;
 10             height: 100px;
 11             background: green;
 12             margin: 10px;
 13         }
 14 
 15         #div2 {
 16             border: 1px solid black;
 17         }
 18         #div3{
 19             -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=30);
 20             filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=30);
 21             opacity: 0.3;
 22         }
 23     </style>
 24     <script>
 25 
 26 
 27         /**
 28          *
 29          * @param obj 操作对象
 30          * @param attr  属性名
 31          * @param iTarget  目标值
 32          */
 33         function startMove(obj, attr, iTarget) {
 34             clearInterval(obj.timer);
 35             obj.timer = setInterval(function () {
 36                 var cur = 0;
 37                 if (attr == 'opacity') { //单独处理透明度问题,因为只有透明度一定要小数
 38                     //因为parseFloat会得到一个带小数的值,因为计算机会有误差,所以会得到一些奇怪的数值。
 39                     //因此在这里使用round()方法对其值进行四舍五入,去除掉小数
 40                     cur = Math.round(parseFloat(getStyle(obj, attr)) * 100);
 41                 } else {
 42                     cur = parseInt(getStyle(obj, attr));
 43                 }
 44                 var speed = (iTarget - cur) / 6; //让速度与当前位置离ITarget的距离成正比。除数越大那么缓冲就越大
 45                 //如果attr的值是0~1之间的话,下面这句代码将不可用,如果是0~100之间的话,那么就没问题
 46                 speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
 47                 if (cur == iTarget) {
 48                     clearInterval(obj.timer);
 49                 } else {
 50                     if (attr == 'opacity') {
 51                         obj.style.filter = 'alpha(opacity:' + (cur + speed) + ')';
 52                         obj.style.opacity = (cur + speed) / 100;//把范围重新缩小为0~1之间
 53                     } else {
 54                         obj.style[attr] = cur + speed + 'px';
 55                     }
 56                 }
 57             }, 30);
 58         }
 59 
 60 
 61         /**
 62          * 获取样式属性的值。代替offset。
 63          * @param obj   操作对象
 64          * @param name  属性名
 65          * @returns {*}
 66          */
 67         function getStyle(obj, name) {
 68             if (obj.currentStyle) {
 69                 return obj.currentStyle[name];
 70             } else {
 71                 return getComputedStyle(obj, false)[name];
 72             }
 73         }
 74 
 75         /**
 76          * 测试:
 77          * 下面的例子只能一个一个进行测试,因为在这里没有设置多对象动作,
 78          *  也就是说定时器此时是共有的,如果同时使用这个定时器,会出错。
 79          */
 80         window.onload = function () {
 81             //测试width的变化(未设置border等其他影响width的属性)
 82             var oDiv1 = document.getElementById("div1");
 83             oDiv1.timer = null;
 84             oDiv1.onmouseover = function () {
 85                 startMove(this, "width", 500);
 86             }
 87             oDiv1.onmouseout = function () {
 88                 startMove(this, "width", 100);
 89             }
 90             //测试width的变化(设置了影响width值得元素)
 91             var oDiv2 = document.getElementById("div2");
 92             oDiv2.timer = null;
 93             oDiv2.onmouseover = function () {
 94                 startMove(this, "width", 500);
 95             }
 96             oDiv2.onmouseout = function () {
 97                 startMove(this, "width", 100);
 98             }
 99 
100             //测试opacity的变化
101             var oDiv3 = document.getElementById("div3");
102             oDiv3.timer = null;
103             oDiv3.onmouseover = function () {
104                 startMove(this, "opacity", 100);
105             }
106             oDiv3.onmouseout = function () {
107                 startMove(this, "opacity", 30);
108             }
109         }
110     </script>
111 </head>
112 <body>
113 <div id="div1"></div>
114 <div id="div2"></div>
115 <div id="div3"></div>
116 </body>
117 </html>

 

   6. 实现链式运动框架

    ①. 要求:让其运动可以一个接一个的运行,也就是链式运动。具体效果看测试代码

    ②. 具体代码:

    html代码部分:

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title></title>
 6     <style>
 7         #div1{
 8             width:100px;
 9             height:100px;
10             background: green;
11         }
12 
13     </style>
14 
15     <script src="链式运动框架.js"></script>
16     <script>
17         window.onload=function(){
18             var oBtn = document.getElementsByTagName('input')[0];
19             var oDiv = document.getElementById('div1');
20             oBtn.onclick = function(){
21                 startMove(oDiv,'width',500,function(){
22                     startMove(oDiv,'height',500);
23                 });
24             }
25         }
26     </script>
27 </head>
28 <body>
29 <input type="button" value="运动">
30 
31 <div id="div1"></div>
32 </body>
33 </html>

 

链式运动框架.js代码:

  

 1 /**
 2  * 获取计算后的样式
 3  * @param obj 对象
 4  * @param name 样式名称:width/height等
 5  * @returns {*}
 6  */
 7 function getStyle(obj, name) {
 8     if (obj.currentStyle) {
 9         return obj.currentStyle[name];
10     } else {
11         return getComputedStyle(obj, false)[name];
12     }
13 }
14 
15 function startMove(obj, attr, iTarget, fun) {
16     clearInterval(obj.timer);
17     obj.timer = setInterval(function () {
18         var cur;
19         if (attr == 'opacity') {
20             cur = Math.round(parseFloat(getStyle(obj, attr)) * 100);
21         } else {
22             cur = parseInt(getStyle(obj, attr));
23         }
24         var speed = (iTarget - cur) / 6;
25         speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
26         if (cur == iTarget) {
27             clearInterval(obj.timer);
28             if (fun) {
29                 fun();
30             }
31         } else {
32             if (attr == 'opacity') {
33                 obj.style.filter = 'alpha(opacity:' + (cur + speed) + ')';
34                 obj.style.opacity = (cur + speed) / 100;//把范围重新缩小为0~1之间
35             } else {
36                 obj.style[attr] = cur + speed + 'px';
37             }
38         }
39     }, 30);
40 }

 

   7. 实现完美运动框架

    ①. 要求:改进链式运动框架,链式框架没办法实现多个“属性”同时运动!比如width、height同时变化。链式运动框架是没法实现的,所以对此进行改进,也就是最终的运动框架!

    ②. 具体代码:

    html代码部分:

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title></title>
 6     <style>
 7         #div1{
 8             width:100px;
 9             height:100px;
10             background: black;
11         }
12     </style>
13     <script src="完美运动框架.js"></script>
14     <script>
15         window.onload = function(){
16             var oBtn = document.getElementById('btn1');
17             var oDiv = document.getElementById('div1');
18             oBtn.onclick = function(){
19                 startMove(oDiv,{width:500,height:500},function(){
20                     startMove(oDiv,{width:100,height:100});
21                 });
22             }
23         }
24 
25     </script>
26 </head>
27 <body>
28 <input id="btn1" type="button" value="运动">
29 <div id="div1"></div>
30 </body>
31 </html>

 

    完美运动框架.js代码部分:

 1 /**
 2  * 获取对象的样式
 3  * @param obj  对象
 4  * @param name 样式名称
 5  */
 6 function getStyle(obj, name) {
 7     if (obj.currentStyle) {
 8         return obj.currentStyle[name];
 9     } else {
10         return getComputedStyle(obj, false)[name];
11     }
12 }
13 /**
14  * 完美运动框架实现了链式运动框架无法实现多属性同时运动的情况。如:width/height同时运动
15  * @param obj
16  * @param json 把要运动的属性通过json方式传入。如:{width:500,height:500}
17  * @param fun 执行完动作后,需要调用的方法
18  */
19 function startMove(obj, json, fun) {
20     clearTimeout(obj.timer);
21     obj.timer = setInterval(function () {
22         var stop = true; //用来判断是否可以关闭定时器
23         for (var item in json) {
24             var cur;
25             if (item == 'opacity') {
26                 cur = Math.round(parseFloat(getStyle(obj, item)) * 100);
27             } else {
28                 cur = parseInt(getStyle(obj, item));
29             }
30             var speed = (json[item] - cur) / 6;
31             speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
32             if (cur != json[item]) {    //判断当前对象的值是否已经达到目标值
33                 stop = false;           //未达到目标值时,让stop为false。
34             }
35             if (item == 'opacity') {
36                 obj.style.filter = 'alpha(opacity:' + (cur + speed) + ')';
37                 obj.style.opacity = (cur + speed) / 100;//把范围重新缩小为0~1之间
38             } else {
39                 obj.style[item] = cur + speed + 'px';
40             }
41             if(stop){
42                 clearInterval(obj.timer);
43                 if(fun){fun();} 
44             }
45         }
46     }, 30);
47 }

 

 

声明:这些知识点都来自智能社的视频所得~~

 

posted @ 2015-11-25 23:15  JamKong  阅读(300)  评论(0编辑  收藏  举报