diff --git a/src/circle.class.js b/src/circle.class.js index d38e415c..dd858bc2 100644 --- a/src/circle.class.js +++ b/src/circle.class.js @@ -127,5 +127,6 @@ */ fabric.Circle.fromObject = function(object) { return new fabric.Circle(object); - } + }; + })(this); \ No newline at end of file diff --git a/src/element.class.js b/src/element.class.js index 2eccda4b..3dbe05a1 100644 --- a/src/element.class.js +++ b/src/element.class.js @@ -112,7 +112,7 @@ * @property _config * @type object */ - this._config = { + this._config = { width: 300, height: 150 }; @@ -192,6 +192,20 @@ */ shouldCacheImages: false, + /** + * Indicates whether objects' state should be saved + * @property + * @type Boolean + */ + stateful: true, + + /** + * Indicates whether fabric.Element#add should also re-render canvas. + * Disabling this option could give a great performance boost when adding a lot of objects to canvas at once + * (followed by a manual rendering after addition) + */ + renderOnAddition: true, + /** * @constant * @type Number @@ -218,9 +232,7 @@ * @method onFpsUpdate * @param {Number} fps */ - onFpsUpdate: function(fps) { - /* NOOP */ - }, + onFpsUpdate: null, /** * Calculates canvas element offset relative to the document @@ -330,6 +342,10 @@ _initConfig: function (config) { extend(this._config, config || { }); + for (var prop in this._config) { + this[prop] = this._config[prop]; + } + this._config.width = parseInt(this._element.width, 10) || 0; this._config.height = parseInt(this._element.height, 10) || 0; @@ -528,7 +544,7 @@ } // only fire :modified event if target coordinates were changed during mousedown-mouseup - if (target.hasStateChanged()) { + if (this.stateful && target.hasStateChanged()) { target.isMoving = false; fireEvent('object:modified', { target: target }); } @@ -542,7 +558,7 @@ } var activeGroup = this.getActiveGroup(); if (activeGroup) { - if (activeGroup.hasStateChanged() && + if (this.stateful && activeGroup.hasStateChanged() && activeGroup.containsPoint(this.getPointer(e))) { fireEvent('group:modified', { target: activeGroup }); } @@ -624,7 +640,7 @@ else { // determine if it's a drag or rotate case // rotate and scale will happen at the same time - target.saveState(); + this.stateful && target.saveState(); if (corner = target._findTargetCorner(e, this._offset)) { this.onBeforeScaleRotate(target); @@ -1123,7 +1139,12 @@ */ add: function () { this._objects.push.apply(this._objects, arguments); - this.renderAll(); + if (this.stateful) { + for (var i = arguments.length; i--; ) { + arguments[i].setupState(); + } + } + this.renderOnAddition && this.renderAll(); return this; }, @@ -1212,9 +1233,8 @@ containerCanvas.fillRect(0, 0, w, h); var length = this._objects.length, - activeGroup = this.getActiveGroup(); - - var startTime = new Date(); + activeGroup = this.getActiveGroup(), + startTime = new Date(); if (length) { for (var i = 0; i < length; ++i) { @@ -1235,8 +1255,10 @@ this.contextTop.drawImage(this.overlayImage, 0, 0); } - var elapsedTime = new Date() - startTime; - this.onFpsUpdate(~~(1000 / elapsedTime)); + if (this.onFpsUpdate) { + var elapsedTime = new Date() - startTime; + this.onFpsUpdate(~~(1000 / elapsedTime)); + } fireEvent('after:render'); diff --git a/src/object.class.js b/src/object.class.js index c958961b..fbf40b31 100644 --- a/src/object.class.js +++ b/src/object.class.js @@ -119,12 +119,8 @@ this.setOptions(options); // "import" state properties into an instance this._importProperties(); - // create "local" members - this.originalState = { }; // set initial coords this.setCoords(); - // setup state properties - this.saveState(); }, /** @@ -167,11 +163,13 @@ * @method _importProperties */ _importProperties: function() { - this.stateProperties.forEach(function(prop) { - (prop === 'angle') + var i = this.stateProperties.length, prop; + while (i--) { + prop = this.stateProperties[i]; + (prop === 'angle') ? this.setAngle(this.options[prop]) : (this[prop] = this.options[prop]); - }, this); + } }, /** @@ -748,6 +746,14 @@ return this; }, + /** + * @method setupState + */ + setupState: function() { + this.originalState = { }; + this.saveState(); + }, + /** * Returns true if object intersects with an area formed by 2 points * @method intersectsWithRect