1. Objects uniform motion
let div = document.getElementsByTagName('div')[0],
btns = document.getElementsByTagName('button')
btns[0].onclick = function() {
console.log(div)
startMove(div, 300)
}
// 使用dom.offsetLeft dom必须是定位的
let timer = null
function startMove(dom, dis) {
let speed = dom.offsetLeft < dis ? 7 : -7
clearInterval(timer)
timer = setInterval(() => {
if (Math.abs(dis - div.offsetLeft) < Math.abs(speed)) {
dom.style.left = dis + 'px'
clearInterval(timer)
} else {
dom.style.left = dom.offsetLeft + speed + 'px'
}
}, 30)
}
2. Buffer moving
the slower the closer the distance of the object when the target point speed to zero speed reaches the target point
let div = document.getElementsByTagName('div')[0],
btns = document.getElementsByTagName('button')
btns[0].onclick = function() {
buffMove(div, 300)
}
let timer = null
function buffMove(dom, dis) {
clearInterval(timer)
let speed = null
timer = setInterval(() => {
speed = (dis - dom.offsetLeft) / 20
speed = speed < 0 ? Math.floor(speed) : Math.ceil(speed)
if (dis == dom.offsetLeft) {
dom.style.left = dis + 'px'
clearInterval(timer)
} else {
dom.style.left = dom.offsetLeft + speed + 'px'
}
}, 30)
}
3. Multi-moving objects
let divArray = [].slice.call(document.getElementsByTagName('div'), 0)
//绑定事件
divArray.forEach(el => {
el.onmouseenter = function() {
run(this, 400)
}
el.onmouseleave = function() {
run(this, 100)
}
})
//获取样式
function getStyle(dom, atr) {
if (window.getComputedStyle) {
return window.getComputedStyle(dom, null)[atr]
} else {
return dom.currentStyle[atr]
}
}
//运动函数
function run(deom, dis) {
let speed = null
clearInterval(deom.timer)
deom.timer = setInterval(() => {
let width = parseInt(getStyle(deom, 'width'))
speed = (dis - width) / 7
speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed)
if (dis == width) {
clearInterval(deom.timer)
} else {
deom.style.width = width + speed + 'px'
}
}, 30)
}
4. A multi-object motion different properties
let divArray = [].slice.call(document.getElementsByTagName('div'), 0)
divArray[0].onclick = function() {
startMove(this, 'width', 300)
}
divArray[1].onclick = function() {
startMove(this, 'borderWidth', 20)
}
divArray[2].onclick = function() {
startMove(this, 'opacity', 50)
}
function getStyle(dom, attr) {
if (window.getComputedStyle) {
return window.getComputedStyle(dom, null)[attr]
} else {
return dom.currentStyle[attr]
}
}
function startMove(dom, atr, target) {
clearInterval(dom.timer)
let speed = null,
curAtr = null
dom.timer = setInterval(() => {
if (atr == 'opactiy') {
curAtr = parseFloat(getStyle(dom, atr)) * 100
} else {
curAtr = parseInt(getStyle(dom, atr))
}
speed = (target - curAtr) / 7
speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed)
if (target == curAtr) {
clearInterval(dom.timer)
}
if (atr == 'opacity') {
dom.style.opacity = (curAtr + speed) / 100
} else {
dom.style[atr] = curAtr + speed + 'px'
}
}, 30)
}
The multi-object while moving a plurality of attributes
let divArray = document.getElementsByTagName('div')
divArray[0].onclick = function() {
startMove(
this,
{ width: 400, height: 400, left: 400, top: 400, opacity: 50 },
() => {
startMove(
divBottom,
{ width: 400, height: 400, left: 400, top: 400 },
() => {
alert('over')
}
)
}
)
}
function getStyle(demo, attr) {
if (window.getComputedStyle) {
return window.getComputedStyle(demo, null)[attr]
} else {
return demo.currentStyle[attr]
}
}
function startMove(demo, attrObj, callback) {
clearInterval(demo.timer)
let speed = null,
curAtr = null
demo.timer = setInterval(() => {
let bStop = true
for (let attr in attrObj) {
if (attr == 'opacity') {
curAtr = parseFloat(getStyle(demo, attr)) * 100
} else {
curAtr = parseInt(getStyle(demo, attr))
}
speed = (attrObj[attr] - curAtr) / 7
speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed)
if (attr == 'opacity') {
demo.style.opacity = (curAtr + speed) / 100
} else {
demo.style[attr] = curAtr + speed + 'px'
}
if (curAtr != attrObj[attr]) bStop = false
}
if (bStop) {
clearInterval(demo.timer)
typeof callback && callback()
}
}, 30)
}
6. The elastic movement
Note: The object of this movement margin value can not be set, otherwise there will be deviation calculating a motion value acquiring dom.offsetLeft
divTop.onclick = function() {
startMove(this, 300)
}
function startMove(dom, target) {
clearInterval(dom.timer)
let speed = 0,
a = 0
dom.timer = setInterval(() => {
a = (target - dom.offsetLeft) / 5
speed = (speed + a) * 0.8
if (Math.abs(speed) < 1 && Math.abs(target - dom.offsetLeft) < 1) {
clearInterval(dom.timer)
dom.style.left = target + 'px'
} else {
dom.style.left = dom.offsetLeft + speed + 'px'
}
}, 30)
}
7. gravitational field motion
multidirectional movement gravitational + + + Collision detection capability wear
let dem = document.getElementsByClassName('demo')[0]
dem.onclick = function() {
startMove(this)
}
function startMove(demo) {
clearInterval(demo.timer)
let iSpeedX = 6,
iSpeedY = 8,
g = 6
demo.timer = setInterval(() => {
iSpeedY += g // 重力影响 y轴方向的速度
let newTop = demo.offsetTop + iSpeedY,
newLeft = demo.offsetLeft + iSpeedX
// demo运动 触碰到墙壁会向相反的方向运动
//垂直方向
if (
newTop >=
document.documentElement.clientHeight - demo.clientHeight
) {
iSpeedY *= -1
iSpeedY *= 0.8
iSpeedX *= 0.8
newTop = document.documentElement.clientHeight - demo.clientHeight
}
if (newTop <= 0) {
iSpeedY *= -1
iSpeedY *= 0.8
iSpeedX *= 0.8
newTop = 0
}
//水平方向
if (
newLeft >=
document.documentElement.clientWidth - demo.clientWidth
) {
iSpeedX *= -1
iSpeedY *= 0.8
iSpeedX *= 0.8
newLeft = document.documentElement.clientWidth - demo.clientWidth
}
if (newLeft <= 0) {
iSpeedX *= -1
iSpeedY *= 0.8
iSpeedX *= 0.8
newLeft = 0
}
//当物体运动到底部且xy轴方向的速度都为0 的时候停止运动 清除定时器
if (Math.abs(iSpeedX) < 1) {
iSpeedX = 0
}
// if (Math.abs(iSpeedY) < 1) { //设置动力加速度g=6 的时候,Math.abs(ISpeedY)在2.6左右,不小于1,所以定时器一直清除不掉
// iSpeedY = 0 设置加速g=3 ,满足这个条件
//}
if (Math.abs(iSpeedY) / g < 1) {
iSpeedY = 0
}
if (
iSpeedX == 0 &&
iSpeedY == 0 &&
newTop == document.documentElement.clientHeight - demo.clientHeight
) {
clearInterval(demo.timer)
} else {
demo.style.top = newTop + 'px'
demo.style.left = newLeft + 'px'
}
}, 30)
}