|
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 } |