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 , fromListS
15 , cubicBezierS
16 ) where
17
18 -- | Signals are time-varying variables. Signals can be composed using function
19 -- composition.
20 type Signal = Double -> Double
21
22 fromListS :: [(Double, Signal)] -> Signal
23 fromListS fns t = worker 0 fns
24 where
25 worker _ [] = 0
26 worker now [(len, fn)] = fn (min 1 ((t-now) / min (1-now) len))
27 worker now ((len, fn):rest)
28 | now+len < t = worker (now+len) rest
29 | otherwise = fn ((t-now) / len)
30
31 -- | Constant signal.
32 --
33 -- Example:
34 --
35 -- > signalA (constantS 0.5) drawProgress
36 --
37 -- <<docs/gifs/doc_constantS.gif>>
38 constantS :: Double -> Signal
39 constantS = const
40
41 -- | Signal with new starting and end values.
42 --
43 -- Example:
44 --
45 -- > signalA (fromToS 0.8 0.2) drawProgress
46 --
47 -- <<docs/gifs/doc_fromToS.gif>>
48 fromToS :: Double -> Double -> Signal
49 fromToS from to t = from + (to-from)*t
50
51 -- | Reverse signal order.
52 --
53 -- Example:
54 --
55 -- > signalA reverseS drawProgress
56 --
57 -- <<docs/gifs/doc_reverseS.gif>>
58 reverseS :: Signal
59 reverseS t = 1-t
60
61 -- | S-curve signal. Takes a steepness parameter. 2 is a good default.
62 --
63 -- Example:
64 --
65 -- > signalA (curveS 2) drawProgress
66 --
67 -- <<docs/gifs/doc_curveS.gif>>
68 curveS :: Double -> Signal
69 curveS steepness s =
70 if s < 0.5
71 then 0.5 * (2*s)**steepness
72 else 1-0.5 * (2 - 2*s)**steepness
73
74 -- | Power curve signal. Takes a steepness parameter. 2 is a good default.
75 --
76 -- Example:
77 --
78 -- > signalA (powerS 2) drawProgress
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 -- > signalA oscillateS drawProgress
89 --
90 -- <<docs/gifs/doc_oscillateS.gif>>
91 oscillateS :: Signal
92 oscillateS t =
93 if t < 1/2
94 then t*2
95 else 2-t*2
96
97 -- | Bell-curve signal. Takes a steepness parameter. 2 is a good default.
98 --
99 -- Example:
100 --
101 -- > signalA (bellS 2) drawProgress
102 --
103 -- <<docs/gifs/doc_bellS.gif>>
104 bellS :: Double -> Signal
105 bellS steepness = curveS steepness . oscillateS
106
107 -- | Cubic Bezier signal. Gives you a fair amount of control over how the
108 -- signal will 'curve'.
109 --
110 -- Example:
111 --
112 -- > signalA (cubicBezierS (0.0, 0.8, 0.9, 1.0)) drawProgress
113 --
114 -- <<docs/gifs/doc_cubicBezierS.gif>>
115 cubicBezierS :: (Double, Double, Double, Double) -> Signal
116 cubicBezierS (x1, x2, x3, x4) s =
117 let ms = 1-s
118 in x1*ms^(3::Int) + 3*x2*ms^(2::Int)*s + 3*x3*ms*s^(2::Int) + x4*s^(3::Int)