使用setInterval或RequestAnimationFrame,我想从X和Y之间获取进展值。 假设X为0且Y为1,我希望在启动时为0,在一半中为0.5,在完成时为1。 我希望在给定的时间范围内发生这种情况,让我们说5秒钟。意味着半值0.5会发生 setInterval / RequestAnimationFrame达到2.5秒。 最后,我喜欢pingPong,所以当它达到5秒时,值正在减少而不是增加,例如 如0.9,0.8,0.7等,然后从0,0.1,0.2 ......再次开始
任何提示或建议?
谢谢!
答案 0 :(得分:5)
线性插值的基本公式类似于
InterpolatedValue = X*t + Y*(1-t)
其中X
和Y
是要插入的值,t
是确定插值程度的0
和1
之间的参数; 0
产生X
,1
产生Y
。此外,您希望进行一些周期长度为5
的周期性移动,交替插值方向;这可以通过以下方式实现。如果t
是一个随时间增长的非负数,请计算
t' = t - t / 10
删除之前发生的所有期间
t'' = t' : t' in [0,5)
5 - t' : t' in [5,10)
然后设置
t''' = t' / 5
将参数标准化为[0,1]
并从头开始使用基本插值公式。
请注意,收集线性插值和各种其他方法here。
答案 1 :(得分:1)
根据您的描述,在任何给定的框架中有6个状态:
通过这些,您可以计算所需的进度值,例如:
function progressValue(startTime, lerpSpanSeconds, dir,
currentTime X, Y, dir, currentTime) {
// lerp
return 0.42;
}
对于requestAnimationFrame,you need a simple callback to pass in。也就是说,该函数必须知道它需要的一切,除了它运行时可以获得的东西。在这里,当它运行时,它只需要获取当前时间并从那里完成剩下的工作。
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函数来调用,或者实际上是一个回调函数,使其适用于其他类型的东西,这样你就可以使用任何元素,绘制函数和设置函数并使一个动画的东西,但这是一个合理的起点。
通过上述内容,我们只需要调用Mother来创建animableThing
函数并使用它调用RequestAnimationFrame。从那时起,它在内部调用RequestAnimationFrame来继续循环。
现在,完成后,你会想让它停止,所以在它可以检查的回调中添加一个变量,这样就可以了
var animableThing = MotherOfAnimableThings(...);
window.requestAnimationFrame(animableThing);
// ... later
animableThing.stop = true; // it should stop on the next frame