/* 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);
}
}