---来自一个前端妹子
1 <!DOCTYPE html> 2 <html> 3 <head lang="en"> 4 <meta charset="UTF-8"> 5 <title></title> 6 7 8 <!-- 9 先快后慢 10 一开始的步子要迈的大,后面的步子要小 11 12 步子要越来越小 13 14 被除数 / 10 ,被除数的值越大,结果就越大,被除数越小。值就越小 15 16 所以我们要找到一个越来越小的数,再去除以10,把结果作为步长,就能起到步子越来越小 17 18 到底什么是越来越小的值?到目标的距离,是越来越小的 19 20 21 当前距离 目标 基数(除数) 22 0 400 10 400 - 0 = 400 / 10 = 40 这步走40 23 40 400 10 400 - 40 = 360 / 10 = 36 这步走36 24 25 76 400 10 400 - 76 = 324 / 10 = 32.4 向上取整变成了33 这步走33 26 109 400 10 400 - 109 = 291 / 10 = 29.1 取整变 30 27 ……………………………………………………………………………… 28 390 400 10 400 - 390 = 10 / 10 = 1 这步走1 29 391 400 10 400 - 391 = 9 / 10 = 0.9 向上取整走1 30 越到后面越慢,而且到最后那几步就是1个像素1个像素的走,能走到,而且绝对不会超 31 32 399 400 10 400 - 399 = 1 / 10 = 0.1 向上取整变1 33 34 --> 35 36 37 <style> 38 39 #box { 40 width: 100px; 41 height: 100px; 42 background-color: red; 43 position: absolute; 44 } 45 46 </style> 47 </head> 48 <body> 49 50 <input type="button" value="移动到400" id="move400"/> 51 <input type="button" value="移动到800" id="move800"/> 52 53 <div id="box"></div> 54 55 </body> 56 </html> 57 58 <script> 59 60 //找到div 61 var box = document.getElementById("box"); 62 63 //移动到400的点击事件 64 document.getElementById("move400").onclick = function () { 65 66 animateSlow(400); 67 } 68 69 70 document.getElementById("move800").onclick = function () { 71 72 animateSlow(800); 73 } 74 75 76 var timerID; 77 function animateSlow(target) { 78 79 clearInterval(timerID); 80 81 timerID = setInterval(function () { 82 83 //获取到当前的位置 84 var current = box.offsetLeft; 85 86 //用目标 - 当前位置 得到距离 ,再用距离除以10,再向上取整得到步长 87 var step = Math.ceil((target - current) / 10); 88 89 //因为绝对不会超,所以算出步长后直接走这一步就行了 90 current += step; 91 92 //设置给要移动的元素 93 box.style.left = current + "px"; 94 95 console.log("当前位置:" + current + "------步长:" + step); 96 97 //如果到了目的地,就停止计时器 98 if (current == target) { 99 100 clearInterval(timerID); 101 } 102 103 }, 50 104 ) 105 } 106 107 108 </script>
01-缓动动画的封装之可以移动到不同的目标距离.html
先快后慢 一开始的步子要迈的大,后面的步子要小 步子要越来越小 被除数 / 10 ,被除数的值越大,结果就越大,被除数越小。值就越小 所以我们要找到一个越来越小的数,再去除以10,把结果作为步长,就能起到步子越来越小 到底什么是越来越小的值?到目标的距离,是越来越小的 当前距离 目标 基数(除数) 0 400 10 400 - 0 = 400 / 10 = 40 这步走40 40 400 10 400 - 40 = 360 / 10 = 36 这步走36 76 400 10 400 - 76 = 324 / 10 = 32.4 向上取整变成了33 这步走33 109 400 10 400 - 109 = 291 / 10 = 29.1 取整变 30……………………………………………………………………………… 390 400 10 400 - 390 = 10 / 10 = 1 这步走1 391 400 10 400 - 391 = 9 / 10 = 0.9 向上取整走1 越到后面越慢,而且到最后那几步就是1个像素1个像素的走,能走到,而且绝对不会超 399 400 10 400 - 399 = 1 / 10 = 0.1 向上取整变1
1 <!DOCTYPE html> 2 <html> 3 <head lang="en"> 4 <meta charset="UTF-8"> 5 <title></title> 6 7 8 <style> 9 div { 10 width: 100px; 11 height: 100px; 12 background-color: red; 13 position: absolute; 14 } 15 16 #blue { 17 background-color: blue; 18 top: 150px; 19 } 20 21 </style> 22 23 </head> 24 <body> 25 26 <input type="button" value="移动到红" id="moveRed"/> 27 <input type="button" value="移动到蓝" id="moveBlue"/> 28 29 <div id="red"></div> 30 <div id="blue"></div> 31 32 </body> 33 </html> 34 35 <script> 36 var red = document.getElementById("red"); 37 var blue = document.getElementById("blue"); 38 39 document.getElementById("moveRed").onclick = function () { 40 animateSlow(red, 400); 41 }; 42 43 document.getElementById("moveBlue").onclick = function () { 44 45 animateSlow(blue, 400); 46 }; 47 48 49 50 /* 51 52 第二重封装: 53 解决了可以移动不同元素的问题 54 以及移动第二个会停止第一个元素的问题(自己的只能自己停) 55 56 */ 57 58 function animateSlow(obj, target) { 59 60 clearInterval(obj.timerID); 61 62 obj.timerID = setInterval(function () { 63 64 //获取到当前的位置 65 var current = obj.offsetLeft; 66 67 //用目标 - 当前位置 得到距离 ,再用距离除以10,再向上取整得到步长 68 var step = Math.ceil((target - current) / 10); 69 70 //因为绝对不会超,所以算出步长后直接走这一步就行了 71 current += step; 72 73 //设置给要移动的元素 74 obj.style.left = current + "px"; 75 76 console.log("当前位置:" + current + "------步长:" + step); 77 78 //如果到了目的地,就停止计时器 79 if (current == target) { 80 81 clearInterval(obj.timerID); 82 } 83 84 }, 50 85 ) 86 } 87 </script>
02-缓动动画的封装之各种对象可以动.html
第二重封装: 解决了可以移动不同元素的问题 以及移动第二个会停止第一个元素的问题(自己的只能自己停)
1 <!DOCTYPE html> 2 <html> 3 <head lang="en"> 4 <meta charset="UTF-8"> 5 <title></title> 6 7 <!-- 8 当前位置 目标位置 基数 9 800 400 10 400 -800 = -400 /10 = -40 10 760 400 10 400 - 760 = -360 / 10 = -36 11 ..................... 12 13 409 400 10 400 - 409 = -9 / 10 = -0.9 向下取整变-1 14 408 400 15 407 16 406 17 400 18 19 如果是往右走 20 21 791 800 10 800-791 = 9 /10 = 0.9 要向上取整才正确 22 23 我们发现有的时候要向上,有的时候要向下 24 25 如果最终算出的结果为负数,一定要向下,如果算出的结果为正数,要向上 26 --> 27 28 29 <style> 30 div { 31 width: 100px; 32 height: 100px; 33 background-color: red; 34 position: absolute; 35 } 36 37 38 </style> 39 40 </head> 41 <body> 42 43 <input type="button" value="移动到400" id="move400"/> 44 <input type="button" value="移动到800" id="move800"/> 45 46 <div id="red"></div> 47 48 </body> 49 </html> 50 51 <script> 52 var red = document.getElementById("red"); 53 var blue = document.getElementById("blue"); 54 55 document.getElementById("move400").onclick = function () { 56 57 animateSlow(red, 400); 58 }; 59 60 document.getElementById("move800").onclick = function () { 61 62 animateSlow(red, 800); 63 }; 64 65 66 /* 67 68 第三重封装: 69 解决了既可以往右走,也可以往走的问题 70 71 发现:只要看算出的结果,如果是正就要向上取整,如果是负就要向下取整 72 73 74 75 */ 76 77 function animateSlow(obj, target) { 78 79 clearInterval(obj.timerID); 80 81 obj.timerID = setInterval(function () { 82 83 //获取到当前的位置 84 var current = obj.offsetLeft; 85 86 //先用目标-当前位置,再除以基数得到结果 87 var result = (target - current) / 10; 88 89 //如果结果是正就用向上取整,如果是负就用 向下取整 90 var step = result > 0 ? Math.ceil(result) : Math.floor(result); 91 92 //因为绝对不会超,所以算出步长后直接走这一步就行了 93 current += step; 94 95 //设置给要移动的元素 96 obj.style.left = current + "px"; 97 98 console.log("当前位置:" + current + "------步长:" + step); 99 100 //如果到了目的地,就停止计时器 101 if (current == target) { 102 103 clearInterval(obj.timerID); 104 } 105 106 }, 50 107 ) 108 } 109 </script>
03-缓动动画的封装完成往左往右动.html
当前位置 目标位置 基数 800 400 10 400 -800 = -400 /10 = -40 760 400 10 400 - 760 = -360 / 10 = -36 ..................... 409 400 10 400 - 409 = -9 / 10 = -0.9 向下取整变-1 408 400 407 406 400 如果是往右走 791 800 10 800-791 = 9 /10 = 0.9 要向上取整才正确 我们发现有的时候要向上,有的时候要向下 如果最终算出的结果为负数,一定要向下,如果算出的结果为正数,要向上
第三重封装:解决了既可以往右走,也可以往走的问题 发现:只要看算出的结果,如果是正就要向上取整,如果是负就要向下取整
1 <!DOCTYPE html> 2 <html> 3 <head lang="en"> 4 <meta charset="UTF-8"> 5 <title></title> 6 7 <style> 8 #box { 9 width: 100px; 10 height: 100px; 11 background-color: red; 12 position: absolute; 13 } 14 15 /* 16 第四重封装: 17 解决了可以改动上下移动和左右移动以及宽高变化的问题 18 19 加一个参数:参数传入一个你需要改动的属性 20 21 然后再通过我们封装的获取样式的方法,获取到当前的值 22 算法不变 23 24 只不过赋值时,就根据你传入的参数来赋值到对应的属性 25 26 */ 27 </style> 28 </head> 29 <body> 30 31 <input type="button" value="向下走500" id="down500"/> 32 <input type="button" value="向右走500" id="right500"/> 33 <input type="button" value="变宽到400" id="width400"/> 34 <input type="button" value="变高到400" id="height400"/> 35 36 <div id="box"></div> 37 38 </body> 39 </html> 40 41 42 <script src="common.js"></script> 43 <script> 44 //找到div 45 var box = document.getElementById("box"); 46 47 document.getElementById("down500").onclick = function () { 48 49 animateSlow(box, 500, "top"); 50 }; 51 52 53 document.getElementById("right500").onclick = function () { 54 55 animateSlow(box, 500, "left"); 56 }; 57 58 document.getElementById("width400").onclick = function () { 59 60 animateSlow(box, 400, "width"); 61 }; 62 63 document.getElementById("height400").onclick = function () { 64 65 animateSlow(box, 400, "height"); 66 }; 67 68 69 function animateSlow(obj, target, attr) {//可能传left,也可能传top 70 71 clearInterval(obj.timerID); 72 73 obj.timerID = setInterval(function () { 74 75 //获取到当前的位置 76 //传入的是什么属性就获取什么属性的样式,因为得到的是带单位的字符串,所以要用parseInt做一个转换 77 var current = parseInt(getStyle(obj, attr)); 78 79 //先用目标-当前位置,再除以基数得到结果 80 var result = (target - current) / 10; 81 82 //如果结果是正就用向上取整,如果是负就用 向下取整 83 var step = result > 0 ? Math.ceil(result) : Math.floor(result); 84 85 //因为绝对不会超,所以算出步长后直接走这一步就行了 86 current += step; 87 88 //设置给要移动的元素 89 obj.style[attr] = current + "px"; 90 91 console.log("当前位置:" + current + "------步长:" + step); 92 93 //如果到了目的地,就停止计时器 94 if (current == target) { 95 96 clearInterval(obj.timerID); 97 } 98 99 }, 50 100 ) 101 } 102 </script>
04-缓动动画的封装之实现上下宽高可以用动画变化.html
第四重封装: 解决了可以改动上下移动和左右移动以及宽高变化的问题 加一个参数:参数传入一个你需要改动的属性 然后再通过我们封装的获取样式的方法,获取到当前的值 算法不变 只不过赋值时,就根据你传入的参数来赋值到对应的属性
1 <!DOCTYPE html> 2 <html> 3 <head lang="en"> 4 <meta charset="UTF-8"> 5 <title></title> 6 7 <style> 8 #box { 9 width: 100px; 10 height: 100px; 11 background-color: red; 12 position: absolute; 13 } 14 15 /* 16 第五重封装: 17 解决了可以同时改多个属性的问题 18 19 1.把函数的参数精简为2个,1个为接受要改的元素,第二个就是接收对象 20 对象里面放你要改的属性(对象的属性)和它对应的目标(属性的值) 21 22 2.在计时器里遍历接收对象的那个参数,取到key,key就是我们要取到的样式的属性,以及要改的属性 23 算法不变,只是取属性时用key来取了 24 25 3.不能哪一个到了目标就停止计时器,而应该是全部到了才停止计时器 26 用一个标记来标记,只要有一个没到,就改成false,循环外面判断是否还是为true,还是为true就代表都到了,都到了就停止计时器 27 28 */ 29 </style> 30 </head> 31 <body> 32 33 <input type="button" value="同时向右走到500向下走到400" id="btn"/> 34 35 36 <div id="box"></div> 37 38 </body> 39 </html> 40 41 42 <script src="common.js"></script> 43 <script> 44 45 46 //找到div 47 var box = document.getElementById("box"); 48 49 document.getElementById("btn").onclick = function () { 50 51 /* 52 我们现在需要同时改多个属性,而且多个属性可能有不同的不表 53 那么如果用以前的那种加参数方式不行,因为假如说要改3个属性,就需要6个,到时再临时加参数肯定不行 54 我想用一个参数,既可以让你传入一个属性和一个目标 55 也可以传入多个属性加多个目标 56 */ 57 58 var att = { 59 60 left: 500, 61 top: 400, 62 width: 400, 63 height: 400, 64 } 65 66 animateSlow(box, att); 67 }; 68 69 70 function animateSlow(obj, attrs) {//可能传left,也可能传top 71 72 clearInterval(obj.timerID); 73 74 obj.timerID = setInterval(function () { 75 76 //我先默认认为所有的都到了目的地(标记为true),在循环里,我判断一下,只要有一个不到,我就把标记改为false 77 78 //默认先认为都到了 79 var flag = true; 80 81 //把所有的属性名取出来 82 for (var key in attrs) { // left: 500 top: 400 83 84 //获取到当前的位置 85 //传入的是什么属性就获取什么属性的样式,因为得到的是带单位的字符串,所以要用parseInt做一个转换 86 var current = parseInt(getStyle(obj, key)); 87 88 //先用目标-当前位置,再除以基数得到结果 89 //注意:此时目标是它的key所对应的值 90 var result = (attrs[key] - current) / 10; 91 92 //如果结果是正就用向上取整,如果是负就用 向下取整 93 var step = result > 0 ? Math.ceil(result) : Math.floor(result); 94 95 //因为绝对不会超,所以算出步长后直接走这一步就行了 96 current += step; 97 98 //设置给要移动的元素 99 obj.style[key] = current + "px"; 100 101 console.log("当前位置:" + current + "------步长:" + step); 102 103 //只要有一个没到,就不要停计时器 104 if (current != attrs[key]) { 105 106 flag = false; 107 } 108 } 109 110 //如果这个值还是为true,就代表所有的属性都到了目的地 111 if (flag) { 112 113 clearInterval(obj.timerID); 114 } 115 116 }, 50) 117 } 118 </script>
05-缓动动画的封装之实现斜着走.html
第五重封装:
我们现在需要同时改多个属性,而且多个属性可能有不同的不表那么如果用以前的那种加参数方式不行,因为假如说要改3个属性,就需要6个,到时再临时加参数肯定不行我想用一个参数,既可以让你传入一个属性和一个目标也可以传入多个属性加多个目标
1 <!DOCTYPE html> 2 <html> 3 <head lang="en"> 4 <meta charset="UTF-8"> 5 <title></title> 6 7 8 <!-- 9 这一重解决了: 10 1.透明度不可以改的问题(解决为可以改) 11 1.1 因为透明度特殊,所以单独在forin里用一个if判断,如果key等于opacity,那么就走opacity的代码,else就走以前写的代码 12 1.2 在opacity里,代码跟以前的代码几乎一样,只改动以下几个部分 13 1.2.1 把parseInt改成parseFloat ,再取到值以后给当前位置和目标位置先乘以100 14 1.2.2 在赋值到元素的opacity之前,先除以100 15 1.2.3 在赋值时去掉px 16 17 18 2.增加动画完成后可以执行你想做的事的代码(回调函数) 19 2.1 先增加一个参数,用来接收用户传入的函数 20 2.2 在清除计时器的代码后面,先判断是不是函数,如果是,就调用 21 22 --> 23 24 <style> 25 #box { 26 width: 100px; 27 height: 100px; 28 background-color: red; 29 position: absolute; 30 } 31 32 </style> 33 </head> 34 <body> 35 36 <input type="button" value="同时向右走到500向下走到400" id="btn"/> 37 38 39 <div id="box"></div> 40 41 </body> 42 </html> 43 44 45 <script src="common.js"></script> 46 <script> 47 48 49 //找到div 50 var box = document.getElementById("box"); 51 52 document.getElementById("btn").onclick = function () { 53 54 /* 55 我们现在需要同时改多个属性,而且多个属性可能有不同的不表 56 那么如果用以前的那种加参数方式不行,因为假如说要改3个属性,就需要6个,到时再临时加参数肯定不行 57 我想用一个参数,既可以让你传入一个属性和一个目标 58 也可以传入多个属性加多个目标 59 */ 60 61 var att = { 62 63 opacity: 0, 64 left: 500, 65 top: 400, 66 width: 300, 67 height: 300 68 } 69 70 animateSlow(box, att, function () { 71 72 var attrs = { 73 74 top: 31, 75 left: 1000, 76 width: 100, 77 height: 100, 78 opacity: 1 79 } 80 animateSlow(box, attrs); 81 }); 82 }; 83 84 85 function animateSlow(obj, attrs, fn) {//可能传left,也可能传top 86 87 clearInterval(obj.timerID); 88 89 obj.timerID = setInterval(function () { 90 91 //我先默认认为所有的都到了目的地(标记为true),在循环里,我判断一下,只要有一个不到,我就把标记改为false 92 93 //默认先认为都到了 94 var flag = true; 95 96 //把所有的属性名取出来 97 for (var key in attrs) { // left: 500 top: 400 98 99 if (key == "opacity") { 100 101 //获取到当前的位置 102 //传入的是什么属性就获取什么属性的样式,因为得到的是带单位的字符串,所以要用parseInt做一个转换 103 var current = parseFloat(getStyle(obj, key)) * 100; 104 105 //它的值太小了 106 //先用目标-当前位置,再除以基数得到结果 107 //注意:此时目标是它的key所对应的值 108 var result = (attrs[key] * 100 - current) / 10; 109 110 //如果结果是正就用向上取整,如果是负就用 向下取整 111 var step = result > 0 ? Math.ceil(result) : Math.floor(result); 112 113 //因为绝对不会超,所以算出步长后直接走这一步就行了 114 current += step; 115 116 //之前你是先乘以100做的运算,所以后面应该把再除以100 117 current /= 100; 118 //设置给要移动的元素 119 obj.style[key] = current; 120 121 console.log("当前位置:" + current + "------步长:" + step); 122 123 //只要有一个没到,就不要停计时器 124 if (current != attrs[key]) { 125 126 flag = false; 127 } 128 129 } else { 130 131 //获取到当前的位置 132 //传入的是什么属性就获取什么属性的样式,因为得到的是带单位的字符串,所以要用parseInt做一个转换 133 var current = parseInt(getStyle(obj, key)); 134 135 //先用目标-当前位置,再除以基数得到结果 136 //注意:此时目标是它的key所对应的值 137 var result = (attrs[key] - current) / 10; 138 139 //如果结果是正就用向上取整,如果是负就用 向下取整 140 var step = result > 0 ? Math.ceil(result) : Math.floor(result); 141 142 //因为绝对不会超,所以算出步长后直接走这一步就行了 143 current += step; 144 145 //设置给要移动的元素 146 obj.style[key] = current + "px"; 147 148 console.log("当前位置:" + current + "------步长:" + step); 149 150 //只要有一个没到,就不要停计时器 151 if (current != attrs[key]) { 152 153 flag = false; 154 } 155 } 156 } 157 158 //如果这个值还是为true,就代表所有的属性都到了目的地 159 if (flag) { 160 161 clearInterval(obj.timerID); 162 163 //这里的代码不要写死,就让别人把要结束时执行的代码传进来 164 //你传的是什么代码,我执行的就是什么代码 165 if (fn instanceof Function) { 166 fn(); 167 } 168 169 } 170 171 }, 50) 172 } 173 </script>
06-缓动动画的封装终极封装.html
这一重解决了: 1.透明度不可以改的问题(解决为可以改) 1.1 因为透明度特殊,所以单独在forin里用一个if判断,如果key等于opacity,那么就走opacity的代码,else就走以前写的代码 1.2 在opacity里,代码跟以前的代码几乎一样,只改动以下几个部分 1.2.1 把parseInt改成parseFloat ,再取到值以后给当前位置和目标位置先乘以100 1.2.2 在赋值到元素的opacity之前,先除以100 1.2.3 在赋值时去掉px 2.增加动画完成后可以执行你想做的事的代码(回调函数) 2.1 先增加一个参数,用来接收用户传入的函数 2.2 在清除计时器的代码后面,先判断是不是函数,如果是,就调用
原文地址:https://www.cnblogs.com/DZzzz/p/8167260.html
时间: 2024-09-30 14:21:54