mirror of
https://github.com/Hopiu/fabric.js.git
synced 2026-04-09 17:01:01 +00:00
Introduce fabric.Element#stateful and fabric.Element#renderOnAddition options, as a way to improve performance. Note that setting "renderOnAddition" to false could give a pretty significant performance boost when adding a lot of objects to canvas at once, since fabric.Element#add would not re-render canvas on each addition. Once added, the canvas should be re-rendered manually, via renderAll method.
This commit is contained in:
parent
848f7990b4
commit
da6b00fc0e
3 changed files with 50 additions and 21 deletions
|
|
@ -127,5 +127,6 @@
|
|||
*/
|
||||
fabric.Circle.fromObject = function(object) {
|
||||
return new fabric.Circle(object);
|
||||
}
|
||||
};
|
||||
|
||||
})(this);
|
||||
|
|
@ -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');
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue