desck 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.gitlab-ci.yml +21 -0
- package/README.md +176 -0
- package/desck.cjs +2 -0
- package/elm.json +39 -0
- package/justfile +13 -0
- package/package.json +25 -0
- package/public/index.html +30 -0
- package/public/palette.json +16 -0
- package/public/projects/something.json +139 -0
- package/public/projects/template.json +69 -0
- package/public/script.js +490 -0
- package/public/style.css +471 -0
- package/public/svg/backface.svg +1 -0
- package/public/svg/courts.svg +30 -0
- package/public/svg/digits.svg +18 -0
- package/public/svg/suits.svg +43 -0
- package/server.cjs +316 -0
- package/settings.json +10 -0
- package/src/Card.elm +38 -0
- package/src/ColorPicker.elm +113 -0
- package/src/Deck.elm +571 -0
- package/src/DeckView.elm +415 -0
- package/src/Layout.elm +224 -0
- package/src/Main.elm +3743 -0
- package/src/Palette.elm +302 -0
- package/src/Project.elm +1029 -0
- package/src/Rect.elm +292 -0
- package/src/SaveFile.elm +422 -0
- package/src/Theme.elm +99 -0
- package/src/Util.elm +337 -0
- package/src/Vec.elm +196 -0
- package/src/Zone.elm +364 -0
package/src/DeckView.elm
ADDED
|
@@ -0,0 +1,415 @@
|
|
|
1
|
+
module DeckView exposing (backface, cardSize, cornerRadius, frontface, includes)
|
|
2
|
+
|
|
3
|
+
import Deck exposing (..)
|
|
4
|
+
import Svg exposing (Svg)
|
|
5
|
+
import Svg.Attributes as A
|
|
6
|
+
import Util exposing (num, rotate, scale, scaleXY, translate, url)
|
|
7
|
+
import Vec exposing (Vec2)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
cardSize : Vec2
|
|
11
|
+
cardSize =
|
|
12
|
+
Vec2 250 350
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
var : String -> String
|
|
16
|
+
var name =
|
|
17
|
+
"var(--" ++ name ++ ")"
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
black : String
|
|
21
|
+
black =
|
|
22
|
+
var "black"
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
white : String
|
|
26
|
+
white =
|
|
27
|
+
var "white"
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
stripes : Float -> String -> String -> Float -> Svg msg
|
|
31
|
+
stripes width a b deg =
|
|
32
|
+
Svg.pattern
|
|
33
|
+
[ A.id "stripes"
|
|
34
|
+
, A.patternUnits "userSpaceOnUse"
|
|
35
|
+
, num A.width 10
|
|
36
|
+
, num A.height (width * 2)
|
|
37
|
+
, A.patternTransform <| rotate deg
|
|
38
|
+
]
|
|
39
|
+
[ Svg.rect
|
|
40
|
+
[ num A.width 10
|
|
41
|
+
, num A.height width
|
|
42
|
+
, A.fill a
|
|
43
|
+
]
|
|
44
|
+
[]
|
|
45
|
+
, Svg.rect
|
|
46
|
+
[ num A.width 10
|
|
47
|
+
, num A.height width
|
|
48
|
+
, num A.y width
|
|
49
|
+
, A.fill b
|
|
50
|
+
]
|
|
51
|
+
[]
|
|
52
|
+
]
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
includes : List (Svg msg)
|
|
56
|
+
includes =
|
|
57
|
+
[ Svg.defs [ A.id "defs" ]
|
|
58
|
+
[ stripes 15 "#444" "#666" 45.0
|
|
59
|
+
, Svg.symbol [ A.id "backface" ]
|
|
60
|
+
[ Svg.rect
|
|
61
|
+
[ num A.x 0
|
|
62
|
+
, num A.y 0
|
|
63
|
+
, num A.width <| 250
|
|
64
|
+
, num A.height <| 350
|
|
65
|
+
, A.class "card-back-pattern"
|
|
66
|
+
, A.rx cornerRadius
|
|
67
|
+
, A.fill (url "stripes")
|
|
68
|
+
, A.strokeWidth borderWidth
|
|
69
|
+
]
|
|
70
|
+
[]
|
|
71
|
+
]
|
|
72
|
+
]
|
|
73
|
+
]
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
cornerRadius : String
|
|
77
|
+
cornerRadius =
|
|
78
|
+
"8"
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
borderWidth : String
|
|
82
|
+
borderWidth =
|
|
83
|
+
"2"
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
backface : Float -> Float -> CardModel -> List (Svg msg)
|
|
87
|
+
backface w h _ =
|
|
88
|
+
let
|
|
89
|
+
p =
|
|
90
|
+
8
|
|
91
|
+
in
|
|
92
|
+
[ Svg.rect
|
|
93
|
+
[ num A.width <| w
|
|
94
|
+
, num A.height <| h
|
|
95
|
+
, A.rx cornerRadius
|
|
96
|
+
, A.class "card-back-rect"
|
|
97
|
+
, A.fill white
|
|
98
|
+
, A.stroke black
|
|
99
|
+
, A.strokeWidth borderWidth
|
|
100
|
+
]
|
|
101
|
+
[]
|
|
102
|
+
|
|
103
|
+
-- , Svg.rect
|
|
104
|
+
-- [ num A.width <| w
|
|
105
|
+
-- , num A.height <| h
|
|
106
|
+
-- , A.transform <| translate p p ++ scaleXY (1.0 - (2 * p / 250)) (1.0 - (2 * p / 350))
|
|
107
|
+
-- , A.rx cornerRadius
|
|
108
|
+
-- , A.class "card-back-rect"
|
|
109
|
+
-- , A.fill "var(--red)"
|
|
110
|
+
-- , A.stroke black
|
|
111
|
+
-- , A.strokeWidth borderWidth
|
|
112
|
+
-- ]
|
|
113
|
+
-- []
|
|
114
|
+
, Svg.use
|
|
115
|
+
[ A.xlinkHref "#backface"
|
|
116
|
+
, A.transform <| translate p p ++ scaleXY (1.0 - (2 * p / 250)) (1.0 - (2 * p / 350))
|
|
117
|
+
]
|
|
118
|
+
[]
|
|
119
|
+
]
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
type alias Pip =
|
|
123
|
+
( Float, Float )
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
pips : Rank -> List Pip
|
|
127
|
+
pips r =
|
|
128
|
+
let
|
|
129
|
+
top =
|
|
130
|
+
0.32
|
|
131
|
+
|
|
132
|
+
htop =
|
|
133
|
+
top / 2.0
|
|
134
|
+
|
|
135
|
+
stop =
|
|
136
|
+
top / 3.0
|
|
137
|
+
|
|
138
|
+
mtop =
|
|
139
|
+
((top - stop) / 2.0) + stop
|
|
140
|
+
|
|
141
|
+
side =
|
|
142
|
+
0.2
|
|
143
|
+
|
|
144
|
+
center4 =
|
|
145
|
+
[ ( -side, stop ), ( side, stop ), ( -side, -stop ), ( side, -stop ) ]
|
|
146
|
+
|
|
147
|
+
courtSide =
|
|
148
|
+
side * 1.2
|
|
149
|
+
|
|
150
|
+
courtTop =
|
|
151
|
+
top * 0.95
|
|
152
|
+
|
|
153
|
+
court =
|
|
154
|
+
[ ( courtSide, courtTop ), ( -courtSide, -courtTop ) ]
|
|
155
|
+
|
|
156
|
+
shiftx : Float -> List Pip -> List Pip
|
|
157
|
+
shiftx v ls =
|
|
158
|
+
List.map (\p -> ( v + Tuple.first p, Tuple.second p )) ls
|
|
159
|
+
in
|
|
160
|
+
case r of
|
|
161
|
+
Ace ->
|
|
162
|
+
[ ( 0.0, 0.0 ) ]
|
|
163
|
+
|
|
164
|
+
Two ->
|
|
165
|
+
[ ( 0.0, top ), ( 0.0, -top ) ]
|
|
166
|
+
|
|
167
|
+
Three ->
|
|
168
|
+
pips Ace ++ pips Two
|
|
169
|
+
|
|
170
|
+
Four ->
|
|
171
|
+
(pips Two |> shiftx -side) ++ (pips Two |> shiftx side)
|
|
172
|
+
|
|
173
|
+
Five ->
|
|
174
|
+
pips Ace ++ pips Four
|
|
175
|
+
|
|
176
|
+
Six ->
|
|
177
|
+
(pips Three |> shiftx -side) ++ (pips Three |> shiftx side)
|
|
178
|
+
|
|
179
|
+
Seven ->
|
|
180
|
+
( 0.0, -htop ) :: pips Six
|
|
181
|
+
|
|
182
|
+
Eight ->
|
|
183
|
+
( 0.0, htop ) :: pips Seven
|
|
184
|
+
|
|
185
|
+
Nine ->
|
|
186
|
+
center4 ++ pips Five
|
|
187
|
+
|
|
188
|
+
Ten ->
|
|
189
|
+
center4 ++ [ ( 0.0, mtop ), ( 0.0, -mtop ) ] ++ pips Four
|
|
190
|
+
|
|
191
|
+
Jack ->
|
|
192
|
+
court
|
|
193
|
+
|
|
194
|
+
Queen ->
|
|
195
|
+
court
|
|
196
|
+
|
|
197
|
+
King ->
|
|
198
|
+
court
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
suitIcon : CardModel -> Svg msg
|
|
202
|
+
suitIcon model =
|
|
203
|
+
case maybeSuit model of
|
|
204
|
+
Just suit ->
|
|
205
|
+
let
|
|
206
|
+
href =
|
|
207
|
+
"#"
|
|
208
|
+
++ suitAsString suit
|
|
209
|
+
in
|
|
210
|
+
Svg.use
|
|
211
|
+
[ A.xlinkHref href
|
|
212
|
+
, transform
|
|
213
|
+
[ translate -50.0 -50.0
|
|
214
|
+
]
|
|
215
|
+
, A.class "card-suit-icon"
|
|
216
|
+
, A.class <| suitAsString suit
|
|
217
|
+
, A.fill <| var <| suitAsColor suit
|
|
218
|
+
]
|
|
219
|
+
[]
|
|
220
|
+
|
|
221
|
+
Nothing ->
|
|
222
|
+
Svg.text ""
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
-- Svg.image
|
|
227
|
+
-- [ imageUrl <| suitString suit
|
|
228
|
+
-- , A.transform <| translate (-size / 2.0) (-size / 2.0)
|
|
229
|
+
-- , A.filter <| url <| suitAsColor suit
|
|
230
|
+
-- ]
|
|
231
|
+
-- []
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
cornerPip : CardModel -> Svg msg
|
|
235
|
+
cornerPip model =
|
|
236
|
+
let
|
|
237
|
+
textScale =
|
|
238
|
+
scale 3.7
|
|
239
|
+
|
|
240
|
+
textPos =
|
|
241
|
+
translate 0 7
|
|
242
|
+
|
|
243
|
+
rankChar =
|
|
244
|
+
case model of
|
|
245
|
+
Ranked rank _ ->
|
|
246
|
+
rankAsChar rank
|
|
247
|
+
|
|
248
|
+
Joker _ ->
|
|
249
|
+
"x"
|
|
250
|
+
in
|
|
251
|
+
Svg.g
|
|
252
|
+
[]
|
|
253
|
+
[ Svg.g
|
|
254
|
+
[ transform [ textPos, textScale ] ]
|
|
255
|
+
[ Svg.use
|
|
256
|
+
[ A.xlinkHref <| "#" ++ rankChar
|
|
257
|
+
, A.fill <| var <| modelAsColor model
|
|
258
|
+
]
|
|
259
|
+
[]
|
|
260
|
+
]
|
|
261
|
+
, Svg.g
|
|
262
|
+
[ transform
|
|
263
|
+
[ translate 12.0 60.0
|
|
264
|
+
, scale 0.26
|
|
265
|
+
]
|
|
266
|
+
]
|
|
267
|
+
[ suitIcon model ]
|
|
268
|
+
]
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
transform : List String -> Svg.Attribute msg
|
|
272
|
+
transform ls =
|
|
273
|
+
A.transform <| String.join " " ls
|
|
274
|
+
|
|
275
|
+
|
|
276
|
+
frontface : Float -> Float -> CardModel -> List (Svg msg)
|
|
277
|
+
frontface w h model =
|
|
278
|
+
let
|
|
279
|
+
p =
|
|
280
|
+
5
|
|
281
|
+
|
|
282
|
+
-- TODO Cards - Jumbo index setting
|
|
283
|
+
cp =
|
|
284
|
+
34.0
|
|
285
|
+
|
|
286
|
+
pipx pos =
|
|
287
|
+
(w / 2.0) + w * Tuple.first pos
|
|
288
|
+
|
|
289
|
+
pipy pos =
|
|
290
|
+
(h / 2.0) + h * Tuple.second pos
|
|
291
|
+
|
|
292
|
+
size =
|
|
293
|
+
0.65
|
|
294
|
+
|
|
295
|
+
courtSymbol m =
|
|
296
|
+
"#"
|
|
297
|
+
++ modelAsShort m
|
|
298
|
+
|
|
299
|
+
isPicture m =
|
|
300
|
+
case m of
|
|
301
|
+
Ranked rank _ ->
|
|
302
|
+
List.member rank [ Jack, Queen, King ]
|
|
303
|
+
|
|
304
|
+
Joker _ ->
|
|
305
|
+
True
|
|
306
|
+
|
|
307
|
+
courtCard =
|
|
308
|
+
if isPicture model then
|
|
309
|
+
Svg.g
|
|
310
|
+
[]
|
|
311
|
+
[ Svg.use
|
|
312
|
+
[ A.xlinkHref <| courtSymbol model
|
|
313
|
+
, A.transform <| translate cp cp ++ scaleXY (1.0 - (cp / 250.0) * 2.0) (1.0 - (cp / 350.0) * 2.0)
|
|
314
|
+
]
|
|
315
|
+
[]
|
|
316
|
+
|
|
317
|
+
-- , Svg.rect
|
|
318
|
+
-- [ case model of
|
|
319
|
+
-- Ranked _ _ ->
|
|
320
|
+
-- A.stroke "#ffffff"
|
|
321
|
+
-- Joker _ ->
|
|
322
|
+
-- A.stroke "transparent"
|
|
323
|
+
-- , A.fill "transparent"
|
|
324
|
+
-- , A.strokeWidth "5px"
|
|
325
|
+
-- , A.class "card-court-border"
|
|
326
|
+
-- , A.rx cornerRadius
|
|
327
|
+
-- -- , A.filter <| url "blue"
|
|
328
|
+
-- , A.transform <| translate cp cp ++ scaleXY (1.0 - (cp / 250.0) * 2.0) (1.0 - (cp / 350.0) * 2.0)
|
|
329
|
+
-- , num A.width 250
|
|
330
|
+
-- , num A.height 350
|
|
331
|
+
-- ]
|
|
332
|
+
-- []
|
|
333
|
+
]
|
|
334
|
+
|
|
335
|
+
else
|
|
336
|
+
Svg.text ""
|
|
337
|
+
|
|
338
|
+
courtPipSize =
|
|
339
|
+
size * 0.8
|
|
340
|
+
|
|
341
|
+
suitIconFromPos pos =
|
|
342
|
+
Svg.g
|
|
343
|
+
[ transform
|
|
344
|
+
[ translate (pipx pos) (pipy pos)
|
|
345
|
+
, rotate
|
|
346
|
+
(if Tuple.second pos <= 0.0 then
|
|
347
|
+
0.0
|
|
348
|
+
|
|
349
|
+
else
|
|
350
|
+
180.0
|
|
351
|
+
)
|
|
352
|
+
, scale
|
|
353
|
+
(case maybeRank model of
|
|
354
|
+
Just rank ->
|
|
355
|
+
case rank of
|
|
356
|
+
Ace ->
|
|
357
|
+
size * 2
|
|
358
|
+
|
|
359
|
+
Jack ->
|
|
360
|
+
courtPipSize
|
|
361
|
+
|
|
362
|
+
Queen ->
|
|
363
|
+
courtPipSize
|
|
364
|
+
|
|
365
|
+
King ->
|
|
366
|
+
courtPipSize
|
|
367
|
+
|
|
368
|
+
_ ->
|
|
369
|
+
size
|
|
370
|
+
|
|
371
|
+
Nothing ->
|
|
372
|
+
size
|
|
373
|
+
)
|
|
374
|
+
]
|
|
375
|
+
]
|
|
376
|
+
[ suitIcon model
|
|
377
|
+
]
|
|
378
|
+
|
|
379
|
+
pipIcons =
|
|
380
|
+
case maybeRank model of
|
|
381
|
+
Just rank ->
|
|
382
|
+
pips rank
|
|
383
|
+
|> List.map suitIconFromPos
|
|
384
|
+
|> Svg.g []
|
|
385
|
+
|
|
386
|
+
Nothing ->
|
|
387
|
+
Svg.text ""
|
|
388
|
+
|
|
389
|
+
cornerLabels =
|
|
390
|
+
Svg.g []
|
|
391
|
+
[ Svg.g
|
|
392
|
+
[ A.transform <| translate p p
|
|
393
|
+
]
|
|
394
|
+
[ cornerPip model ]
|
|
395
|
+
, Svg.g
|
|
396
|
+
[ A.transform <| translate (w - p) (h - p) ++ rotate 180
|
|
397
|
+
]
|
|
398
|
+
[ cornerPip model ]
|
|
399
|
+
]
|
|
400
|
+
in
|
|
401
|
+
[ Svg.rect
|
|
402
|
+
[ num A.width <| w
|
|
403
|
+
, num A.height <| h
|
|
404
|
+
, A.rx cornerRadius
|
|
405
|
+
, A.class "card-front-rect"
|
|
406
|
+
, A.ry cornerRadius
|
|
407
|
+
, A.fill white
|
|
408
|
+
, A.stroke black
|
|
409
|
+
, A.strokeWidth borderWidth
|
|
410
|
+
]
|
|
411
|
+
[]
|
|
412
|
+
, courtCard
|
|
413
|
+
, pipIcons
|
|
414
|
+
, cornerLabels
|
|
415
|
+
]
|
package/src/Layout.elm
ADDED
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
module Layout exposing (..)
|
|
2
|
+
|
|
3
|
+
import List exposing (indexedMap, length, map, reverse)
|
|
4
|
+
import Vec exposing (Vec2)
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
type Spread
|
|
8
|
+
= Horizontal
|
|
9
|
+
| Vertical
|
|
10
|
+
| Diagonal
|
|
11
|
+
| Rows
|
|
12
|
+
| Columns
|
|
13
|
+
| Stack
|
|
14
|
+
| Fan
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
defaultSpread : Spread -> Int
|
|
18
|
+
defaultSpread s =
|
|
19
|
+
let
|
|
20
|
+
dist =
|
|
21
|
+
35
|
|
22
|
+
in
|
|
23
|
+
case s of
|
|
24
|
+
Horizontal ->
|
|
25
|
+
dist
|
|
26
|
+
|
|
27
|
+
Vertical ->
|
|
28
|
+
85
|
|
29
|
+
|
|
30
|
+
Diagonal ->
|
|
31
|
+
dist
|
|
32
|
+
|
|
33
|
+
Rows ->
|
|
34
|
+
4
|
|
35
|
+
|
|
36
|
+
Columns ->
|
|
37
|
+
4
|
|
38
|
+
|
|
39
|
+
Stack ->
|
|
40
|
+
0
|
|
41
|
+
|
|
42
|
+
Fan ->
|
|
43
|
+
15
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
updateSpreadValue : Spread -> Spread -> Int -> Int
|
|
47
|
+
updateSpreadValue prev next value =
|
|
48
|
+
if defaultSpread prev == defaultSpread next then
|
|
49
|
+
value
|
|
50
|
+
|
|
51
|
+
else
|
|
52
|
+
defaultSpread next
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
validateSpreadValue : Spread -> Int -> Int
|
|
56
|
+
validateSpreadValue spreadType value =
|
|
57
|
+
case spreadType of
|
|
58
|
+
Rows ->
|
|
59
|
+
max 1 value
|
|
60
|
+
|
|
61
|
+
Columns ->
|
|
62
|
+
max 1 value
|
|
63
|
+
|
|
64
|
+
_ ->
|
|
65
|
+
value
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
spreadAsString : Spread -> String
|
|
69
|
+
spreadAsString st =
|
|
70
|
+
case st of
|
|
71
|
+
Horizontal ->
|
|
72
|
+
"Horizontal"
|
|
73
|
+
|
|
74
|
+
Vertical ->
|
|
75
|
+
"Vertical"
|
|
76
|
+
|
|
77
|
+
Diagonal ->
|
|
78
|
+
"Diagonal"
|
|
79
|
+
|
|
80
|
+
Rows ->
|
|
81
|
+
"Rows"
|
|
82
|
+
|
|
83
|
+
Columns ->
|
|
84
|
+
"Columns"
|
|
85
|
+
|
|
86
|
+
Stack ->
|
|
87
|
+
"Stack"
|
|
88
|
+
|
|
89
|
+
Fan ->
|
|
90
|
+
"Fan"
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
spreadTransforms : Int -> Vec2 -> Int -> Spread -> List ( Vec2, Vec2, Float )
|
|
94
|
+
spreadTransforms n cardSize spreadValue s =
|
|
95
|
+
let
|
|
96
|
+
noRotation =
|
|
97
|
+
List.map (\v -> ( v, Vec.half Vec.one, 0.0 ))
|
|
98
|
+
|
|
99
|
+
vec2i : Int -> Int -> Vec2
|
|
100
|
+
vec2i x y =
|
|
101
|
+
Vec2 (toFloat x) (toFloat y)
|
|
102
|
+
|
|
103
|
+
targets =
|
|
104
|
+
List.range 0 (n - 1)
|
|
105
|
+
in
|
|
106
|
+
case s of
|
|
107
|
+
Stack ->
|
|
108
|
+
targets
|
|
109
|
+
|> map (\_ -> Vec.zero)
|
|
110
|
+
|> noRotation
|
|
111
|
+
|> indexedMap (\i ( p, pv, _ ) -> ( p, pv, toFloat <| spreadValue * i ))
|
|
112
|
+
|
|
113
|
+
Horizontal ->
|
|
114
|
+
targets
|
|
115
|
+
|> map
|
|
116
|
+
(\i -> vec2i (i * spreadValue) 0)
|
|
117
|
+
|> reverse
|
|
118
|
+
|> noRotation
|
|
119
|
+
|
|
120
|
+
Vertical ->
|
|
121
|
+
targets
|
|
122
|
+
|> map
|
|
123
|
+
(\i -> vec2i 0 (i * spreadValue))
|
|
124
|
+
|> reverse
|
|
125
|
+
|> noRotation
|
|
126
|
+
|
|
127
|
+
-- FIX 4 cards to 3 rows etc, same for columns
|
|
128
|
+
Rows ->
|
|
129
|
+
let
|
|
130
|
+
columns =
|
|
131
|
+
max 1 (length targets // spreadValue)
|
|
132
|
+
in
|
|
133
|
+
targets
|
|
134
|
+
|> map
|
|
135
|
+
(\i ->
|
|
136
|
+
Vec2
|
|
137
|
+
(toFloat (modBy columns i) * cardSize.x)
|
|
138
|
+
(toFloat (i // columns) * cardSize.y)
|
|
139
|
+
)
|
|
140
|
+
|> reverse
|
|
141
|
+
|> noRotation
|
|
142
|
+
|
|
143
|
+
Columns ->
|
|
144
|
+
let
|
|
145
|
+
rows =
|
|
146
|
+
max 1 (length targets // spreadValue)
|
|
147
|
+
in
|
|
148
|
+
targets
|
|
149
|
+
|> map
|
|
150
|
+
(\i ->
|
|
151
|
+
Vec2
|
|
152
|
+
(toFloat (i // rows) * cardSize.x)
|
|
153
|
+
(toFloat (modBy rows i) * cardSize.y)
|
|
154
|
+
)
|
|
155
|
+
|> reverse
|
|
156
|
+
|> noRotation
|
|
157
|
+
|
|
158
|
+
Diagonal ->
|
|
159
|
+
targets
|
|
160
|
+
|> map
|
|
161
|
+
(\i ->
|
|
162
|
+
Vec2
|
|
163
|
+
(toFloat <| i * spreadValue)
|
|
164
|
+
(toFloat <| i * spreadValue)
|
|
165
|
+
)
|
|
166
|
+
|> reverse
|
|
167
|
+
|> noRotation
|
|
168
|
+
|
|
169
|
+
Fan ->
|
|
170
|
+
targets
|
|
171
|
+
|> map
|
|
172
|
+
(\i ->
|
|
173
|
+
let
|
|
174
|
+
t =
|
|
175
|
+
toFloat i / toFloat (n - 1)
|
|
176
|
+
|
|
177
|
+
-- angle =
|
|
178
|
+
-- 0.2
|
|
179
|
+
-- p =
|
|
180
|
+
-- t * pi * 2.0 * 0.1 - pi * 0.5 - pi * angle
|
|
181
|
+
-- x =
|
|
182
|
+
-- cos p
|
|
183
|
+
-- y =
|
|
184
|
+
-- sin p
|
|
185
|
+
-- radius =
|
|
186
|
+
-- (toFloat <| length targets) * 80.0
|
|
187
|
+
deg =
|
|
188
|
+
toFloat spreadValue * 0.5 * (toFloat <| List.length targets)
|
|
189
|
+
|
|
190
|
+
pos =
|
|
191
|
+
-- sub (scale radius (Vec2 x y)) (Vec2 (-radius * 0.105) (-radius * 0.995))
|
|
192
|
+
Vec.zero
|
|
193
|
+
|
|
194
|
+
pivot =
|
|
195
|
+
Vec2 0.5 1.0
|
|
196
|
+
|
|
197
|
+
rot =
|
|
198
|
+
-0.5 * deg + deg * t
|
|
199
|
+
in
|
|
200
|
+
( pos, pivot, rot )
|
|
201
|
+
)
|
|
202
|
+
|> reverse
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
-- _ ->
|
|
207
|
+
-- targets
|
|
208
|
+
-- |> map (\_ -> zero)
|
|
209
|
+
-- |> noRotation
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
hsep : Int -> Float -> Vec2 -> Int -> Vec2
|
|
213
|
+
hsep rows separation size index =
|
|
214
|
+
let
|
|
215
|
+
column =
|
|
216
|
+
index // rows
|
|
217
|
+
|
|
218
|
+
row =
|
|
219
|
+
modBy rows index
|
|
220
|
+
|
|
221
|
+
( w, h ) =
|
|
222
|
+
Vec.tuple size
|
|
223
|
+
in
|
|
224
|
+
Vec2 (separation + toFloat column * w) (separation + toFloat row * h)
|