diff --git a/src/containers/paint-editor.jsx b/src/containers/paint-editor.jsx index f3bce656..b11c711e 100644 --- a/src/containers/paint-editor.jsx +++ b/src/containers/paint-editor.jsx @@ -8,6 +8,7 @@ import {undo, redo, undoSnapshot} from '../reducers/undo'; import {clearSelectedItems, setSelectedItems} from '../reducers/selected-items'; import {deactivateEyeDropper} from '../reducers/eye-dropper'; import {setTextEditTarget} from '../reducers/text-edit-target'; +import {updateViewBounds} from '../reducers/view-bounds'; import {hideGuideLayers, showGuideLayers} from '../helper/layer'; import {performUndo, performRedo, performSnapshot, shouldShowUndo, shouldShowRedo} from '../helper/undo'; @@ -38,6 +39,9 @@ class PaintEditor extends React.Component { 'handleSendToFront', 'handleGroup', 'handleUngroup', + 'handleZoomIn', + 'handleZoomOut', + 'handleZoomReset', 'canRedo', 'canUndo', 'onMouseDown', @@ -137,12 +141,15 @@ class PaintEditor extends React.Component { } handleZoomIn () { zoomOnSelection(PaintEditor.ZOOM_INCREMENT); + this.props.updateViewBounds(paper.view.matrix); } handleZoomOut () { zoomOnSelection(-PaintEditor.ZOOM_INCREMENT); + this.props.updateViewBounds(paper.view.matrix); } handleZoomReset () { resetZoom(); + this.props.updateViewBounds(paper.view.matrix); } setCanvas (canvas) { this.setState({canvas: canvas}); @@ -158,7 +165,6 @@ class PaintEditor extends React.Component { } if (event.target !== paper.view.element && !event.target.classList.contains(styles.textArea)) { - debugger; // Exit text edit mode if you click anywhere outside of canvas this.props.removeTextEditTarget(); } @@ -273,7 +279,8 @@ PaintEditor.propTypes = { undoState: PropTypes.shape({ stack: PropTypes.arrayOf(PropTypes.object).isRequired, pointer: PropTypes.number.isRequired - }) + }), + updateViewBounds: PropTypes.instanceOf(paper.Matrix).isRequired }; const mapStateToProps = state => ({ @@ -317,6 +324,10 @@ const mapDispatchToProps = dispatch => ({ setSelectedItems: () => { dispatch(setSelectedItems(getSelectedLeafItems())); }, + onDeactivateEyeDropper: () => { + // set redux values to default for eye dropper reducer + dispatch(deactivateEyeDropper()); + }, onUndo: () => { dispatch(undo()); }, @@ -326,9 +337,8 @@ const mapDispatchToProps = dispatch => ({ undoSnapshot: snapshot => { dispatch(undoSnapshot(snapshot)); }, - onDeactivateEyeDropper: () => { - // set redux values to default for eye dropper reducer - dispatch(deactivateEyeDropper()); + updateViewBounds: matrix => { + dispatch(updateViewBounds(matrix)); } }); diff --git a/src/containers/paper-canvas.jsx b/src/containers/paper-canvas.jsx index 2a3f176a..4cf61b8d 100644 --- a/src/containers/paper-canvas.jsx +++ b/src/containers/paper-canvas.jsx @@ -16,7 +16,7 @@ import {pan, resetZoom, zoomOnFixedPoint} from '../helper/view'; import {ensureClockwise} from '../helper/math'; import {clearHoveredItem} from '../reducers/hover'; import {clearPasteOffset} from '../reducers/clipboard'; - +import {updateViewBounds} from '../reducers/view-bounds'; import styles from './paper-canvas.css'; @@ -59,6 +59,7 @@ class PaperCanvas extends React.Component { const oldZoom = paper.project.view.zoom; const oldCenter = paper.project.view.center.clone(); resetZoom(); + this.props.updateViewBounds(paper.view.matrix); this.importSvg(newProps.svg, newProps.rotationCenterX, newProps.rotationCenterY); paper.project.view.zoom = oldZoom; paper.project.view.center = oldCenter; @@ -179,16 +180,19 @@ class PaperCanvas extends React.Component { new paper.Point(offsetX, offsetY) ); zoomOnFixedPoint(-event.deltaY / 100, fixedPoint); + this.props.updateViewBounds(paper.view.matrix); } else if (event.shiftKey && event.deltaX === 0) { // Scroll horizontally (based on vertical scroll delta) // This is needed as for some browser/system combinations which do not set deltaX. // See #156. const dx = event.deltaY / paper.project.view.zoom; pan(dx, 0); + this.props.updateViewBounds(paper.view.matrix); } else { const dx = event.deltaX / paper.project.view.zoom; const dy = event.deltaY / paper.project.view.zoom; pan(dx, dy); + this.props.updateViewBounds(paper.view.matrix); } event.preventDefault(); } @@ -218,7 +222,8 @@ PaperCanvas.propTypes = { setSelectedItems: PropTypes.func.isRequired, svg: PropTypes.string, svgId: PropTypes.string, - undoSnapshot: PropTypes.func.isRequired + undoSnapshot: PropTypes.func.isRequired, + updateViewBounds: PropTypes.instanceOf(paper.Matrix).isRequired }; const mapStateToProps = state => ({ mode: state.scratchPaint.mode @@ -241,6 +246,9 @@ const mapDispatchToProps = dispatch => ({ }, clearPasteOffset: () => { dispatch(clearPasteOffset()); + }, + updateViewBounds: matrix => { + dispatch(updateViewBounds(matrix)); } }); diff --git a/src/containers/text-mode.jsx b/src/containers/text-mode.jsx index bbc21a2a..2bf0c5c1 100644 --- a/src/containers/text-mode.jsx +++ b/src/containers/text-mode.jsx @@ -39,6 +39,9 @@ class TextMode extends React.Component { if (this.tool && !nextProps.textEditTarget && this.props.textEditTarget) { this.tool.onTextEditCancelled(); } + if (this.tool && !nextProps.viewBounds.equals(this.props.viewBounds)) { + this.tool.onViewBoundsChanged(nextProps.viewBounds); + } if (nextProps.isTextModeActive && !this.props.isTextModeActive) { this.activateTool(); @@ -114,7 +117,8 @@ const mapStateToProps = state => ({ colorState: state.scratchPaint.color, isTextModeActive: state.scratchPaint.mode === Modes.TEXT, selectedItems: state.scratchPaint.selectedItems, - textEditTarget: state.scratchPaint.textEditTarget + textEditTarget: state.scratchPaint.textEditTarget, + viewBounds: state.scratchPaint.viewBounds }); const mapDispatchToProps = dispatch => ({ clearSelectedItems: () => { diff --git a/src/helper/tools/text-tool.js b/src/helper/tools/text-tool.js index 4c689553..99e9eac9 100644 --- a/src/helper/tools/text-tool.js +++ b/src/helper/tools/text-tool.js @@ -94,7 +94,7 @@ class TextTool extends paper.Tool { }; } /** - * Should be called if the selection changes to update the bounds of the bounding box. + * Called when the selection changes to update the bounds of the bounding box. * @param {Array<paper.Item>} selectedItems Array of selected items. */ onSelectionChanged (selectedItems) { @@ -104,6 +104,22 @@ class TextTool extends paper.Tool { onTextEditCancelled () { this.endTextEdit(); } + /** + * Called when the view matrix changes + * @param {paper.Matrix} viewMtx applied to paper.view + */ + onViewBoundsChanged (viewMtx) { + if (this.mode !== TextTool.TEXT_EDIT_MODE) { + return; + } + const matrix = this.textBox.matrix; + this.element.style.transform = + `translate(0px, ${this.textBox.internalBounds.y}px) + matrix(${viewMtx.a}, ${viewMtx.b}, ${viewMtx.c}, ${viewMtx.d}, + ${viewMtx.tx}, ${viewMtx.ty}) + matrix(${matrix.a}, ${matrix.b}, ${matrix.c}, ${matrix.d}, + ${matrix.tx}, ${matrix.ty})`; + } setColorState (colorState) { this.colorState = colorState; } diff --git a/src/reducers/scratch-paint-reducer.js b/src/reducers/scratch-paint-reducer.js index 51e689f7..258dea9e 100644 --- a/src/reducers/scratch-paint-reducer.js +++ b/src/reducers/scratch-paint-reducer.js @@ -8,6 +8,7 @@ import hoverReducer from './hover'; import modalsReducer from './modals'; import selectedItemReducer from './selected-items'; import textEditTargetReducer from './text-edit-target'; +import viewBoundsReducer from './view-bounds'; import undoReducer from './undo'; export default combineReducers({ @@ -20,5 +21,6 @@ export default combineReducers({ modals: modalsReducer, selectedItems: selectedItemReducer, textEditTarget: textEditTargetReducer, - undo: undoReducer + undo: undoReducer, + viewBounds: viewBoundsReducer });