tween.go 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. // Copyright 2014 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package clock
  5. // Standard tween functions.
  6. //
  7. // Easing means a slowing near the timing boundary, as defined by
  8. // a cubic bezier curve. Exact parameters match the CSS properties.
  9. var (
  10. EaseIn = CubicBezier(0.42, 0, 1, 1)
  11. EaseOut = CubicBezier(0, 0, 0.58, 1)
  12. EaseInOut = CubicBezier(0.42, 0, 0.58, 1)
  13. )
  14. // Linear computes the fraction [0,1] that t lies between [t0,t1].
  15. func Linear(t0, t1, t Time) float32 {
  16. if t >= t1 {
  17. return 1
  18. }
  19. if t <= t0 {
  20. return 0
  21. }
  22. return float32(t-t0) / float32(t1-t0)
  23. }
  24. // CubicBezier generates a tween function determined by a Cubic Bézier curve.
  25. //
  26. // The parameters are cubic control parameters. The curve starts at (0,0)
  27. // going toward (x0,y0), and arrives at (1,1) coming from (x1,y1).
  28. func CubicBezier(x0, y0, x1, y1 float32) func(t0, t1, t Time) float32 {
  29. return func(start, end, now Time) float32 {
  30. // A Cubic-Bezier curve restricted to starting at (0,0) and
  31. // ending at (1,1) is defined as
  32. //
  33. // B(t) = 3*(1-t)^2*t*P0 + 3*(1-t)*t^2*P1 + t^3
  34. //
  35. // with derivative
  36. //
  37. // B'(t) = 3*(1-t)^2*P0 + 6*(1-t)*t*(P1-P0) + 3*t^2*(1-P1)
  38. //
  39. // Given a value x ∈ [0,1], we solve for t using Newton's
  40. // method and solve for y using t.
  41. x := Linear(start, end, now)
  42. // Solve for t using x.
  43. t := x
  44. for i := 0; i < 5; i++ {
  45. t2 := t * t
  46. t3 := t2 * t
  47. d := 1 - t
  48. d2 := d * d
  49. nx := 3*d2*t*x0 + 3*d*t2*x1 + t3
  50. dxdt := 3*d2*x0 + 6*d*t*(x1-x0) + 3*t2*(1-x1)
  51. if dxdt == 0 {
  52. break
  53. }
  54. t -= (nx - x) / dxdt
  55. if t <= 0 || t >= 1 {
  56. break
  57. }
  58. }
  59. if t < 0 {
  60. t = 0
  61. }
  62. if t > 1 {
  63. t = 1
  64. }
  65. // Solve for y using t.
  66. t2 := t * t
  67. t3 := t2 * t
  68. d := 1 - t
  69. d2 := d * d
  70. y := 3*d2*t*y0 + 3*d*t2*y1 + t3
  71. return y
  72. }
  73. }