add state to switch tools, and keyboard shortcuts to do so

This commit is contained in:
DD Liu 2017-07-17 18:39:50 -04:00
parent eba604d242
commit 435f00b745
9 changed files with 141 additions and 15 deletions

View file

@ -49,6 +49,7 @@
"react": "15.5.4",
"react-dom": "15.5.4",
"react-intl": "2.3.0",
"react-redux": "5.0.5",
"redux": "3.6.0",
"redux-throttle": "0.1.1",
"rimraf": "^2.6.1",

View file

@ -1,13 +1,18 @@
import PropTypes from 'prop-types';
import React from 'react';
import PaperCanvas from './paper-canvas.jsx';
import PaperCanvas from '../containers/paper-canvas.jsx';
export default class PaintEditorComponent extends React.Component {
render () {
return (
<PaperCanvas />
const PaintEditorComponent = props => (
<PaperCanvas
tool={props.tool}
/>
);
}
}
PaintEditorComponent.defaultProps = {
PaintEditorComponent.propTypes = {
tool: PropTypes.shape({
name: PropTypes.string.isRequired
})
};
module.exports = PaintEditorComponent;

View file

@ -0,0 +1,48 @@
import PropTypes from 'prop-types';
import React from 'react';
import PaintEditorComponent from '../components/paint-editor.jsx';
import tools from '../reducers/tools';
import ToolTypes from '../tools/tool-types.js';
import {connect} from 'react-redux';
class PaintEditor extends React.Component {
componentDidMount () {
const onKeyPress = this.props.onKeyPress;
document.onkeydown = function (e) {
e = e || window.event;
onKeyPress(e);
};
}
render () {
return (
<PaintEditorComponent
tool={this.props.tool}
/>
);
}
}
PaintEditor.propTypes = {
onKeyPress: PropTypes.func.isRequired,
tool: PropTypes.shape({
name: PropTypes.string.isRequired
})
};
const mapStateToProps = state => ({
tool: state.tool
});
const mapDispatchToProps = dispatch => ({
onKeyPress: e => {
if (e.key === 'e') {
dispatch(tools.changeTool(ToolTypes.ERASER));
} else if (e.key === 'b') {
dispatch(tools.changeTool(ToolTypes.BRUSH));
}
}
});
module.exports = connect(
mapStateToProps,
mapDispatchToProps
)(PaintEditor);

View file

@ -1,5 +1,7 @@
import PropTypes from 'prop-types';
import React from 'react';
import paper from 'paper';
import ToolTypes from '../tools/tool-types.js';
class PaperCanvas extends React.Component {
constructor (props) {
@ -22,6 +24,11 @@ class PaperCanvas extends React.Component {
// Draw the view now:
paper.view.draw();
}
componentWillReceiveProps (nextProps) {
if (nextProps.tool !== this.props.tool && nextProps.tool instanceof ToolTypes) {
// TODO switch tool
}
}
componentWillUnmount () {
}
render () {
@ -31,6 +38,10 @@ class PaperCanvas extends React.Component {
}
}
PaperCanvas.propTypes = {};
PaperCanvas.propTypes = {
tool: PropTypes.shape({
name: PropTypes.string.isRequired
})
};
module.exports = PaperCanvas;

View file

@ -1,3 +1,3 @@
import PaintEditorComponent from './components/paint-editor.jsx';
import PaintEditor from './containers/paint-editor.jsx';
export {PaintEditorComponent as default};
export {PaintEditor as default};

View file

@ -1,9 +1,21 @@
import React from 'react';
import ReactDOM from 'react-dom';
import PaintEditor from '..';
import {Provider} from 'react-redux';
import {createStore, applyMiddleware} from 'redux';
import throttle from 'redux-throttle';
import reducer from '../reducers/combine-reducers';
const appTarget = document.createElement('div');
document.body.appendChild(appTarget);
ReactDOM.render(
<PaintEditor />,
appTarget);
const store = applyMiddleware(
throttle(300, {leading: true, trailing: true})
)(createStore)(
reducer,
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
);
ReactDOM.render((
<Provider store={store}>
<PaintEditor />
</Provider>
), appTarget);

View file

@ -0,0 +1,5 @@
import {combineReducers} from 'redux';
module.exports = combineReducers({
tool: require('./tools')
});

32
src/reducers/tools.js Normal file
View file

@ -0,0 +1,32 @@
import ToolTypes from '../tools/tool-types.js';
const CHANGE_TOOL = 'scratch-paint/tools/CHANGE_TOOL';
const initialState = ToolTypes.BRUSH;
const reducer = function (state, action) {
if (typeof state === 'undefined') state = initialState;
switch (action.type) {
case CHANGE_TOOL:
if (action.tool instanceof ToolTypes) {
return action.tool;
}
// TODO switch to minilog
console.warn('Warning: Tool type does not exist: ${action.tool}');
/* falls through */
default:
return state;
}
};
// Action creators ==================================
reducer.changeTool = function (tool) {
return {
type: CHANGE_TOOL,
tool: tool,
meta: {
throttle: 30
}
};
};
module.exports = reducer;

12
src/tools/tool-types.js Normal file
View file

@ -0,0 +1,12 @@
class ToolTypes {
constructor (name) {
this.name = name;
}
toString () {
return `ToolTypes.${this.name}`;
}
}
ToolTypes.BRUSH = new ToolTypes('BRUSH');
ToolTypes.ERASER = new ToolTypes('ERASER');
module.exports = ToolTypes;