diff --git a/src/components/paint-editor.jsx b/src/components/paint-editor.jsx
index 090b9bed..306bde8f 100644
--- a/src/components/paint-editor.jsx
+++ b/src/components/paint-editor.jsx
@@ -3,6 +3,7 @@ import React from 'react';
import PaperCanvas from '../containers/paper-canvas.jsx';
import BrushMode from '../containers/brush-mode.jsx';
import EraserMode from '../containers/eraser-mode.jsx';
+import PropTypes from 'prop-types';
import LineMode from '../containers/line-mode.jsx';
class PaintEditorComponent extends React.Component {
@@ -21,10 +22,24 @@ class PaintEditorComponent extends React.Component {
if (this.state.canvas) {
return (
);
}
@@ -36,4 +51,11 @@ class PaintEditorComponent extends React.Component {
}
}
+PaintEditorComponent.propTypes = {
+ onUpdateSvg: PropTypes.func.isRequired,
+ rotationCenterX: PropTypes.number,
+ rotationCenterY: PropTypes.number,
+ svg: PropTypes.string
+};
+
export default PaintEditorComponent;
diff --git a/src/containers/blob/blob.js b/src/containers/blob/blob.js
index bc7f63d1..22f4cda5 100644
--- a/src/containers/blob/blob.js
+++ b/src/containers/blob/blob.js
@@ -24,9 +24,13 @@ class Blobbiness {
return 9;
}
- constructor () {
+ /**
+ * @param {function} updateCallback call when the drawing has changed to let listeners know
+ */
+ constructor (updateCallback) {
this.broadBrushHelper = new BroadBrushHelper();
this.segmentBrushHelper = new SegmentBrushHelper();
+ this.updateCallback = updateCallback;
}
/**
@@ -113,6 +117,9 @@ class Blobbiness {
blob.mergeBrush(lastPath);
}
+ blob.cursorPreview.visible = false;
+ blob.updateCallback();
+ blob.cursorPreview.visible = true;
blob.cursorPreview.bringToFront();
blob.cursorPreview.position = event.point;
diff --git a/src/containers/brush-mode.jsx b/src/containers/brush-mode.jsx
index e751030f..c89e08f9 100644
--- a/src/containers/brush-mode.jsx
+++ b/src/containers/brush-mode.jsx
@@ -16,7 +16,7 @@ class BrushMode extends React.Component {
'deactivateTool',
'onScroll'
]);
- this.blob = new Blobbiness();
+ this.blob = new Blobbiness(this.props.onUpdateSvg);
}
componentDidMount () {
if (this.props.isBrushModeActive) {
@@ -70,7 +70,8 @@ BrushMode.propTypes = {
canvas: PropTypes.instanceOf(Element).isRequired,
changeBrushSize: PropTypes.func.isRequired,
handleMouseDown: PropTypes.func.isRequired,
- isBrushModeActive: PropTypes.bool.isRequired
+ isBrushModeActive: PropTypes.bool.isRequired,
+ onUpdateSvg: PropTypes.func.isRequired
};
const mapStateToProps = state => ({
diff --git a/src/containers/eraser-mode.jsx b/src/containers/eraser-mode.jsx
index af932329..0972ed36 100644
--- a/src/containers/eraser-mode.jsx
+++ b/src/containers/eraser-mode.jsx
@@ -16,7 +16,7 @@ class EraserMode extends React.Component {
'deactivateTool',
'onScroll'
]);
- this.blob = new Blobbiness();
+ this.blob = new Blobbiness(this.props.onUpdateSvg);
}
componentDidMount () {
if (this.props.isEraserModeActive) {
@@ -66,7 +66,8 @@ EraserMode.propTypes = {
brushSize: PropTypes.number.isRequired
}),
handleMouseDown: PropTypes.func.isRequired,
- isEraserModeActive: PropTypes.bool.isRequired
+ isEraserModeActive: PropTypes.bool.isRequired,
+ onUpdateSvg: PropTypes.func.isRequired
};
const mapStateToProps = state => ({
diff --git a/src/containers/line-mode.jsx b/src/containers/line-mode.jsx
index 030b33ba..7648c045 100644
--- a/src/containers/line-mode.jsx
+++ b/src/containers/line-mode.jsx
@@ -209,6 +209,7 @@ class LineMode extends React.Component {
}
this.hitResult = null;
}
+ this.props.onUpdateSvg();
// TODO add back undo
// if (this.path) {
@@ -280,7 +281,8 @@ LineMode.propTypes = {
isLineModeActive: PropTypes.bool.isRequired,
lineModeState: PropTypes.shape({
lineWidth: PropTypes.number.isRequired
- })
+ }),
+ onUpdateSvg: PropTypes.func.isRequired
};
const mapStateToProps = state => ({
diff --git a/src/containers/paint-editor.jsx b/src/containers/paint-editor.jsx
index 772d8985..ba260313 100644
--- a/src/containers/paint-editor.jsx
+++ b/src/containers/paint-editor.jsx
@@ -4,23 +4,50 @@ import PaintEditorComponent from '../components/paint-editor.jsx';
import {changeMode} from '../reducers/modes';
import Modes from '../modes/modes';
import {connect} from 'react-redux';
+import bindAll from 'lodash.bindall';
+import paper from 'paper';
class PaintEditor extends React.Component {
+ constructor (props) {
+ super(props);
+ bindAll(this, [
+ 'handleUpdateSvg'
+ ]);
+ }
componentDidMount () {
document.addEventListener('keydown', this.props.onKeyPress);
}
componentWillUnmount () {
document.removeEventListener('keydown', this.props.onKeyPress);
}
+ handleUpdateSvg () {
+ const bounds = paper.project.activeLayer.bounds;
+ this.props.onUpdateSvg(
+ paper.project.exportSVG({
+ asString: true,
+ matrix: new paper.Matrix().translate(-bounds.x, -bounds.y)
+ }),
+ paper.project.view.center.x - bounds.x,
+ paper.project.view.center.y - bounds.y);
+ }
render () {
return (
-
+
);
}
}
PaintEditor.propTypes = {
- onKeyPress: PropTypes.func.isRequired
+ onKeyPress: PropTypes.func.isRequired,
+ onUpdateSvg: PropTypes.func.isRequired,
+ rotationCenterX: PropTypes.number,
+ rotationCenterY: PropTypes.number,
+ svg: PropTypes.string
};
const mapDispatchToProps = dispatch => ({
diff --git a/src/containers/paper-canvas.jsx b/src/containers/paper-canvas.jsx
index 4ccb0b58..fdd6e44d 100644
--- a/src/containers/paper-canvas.jsx
+++ b/src/containers/paper-canvas.jsx
@@ -7,27 +7,50 @@ class PaperCanvas extends React.Component {
constructor (props) {
super(props);
bindAll(this, [
- 'setCanvas'
+ 'setCanvas',
+ 'importSvg'
]);
}
componentDidMount () {
paper.setup(this.canvas);
- // Create a Paper.js Path to draw a line into it:
- const path = new paper.Path();
- // Give the stroke a color
- path.strokeColor = 'black';
- const start = new paper.Point(100, 100);
- // Move to start and draw a line from there
- path.moveTo(start);
- // Note that the plus operator on Point objects does not work
- // in JavaScript. Instead, we need to call the add() function:
- path.lineTo(start.add([200, -50]));
- // Draw the view now:
- paper.view.draw();
+ if (this.props.svg) {
+ this.importSvg(this.props.svg, this.props.rotationCenterX, this.props.rotationCenterY);
+ }
+ }
+ componentWillReceiveProps (newProps) {
+ paper.project.activeLayer.removeChildren();
+ this.importSvg(newProps.svg, newProps.rotationCenterX, newProps.rotationCenterY);
}
componentWillUnmount () {
paper.remove();
}
+ importSvg (svg, rotationCenterX, rotationCenterY) {
+ const imported = paper.project.importSVG(svg,
+ {
+ expandShapes: true,
+ onLoad: function (item) {
+ // Remove viewbox
+ if (item.clipped) {
+ item.clipped = false;
+ // Consider removing clip mask here?
+ }
+ while (item.reduce() !== item) {
+ item = item.reduce();
+ }
+ }
+ });
+ if (typeof rotationCenterX !== 'undefined' && typeof rotationCenterY !== 'undefined') {
+ imported.position =
+ paper.project.view.center
+ .add(imported.bounds.width / 2, imported.bounds.height / 2)
+ .subtract(rotationCenterX, rotationCenterY);
+ } else {
+ // Center
+ imported.position = paper.project.view.center;
+ }
+
+ paper.project.view.update();
+ }
setCanvas (canvas) {
this.canvas = canvas;
if (this.props.canvasRef) {
@@ -44,7 +67,10 @@ class PaperCanvas extends React.Component {
}
PaperCanvas.propTypes = {
- canvasRef: PropTypes.func
+ canvasRef: PropTypes.func,
+ rotationCenterX: PropTypes.number,
+ rotationCenterY: PropTypes.number,
+ svg: PropTypes.string
};
export default PaperCanvas;
diff --git a/src/playground/playground.jsx b/src/playground/playground.jsx
index 9f68704a..f59ef2b0 100644
--- a/src/playground/playground.jsx
+++ b/src/playground/playground.jsx
@@ -13,10 +13,28 @@ const store = createStore(
intlInitialState,
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
);
+const svgString =
+ '';
+const onUpdateSvg = function (newSvgString, rotationCenterX, rotationCenterY) {
+ console.log(newSvgString);
+ console.log(`rotationCenterX: ${rotationCenterX} rotationCenterY: ${rotationCenterY}`);
+};
ReactDOM.render((
-
+
), appTarget);