将缓动应用于循环延迟

时间:2016-08-12 11:17:16

标签: loops go delay easing

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

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

正如你所读到的,这是非常基本的。假设我想在3s内完成整个循环(作业完成时间是可以忽略的,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

根据我的理解,我必须计算抽象的“经过的百分比时间”,并以某种方式用缓动函数插值这个值。

这个Node项目似乎只是这样做:https://github.com/CharlotteGore/animation-timer,但我再也无法弄清楚如何重现它。

2 个答案:

答案 0 :(得分:1)

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

使用原始代码,如果您希望在3秒内完成114次迭代,最简单的方法是使用迭代索引作为当前进度,将114作为总计,然后将计算出的延迟因子乘以总持续时间3.0S。

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

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

答案 1 :(得分:0)

我想,你可以使用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()