根据您的描述,在任何给定的帧中都有 6 个状态:
- 当前 lerp 的开始时间
- 勒普时间跨度
- 当前方向
- 当前时间
- 起始值
- 终值
从这些您可以计算所需的进度值,例如:
function progressValue(startTime, lerpSpanSeconds, dir,
currentTime X, Y, dir, currentTime) {
// lerp
return 0.42;
}
对于 requestAnimationFrame,您需要一个简单的回调来传入. 也就是说,函数必须知道它所需要的一切,除了它在运行时可以获得的东西。在这里,当它运行时,它只需要获取当前时间并从那里处理其余部分。
function animableThing() {
var startTime = 7;
var lerpSpanSeconds = 3;
var dir = +1;
var X = 0;
var Y = 1;
var currentTime = GetCurrentUnicornTime();
var thingToAnimate = document.getElementById('myAnimableElement');
var progress = progressValue(startTime, lerpSpanSeconds, dir,
currentTime, X, Y, dir, currentTime);
// reverse when we hit the end
if(progress > Y) {
dir *= -1;
startTime = currentTime;
progress = Y;
}
DrawAnimationThing(thingToAnimate, progress);
// continue the animation
window.requestAnimationFrame(animableThing);
}
但是有一个问题;如果您希望能够使用来自脚本的值或来自屏幕的输入或有关屏幕上元素的最新信息来设置动画,那么您需要能够animableThing
在有新的价值观。看,妈妈:
function MotherOfAnimableThings(startTime, lerpSpanSeconds, dir, X, Y,
thingToAnimate)
{
// Passed in variables have scope outside the animableThing, these
// will be private to the animableThing function.
// Consider defaulting or validation here
// Construct a new function freshly each time the Mother is called,
// and return it to the caller. Note that we assign a variable here
// so that we can re-call RequestAnimationFrame to continue the loop
var callback = (function() {
var currentTime = GetCurrentUnicornTime();
var progress = progressValue(startTime, lerpSpanSeconds, dir,
currentTime, X, Y, dir, currentTime);
// reverse when we hit the end
if(progress > Y) {
dir *= -1;
startTime = currentTime;
progress = Y;
}
DrawAnimationThing(thingToAnimate, progress);
window.requestAnimationFrame(callback);
});
return callback;
}
我们可以走得更远,通过让调用者传入一个progressValue函数来调用,或者实际上是一个回调,从而使其他类型的事物通用化,这样您就可以获取任何元素、Draw函数和setup函数并制作一个动画,但这是一个合理的起点。
有了上面,我们只需要调用 Mother 来创建一个animableThing
函数并用它调用 RequestAnimationFrame。从那时起,它在内部调用 RequestAnimationFrame 以继续循环。
现在,已经完成了,你会想要让它停止,所以在回调中添加一个它可以检查的变量,这样你就可以做到
var animableThing = MotherOfAnimableThings(...);
window.requestAnimationFrame(animableThing);
// ... later
animableThing.stop = true; // it should stop on the next frame