JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
css bump
[crayon_mockup.git] / auto.coffee
1 # settings
2 width = 500
3 height = 500
4
5 # globals
6 $svg = null # jquery object for svg element
7 svg = null # dom object for svg element
8 $tool_options = null # jquery object for tool options line
9 selection = null
10 svg_ns = 'http://www.w3.org/2000/svg'
11 cur_tool = null
12 cur_tool_name = null
13 mouse = x: 0, y: 0, buttons: [0,0,0]
14
15 class Tool
16         constructor: (args) ->
17                 @button = args.button
18                 if @button?
19                         @button.addClass 'disabled'
20                 @tool_options = args.tool_options
21         click: (x, y) ->
22         mousemove: (x, y) ->
23         keydown: (keycode) ->
24         disable: ->
25                 if @button?
26                         @button.removeClass 'disabled'
27                 @tool_options.empty()
28
29 class TutorialTool extends Tool
30         constructor: (args) ->
31                 super args
32                 @paths = []
33                 choose = [
34                         [[219,34],[53,141],[96,143],[92,255],[365,257],[362,145],[407,144,'z']],
35                         [[161,118],[144,106],[130,115],[128,152],[140,160],[156,150]],
36                         [[173,107],[169,159],[180,137],[189,133],[193,160]],
37                         [[218,135],[205,144],[205,158],[215,164],[225,156],[225,144,'z']],
38                         [[242,135],[233,145],[233,157],[244,168],[256,158],[254,144,'z']],
39                         [[278,141],[269,135],[261,142],[264,151],[278,153],[281,162],[271,170],[264,163]],
40                         [[291,151],[305,151],[312,143],[299,135],[288,140],[293,160],[302,167],[313,158]],
41                         [[136,208],[121,206],[116,226],[128,233],[136,229],[137,209],[140,233]],
42                         [[160,207],[191,205]],
43                         [[176,184],[174,228],[180,238]],
44                         [[198,216],[187,223],[189,236],[200,242],[210,235],[209,224,'z']],
45                         [[227,216],[216,222],[216,236],[224,244],[237,240],[237,226,'z']],
46                         [[247,187],[249,241],[254,243]]
47                 ]
48                 for c in choose
49                         path = data: c, element: document.createElementNS svg_ns, "path"
50                         update_path path, close: c[c.length - 1][2] is 'z'
51                         svg.appendChild path.element
52                         @paths.push path
53                 @tip = $ "<span>&nbsp;</span>"
54                 @tool_options.append @tip
55         disable: ->
56                 super()
57                 for p in @paths
58                         svg.removeChild p.element
59
60 class DrawTool extends Tool
61         constructor: (args) ->
62                 super args
63                 @tool_options.append $ "<span>Draw tool helpers:</span>"
64                 @stop_button = $ '<span class="button" title="keyboard shortcut: space">finish line</span>'
65                 @stop_close_button = $ '<span class="button" title="keyboard shortcut: O">close (loop)</span>'
66                 @cancel_button = $ '<span class="button" title="keyboard shortcut: Esc">cancel line</span>'
67                 @tool_options.append @stop_button
68                 @tool_options.append @stop_close_button
69                 @tool_options.append @cancel_button
70                 @stop_button.click @stop_drawing.bind @
71                 @stop_close_button.click @stop_close_drawing.bind @
72                 @cancel_button.click @cancel_drawing.bind @
73                 @update_helper_buttons()
74         click: (x, y) ->
75                 if selection? and not selection.drawing?
76                         selection = null
77                 unless selection?
78                         path = document.createElementNS svg_ns, "path"
79                         selection = data: [], element: path, drawing: true
80                         svg.appendChild path
81                 selection.data.push [x, y]
82                 update_path selection
83                 @update_helper_buttons()
84         update_helper_buttons: ->
85                 if selection?.drawing? and selection?.data.length > 0
86                         @cancel_button.removeClass 'disabled'
87                 else
88                         @cancel_button.addClass 'disabled'
89                 if selection?.drawing? and selection?.data.length > 1
90                         @stop_button.removeClass 'disabled'
91                 else
92                         @stop_button.addClass 'disabled'
93                 if selection?.drawing? and selection?.data.length > 2
94                         @stop_close_button.removeClass 'disabled'
95                 else
96                         @stop_close_button.addClass 'disabled'
97         cancel_drawing: ->
98                 if selection?.drawing?
99                         svg.removeChild selection.element
100                 selection = null
101                 @update_helper_buttons()
102                 return false
103         stop_drawing: ->
104                 if selection?.drawing?
105                         if selection?.data.length < 2
106                                 return @cancel_drawing()
107                         update_path selection
108                 selection = null
109                 @update_helper_buttons()
110                 return false
111         stop_close_drawing: ->
112                 if selection?.drawing?
113                         if selection?.data.length < 3
114                                 return @stop_drawing()
115                         update_path selection, close: true
116                 selection = null
117                 @update_helper_buttons()
118                 return false
119         mousemove: (x, y) ->
120                 mouse.x = x
121                 mouse.y = y
122                 if selection?.drawing?
123                         update_path selection, to_mouse: true
124         keydown: (keycode) ->
125                 switch keycode
126                         when ('O'.charCodeAt 0), ('0'.charCodeAt 0)
127                                 return @stop_close_drawing()
128                         when (' '.charCodeAt 0), 13, 10
129                                 return @stop_drawing()
130                         when 27
131                                 return @cancel_drawing()
132         disable: ->
133                 super()
134                 @stop_drawing()
135                 if selection?.drawing?
136                         delete selection.drawing
137
138 class EditTool extends Tool
139         constructor: (args) ->
140                 super args
141                 args.tool_options.append $ "<span>Oops, the edit tool isn't implemented yet</span>"
142
143 class DeleteTool extends Tool
144         constructor: (args) ->
145                 super args
146                 args.tool_options.append $ "<span>To delete: click on a line below</span>"
147         click: (x, y) ->
148                 $svg.find('path:hover').remove()
149                 return false
150
151 update_path = (path, flags) ->
152         d = ''
153         sep = 'M'
154         for loc, i in path.data
155                 d += "#{sep} #{loc[0]} #{loc[1]}"
156                 sep = ' L'
157         if flags?.to_mouse?
158                 d += "#{sep} #{mouse.x} #{mouse.y}"
159         if flags?.close
160                 d += " z"
161         path.element.setAttribute "d", d
162
163 switch_to_tool = (tool_class) ->
164
165 # called automatically on domcontentloaded
166 init = ->
167         $container = $ '.crayon_mockup'
168         $toolbar = $ '<div class="toolbar"><span>Tools:</span></div>'
169         $tool_options = $ '<div class="tool_options"></div>'
170         $container.append $toolbar
171         $container.append $tool_options
172         svg = document.createElementNS svg_ns, 'svg'
173         svg.setAttribute 'width', width
174         svg.setAttribute 'height', height
175         svg.setAttribute 'viewBox', "0 0 #{width} #{height}"
176         $svg = $ svg
177         $container.append $svg
178
179         tool_buttons =
180                 tutorial: default: true, factory: TutorialTool
181                 draw: button_text: 'draw', factory: DrawTool
182                 edit: button_text: 'edit', factory: EditTool
183                 delete: button_text: 'delete', factory: DeleteTool
184         for k, t of tool_buttons
185                 if t.button_text?
186                         t.button = $ "<span class=\"button\"></span>"
187                         t.button.text t.button_text
188                         $toolbar.append t.button
189                 do (k, t) ->
190                         activate = ->
191                                 if cur_tool?
192                                         cur_tool.disable()
193                                         $container.removeClass "#{cur_tool_name}_tool"
194                                         ($toolbar.find '.button').removeClass 'disabled'
195                                 cur_tool_name = k
196                                 $container.addClass "#{cur_tool_name}_tool"
197                                 $tool_options.empty()
198                                 cur_tool = new t.factory button: t.button, tool_options: $tool_options
199                         if t.button?
200                                 t.button.click activate
201                         if t.default
202                                 activate()
203
204         $svg.mousedown (e) ->
205                 offset = $svg.offset()
206                 if cur_tool?
207                         return cur_tool.click e.pageX - offset.left, e.pageY - offset.top
208         $svg.mousemove (e) ->
209                 offset = $svg.offset()
210                 if cur_tool?
211                         return cur_tool.mousemove e.pageX - offset.left, e.pageY - offset.top
212         ($ document).keydown (e) ->
213                 if cur_tool?
214                         return cur_tool.keydown e.keyCode
215
216 $ init