JS运动学习笔记。冲鸭!!!!
1. 匀速运动
<style>
div {
width: 100px;
height: 100px;
background-color: orange;
position: absolute;
top: 0;
left: 500px;
}
button {
margin-top: 150px;
}
span {
position: absolute;
width: 1px;
height: 100px;
top: 0px;
background-color: black;
left: 300px;
}
</style>
... ...
<body>
<div></div>
<span></span>
<button id="btn">run</button>
<script>
var oDiv = document.getElementsByTagName('div')[0];
var oBtn = document.getElementById('btn');
var timer = null;
oBtn.onclick = function() {
startMove(oDiv, 300);
}
function startMove(dom, target) {
clearInterval(timer);
var iSpeed = target - dom.offsetLeft > 0 ? 7 : -7;
timer = setInterval(function() {
if (Math.abs(target - dom.offsetLeft) < Math.abs(iSpeed)) {
clearInterval(timer);
dom.style.left = target+ 'px';
} else {
dom.style.left = dom.offsetLeft + iSpeed + 'px';
}
}, 30);
}
</script>
</body>
2. 缓冲运动
物体的速度距离目标点越近,就越小;当到达目标点时,速度减小为0。
function startMove(dom, target) {
clearInterval(timer);
var iSpeed = null;
timer = setInterval(function() {
iSpeed = (target - oDiv.offsetLeft) / 7;
iSpeed = iSpeed > 0 ? Math.ceil(iSpeed) : Math.floor(iSpeed);
if (oDiv.offsetLeft == target) {
clearInterval(timer);
} else {
oDiv.style.left = oDiv.offsetLeft + iSpeed + 'px';
}
}, 30)
}
- 小练习 1
<body>
<div class="wrapper">
<span></span>
</div>
<script>
var timer = null;
var oDiv = document.getElementsByClassName('wrapper')[0];
oDiv.onmouseenter = function() {
startMove(this, 0);
}
oDiv.onmouseleave = function() {
startMove(this, -400);
}
function startMove(dom, target) {
clearInterval(timer);
var iSpeed = null;
timer = setInterval(function() {
iSpeed = (target - oDiv.offsetLeft) / 7;
iSpeed = iSpeed > 0 ? Math.ceil(iSpeed) : Math.floor(iSpeed);
if (oDiv.offsetLeft == target) {
clearInterval(timer);
} else {
oDiv.style.left = oDiv.offsetLeft + iSpeed + 'px';
}
}, 30)
}
</script>
</body>

- 小练习2:透明度缓冲变化
<style>
div {
width: 100px;
height: 100px;
background-color: orange;
opacity: 1;
}
</style>
... ...
<body>
<div></div>
<script>
var timer = null;
var oDiv = document.getElementsByTagName('div')[0];
oDiv.onclick = function() {
startMove(this, 50);
}
function getStyle (dom, attr) {
if (window.getComputedStyle) {
return window.getComputedStyle(dom, null)[attr];
} else {
return dom.currentStyle[attr];
}
}
function startMove(dom, target) {
clearInterval(timer);
var iSpeed = null, iCur = null;
timer = setInterval(function () {
iCur = parseFloat(getStyle(dom, 'opacity')) * 100;
iSpeed = (target - iCur) / 7;
iSpeed = iSpeed > 0 ? Math.ceil(iSpeed) : Math.floor(iSpeed);
if (iCur == target) {
clearInterval(timer);
} else {
oDiv.style.opacity = (iCur + iSpeed) / 100;
}
}, 30)
}
</script>
</body>

3. 多物体多值运动 + 回调机制
<style>
div {
width: 100px;
height: 100px;
opacity: 1;
position: absolute;
left: 0;
}
#topDiv {
top: 200px;
background-color: orange;
}
#bottomDiv {
top: 400px;
background-color: red;
}
</style>
... ...
<body>
<div id="topDiv"></div>
<div id="bottomDiv"></div>
<script>
var timer = null;
var oTopDiv = document.getElementById('topDiv');
var bottomDiv = document.getElementById('bottomDiv');
oTopDiv.onclick = function() {
startMove(this, {width: 300, height: 300, left: 200, top: 300, opacity: 50}, function () {
startMove(bottomDiv, {width: 300, height: 300, left: 200, top: 300, opacity: 50}, function() {
alert('over');
})
});
}
function getStyle (dom, attr) {
if (window.getComputedStyle) {
return window.getComputedStyle(dom, null)[attr];
} else {
return dom.currentStyle[attr];
}
}
function startMove (dom, attrObj, callback) {
clearInterval(dom.timer);
var iSpeed = null, iCur = null;
dom.timer = setInterval(function() {
var bStop = true;
for (var attr in attrObj) {
if (attr == 'opacity') {
iCur = parseFloat(getStyle(dom, attr) * 100);
} else {
iCur = parseInt(getStyle(dom, attr));
}
iSpeed = (attrObj[attr] - iCur) / 7;
iSpeed = iSpeed > 0 ? Math.ceil(iSpeed) : Math.floor(iSpeed);
if (attr == 'opacity') {
dom.style.opacity = (iCur + iSpeed) / 100;
} else {
dom.style[attr] = iCur + iSpeed + 'px';
}
if (iCur !== attrObj[attr]) {
bStop = false;
}
}
if (bStop) {
clearInterval(dom.timer);
typeof callback == 'function' && callback();
}
}, 30)
}
</script>
</body>

4. 加速运动
<style>
div {
position: absolute;
left: 0px;
top: 0px;
width: 100px;
height: 100px;
background: orange;
}
</style>
... ...
<body>
<div></div>
<script>
// v = v + at
var oDiv = document.getElementsByTagName('div')[0];
var timer = null;
oDiv.onclick = function() {
startMove(this);
}
// 加速度不变的加速运动
function startMove(dom) {
clearInterval(timer);
var a = 2;
var iSpeed = 20;
timer = setInterval(function() {
iSpeed = iSpeed + a;
oDiv.style.left = oDiv.offsetLeft + iSpeed + 'px';
}, 30);
}
</script>
</body>
5. 弹性运动
大概的理解一下弹性运动,这个图表示的是一根橡皮筋绑着一颗球球。蓝色柱子只是表示一下分界点。其中,距离分界点越近,作用力越小,加速度越小。
如图所示,第一阶段是av同向,所以是【加速度减小的加速运动】;第二阶段【加速度增大的减速运动】;第三阶段【加速度减小的加速运动】;第四阶段【加速度增大的减速运动】。

<style>
div {
position: absolute;
left: 0px;
top: 0px;
width: 100px;
height: 100px;
background: orange;
}
span {
position: absolute;
left: 300px;
top: 0px;
background: black;
width: 1px;
height: 100px;
}
</style>
... ...
<body>
<div></div>
<span></span>
<script>
var oDiv = document.getElementsByTagName('div')[0];
var timer = null;
oDiv.onclick = function() {
startMove(this, 300);
}
// 参数1:做弹性运动的元素; 参数二:分隔点
function startMove(dom, target) {
clearInterval(timer);
// a是加速度
var a = 3;
// iSpeed定义初始速度
var iSpeed = 0;
var u = 0.8;
timer = setInterval(function() {
a = (target - dom.offsetLeft) / 5;
iSpeed += a;
iSpeed *= 0.8;
// 绝对值小于1时,看成时速度为0
if (Math.abs(iSpeed) < 1 && Math.abs(target-dom.offsetLeft) < 1) {
clearInterval(timer);
dom.style.left = target + 'px';
} else {
dom.style.left = dom.offsetLeft + iSpeed + 'px';
}
}, 30);
}
</script>
</body>

- 用上面封装好的方法做个小demo
<style>
* {
margin: 0px;
padding: 0px;
list-style: none;
}
ul {
position: relative;
margin: 100px auto 0px;
width: 800px;
height: 100px;
}
ul .ele {
float: left;
width: 198px;
border: 1px solid black;
background-color: skyblue;
height: 98px;
line-height: 98px;
text-align: center;
}
.bg {
position: absolute;
left: 0px;
top: 0px;
width: 200px;
height: 100px;
opacity: 0.4;
background-color: orange;
}
</style>
<body>
<ul>
<li class="ele">a</li>
<li class="ele">b</li>
<li class="ele">c</li>
<li class="ele">d</li>
<li class="bg"></li>
</ul>
<script>
var timer = null;
var oLiArray = document.getElementsByTagName('li');
var oLiBg = oLiArray[oLiArray.length -1];
for (var i = 0; i < oLiArray.length - 1; i++) {
oLiArray[i].onmouseenter = function () {
startMove(oLiBg, this.offsetLeft)
}
}
// 参数1:做弹性运动的元素; 参数二:分隔点
function startMove(dom, target) {
clearInterval(timer);
// a是加速度
var a = 3;
// iSpeed定义初始速度
var iSpeed = 0;
var u = 0.8;
timer = setInterval(function() {
a = (target - dom.offsetLeft) / 5;
iSpeed += a;
iSpeed *= 0.8;
// 绝对值小于1时,看成时速度为0
if (Math.abs(iSpeed) < 1 && Math.abs(target-dom.offsetLeft) < 1) {
clearInterval(timer);
dom.style.left = target + 'px';
} else {
dom.style.left = dom.offsetLeft + iSpeed + 'px';
}
}, 30);
}
</script>
</body>
... ...
<body>
<ul>
<li class="ele">a</li>
<li class="ele">b</li>
<li class="ele">c</li>
<li class="ele">d</li>
<li class="bg"></li>
</ul>
<script>
var timer = null;
var oLiArray = document.getElementsByTagName('li');
var oLiBg = oLiArray[oLiArray.length -1];
for (var i = 0; i < oLiArray.length - 1; i++) {
oLiArray[i].onmouseenter = function () {
startMove(oLiBg, this.offsetLeft)
}
}
// 参数1:做弹性运动的元素; 参数二:分隔点
function startMove(dom, target) {
clearInterval(timer);
// a是加速度
var a = 3;
// iSpeed定义初始速度
var iSpeed = 0;
var u = 0.8;
timer = setInterval(function() {
a = (target - dom.offsetLeft) / 5;
iSpeed += a;
iSpeed *= 0.8;
// 绝对值小于1时,看成时速度为0
if (Math.abs(iSpeed) < 1 && Math.abs(target-dom.offsetLeft) < 1) {
clearInterval(timer);
dom.style.left = target + 'px';
} else {
dom.style.left = dom.offsetLeft + iSpeed + 'px';
}
}, 30);
}
</script>
</body>

6. 模拟重力场
多方向运动 + 碰撞检测 + 重力加速度 + 能量损失
<style>
* {
margin: 0px;
padding: 0px;
}
div {
position: absolute;
left: 0px;
top: 0px;
background-color: pink;
width: 100px;
height: 100px;
border-radius: 50%;
}
</style>
... ...
<body>
<div id="demo"></div>
<script>
var timer = null;
var oDiv = document.getElementById('demo');
oDiv.onclick = function () {
startMove(this);
}
function startMove(dom) {
clearInterval(dom.timer);
var iSpeedX = 6;
var iSpeedY = 8;
// 重力加速度
var g = 3;
dom.timer = setInterval(function () {
iSpeedY += g;
var newTop = dom.offsetTop + iSpeedY;
var newLeft = dom.offsetLeft + iSpeedX;
if (newTop >= document.documentElement.clientHeight - dom.clientHeight) {
iSpeedY *= -1;
iSpeedY *= 0.8;
iSpeedX *= 0.8;
newTop = document.documentElement.clientHeight - dom.clientHeight;
}
if (newTop <= 0) {
iSpeedY *= -1;
iSpeedY *= 0.8;
iSpeedX *= 0.8;
newTop = 0;
}
if (newLeft >= document.documentElement.clientWidth - dom.clientWidth) {
iSpeedX *= -1;
iSpeedY *= 0.8;
iSpeedX *= 0.8;
newLeft = document.documentElement.clientWidth - dom.clientWidth;
}
if (newLeft <= 0) {
iSpeedX *= -1;
iSpeedY *= 0.8;
iSpeedX *= 0.8;
newLeft = 0;
}
//console.log(iSpeedX, iSpeedY);
if (Math.abs(iSpeedX) < 1) {
iSpeedX = 0;
}
if (Math.abs(iSpeedY) < 1) {
iSpeedY = 0;
}
if (iSpeedX == 0 && iSpeedY == 0 && newTop == document.documentElement.clientHeight - dom.clientWidth) {
clearInterval(dom.timer);
console.log('over');
} else {
dom.style.top = newTop + 'px';
dom.style.left = newLeft + 'px';
}
}, 30);
}
</script>
</body>

7. 拖拽
<style>
div {
position: absolute;
left: 0px;
top: 0px;
background-color: pink;
width: 100px;
height: 100px;
border-radius: 50%;
}
</style>
... ...
<body>
<div id="demo"></div>
<script>
var timer = null;
var oDiv = document.getElementById('demo');
var lastX = 0;
var lastY = 0;
var iSpeedX = 0;
var iSpeedY = 0;
oDiv.onmousedown = function (e) {
var event = event || e;
var disX = event.clientX - this.offsetLeft;
var disY = event.clientY - this.offsetTop;
var self = this;
document.onmousemove = function (e) {
clearInterval(this.timer);
var event = event || e;
var newLeft = event.clientX - disX;
var newTop = event.clientY - disY;
iSpeedX = newLeft - lastX;
iSpeedY = newTop - lastY;
lastX = newLeft;
lastY = newTop;
// 运动的轨迹
// var oSpan = document.createElement('span');
// oSpan.style.position = 'absolute';
// oSpan.style.left = newLeft + 'px';
// oSpan.style.top = newTop + 'px';
// oSpan.style.width = '5px';
// oSpan.style.height = '5px';
// oSpan.style.backgroundColor = 'orange';
// document.body.appendChild(oSpan);
self.style.left = newLeft + 'px';
self.style.top = newTop + 'px';
}
document.onmouseup = function () {
document.onmouseup = null;
document.onmousemove = null;
startMove(self, iSpeedX, iSpeedY);
}
}
function startMove(dom, iSpeedX, iSpeedY) {
clearInterval(dom.timer);
var g = 3;
dom.timer = setInterval(function () {
iSpeedY += g;
var newTop = dom.offsetTop + iSpeedY;
var newLeft = dom.offsetLeft + iSpeedX;
if (newTop >= document.documentElement.clientHeight - dom.clientHeight) {
iSpeedY *= -1;
iSpeedY *= 0.8;
iSpeedX *= 0.8;
newTop = document.documentElement.clientHeight - dom.clientHeight;
}
if (newTop <= 0) {
iSpeedY *= -1;
iSpeedY *= 0.8;
iSpeedX *= 0.8;
newTop = 0;
}
if (newLeft >= document.documentElement.clientWidth - dom.clientWidth) {
iSpeedX *= -1;
iSpeedY *= 0.8;
iSpeedX *= 0.8;
newLeft = document.documentElement.clientWidth - dom.clientWidth;
}
if (newLeft <= 0) {
iSpeedX *= -1;
iSpeedY *= 0.8;
iSpeedX *= 0.8;
newLeft = 0;
}
if (Math.abs(iSpeedX) < 1) {
iSpeedX = 0;
}
if (Math.abs(iSpeedY) < 1) {
iSpeedY = 0;
}
if (iSpeedX == 0 && iSpeedY == 0 && newTop == document.documentElement.clientHeight - dom.clientWidth) {
clearInterval(dom.timer);
console.log('over');
} else {
dom.style.top = newTop + 'px';
dom.style.left = newLeft + 'px';
}
}, 30);
}
</script>
</body>

网友评论