From 984cd792dfee443be70874d4dfbab48b084a3ad9 Mon Sep 17 00:00:00 2001 From: Asturur Date: Thu, 22 Dec 2016 09:57:07 +0100 Subject: [PATCH 1/3] send up to group the change on dirty flag --- src/shapes/object.class.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/shapes/object.class.js b/src/shapes/object.class.js index f68c53cfbdf..3e6eb9169b5 100644 --- a/src/shapes/object.class.js +++ b/src/shapes/object.class.js @@ -1139,10 +1139,16 @@ else if (key === 'shadow' && value && !(value instanceof fabric.Shadow)) { value = new fabric.Shadow(value); } + else if (key === 'dirty' && this.group) { + this.group.set('dirty', value); + } this[key] = value; if (this.cacheProperties.indexOf(key) > -1) { + if (this.group) { + this.group.set('dirty', true); + } this.dirty = true; } From 7801f4bfb85e1a3082d43fb36bf5ee8a6b3c7829 Mon Sep 17 00:00:00 2001 From: Asturur Date: Sat, 24 Dec 2016 11:58:28 +0100 Subject: [PATCH 2/3] add test --- test/unit/group.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/unit/group.js b/test/unit/group.js index bb868171f0d..d527cc07682 100644 --- a/test/unit/group.js +++ b/test/unit/group.js @@ -527,6 +527,15 @@ equal(rect1.canvas, canvas); }); + test('dirty flag propagation from children up', function() { + var g1 = makeGroupWith4Objects(); + var obj = g1.item(0); + equal(g1.dirty, false, 'Group has no dirty flag set'); + obj.set('fill', 'red'); + equal(obj.dirty, true, 'Obj has dirty flag set') + equal(g1.dirty, true, 'Group has dirty flag set'); + }); + test('test group transformMatrix', function() { var rect1 = new fabric.Rect({ top: 1, left: 1, width: 2, height: 2, strokeWidth: 0, fill: 'red', opacity: 1}), rect2 = new fabric.Rect({ top: 5, left: 5, width: 2, height: 2, strokeWidth: 0, fill: 'red', opacity: 1}), From 2758af1093ce3fd310f37aad9e77e2a04e73407a Mon Sep 17 00:00:00 2001 From: Asturur Date: Sat, 24 Dec 2016 13:30:40 +0100 Subject: [PATCH 3/3] added tests --- test/unit/group.js | 11 ++++++++ test/unit/object.js | 65 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) diff --git a/test/unit/group.js b/test/unit/group.js index d527cc07682..2b62799f66f 100644 --- a/test/unit/group.js +++ b/test/unit/group.js @@ -530,12 +530,23 @@ test('dirty flag propagation from children up', function() { var g1 = makeGroupWith4Objects(); var obj = g1.item(0); + g1.dirty = false; + obj.dirty = false; equal(g1.dirty, false, 'Group has no dirty flag set'); obj.set('fill', 'red'); equal(obj.dirty, true, 'Obj has dirty flag set') equal(g1.dirty, true, 'Group has dirty flag set'); }); + test('_getCacheCanvasDimensions returns dimensions and zoom for cache canvas are influenced by group', function() { + var g1 = makeGroupWith4Objects(); + var obj = g1.item(0); + var dims = obj._getCacheCanvasDimensions(); + g1.scaleX = 2; + var dims2 = obj._getCacheCanvasDimensions(); + equal(dims2.width, dims.width * g1.scaleX, 'width of cache has increased with group scale'); + }); + test('test group transformMatrix', function() { var rect1 = new fabric.Rect({ top: 1, left: 1, width: 2, height: 2, strokeWidth: 0, fill: 'red', opacity: 1}), rect2 = new fabric.Rect({ top: 5, left: 5, width: 2, height: 2, strokeWidth: 0, fill: 'red', opacity: 1}), diff --git a/test/unit/object.js b/test/unit/object.js index c3449ce9d7b..f884a45df2a 100644 --- a/test/unit/object.js +++ b/test/unit/object.js @@ -1467,6 +1467,71 @@ }); }); + test('dirty flag on set property', function() { + var object = new fabric.Object({ scaleX: 3, scaleY: 2}); + object.cacheProperties = ['propA', 'propB']; + object.dirty = false; + equal(object.dirty, false, 'object starts with dirty flag disabled'); + object.set('propC', '3'); + equal(object.dirty, false, 'after setting a property out of cache, dirty flag is still false'); + object.set('propA', '2'); + equal(object.dirty, true, 'after setting a property from cache, dirty flag is true'); + }); + + test('isCacheDirty statefullCache disabled', function() { + var object = new fabric.Object({ scaleX: 3, scaleY: 2}); + object.cacheProperties = ['propA', 'propB']; + object.dirty = false; + object.statefullCache = false; + object._createCacheCanvas(); + equal(object.isCacheDirty(), false, 'object is not dirty if dirty flag is false'); + object.dirty = true; + equal(object.isCacheDirty(), true, 'object is dirty if dirty flag is true'); + }); + + test('isCacheDirty statefullCache enabled', function() { + var object = new fabric.Object({ scaleX: 3, scaleY: 2}); + object.cacheProperties = ['propA', 'propB']; + object.dirty = false; + object.statefullCache = true; + object.propA = 'A'; + object.setupState({ propertySet: 'cacheProperties' }); + object._createCacheCanvas(); + equal(object.isCacheDirty(), false, 'object is not dirty'); + object.propA = 'B'; + equal(object.isCacheDirty(), true, 'object is dirty because change in propA is detected by statefullCache'); + }); + + test('_getCacheCanvasDimensions returns dimensions and zoom for cache canvas', function() { + var object = new fabric.Object({ width: 10, height: 10, strokeWidth: 0 }); + var dims = object._getCacheCanvasDimensions(); + deepEqual(dims, { width: 10, height: 10, zoomX: 1, zoomY: 1 }, 'if no scaling is applied cache is as big as object'); + object.strokeWidth = 2; + dims = object._getCacheCanvasDimensions(); + deepEqual(dims, { width: 12, height: 12, zoomX: 1, zoomY: 1 }, 'cache contains the stroke'); + object.scaleX = 2; + object.scaleY = 3; + dims = object._getCacheCanvasDimensions(); + deepEqual(dims, { width: 24, height: 36, zoomX: 2, zoomY: 3 }, 'cache is as big as the scaled object'); + }); + + test('_updateCacheCanvas check if cache canvas should be updated', function() { + var object = new fabric.Object({ width: 10, height: 10, strokeWidth: 0 }); + object._createCacheCanvas(); + equal(object.cacheWidth, 10, 'current cache dimensions are saved'); + equal(object.cacheHeight, 10, 'current cache dimensions are saved'); + equal(object._updateCacheCanvas(), false, 'second execution of cache canvas return false'); + object.scaleX = 2; + equal(object._updateCacheCanvas(), true, 'if scale change, it returns true'); + equal(object.cacheWidth, 20, 'current cache dimensions is updated'); + equal(object.zoomX, 2, 'current scale level is saved'); + object.width = 2; + equal(object._updateCacheCanvas(), true, 'if dimension change, it returns true'); + equal(object.cacheWidth, 4, 'current cache dimensions is updated'); + object.strokeWidth = 2; + equal(object._updateCacheCanvas(), true, 'if strokeWidth change, it returns true'); + }); + test('_setShadow', function(){ var el = fabric.document.createElement('canvas'); el.width = 600; el.height = 600;