JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
all 8 resize controls for box
[crayon_mockup.git] / main.coffee
index 48c001b..de2e86b 100644 (file)
@@ -46,6 +46,52 @@ json_to_svg = (json) ->
                                el.setAttribute k, v
        return el
 
+resizer_nw = (widget) ->
+       return (dxy) ->
+               widget.resize w: widget.width - dxy.x, h: widget.height - dxy.y
+               widget.move x: widget.x + dxy.x, y: widget.y + dxy.y
+resizer_n = (widget) ->
+       return (dxy) ->
+               widget.resize w: widget.width, h: widget.height - dxy.y
+               widget.move x: widget.x, y: widget.y + dxy.y
+resizer_ne = (widget) ->
+       return (dxy) ->
+               widget.resize w: widget.width + dxy.x, h: widget.height - dxy.y
+               widget.move x: widget.x, y: widget.y + dxy.y
+resizer_e = (widget) ->
+       return (dxy) ->
+               widget.resize w: widget.width + dxy.x, h: widget.height
+resizer_se = (widget) ->
+       return (dxy) ->
+               widget.resize w: widget.width + dxy.x, h: widget.height + dxy.y
+resizer_s = (widget) ->
+       return (dxy) ->
+               widget.resize w: widget.width, h: widget.height + dxy.y
+resizer_sw = (widget) ->
+       return (dxy) ->
+               widget.resize w: widget.width - dxy.x, h: widget.height + dxy.y
+               widget.move x: widget.x + dxy.x, y: widget.y
+resizer_w = (widget) ->
+       return (dxy) ->
+               widget.resize w: widget.width - dxy.x, h: widget.height
+               widget.move x: widget.x + dxy.x, y: widget.y
+resizers = [
+       resizer_nw
+       resizer_n
+       resizer_ne
+       resizer_e
+       resizer_se
+       resizer_s
+       resizer_sw
+       resizer_w
+]
+resizer_shapes = [
+       (xy) -> return "M#{@x - 5} #{@y - 5}h6l-2 2 4 4 2 -2v6h-6l2-2-4-4-2 2z"
+       (xy) -> return "M #{@x},#{@y - 7} l 4,4 -2.5,0 0,5 2.5,0 -4,4 -4,-4 2.5,0 0,-5 -2.5,0 z"
+       (xy) -> return "M#{@x + 5} #{@y - 5}v6l-2-2-4 4 2 2h-6v-6l2 2 4-4-2-2z"
+       (xy) -> return "M #{@x - 7},#{@y} l 4,-4 0,2.5 5,0 0,-2.5 4,4 -4,4 0,-2.5 -5,0 0,2.5 z"
+]
+
 next_widget_id = 0
 # public vars: x, y, width, height, el
 class Visible
@@ -96,18 +142,15 @@ class Control extends Visible
                dx = xy.x - @x
                dy = xy.y - @y
                return dx * dx + dy * dy
-
-class ControlNWSE extends Control
+class ControlPath extends Control
        constructor: (args) ->
                super args
                @css_class = 'control_point'
+               @make_path = args.shape
                @el = json_to_svg path:
                        d: @make_path()
                        class: 'control_point normal'
                @svg.appendChild @el
-       make_path: ->
-               # / return "M#{@x + 5} #{@y - 5}v6l-2-2-4 4 2 2h-6v-6l2 2 4-4-2-2z"
-               return "M#{@x - 5} #{@y - 5}h6l-2 2 4 4 2 -2v6h-6l2-2-4-4-2 2z"
        destruct: ->
                super()
                if @el?
@@ -129,7 +172,6 @@ class Widget extends Visible
        make_controls: -> # create controls, return them
                return []
        kill_controls: ->
-               console.log 'kill_controls'
                for c in @controls
                        c.destruct()
                @controls = []
@@ -170,6 +212,7 @@ class RectWidget extends Widget
                super args
                @el.setAttribute 'x', @x + 1
                @el.setAttribute 'y', @y + 1
+               @reposition_controls()
        proximity: (xy) -> # return the square of the distance to your visible bits
                x = xy.x
                y = xy.y
@@ -204,21 +247,42 @@ class RectWidget extends Widget
                @el.setAttribute 'width', @width - 2
                @height = wh.h
                @el.setAttribute 'height', @height - 2
+               @reposition_controls()
+       reposition_controls: ->
                if @controls.length > 1
-                       @controls[1].move x: @controls[1].x + dw, y: @controls[1].y + dh
+                       positions = @control_positions()
+                       for i in [0...positions.length]
+                               @controls[i].move x: positions[i].x, y: positions[i].y
+       control_positions: ->
+               gap = 7
+               mgap = 9
+               w2p = Math.floor(@width / 2) + 0.5
+               h2p = Math.floor(@height / 2) + 0.5
+               return [
+                       { x: @x - gap, y: @y - gap }
+                       { x: @x + w2p, y: @y - mgap }
+                       { x: @x + @width + gap, y: @y - gap }
+                       { x: @x + @width + mgap, y: @y + h2p }
+                       { x: @x + @width + gap, y: @y + @height + gap }
+                       { x: @x + w2p, y: @y + @height + mgap }
+                       { x: @x - gap, y: @y + @height + gap }
+                       { x: @x - mgap, y: @y + h2p }
+               ]
        make_controls: (args) -> # create controls, return them
-               console.log 'make_controls'
                if @controls.length > 0
-                       console.log "warning: re-adding controls"
+                       if console?.log?
+                               console.log "warning: re-adding controls"
                        @kill_controls()
-               w = @
-               @controls = [
-                       new ControlNWSE svg: @svg, x: @x - 7, y: @y - 7, done: args.done, drag: (dxy) ->
-                               w.resize w: w.width - dxy.x, h: w.height - dxy.y
-                               w.move x: w.x + dxy.x, y: w.y + dxy.y
-                       new ControlNWSE svg: @svg, x: @x + @width + 7, y: @y + @height + 7, done: args.done, drag: (dxy) ->
-                               w.resize w: w.width + dxy.x, h: w.height + dxy.y
-               ]
+               positions = @control_positions()
+               for i in [0...positions.length]
+                       @controls.push new ControlPath {
+                               svg: @svg
+                               x: positions[i].x
+                               y: positions[i].y
+                               done: args.done
+                               drag: resizers[i] @
+                               shape: resizer_shapes[i % resizer_shapes.length]
+                       }
                return @controls
 
 # called automatically on domcontentloaded
@@ -361,7 +425,6 @@ init = ->
                        dragging = true
                        drag_layer = hit.layer
                        drag_from = xy
-                       console.log hit
                else
                        deselect_all widget_layer
                return