never executed always true always false
1 module Reanimate.Ease
2 ( Signal
3 , constantS
4 , fromToS
5 , reverseS
6 , curveS
7 , powerS
8 , bellS
9 , oscillateS
10 , fromListS
11 , cubicBezierS
12 ) where
13
14 -- | Signals are time-varying variables. Signals can be composed using function
15 -- composition.
16 type Signal = Double -> Double
17
18 fromListS :: [(Double, Signal)] -> Signal
19 fromListS fns t = worker 0 fns
20 where
21 worker _ [] = 0
22 worker now [(len, fn)] = fn (min 1 ((t-now) / min (1-now) len))
23 worker now ((len, fn):rest)
24 | now+len < t = worker (now+len) rest
25 | otherwise = fn ((t-now) / len)
26
27 -- | Constant signal.
28 --
29 -- Example:
30 --
31 -- > signalA (constantS 0.5) drawProgress
32 --
33 -- <<docs/gifs/doc_constantS.gif>>
34 constantS :: Double -> Signal
35 constantS = const
36
37 -- | Signal with new starting and end values.
38 --
39 -- Example:
40 --
41 -- > signalA (fromToS 0.8 0.2) drawProgress
42 --
43 -- <<docs/gifs/doc_fromToS.gif>>
44 fromToS :: Double -> Double -> Signal
45 fromToS from to t = from + (to-from)*t
46
47 -- | Reverse signal order.
48 --
49 -- Example:
50 --
51 -- > signalA reverseS drawProgress
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 -- > signalA (curveS 2) drawProgress
62 --
63 -- <<docs/gifs/doc_curveS.gif>>
64 curveS :: Double -> Signal
65 curveS steepness s =
66 if s < 0.5
67 then 0.5 * (2*s)**steepness
68 else 1-0.5 * (2 - 2*s)**steepness
69
70 powerS :: Double -> Signal
71 powerS steepness s = s**steepness
72
73 -- | Oscillate signal.
74 --
75 -- Example:
76 --
77 -- > signalA oscillateS drawProgress
78 --
79 -- <<docs/gifs/doc_oscillateS.gif>>
80 oscillateS :: Signal
81 oscillateS t =
82 if t < 1/2
83 then t*2
84 else 2-t*2
85
86 -- | Bell-curve signal. Takes a steepness parameter. 2 is a good default.
87 --
88 -- Example:
89 --
90 -- > signalA (bellS 2) drawProgress
91 --
92 -- <<docs/gifs/doc_bellS.gif>>
93 bellS :: Double -> Signal
94 bellS steepness = curveS steepness . oscillateS
95
96 -- | Cubic Bezier signal. Gives you a fair amount of control over how the
97 -- signal will 'curve'.
98 --
99 -- Example:
100 --
101 -- > signalA (cubicBezierS (0.0, 0.8, 0.9, 1.0)) drawProgress
102 --
103 -- <<docs/gifs/doc_cubicBezierS.gif>>
104 cubicBezierS :: (Double, Double, Double, Double) -> Signal
105 cubicBezierS (x1, x2, x3, x4) s =
106 let ms = 1-s
107 in x1*ms^(3::Int) + 3*x2*ms^(2::Int)*s + 3*x3*ms*s^(2::Int) + x4*s^(3::Int)