diff --git a/src/containers/tools/brush-tool.jsx b/src/containers/tools/brush-tool.jsx index 56091ba0..931f2134 100644 --- a/src/containers/tools/brush-tool.jsx +++ b/src/containers/tools/brush-tool.jsx @@ -44,13 +44,13 @@ class BrushTool extends React.Component { this.tool = new paper.Tool(); this.blob.activateTool(false /* isEraser */, this.tool, this.props.brushToolState); - // // Make sure a fill color is set on the brush + // TODO Make sure a fill color is set on the brush // if(!pg.stylebar.getFillColor()) { // pg.stylebar.setFillColor(pg.stylebar.getStrokeColor()); // pg.stylebar.setStrokeColor(null); // } - // // setup floating tool options panel in the editor + // TODO setup floating tool options panel in the editor // pg.toolOptionPanel.setup(options, components, function() {}); this.tool.activate(); @@ -58,7 +58,6 @@ class BrushTool extends React.Component { deactivateTool () { document.getElementById(this.props.canvasId) .removeEventListener('mousewheel', this.onScroll); - this.blob.deactivateTool(); } onScroll (event) { if (event.deltaY < 0) { diff --git a/src/containers/tools/eraser-tool.jsx b/src/containers/tools/eraser-tool.jsx index 79ca40a1..c3fa1656 100644 --- a/src/containers/tools/eraser-tool.jsx +++ b/src/containers/tools/eraser-tool.jsx @@ -43,24 +43,12 @@ class EraserTool extends React.Component { this.tool = new paper.Tool(); this.blob.activateTool(true /* isEraser */, this.tool, this.props.eraserToolState); - - // // Make sure a fill color is set on the brush - // if(!pg.stylebar.getFillColor()) { - // pg.stylebar.setFillColor(pg.stylebar.getStrokeColor()); - // pg.stylebar.setStrokeColor(null); - // } - - // // setup floating tool options panel in the editor - // pg.toolOptionPanel.setup(options, components, function() {}); - // get options from local storage if presentz - this.tool.activate(); } deactivateTool () { document.getElementById(this.props.canvasId) .removeEventListener('mousewheel', this.onScroll); this.blob.deactivateTool(); - this.tool.remove(); } onScroll (event) { if (event.deltaY < 0) { @@ -89,7 +77,7 @@ EraserTool.propTypes = { }; const mapStateToProps = state => ({ - eraserToolState: state.brushTool, + eraserToolState: state.eraserTool, tool: state.tool }); const mapDispatchToProps = dispatch => ({ diff --git a/src/tools/blob.js b/src/tools/blob.js index ba5e86f5..d2617fc7 100644 --- a/src/tools/blob.js +++ b/src/tools/blob.js @@ -19,31 +19,45 @@ class BlobTool { } setOptions (options) { - console.log('setOptions'); - this.options = options; - if (this.cursorPreview) { - this.cursorPreview = new paper.Path.Circle({ - center: [this.cursorPreview.center.x, this.cursorPreview.center.y], - radius: options.brushSize / 2 - }); + if (this.tool) { + this.tool.options = options; + this.tool.resizeCursorIfNeeded(); } } activateTool (isEraser, tool, options) { - console.log('activateTool isEraser?'+isEraser); this.tool = tool; - this.options = options; - - let cursorPreview = this.cursorPreview = new paper.Path.Circle({ - center: [-10000, -10000], - radius: options.brushSize / 2 - }); - this.brushSize = options.brushSize; + + tool.cursorPreviewLastPoint = new paper.Point(-10000, -10000); + tool.resizeCursorIfNeeded = function (point) { + if (typeof point === 'undefined') { + point = this.cursorPreviewLastPoint; + } else { + this.cursorPreviewLastPoint = point; + } + + if (this.brushSize === this.options.brushSize) { + return; + } + const newPreview = new paper.Path.Circle({ + center: point, + radius: this.options.brushSize / 2 + }); + if (this.cursorPreview) { + this.cursorPreview.segments = newPreview.segments; + newPreview.remove(); + } else { + this.cursorPreview = newPreview; + } + this.brushSize = this.options.brushSize; + }; + + this.setOptions(options); tool.stylePath = function (path) { if (isEraser) { path.fillColor = 'white'; - if (path === cursorPreview) { + if (path === this.cursorPreview) { path.strokeColor = 'cornflowerblue'; path.strokeWidth = 1; } @@ -54,50 +68,46 @@ class BlobTool { //TODO FIX path.fillColor = 'black'; - if (path === cursorPreview) { + if (path === this.cursorPreview) { path.strokeColor = 'cornflowerblue'; path.strokeWidth = 1; } } }; - tool.stylePath(cursorPreview); + tool.stylePath(this.tool.cursorPreview); tool.fixedDistance = 1; - broadBrushHelper(tool, options); + broadBrushHelper(tool); // TODO add //pg.segmentbrushhelper(tool, options); + tool.onMouseMove = function (event) { - if (this.brushSize !== options.brushSize) { - cursorPreview.remove(); - cursorPreview = new paper.Path.Circle({ - center: event.point, - radius: options.brushSize / 2 - }); - this.brushSize = options.brushSize; - } - tool.stylePath(cursorPreview); - cursorPreview.bringToFront(); - cursorPreview.position = event.point; + tool.resizeCursorIfNeeded(event.point); + tool.stylePath(this.cursorPreview); + this.cursorPreview.bringToFront(); + this.cursorPreview.position = event.point; }; tool.onMouseDown = function (event) { + tool.resizeCursorIfNeeded(event.point); if (event.event.button > 0) return; // only first mouse button - if (options.brushSize < BlobTool.THRESHOLD) { + if (this.options.brushSize < BlobTool.THRESHOLD) { this.brush = BlobTool.BROAD; this.onBroadMouseDown(event); } else { this.brush = BlobTool.SEGMENT; this.onSegmentMouseDown(event); } - cursorPreview.bringToFront(); - cursorPreview.position = event.point; + this.cursorPreview.bringToFront(); + this.cursorPreview.position = event.point; paper.view.draw(); }; tool.onMouseDrag = function (event) { + tool.resizeCursorIfNeeded(event.point); if (event.event.button > 0) return; // only first mouse button if (this.brush === BlobTool.BROAD) { this.onBroadMouseDrag(event); @@ -107,12 +117,13 @@ class BlobTool { log.warning(`Brush type does not exist: ${this.brush}`); } - cursorPreview.bringToFront(); - cursorPreview.position = event.point; + this.cursorPreview.bringToFront(); + this.cursorPreview.position = event.point; paper.view.draw(); }; tool.onMouseUp = function (event) { + tool.resizeCursorIfNeeded(event.point); if (event.event.button > 0) return; // only first mouse button let lastPath; @@ -130,8 +141,8 @@ class BlobTool { tool.mergeBrush(lastPath); } - cursorPreview.bringToFront(); - cursorPreview.position = event.point; + this.cursorPreview.bringToFront(); + this.cursorPreview.position = event.point; // Reset this.brush = null; @@ -214,7 +225,8 @@ class BlobTool { // Gather path segments const subpaths = []; - if (items[i] instanceof paper.PathItem && !items[i].closed) { + // TODO handle compound path + if (items[i] instanceof paper.Path && !items[i].closed) { const firstSeg = items[i].clone(); const intersections = firstSeg.getIntersections(lastPath); // keep first and last segments @@ -312,15 +324,17 @@ class BlobTool { tool.isMergeable = function (newPath, existingPath) { return existingPath instanceof paper.PathItem && // path or compound path - existingPath !== cursorPreview && // don't merge with the mouse preview + existingPath !== this.cursorPreview && // don't merge with the mouse preview existingPath !== newPath && // don't merge with self existingPath.parent instanceof paper.Layer; // don't merge with nested in group }; } deactivateTool () { - console.log('deactivateTool'); - this.cursorPreview.remove(); + if (this.tool) { + this.tool.cursorPreview.remove(); + this.tool.remove(); + } } } diff --git a/src/tools/broad-brush-helper.js b/src/tools/broad-brush-helper.js index 4d6684ca..989e5749 100644 --- a/src/tools/broad-brush-helper.js +++ b/src/tools/broad-brush-helper.js @@ -4,17 +4,15 @@ const paper = require('paper'); /** * Applies segment brush functions to the tool. * @param {!Tool} tool paper.js mouse object - * @param {!options} options brush tool state object - * @param {!options.brushSize} brush tool diameter */ -const broadBrushHelper = function (tool, options) { +const broadBrushHelper = function (tool) { let lastPoint; let secondLastPoint; let finalPath; tool.onBroadMouseDown = function (event) { - tool.minDistance = options.brushSize / 4; - tool.maxDistance = options.brushSize; + tool.minDistance = this.options.brushSize / 4; + tool.maxDistance = this.options.brushSize; if (event.event.button > 0) return; // only first mouse button finalPath = new paper.Path(); @@ -24,14 +22,14 @@ const broadBrushHelper = function (tool, options) { }; tool.onBroadMouseDrag = function (event) { - const step = (event.delta).normalize(options.brushSize / 2); + const step = (event.delta).normalize(this.options.brushSize / 2); // Move the first point out away from the drag so that the end of the path is rounded if (finalPath.segments && finalPath.segments.length === 1) { const removedPoint = finalPath.removeSegment(0).point; // Add handles to round the end caps const handleVec = step.clone(); - handleVec.length = options.brushSize / 2; + handleVec.length = this.options.brushSize / 2; handleVec.angle += 90; finalPath.add(new paper.Segment(removedPoint.subtract(step), -handleVec, handleVec)); } @@ -50,7 +48,7 @@ const broadBrushHelper = function (tool, options) { if (finalPath.segments.length === 5) { // Flatten is necessary to prevent smooth from getting rid of the effect // of the handles on the first point. - finalPath.flatten(options.brushSize / 5); + finalPath.flatten(this.options.brushSize / 5); } finalPath.smooth(); lastPoint = event.point; @@ -68,14 +66,14 @@ const broadBrushHelper = function (tool, options) { finalPath.remove(); finalPath = new paper.Path.Circle({ center: event.point, - radius: options.brushSize / 2 + radius: this.options.brushSize / 2 }); tool.stylePath(finalPath); } else { - const step = (event.point.subtract(lastPoint)).normalize(options.brushSize / 2); + const step = (event.point.subtract(lastPoint)).normalize(this.options.brushSize / 2); step.angle += 90; const handleVec = step.clone(); - handleVec.length = options.brushSize / 2; + handleVec.length = this.options.brushSize / 2; const top = event.point.add(step); const bottom = event.point.subtract(step);