From b63a943137d0af167f6723a7cd7dd0c5a1932474 Mon Sep 17 00:00:00 2001 From: Kienz Date: Wed, 7 Aug 2013 21:01:45 +0200 Subject: [PATCH] Renamed property renderOnAddition to renderOnAddRemove fabric.Canvas.renderAll can now be disabled on removing objects (renderOnAddRemove = false) Add tests for renderOnAddRemove (add, insertAt and remove) jsdoc additions --- src/brushes/circle_brush.class.js | 6 +- src/brushes/spray_brush.class.js | 6 +- src/mixins/canvas_serialization.mixin.js | 6 +- src/mixins/collection.mixin.js | 25 +++---- src/static_canvas.class.js | 29 ++++++-- test/unit/canvas_static.js | 93 ++++++++++++++++++++++++ 6 files changed, 136 insertions(+), 29 deletions(-) diff --git a/src/brushes/circle_brush.class.js b/src/brushes/circle_brush.class.js index a52f7ff1..e54d69bf 100644 --- a/src/brushes/circle_brush.class.js +++ b/src/brushes/circle_brush.class.js @@ -57,8 +57,8 @@ fabric.CircleBrush = fabric.util.createClass( fabric.BaseBrush, /** @lends fabri * Invoked on mouse up */ onMouseUp: function() { - var originalRenderOnAddition = this.canvas.renderOnAddition; - this.canvas.renderOnAddition = false; + var originalRenderOnAddRemove = this.canvas.renderOnAddRemove; + this.canvas.renderOnAddRemove = false; for (var i = 0, len = this.points.length; i < len; i++) { var point = this.points[i]; @@ -84,7 +84,7 @@ fabric.CircleBrush = fabric.util.createClass( fabric.BaseBrush, /** @lends fabri this.canvas.clearContext(this.canvas.contextTop); this.removeShadowStyles(); - this.canvas.renderOnAddition = originalRenderOnAddition; + this.canvas.renderOnAddRemove = originalRenderOnAddRemove; this.canvas.renderAll(); }, diff --git a/src/brushes/spray_brush.class.js b/src/brushes/spray_brush.class.js index 9c312253..e66647e9 100644 --- a/src/brushes/spray_brush.class.js +++ b/src/brushes/spray_brush.class.js @@ -75,8 +75,8 @@ fabric.SprayBrush = fabric.util.createClass( fabric.BaseBrush, /** @lends fabric * Invoked on mouse up */ onMouseUp: function() { - var originalRenderOnAddition = this.canvas.renderOnAddition; - this.canvas.renderOnAddition = false; + var originalRenderOnAddRemove = this.canvas.renderOnAddRemove; + this.canvas.renderOnAddRemove = false; for (var i = 0, ilen = this.sprayChunks.length; i < ilen; i++) { var sprayChunk = this.sprayChunks[i]; @@ -107,7 +107,7 @@ fabric.SprayBrush = fabric.util.createClass( fabric.BaseBrush, /** @lends fabric this.canvas.clearContext(this.canvas.contextTop); this.removeShadowStyles(); - this.canvas.renderOnAddition = originalRenderOnAddition; + this.canvas.renderOnAddRemove = originalRenderOnAddRemove; this.canvas.renderAll(); }, diff --git a/src/mixins/canvas_serialization.mixin.js b/src/mixins/canvas_serialization.mixin.js index 0c9a95c2..68dd84b2 100644 --- a/src/mixins/canvas_serialization.mixin.js +++ b/src/mixins/canvas_serialization.mixin.js @@ -117,15 +117,15 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati callback && callback(); } - var renderOnAddition = this.renderOnAddition; - this.renderOnAddition = false; + var renderOnAddRemove = this.renderOnAddRemove; + this.renderOnAddRemove = false; fabric.util.enlivenObjects(objects, function(enlivenedObjects) { enlivenedObjects.forEach(function(obj, index) { _this.insertAt(obj, index, true); }); - _this.renderOnAddition = renderOnAddition; + _this.renderOnAddRemove = renderOnAddRemove; callback && callback(); }); }, diff --git a/src/mixins/collection.mixin.js b/src/mixins/collection.mixin.js index 05321613..650d8eef 100644 --- a/src/mixins/collection.mixin.js +++ b/src/mixins/collection.mixin.js @@ -4,7 +4,7 @@ fabric.Collection = { /** - * Adds objects to collection, then renders canvas (if `renderOnAddition` is not `false`) + * Adds objects to collection, then renders canvas (if `renderOnAddRemove` is not `false`) * Objects should be instances of (or inherit from) fabric.Object * @param [...] Zero or more fabric instances * @return {Self} thisArg @@ -14,16 +14,16 @@ fabric.Collection = { for (var i = arguments.length; i--; ) { this._onObjectAdded(arguments[i]); } - this.renderOnAddition && this.renderAll(); + this.renderOnAddRemove && this.renderAll(); return this; }, /** - * Inserts an object into collection at specified index and renders canvas + * Inserts an object into collection at specified index, then renders canvas (if `renderOnAddRemove` is not `false`) * An object should be an instance of (or inherit from) fabric.Object - * @param object {Object} Object to insert - * @param index {Number} index to insert object at - * @param nonSplicing {Boolean} when `true`, no splicing (shifting) of objects occurs + * @param {Object} object Object to insert + * @param {Number} index Index to insert object at + * @param {Boolean} nonSplicing When `true`, no splicing (shifting) of objects occurs * @return {Self} thisArg */ insertAt: function (object, index, nonSplicing) { @@ -35,19 +35,18 @@ fabric.Collection = { objects.splice(index, 0, object); } this._onObjectAdded(object); - this.renderOnAddition && this.renderAll(); + this.renderOnAddRemove && this.renderAll(); return this; }, /** - * Removes an object from a group - * @param {Object} object + * Removes an object from a collection, then renders canvas (if `renderOnAddRemove` is not `false`) + * @param {Object} object Object to remove * @return {Self} thisArg */ remove: function(object) { - - var objects = this.getObjects(); - var index = objects.indexOf(object); + var objects = this.getObjects(), + index = objects.indexOf(object); // only call onObjectRemoved if an object was actually removed if (index !== -1) { @@ -55,7 +54,7 @@ fabric.Collection = { this._onObjectRemoved(object); } - this.renderAll && this.renderAll(); + this.renderOnAddRemove && this.renderAll(); return object; }, diff --git a/src/static_canvas.class.js b/src/static_canvas.class.js index ac976066..10f324ac 100644 --- a/src/static_canvas.class.js +++ b/src/static_canvas.class.js @@ -42,6 +42,7 @@ /** * Background color of canvas instance * @type String + * @default */ backgroundColor: '', @@ -49,12 +50,14 @@ * Background image of canvas instance * Should be set via {@link fabric.StaticCanvas#setBackgroundImage} * @type String + * @default */ backgroundImage: '', /** * Opacity of the background image of the canvas instance * @type Float + * @default */ backgroundImageOpacity: 1, @@ -62,6 +65,7 @@ * Indicates whether the background image should be stretched to fit the * dimensions of the canvas instance. * @type Boolean + * @default */ backgroundImageStretch: true, @@ -69,51 +73,59 @@ * Overlay image of canvas instance * Should be set via {@link fabric.StaticCanvas#setOverlayImage} * @type String + * @default */ overlayImage: '', /** * Left offset of overlay image (if present) * @type Number + * @default */ overlayImageLeft: 0, /** * Top offset of overlay image (if present) * @type Number + * @default */ overlayImageTop: 0, /** * Indicates whether toObject/toDatalessObject should include default values * @type Boolean + * @default */ includeDefaultValues: true, /** * Indicates whether objects' state should be saved * @type Boolean + * @default */ stateful: true, /** - * Indicates whether {@link fabric.Canvas.prototype.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) + * Indicates whether {@link fabric.Collection.add}, {@link fabric.Collection.insertAt} and {@link fabric.Collection.remove} should also re-render canvas. + * Disabling this option could give a great performance boost when adding/removing a lot of objects to/from canvas at once + * (followed by a manual rendering after addition/deletion) * @type Boolean + * @default */ - renderOnAddition: true, + renderOnAddRemove: true, /** * Function that determines clipping of entire canvas area * Being passed context as first argument. See clipping canvas area in {@link https://github.com/kangax/fabric.js/wiki/FAQ} * @type Function + * @default */ clipTo: null, /** * Indicates whether object controls (borders/controls) are rendered above overlay image * @type Boolean + * @default */ controlsAboveOverlay: false, @@ -125,9 +137,11 @@ /* NOOP */ }, - /** - * @private - */ + /** + * @private + * @param {HTMLElement | String} el <canvas> element to initialize instance on + * @param {Object} [options] Options object + */ _initStatic: function(el, options) { this._objects = []; @@ -277,6 +291,7 @@ /** * Creates a bottom canvas * @private + * @param {HTMLElement} [canvasEl] */ _createLowerCanvas: function (canvasEl) { this.lowerCanvasEl = fabric.util.getById(canvasEl) || this._createCanvasElement(); diff --git a/test/unit/canvas_static.js b/test/unit/canvas_static.js index a26c1914..e444dcce 100644 --- a/test/unit/canvas_static.js +++ b/test/unit/canvas_static.js @@ -99,6 +99,36 @@ equal(canvas.getObjects().length, 4, 'should support multiple arguments'); }); + test('add renderOnAddRemove disabled', function() { + var rect = makeRect(), + originalRenderOnAddition, + renderAllCount = 0; + + function countRenderAll() { + renderAllCount++; + } + + originalRenderOnAddition = canvas.renderOnAddRemove; + canvas.renderOnAddRemove = false; + + canvas.on('after:render', countRenderAll); + + ok(canvas === canvas.add(rect), 'should be chainable'); + equal(renderAllCount, 0); + + equal(canvas.item(0), rect); + + canvas.add(makeRect(), makeRect(), makeRect()); + equal(canvas.getObjects().length, 4, 'should support multiple arguments'); + equal(renderAllCount, 0); + + canvas.renderAll(); + equal(renderAllCount, 1); + + canvas.off('after:render', countRenderAll); + canvas.renderOnAddRemove = originalRenderOnAddition; + }); + test('insertAt', function() { var rect1 = makeRect(), rect2 = makeRect(); @@ -115,6 +145,40 @@ equal(canvas, canvas.insertAt(rect, 2), 'should be chainable'); }); + test('insertAt renderOnAddRemove disabled', function() { + var rect1 = makeRect(), + rect2 = makeRect(), + originalRenderOnAddition, + renderAllCount = 0; + + function countRenderAll() { + renderAllCount++; + } + + originalRenderOnAddition = canvas.renderOnAddRemove; + canvas.renderOnAddRemove = false; + + canvas.on('after:render', countRenderAll); + + canvas.add(rect1, rect2); + equal(renderAllCount, 0); + + var rect = makeRect(); + + canvas.insertAt(rect, 1); + equal(renderAllCount, 0); + + equal(canvas.item(1), rect); + canvas.insertAt(rect, 2); + equal(renderAllCount, 0); + + canvas.renderAll(); + equal(renderAllCount, 1); + + canvas.off('after:render', countRenderAll); + canvas.renderOnAddRemove = originalRenderOnAddition; + }); + test('clearContext', function() { ok(typeof canvas.clearContext == 'function'); equal(canvas, canvas.clearContext(canvas.contextContainer), 'chainable'); @@ -379,6 +443,35 @@ equal(canvas.item(0), rect2, 'only second object should be left'); }); + test('remove renderOnAddRemove disabled', function() { + var rect1 = makeRect(), + rect2 = makeRect(), + originalRenderOnAddition, + renderAllCount = 0; + + function countRenderAll() { + renderAllCount++; + } + + originalRenderOnAddition = canvas.renderOnAddRemove; + canvas.renderOnAddRemove = false; + + canvas.on('after:render', countRenderAll); + + canvas.add(rect1, rect2); + equal(renderAllCount, 0); + + equal(canvas.remove(rect1), rect1, 'should return removed object'); + equal(renderAllCount, 0); + equal(canvas.item(0), rect2, 'only second object should be left'); + + canvas.renderAll(); + equal(renderAllCount, 1); + + canvas.off('after:render', countRenderAll); + canvas.renderOnAddRemove = originalRenderOnAddition; + }); + test('sendToBack', function() { ok(typeof canvas.sendToBack == 'function');