Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(314)

Side by Side Diff: elements/designer-selection/designer-selection.html

Issue 877243005: Add designer-selection element (Closed) Base URL: https://github.com/PolymerLabs/designer2.git@master
Patch Set: Move style outside template Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« bower.json ('K') | « elements/designer-selection/demo.html ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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 </head>
7 <body>
8
9 <dom-module id="designer-selection">
10 <style>
11 designer-selection {
12 display: block;
13 position: absolute;
14 box-sizing: border-box;
15 }
16 designer-selection > #bounds {
17 position: absolute;
18 top: 0;
19 left: 0;
20 right: 0;
21 bottom: 0;
22 background: rgba(128, 128, 255, .5);
23 border: solid 1px #88f;
imac 2015/02/05 03:18:33 do you want border-box here?
justinfagnani 2015/02/05 20:15:54 Done.
24 }
25 designer-selection > .handle {
26 position: absolute;
27 box-sizing: border-box;
28 width: 8px;
29 height: 8px;
30 border: solid 1px #88f;
31 background: #fff;
32 }
33 designer-selection > .handle:hover {
34 background: #88f;
35 }
36 designer-selection > #top {
37 top: -4px;
38 left: calc(50% - 4px);
39 cursor: ns-resize;
40 }
41 designer-selection > #left {
42 top: calc(50% - 4px);
43 left: -4px;
44 cursor: ew-resize;
45 }
46 designer-selection > #bottom {
47 bottom: -4px;
48 left: calc(50% - 4px);
49 cursor: ns-resize;
50 }
51 designer-selection > #right {
52 top: calc(50% - 4px);
53 right: -4px;
54 cursor: ew-resize;
55 }
56 designer-selection > #top_left {
57 top: -4px;
58 left: -4px;
59 cursor: nwse-resize;
60 }
61 designer-selection > #top_right {
62 top: -4px;
63 right: -4px;
64 cursor: nesw-resize;
65 }
66 designer-selection > #bottom_left {
67 bottom: -4px;
68 left: -4px;
69 cursor: nesw-resize;
70 }
71 designer-selection > #bottom_right {
72 bottom: -4px;
73 right: -4px;
74 cursor: nwse-resize;
75 }
76 </style>
77 <template>
78 <div id="bounds"></div>
79 <template is="x-repeat" items="{{directions}}">
80 <div class="handle" id$="{{item.name}}"></div>
81 </template>
82 </template>
83 </dom-module>
84
85 <script type="text/javascript">
86 function ResizeDirection(name, x, y) {
87 this.name = name;
88 this.x = x;
89 this.y = y;
90 }
91
92 ResizeDirection.prototype.toString = function() {
93 return 'ResizeDirection(' + this.name + ', ' + this.x + ', ' + this.y + ')';
94 };
imac 2015/02/05 03:18:33 Yay!
justinfagnani 2015/02/05 20:15:54 Done.
95
96 ResizeDirection.prototype.locate = function(rect) {
97 return {
98 x: rect.left + rect.width * this.x,
99 y: rect.top + rect.height * this.y
100 };
101 };
102
103 ResizeDirection.prototype.resizesLeft = function() {
104 return this.x == 0.0;
105 },
106
107 ResizeDirection.prototype.resizesRight = function() {
108 return this.x == 1.0;
109 },
110
111 ResizeDirection.prototype.resizesTop = function() {
112 return this.y == 0.0;
113 },
114
115 ResizeDirection.prototype.resizesBottom = function() {
116 return this.y == 1.0;
117 },
118
119 (function () {
120 var top = ResizeDirection.top = new ResizeDirection('top', 0.5, 0.0);
121 var left = ResizeDirection.left = new ResizeDirection('left', 0.0, 0.5);
122 var bottom = ResizeDirection.bottom = new ResizeDirection('bottom', 0.5, 1.0);
123 var right = ResizeDirection.right = new ResizeDirection('right', 1.0, 0. 5);
124 var top_left = ResizeDirection.top_left = new ResizeDirection('top_left' , 0.0, 0.0);
125 var top_right = ResizeDirection.top_right = new ResizeDirection('top_rig ht', 1.0, 0.0);
126 var bottom_left = ResizeDirection.bottom_left = new ResizeDirection('bot tom_left', 0.0, 1.0);
127 var bottom_right = ResizeDirection.bottom_right = new ResizeDirection('b ottom_right', 1.0, 1.0);
imac 2015/02/05 03:18:33 these should probably be ALL_CAPS (constants), or
justinfagnani 2015/02/05 20:15:54 I'll do camel case, I don't find ALL_CAPS to conve
128
129 ResizeDirection.all_directions = [top, left, bottom, right, top_left, to p_right, bottom_left, bottom_right];
130 ResizeDirection.width_height = [bottom, right, bottom_right];
131 })();
imac 2015/02/05 03:18:33 consider moving ResizeDirection out to a separate
justinfagnani 2015/02/05 20:15:54 Done.
132
133 Polymer({
134 is: 'designer-selection',
135
136 created: function() {
137 this._onMove = null;
138 this._dragging = false;
139 this._offsetX = null;
140 this._offsetY = null;
141 this._onMouseMove_bound = this._onMouseMove.bind(this);
142 this._onMouseUp_bound = this._onMouseUp.bind(this);
143 this._resizeDirection = null;
144 },
145
146 ready: function() {
147 this.directions = ResizeDirection.all_directions;
148 },
149
150 listeners: {
151 'mousedown': '_onMouseDown'
152 },
153
154 _onMouseDown: function(e) {
155 if (e.target.id == 'bounds') {
156 this._boundsDown(e);
157 } else {
158 this._handleDown(e);
159 }
160 },
161
162 _onMouseUp: function(e) {
163 this._stopDrag();
164 },
165
166 _onMouseMove: function(e) {
167 if (this._onMove != null) {
imac 2015/02/05 03:18:33 this feels like it should be an assert
justinfagnani 2015/02/05 20:15:54 Done.
168 var deltaX = e.clientX - this._offsetX;
169 var deltaY = e.clientY - this._offsetY;
170 this._onMove(deltaX, deltaY);
171 }
172 },
173
174 // called for mousedown on the main bounding box div
175 _boundsDown: function(e) {
176 this.$.bounds.style.cursor = 'move';
imac 2015/02/05 03:18:33 wouldn't you want the cursor to always be this to
justinfagnani 2015/02/05 20:15:54 I'm not totally sure, you should also be able to c
177 this._startDrag(this._boundsMove, e.clientX - this.offsetLeft, e.clien tY - this.offsetTop);
178 },
179
180 // [x], and [y] are relative to the offset passed to _startDrag
181 _boundsMove: function(x, y) {
182 var event = new CustomEvent('designer-selection-resize',
183 {detail: {
184 left: x,
185 top: y,
186 width: this.offsetWidth,
187 height: this.offsetHeight}});
188 this.dispatchEvent(event);
189 },
190
191 // called for mousedown on one of the resize handle divs
192 _handleDown: function(e) {
imac 2015/02/05 03:18:33 _resizeDown/_resizeMove would be clearer, I think
justinfagnani 2015/02/05 20:15:54 _resizeHandleDown is the most clear!
imac 2015/02/06 20:26:31 Most clearerer!
justinfagnani 2015/02/06 23:46:39 Acknowledged.
193 var handle = e.target;
194 var direction = this._resizeDirection = ResizeDirection[handle.id];
195
196 var boundsBounds = this.$.bounds.getBoundingClientRect();
imac 2015/02/05 03:18:33 http://vimeo.com/87712359
justinfagnani 2015/02/05 20:15:54 Acknowledged.
197 var handleBounds = handle.getBoundingClientRect();
198
199 var offsetLeft = direction.resizesLeft()
200 ? 0
201 : boundsBounds.left + (e.clientX - handleBounds.left);
imac 2015/02/05 03:18:33 I'm confused, why does the position of the handle
justinfagnani 2015/02/05 20:15:54 This prevents a jump on first move by the amount t
202
203 var offsetTop = direction.resizesTop()
204 ? 0
205 : boundsBounds.top + (e.clientY - handleBounds.top);
206
207 this._startDrag(this._handleMove, offsetLeft, offsetTop);
208 },
209
210 _handleMove: function(x, y) {
211 var direction = this._resizeDirection;
212
213 var newWidth =
214 direction.resizesLeft() ? this.offsetWidth + this.offsetLeft - x :
imac 2015/02/05 03:18:33 Rather than having to calculate offsetLeft/Top eac
justinfagnani 2015/02/05 20:15:54 Yeah, this.offsetWidth + this.offsetLeft is what I
imac 2015/02/06 20:26:31 Hmm, I mean that you shouldn't need to refer to th
justinfagnani 2015/02/06 23:46:39 Yes, but I want to restructure this so I don't hav
215 direction.resizesRight() ? x :
216 this.offsetWidth;
217
218 var newHeight =
219 direction.resizesTop() ? this.offsetHeight + this.offsetTop - y :
220 direction.resizesBottom() ? y :
221 this.offsetHeight;
222
223 var newLeft = direction.resizesLeft() ? x : this.offsetLeft;
224 var newTop = direction.resizesTop() ? y : this.offsetTop;
225
226 var event = new CustomEvent('designer-selection-resize',
227 {detail: {
228 left: newLeft,
229 top: newTop,
230 width: newWidth,
231 height: newHeight}});
232 this.dispatchEvent(event);
233
234 },
235
236 _startDrag: function(onMove, offsetX, offsetY) {
237 this._dragging = true;
238 this._onMove = onMove;
239 this._offsetX = offsetX;
240 this._offsetY = offsetY;
241 window.addEventListener('mouseup', this._onMouseUp_bound);
242 window.addEventListener('mousemove', this._onMouseMove_bound);
243 },
244
245 _stopDrag: function() {
246 this._dragging = false;
247 this._onMove = null;
248 this._offsetX = null;
249 this._offsetY = null;
250 window.removeEventListener('mouseup', this._onMouseUp_bound);
251 window.removeEventListener('mousemove', this._onMouseMove_bound);
252 this.$.bounds.style.cursor = 'auto';
253 }
254 });
255 </script>
256 </body>
257 </html>
OLDNEW
« bower.json ('K') | « elements/designer-selection/demo.html ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698