From 02730cbd58911646ec5a5fe39b4694c6e3508052 Mon Sep 17 00:00:00 2001 From: DD Liu Date: Tue, 25 Jul 2017 11:53:54 -0400 Subject: [PATCH] add eraser --- src/components/paint-editor.jsx | 2 + src/containers/tools/brush-tool.jsx | 6 +- src/containers/tools/eraser-tool.jsx | 104 +++++++++++++++++++++++++++ src/index.js | 2 +- src/reducers/combine-reducers.js | 3 +- src/reducers/eraser-tool.js | 25 +++++++ src/tools/eraser.js | 44 ------------ 7 files changed, 137 insertions(+), 49 deletions(-) create mode 100644 src/containers/tools/eraser-tool.jsx create mode 100644 src/reducers/eraser-tool.js delete mode 100644 src/tools/eraser.js diff --git a/src/components/paint-editor.jsx b/src/components/paint-editor.jsx index 3ab5fb07..c55ef2c5 100644 --- a/src/components/paint-editor.jsx +++ b/src/components/paint-editor.jsx @@ -2,6 +2,7 @@ import PropTypes from 'prop-types'; import React from 'react'; import PaperCanvas from '../containers/paper-canvas.jsx'; import BrushTool from '../containers/tools/brush-tool.jsx'; +import EraserTool from '../containers/tools/eraser-tool.jsx'; const PaintEditorComponent = props => (
@@ -10,6 +11,7 @@ const PaintEditorComponent = props => ( tool={props.tool} /> +
); diff --git a/src/containers/tools/brush-tool.jsx b/src/containers/tools/brush-tool.jsx index 604b56eb..56091ba0 100644 --- a/src/containers/tools/brush-tool.jsx +++ b/src/containers/tools/brush-tool.jsx @@ -41,8 +41,8 @@ class BrushTool extends React.Component { document.getElementById(this.props.canvasId) .addEventListener('mousewheel', this.onScroll); - const tool = new paper.Tool(); - this.blob.activateTool(false /* isEraser */, tool, this.props.brushToolState); + 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 // if(!pg.stylebar.getFillColor()) { @@ -53,7 +53,7 @@ class BrushTool extends React.Component { // // setup floating tool options panel in the editor // pg.toolOptionPanel.setup(options, components, function() {}); - tool.activate(); + this.tool.activate(); } deactivateTool () { document.getElementById(this.props.canvasId) diff --git a/src/containers/tools/eraser-tool.jsx b/src/containers/tools/eraser-tool.jsx new file mode 100644 index 00000000..79ca40a1 --- /dev/null +++ b/src/containers/tools/eraser-tool.jsx @@ -0,0 +1,104 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import {connect} from 'react-redux'; +import bindAll from 'lodash.bindall'; +import ToolTypes from '../../tools/tool-types.js'; +import BlobTool from '../../tools/blob.js'; +import EraserToolReducer from '../../reducers/eraser-tool'; +import paper from 'paper'; + +class EraserTool extends React.Component { + static get TOOL_TYPE () { + return ToolTypes.ERASER; + } + constructor (props) { + super(props); + bindAll(this, [ + 'activateTool', + 'deactivateTool', + 'onScroll' + ]); + this.blob = new BlobTool(); + } + componentDidMount () { + if (this.props.tool === EraserTool.TOOL_TYPE) { + this.activateTool(); + } + } + componentWillReceiveProps (nextProps) { + if (nextProps.tool === EraserTool.TOOL_TYPE && this.props.tool !== EraserTool.TOOL_TYPE) { + this.activateTool(); + } else if (nextProps.tool !== EraserTool.TOOL_TYPE && this.props.tool === EraserTool.TOOL_TYPE) { + this.deactivateTool(); + } else if (nextProps.tool === EraserTool.TOOL_TYPE && this.props.tool === EraserTool.TOOL_TYPE) { + this.blob.setOptions(nextProps.eraserToolState); + } + } + shouldComponentUpdate () { + return false; // Logic only component + } + activateTool () { + document.getElementById(this.props.canvasId) + .addEventListener('mousewheel', this.onScroll); + + 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) { + this.props.changeBrushSize(this.props.eraserToolState.brushSize + 1); + } else if (event.deltaY > 0 && this.props.eraserToolState.brushSize > 1) { + this.props.changeBrushSize(this.props.eraserToolState.brushSize - 1); + } + return false; + } + render () { + return ( +
+ ); + } +} + +EraserTool.propTypes = { + canvasId: PropTypes.string.isRequired, + changeBrushSize: PropTypes.func.isRequired, + eraserToolState: PropTypes.shape({ + brushSize: PropTypes.number.isRequired + }), + tool: PropTypes.shape({ + name: PropTypes.string.isRequired + }) +}; + +const mapStateToProps = state => ({ + eraserToolState: state.brushTool, + tool: state.tool +}); +const mapDispatchToProps = dispatch => ({ + changeBrushSize: brushSize => { + dispatch(EraserToolReducer.changeBrushSize(brushSize)); + } +}); + +module.exports = connect( + mapStateToProps, + mapDispatchToProps +)(EraserTool); diff --git a/src/index.js b/src/index.js index 986f2302..6611b719 100644 --- a/src/index.js +++ b/src/index.js @@ -1,3 +1,3 @@ import PaintEditor from './containers/paint-editor.jsx'; -export default PaintEditorComponent; +export default PaintEditor; diff --git a/src/reducers/combine-reducers.js b/src/reducers/combine-reducers.js index c237d7bb..75a429b1 100644 --- a/src/reducers/combine-reducers.js +++ b/src/reducers/combine-reducers.js @@ -2,5 +2,6 @@ import {combineReducers} from 'redux'; module.exports = combineReducers({ tool: require('./tools'), - brushTool: require('./brush-tool') + brushTool: require('./brush-tool'), + eraserTool: require('./eraser-tool') }); diff --git a/src/reducers/eraser-tool.js b/src/reducers/eraser-tool.js new file mode 100644 index 00000000..e8371e3e --- /dev/null +++ b/src/reducers/eraser-tool.js @@ -0,0 +1,25 @@ +const CHANGE_ERASER_SIZE = 'scratch-paint/tools/CHANGE_ERASER_SIZE'; +const initialState = {brushSize: 20}; + +const reducer = function (state, action) { + if (typeof state === 'undefined') state = initialState; + switch (action.type) { + case CHANGE_ERASER_SIZE: + return {brushSize: Math.max(1, action.brushSize)}; + default: + return state; + } +}; + +// Action creators ================================== +reducer.changeBrushSize = function (brushSize) { + return { + type: CHANGE_ERASER_SIZE, + brushSize: brushSize, + meta: { + throttle: 30 + } + }; +}; + +module.exports = reducer; diff --git a/src/tools/eraser.js b/src/tools/eraser.js deleted file mode 100644 index 525958b0..00000000 --- a/src/tools/eraser.js +++ /dev/null @@ -1,44 +0,0 @@ -// TODO share code with brush - -pg.tools.registerTool({ - id: 'eraser', - name: 'Eraser' -}); - -pg.tools.eraser = function() { - var blob = new pg.blob(); - - var options = { - brushWidth: 20 - }; - - var components = { - brushWidth: { - type: 'float', - label: 'Eraser width', - min: 0 - } - }; - - var activateTool = function() { - // get options from local storage if present - options = pg.tools.getLocalOptions(options); - var tool = new Tool(); - blob.activateTool(true /* isEraser */, tool, options); - - // setup floating tool options panel in the editor - pg.toolOptionPanel.setup(options, components, function() {}); - - tool.activate(); - }; - - var deactivateTool = function() { - blob.deactivateTool(); - }; - - return { - options: options, - activateTool : activateTool, - deactivateTool : deactivateTool - }; -}; \ No newline at end of file