diff -r de5736883786 -r f912b591e1c1 src_js/iconolab-bundle/src/components/cutout/shape-resizer.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src_js/iconolab-bundle/src/components/cutout/shape-resizer.js Fri Aug 19 19:04:26 2016 +0200 @@ -0,0 +1,159 @@ +/* Enabling us to resize a shape width a handler + #http://stackoverflow.com/questions/32390028/how-to-drag-and-resize-svg-rectangle-using-cursor-types +*/ +import { eventEmitter } from "../utils" + +var ShapeResizer = function (paper, shape, vp, vb) { + this.paper = paper; + this.shape = shape; + this.handlers = []; + this.viewPort = vp; + this.viewBox = vb; + this.isResizing = false; + this.currentPosition = {}; + this.HANDLER_SIZE = 8; + this.SHAPE_MIN_SIZE = 20; + this.states = {}; + this.noop = function (){} + this.init(); +} + +var api = ShapeResizer.prototype = { + + init: function () { + this.showHandlers(); + + }, + + computeHandlerSize: function () { + return this.HANDLER_SIZE * (Math.min(this.viewBox[2], this.viewBox[3])) / this.viewPort.width; //w==h + }, + + showHandlers: function () { + /* show handler here */ + var bbox = this.shape.getBBox(); + var handleX = bbox.x - (this.computeHandlerSize()/2); + var handleY = bbox.y - (this.computeHandlerSize()/2); + var handler = this.paper.rect(handleX, handleY, this.computeHandlerSize(), this.computeHandlerSize()).attr({fill: 'red'}); + handler.addClass("drawingHandler"); + this.shape.addClass("drawingHandler"); + var handlerInfos = {position: "t_r", handler: handler}; + this.handlers.push(handlerInfos); + this.shapesGroup = this.paper.g(this.shape, handler); + this.attachEvents(); + }, + + /*one handlers */ + updateShapePositions: function (handlerData, dx, dy) { + //start + var handlerBBox = handlerData.handler.getBBox(); + var shapeBBox = this.shape.data("origBbox"); + var newX = handlerBBox.x + (this.computeHandlerSize() / 2); + var newY = handlerBBox.y + (this.computeHandlerSize() / 2); + + /*to the right => reduce the size */ + var newWidth = (dx > 0) ? shapeBBox.width - dx : shapeBBox.width + Math.abs(dx); + var newHeight = (dy > 0) ? shapeBBox.height - dy : shapeBBox.height + Math.abs(dy); + + var transformValue = this.shape.data('origTransform') + (this.shape.data('origTransform') ? "T" : "t") + [dx, dy]; + this.shape.attr({'transform': transformValue, width: newWidth, height: newHeight}); + }, + + dragEvents: { + onStart: function (handlerData, dx, dy, e) { + this.startPosition = {x: e.clientX, y: e.clientY}; + this.isResizing = true; + this.currentPosition = {}; + handlerData.handler.data("origTransform", handlerData.handler.transform().local); + this.shape.data("origBbox", this.shape.getBBox()); + this.shape.data("origBounding", this.shape.node.getBoundingClientRect()); + this.shape.data("origTransform", this.shape.transform().local); + }, + + onMove: function (handlerData, dx, dy, x, y, e) { + + var tdx, tdy; + var snapInvMatrix = handlerData.handler.transform().diffMatrix.invert(); + snapInvMatrix.e = snapInvMatrix.f = 0; + tdx = snapInvMatrix.x( dx,dy ); + tdy = snapInvMatrix.y( dx,dy ); + + this.currentPosition.x = e.clientX; + this.currentPosition.y = e.clientY; + if (! this.checkBondaries(dx, dy)) { return; } + + handlerData.handler.transform( "t" + [ tdx, tdy ] + handlerData.handler.data("origTransform") ); + this.updateShapePositions(handlerData, tdx, tdy); + }, + + onStop: function () { + this.isResizing = false; + this.startPosition = {}; + this.currentPosition = {}; + } + }, + + checkBondaries: function (dx, dy) { + var result = true; + var origBounding = this.shape.data("origBounding"); + var getBoundingClientRect = this.shape.node.getBoundingClientRect(); + + if (origBounding.width - dx <= this.SHAPE_MIN_SIZE) { + result = false; + } + + if (origBounding.height - dy <= this.SHAPE_MIN_SIZE) { + result = false; + } + + return result; + }, + + destroy: function () { + this.handlers.map(function (handlerData) { + handlerData.handler.remove(); + }); + delete this; + }, + + getZoomFactor: function () { + return { + x: this.viewPort.width / this.viewBox[2], + y: this.viewPort.height / this.viewBox[3] + }; + }, + + attachEvents: function () { + var self = this; + this.handlers.map(function (handlerData) { + handlerData.handler.drag( + self.dragEvents.onMove.bind(self, handlerData), + self.dragEvents.onStart.bind(self, handlerData), + self.dragEvents.onStop.bind(self, handlerData)); + }); + + eventEmitter.on("cutout:clear", function () { + self.destroy(); + }); + + this.shapesGroup.drag(function (dx, dy) { + if (self.isResizing) { return; } + var snapInvMatrix = this.transform().diffMatrix.invert(); + snapInvMatrix.e = snapInvMatrix.f = 0; + var tdx = snapInvMatrix.x( dx,dy ); + var tdy = snapInvMatrix.y( dx,dy ); + + var transformValue = this.data('origTransform') + (this.data('origTransform') ? "T" : "t") + [tdx, tdy]; + this.transform(transformValue); + }, function () { + this.data('origTransform', this.transform().local); + }, this.noop); + }, +} + +export default { + + enable_resizer : function (paper, rect, viewPort, cViewbox) { + new ShapeResizer(paper, rect, viewPort, cViewbox); + } +} \ No newline at end of file