Skip to content

Commit cca0832

Browse files
committed
Fix zero-width-outline logic
- Set the stroke color to "null" when the width is set to 0 - Properly set the stroke color state when the width is increased from 0
1 parent 852eefc commit cca0832

File tree

2 files changed

+46
-8
lines changed

2 files changed

+46
-8
lines changed

src/containers/stroke-width-indicator.jsx

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@ import PropTypes from 'prop-types';
33
import React from 'react';
44
import bindAll from 'lodash.bindall';
55
import parseColor from 'parse-color';
6-
import {changeStrokeColor} from '../reducers/stroke-style';
6+
import {changeStrokeColor, changeStrokeColor2, changeStrokeGradientType} from '../reducers/stroke-style';
77
import {changeStrokeWidth} from '../reducers/stroke-width';
88
import StrokeWidthIndicatorComponent from '../components/stroke-width-indicator.jsx';
99
import {getSelectedLeafItems} from '../helper/selection';
1010
import {applyColorToSelection, applyStrokeWidthToSelection, getColorsFromSelection, MIXED}
1111
from '../helper/style-path';
12+
import GradientTypes from '../lib/gradient-types';
1213
import Modes from '../lib/modes';
1314
import Formats from '../lib/format';
1415
import {isBitmap} from '../lib/format';
@@ -23,20 +24,31 @@ class StrokeWidthIndicator extends React.Component {
2324
handleChangeStrokeWidth (newWidth) {
2425
let changed = applyStrokeWidthToSelection(newWidth, this.props.textEditTarget);
2526
if ((!this.props.strokeWidth || this.props.strokeWidth === 0) && newWidth > 0) {
26-
let currentColor = getColorsFromSelection(getSelectedLeafItems(), isBitmap(this.props.format)).strokeColor;
27-
if (currentColor === null) {
27+
const currentColorState = getColorsFromSelection(getSelectedLeafItems(), isBitmap(this.props.format));
28+
29+
// Color counts as null if either both colors are null or the primary color is null and it's solid
30+
// TODO: consolidate this check in one place
31+
const wasNull = currentColorState.strokeColor === null &&
32+
(currentColorState.strokeColor2 === null ||
33+
currentColorState.strokeGradientType === GradientTypes.SOLID);
34+
35+
if (wasNull) {
2836
changed = applyColorToSelection(
2937
'#000',
3038
0, // colorIndex,
3139
true, // isSolidGradient
3240
true, // applyToStroke
3341
this.props.textEditTarget) ||
3442
changed;
35-
currentColor = '#000';
36-
} else if (currentColor !== MIXED) {
37-
currentColor = parseColor(currentColor).hex;
43+
// If there's no previous stroke color, default to solid black
44+
this.props.onChangeStrokeGradientType(GradientTypes.SOLID);
45+
this.props.onChangeStrokeColor('#000');
46+
} else if (currentColorState.strokeColor !== MIXED) {
47+
// Set color state from the selected item's stroke color
48+
this.props.onChangeStrokeGradientType(currentColorState.strokeGradientType);
49+
this.props.onChangeStrokeColor(parseColor(currentColorState.strokeColor).hex);
50+
this.props.onChangeStrokeColor2(parseColor(currentColorState.strokeColor2).hex);
3851
}
39-
this.props.onChangeStrokeColor(currentColor);
4052
}
4153
this.props.onChangeStrokeWidth(newWidth);
4254
if (changed) this.props.onUpdateImage();
@@ -64,6 +76,12 @@ const mapDispatchToProps = dispatch => ({
6476
onChangeStrokeColor: strokeColor => {
6577
dispatch(changeStrokeColor(strokeColor));
6678
},
79+
onChangeStrokeColor2: strokeColor => {
80+
dispatch(changeStrokeColor2(strokeColor));
81+
},
82+
onChangeStrokeGradientType: strokeColor => {
83+
dispatch(changeStrokeGradientType(strokeColor));
84+
},
6785
onChangeStrokeWidth: strokeWidth => {
6886
dispatch(changeStrokeWidth(strokeWidth));
6987
}
@@ -73,6 +91,8 @@ StrokeWidthIndicator.propTypes = {
7391
disabled: PropTypes.bool.isRequired,
7492
format: PropTypes.oneOf(Object.keys(Formats)),
7593
onChangeStrokeColor: PropTypes.func.isRequired,
94+
onChangeStrokeColor2: PropTypes.func.isRequired,
95+
onChangeStrokeGradientType: PropTypes.func.isRequired,
7696
onChangeStrokeWidth: PropTypes.func.isRequired,
7797
onUpdateImage: PropTypes.func.isRequired,
7898
strokeWidth: PropTypes.number,

src/reducers/stroke-style.js

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ const CHANGE_STROKE_GRADIENT_TYPE = 'scratch-paint/stroke-style/CHANGE_STROKE_GR
66
const CLEAR_STROKE_GRADIENT = 'scratch-paint/stroke-style/CLEAR_STROKE_GRADIENT';
77
const DEFAULT_COLOR = '#000000';
88

9+
import {CHANGE_STROKE_WIDTH} from './stroke-width';
10+
911
const reducer = makeColorStyleReducer({
1012
changePrimaryColorAction: CHANGE_STROKE_COLOR,
1113
changeSecondaryColorAction: CHANGE_STROKE_COLOR_2,
@@ -17,6 +19,22 @@ const reducer = makeColorStyleReducer({
1719
selectionGradientTypeKey: 'strokeGradientType'
1820
});
1921

22+
// This is mostly the same as the generated reducer, but with one piece of extra logic to set the color to null when the
23+
// stroke width is set to 0.
24+
// https://redux.js.org/recipes/structuring-reducers/reusing-reducer-logic
25+
const strokeReducer = function (state, action) {
26+
if (action.type === CHANGE_STROKE_WIDTH && Math.max(action.strokeWidth, 0) === 0) {
27+
// TODO: this preserves the gradient type when you change the stroke width to 0.
28+
// Alternatively, we could set gradientType to SOLID instead of setting secondary to null, but since
29+
// the stroke width is automatically set to 0 as soon as a "null" color is detected (including a gradient for
30+
// which both colors are null), that would change the gradient type back to solid if you selected null for both
31+
// gradient colors.
32+
return {...state, primary: null, secondary: null};
33+
}
34+
35+
return reducer(state, action);
36+
};
37+
2038
// Action creators ==================================
2139
const changeStrokeColor = function (strokeColor) {
2240
return {
@@ -46,7 +64,7 @@ const clearStrokeGradient = function () {
4664
};
4765

4866
export {
49-
reducer as default,
67+
strokeReducer as default,
5068
changeStrokeColor,
5169
changeStrokeColor2,
5270
changeStrokeGradientType,

0 commit comments

Comments
 (0)