src_js/iconolab-bundle/src/components/cutout/shape-resizer.js
changeset 146 f912b591e1c1
equal deleted inserted replaced
145:de5736883786 146:f912b591e1c1
       
     1 /* Enabling us to resize a shape width a handler 
       
     2 	#http://stackoverflow.com/questions/32390028/how-to-drag-and-resize-svg-rectangle-using-cursor-types
       
     3 */
       
     4 import { eventEmitter } from "../utils"
       
     5 
       
     6 var ShapeResizer = function (paper, shape, vp, vb) {
       
     7 	this.paper = paper;
       
     8 	this.shape = shape;
       
     9 	this.handlers = [];
       
    10 	this.viewPort = vp;
       
    11 	this.viewBox = vb;
       
    12 	this.isResizing = false;
       
    13 	this.currentPosition = {};
       
    14 	this.HANDLER_SIZE = 8;
       
    15 	this.SHAPE_MIN_SIZE = 20;
       
    16 	this.states = {};
       
    17 	this.noop = function (){}
       
    18 	this.init();
       
    19 }
       
    20 
       
    21 var api = ShapeResizer.prototype = {
       
    22 
       
    23 	init: function () {
       
    24 		this.showHandlers();
       
    25 
       
    26 	},
       
    27 	
       
    28 	computeHandlerSize: function () {
       
    29 		return this.HANDLER_SIZE * (Math.min(this.viewBox[2], this.viewBox[3])) / this.viewPort.width; //w==h
       
    30 	},
       
    31 
       
    32 	showHandlers: function () {
       
    33 		/* show handler here */
       
    34 		var bbox = this.shape.getBBox();
       
    35 		var handleX = bbox.x - (this.computeHandlerSize()/2);
       
    36 		var handleY = bbox.y - (this.computeHandlerSize()/2);
       
    37 		var handler = this.paper.rect(handleX, handleY, this.computeHandlerSize(), this.computeHandlerSize()).attr({fill: 'red'});
       
    38 		handler.addClass("drawingHandler");
       
    39 		this.shape.addClass("drawingHandler");
       
    40 		var handlerInfos = {position: "t_r", handler: handler};
       
    41 		this.handlers.push(handlerInfos);
       
    42 		this.shapesGroup = this.paper.g(this.shape, handler);
       
    43 		this.attachEvents();
       
    44 	},
       
    45 
       
    46 	/*one handlers */
       
    47 	updateShapePositions: function (handlerData, dx, dy) {
       
    48 		//start
       
    49 		var handlerBBox = handlerData.handler.getBBox();
       
    50 		var shapeBBox = this.shape.data("origBbox");
       
    51 		var newX = handlerBBox.x + (this.computeHandlerSize() / 2);
       
    52 		var newY = handlerBBox.y + (this.computeHandlerSize() / 2);
       
    53 
       
    54 		/*to the right => reduce the size */
       
    55 		var newWidth = (dx > 0) ? shapeBBox.width - dx : shapeBBox.width + Math.abs(dx); 
       
    56 		var newHeight = (dy > 0) ? shapeBBox.height - dy : shapeBBox.height + Math.abs(dy);
       
    57 		
       
    58 		var transformValue = this.shape.data('origTransform') + (this.shape.data('origTransform') ? "T" : "t") + [dx, dy];
       
    59 		this.shape.attr({'transform': transformValue, width: newWidth, height: newHeight});
       
    60 	},
       
    61 
       
    62 	dragEvents: {
       
    63 		onStart: function (handlerData, dx, dy, e) {
       
    64 			this.startPosition = {x: e.clientX, y: e.clientY};
       
    65 			this.isResizing = true;
       
    66 			this.currentPosition = {};
       
    67 			handlerData.handler.data("origTransform", handlerData.handler.transform().local);
       
    68 			this.shape.data("origBbox", this.shape.getBBox());
       
    69 			this.shape.data("origBounding", this.shape.node.getBoundingClientRect());
       
    70 			this.shape.data("origTransform", this.shape.transform().local);
       
    71 		},
       
    72 
       
    73 		onMove: function (handlerData, dx, dy, x, y, e) {
       
    74 			
       
    75 			var tdx, tdy;
       
    76             var snapInvMatrix = handlerData.handler.transform().diffMatrix.invert();
       
    77             snapInvMatrix.e = snapInvMatrix.f = 0;
       
    78             tdx = snapInvMatrix.x( dx,dy ); 
       
    79             tdy = snapInvMatrix.y( dx,dy );
       
    80 
       
    81 			this.currentPosition.x = e.clientX;
       
    82 			this.currentPosition.y = e.clientY;
       
    83 			if (! this.checkBondaries(dx, dy)) { return; }
       
    84 
       
    85 			handlerData.handler.transform( "t" + [ tdx, tdy ] + handlerData.handler.data("origTransform")  );
       
    86 			this.updateShapePositions(handlerData, tdx, tdy);
       
    87 		},
       
    88 
       
    89 		onStop: function () {
       
    90 			this.isResizing = false;
       
    91 			this.startPosition = {};
       
    92 			this.currentPosition = {};
       
    93 		}
       
    94 	},
       
    95 	
       
    96 	checkBondaries: function (dx, dy) {
       
    97 		var result = true;
       
    98 		var origBounding = this.shape.data("origBounding");
       
    99 		var getBoundingClientRect = this.shape.node.getBoundingClientRect();
       
   100 
       
   101 		if (origBounding.width - dx <=  this.SHAPE_MIN_SIZE) {
       
   102 			result = false;
       
   103 		}
       
   104 
       
   105 		if (origBounding.height - dy <= this.SHAPE_MIN_SIZE) {
       
   106 			result = false;
       
   107 		}
       
   108 
       
   109 		return result;
       
   110 	},
       
   111 
       
   112 	destroy: function () {
       
   113 		this.handlers.map(function (handlerData) {
       
   114 			handlerData.handler.remove();
       
   115 		});
       
   116 		delete this;
       
   117 	},
       
   118 
       
   119 	getZoomFactor: function () {
       
   120 		return { 
       
   121 				x: this.viewPort.width / this.viewBox[2],
       
   122 				y: this.viewPort.height / this.viewBox[3]
       
   123 		};
       
   124 	},
       
   125 
       
   126 	attachEvents: function () {
       
   127 		var self = this;
       
   128 		this.handlers.map(function (handlerData) {
       
   129 			handlerData.handler.drag(
       
   130 				self.dragEvents.onMove.bind(self, handlerData),
       
   131 			 	self.dragEvents.onStart.bind(self, handlerData),
       
   132 				self.dragEvents.onStop.bind(self, handlerData));
       
   133 		});
       
   134 
       
   135 		eventEmitter.on("cutout:clear", function () {
       
   136 			self.destroy();
       
   137 		});
       
   138 		
       
   139 		this.shapesGroup.drag(function (dx, dy) {
       
   140 			if (self.isResizing) { return; }
       
   141             var snapInvMatrix = this.transform().diffMatrix.invert();
       
   142             snapInvMatrix.e = snapInvMatrix.f = 0;
       
   143             var tdx = snapInvMatrix.x( dx,dy ); 
       
   144             var tdy = snapInvMatrix.y( dx,dy );
       
   145 
       
   146 			var transformValue = this.data('origTransform') + (this.data('origTransform') ? "T" : "t") + [tdx, tdy];
       
   147 			this.transform(transformValue);
       
   148 		}, function () {
       
   149 			this.data('origTransform', this.transform().local);
       
   150 		}, this.noop);
       
   151 	},
       
   152 }
       
   153 
       
   154 export default {
       
   155 
       
   156 	enable_resizer : function (paper, rect, viewPort, cViewbox) {
       
   157 		new ShapeResizer(paper, rect, viewPort, cViewbox);
       
   158 	}
       
   159 }