匀速/缓冲
匀速运动
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.move{
width: 100px;
height: 100px;
position: absolute;
background: red;
}
</style>
</head>
<body>
<div class="move"></div>
<script>
var div = document.getElementsByClassName('move')[0];
// 匀速运动
function move (dom,target){
var time = null;
clearInterval(time);
var iSpeed = target - dom.offsetLeft > 0 ? 7 : -7;
time = setInterval(() => {
if(Math.abs(target - dom.offsetLeft) < Math.abs(iSpeed)){
clearInterval(time)
dom.style.left = target + 'px';
}else{
dom.style.left = dom.offsetLeft + iSpeed + 'px'
}
}, 30);
}
move(div,500)
</script>
</body>
缓冲运动
// 物体的速度,距离目标点越近,就越小,当到达目标点时,速度减小为0
// 缓冲运动的原理:速度由距离决定,速度=(目标值-当前值)/缩放比例
function startMove (dom ,target){
var timer = null,iSpeed = null;
clearInterval(timer);
timer = setInterval(() => {
iSpeed = (target - dom.offsetLeft) / 7;
iSpeed = iSpeed > 0 ? Math.ceil(iSpeed) : Math.floor(iSpeed); //ceil 向上一位取整
if(dom.offsetLeft == target){
clearInterval(timer);
}else{
dom.style.left = dom.offsetLeft + iSpeed + 'px';
}
}, (30));
}
透明度
var div = document.getElementsByClassName('move')[0];
var timer = null;
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) {
console.log(1)
clearInterval(timer);
}else {
// 0 - 1 iCur * 100 target * 100 iSpeed * 100 iCur + iSpeed 0 - 100 / 100
dom.style.opacity = (iCur + iSpeed) / 100;
}
}, 30)
}
div.onclick = function(){
startMove(this,50)
}
多物体不同值运动
function startMove(dom , attr, target){
var timer = null,iSpeed = null,iCur = null;
clearInterval(timer);
dom.timer = setInterval(function(){
if(attr == 'opacity'){
iCur = parseFloat(getStyle(dom,attr))*100
}else{
iCur = parseInt(getStyle(dom,attr))
}
iSpeed = (target - iCur) /7 ;
iSpeed = iSpeed > 0 ? Math.ceil(iSpeed) : Math.floor(iSpeed);
if(iCur == target){
clearInterval(dom.timer);
}
if(attr == 'opacity'){
dom.style.opacity = (iSpeed+iCur)/100;
}else{
dom.style[attr]=iCur+iSpeed +'px'
}
})
}
function getStyle(dom,attr){
if(window.getComputedStyle){
return window.getComputedStyle(dom,null)[attr];
}else{
return dom.currentStyle[attr];
}
}
div[0].onclick = function(){
startMove(div[0],'width',500)
};
div[1].onclick = function(){
startMove(div[1],'height',500)
};
div[2].onclick = function(){
startMove(div[2],'opacity',50)
};
多物体多值运动+回调
<div id='topDiv'></div>
<div id="bottomDiv"></div>
<script>
// js div
// width -> 100 400 height 100 400 left 0 200 top 200 300 opacity 1 0.5
// {width: 400, height: 400, left: 200, top: 300, opacity: 50}
var oTopDiv = document.getElementById('topDiv');
var oBottomDiv = document.getElementById('bottomDiv');
oTopDiv.onclick = function () {
startMove(this, {width: 400, height: 400, left: 200, top: 300, opacity: 50}, function () {
startMove(oBottomDiv, {width: 400, height: 400, 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) {
// 'width' 'height'
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(); // 此处&& 当前面为true就会执行回调函数
}
}, 30);
}
</script>