做一件事情应该向闻一多先生学习,做了再说或者是做了也没有必要说出去。
弹性运动
分析:当拿到一个问题的时候,要进行三步分析,明确已知,明确所求,找已知与所求之间的联系。
- 要想实现弹性运动,抽象出来的话就是类似于物理学当中的小球在用皮筋拉长之后的来回伸缩运动,是加速度指向皮筋中心的加速度不断变化的运动。
- 我在自我实现过程中出现的问题是:1.在赋予初值速度,加速度,摩擦力的时候出现了在定时器内部赋值的问题,这样子会导致速度每次都重新更新为第一次的情况,根本无法减速。2.在定时器内部改变的变量是加速度(随着dom元素距离target的距离来动态改变),在加速度改变之后,我们相对应的改变当时的速度,此时要乘上一个摩擦力。
- 最后进行判断的时候,由于在实际验证的过程中,由于
a = (target - dom.offsetLeft) / 5;
这样子运算出来的加速度以及最终通过dom.style.left = dom.offsetLeft + iSpeed + 'px';
的改变无法准确使得最终dom元素距离target的距离是0,而是一个绝对值介于0~1之间的小数,会陷入定时器无法清除的问题,所以我们要人为清空定时器的同时将dom.style.left = target;
使得dom元素与目标点重合。(类似于缓冲运动)
标准的代码实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>弹性运动</title>
<style>
div {
width: 100px;
height: 100px;
background-color: orange;
position: absolute;
left: 0px;
top: 0px;
}
span {
width: 1px;
height: 100px;
background-color: black;
position: absolute;
left: 300px;
top: 0px;
}
</style>
</head>
<body>
<div></div>
<span></span>
<script>
var oDiv = document.getElementsByTagName('div')[0];
var timer = null;
oDiv.onclick = function () {
startMove(this, 300);
}
function startMove(dom, target) {
clearInterval(dom.timer);
// 赋初值
var iSpeed = 0; //初速度
var a = 3;
var u = 0.8; //摩擦力
// 通过定时器来改变dom的运动状况
dom.timer = setInterval(function () {
a = (target - dom.offsetLeft) /
5; //加速度,大小和方向都是动态变化的,大小随着举例目标点越近而变小,方向小于目标点是加速度为正,大于目标点时加速度为负
iSpeed = iSpeed + a;
iSpeed *= u;
if (Math.abs(iSpeed) < 1 && Math.abs(target - dom.offsetLeft) < 1) {
clearInterval(dom.timer);
dom.style.left = target;
} else {
dom.style.left = dom.offsetLeft + iSpeed + 'px';
}
}, 30)
}
</script>
</body>
</html>
弹性运动的案例实现
案列描述:实现一个导航栏,使得可以在鼠标移入的时候实现弹性运动的效果。
展示效果
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>弹性运动的案例实现</title>
<style>
* {
margin: 0;
padding: 0;
list-style: none;
}
ul {
width: 800px;
height: 100px;
position: relative;
margin: 100px auto;
}
ul .element {
width: 198px;
height: 98px;
line-height: 98px;
text-align: center;
float: left;
border: 1px solid black;
background-color: orange;
}
ul .special {
width: 200px;
height: 100px;
background-color: deeppink;
/* 设置绝对定位来游离于ul下面的li之间 */
position: absolute;
left: 0;
top: 0;
/* 设置透明度使得变成绝对定位之后的special不会遮盖住文字,并且可以巧妙实现hover效果(通过颜色的混合) */
opacity: 0.4;
}
</style>
</head>
<body>
<ul>
<li class="element">HTML</li>
<li class="element">CSS</li>
<li class="element">JAVASCRIPT</li>
<li class="element">ECMASCRIPT6</li>
<li class="special"></li>
<script>
var oLiArray = document.getElementsByClassName('element');
var special = document.getElementsByClassName('special')[0];
for(var i = 0;i<oLiArray.length;i++){
oLiArray[i].onmouseenter = function(){
console.log(1);
startMove(special,this.offsetLeft);
}
}
function startMove(dom, target) {
clearInterval(dom.timer);
// 赋初值
var iSpeed = 0; //初速度
var a = 3;
var u = 0.8; //摩擦力
// 通过定时器来改变dom的运动状况
dom.timer = setInterval(function () {
a = (target - dom.offsetLeft) /
5; //加速度,大小和方向都是动态变化的,大小随着举例目标点越近而变小,方向小于目标点是加速度为正,大于目标点时加速度为负
iSpeed = iSpeed + a;
iSpeed *= u;
if (Math.abs(iSpeed) < 1 && Math.abs(target - dom.offsetLeft) < 1) {
clearInterval(dom.timer);
dom.style.left = target;
} else {
dom.style.left = dom.offsetLeft + iSpeed + 'px';
}
}, 30)
}
</script>
</ul>
</body>
</html>