diff --git a/src/brushes/circle_brush.class.js b/src/brushes/circle_brush.class.js index 26642d1a8f3..b0dc9bd13b9 100644 --- a/src/brushes/circle_brush.class.js +++ b/src/brushes/circle_brush.class.js @@ -92,7 +92,7 @@ fabric.CircleBrush = fabric.util.createClass(fabric.BaseBrush, /** @lends fabric this.canvas.clearContext(this.canvas.contextTop); this._resetShadow(); this.canvas.renderOnAddRemove = originalRenderOnAddRemove; - this.canvas.renderAll(); + this.canvas.requestRenderAll(); }, /** diff --git a/src/brushes/pencil_brush.class.js b/src/brushes/pencil_brush.class.js index 0905163a0bd..3c473509bad 100644 --- a/src/brushes/pencil_brush.class.js +++ b/src/brushes/pencil_brush.class.js @@ -197,7 +197,7 @@ // rendered inconsistently across browsers // Firefox 4, for example, renders a dot, // whereas Chrome 10 renders nothing - this.canvas.renderAll(); + this.canvas.requestRenderAll(); return; } @@ -208,7 +208,7 @@ this.canvas.clearContext(this.canvas.contextTop); this._resetShadow(); - this.canvas.renderAll(); + this.canvas.requestRenderAll(); // fire event 'path' created this.canvas.fire('path:created', { path: path }); diff --git a/src/brushes/spray_brush.class.js b/src/brushes/spray_brush.class.js index 5cff07eea87..95cf9706a36 100644 --- a/src/brushes/spray_brush.class.js +++ b/src/brushes/spray_brush.class.js @@ -120,7 +120,7 @@ fabric.SprayBrush = fabric.util.createClass( fabric.BaseBrush, /** @lends fabric this.canvas.clearContext(this.canvas.contextTop); this._resetShadow(); this.canvas.renderOnAddRemove = originalRenderOnAddRemove; - this.canvas.renderAll(); + this.canvas.requestRenderAll(); }, /** diff --git a/src/canvas.class.js b/src/canvas.class.js index c9ba06ed43d..7c0d38f4e2e 100644 --- a/src/canvas.class.js +++ b/src/canvas.class.js @@ -45,7 +45,7 @@ */ initialize: function(el, options) { options || (options = { }); - + this.renderAndResetBound = this.renderAndReset.bind(this); this._initStatic(el, options); this._initInteractive(); this._createCacheCanvas(); @@ -1396,7 +1396,7 @@ this._setActiveObject(object); this.fire('object:selected', { target: object, e: e }); object.fire('selected', { e: e }); - this.renderAll(); + this.requestRenderAll(); return this; }, diff --git a/src/mixins/animation.mixin.js b/src/mixins/animation.mixin.js index a5e2d37fb6f..edb837dce52 100644 --- a/src/mixins/animation.mixin.js +++ b/src/mixins/animation.mixin.js @@ -30,7 +30,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati duration: this.FX_DURATION, onChange: function(value) { object.set('left', value); - _this.renderAll(); + _this.requestRenderAll(); onChange(); }, onComplete: function() { @@ -65,7 +65,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati duration: this.FX_DURATION, onChange: function(value) { object.set('top', value); - _this.renderAll(); + _this.requestRenderAll(); onChange(); }, onComplete: function() { @@ -103,7 +103,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati }, onChange: function(value) { object.set('opacity', value); - _this.renderAll(); + _this.requestRenderAll(); onChange(); }, onComplete: function () { diff --git a/src/mixins/canvas_events.mixin.js b/src/mixins/canvas_events.mixin.js index a48cf3e8696..fc758cc478d 100644 --- a/src/mixins/canvas_events.mixin.js +++ b/src/mixins/canvas_events.mixin.js @@ -368,7 +368,7 @@ this._setCursorFromEvent(e, target); this._handleEvent(e, 'up', target ? target : null, LEFT_CLICK, isClick); target && (target.__corner = 0); - shouldRender && this.renderAll(); + shouldRender && this.requestRenderAll(); }, /** @@ -447,7 +447,7 @@ */ _onMouseDownInDrawingMode: function(e) { this._isCurrentlyDrawing = true; - this.discardActiveObject(e).renderAll(); + this.discardActiveObject(e).requestRenderAll(); if (this.clipTo) { fabric.util.clipContext(this, this.contextTop); } @@ -559,7 +559,7 @@ } this._handleEvent(e, 'down', target ? target : null); // we must renderAll so that we update the visuals - shouldRender && this.renderAll(); + shouldRender && this.requestRenderAll(); }, /** @@ -681,7 +681,7 @@ this._beforeScaleTransform(e, transform); this._performTransformAction(e, transform, pointer); - transform.actionPerformed && this.renderAll(); + transform.actionPerformed && this.requestRenderAll(); }, /** diff --git a/src/mixins/canvas_gestures.mixin.js b/src/mixins/canvas_gestures.mixin.js index d48a02bdcc4..961bd297e9e 100644 --- a/src/mixins/canvas_gestures.mixin.js +++ b/src/mixins/canvas_gestures.mixin.js @@ -64,7 +64,7 @@ this._setCenterToOrigin(t.target); - this.renderAll(); + this.requestRenderAll(); t.action = 'drag'; }, diff --git a/src/mixins/canvas_grouping.mixin.js b/src/mixins/canvas_grouping.mixin.js index c6f0d9420a3..4eb16286e25 100644 --- a/src/mixins/canvas_grouping.mixin.js +++ b/src/mixins/canvas_grouping.mixin.js @@ -123,7 +123,7 @@ group.addWithUpdate(); this.setActiveGroup(group, e); this.fire('selection:created', { target: group, e: e }); - this.renderAll(); + this.requestRenderAll(); } }, diff --git a/src/mixins/itext_behavior.mixin.js b/src/mixins/itext_behavior.mixin.js index f6742750fe7..897e532b1dd 100644 --- a/src/mixins/itext_behavior.mixin.js +++ b/src/mixins/itext_behavior.mixin.js @@ -347,7 +347,7 @@ } this.canvas.fire('text:editing:entered', { target: this }); this.initMouseMoveHandler(); - this.canvas.renderAll(); + this.canvas.requestRenderAll(); return this; }, diff --git a/src/mixins/itext_key_behavior.mixin.js b/src/mixins/itext_key_behavior.mixin.js index a6fbac4f4e6..5a2cc76b2fb 100644 --- a/src/mixins/itext_key_behavior.mixin.js +++ b/src/mixins/itext_key_behavior.mixin.js @@ -93,7 +93,7 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot this.renderCursorOrSelection(); } else { - this.canvas && this.canvas.renderAll(); + this.canvas && this.canvas.requestRenderAll(); } }, @@ -116,7 +116,7 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot } e.stopImmediatePropagation(); e.preventDefault(); - this.canvas && this.canvas.renderAll(); + this.canvas && this.canvas.requestRenderAll(); }, /** @@ -143,7 +143,7 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot this.fire('changed'); if (this.canvas) { this.canvas.fire('text:changed', { target: this }); - this.canvas.renderAll(); + this.canvas.requestRenderAll(); } } @@ -184,7 +184,7 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot this.fire('changed'); if (this.canvas) { this.canvas.fire('text:changed', { target: this }); - this.canvas.renderAll(); + this.canvas.requestRenderAll(); } }, /** @@ -592,7 +592,7 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot this._removeExtraneousStyles(); - this.canvas && this.canvas.renderAll(); + this.canvas && this.canvas.requestRenderAll(); this.setCoords(); this.fire('changed'); diff --git a/src/static_canvas.class.js b/src/static_canvas.class.js index b64efe755de..cf9537121e1 100644 --- a/src/static_canvas.class.js +++ b/src/static_canvas.class.js @@ -40,7 +40,7 @@ */ initialize: function(el, options) { options || (options = { }); - + this.renderAndResetBound = this.renderAndReset.bind(this); this._initStatic(el, options); }, @@ -818,6 +818,31 @@ return this; }, + /** + * Function created to be instance bound at initialization + * used in requestAnimationFrame rendering + * @return {fabric.Canvas} instance + * @chainable + */ + renderAndReset: function() { + this.renderAll(); + this.isRendering = false; + }, + + /** + * Append a renderAll request to next animation frame. + * a boolean flag will avoid appending more. + * @return {fabric.Canvas} instance + * @chainable + */ + requestRenderAll: function () { + if (!this.isRendering) { + this.isRendering = true; + fabric.util.requestAnimFrame(this.renderAndResetBound); + } + return this; + }, + /** * Calculate the position of the 4 corner of canvas with current viewportTransform. * helps to determinate when an object is in the current rendering viewport using @@ -1424,7 +1449,8 @@ removeFromArray(this._objects, object); this._objects.unshift(object); } - return this.renderAll && this.renderAll(); + this.renderAll && this.renderAll(); + return this; }, /** @@ -1452,7 +1478,8 @@ removeFromArray(this._objects, object); this._objects.push(object); } - return this.renderAll && this.renderAll(); + this.renderAll && this.renderAll(); + return this; }, /**