-
Notifications
You must be signed in to change notification settings - Fork 2
/
View.elm
162 lines (120 loc) · 4.48 KB
/
View.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
156
157
158
159
160
161
162
module View exposing (..)
import Model exposing (..)
import Util exposing (..)
import Html exposing (div,Html,pre,h2)
import Html.Attributes as HtmlAttri exposing (class,style)
import Html.App exposing (program)
import Html.Lazy as Html
import Svg exposing (..)
import Svg.Attributes as SvgAttri exposing (..)
import Svg.Events exposing (on)
import Svg.Lazy exposing (lazy)
import Style exposing (..)
import Mouse exposing (..)
import Json.Decode as Json
import String
import Array exposing (..)
containerCss =
HtmlAttri.style [ Style.display "flex"
, Style.justifyContent Style.center]
generaterCss =
HtmlAttri.style [ Style.overflow Style.scroll
, Style.backgroundColor "#ffffff"
, Style.padding <| px 20
, Style.width <| pc 20]
logoAreaCss : Attribute Msg
logoAreaCss =
HtmlAttri.style [Style.backgroundColor "#ffffff"
,Style.width <| px 600
,Style.height <| px 550
,Style.margin <| px 20]
view : Model -> Html Msg
view model =
div [containerCss]
[ lazy logoArea model
, lazy generaterArea model]
viewboxSize = "-300 -300 923.141 922.95"
logoArea : Model -> Html Msg
logoArea model =
div [logoAreaCss]
[
svg
[ version "1.1", x "0", y "0", viewBox viewboxSize]
<| Array.toList
<| Array.map (\piece -> makeSvg piece)
<| currentPieces model.drag model.pieces
]
generaterArea model =
div [generaterCss] [
div []
[Html.lazy generater <| Array.toList model.pieces]]
moveStr : Position -> String
moveStr {x,y} =
"translate(" ++ (toString x) ++ " " ++ (toString y) ++ ")"
rotateString : Int -> Float -> Float -> String
rotateString num x y =
"rotate(" ++ (String.join " " <| List.map toString [toFloat num, x , y]) ++ ")"
rotatePiece : Piece -> String
rotatePiece {svgType,points,rotate,width,height,x,y} =
case svgType of
Rect ->
rotateString rotate (x + width/2) (y+ height/2)
_ ->
let (ax,ay) = List.foldl (\(a,b) (c,d) -> (a+c,b+d)) (0,0) points
n = toFloat <| List.length points
in rotateString rotate (ax/n) (ay/n)
matrixStr : List Float -> String
matrixStr list =
if List.isEmpty list then ""
else
let strings = List.map toString list |> String.join " "
in "matrix(" ++ strings ++ ")"
transformStr piece =
String.join " " [
moveStr piece.position
, matrixStr piece.matrix
, rotatePiece piece]
transformAttri : Piece -> Attribute Msg
transformAttri piece =
SvgAttri.transform <| transformStr piece
onMouseDown : Int -> Attribute Msg
onMouseDown n =
on "mousedown" (Json.map (DragStart n) Mouse.position)
makeAttribute : Piece -> List (Attribute Msg)
makeAttribute piece =
[ onMouseDown piece.id
, fill piece.fill
, SvgAttri.x <| toString piece.x
, SvgAttri.y <| toString piece.y
, SvgAttri.width <| toString piece.width
, SvgAttri.height <| toString piece.height
, points <| String.join " " <| List.map (\(x,y) -> toString x ++"," ++ toString y ) piece.points
, transformAttri piece ]
makeSvg piece =
case piece.svgType of
Polygon -> polygon (makeAttribute piece) []
Rect -> rect (makeAttribute piece) []
------svg string generater
generater pieces =
Html.pre [] [text <|generateSvgStr pieces]
generateSvgStr pieces =
"<svg viewBox=" ++ (toString <| viewboxSize) ++ " >" ++
(String.concat <| List.map pieceStr pieces)
++ "</svg>"
pieceStr piece =
case piece.svgType of
Polygon ->String.join " " <| ["<polygon"] ++ polynakami piece ++ ["/>\n"]
Rect ->String.join " " <| ["<rect"] ++ rectnakami piece ++ ["/>\n"]
polynakami : Piece -> List String
polynakami piece =
[ "fill="++ toString piece.fill
, String.append "points=" <| toString <| String.join " " <| List.map (\(x,y) -> toString x ++"," ++ toString y ) piece.points
, "transform="++ (toString <| transformStr piece) ]
rectnakami : Piece -> List String
rectnakami piece =
[ "fill=" ++ toString piece.fill
, String.append "x=" <| toString <| toString piece.x
, String.append "y=" <| toString <| toString piece.y
, String.append "width=" <| toString <| toString piece.width
, String.append "height=" <| toString <| toString piece.height
, String.append "transform=" <| toString <|transformStr piece ]