1+ /*eslint no-unused-vars: 0*/
12'use strict' ;
3+
24import React from 'react' ;
35import ReactDOM from 'react-dom' ;
6+
47import History from './history' ;
58import { uuid4 } from './utils' ;
69
@@ -34,7 +37,11 @@ class SketchField extends React.Component {
3437 // image format when calling toDataURL
3538 imageFormat : React . PropTypes . string ,
3639 // Scale the drawing when we resize the canvas
37- scaleOnResize : React . PropTypes . bool
40+ scaleOnResize : React . PropTypes . bool ,
41+ // Default initial data
42+ defaultData : React . PropTypes . object ,
43+ // Type of initial data
44+ defaultDataType : React . PropTypes . oneOf ( [ 'json' , 'url' ] )
3845 } ;
3946
4047 static defaultProps = {
@@ -44,7 +51,8 @@ class SketchField extends React.Component {
4451 opacity : 1.0 ,
4552 undoSteps : 15 ,
4653 scaleOnResize : true ,
47- tool : Tool . Pencil
54+ tool : Tool . Pencil ,
55+ defaultDataType : 'json'
4856 } ;
4957
5058 constructor ( props , context ) {
@@ -65,18 +73,23 @@ class SketchField extends React.Component {
6573 }
6674
6775 componentDidMount ( ) {
76+ let { tool,
77+ undoSteps,
78+ defaultData,
79+ defaultDataType} = this . props ;
80+
6881 let canvas = this . _fc = new fabric . Canvas ( this . _canvas . id ) ;
6982 this . _initTools ( canvas ) ;
7083
71- let tool = this . _tools [ this . props . tool ] ;
72- tool . configureCanvas ( this . props ) ;
84+ let selectedTool = this . _tools [ tool ] ;
85+ selectedTool . configureCanvas ( this . props ) ;
7386
7487 // Control resize
7588 window . addEventListener ( 'resize' , this . _resize , false ) ;
7689 this . _resize ( null ) ;
7790
7891 // Initialize History, with maximum number of undo steps
79- this . _history = new History ( this . props . undoSteps ) ;
92+ this . _history = new History ( undoSteps ) ;
8093
8194 // Events binding
8295 canvas . on ( 'object:added' , this . _onObjectAdded ) ;
@@ -86,6 +99,18 @@ class SketchField extends React.Component {
8699 canvas . on ( 'mouse:move' , this . _onMouseMove ) ;
87100 canvas . on ( 'mouse:up' , this . _onMouseUp ) ;
88101 canvas . on ( 'mouse:out' , this . _onMouseOut ) ;
102+
103+ // initialize canvas with default data
104+ setTimeout ( ( ) => {
105+ if ( defaultData ) {
106+ if ( 'json' === defaultDataType ) {
107+ this . fromJson ( defaultData ) ;
108+ }
109+ if ( 'url' === defaultDataType ) {
110+ this . fromDataURL ( defaultData ) ;
111+ }
112+ }
113+ } , 100 )
89114 }
90115
91116 _initTools ( fabricCanvas ) {
@@ -102,11 +127,8 @@ class SketchField extends React.Component {
102127 }
103128
104129 componentWillReceiveProps ( props ) {
105- //if (this.props.tool !== props.tool) {
106- // tool has changed
107130 let tool = this . _tools [ props . tool ] || this . _tools [ 'pencil' ] ;
108131 tool . configureCanvas ( props ) ;
109- //}
110132 }
111133
112134 _onObjectAdded ( e ) {
@@ -154,17 +176,19 @@ class SketchField extends React.Component {
154176 if ( tool ) {
155177 tool . doMouseUp ( e ) ;
156178 }
157- //// there is no direct on change event
158- //if (this.props.onChange) {
159- // this.props.onChange(event.e, this._fc.toDataURL('png'));
160- //}
179+ if ( this . props . onChange ) {
180+ this . props . onChange ( event . e ) ;
181+ }
161182 }
162183
163184 _onMouseOut ( e ) {
164185 let tool = this . _tools [ this . props . tool ] ;
165186 if ( tool ) {
166187 tool . doMouseOut ( e ) ;
167188 }
189+ if ( this . props . onChange ) {
190+ this . props . onChange ( event . e ) ;
191+ }
168192 }
169193
170194 /**
@@ -244,6 +268,7 @@ class SketchField extends React.Component {
244268 let history = this . _history ;
245269 if ( history . canRedo ( ) ) {
246270 let canvas = this . _fc ;
271+ //noinspection Eslint
247272 let [ obj , prevState , currState ] = history . redo ( ) ;
248273 if ( obj . version === 0 ) {
249274 this . setState ( { action : false } , ( ) => {
@@ -278,12 +303,65 @@ class SketchField extends React.Component {
278303 }
279304
280305 /**
281- * Get the current content from Canvas
306+ * Exports canvas element to a dataurl image. Note that when multiplier is used, cropping is scaled appropriately
307+ *
308+ * Available Options are
309+ * <table style="width:100%">
310+ *
311+ * <tr><td><b>Name</b></td><td><b>Type</b></td><td><b>Argument</b></td><td><b>Default</b></td><td><b>Description</b></td></tr>
312+ * <tr><td>format</td> <td>String</td> <td><optional></td><td>png</td><td>The format of the output image. Either "jpeg" or "png"</td></tr>
313+ * <tr><td>quality</td><td>Number</td><td><optional></td><td>1</td><td>Quality level (0..1). Only used for jpeg.</td></tr>
314+ * <tr><td>multiplier</td><td>Number</td><td><optional></td><td>1</td><td>Multiplier to scale by</td></tr>
315+ * <tr><td>left</td><td>Number</td><td><optional></td><td></td><td>Cropping left offset. Introduced in v1.2.14</td></tr>
316+ * <tr><td>top</td><td>Number</td><td><optional></td><td></td><td>Cropping top offset. Introduced in v1.2.14</td></tr>
317+ * <tr><td>width</td><td>Number</td><td><optional></td><td></td><td>Cropping width. Introduced in v1.2.14</td></tr>
318+ * <tr><td>height</td><td>Number</td><td><optional></td><td></td><td>Cropping height. Introduced in v1.2.14</td></tr>
319+ *
320+ * </table>
321+ *
322+ * @returns {String } URL containing a representation of the object in the format specified by options.format
323+ */
324+ toDataURL ( options ) {
325+ return this . _fc . toDataURL ( options ) ;
326+ }
327+
328+ /**
329+ * Returns JSON representation of canvas
330+ *
331+ * @param propertiesToInclude Array <optional>
332+ Any properties that you might want to additionally include in the output
333+ * @returns {string } JSON string
334+ */
335+ toJSON ( propertiesToInclude ) {
336+ return this . _fc . toJSON ( propertiesToInclude ) ;
337+ }
338+
339+ /**
340+ * Populates canvas with data from the specified JSON.
282341 *
283- * @returns {null } the data of the canvas
342+ * JSON format must conform to the one of fabric.Canvas#toDatalessJSON
343+ *
344+ * @param json JSON string or object
345+ * @param callback Callback, invoked when json is parsed and corresponding objects (e.g: fabric.Image) are initialized
346+ * @param reviver Method for further parsing of JSON elements, called after each fabric object created.
347+
284348 */
285- getContent ( ) {
286- return this . state . content ;
349+ fromJson ( json ) {
350+ let canvas = this . _fc ;
351+ canvas . loadFromJSON ( json , ( ) => canvas . renderAll ( ) ) ;
352+ }
353+
354+ /**
355+ * This method will create an image and load the given url data
356+ *
357+ * @param data URL data to load as image
358+ * @param options options to be applied to image <optional>
359+ */
360+ fromDataURL ( data , options = { } ) {
361+ let canvas = this . _fc ;
362+ let img = new Image ( ) ;
363+ img . src = data ;
364+ img . onload = ( ) => canvas . add ( new fabric . Image ( img , options ) ) ;
287365 }
288366
289367 /**
@@ -304,7 +382,7 @@ class SketchField extends React.Component {
304382 ...other
305383 } = this . props ;
306384 return (
307- < div className = { className } style = { style } ref = { ( c ) => this . _canvasWrapper = c } >
385+ < div className = { className } style = { style } >
308386 < canvas
309387 id = { uuid4 ( ) }
310388 height = { height || 512 }
0 commit comments