/
Model.elm
155 lines (122 loc) · 3.46 KB
/
Model.elm
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
module Clouds.Model exposing (Cloud, CloudRow, Coords, Dimensions, Model, buildCloudRow, init)
import List.Extra as List
import Random
import Time exposing (Posix)
type alias Model =
{ window : Dimensions
, cloudRows : List CloudRow
, extremity : Float
, speed : Float
}
type alias CloudRow =
{ y : Float
, height : Float
, xScale : Float
, yScale : Float
, clouds : List Cloud
, opacity : Float
}
type alias Cloud =
{ width : Float
, x : Float
, corners :
{ topLeft : CornerInfo
, topRight : CornerInfo
, bottomLeft : CornerInfo
, bottomRight : CornerInfo
}
}
type alias CornerInfo =
{ horizontalLength : Float
, firstControlPointX : Float
, secondControlPointY : Float
}
type alias Dimensions =
{ width : Float, height : Float }
type alias Coords =
{ x : Float, y : Float }
type alias Flags =
{ window : Dimensions
, time : Int
}
init : Flags -> Model
init flags =
let
seed =
Random.initialSeed flags.time
width =
flags.window.width - 200
in
{ window = flags.window
, cloudRows =
[ buildCloudRow 0.5 width seed
]
, extremity = 0.5
, speed = 0.5
}
type alias CloudBuildData =
{ totalWidth : Float
, allocatedWidth : Float
, extremity : Float
, seed : Random.Seed
}
buildCloudRow : Float -> Float -> Random.Seed -> CloudRow
buildCloudRow extremity windowWidth seed =
{ height = 10
, y = 1
, xScale = 1
, yScale = 1
, opacity = 0
, clouds =
List.unfoldr buildCloud
{ totalWidth = windowWidth
, allocatedWidth = 0
, extremity = extremity
, seed = seed
}
}
buildCloud : CloudBuildData -> Maybe ( Cloud, CloudBuildData )
buildCloud { totalWidth, allocatedWidth, seed, extremity } =
if allocatedWidth >= totalWidth then
Nothing
else
let
( cloudWidth, seed1 ) =
Random.step (Random.float 20 50) seed
( topLeftCorner, seed2 ) =
Random.step (cornerGenerator extremity) seed1
( topRightCorner, seed3 ) =
Random.step (cornerGenerator extremity) seed2
( bottomLeftCorner, seed4 ) =
Random.step (cornerGenerator extremity) seed3
( bottomRightCorner, seed5 ) =
Random.step (cornerGenerator extremity) seed4
in
Just
( { width = cloudWidth
, x = allocatedWidth
, corners =
{ topLeft = topLeftCorner
, topRight = topRightCorner
, bottomLeft = bottomLeftCorner
, bottomRight = bottomRightCorner
}
}
, { allocatedWidth = allocatedWidth + cloudWidth + 2
, seed = seed5
, extremity = extremity
, totalWidth = totalWidth
}
)
probability : Random.Generator Float
probability =
Random.float 0 1
cornerGenerator : Float -> Random.Generator CornerInfo
cornerGenerator extremity =
Random.map3 CornerInfo
-- horizontal length of curve (%)
(Random.float (0.6 * extremity) (1 * extremity))
-- X control point position
(Random.float (0.8 * extremity) (extremity + 1))
-- Y control point position
(Random.float 0 (1.2 * extremity))