Skip to content

Commit

Permalink
Bit text tool (#515)
Browse files Browse the repository at this point in the history
  • Loading branch information
fsih authored Jun 19, 2018
1 parent a70f8e1 commit d7298c0
Show file tree
Hide file tree
Showing 8 changed files with 142 additions and 86 deletions.
35 changes: 17 additions & 18 deletions src/components/bit-text-mode/bit-text-mode.jsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,26 @@
import React from 'react';
import PropTypes from 'prop-types';

import {ComingSoonTooltip} from '../coming-soon/coming-soon.jsx';
import ToolSelectComponent from '../tool-select-base/tool-select-base.jsx';

import textIcon from './text.svg';

const BitTextComponent = () => (
<ComingSoonTooltip
place="right"
tooltipId="bit-text-mode"
>
<ToolSelectComponent
disabled
imgDescriptor={{
defaultMessage: 'Text',
description: 'Label for the text tool',
id: 'paint.textMode.text'
}}
imgSrc={textIcon}
isSelected={false}
onMouseDown={function () {}} // eslint-disable-line react/jsx-no-bind
/>
</ComingSoonTooltip>
const BitTextComponent = props => (
<ToolSelectComponent
imgDescriptor={{
defaultMessage: 'Text',
description: 'Label for the text tool',
id: 'paint.textMode.text'
}}
imgSrc={textIcon}
isSelected={props.isSelected}
onMouseDown={props.onMouseDown}
/>
);

BitTextComponent.propTypes = {
isSelected: PropTypes.bool.isRequired,
onMouseDown: PropTypes.func.isRequired
};

export default BitTextComponent;
2 changes: 2 additions & 0 deletions src/components/mode-tools/mode-tools.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,8 @@ const ModeToolsComponent = props => {
</InputGroup>
</div>
);
case Modes.BIT_TEXT:
/* falls through */
case Modes.TEXT:
return (
<div className={classNames(props.className, styles.modeTools)}>
Expand Down
11 changes: 7 additions & 4 deletions src/components/paint-editor/paint-editor.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import BitBrushMode from '../../containers/bit-brush-mode.jsx';
import BitLineMode from '../../containers/bit-line-mode.jsx';
import BitOvalMode from '../../containers/bit-oval-mode.jsx';
import BitRectMode from '../../containers/bit-rect-mode.jsx';
import BitTextMode from '../../components/bit-text-mode/bit-text-mode.jsx';
import BitFillMode from '../../containers/bit-fill-mode.jsx';
import BitEraserMode from '../../containers/bit-eraser-mode.jsx';
import BitSelectMode from '../../components/bit-select-mode/bit-select-mode.jsx';
Expand Down Expand Up @@ -167,7 +166,7 @@ const PaintEditorComponent = props => (
/>
</div>
) : null}

{props.canvas !== null ? ( // eslint-disable-line no-negated-condition
<div className={isBitmap(props.format) ? styles.modeSelector : styles.hidden}>
<BitBrushMode
Expand All @@ -182,7 +181,11 @@ const PaintEditorComponent = props => (
<BitRectMode
onUpdateImage={props.onUpdateImage}
/>
<BitTextMode />
<TextMode
isBitmap
textArea={props.textArea}
onUpdateImage={props.onUpdateImage}
/>
<BitFillMode
onUpdateImage={props.onUpdateImage}
/>
Expand All @@ -192,7 +195,7 @@ const PaintEditorComponent = props => (
<BitSelectMode />
</div>
) : null}

<div>
{/* Canvas */}
<div
Expand Down
6 changes: 6 additions & 0 deletions src/containers/paint-editor.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,9 @@ class PaintEditor extends React.Component {
case Modes.BIT_RECT:
this.props.changeMode(Modes.RECT);
break;
case Modes.BIT_TEXT:
this.props.changeMode(Modes.TEXT);
break;
case Modes.BIT_FILL:
this.props.changeMode(Modes.FILL);
break;
Expand All @@ -150,6 +153,9 @@ class PaintEditor extends React.Component {
case Modes.RECT:
this.props.changeMode(Modes.BIT_RECT);
break;
case Modes.TEXT:
this.props.changeMode(Modes.BIT_TEXT);
break;
case Modes.FILL:
this.props.changeMode(Modes.BIT_FILL);
break;
Expand Down
52 changes: 33 additions & 19 deletions src/containers/text-mode.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {clearSelectedItems, setSelectedItems} from '../reducers/selected-items';
import {clearSelection, getSelectedLeafItems} from '../helper/selection';
import TextTool from '../helper/tools/text-tool';
import TextModeComponent from '../components/text-mode/text-mode.jsx';
import BitTextModeComponent from '../components/bit-text-mode/bit-text-mode.jsx';

class TextMode extends React.Component {
constructor (props) {
Expand Down Expand Up @@ -49,21 +50,21 @@ class TextMode extends React.Component {
}

if (nextProps.isTextModeActive && !this.props.isTextModeActive) {
this.activateTool();
this.activateTool(nextProps);
} else if (!nextProps.isTextModeActive && this.props.isTextModeActive) {
this.deactivateTool();
}
}
shouldComponentUpdate (nextProps) {
return nextProps.isTextModeActive !== this.props.isTextModeActive;
}
activateTool () {
activateTool (nextProps) {
clearSelection(this.props.clearSelectedItems);

// If fill and stroke color are both mixed/transparent/absent, set fill to default and stroke to transparent.
// If exactly one of fill or stroke color is set, set the other one to transparent.
// This way the tool won't draw an invisible state, or be unclear about what will be drawn.
const {fillColor, strokeColor, strokeWidth} = this.props.colorState;
const {fillColor, strokeColor, strokeWidth} = nextProps.colorState;
const fillColorPresent = fillColor !== MIXED && fillColor !== null;
const strokeColorPresent =
strokeColor !== MIXED && strokeColor !== null && strokeWidth !== null && strokeWidth !== 0;
Expand All @@ -75,8 +76,8 @@ class TextMode extends React.Component {
} else if (fillColorPresent && !strokeColorPresent) {
this.props.onChangeStrokeColor(null);
}
if (!this.props.font || Object.keys(Fonts).map(key => Fonts[key])
.indexOf(this.props.font) < 0) {
if (!nextProps.font || Object.keys(Fonts).map(key => Fonts[key])
.indexOf(nextProps.font) < 0) {
this.props.changeFont(Fonts.SANS_SERIF);
}

Expand All @@ -86,10 +87,11 @@ class TextMode extends React.Component {
this.props.clearSelectedItems,
this.props.onUpdateImage,
this.props.setTextEditTarget,
this.props.changeFont
this.props.changeFont,
nextProps.isBitmap
);
this.tool.setColorState(this.props.colorState);
this.tool.setFont(this.props.font);
this.tool.setColorState(nextProps.colorState);
this.tool.setFont(nextProps.font);
this.tool.activate();
}
deactivateTool () {
Expand All @@ -99,10 +101,15 @@ class TextMode extends React.Component {
}
render () {
return (
<TextModeComponent
isSelected={this.props.isTextModeActive}
onMouseDown={this.props.handleMouseDown}
/>
this.props.isBitmap ?
<BitTextModeComponent
isSelected={this.props.isTextModeActive}
onMouseDown={this.props.handleChangeModeBitText}
/> :
<TextModeComponent
isSelected={this.props.isTextModeActive}
onMouseDown={this.props.handleChangeModeText}
/>
);
}
}
Expand All @@ -116,7 +123,9 @@ TextMode.propTypes = {
strokeWidth: PropTypes.number
}).isRequired,
font: PropTypes.string,
handleMouseDown: PropTypes.func.isRequired,
handleChangeModeBitText: PropTypes.func.isRequired,
handleChangeModeText: PropTypes.func.isRequired,
isBitmap: PropTypes.bool,
isTextModeActive: PropTypes.bool.isRequired,
onChangeFillColor: PropTypes.func.isRequired,
onChangeStrokeColor: PropTypes.func.isRequired,
Expand All @@ -129,10 +138,12 @@ TextMode.propTypes = {
viewBounds: PropTypes.instanceOf(paper.Matrix).isRequired
};

const mapStateToProps = state => ({
const mapStateToProps = (state, ownProps) => ({
colorState: state.scratchPaint.color,
font: state.scratchPaint.font,
isTextModeActive: state.scratchPaint.mode === Modes.TEXT,
isTextModeActive: ownProps.isBitmap ?
state.scratchPaint.mode === Modes.BIT_TEXT :
state.scratchPaint.mode === Modes.TEXT,
selectedItems: state.scratchPaint.selectedItems,
textEditTarget: state.scratchPaint.textEditTarget,
viewBounds: state.scratchPaint.viewBounds
Expand All @@ -144,15 +155,18 @@ const mapDispatchToProps = dispatch => ({
clearSelectedItems: () => {
dispatch(clearSelectedItems());
},
handleChangeModeBitText: () => {
dispatch(changeMode(Modes.BIT_TEXT));
},
handleChangeModeText: () => {
dispatch(changeMode(Modes.TEXT));
},
setSelectedItems: () => {
dispatch(setSelectedItems(getSelectedLeafItems()));
},
setTextEditTarget: targetId => {
dispatch(setTextEditTarget(targetId));
},
handleMouseDown: () => {
dispatch(changeMode(Modes.TEXT));
},
onChangeFillColor: fillColor => {
dispatch(changeFillColor(fillColor));
},
Expand Down
6 changes: 3 additions & 3 deletions src/helper/bitmap.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ const forEachLinePoint = function (point1, point2, callback) {
const x2 = ~~point2.x;
let y1 = ~~point1.y;
const y2 = ~~point2.y;

const dx = Math.abs(x2 - x1);
const dy = Math.abs(y2 - y1);
const sx = (x1 < x2) ? 1 : -1;
const sy = (y1 < y2) ? 1 : -1;
let err = dx - dy;

callback(x1, y1);
while (x1 !== x2 || y1 !== y2) {
const e2 = err * 2;
Expand Down Expand Up @@ -336,7 +336,7 @@ const convertToBitmap = function (clearSelectedItems, onUpdateImage) {
showGuideLayers(guideLayers);

// Get rid of anti-aliasing
// @todo get crisp text?
// @todo get crisp text https://github.com/LLK/scratch-paint/issues/508
svg.setAttribute('shape-rendering', 'crispEdges');
inlineSvgFonts(svg);
const svgString = (new XMLSerializer()).serializeToString(svg);
Expand Down
Loading

0 comments on commit d7298c0

Please sign in to comment.