80 lines
1.8 KiB
Go
80 lines
1.8 KiB
Go
// Copyright 2014 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package clock
|
|
|
|
// Standard tween functions.
|
|
//
|
|
// Easing means a slowing near the timing boundary, as defined by
|
|
// a cubic bezier curve. Exact parameters match the CSS properties.
|
|
var (
|
|
EaseIn = CubicBezier(0.42, 0, 1, 1)
|
|
EaseOut = CubicBezier(0, 0, 0.58, 1)
|
|
EaseInOut = CubicBezier(0.42, 0, 0.58, 1)
|
|
)
|
|
|
|
func Linear(t0, t1, t Time) float32 {
|
|
if t0 == t1 {
|
|
return 1
|
|
}
|
|
return float32(t-t0) / float32(t1-t0)
|
|
}
|
|
|
|
// CubicBezier generates a tween function determined by a Cubic Bézier curve.
|
|
//
|
|
// The parameters are cubic control parameters. The curve starts at (0,0)
|
|
// going toward (x0,y0), and arrives at (1,1) coming from (x1,y1).
|
|
func CubicBezier(x0, y0, x1, y1 float32) func(t0, t1, t Time) float32 {
|
|
return func(start, end, now Time) float32 {
|
|
// A Cubic-Bezier curve restricted to starting at (0,0) and
|
|
// ending at (1,1) is defined as
|
|
//
|
|
// B(t) = 3*(1-t)^2*t*P0 + 3*(1-t)*t^2*P1 + t^3
|
|
//
|
|
// with derivative
|
|
//
|
|
// B'(t) = 3*(1-t)^2*P0 + 6*(1-t)*t*(P1-P0) + 3*t^2*(1-P1)
|
|
//
|
|
// Given a value x ∈ [0,1], we solve for t using Newton's
|
|
// method and solve for y using t.
|
|
|
|
x := Linear(start, end, now)
|
|
|
|
// Solve for t using x.
|
|
t := x
|
|
for i := 0; i < 5; i++ {
|
|
t2 := t * t
|
|
t3 := t2 * t
|
|
d := 1 - t
|
|
d2 := d * d
|
|
|
|
nx := 3*d2*t*x0 + 3*d*t2*x1 + t3
|
|
dxdt := 3*d2*x0 + 6*d*t*(x1-x0) + 3*t2*(1-x1)
|
|
if dxdt == 0 {
|
|
break
|
|
}
|
|
|
|
t -= (nx - x) / dxdt
|
|
if t <= 0 || t >= 1 {
|
|
break
|
|
}
|
|
}
|
|
if t < 0 {
|
|
t = 0
|
|
}
|
|
if t > 1 {
|
|
t = 1
|
|
}
|
|
|
|
// Solve for y using t.
|
|
t2 := t * t
|
|
t3 := t2 * t
|
|
d := 1 - t
|
|
d2 := d * d
|
|
y := 3*d2*t*y0 + 3*d*t2*y1 + t3
|
|
|
|
return y
|
|
}
|
|
}
|