Skip to content

Commit abd8e93

Browse files
committed
Shapes: add line, rect and circle resize
1 parent e9f8ac4 commit abd8e93

File tree

1 file changed

+77
-4
lines changed

1 file changed

+77
-4
lines changed

src/components/shapes/index.js

Lines changed: 77 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -351,11 +351,18 @@ function updateShape(gd, index, opt, value) {
351351
}
352352

353353
function setupDragElement(gd, shapePath, shapeOptions, index) {
354+
var MINWIDTH = 10,
355+
MINHEIGHT = 10;
356+
354357
var update;
355358
var x0, y0, x1, y1, astrX0, astrY0, astrX1, astrY1;
359+
var n0, s0, w0, e0, astrN, astrS, astrW, astrE, optN, optS, optW, optE;
356360
var pathIn, astrPath;
361+
357362
var xa, ya, x2p, y2p, p2x, p2y;
358363

364+
var dragBBox, dragMode;
365+
359366
var dragOptions = {
360367
element: shapePath.node(),
361368
prepFn: startDrag,
@@ -364,9 +371,8 @@ function setupDragElement(gd, shapePath, shapeOptions, index) {
364371

365372
dragElement.init(dragOptions);
366373

367-
function startDrag() {
368-
setCursor(shapePath, 'move');
369-
374+
function startDrag(evt, startX, startY) {
375+
// setup conversion functions
370376
xa = Axes.getFromId(gd, shapeOptions.xref);
371377
ya = Axes.getFromId(gd, shapeOptions.yref);
372378

@@ -375,6 +381,7 @@ function setupDragElement(gd, shapePath, shapeOptions, index) {
375381
p2x = getPixelToData(gd, xa);
376382
p2y = getPixelToData(gd, ya, true);
377383

384+
// setup update strings and initial values
378385
var astr = 'shapes[' + index + ']';
379386
if(shapeOptions.type === 'path') {
380387
pathIn = shapeOptions.path;
@@ -392,9 +399,43 @@ function setupDragElement(gd, shapePath, shapeOptions, index) {
392399
astrY1 = astr + '.y1';
393400
}
394401

402+
if(x0 < x1) {
403+
w0 = x0; astrW = astr + '.x0'; optW = 'x0';
404+
e0 = x1; astrE = astr + '.x1'; optE = 'x1';
405+
}
406+
else {
407+
w0 = x1; astrW = astr + '.x1'; optW = 'x1';
408+
e0 = x0; astrE = astr + '.x0'; optE = 'x0';
409+
}
410+
if(y0 < y1) {
411+
n0 = y0; astrN = astr + '.y0'; optN = 'y0';
412+
s0 = y1; astrS = astr + '.y1'; optS = 'y1';
413+
}
414+
else {
415+
n0 = y1; astrN = astr + '.y1'; optN = 'y1';
416+
s0 = y0; astrS = astr + '.y0'; optS = 'y0';
417+
}
418+
395419
update = {};
396420

397-
dragOptions.moveFn = moveShape;
421+
// choose 'move' or 'resize'
422+
// based on initial position of cursor within the drag element
423+
dragBBox = dragOptions.element.getBoundingClientRect();
424+
425+
var w = dragBBox.right - dragBBox.left,
426+
h = dragBBox.bottom - dragBBox.top,
427+
x = startX - dragBBox.left,
428+
y = startY - dragBBox.top,
429+
cursor = (w > MINWIDTH && h > MINHEIGHT) ?
430+
dragElement.getCursor(x / w, 1 - y / h) :
431+
'move';
432+
433+
setCursor(shapePath, cursor);
434+
435+
// possible values 'move', 'sw', 'w', 'se', 'e', 'ne', 'n', 'nw' and 'w'
436+
dragMode = cursor.split('-')[0];
437+
438+
dragOptions.moveFn = (dragMode === 'move') ? moveShape : resizeShape;
398439
}
399440

400441
function endDrag(dragged) {
@@ -424,6 +465,38 @@ function setupDragElement(gd, shapePath, shapeOptions, index) {
424465

425466
shapePath.attr('d', getPathString(gd, shapeOptions));
426467
}
468+
469+
function resizeShape(dx, dy) {
470+
if(shapeOptions.type === 'path') {
471+
// TODO: implement path resize
472+
var moveX = function moveX(x) { return p2x(x2p(x) + dx); };
473+
if(xa && xa.type === 'date') moveX = encodeDate(moveX);
474+
475+
var moveY = function moveY(y) { return p2y(y2p(y) + dy); };
476+
if(ya && ya.type === 'date') moveY = encodeDate(moveY);
477+
478+
shapeOptions.path = movePath(pathIn, moveX, moveY);
479+
update[astrPath] = shapeOptions.path;
480+
}
481+
else {
482+
var newN = (~dragMode.indexOf('n')) ? n0 + dy : n0,
483+
newS = (~dragMode.indexOf('s')) ? s0 + dy : s0,
484+
newW = (~dragMode.indexOf('w')) ? w0 + dx : w0,
485+
newE = (~dragMode.indexOf('e')) ? e0 + dx : e0;
486+
487+
if(newS - newN > MINHEIGHT) {
488+
update[astrN] = shapeOptions[optN] = p2y(newN);
489+
update[astrS] = shapeOptions[optS] = p2y(newS);
490+
}
491+
492+
if(newE - newW > MINWIDTH) {
493+
update[astrW] = shapeOptions[optW] = p2x(newW);
494+
update[astrE] = shapeOptions[optE] = p2x(newE);
495+
}
496+
}
497+
498+
shapePath.attr('d', getPathString(gd, shapeOptions));
499+
}
427500
}
428501

429502
function getShapeLayer(gd, index) {

0 commit comments

Comments
 (0)