-
Notifications
You must be signed in to change notification settings - Fork 25
Expand file tree
/
Copy pathChain.hs
More file actions
98 lines (78 loc) · 2.61 KB
/
Copy pathChain.hs
File metadata and controls
98 lines (78 loc) · 2.61 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
{-# LANGUAGE OverloadedStrings, LiberalTypeSynonyms #-}
module Chain (chainClass) where
import Control.Applicative
import Data.String (fromString)
import Haste hiding (fromString)
import Haste.JSON
import Lens.Family2 hiding (view)
import React
import React.Anim
import React.Anim.Class
-- model
data ChainState = Open | Closed deriving Eq
data Toggle = Toggle deriving Show
type Chain a = a ChainState Toggle Double
initialClassState :: ChainState
initialClassState = Closed
initialAnimationState :: Double
initialAnimationState = 0
-- update
chain :: Double -> AnimConfig Toggle Double
chain from = AnimConfig
{ duration = 1000
, lens = id
, endpoints = (from, 0)
, easing = EaseInOutQuad
, onComplete = const Nothing
}
transition :: Toggle -> ChainState -> (ChainState, [AnimConfig Toggle Double])
transition Toggle Open = (Closed, [ chain 1 ])
transition Toggle Closed = (Open, [ chain (-1) ])
-- view
startWidth, startHeight, finalWidth, finalHeight :: Double
startWidth = 20
startHeight = 20
finalWidth = 400
finalHeight = 200
startColor = Color 74 74 182
endColor = Color 74 178 182
-- Note:
--
-- This is not necessarily how I recommend doing compound animations. This
-- is pretty low level - I'd consider it a hack, almost. I need to think
-- more about how this should be done, but this serves my purposes for
-- a quick demo.
derive :: Double -> (Double, Double)
derive t | t == 0 = (startWidth, startHeight)
derive t | t < 1/3 =
( interpolate EaseInOutQuad startWidth finalWidth (t * 1.5)
, startHeight
)
derive t | t < 2/3 =
( interpolate EaseInOutQuad startWidth finalWidth (t * 1.5)
, interpolate EaseInOutQuad startHeight finalHeight ((t - 1/3) * 1.5)
)
derive t | t < 1 =
( finalWidth
, interpolate EaseInOutQuad startHeight finalHeight ((t - 1/3) * 1.5)
)
derive t = (finalWidth, finalHeight)
view :: ChainState -> Double -> Chain ReactA'
view status animState = div_ [ class_ "chain-container" ] $ do
let numStatus = if status == Open then 1 else 0
t = animState + numStatus
(xt, yt) = derive t
color = fromString $ show $ interpolate Linear startColor endColor t
div_ $ button_ [ class_ "btn btn--m btn--gray-border"
, onClick (const (Just Toggle))
] "toggle"
div_ [ class_ "chaining"
, style_ (Dict [("width", Num xt),
("height", Num yt),
("backgroundColor", color)
])
]
""
chainClass :: IO (Chain ReactClassA')
chainClass =
createClass view transition initialClassState initialAnimationState []