From f4596a0f7a284b58e9a6c0b95c72c100ec37a73d Mon Sep 17 00:00:00 2001 From: Michael Dewberry Date: Tue, 9 Feb 2016 00:02:18 -0500 Subject: [PATCH 1/9] Add basic cut/copy/paste for single paths --- src/tools/tool.select.js | 50 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 3 deletions(-) diff --git a/src/tools/tool.select.js b/src/tools/tool.select.js index c97751a..c987448 100644 --- a/src/tools/tool.select.js +++ b/src/tools/tool.select.js @@ -26,6 +26,7 @@ module.exports = function(paper) { fill: true, tolerance: 5 }; + var pasteBuffer = []; // Externalize deseletion paper.deselect = function() { @@ -224,13 +225,38 @@ module.exports = function(paper) { } }; + function deleteSelection() { + paper.selectRect.ppath.remove(); + if (paper.imageTraceMode) paper.traceImage = null; + paper.deselect(); + } + + function copySelectionToBuffer() { + pasteBuffer = []; + var itemsToCopy = [ paper.selectRect.ppath ]; + _.each(itemsToCopy, function (copyItem) { + pasteBuffer.push(copyItem.exportJSON({ asString: false })); + }); + } + + function pasteFromBuffer() { + var addedItems = []; + _.each(pasteBuffer, function (pasteItem) { + if (pasteItem[0] === 'Path') { + var newPath = new Path(); + newPath.importJSON(JSON.stringify(pasteItem)); + addedItems.push(newPath); + } + }); + + initSelectionRectangle(addedItems[0]); + } + tool.onKeyDown = function (event) { if (paper.selectRect) { // Delete a selected path if (event.key === 'delete' || event.key === 'backspace') { - paper.selectRect.ppath.remove(); - if (paper.imageTraceMode) paper.traceImage = null; - paper.deselect(); + deleteSelection(); } // Deselect @@ -239,7 +265,25 @@ module.exports = function(paper) { paper.deselect(); } + // Copy + if (event.key === 'c' && !event.event.shiftKey && (event.event.ctrlKey || event.event.metaKey)) { + copySelectionToBuffer(); + } + + // Cut + if (event.key === 'x' && !event.event.shiftKey && (event.event.ctrlKey || event.event.metaKey)) { + copySelectionToBuffer(); + deleteSelection(); + } } + + if (pasteBuffer.length > 0) { + // Paste + if (event.key === 'v' && !event.event.shiftKey && (event.event.ctrlKey || event.event.metaKey)) { + pasteFromBuffer(); + } + } + }; function initSelectionRectangle(path) { From 7bcf7e3d9c105d4076404e9e24d2c1ec19bd5558 Mon Sep 17 00:00:00 2001 From: Michael Dewberry Date: Tue, 9 Feb 2016 01:18:03 -0500 Subject: [PATCH 2/9] Prototype multiple selection using shift-click to add/remove Still needs: - Rotation correction - Box select --- src/app.js | 12 ++-- src/tools/tool.select.js | 115 ++++++++++++++++++++++++--------------- 2 files changed, 76 insertions(+), 51 deletions(-) diff --git a/src/app.js b/src/app.js index 50995be..5d7d725 100644 --- a/src/app.js +++ b/src/app.js @@ -288,17 +288,17 @@ function selectColor(index) { // Change selected path's color if (paper.selectRect) { - if (paper.selectRect.ppath) { - if (paper.selectRect.ppath.data.fill === true) { - paper.selectRect.ppath.fillColor = paper.pancakeShades[index]; + _.each(paper.selectRect.paths, function (selectedPath) { + if (selectedPath.data.fill === true) { + selectedPath.fillColor = paper.pancakeShades[index]; } else { - paper.selectRect.ppath.strokeColor = paper.pancakeShades[index]; + selectedPath.strokeColor = paper.pancakeShades[index]; } - paper.selectRect.ppath.data.color = index; + selectedPath.data.color = index; paper.view.update(); currentFile.changed = true; - } + }); } } diff --git a/src/tools/tool.select.js b/src/tools/tool.select.js index c987448..f5cb565 100644 --- a/src/tools/tool.select.js +++ b/src/tools/tool.select.js @@ -92,7 +92,6 @@ module.exports = function(paper) { if (hitResult.type === 'segment') { hitResult.segment.remove(); } - return; } if (hitResult) { @@ -126,15 +125,26 @@ module.exports = function(paper) { segment = hitResult.segment; } } else if (hitResult.type === 'stroke' && path !== paper.selectRect) { - if (paper.selectRect && paper.selectRect.ppath === path) { + if (!event.modifiers.shift && paper.selectRect && _.contains(paper.selectRect.paths, path)) { // Add new segment node to the path (if it's already selected) var location = hitResult.location; segment = path.insert(location.index + 1, event.point); } } - if ((paper.selectRect === null || paper.selectRect.ppath !== path) && paper.selectRect !== path) { - initSelectionRectangle(path); + if ((paper.selectRect === null || !_.contains(paper.selectRect.paths, path)) && paper.selectRect !== path) { + if (!event.modifiers.shift || paper.selectRect === null) { + initSelectionRectangle([path]); + } else { + var newSelection = paper.selectRect.paths; + newSelection.push(path); + initSelectionRectangle(newSelection); + } + } else if (paper.selectRect !== null && _.contains(paper.selectRect.paths, path)) { + if (event.modifiers.shift) { + var newSelection = _.filter(paper.selectRect.paths, function (p) { return p !== path }); + initSelectionRectangle(newSelection); + } } } @@ -150,12 +160,16 @@ module.exports = function(paper) { var ratio = event.point.subtract(paper.selectRect.bounds.center).length / selectionRectangleScale; var scaling = new Point(ratio, ratio); paper.selectRect.scaling = scaling; - paper.selectRect.ppath.scaling = scaling; + _.each(paper.selectRect.paths, function (selectedPath) { + selectedPath.scaling = scaling; + }); return; } else if (selectionRectangleRotation !== null) { // Path rotation adjustment var rotation = event.point.subtract(paper.selectRect.pivot).angle + 90; - paper.selectRect.ppath.rotation = rotation; + _.each(paper.selectRect.paths, function (selectedPath) { + selectedPath.rotation = rotation; + }); paper.selectRect.rotation = rotation; return; } @@ -168,18 +182,13 @@ module.exports = function(paper) { // Smooth -only- non-polygonal paths //if (!path.data.isPolygonal) path.smooth(); - initSelectionRectangle(path); - } else if (path) { + initSelectionRectangle([path]); + } else if (paper.selectRect !== null && paper.selectRect.paths.length > 0) { // Path translate position adjustment - if (path !== paper.selectRect) { - path.position.x += event.delta.x; - path.position.y += event.delta.y; - paper.selectRect.position.x += event.delta.x; - paper.selectRect.position.y += event.delta.y; - } else { - paper.selectRect.position = paper.selectRect.position.add(event.delta); - paper.selectRect.ppath.position = paper.selectRect.ppath.position.add(event.delta); - } + _.each(paper.selectRect.paths, function (selectedPath) { + selectedPath.position = selectedPath.position.add(event.delta); + }); + paper.selectRect.position = paper.selectRect.position.add(event.delta); } }; @@ -225,18 +234,33 @@ module.exports = function(paper) { } }; + function cancelSelection() { + if (paper.selectRect !== null) { + _.each(paper.selectRect.paths, function (selectedPath) { + selectedPath.fullySelected = false; + }); + } + paper.deselect(); + } + function deleteSelection() { - paper.selectRect.ppath.remove(); + if (paper.selectRect !== null) { + _.each(paper.selectRect.paths, function (selectedPath) { + selectedPath.remove(); + }); + } if (paper.imageTraceMode) paper.traceImage = null; paper.deselect(); } function copySelectionToBuffer() { pasteBuffer = []; - var itemsToCopy = [ paper.selectRect.ppath ]; - _.each(itemsToCopy, function (copyItem) { - pasteBuffer.push(copyItem.exportJSON({ asString: false })); - }); + if (paper.selectRect !== null) { + var itemsToCopy = paper.selectRect.paths; + _.each(itemsToCopy, function (copyItem) { + pasteBuffer.push(copyItem.exportJSON({ asString: false })); + }); + } } function pasteFromBuffer() { @@ -249,7 +273,9 @@ module.exports = function(paper) { } }); - initSelectionRectangle(addedItems[0]); + if (addedItems.length > 0) { + initSelectionRectangle(addedItems); + } } tool.onKeyDown = function (event) { @@ -261,8 +287,7 @@ module.exports = function(paper) { // Deselect if (event.key === 'escape') { - paper.selectRect.ppath.fullySelected = false; - paper.deselect(); + cancelSelection(); } // Copy @@ -286,20 +311,23 @@ module.exports = function(paper) { }; - function initSelectionRectangle(path) { - if (paper.selectRect !== null) paper.selectRect.remove(); - var reset = path.rotation === 0 && path.scaling.x === 1 && path.scaling.y === 1; - var bounds; + function initSelectionRectangle(paths) { + cancelSelection(); - if (reset) { - // Actually reset bounding box - bounds = path.bounds; - path.pInitialBounds = path.bounds; - } else { - // No bounding box reset - bounds = path.pInitialBounds; + if (paths.length <= 0) { + return; } + var bounds = undefined; + + _.each(paths, function (selectedPath) { + if (bounds) { + bounds = bounds.unite(selectedPath.bounds); + } else { + bounds = selectedPath.bounds; + } + }); + var b = bounds.clone().expand(25, 25); paper.selectRect = new Path.Rectangle(b); @@ -308,18 +336,15 @@ module.exports = function(paper) { paper.selectRect.insert(2, new Point(b.center.x, b.top - 25)); paper.selectRect.insert(2, new Point(b.center.x, b.top)); - if (!reset) { - paper.selectRect.position = path.bounds.center; - paper.selectRect.rotation = path.rotation; - paper.selectRect.scaling = path.scaling; - } - paper.selectRect.strokeWidth = 2; paper.selectRect.strokeColor = 'blue'; paper.selectRect.name = "selection rectangle"; paper.selectRect.selected = true; - paper.selectRect.ppath = path; - paper.selectRect.ppath.pivot = paper.selectRect.pivot; + paper.selectRect.paths = paths; + + _.each(paths, function (selectedPath) { + selectedPath.pivot = paper.selectRect.pivot; + }); } function getBoundSelection(point) { @@ -353,7 +378,7 @@ module.exports = function(paper) { paper.imageTraceMode = toggle; if (toggle) { - initSelectionRectangle(paper.traceImage); + initSelectionRectangle([paper.traceImage]); tool.activate(); } else { path = null; From bd55ca747412471725eb93b9955b294b468d65fb Mon Sep 17 00:00:00 2001 From: Michael Dewberry Date: Tue, 9 Feb 2016 01:32:44 -0500 Subject: [PATCH 3/9] Select All key command --- src/tools/tool.select.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/tools/tool.select.js b/src/tools/tool.select.js index f5cb565..f1f19e8 100644 --- a/src/tools/tool.select.js +++ b/src/tools/tool.select.js @@ -309,6 +309,10 @@ module.exports = function(paper) { } } + // Select All + if (event.key === 'a' && !event.event.shiftKey && (event.event.ctrlKey || event.event.metaKey)) { + initSelectionRectangle(project.activeLayer.getItems({ class: Path })); + } }; function initSelectionRectangle(paths) { From 2201e794b95099540203942aac5af469e1f4bdd6 Mon Sep 17 00:00:00 2001 From: Michael Dewberry Date: Mon, 15 Feb 2016 16:39:03 -0500 Subject: [PATCH 4/9] Add rubber-banding box selection --- src/tools/tool.select.js | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/tools/tool.select.js b/src/tools/tool.select.js index f1f19e8..dfd98b3 100644 --- a/src/tools/tool.select.js +++ b/src/tools/tool.select.js @@ -27,6 +27,8 @@ module.exports = function(paper) { tolerance: 5 }; var pasteBuffer = []; + var rubberBandStartPoint = null; + var rubberBandPath = null; // Externalize deseletion paper.deselect = function() { @@ -83,6 +85,7 @@ module.exports = function(paper) { if (paper.selectRect !== null) { paper.deselect(); } + rubberBandStartPoint = event.point; return; } @@ -189,6 +192,12 @@ module.exports = function(paper) { selectedPath.position = selectedPath.position.add(event.delta); }); paper.selectRect.position = paper.selectRect.position.add(event.delta); + } else { + if (rubberBandPath) { rubberBandPath.remove(); } + rubberBandPath = Path.Rectangle(rubberBandStartPoint, event.point); + rubberBandPath.dashArray = [12, 6]; + rubberBandPath.strokeWidth = 2; + rubberBandPath.strokeColor = 'cyan'; } }; @@ -227,6 +236,19 @@ module.exports = function(paper) { selectionRectangleScale = null; selectionRectangleRotation = null; + if (rubberBandPath !== null) { + var rbRect = rubberBandPath.bounds; + rubberBandPath.remove(); + rubberBandPath = null; + + var rbItems = project.activeLayer.getItems({ + inside: rbRect, + class: Path + }); + + initSelectionRectangle(rbItems); + } + // If we have a mouse up with either of these, the file has changed! if (path || segment) { paper.cleanPath(path); From effc114b520c4d22c5744600b9fd010533cc825b Mon Sep 17 00:00:00 2001 From: Michael Dewberry Date: Mon, 15 Feb 2016 16:53:54 -0500 Subject: [PATCH 5/9] Use ctrl/command as multi-select key modifier --- src/tools/tool.select.js | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/tools/tool.select.js b/src/tools/tool.select.js index dfd98b3..66f5d0a 100644 --- a/src/tools/tool.select.js +++ b/src/tools/tool.select.js @@ -135,19 +135,23 @@ module.exports = function(paper) { } } + // Selection + var isMultiSelect = event.modifiers.command || event.modifiers.control; if ((paper.selectRect === null || !_.contains(paper.selectRect.paths, path)) && paper.selectRect !== path) { - if (!event.modifiers.shift || paper.selectRect === null) { + if (!isMultiSelect || paper.selectRect === null) { + // Start a new selection with this path initSelectionRectangle([path]); } else { + // Multiselect key held, add this path to the existing selection var newSelection = paper.selectRect.paths; newSelection.push(path); initSelectionRectangle(newSelection); } - } else if (paper.selectRect !== null && _.contains(paper.selectRect.paths, path)) { - if (event.modifiers.shift) { - var newSelection = _.filter(paper.selectRect.paths, function (p) { return p !== path }); - initSelectionRectangle(newSelection); - } + } + // When multiselect key is held and path is already selected, remove it from selection + else if (isMultiSelect && paper.selectRect !== null && _.contains(paper.selectRect.paths, path)) { + var newSelection = _.filter(paper.selectRect.paths, function (p) { return p !== path }); + initSelectionRectangle(newSelection); } } From f56524aa6c590be68136531b17e86c4f862b4232 Mon Sep 17 00:00:00 2001 From: Michael Dewberry Date: Mon, 15 Feb 2016 17:19:53 -0500 Subject: [PATCH 6/9] Correctly calculate rotation when chaining single-item rotation and multi-select rotation --- src/tools/tool.select.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/tools/tool.select.js b/src/tools/tool.select.js index 66f5d0a..ce8fd2c 100644 --- a/src/tools/tool.select.js +++ b/src/tools/tool.select.js @@ -373,6 +373,9 @@ module.exports = function(paper) { paper.selectRect.paths = paths; _.each(paths, function (selectedPath) { + // Apply previous rotation to segments before moving pivot + selectedPath.applyMatrix = true; + selectedPath.applyMatrix = false; selectedPath.pivot = paper.selectRect.pivot; }); } From e9619d69958a071cea23f4e2b9c5b13e33143476 Mon Sep 17 00:00:00 2001 From: Michael Dewberry Date: Mon, 15 Feb 2016 18:16:57 -0500 Subject: [PATCH 7/9] Add Edit menu with cut/copy/paste/delete/select all --- locales/en-US/menus-en-US.json | 7 ++++++ menus/menu-darwin.js | 25 ++++++++++++++++++++ menus/menu-win32.js | 25 ++++++++++++++++++++ src/app.js | 43 ++++++++++++++++++++++++++++++++++ src/tools/tool.select.js | 38 ++++++------------------------ 5 files changed, 107 insertions(+), 31 deletions(-) diff --git a/locales/en-US/menus-en-US.json b/locales/en-US/menus-en-US.json index 623f990..a83c74f 100644 --- a/locales/en-US/menus-en-US.json +++ b/locales/en-US/menus-en-US.json @@ -15,6 +15,13 @@ "save": "&Save Project", "saveas": "Save Project &as…" }, + "edit" : { + "cut": "Cut", + "copy": "&Copy", + "paste": "Paste", + "delete": "Delete", + "selectall": "Select &All" + }, "view" : { "settings": "Advanced Settings" }, diff --git a/menus/menu-darwin.js b/menus/menu-darwin.js index d19b045..a4e733e 100644 --- a/menus/menu-darwin.js +++ b/menus/menu-darwin.js @@ -96,6 +96,31 @@ module.exports = function applyTemplate() { } ] }, + { + label: 'Edit ', // space prevents OS X from adding Dictation/Emoji menu items + submenu: [ + { + key: 'edit.cut', + accelerator: 'Command+X' + }, + { + key: 'edit.copy', + accelerator: 'Command+C' + }, + { + key: 'edit.paste', + accelerator: 'Command+V' + }, + { + key: 'edit.delete', + accelerator: 'Backspace' + }, + { + key: 'edit.selectall', + accelerator: 'Command+A' + } + ] + }, { label: 'View', submenu: [ diff --git a/menus/menu-win32.js b/menus/menu-win32.js index c4a4cc1..70d42da 100644 --- a/menus/menu-win32.js +++ b/menus/menu-win32.js @@ -46,6 +46,31 @@ module.exports = function applyTemplate() { } ] }, + { + label: 'Edit', + submenu: [ + { + key: 'edit.cut', + accelerator: 'Control+X' + }, + { + key: 'edit.copy', + accelerator: 'Control+C' + }, + { + key: 'edit.paste', + accelerator: 'Control+V' + }, + { + key: 'edit.delete', + accelerator: 'Delete' + }, + { + key: 'edit.selectall', + accelerator: 'Control+A' + } + ] + }, { label: 'View', submenu: [ diff --git a/src/app.js b/src/app.js index 5d7d725..f158ce6 100644 --- a/src/app.js +++ b/src/app.js @@ -247,6 +247,14 @@ function activateToolItem(item) { paper.view.update(); } +function switchToSelectTool() { + var selectTool = _.findWhere(paper.tools, { key: 'select'}); + if (selectTool) { + selectTool.activate(); + activateToolItem($("#tool-select")); + } +} + // Build the elements for the colorpicker non-tool item function buildColorPicker() { var $picker = $('
').attr('id', 'picker'); @@ -417,6 +425,41 @@ function bindControls() { paper.newPBP(); }); break; + case 'edit.cut': + if (paper.tool.key === 'select') { + paper.tool.copySelectionToBuffer(); + paper.tool.deleteSelection(); + currentFile.changed = true; + paper.view.update(); + } + break; + case 'edit.copy': + if (paper.tool.key === 'select') { + paper.tool.copySelectionToBuffer(); + } + break; + case 'edit.paste': + if (paper.tool.key !== 'select') { + switchToSelectTool(); + } + paper.tool.pasteFromBuffer(); + currentFile.changed = true; + paper.view.update(); + break; + case 'edit.delete': + if (paper.tool.key === 'select') { + paper.tool.deleteSelection(); + currentFile.changed = true; + paper.view.update(); + } + break; + case 'edit.selectall': + if (paper.tool.key !== 'select') { + switchToSelectTool(); + } + paper.tool.selectAll(); + paper.view.update(); + break; case 'view.settings': toggleOverlay(true, function(){ $('#settings').fadeIn('slow'); diff --git a/src/tools/tool.select.js b/src/tools/tool.select.js index ce8fd2c..5d7dfc0 100644 --- a/src/tools/tool.select.js +++ b/src/tools/tool.select.js @@ -269,7 +269,7 @@ module.exports = function(paper) { paper.deselect(); } - function deleteSelection() { + tool.deleteSelection = function() { if (paper.selectRect !== null) { _.each(paper.selectRect.paths, function (selectedPath) { selectedPath.remove(); @@ -279,7 +279,7 @@ module.exports = function(paper) { paper.deselect(); } - function copySelectionToBuffer() { + tool.copySelectionToBuffer = function() { pasteBuffer = []; if (paper.selectRect !== null) { var itemsToCopy = paper.selectRect.paths; @@ -289,7 +289,7 @@ module.exports = function(paper) { } } - function pasteFromBuffer() { + tool.pasteFromBuffer = function() { var addedItems = []; _.each(pasteBuffer, function (pasteItem) { if (pasteItem[0] === 'Path') { @@ -304,40 +304,16 @@ module.exports = function(paper) { } } + tool.selectAll = function() { + initSelectionRectangle(project.activeLayer.getItems({ class: Path })); + } + tool.onKeyDown = function (event) { if (paper.selectRect) { - // Delete a selected path - if (event.key === 'delete' || event.key === 'backspace') { - deleteSelection(); - } - // Deselect if (event.key === 'escape') { cancelSelection(); } - - // Copy - if (event.key === 'c' && !event.event.shiftKey && (event.event.ctrlKey || event.event.metaKey)) { - copySelectionToBuffer(); - } - - // Cut - if (event.key === 'x' && !event.event.shiftKey && (event.event.ctrlKey || event.event.metaKey)) { - copySelectionToBuffer(); - deleteSelection(); - } - } - - if (pasteBuffer.length > 0) { - // Paste - if (event.key === 'v' && !event.event.shiftKey && (event.event.ctrlKey || event.event.metaKey)) { - pasteFromBuffer(); - } - } - - // Select All - if (event.key === 'a' && !event.event.shiftKey && (event.event.ctrlKey || event.event.metaKey)) { - initSelectionRectangle(project.activeLayer.getItems({ class: Path })); } }; From 4f150761b576e56c49966c50a28bdaf08eb8723c Mon Sep 17 00:00:00 2001 From: Michael Dewberry Date: Mon, 15 Feb 2016 18:19:48 -0500 Subject: [PATCH 8/9] Offset pasted paths a bit; fix incorrect selection bounds after hitting select-all twice --- src/tools/tool.select.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/tools/tool.select.js b/src/tools/tool.select.js index 5d7dfc0..e2351f2 100644 --- a/src/tools/tool.select.js +++ b/src/tools/tool.select.js @@ -295,6 +295,8 @@ module.exports = function(paper) { if (pasteItem[0] === 'Path') { var newPath = new Path(); newPath.importJSON(JSON.stringify(pasteItem)); + newPath.position.x += 15; + newPath.position.y += 15; addedItems.push(newPath); } }); @@ -318,6 +320,7 @@ module.exports = function(paper) { }; function initSelectionRectangle(paths) { + paths = _.filter(paths, function(p) { return p !== paper.selectRect }); cancelSelection(); if (paths.length <= 0) { From a4f7225eb36930a13f00e0bfccb92a9cd0d93843 Mon Sep 17 00:00:00 2001 From: Michael Dewberry Date: Mon, 15 Feb 2016 18:52:07 -0500 Subject: [PATCH 9/9] Fix display issues when mixing scaling/rotation/translation on the same selection --- src/tools/tool.select.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/tools/tool.select.js b/src/tools/tool.select.js index e2351f2..126abbe 100644 --- a/src/tools/tool.select.js +++ b/src/tools/tool.select.js @@ -169,6 +169,7 @@ module.exports = function(paper) { paper.selectRect.scaling = scaling; _.each(paper.selectRect.paths, function (selectedPath) { selectedPath.scaling = scaling; + selectedPath.strokeWidth = 4 / ratio; }); return; } else if (selectionRectangleRotation !== null) { @@ -193,6 +194,9 @@ module.exports = function(paper) { } else if (paper.selectRect !== null && paper.selectRect.paths.length > 0) { // Path translate position adjustment _.each(paper.selectRect.paths, function (selectedPath) { + selectedPath.applyMatrix = true; + selectedPath.applyMatrix = false; + selectedPath.strokeWidth = 4; selectedPath.position = selectedPath.position.add(event.delta); }); paper.selectRect.position = paper.selectRect.position.add(event.delta); @@ -355,6 +359,7 @@ module.exports = function(paper) { // Apply previous rotation to segments before moving pivot selectedPath.applyMatrix = true; selectedPath.applyMatrix = false; + selectedPath.strokeWidth = 4; selectedPath.pivot = paper.selectRect.pivot; }); }