| OLD | NEW |
| (Empty) | |
| 1 <!doctype html> |
| 2 <html> |
| 3 <head> |
| 4 <link rel="import" href="../../../polymer/polymer.html"> |
| 5 <link rel="import" href="../../../neoprene/components/x-elements/x-template/
x-template.html"> |
| 6 <script type="application/javascript" src="ResizeDirection.js"></script> |
| 7 </head> |
| 8 <body> |
| 9 |
| 10 <dom-module id="designer-selection"> |
| 11 <style> |
| 12 designer-selection { |
| 13 display: block; |
| 14 position: absolute; |
| 15 box-sizing: border-box; |
| 16 } |
| 17 designer-selection > #bounds { |
| 18 position: absolute; |
| 19 top: 0; |
| 20 left: 0; |
| 21 right: 0; |
| 22 bottom: 0; |
| 23 background: rgba(128, 128, 255, .5); |
| 24 border: solid 1px #88f; |
| 25 box-sizing: border-box; |
| 26 } |
| 27 designer-selection > .handle { |
| 28 position: absolute; |
| 29 box-sizing: border-box; |
| 30 width: 8px; |
| 31 height: 8px; |
| 32 border: solid 1px #88f; |
| 33 background: #fff; |
| 34 } |
| 35 designer-selection > .handle:hover { |
| 36 background: #88f; |
| 37 } |
| 38 designer-selection > #top { |
| 39 top: -4px; |
| 40 left: calc(50% - 4px); |
| 41 cursor: ns-resize; |
| 42 } |
| 43 designer-selection > #left { |
| 44 top: calc(50% - 4px); |
| 45 left: -4px; |
| 46 cursor: ew-resize; |
| 47 } |
| 48 designer-selection > #bottom { |
| 49 bottom: -4px; |
| 50 left: calc(50% - 4px); |
| 51 cursor: ns-resize; |
| 52 } |
| 53 designer-selection > #right { |
| 54 top: calc(50% - 4px); |
| 55 right: -4px; |
| 56 cursor: ew-resize; |
| 57 } |
| 58 designer-selection > #top_left { |
| 59 top: -4px; |
| 60 left: -4px; |
| 61 cursor: nwse-resize; |
| 62 } |
| 63 designer-selection > #top_right { |
| 64 top: -4px; |
| 65 right: -4px; |
| 66 cursor: nesw-resize; |
| 67 } |
| 68 designer-selection > #bottom_left { |
| 69 bottom: -4px; |
| 70 left: -4px; |
| 71 cursor: nesw-resize; |
| 72 } |
| 73 designer-selection > #bottom_right { |
| 74 bottom: -4px; |
| 75 right: -4px; |
| 76 cursor: nwse-resize; |
| 77 } |
| 78 </style> |
| 79 <template> |
| 80 <div id="bounds"></div> |
| 81 <template is="x-repeat" items="{{directions}}"> |
| 82 <div class="handle" id$="{{item.name}}"></div> |
| 83 </template> |
| 84 </template> |
| 85 </dom-module> |
| 86 |
| 87 <script type="text/javascript"> |
| 88 Polymer({ |
| 89 is: 'designer-selection', |
| 90 |
| 91 created: function() { |
| 92 this._onMove = null; |
| 93 this._dragging = false; |
| 94 this._offsetX = null; |
| 95 this._offsetY = null; |
| 96 this._onMouseMove_bound = this._onMouseMove.bind(this); |
| 97 this._onMouseUp_bound = this._onMouseUp.bind(this); |
| 98 this._resizeDirection = null; |
| 99 }, |
| 100 |
| 101 ready: function() { |
| 102 this.directions = ResizeDirection.all_directions; |
| 103 }, |
| 104 |
| 105 listeners: { |
| 106 'mousedown': '_onMouseDown' |
| 107 }, |
| 108 |
| 109 _onMouseDown: function(e) { |
| 110 if (e.target.id == 'bounds') { |
| 111 this._boundsDown(e); |
| 112 } else { |
| 113 this._resizeHandleDown(e); |
| 114 } |
| 115 }, |
| 116 |
| 117 _onMouseUp: function(e) { |
| 118 this._stopDrag(); |
| 119 }, |
| 120 |
| 121 _onMouseMove: function(e) { |
| 122 if (this._onMove == null) { |
| 123 throw new Error('<designer-selection> expected _onMove to ' + |
| 124 'be non-null'); |
| 125 } |
| 126 var deltaX = e.clientX - this._offsetX; |
| 127 var deltaY = e.clientY - this._offsetY; |
| 128 this._onMove(deltaX, deltaY); |
| 129 }, |
| 130 |
| 131 // called for mousedown on the main bounding box div |
| 132 _boundsDown: function(e) { |
| 133 this.$.bounds.style.cursor = 'move'; |
| 134 this._startDrag(this._boundsMove, e.clientX - this.offsetLeft, |
| 135 e.clientY - this.offsetTop); |
| 136 }, |
| 137 |
| 138 // [x], and [y] are relative to the offset passed to _startDrag |
| 139 _boundsMove: function(x, y) { |
| 140 var event = new CustomEvent('designer-selection-resize', |
| 141 {detail: { |
| 142 left: x, |
| 143 top: y, |
| 144 width: this.offsetWidth, |
| 145 height: this.offsetHeight}}); |
| 146 this.dispatchEvent(event); |
| 147 }, |
| 148 |
| 149 // called for mousedown on one of the resize handle divs |
| 150 _resizeHandleDown: function(e) { |
| 151 var handle = e.target; |
| 152 var direction = this._resizeDirection = ResizeDirection[handle.id]; |
| 153 |
| 154 var boundsBounds = this.$.bounds.getBoundingClientRect(); |
| 155 var handleBounds = handle.getBoundingClientRect(); |
| 156 |
| 157 var offsetLeft = direction.resizesLeft() |
| 158 ? 0 |
| 159 : boundsBounds.left + (e.clientX - handleBounds.left); |
| 160 |
| 161 var offsetTop = direction.resizesTop() |
| 162 ? 0 |
| 163 : boundsBounds.top + (e.clientY - handleBounds.top); |
| 164 |
| 165 this._startDrag(this._resizeHandleMove, offsetLeft, offsetTop); |
| 166 }, |
| 167 |
| 168 _resizeHandleMove: function(x, y) { |
| 169 var direction = this._resizeDirection; |
| 170 |
| 171 // TODO: remember the right offset, rather than recalc each move |
| 172 var newWidth = |
| 173 direction.resizesLeft() ? this.offsetWidth + this.offsetLeft - x : |
| 174 direction.resizesRight() ? x : |
| 175 this.offsetWidth; |
| 176 |
| 177 var newHeight = |
| 178 direction.resizesTop() ? this.offsetHeight + this.offsetTop - y : |
| 179 direction.resizesBottom() ? y : |
| 180 this.offsetHeight; |
| 181 |
| 182 var newLeft = direction.resizesLeft() ? x : this.offsetLeft; |
| 183 var newTop = direction.resizesTop() ? y : this.offsetTop; |
| 184 |
| 185 var event = new CustomEvent('designer-selection-resize', |
| 186 {detail: { |
| 187 left: newLeft, |
| 188 top: newTop, |
| 189 width: newWidth, |
| 190 height: newHeight}}); |
| 191 this.dispatchEvent(event); |
| 192 |
| 193 }, |
| 194 |
| 195 _startDrag: function(onMove, offsetX, offsetY) { |
| 196 this._dragging = true; |
| 197 this._onMove = onMove; |
| 198 this._offsetX = offsetX; |
| 199 this._offsetY = offsetY; |
| 200 window.addEventListener('mouseup', this._onMouseUp_bound); |
| 201 window.addEventListener('mousemove', this._onMouseMove_bound); |
| 202 }, |
| 203 |
| 204 _stopDrag: function() { |
| 205 this._dragging = false; |
| 206 this._onMove = null; |
| 207 this._offsetX = null; |
| 208 this._offsetY = null; |
| 209 window.removeEventListener('mouseup', this._onMouseUp_bound); |
| 210 window.removeEventListener('mousemove', this._onMouseMove_bound); |
| 211 this.$.bounds.style.cursor = 'auto'; |
| 212 } |
| 213 }); |
| 214 </script> |
| 215 </body> |
| 216 </html> |
| OLD | NEW |