缓动函数与动画
搬运https://www.zybuluo.com/dengzhirong/note/184284
缓动函数, 主要用在控制动画上, 它是一个区间函数
用它来做动画, 实际上就是将这个函数离散化
比如在x轴上取100个点, 计算得到f(x)值 就是得到了这个动画在这100步的变化过程
缓动函数需要四个参数
b 函数开始值
c 函数结束值
d 结束时间(实际上这里并不是真正意义上的时间, 而是离散时的取样)
t 一般为0 也就是从开始值开始变化
例如我将d值设置为100 就是讲这个连续的函数离散为100个点 根据t值(x轴位置)的不同得到不同的结果( f(x)的值 )
两个简单的例子
function timeoutMove() {
var pos = 0;
var t1 = +new Date;
var b = 50, //开始值
c = 100, //结束值
d = 100, //运算次数 虽然很多文章这里说时间 但这不是时间 不过这个值决定了执行时间 约1677ms
t = 0;
function run() {
//t =0时 运算结果是 b值
//t =d时 运算结果是d值
pos = Math.ceil(Tween.Quad.easeOut(t, b, c - b, d));
cube.style.top = pos + 'px';
console.log('t= ',t,'pos=',pos);
t++;
timer = setTimeout(run, 1000 / 60);
if (t >= d) {
clearTimeout(timer);
console.log(+new Date - t1);
}
}
run();
}
再来一个RAF的例子
function raqMove() {
var move = 0,
t = 0,
end = 50,
t1 = +new Date;
function run() {
move = Tween.Sine.easeInOut(t, 0, 500, end)
cube.style.left = move + 'px';
console.log('t= ',t,'move=',move);
t++;
//因为是使用的RAF 不能精确的得到执行结束时间
//大约执行结束时间是 50*16.7 = 835ms 肯定会比这个时间长
//16.7 是根据一秒60桢来计算的
if (t <= end) {
requestAnimationFrame(run)
} else {
console.log(+new Date - t1)
}
}
run();
}
如何将缓动函数真正的用在动画中呢
来看个缓动函数大集合
https://github.com/tweenjs/tween.js/blob/master/src/Tween.js
接下来和动画集合一下
util = {
animate: function(ele, style, time, animate) {
time = time || 432;
animate = animate || 'Linear';
var t1 = +new Date;
var begins = [], ends= [];
for (key in style) {
if(key == 'opacity'){
begins[key] = parseFloat(window.getComputedStyle(ele)[key])
console.log(begins[key]);
}else{
begins[key] = parseInt(window.getComputedStyle(ele)[key]);
}
}
var d = Math.ceil(time / (1000/60)), //计算次数
t = 0;
var b = 1, c = 0.1
function run() {
for (key in style) {
if(key == 'opacity'){
ele.style[key] = Tween[animate](t, begins[key], style[key]- b, d);
}else{
ele.style[key] = Tween[animate](t, begins[key], style[key]- begins[key], d) + 'px';
}
}
t++;
if (t <= d) {
requestAnimationFrame(run);
}else{
console.log(+new Date - t1);
}
}
run();
}
}
这样调用就可以
util.animate(cube, {
top: 500,
left:100,
opacity: 0.1
}, 1000, 'easeInOut');