js-运动总结(常见运动效果)

mac2022-06-30  30

匀速运动加速运动缓冲运动碰撞运动重力运动多物体多值多链式运动框架

1. 匀速运动

速度isSpeed是个定值

function startmov(obj) { clearInterval(timer); var isSpeed = 10; timer = setInterval(function () { obj.style.left = obj.offsetLeft + isSpeed + 'px'; },30); }

2. 变速运动

核心就是isSpeed每次执行发生改变

// 变速运动 function starSpeedChangeMove(obj,target) { clearInterval(timer); var isSpeed; timer = setInterval(function () { isSpeed = (target - obj.offsetLeft) / 15; isSpeed = isSpeed > 0 ? Math.ceil(isSpeed) : Math.floor(isSpeed); obj.style.left = obj.offsetLeft + isSpeed + 'px'; },30); }
应用(伸缩栏)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <style> .wrapper{ position : absolute; top: 200px; left: -400px; width: 400px; height: 100px; background: yellowgreen; } .demo{ position: absolute; top: 0; left: 400px; width: 40px; height: 100px; background: yellow; } </style> </head> <body> <div class="wrapper"> <div class="demo"> </div> </div> <script> var oDivDemo = document.getElementsByClassName('wrapper')[0]; var timer = null; oDivDemo.onmouseenter = function () { starSpeedChangeMove(this,0); } oDivDemo.onmouseleave = function () { starSpeedChangeMove(this,-400); } function starSpeedChangeMove(obj,target) { clearInterval(timer); var isSpeed; timer = setInterval(function () { isSpeed = (target - obj.offsetLeft) / 15; isSpeed = isSpeed > 0 ? Math.ceil(isSpeed) : Math.floor(isSpeed); obj.style.left = obj.offsetLeft + isSpeed + 'px'; },30); } </script> </body> </html>

3. 缓冲运动

顾名思义,所谓缓冲,就是说速度不同;在一定条件下,距离越大,速度越大;距离越小,速度也就越小。 也就是跟变速运动差不多代码

4.碰撞运动(弹性运动)

在发生碰撞的时候,我们把对应的x,y方向的速度乘以"摩擦系数"

// 弹性运动 function starMove (obj, target) { clearInterval(obj.timer); var isSpeed = 20; var a, u = 0.8; // u表示摩擦系数 obj.timer = setInterval(function (){ a = (target - obj.offsetLeft) / 15; isSpeed = isSpeed + a; isSpeed = isSpeed * 0.9; if(Math.abs(isSpeed) < 1 && Math.abs(target - obj.offsetLeft) < 1){ clearInterval(obj.timer); }else{ obj.style.left = obj.offsetLeft + isSpeed + 'px'; } },30); }
应用(弹性导航栏)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <style> *{ margin: 0px; padding: 0px; list-style: none; } ul{ position: relative; width: 600px; height: 80px; /* border: 1px solid #000; */ margin : 100px auto 0; } ul li.nav{ width: 148px; height: 78px; border: 1px solid #000; color : #000; text-align: center; line-height: 78px; float: left; } ul li.bg{ position: absolute; top: 0px; left: 0px; width: 150px; height: 80px; background: rgb(214, 49, 49); z-index: -1; } </style> </head> <body> <ul> <li class="nav">ES6</li> <li class="nav">Webpack</li> <li class="nav">Vue</li> <li class="nav">Node</li> <li class="bg"></li> </ul> <script> var oLi = document.getElementsByTagName('li'); var oBg = document.getElementsByClassName('bg')[0]; var oLiArr = Array.prototype.slice.call(oLi, 0); oLiArr.forEach(function (ele, index){ ele.onmouseenter = function (){ starMove(oBg,this.offsetLeft); } }); function starMove (obj, target) { clearInterval(obj.timer); var isSpeed = 20; var a, u = 0.8; // u表示摩擦系数 obj.timer = setInterval(function (){ a = (target - obj.offsetLeft) / 15; isSpeed = isSpeed + a; isSpeed = isSpeed * 0.9; if(Math.abs(isSpeed) < 1 && Math.abs(target - obj.offsetLeft) < 1){ clearInterval(obj.timer); }else{ obj.style.left = obj.offsetLeft + isSpeed + 'px'; } },30); } </script> </body> </html>

5. 重力运动

// targetSpeedX,targetSpeedY 表示的是x,y速度矢量值 function starMove (obj,targetSpeedX,targetSpeedY){ clearInterval(obj.timer); var iSpeedX, iSpeedY, g = 10, // 重力加速度 u = 0.8; // 碰撞时速度损失 iSpeedX = (typeof targetSpeedX == 'undefined' ? 6 : targetSpeedX), iSpeedY = (typeof targetSpeedY == 'undefined' ? 8 : targetSpeedY); console.log(iSpeedY,iSpeedX); obj.timer = setInterval(function (){ iSpeedY += g; var newLeft = obj.offsetLeft + iSpeedX, newTop = obj.offsetTop + iSpeedY; // 边界处理 if(newTop >= document.documentElement.clientHeight - obj.offsetHeight){ iSpeedY *= -1; iSpeedY *= u; iSpeedX *= u; newTop = document.documentElement.clientHeight - obj.offsetHeight; } if(newTop <= 0){ iSpeedY *= -1; iSpeedY *= u; iSpeedX *= u; newTop = 0; } if(newLeft >= document.documentElement.clientWidth - obj.offsetWidth){ iSpeedX *= -1; iSpeedX *= u; newLeft = document.documentElement.clientWidth - obj.offsetWidth; } if(newLeft <= 0){ iSpeedX *= -1; iSpeedX *= u; newLeft = 0; } // 判断结束条件 if(Math.abs(document.documentElement.clientHeight-obj.offsetHeight-newTop) < 1 && Math.abs(iSpeedY) < 1){ clearInterval(obj.timer); }else{ obj.style.left = newLeft + 'px'; obj.style.top = newTop + 'px'; } },30); }
应用(拖拽抛出效果)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <style> body{ overflow: hidden; } .demo{ position: absolute; left: 0px; top: 0px; width: 100px; height: 100px; border-radius: 50%; background: #000; } </style> </head> <body> <div class="demo"></div> <script> var oDiv = document.getElementsByClassName('demo')[0]; // oDiv.onclick = function (){ // starMove(this,1,1); // } var lastX = oDiv.offsetLeft, lastY = oDiv.offsetTop; oDiv.onmousedown = function (e) { var event = e || window.event; var disX = event.clientX - this.offsetLeft, disY = event.clientY - this.offsetTop, that = this; var iSpeedX = 0, iSpeedY = 0; document.onmousemove = function (e) { var newLeft = e.clientX - disX, newTop = e.clientY - disY; iSpeedX = newLeft - lastX, iSpeedY = newTop - lastY, lastX = newLeft, lastY = newTop; that.style.left = newLeft + 'px'; that.style.top = newTop + 'px'; document.onmouseup = function () { document.onmousemove = null; document.onmouseup = null; //iSpeedX,iSpeedY 相当于是速度的方向差值 正负表示方向 starMove(that,iSpeedX,iSpeedY); } } } // 模拟重力场 // targetSpeedX,targetSpeedY 表示的是x,y速度矢量值 function starMove (obj,targetSpeedX,targetSpeedY){ clearInterval(obj.timer); var iSpeedX, iSpeedY, g = 10, // 重力加速度 u = 0.8; // 碰撞时速度损失 iSpeedX = (typeof targetSpeedX == 'undefined' ? 6 : targetSpeedX), iSpeedY = (typeof targetSpeedY == 'undefined' ? 8 : targetSpeedY); console.log(iSpeedY,iSpeedX); obj.timer = setInterval(function (){ iSpeedY += g; var newLeft = obj.offsetLeft + iSpeedX, newTop = obj.offsetTop + iSpeedY; // 边界处理 if(newTop >= document.documentElement.clientHeight - obj.offsetHeight){ iSpeedY *= -1; iSpeedY *= u; iSpeedX *= u; newTop = document.documentElement.clientHeight - obj.offsetHeight; } if(newTop <= 0){ iSpeedY *= -1; iSpeedY *= u; iSpeedX *= u; newTop = 0; } if(newLeft >= document.documentElement.clientWidth - obj.offsetWidth){ iSpeedX *= -1; iSpeedX *= u; newLeft = document.documentElement.clientWidth - obj.offsetWidth; } if(newLeft <= 0){ iSpeedX *= -1; iSpeedX *= u; newLeft = 0; } // 判断结束条件 if(Math.abs(document.documentElement.clientHeight-obj.offsetHeight-newTop) < 1 && Math.abs(iSpeedY) < 1){ clearInterval(obj.timer); }else{ obj.style.left = newLeft + 'px'; obj.style.top = newTop + 'px'; } },30); } </script> </body> </html>

6. 多物体多值多链式运动框架

多物体运动: 让每一个运动的物体拥有自己的定时器 定时器独立 把定时器作为对象的属性 让定时器独立

链式运动 上一个动作结束 进入到下一个动作 解决 : 在运动函数上加一个参数,参数代表回调函数

参数说明:obj 对应元素, json 对象, 属性是改变的样式,比如 width height opacity callback 回调函数 可以进行多个动作发生 小技巧: opacity 改变的时候,可以把isSpeed扩大100倍,最后在缩小100倍

function startMove(obj, json, callback){ clearInterval(obj.timer); obj.timer = setInterval(function (){ var oBstop = true, isSpeed, iCur; for(var attr in json){ if(attr == 'opacity'){ iCur = parseFloat(getStyle(obj,attr)) * 100; }else{ iCur = parseInt(getStyle(obj,attr)); } isSpeed = (json[attr] - iCur) / 7; isSpeed = isSpeed > 0 ? Math.ceil(isSpeed) : Math.floor(isSpeed); if(attr == 'opacity'){ obj.style.opacity = (isSpeed + iCur) / 100; }else{ obj.style[attr] = (isSpeed + iCur) + 'px'; } if(json[attr] != iCur){ oBstop = false; } } if(oBstop){ clearInterval(obj.timer); typeof callback == 'function' ? callback() : ""; } },30); }
demo(具体用法)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <style> div{ position : absolute; left: 0; width: 100px; height: 100px; background : red; opacity: 1; border : 1px solid #000; margin: 100px; } .top { top : 100px; } .buttom { bottom : 100px; } </style> </head> <body> <div class="top">1</div> <div class="buttom">2</div> <script> var oDiv = document.getElementsByTagName('div'); var timer = null; var targetObj = { width : 400, height : 400, opacity : 20, left : 200, top : 200 } oDiv[0].onclick = function (){ startMove(this,targetObj,function (){ console.log('this == ', this); startMove(oDiv[1],targetObj); }); console.log(222); } // 多物体多链式运动框架 function getStyle (obj, attr) { if(obj.currentStyle){ return obj.currentStyle[attr]; }else{ return window.getComputedStyle(obj,false)[attr]; } } function startMove(obj, json, callback){ clearInterval(obj.timer); obj.timer = setInterval(function (){ var oBstop = true, isSpeed, iCur; for(var attr in json){ if(attr == 'opacity'){ iCur = parseFloat(getStyle(obj,attr)) * 100; }else{ iCur = parseInt(getStyle(obj,attr)); } isSpeed = (json[attr] - iCur) / 7; isSpeed = isSpeed > 0 ? Math.ceil(isSpeed) : Math.floor(isSpeed); if(attr == 'opacity'){ obj.style.opacity = (isSpeed + iCur) / 100; }else{ obj.style[attr] = (isSpeed + iCur) + 'px'; } if(json[attr] != iCur){ oBstop = false; } } if(oBstop){ clearInterval(obj.timer); typeof callback == 'function' ? callback() : ""; } },30); } </script> </body> </html>
最新回复(0)