Merge pull request #12 from fsih/strokeWidth

Add stroke width input
This commit is contained in:
DD Liu 2017-09-18 10:27:04 -04:00 committed by GitHub
commit 6c448a71a8
11 changed files with 131 additions and 87 deletions

View file

@ -7,6 +7,7 @@ import PropTypes from 'prop-types';
import LineMode from '../containers/line-mode.jsx';
import FillColorIndicatorComponent from '../containers/fill-color-indicator.jsx';
import StrokeColorIndicatorComponent from '../containers/stroke-color-indicator.jsx';
import StrokeWidthIndicatorComponent from '../containers/stroke-width-indicator.jsx';
import {defineMessages, injectIntl, intlShape} from 'react-intl';
import BufferedInputHOC from './forms/buffered-input-hoc.jsx';
@ -101,6 +102,8 @@ class PaintEditorComponent extends React.Component {
<FillColorIndicatorComponent />
{/* stroke */}
<StrokeColorIndicatorComponent />
{/* stroke width */}
<StrokeWidthIndicatorComponent />
<div className={styles.inputGroup}>
Mode tools

View file

@ -0,0 +1,29 @@
import React from 'react';
import PropTypes from 'prop-types';
import BufferedInputHOC from './forms/buffered-input-hoc.jsx';
import Input from './forms/input.jsx';
import {MAX_STROKE_WIDTH} from '../reducers/stroke-width';
import styles from './paint-editor.css';
const BufferedInput = BufferedInputHOC(Input);
const StrokeWidthIndicatorComponent = props => (
<div className={styles.inputGroup}>
<BufferedInput
small
max={MAX_STROKE_WIDTH}
min="0"
type="number"
value={props.strokeWidth}
onSubmit={props.onChangeStrokeWidth}
/>
</div>
);
StrokeWidthIndicatorComponent.propTypes = {
onChangeStrokeWidth: PropTypes.func.isRequired,
strokeWidth: PropTypes.number.isRequired
};
export default StrokeWidthIndicatorComponent;

View file

@ -79,7 +79,8 @@ BrushMode.propTypes = {
changeBrushSize: PropTypes.func.isRequired,
colorState: PropTypes.shape({
fillColor: PropTypes.string.isRequired,
strokeColor: PropTypes.string.isRequired
strokeColor: PropTypes.string.isRequired,
strokeWidth: PropTypes.number.isRequired
}).isRequired,
handleMouseDown: PropTypes.func.isRequired,
isBrushModeActive: PropTypes.bool.isRequired,

View file

@ -3,7 +3,7 @@ import React from 'react';
import {connect} from 'react-redux';
import bindAll from 'lodash.bindall';
import Modes from '../modes/modes';
import {changeLineWidth} from '../reducers/line-mode';
import {changeStrokeWidth} from '../reducers/stroke-width';
import LineModeComponent from '../components/line-mode.jsx';
import {changeMode} from '../reducers/modes';
import paper from 'paper';
@ -50,13 +50,6 @@ class LineMode extends React.Component {
this.path = null;
this.hitResult = null;
// TODO add back colors
// Make sure a stroke color is set on the line tool
// if(!pg.stylebar.getStrokeColor()) {
// pg.stylebar.setStrokeColor(pg.stylebar.getFillColor());
// pg.stylebar.setFillColor(null);
// }
const lineMode = this;
this.tool.onMouseDown = function (event) {
if (event.event.button > 0) return; // only first mouse button
@ -100,9 +93,9 @@ class LineMode extends React.Component {
if (!this.path) {
this.path = new paper.Path();
// TODO add back stroke width styling
this.path.setStrokeColor(this.props.colorState.strokeColor);
this.path.setStrokeWidth(this.props.lineModeState.lineWidth);
// Make sure a visible line is drawn
this.path.setStrokeWidth(Math.max(1, this.props.colorState.strokeWidth));
this.path.setSelected(true);
this.path.add(event.point);
@ -260,9 +253,9 @@ class LineMode extends React.Component {
}
onScroll (event) {
if (event.deltaY < 0) {
this.props.changeLineWidth(this.props.lineModeState.lineWidth + 1);
} else if (event.deltaY > 0 && this.props.lineModeState.lineWidth > 1) {
this.props.changeLineWidth(this.props.lineModeState.lineWidth - 1);
this.props.changeStrokeWidth(this.props.colorState.strokeWidth + 1);
} else if (event.deltaY > 0 && this.props.colorState.strokeWidth > 1) {
this.props.changeStrokeWidth(this.props.colorState.strokeWidth - 1);
}
return true;
}
@ -275,27 +268,24 @@ class LineMode extends React.Component {
LineMode.propTypes = {
canvas: PropTypes.instanceOf(Element).isRequired,
changeLineWidth: PropTypes.func.isRequired,
changeStrokeWidth: PropTypes.func.isRequired,
colorState: PropTypes.shape({
fillColor: PropTypes.string.isRequired,
strokeColor: PropTypes.string.isRequired
strokeColor: PropTypes.string.isRequired,
strokeWidth: PropTypes.number.isRequired
}).isRequired,
handleMouseDown: PropTypes.func.isRequired,
isLineModeActive: PropTypes.bool.isRequired,
lineModeState: PropTypes.shape({
lineWidth: PropTypes.number.isRequired
}),
onUpdateSvg: PropTypes.func.isRequired
};
const mapStateToProps = state => ({
colorState: state.scratchPaint.color,
lineModeState: state.scratchPaint.lineMode,
isLineModeActive: state.scratchPaint.mode === Modes.LINE
});
const mapDispatchToProps = dispatch => ({
changeLineWidth: lineWidth => {
dispatch(changeLineWidth(lineWidth));
changeStrokeWidth: strokeWidth => {
dispatch(changeStrokeWidth(strokeWidth));
},
handleMouseDown: () => {
dispatch(changeMode(Modes.LINE));

View file

@ -0,0 +1,17 @@
import {connect} from 'react-redux';
import {changeStrokeWidth} from '../reducers/stroke-width';
import StrokeWidthIndicatorComponent from '../components/stroke-width-indicator.jsx';
const mapStateToProps = state => ({
strokeWidth: state.scratchPaint.color.strokeWidth
});
const mapDispatchToProps = dispatch => ({
onChangeStrokeWidth: strokeWidth => {
dispatch(changeStrokeWidth(strokeWidth));
}
});
export default connect(
mapStateToProps,
mapDispatchToProps
)(StrokeWidthIndicatorComponent);

View file

@ -1,8 +1,10 @@
import {combineReducers} from 'redux';
import fillColorReducer from './fill-color';
import strokeColorReducer from './stroke-color';
import strokeWidthReducer from './stroke-width';
export default combineReducers({
fillColor: fillColorReducer,
strokeColor: strokeColorReducer
strokeColor: strokeColorReducer,
strokeWidth: strokeWidthReducer
});

View file

@ -1,31 +0,0 @@
import log from '../log/log';
const CHANGE_LINE_WIDTH = 'scratch-paint/line-mode/CHANGE_LINE_WIDTH';
const initialState = {lineWidth: 2};
const reducer = function (state, action) {
if (typeof state === 'undefined') state = initialState;
switch (action.type) {
case CHANGE_LINE_WIDTH:
if (isNaN(action.lineWidth)) {
log.warn(`Invalid line width: ${action.lineWidth}`);
return state;
}
return {lineWidth: Math.max(1, action.lineWidth)};
default:
return state;
}
};
// Action creators ==================================
const changeLineWidth = function (lineWidth) {
return {
type: CHANGE_LINE_WIDTH,
lineWidth: lineWidth
};
};
export {
reducer as default,
changeLineWidth
};

View file

@ -2,13 +2,11 @@ import {combineReducers} from 'redux';
import modeReducer from './modes';
import brushModeReducer from './brush-mode';
import eraserModeReducer from './eraser-mode';
import lineModeReducer from './line-mode';
import colorReducer from './color';
export default combineReducers({
mode: modeReducer,
brushMode: brushModeReducer,
eraserMode: eraserModeReducer,
lineMode: lineModeReducer,
color: colorReducer
});

View file

@ -0,0 +1,33 @@
import log from '../log/log';
const CHANGE_STROKE_WIDTH = 'scratch-paint/stroke-width/CHANGE_STROKE_WIDTH';
const MAX_STROKE_WIDTH = 400;
const initialState = 2;
const reducer = function (state, action) {
if (typeof state === 'undefined') state = initialState;
switch (action.type) {
case CHANGE_STROKE_WIDTH:
if (isNaN(action.strokeWidth)) {
log.warn(`Invalid brush size: ${action.strokeWidth}`);
return state;
}
return Math.min(MAX_STROKE_WIDTH, Math.max(0, action.strokeWidth));
default:
return state;
}
};
// Action creators ==================================
const changeStrokeWidth = function (strokeWidth) {
return {
type: CHANGE_STROKE_WIDTH,
strokeWidth: strokeWidth
};
};
export {
reducer as default,
changeStrokeWidth,
MAX_STROKE_WIDTH
};

View file

@ -1,31 +0,0 @@
/* eslint-env jest */
import lineReducer from '../../src/reducers/line-mode';
import {changeLineWidth} from '../../src/reducers/line-mode';
test('initialState', () => {
let defaultState;
expect(lineReducer(defaultState /* state */, {type: 'anything'} /* action */)).toBeDefined();
expect(lineReducer(defaultState /* state */, {type: 'anything'} /* action */).lineWidth).toBeGreaterThan(0);
});
test('changeLineWidth', () => {
let defaultState;
const newLineWidth = 8078;
expect(lineReducer(defaultState /* state */, changeLineWidth(newLineWidth) /* action */))
.toEqual({lineWidth: newLineWidth});
expect(lineReducer(2 /* state */, changeLineWidth(newLineWidth) /* action */))
.toEqual({lineWidth: newLineWidth});
expect(lineReducer(2 /* state */, changeLineWidth(-1) /* action */))
.toEqual({lineWidth: 1});
});
test('invalidChangeLineWidth', () => {
const origState = {lineWidth: 2};
expect(lineReducer(origState /* state */, changeLineWidth('invalid argument') /* action */))
.toBe(origState);
expect(lineReducer(origState /* state */, changeLineWidth() /* action */))
.toBe(origState);
});

View file

@ -0,0 +1,33 @@
/* eslint-env jest */
import strokeWidthReducer from '../../src/reducers/stroke-width';
import {MAX_STROKE_WIDTH, changeStrokeWidth} from '../../src/reducers/stroke-width';
test('initialState', () => {
let defaultState;
expect(strokeWidthReducer(defaultState /* state */, {type: 'anything'} /* action */)).toBeDefined();
expect(strokeWidthReducer(defaultState /* state */, {type: 'anything'} /* action */)).toBeGreaterThanOrEqual(0);
});
test('changestrokeWidth', () => {
let defaultState;
const newstrokeWidth = 234;
expect(strokeWidthReducer(defaultState /* state */, changeStrokeWidth(newstrokeWidth) /* action */))
.toEqual(newstrokeWidth);
expect(strokeWidthReducer(1 /* state */, changeStrokeWidth(newstrokeWidth) /* action */))
.toEqual(newstrokeWidth);
expect(strokeWidthReducer(1 /* state */, changeStrokeWidth(-1) /* action */))
.toEqual(0);
expect(strokeWidthReducer(1 /* state */, changeStrokeWidth(453452352) /* action */))
.toEqual(MAX_STROKE_WIDTH);
});
test('invalidChangestrokeWidth', () => {
const origState = {strokeWidth: 1};
expect(strokeWidthReducer(origState /* state */, changeStrokeWidth('invalid argument') /* action */))
.toBe(origState);
expect(strokeWidthReducer(origState /* state */, changeStrokeWidth() /* action */))
.toBe(origState);
});