| Index: elements/designer-selection/designer-selection.html
|
| diff --git a/elements/designer-selection/designer-selection.html b/elements/designer-selection/designer-selection.html
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..562f4f93d7a4aacb77d6d1c79723bb85ddd18fa4
|
| --- /dev/null
|
| +++ b/elements/designer-selection/designer-selection.html
|
| @@ -0,0 +1,216 @@
|
| +<!doctype html>
|
| +<html>
|
| + <head>
|
| + <link rel="import" href="../../../polymer/polymer.html">
|
| + <link rel="import" href="../../../neoprene/components/x-elements/x-template/x-template.html">
|
| + <script type="application/javascript" src="ResizeDirection.js"></script>
|
| + </head>
|
| + <body>
|
| +
|
| + <dom-module id="designer-selection">
|
| + <style>
|
| + designer-selection {
|
| + display: block;
|
| + position: absolute;
|
| + box-sizing: border-box;
|
| + }
|
| + designer-selection > #bounds {
|
| + position: absolute;
|
| + top: 0;
|
| + left: 0;
|
| + right: 0;
|
| + bottom: 0;
|
| + background: rgba(128, 128, 255, .5);
|
| + border: solid 1px #88f;
|
| + box-sizing: border-box;
|
| + }
|
| + designer-selection > .handle {
|
| + position: absolute;
|
| + box-sizing: border-box;
|
| + width: 8px;
|
| + height: 8px;
|
| + border: solid 1px #88f;
|
| + background: #fff;
|
| + }
|
| + designer-selection > .handle:hover {
|
| + background: #88f;
|
| + }
|
| + designer-selection > #top {
|
| + top: -4px;
|
| + left: calc(50% - 4px);
|
| + cursor: ns-resize;
|
| + }
|
| + designer-selection > #left {
|
| + top: calc(50% - 4px);
|
| + left: -4px;
|
| + cursor: ew-resize;
|
| + }
|
| + designer-selection > #bottom {
|
| + bottom: -4px;
|
| + left: calc(50% - 4px);
|
| + cursor: ns-resize;
|
| + }
|
| + designer-selection > #right {
|
| + top: calc(50% - 4px);
|
| + right: -4px;
|
| + cursor: ew-resize;
|
| + }
|
| + designer-selection > #top_left {
|
| + top: -4px;
|
| + left: -4px;
|
| + cursor: nwse-resize;
|
| + }
|
| + designer-selection > #top_right {
|
| + top: -4px;
|
| + right: -4px;
|
| + cursor: nesw-resize;
|
| + }
|
| + designer-selection > #bottom_left {
|
| + bottom: -4px;
|
| + left: -4px;
|
| + cursor: nesw-resize;
|
| + }
|
| + designer-selection > #bottom_right {
|
| + bottom: -4px;
|
| + right: -4px;
|
| + cursor: nwse-resize;
|
| + }
|
| + </style>
|
| + <template>
|
| + <div id="bounds"></div>
|
| + <template is="x-repeat" items="{{directions}}">
|
| + <div class="handle" id$="{{item.name}}"></div>
|
| + </template>
|
| + </template>
|
| + </dom-module>
|
| +
|
| + <script type="text/javascript">
|
| + Polymer({
|
| + is: 'designer-selection',
|
| +
|
| + created: function() {
|
| + this._onMove = null;
|
| + this._dragging = false;
|
| + this._offsetX = null;
|
| + this._offsetY = null;
|
| + this._onMouseMove_bound = this._onMouseMove.bind(this);
|
| + this._onMouseUp_bound = this._onMouseUp.bind(this);
|
| + this._resizeDirection = null;
|
| + },
|
| +
|
| + ready: function() {
|
| + this.directions = ResizeDirection.all_directions;
|
| + },
|
| +
|
| + listeners: {
|
| + 'mousedown': '_onMouseDown'
|
| + },
|
| +
|
| + _onMouseDown: function(e) {
|
| + if (e.target.id == 'bounds') {
|
| + this._boundsDown(e);
|
| + } else {
|
| + this._resizeHandleDown(e);
|
| + }
|
| + },
|
| +
|
| + _onMouseUp: function(e) {
|
| + this._stopDrag();
|
| + },
|
| +
|
| + _onMouseMove: function(e) {
|
| + if (this._onMove == null) {
|
| + throw new Error('<designer-selection> expected _onMove to ' +
|
| + 'be non-null');
|
| + }
|
| + var deltaX = e.clientX - this._offsetX;
|
| + var deltaY = e.clientY - this._offsetY;
|
| + this._onMove(deltaX, deltaY);
|
| + },
|
| +
|
| + // called for mousedown on the main bounding box div
|
| + _boundsDown: function(e) {
|
| + this.$.bounds.style.cursor = 'move';
|
| + this._startDrag(this._boundsMove, e.clientX - this.offsetLeft,
|
| + e.clientY - this.offsetTop);
|
| + },
|
| +
|
| + // [x], and [y] are relative to the offset passed to _startDrag
|
| + _boundsMove: function(x, y) {
|
| + var event = new CustomEvent('designer-selection-resize',
|
| + {detail: {
|
| + left: x,
|
| + top: y,
|
| + width: this.offsetWidth,
|
| + height: this.offsetHeight}});
|
| + this.dispatchEvent(event);
|
| + },
|
| +
|
| + // called for mousedown on one of the resize handle divs
|
| + _resizeHandleDown: function(e) {
|
| + var handle = e.target;
|
| + var direction = this._resizeDirection = ResizeDirection[handle.id];
|
| +
|
| + var boundsBounds = this.$.bounds.getBoundingClientRect();
|
| + var handleBounds = handle.getBoundingClientRect();
|
| +
|
| + var offsetLeft = direction.resizesLeft()
|
| + ? 0
|
| + : boundsBounds.left + (e.clientX - handleBounds.left);
|
| +
|
| + var offsetTop = direction.resizesTop()
|
| + ? 0
|
| + : boundsBounds.top + (e.clientY - handleBounds.top);
|
| +
|
| + this._startDrag(this._resizeHandleMove, offsetLeft, offsetTop);
|
| + },
|
| +
|
| + _resizeHandleMove: function(x, y) {
|
| + var direction = this._resizeDirection;
|
| +
|
| + // TODO: remember the right offset, rather than recalc each move
|
| + var newWidth =
|
| + direction.resizesLeft() ? this.offsetWidth + this.offsetLeft - x :
|
| + direction.resizesRight() ? x :
|
| + this.offsetWidth;
|
| +
|
| + var newHeight =
|
| + direction.resizesTop() ? this.offsetHeight + this.offsetTop - y :
|
| + direction.resizesBottom() ? y :
|
| + this.offsetHeight;
|
| +
|
| + var newLeft = direction.resizesLeft() ? x : this.offsetLeft;
|
| + var newTop = direction.resizesTop() ? y : this.offsetTop;
|
| +
|
| + var event = new CustomEvent('designer-selection-resize',
|
| + {detail: {
|
| + left: newLeft,
|
| + top: newTop,
|
| + width: newWidth,
|
| + height: newHeight}});
|
| + this.dispatchEvent(event);
|
| +
|
| + },
|
| +
|
| + _startDrag: function(onMove, offsetX, offsetY) {
|
| + this._dragging = true;
|
| + this._onMove = onMove;
|
| + this._offsetX = offsetX;
|
| + this._offsetY = offsetY;
|
| + window.addEventListener('mouseup', this._onMouseUp_bound);
|
| + window.addEventListener('mousemove', this._onMouseMove_bound);
|
| + },
|
| +
|
| + _stopDrag: function() {
|
| + this._dragging = false;
|
| + this._onMove = null;
|
| + this._offsetX = null;
|
| + this._offsetY = null;
|
| + window.removeEventListener('mouseup', this._onMouseUp_bound);
|
| + window.removeEventListener('mousemove', this._onMouseMove_bound);
|
| + this.$.bounds.style.cursor = 'auto';
|
| + }
|
| + });
|
| + </script>
|
| + </body>
|
| +</html>
|
|
|