mirror of
https://github.com/scratchfoundation/scratch-paint.git
synced 2024-12-22 13:32:28 -05:00
add state to switch tools, and keyboard shortcuts to do so
This commit is contained in:
parent
eba604d242
commit
435f00b745
9 changed files with 141 additions and 15 deletions
|
@ -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",
|
||||
|
|
|
@ -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;
|
||||
|
|
48
src/containers/paint-editor.jsx
Normal file
48
src/containers/paint-editor.jsx
Normal 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);
|
|
@ -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;
|
|
@ -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};
|
||||
|
|
|
@ -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);
|
||||
|
|
5
src/reducers/combine-reducers.js
Normal file
5
src/reducers/combine-reducers.js
Normal file
|
@ -0,0 +1,5 @@
|
|||
import {combineReducers} from 'redux';
|
||||
|
||||
module.exports = combineReducers({
|
||||
tool: require('./tools')
|
||||
});
|
32
src/reducers/tools.js
Normal file
32
src/reducers/tools.js
Normal 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
12
src/tools/tool-types.js
Normal 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;
|
Loading…
Reference in a new issue