1 参考
常见的动画都是速率相同的平滑效果,而有些动画在变动过程中速率不同,比如有些网站的返回顶部的动画效果会经过慢-快-慢的效果,这就设计到数学模型了,有一片参考文章:http://blog.csdn.net/jebe7282/article/details/7521067。这里讲解了tween算法代码。可以将里面的代码拷贝下来,可以直观的看到速度的曲率变化
2 简化
变换一下算法:http://greweb.me/2012/02/bezier-curve-based-easing-functions-from-concept-to-implementation/
EasingFunctions = {
linear: function (t) { return t },
easeInQuad: function (t) { return t*t },
easeOutQuad: function (t) { return t*(2-t) },
easeInOutQuad: function (t) { return t<.5 ? 2*t*t : -1+(4-2*t)*t },
easeInCubic: function (t) { return t*t*t },
easeOutCubic: function (t) { return (--t)*t*t+1 },
easeInOutCubic: function (t) { return t<.5 ? 4*t*t*t : (t-1)*(2*t-2)*(2*t-2)+1 },
easeInQuart: function (t) { return t*t*t*t },
easeOutQuart: function (t) { return 1-(--t)*t*t*t },
easeInOutQuart: function (t) { return t<.5 ? 8*t*t*t*t : 1-8*(--t)*t*t*t },
easeInQuint: function (t) { return t*t*t*t*t },
easeOutQuint: function (t) { return 1+(--t)*t*t*t*t },
easeInOutQuint: function (t) { return t<.5 ? 16*t*t*t*t*t : 1+16*(--t)*t*t*t*t }
}
这里只需要一个参数t:已用时间/总时间。
下面实现:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style lang="css">
#test1 {
background-color: aliceblue;
}
#test2 {
background-color: aqua;
}
#test3 {
background-color: aquamarine;
}
#test4 {
background-color: cadetblue;
}
#test5 {
background-color: aliceblue;
}
#test6 {
background-color: aqua;
}
#test7 {
background-color: aquamarine;
}
#test8 {
background-color: cadetblue;
}
.box {
width: 100%;
height: 500px;
}
#backtop {
position: fixed;
right: 20px;
bottom: 20px;
}
</style>
</head>
<body>
<div id="test1" class="box"></div>
<div id="test2" class="box"></div>
<div id="test3" class="box"></div>
<div id="test4" class="box"></div>
<div id="test5" class="box"></div>
<div id="test6" class="box"></div>
<div id="test7" class="box"></div>
<div id="test8" class="box"></div>
<button id="backtop">顶部</button>
<script>
var requestAnimationFrame = window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.msRquestAnimationFrame || function (fn) {
setTimeout(fn, 15);
}
EasingFunctions = {
linear: function (t) {
return t
},
easeInQuad: function (t) {
return t * t
},
easeOutQuad: function (t) {
return t * (2 - t)
},
easeInOutQuad: function (t) {
return t < .5 ? 2 * t * t : -1 + (4 - 2 * t) * t
},
easeInCubic: function (t) {
return t * t * t
},
easeOutCubic: function (t) {
return (--t) * t * t + 1
},
easeInOutCubic: function (t) {
return t < .5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1
},
easeInQuart: function (t) {
return t * t * t * t
},
easeOutQuart: function (t) {
return 1 - (--t) * t * t * t
},
easeInOutQuart: function (t) {
return t < .5 ? 8 * t * t * t * t : 1 - 8 * (--t) * t * t * t
},
easeInQuint: function (t) {
return t * t * t * t * t
},
easeOutQuint: function (t) {
return 1 + (--t) * t * t * t * t
},
easeInOutQuint: function (t) {
return t < .5 ? 16 * t * t * t * t * t : 1 + 16 * (--t) * t * t * t * t
}
}
var position = function (start, end, elapsed, duration) {
if (elapsed > duration) {
return end;
};
return start + (end - start) * this.EasingFunctions.easeInOutQuint(elapsed / duration);
}
var smoothScroll = function (el) {
var el = document.getElementById('test1');
var duration = 1000;
var clock = Date.now();
var scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop -
el.offsetTop;
var start = scrollTop;
var end = 0;
var _selt = this;
var step = function () {
console.log(1);
var elapsed = Date.now() - clock;
var position = _selt.position(start, end, elapsed, duration);
window.scrollTo(0, position);
if (elapsed > duration) {} else {
requestAnimationFrame(step);
}
}
requestAnimationFrame(step);
};
document.getElementById('backtop').onclick = function () {
var el = document.getElementById('test1')
smoothScroll(el)
};
</script>
</body>
</html>