// 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 } }