never executed always true always false
    1 {-|
    2   Easing functions modify the rate of change in animations.
    3   More examples can be seen here: <https://easings.net/>.
    4 -}
    5 module Reanimate.Ease
    6   ( Signal
    7   , constantS
    8   , fromToS
    9   , reverseS
   10   , curveS
   11   , powerS
   12   , bellS
   13   , oscillateS
   14   , cubicBezierS
   15   ) where
   16 
   17 -- | Signals are time-varying variables. Signals can be composed using function
   18 --   composition.
   19 type Signal = Double -> Double
   20 
   21 -- | Constant signal.
   22 --
   23 --   Example:
   24 --
   25 -- @
   26 -- 'Reanimate.signalA' ('constantS' 0.5) 'Reanimate.Builtin.Documentation.drawProgress'
   27 -- @
   28 --
   29 --   <<docs/gifs/doc_constantS.gif>>
   30 constantS :: Double -> Signal
   31 constantS = const
   32 
   33 -- | Signal with new starting and end values.
   34 --
   35 --   Example:
   36 --
   37 -- @
   38 -- 'Reanimate.signalA' ('fromToS' 0.8 0.2) 'Reanimate.Builtin.Documentation.drawProgress'
   39 -- @
   40 --
   41 --   <<docs/gifs/doc_fromToS.gif>>
   42 fromToS :: Double -> Double -> Signal
   43 fromToS from to t = from + (to-from)*t
   44 
   45 -- | Reverse signal order.
   46 --
   47 --   Example:
   48 --
   49 -- @
   50 -- 'Reanimate.signalA' 'reverseS' 'Reanimate.Builtin.Documentation.drawProgress'
   51 -- @
   52 --
   53 --   <<docs/gifs/doc_reverseS.gif>>
   54 reverseS :: Signal
   55 reverseS t = 1-t
   56 
   57 -- | S-curve signal. Takes a steepness parameter. 2 is a good default.
   58 --
   59 --   Example:
   60 --
   61 -- @
   62 -- 'Reanimate.signalA' ('curveS' 2) 'Reanimate.Builtin.Documentation.drawProgress'
   63 -- @
   64 --
   65 --   <<docs/gifs/doc_curveS.gif>>
   66 curveS :: Double -> Signal
   67 curveS steepness s =
   68   if s < 0.5
   69     then 0.5 * (2*s)**steepness
   70     else 1-0.5 * (2 - 2*s)**steepness
   71 
   72 -- | Power curve signal. Takes a steepness parameter. 2 is a good default.
   73 --
   74 --   Example:
   75 --
   76 -- @
   77 -- 'Reanimate.signalA' ('powerS' 2) 'Reanimate.Builtin.Documentation.drawProgress'
   78 -- @
   79 --
   80 --   <<docs/gifs/doc_powerS.gif>>
   81 powerS :: Double -> Signal
   82 powerS steepness s = s**steepness
   83 
   84 -- | Oscillate signal.
   85 --
   86 --   Example:
   87 --
   88 -- @
   89 -- 'Reanimate.signalA' 'oscillateS' 'Reanimate.Builtin.Documentation.drawProgress'
   90 -- @
   91 --
   92 --   <<docs/gifs/doc_oscillateS.gif>>
   93 oscillateS :: Signal
   94 oscillateS t =
   95   if t < 1/2
   96     then t*2
   97     else 2-t*2
   98 
   99 -- | Bell-curve signal. Takes a steepness parameter. 2 is a good default.
  100 --
  101 --   Example:
  102 --
  103 -- @
  104 -- 'Reanimate.signalA' ('bellS' 2) 'Reanimate.Builtin.Documentation.drawProgress'
  105 -- @
  106 --
  107 --   <<docs/gifs/doc_bellS.gif>>
  108 bellS :: Double -> Signal
  109 bellS steepness = curveS steepness . oscillateS
  110 
  111 -- | Cubic Bezier signal. Gives you a fair amount of control over how the
  112 --   signal will curve.
  113 --
  114 --   Example:
  115 --
  116 -- @
  117 -- 'Reanimate.signalA' ('cubicBezierS' (0.0, 0.8, 0.9, 1.0)) 'Reanimate.Builtin.Documentation.drawProgress'
  118 -- @
  119 --   
  120 --   <<docs/gifs/doc_cubicBezierS.gif>>
  121 cubicBezierS :: (Double, Double, Double, Double) -> Signal
  122 cubicBezierS (x1, x2, x3, x4) s = 
  123   let ms = 1-s
  124   in x1*ms^(3::Int) + 3*x2*ms^(2::Int)*s + 3*x3*ms*s^(2::Int) + x4*s^(3::Int)