5 CLICK_FUZ = 10 # this far away from things is close enough to be "clicked on"
6 PROX_MAX = CLICK_FUZ * CLICK_FUZ
15 # json (compiled to javascript and minified) is ~8% smaller than the resulting xml
16 json_to_svg = (json) ->
17 for tag, attrs of json
18 el = document.createElementNS 'http://www.w3.org/2000/svg', tag
22 el.appendChild json_to_svg child
28 # public vars: x, y, width, height, el
31 constructor: (args) ->
35 @style = args.style ? STYLE_NORMAL
38 @width = args.width ? 50
39 @height = args.height ? 34
46 proximity: (xy) -> # return the square of the distance to your visible bits
49 return if @style is style
50 if style is STYLE_NORMAL
51 @el.setAttribute 'style', 'filter: url(#crayon)'
53 if @style is STYLE_NORMAL
54 @el.setAttribute 'style', ''
57 @el.setAttribute 'class', "#{@css_class}"
59 @el.setAttribute 'class', "#{@css_class} selected"
61 @el.setAttribute 'class', "#{@css_class} hover"
63 @el.setAttribute 'class', "#{@css_class} dragging"
64 # FIXME when STYLE_EDITING
66 controls: -> # create controls, return them
70 class RectWidget extends Widget
71 constructor: (args) ->
74 @el = json_to_svg rect:
80 style: if @style is STYLE_NORMAL then 'filter: url(#crayon)' else ''
87 return new RectWidget @
90 @el.setAttribute 'x', @x + 1
91 @el.setAttribute 'y', @y + 1
92 proximity: (xy) -> # return the square of the distance to your visible bits
98 if x > @x - CLICK_FUZ and x < @x + @width + CLICK_FUZ
100 if y < @y + @height / 2
103 new_prox = @y + @height - y
107 if y > @y - CLICK_FUZ and y < @y + @height + CLICK_FUZ
109 if x < @x + @width / 2
112 new_prox = @x + @width - x
116 if in_x and in_y and prox > PROX_MAX
119 controls: -> # create controls, return them
123 # called automatically on domcontentloaded
126 $container = $ '.crayon_mockup'
127 svg = json_to_svg svg: width: width, height: height, viewBox: "0 0 #{width} #{height}"
129 $container.append $svg
130 svg.appendChild json_to_svg filter:
131 id: 'crayon', filterUnits: 'userSpaceOnUse'
132 x: '-5%', y: '-5%', height: '110%', width: '110%'
134 { feTurbulence: baseFrequency: '.3', numOctaves: '2', type: 'fractalNoise' }
135 { feDisplacementMap: scale: '6', xChannelSelector: 'R', in: 'SourceGraphic' }
138 # create canvas border
139 svg.appendChild json_to_svg rect:
143 height: height - 2 - supply_height
144 class: 'canvas_border'
148 { width: 40, height: 40 }
149 { width: 12, height: 50 }
150 { width: 70, height: 12 }
152 widget = new RectWidget {
155 x: 30 + i * 90 + (70 - args.width) / 2
156 y: (supply_height - args.height) / 2
159 supply[widget.id] = widget
164 editing = {} # has controls
166 drag_from = x: 0, y: 0 # mouse was here at last frame of drag
167 shift_key_down = false
169 deselect_all = (args) ->
170 except = args?.except ? null
171 for id, w of selected
172 w.set_style STYLE_NORMAL
174 closest_widget = (widgets, xy) ->
178 new_prox = w.proximity xy
185 svg_event_to_xy = (e) ->
187 svg_offset = $svg.offset()
189 x: Math.round(e.pageX - svg_offset.left)
190 y: Math.round(e.pageY - svg_offset.top)
194 if dragging # two mousedowns in a row?! it happens
196 xy = svg_event_to_xy e
197 if xy.y < supply_height
198 closest = closest_widget supply, xy
200 closest = closest.clone()
201 on_canvas[closest.id] = closest
203 closest = closest_widget on_canvas, xy
205 unless (shift_key_down or selected[closest.id]?)
206 deselect_all except: closest
207 selected[closest.id] = closest
208 closest.set_style STYLE_DRAGGING
217 for id, w of selected
218 if w.y < supply_height
222 w.set_style STYLE_SELECTED
227 xy = svg_event_to_xy e
229 return if drag_from.x is xy.x and drag_from.y is xy.y
230 rel_x = xy.x - drag_from.x
231 rel_y = xy.y - drag_from.y
233 for id, w of selected
234 w.move x: w.x + rel_x, y: w.y + rel_y
236 hover = closest_widget on_canvas, xy
238 hover = closest_widget supply, xy
239 if hover != prev_hover
242 if selected[prev_hover.id]?
243 prev_hover.set_style STYLE_SELECTED
245 prev_hover.set_style STYLE_NORMAL
247 hover.set_style STYLE_HOVER
250 $svg.mousedown mousedown
252 $svg.mousemove mousemove
253 $(document).on 'keyup keydown', (e) ->
254 shift_key_down = e.shiftKey
256 #($ document).keydown (e) ->