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
10 svg_ns = 'http://www.w3.org/2000/svg'
13 mouse = x: 0, y: 0, buttons: [0,0,0]
18 click_proximity: (x, y) ->
27 class PolyLine extends EditableThing
28 constructor: (args) ->
30 @drawing = args?.drawing ? false
31 @el = document.createElementNS svg_ns, "path"
33 @points = args?.points ? []
37 @drawing = args.drawing
42 d += l = "#{sep} #{loc[0]} #{loc[1]}"
45 d += l = "#{sep} #{args.mouse_x} #{args.mouse_y}"
46 if args?.close # FIXME ?remove
49 if l is " L #{@points[0][0]} #{@points[0][1]}"
50 d = d.substr 0, d.length - l.length
52 @el.setAttribute "d", d
57 @add_point @points[0][0], @points[0][1]
60 constructor: (args) ->
63 @button.addClass 'disabled'
64 @tool_options = args.tool_options
70 @button.removeClass 'disabled'
73 class TutorialTool extends Tool
74 constructor: (args) ->
78 [[219,34],[53,141],[96,143],[92,255],[365,257],[362,145],[407,144,'z']],
79 [[161,118],[144,106],[130,115],[128,152],[140,160],[156,150]],
80 [[173,107],[169,159],[180,137],[189,133],[193,160]],
81 [[218,135],[205,144],[205,158],[215,164],[225,156],[225,144,'z']],
82 [[242,135],[233,145],[233,157],[244,168],[256,158],[254,144,'z']],
83 [[278,141],[269,135],[261,142],[264,151],[278,153],[281,162],[271,170],[264,163]],
84 [[291,151],[305,151],[312,143],[299,135],[288,140],[293,160],[302,167],[313,158]],
85 [[136,208],[121,206],[116,226],[128,233],[136,229],[137,209],[140,233]],
86 [[160,207],[191,205]],
87 [[176,184],[174,228],[180,238]],
88 [[198,216],[187,223],[189,236],[200,242],[210,235],[209,224,'z']],
89 [[227,216],[216,222],[216,236],[224,244],[237,240],[237,226,'z']],
90 [[247,187],[249,241],[254,243]]
93 path = data: c, element: document.createElementNS svg_ns, "path"
94 update_path path, close: c[c.length - 1][2] is 'z'
95 svg.appendChild path.element
97 @tip = $ "<span> </span>"
98 @tool_options.append @tip
102 svg.removeChild p.element
104 class DrawTool extends Tool
105 constructor: (args) ->
107 @tool_options.append $ "<span>Draw tool helpers:</span>"
108 @stop_button = $ '<span class="button" title="keyboard shortcut: space">finish line</span>'
109 @stop_close_button = $ '<span class="button" title="keyboard shortcut: O">close (loop)</span>'
110 @cancel_button = $ '<span class="button" title="keyboard shortcut: Esc">cancel line</span>'
111 @tool_options.append @stop_button
112 @tool_options.append @stop_close_button
113 @tool_options.append @cancel_button
114 @stop_button.click @stop_drawing.bind @
115 @stop_close_button.click @stop_close_drawing.bind @
116 @cancel_button.click @cancel_drawing.bind @
117 @update_helper_buttons()
119 if selection.length and not selection[0].drawing?
121 unless selection.length
122 selection.push new PolyLine drawing: true
123 selection[0].add_point x, y
124 selection[0].update()
125 @update_helper_buttons()
126 update_helper_buttons: ->
127 if selection[0]?.drawing? and selection[0]?.points.length > 0
128 @cancel_button.removeClass 'disabled'
130 @cancel_button.addClass 'disabled'
131 if selection[0]?.drawing? and selection[0]?.points.length > 1
132 @stop_button.removeClass 'disabled'
134 @stop_button.addClass 'disabled'
135 if selection[0]?.drawing? and selection[0]?.points.length > 2
136 @stop_close_button.removeClass 'disabled'
138 @stop_close_button.addClass 'disabled'
140 if selection[0]?.drawing?
141 selection[0].destructor()
143 @update_helper_buttons()
146 if selection[0]?.drawing?
147 if selection[0]?.points.length < 2
148 return @cancel_drawing()
150 selection[0].update()
152 @update_helper_buttons()
154 stop_close_drawing: ->
155 if selection[0]?.drawing?
156 if selection[0]?.points.length < 3
157 return @stop_drawing()
158 selection[0].close_loop()
159 selection[0].update drawing: false
161 @update_helper_buttons()
166 if selection[0]?.drawing?
167 selection[0].update to_mouse: true, mouse_x: x, mouse_y: y
168 keydown: (keycode) ->
170 when ('O'.charCodeAt 0), ('0'.charCodeAt 0)
171 return @stop_close_drawing()
172 when (' '.charCodeAt 0), 13, 10
173 return @stop_drawing()
175 return @cancel_drawing()
180 class EditTool extends Tool
181 constructor: (args) ->
183 args.tool_options.append $ "<span>Oops, the edit tool isn't implemented yet</span>"
185 class DeleteTool extends Tool
186 constructor: (args) ->
188 args.tool_options.append $ "<span>To delete: click on a line below</span>"
190 $svg.find('path:hover').remove()
193 update_path = (path, flags) ->
196 for loc, i in path.data
197 d += "#{sep} #{loc[0]} #{loc[1]}"
200 d += "#{sep} #{mouse.x} #{mouse.y}"
203 path.element.setAttribute "d", d
205 switch_to_tool = (tool_class) ->
207 # json (compiled to javascript and minified) is ~8% smaller than the resulting xml
208 json_to_svg = (json) ->
209 for tag, attrs of json
210 el = document.createElementNS svg_ns, tag
214 el.appendChild json_to_svg child
219 # called automatically on domcontentloaded
221 $container = $ '.crayon_mockup'
222 $toolbar = $ '<div class="toolbar"><span>Tools:</span></div>'
223 $tool_options = $ '<div class="tool_options"></div>'
224 $container.append $toolbar
225 $container.append $tool_options
226 svg = json_to_svg svg: width: width, height: height, viewBox: "0 0 #{width} #{height}"
228 $container.append $svg
229 svg.appendChild json_to_svg filter:
230 id: 'crayon', filterUnits: 'userSpaceOnUse'
231 x: '-5%', y: '-5%', height: '110%', width: '110%'
233 { feTurbulence: baseFrequency: '.3', numOctaves: '2', type: 'fractalNoise' }
234 { feDisplacementMap: scale: '6', xChannelSelector: 'R', in: 'SourceGraphic' }
238 tutorial: default: true, factory: TutorialTool
239 draw: button_text: 'draw', factory: DrawTool
240 edit: button_text: 'edit', factory: EditTool
241 delete: button_text: 'delete', factory: DeleteTool
242 for k, t of tool_buttons
244 t.button = $ "<span class=\"button\"></span>"
245 t.button.text t.button_text
246 $toolbar.append t.button
251 $container.removeClass "#{cur_tool_name}_tool"
252 ($toolbar.find '.button').removeClass 'disabled'
254 $container.addClass "#{cur_tool_name}_tool"
255 $tool_options.empty()
256 cur_tool = new t.factory button: t.button, tool_options: $tool_options
258 t.button.click activate
262 $svg.mousedown (e) ->
263 offset = $svg.offset()
265 mouse_x = Math.round(e.pageX - offset.left)
266 mouse_y = Math.round(e.pageY - offset.top)
267 return cur_tool.click mouse_x, mouse_y
268 $svg.mousemove (e) ->
269 offset = $svg.offset()
271 mouse_x = Math.round(e.pageX - offset.left)
272 mouse_y = Math.round(e.pageY - offset.top)
273 return cur_tool.mousemove mouse_x, mouse_y
274 ($ document).keydown (e) ->
276 return cur_tool.keydown e.keyCode