将缓动应用于循环延迟

Applying easing to a loop delay

简单来说,我正在尝试弄清楚如何将缓动应用于循环延迟。

for (i := 0; i < 114; i++) {
    // do a task
    time.Sleep(//delay before next job)
}

如您所见,这是非常基础的。假设我想在 3 秒内完成整个循环(作业完成时间可以忽略不计,t <= us)。使用 Penner 方程为每次迭代计算适当的缓和延迟的正确方法是什么?

因此,使用此函数,要模拟从零速度开始的加速度,我应该如何在循环的每次迭代中使用 t 参数来创建适当的睡眠延迟?

func easeInQuad(t float64) {
  return math.Pow(t, 2)
}

如果你能帮助我,我将不胜感激。方程式到目前为止还不是问题,但如何在我的用例中使用它们。

我的问题一开始可能看起来像这样:Applying easing to setTimeout delays, within a loop 但是这个没有考虑循环的总时间。

但是,我认为使用重写为仅使用范围 [0,1] 中的一个参数的方程式可能会更好:https://gist.github.com/rezoner/713615dabedb59a15470

根据我的理解,我必须计算抽象 "percentage time elapsed",并以某种方式用缓动函数插入该值。

这个 Node 项目似乎就是这样做的:https://github.com/CharlotteGore/animation-timer,但我还是不知道如何重现它。

我想,你可以使用 time.Ticker。

numLoops := 144
timePerIteration := time.Duration(3) * time.Second / time.Duration(numLoops)
ticker := time.NewTicker(timePerIteration)
for i := 0; i < numLoops; i++ {
    // your code
    <-ticker.C
}
ticker.Stop()

Penner 方程式基本上需要两个参数:当前进度和可能的总进度。但是,或者,您可以将总进度百分比作为单个参数(作为 0 到 1 之间的值)提供给它,因为无论如何它都是使用当前和总计来计算的。

用你原来的代码,如果你想在3秒内进行114次迭代,最简单的方法是用你的迭代索引作为当前进度,114作为总进度,然后将计算出的延迟因子乘以你的总时长 3.0s.

请注意,Penner 方程式计算从起始位置开始的总位移,而不是每一步的相对位移,因此您实际上需要自己计算该差值。因此this迭代的延迟是本次迭代的总位移(延迟)减去最后一次迭代的总位移:

func DoStuffWithEasing() {
    iterations := 114
    runTime := 3 * time.Second

    for i := 1; i <= iterations; i++ {
        // do a task
        time.Sleep(easeInQuadDelay(i, iterations, runTime))
    }
}

func easeInQuadDelay(c, t int, dur time.Duration) time.Duration {
    if c <= 0 || t == 0 { // invalid cases
        return 0
    }

    // This return can be a single-liner, but I split it up for clarity
    // Note that time.Durations are fundamentally int64s,
    // so we can easily type convert them to float64s and back

    this := math.Pow(float64(c)/float64(t), 2)
    last := math.Pow(float64(c-1)/float64(t), 2)
    return time.Duration((this - last) * float64(dur))
}

https://play.golang.org/p/TTgZUYUvxW

Graph of the easing