From 77eddb1be88013416fe3ce5efcd16681fda05479 Mon Sep 17 00:00:00 2001 From: Asturur Date: Sun, 11 Jun 2017 22:27:30 +0200 Subject: [PATCH 1/3] switch to request animation frame --- src/brushes/circle_brush.class.js | 2 +- src/brushes/pencil_brush.class.js | 4 +- src/brushes/spray_brush.class.js | 2 +- src/canvas.class.js | 2 +- src/mixins/animation.mixin.js | 6 +-- src/mixins/canvas_events.mixin.js | 8 ++-- src/mixins/canvas_gestures.mixin.js | 2 +- src/mixins/canvas_grouping.mixin.js | 2 +- src/mixins/canvas_serialization.mixin.js | 4 +- src/mixins/collection.mixin.js | 6 +-- src/mixins/itext_behavior.mixin.js | 2 +- src/mixins/itext_key_behavior.mixin.js | 10 ++--- src/mixins/object_straightening.mixin.js | 2 +- src/static_canvas.class.js | 47 ++++++++++++++++++------ test/unit/collection.js | 2 +- 15 files changed, 62 insertions(+), 39 deletions(-) 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..33e280a94e6 100644 --- a/src/canvas.class.js +++ b/src/canvas.class.js @@ -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/canvas_serialization.mixin.js b/src/mixins/canvas_serialization.mixin.js index 8788bf22eab..05eade5db0a 100644 --- a/src/mixins/canvas_serialization.mixin.js +++ b/src/mixins/canvas_serialization.mixin.js @@ -91,7 +91,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati var cbIfLoaded = function () { if (loaded.backgroundImage && loaded.overlayImage && loaded.backgroundColor && loaded.overlayColor) { - _this.renderAll(); + _this.requestRenderAll(); callback && callback(); } }; @@ -215,7 +215,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati clone.clipTo = this.clipTo; if (this.backgroundImage) { clone.setBackgroundImage(this.backgroundImage.src, function() { - clone.renderAll(); + clone.requestRenderAll(); callback && callback(clone); }); clone.backgroundImageOpacity = this.backgroundImageOpacity; diff --git a/src/mixins/collection.mixin.js b/src/mixins/collection.mixin.js index fbd7ae1156b..48fa7319c85 100644 --- a/src/mixins/collection.mixin.js +++ b/src/mixins/collection.mixin.js @@ -21,7 +21,7 @@ fabric.Collection = { this._onObjectAdded(arguments[i]); } } - this.renderOnAddRemove && this.renderAll(); + this.renderOnAddRemove && this.requestRenderAll(); return this; }, @@ -43,7 +43,7 @@ fabric.Collection = { objects.splice(index, 0, object); } this._onObjectAdded && this._onObjectAdded(object); - this.renderOnAddRemove && this.renderAll(); + this.renderOnAddRemove && this.requestRenderAll(); return this; }, @@ -68,7 +68,7 @@ fabric.Collection = { } } - this.renderOnAddRemove && somethingRemoved && this.renderAll(); + this.renderOnAddRemove && somethingRemoved && this.requestRenderAll(); return this; }, 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/mixins/object_straightening.mixin.js b/src/mixins/object_straightening.mixin.js index 0c3e30aa04b..273f94f5b2c 100644 --- a/src/mixins/object_straightening.mixin.js +++ b/src/mixins/object_straightening.mixin.js @@ -69,7 +69,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati */ straightenObject: function (object) { object.straighten(); - this.renderAll(); + this.requestRenderAll(); return this; }, diff --git a/src/static_canvas.class.js b/src/static_canvas.class.js index b64efe755de..ab8f2514285 100644 --- a/src/static_canvas.class.js +++ b/src/static_canvas.class.js @@ -40,8 +40,8 @@ */ initialize: function(el, options) { options || (options = { }); - this._initStatic(el, options); + this.renderAndResetBound = this.renderAndReset.bind(this); }, /** @@ -599,7 +599,7 @@ this.calcOffset(); if (!options.cssOnly) { - this.renderAll(); + this.requestRenderAll(); } return this; @@ -676,7 +676,7 @@ activeGroup.setCoords(ingoreVpt, skipAbsolute); } this.calcViewportBoundaries(); - this.renderAll(); + this.requestRenderAll(); return this; }, @@ -803,7 +803,7 @@ } this.clearContext(this.contextContainer); this.fire('canvas:cleared'); - this.renderAll(); + this.requestRenderAll(); return this; }, @@ -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 @@ -1031,7 +1056,7 @@ */ _centerObject: function(object, center) { object.setPositionByOrigin(center, 'center', 'center'); - this.renderAll(); + this.requestRenderAll(); return this; }, @@ -1424,7 +1449,7 @@ removeFromArray(this._objects, object); this._objects.unshift(object); } - return this.renderAll && this.renderAll(); + return this.requestRenderAll(); }, /** @@ -1452,7 +1477,7 @@ removeFromArray(this._objects, object); this._objects.push(object); } - return this.renderAll && this.renderAll(); + return this.requestRenderAll(); }, /** @@ -1490,8 +1515,7 @@ this._objects.splice(newIdx, 0, object); } } - this.renderAll && this.renderAll(); - return this; + return this.requestRenderAll(); }, /** @@ -1558,8 +1582,7 @@ this._objects.splice(newIdx, 0, object); } } - this.renderAll && this.renderAll(); - return this; + return this.requestRenderAll(); }, /** @@ -1601,7 +1624,7 @@ moveTo: function (object, index) { removeFromArray(this._objects, object); this._objects.splice(index, 0, object); - return this.renderAll && this.renderAll(); + return this.requestRenderAll(); }, /** diff --git a/test/unit/collection.js b/test/unit/collection.js index 57708ad9be6..2a36eba0652 100644 --- a/test/unit/collection.js +++ b/test/unit/collection.js @@ -12,7 +12,7 @@ } }); - collection.renderAll = function() { + collection.requestRenderAll = function() { this.rendered++; }; From 507ed89100fca0d7cfb6d4bbfe56d9dccc671c15 Mon Sep 17 00:00:00 2001 From: Asturur Date: Sun, 11 Jun 2017 23:00:36 +0200 Subject: [PATCH 2/3] added request animation frame --- src/mixins/canvas_serialization.mixin.js | 4 ++-- src/mixins/collection.mixin.js | 6 +++--- src/mixins/object_straightening.mixin.js | 2 +- src/static_canvas.class.js | 22 +++++++++++++--------- test/unit/collection.js | 2 +- 5 files changed, 20 insertions(+), 16 deletions(-) diff --git a/src/mixins/canvas_serialization.mixin.js b/src/mixins/canvas_serialization.mixin.js index 05eade5db0a..8788bf22eab 100644 --- a/src/mixins/canvas_serialization.mixin.js +++ b/src/mixins/canvas_serialization.mixin.js @@ -91,7 +91,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati var cbIfLoaded = function () { if (loaded.backgroundImage && loaded.overlayImage && loaded.backgroundColor && loaded.overlayColor) { - _this.requestRenderAll(); + _this.renderAll(); callback && callback(); } }; @@ -215,7 +215,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati clone.clipTo = this.clipTo; if (this.backgroundImage) { clone.setBackgroundImage(this.backgroundImage.src, function() { - clone.requestRenderAll(); + clone.renderAll(); callback && callback(clone); }); clone.backgroundImageOpacity = this.backgroundImageOpacity; diff --git a/src/mixins/collection.mixin.js b/src/mixins/collection.mixin.js index 48fa7319c85..fbd7ae1156b 100644 --- a/src/mixins/collection.mixin.js +++ b/src/mixins/collection.mixin.js @@ -21,7 +21,7 @@ fabric.Collection = { this._onObjectAdded(arguments[i]); } } - this.renderOnAddRemove && this.requestRenderAll(); + this.renderOnAddRemove && this.renderAll(); return this; }, @@ -43,7 +43,7 @@ fabric.Collection = { objects.splice(index, 0, object); } this._onObjectAdded && this._onObjectAdded(object); - this.renderOnAddRemove && this.requestRenderAll(); + this.renderOnAddRemove && this.renderAll(); return this; }, @@ -68,7 +68,7 @@ fabric.Collection = { } } - this.renderOnAddRemove && somethingRemoved && this.requestRenderAll(); + this.renderOnAddRemove && somethingRemoved && this.renderAll(); return this; }, diff --git a/src/mixins/object_straightening.mixin.js b/src/mixins/object_straightening.mixin.js index 273f94f5b2c..0c3e30aa04b 100644 --- a/src/mixins/object_straightening.mixin.js +++ b/src/mixins/object_straightening.mixin.js @@ -69,7 +69,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati */ straightenObject: function (object) { object.straighten(); - this.requestRenderAll(); + this.renderAll(); return this; }, diff --git a/src/static_canvas.class.js b/src/static_canvas.class.js index ab8f2514285..429369638c7 100644 --- a/src/static_canvas.class.js +++ b/src/static_canvas.class.js @@ -599,7 +599,7 @@ this.calcOffset(); if (!options.cssOnly) { - this.requestRenderAll(); + this.renderAll(); } return this; @@ -676,7 +676,7 @@ activeGroup.setCoords(ingoreVpt, skipAbsolute); } this.calcViewportBoundaries(); - this.requestRenderAll(); + this.renderAll(); return this; }, @@ -803,7 +803,7 @@ } this.clearContext(this.contextContainer); this.fire('canvas:cleared'); - this.requestRenderAll(); + this.renderAll(); return this; }, @@ -1056,7 +1056,7 @@ */ _centerObject: function(object, center) { object.setPositionByOrigin(center, 'center', 'center'); - this.requestRenderAll(); + this.renderAll(); return this; }, @@ -1449,7 +1449,8 @@ removeFromArray(this._objects, object); this._objects.unshift(object); } - return this.requestRenderAll(); + this.renderAll && this.renderAll(); + return this; }, /** @@ -1477,7 +1478,8 @@ removeFromArray(this._objects, object); this._objects.push(object); } - return this.requestRenderAll(); + this.renderAll && this.renderAll(); + return this; }, /** @@ -1515,7 +1517,8 @@ this._objects.splice(newIdx, 0, object); } } - return this.requestRenderAll(); + this.renderAll && this.renderAll(); + return this; }, /** @@ -1582,7 +1585,8 @@ this._objects.splice(newIdx, 0, object); } } - return this.requestRenderAll(); + this.renderAll && this.renderAll(); + return this; }, /** @@ -1624,7 +1628,7 @@ moveTo: function (object, index) { removeFromArray(this._objects, object); this._objects.splice(index, 0, object); - return this.requestRenderAll(); + return this.renderAll && this.renderAll(); }, /** diff --git a/test/unit/collection.js b/test/unit/collection.js index 2a36eba0652..57708ad9be6 100644 --- a/test/unit/collection.js +++ b/test/unit/collection.js @@ -12,7 +12,7 @@ } }); - collection.requestRenderAll = function() { + collection.renderAll = function() { this.rendered++; }; From 977c8ee45d7ab7710c75ab0462a1c61da5bfc27e Mon Sep 17 00:00:00 2001 From: Asturur Date: Sun, 11 Jun 2017 23:11:31 +0200 Subject: [PATCH 3/3] fix --- src/canvas.class.js | 2 +- src/static_canvas.class.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/canvas.class.js b/src/canvas.class.js index 33e280a94e6..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(); diff --git a/src/static_canvas.class.js b/src/static_canvas.class.js index 429369638c7..cf9537121e1 100644 --- a/src/static_canvas.class.js +++ b/src/static_canvas.class.js @@ -40,8 +40,8 @@ */ initialize: function(el, options) { options || (options = { }); - this._initStatic(el, options); this.renderAndResetBound = this.renderAndReset.bind(this); + this._initStatic(el, options); }, /**