基础代码
代码实现的功能,点击小方块,可使其减速移动到指定位置,到达指定位置时,速度为0,代码效果
html代码
<div id="demo"></div>
<button>run</button>
<span></span>
css代码
div {
width: 100px;
height: 100px;
position: absolute;
left: 0;
top: 0;
background-color: cadetblue;
}
button {
position: absolute;
top: 200px;
}
span {
width: 1px;
height: 100px;
position: absolute;
left: 300px;
top: 0;
background-color: black;
}
js代码
var oDiv = document.getElementById('demo');
var oBtn = document.getElementsByTagName('button')[0];
oBtn.onclick = function() {
startMove(oDiv, 300);
}
function startMove(dom, target) {
clearInterval(timer);
var speed = null;
var timer = setInterval (function () {
speed = (target - oDiv.offsetLeft)/13;
speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
if (dom.offsetLeft == target) {
clearInterval(timer);
} else {
dom.style.left = dom.offsetLeft + speed +'px';
console.log(dom.style.left);
}
},30)
}
变量说明:target——指定位置的像素点
speed——小方块一次移动的像素大小
timer——定时器的唯一标识
问题1:怎样使小方块越靠近指定位置速度越低
解决:在靠近指定位置的过程中,二者距离减小,则可将速度与二者的距离联系起来。因为在初始过程中,二者距离过大,如果直接将这个值作为速度,则会使小方块瞬间移动到指定位置,因此可将距离除以某个大于1的常数作为其移动速度。
问题2:当小方块非常接近指定位置时,其速度小于1时,不足以让像素发生变化(像素只能是整数)
解决:此时采取向上取整或向下取整的方法,这样可使小方块移动到指定位置。
问题3:三目运算符的作用
解决:因为小方块可以在指定位置的左右两边,这两种情况对速度的处理是不同的,当小方块的左边线在指定位置的左边时,其速度为正,此时为了解决问题2,需要使速度向上取整;当小方块的左边线在指定位置的右边时,其速度为负,此时为解决问题2,速度需要向下取整,使其绝对值增大
问题4:startMove函数中第一个定时器的作用
解决:为了防止多次触发点击事件造成多个定时器累加
【ps】写博客的时候还遇到了之前没有注意到的问题,之前虽然小方块也停在了指定位置(速度为零了),但是因为判定条件错误,导致定时器未被清除,错误原因是将dom.style.left==target作为判定条件,dom.offsetLeft是数字,而dom.style.left是字符串,不能等于target,因此不会走清理定时器的语句。
利用缓冲运动做悬浮窗
实现功能:鼠标移入,悬浮窗移出,鼠标移出,悬浮窗缩进,代码效果
html代码
<div id="demo">
<span></span>
</div>
css代码
div {
width: 400px;
height: 50px;
position: absolute;
top: 200px;
left: -400px;
background-color: cadetblue;
}
span {
width: 50px;
height: 50px;
background-color: darkseagreen;
position: absolute;
top: 0;
right: -50px;
}
js代码
var oDiv = document.getElementById('demo');
oDiv.onmouseenter = function () {
startMove(this, 0);
}
oDiv.onmouseleave = function () {
startMove(this, -400);
}
function startMove(dom, target) {
clearInterval(dom.timer); //清理上个事件中走了else程序的定时器
var speed = null;
dom.timer = setInterval (function () {
speed = (target - oDiv.offsetLeft)/13;
speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
if (dom.offsetLeft == target) {
clearInterval(dom.timer);
} else {
dom.style.left = dom.offsetLeft + speed +'px';
console.log(dom.style.left);
}
},30)
}
该例完全是对缓冲运动的一个应用,没有新的注意点
透明度的缓冲
代码效果
html代码
<div id="demo"></div>
css代码
div {
width: 100px;
height: 100px;
background-color: cadetblue;
opacity: 1;
cursor: pointer;
}
js代码
var oDiv = document.getElementById('demo');
var timer;
oDiv.onclick = function () {
startMove(oDiv, 50);
}
//封装getStyle函数
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 speed = null,
iCur = null;
timer = setInterval (function () {
iCur = parseFloat(getStyle(dom, 'opacity')) * 100;
speed = (target - iCur) / 13;
speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
if (iCur == target) {
clearInterval(timer);
} else {
dom.style.opacity = (iCur + speed) / 100;
console.log(dom.style.opacity);
}
},30)
}
问题:透明度是的值在[0,1],且其变化是小数位,这样取整的过程不合理
解决:将参数先扩大100倍进行运算,在赋值给dom.style.opacity时再缩100倍