如果有的话,我很乐意带一个图书馆吗?或者对我的psuedocode api的任何其他建议。
如何编写一个带有4个参数interpolate(start, end, time, ease)
的函数,并在一段时间内轻松插入开始到结束的数字?
问题:
这感觉特别难,因为我不知道如何在请求动画帧中控制时间或轻松。其次,我不知道如何编写贝塞尔曲线处理程序。最后,如果需要进行优化。
interpolate(start:number, end:number, time:number, ease) {
// easing
return value;
}
function _draw() {
currentValue = interpolate(0, 10, 0.7, 'cubic-bezier(.62,.28,.23,.99)');
if(currentValue !== lastValue) {
console.log(currentValue)
}
requestAnimationFrame(_draw);
}
所以最后currentValue会在它的最终刻度中记录10。
答案 0 :(得分:2)
我建议使用Penner Equations进行通用缓和。这些函数可以在github上找到库: tween-functions
一个简单的演示,展示如何在每个帧上计算值:
const Easings = [
function easeInQuad(t, b, c, d) {
return c * (t /= d) * t + b;
},
function easeOutBounce(t, b, c, d) {
if ((t /= d) < (1 / 2.75)) {
return c * (7.5625 * t * t) + b;
} else if (t < (2 / 2.75)) {
return c * (7.5625 * (t -= (1.5 / 2.75)) * t + 0.75) + b;
} else if (t < (2.5 / 2.75)) {
return c * (7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375) + b;
} else {
return c * (7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375) + b;
}
},
function easeInOutElastic(t, b, c, d) {
// jshint eqeqeq: false, -W041: true
var s = 1.70158;
var p = 0;
var a = c;
if (t == 0) return b;
if ((t /= d / 2) == 2) return b + c;
if (!p) p = d * (0.3 * 1.5);
if (a < Math.abs(c)) {
a = c;
s = p / 4;
} else s = p / (2 * Math.PI) * Math.asin(c / a);
if (t < 1) return -0.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b;
return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p) * 0.5 + c + b;
},
];
const duration = 2000;
const div = document.querySelector('div');
let start = Date.now();
let from = 0;
let to = 300;
let fnCounter = 0;
let fn = Easings[fnCounter];
function tick() {
let now = Date.now();
let elapsed = now - start;
let val = fn(elapsed, from, to - from, duration);
div.style.transform = `translateX(${val}px)`;
if (elapsed >= duration) {
start = now;
let x = from;
from = to;
to = x;
fn = Easings[++fnCounter % Easings.length]
setTimeout(tick, 300);
return;
}
requestAnimationFrame(tick);
}
requestAnimationFrame(tick);
&#13;
div {
position: absolute;
top: 0px;
left: 0;
width: 100px;
height: 100px;
background: orange;
}
&#13;
<div></div>
&#13;
对于自定义贝塞尔曲线,我建议使用此库:bezier-easing。这里的计算是相同的:在每个刻度线上,您可以获得经过的时间并计算持续时间的百分比,现在每个帧上都有0
到1
的刻度值。