From 06e0c4332574870683a0e2ed802337094d205cff Mon Sep 17 00:00:00 2001 From: sasensi Date: Fri, 23 Nov 2018 15:22:47 +0100 Subject: [PATCH] Fix change propagation with colors on groups Closes #1152 --- src/style/Color.js | 27 +++++++++++++++++++++++++++ src/style/Style.js | 6 ++++++ test/tests/Color.js | 8 ++++++++ 3 files changed, 41 insertions(+) diff --git a/src/style/Color.js b/src/style/Color.js index 2e1d4a70..0a2ee035 100644 --- a/src/style/Color.js +++ b/src/style/Color.js @@ -1375,3 +1375,30 @@ new function() { */ }); }); + +/** + * @name LinkedColor + * + * @class An internal version of Color that notifies its owner of each change + * through setting itself again on the setter that corresponds to the getter + * that produced this LinkedColor. This is used to solve group color update + * problem (#1152) with the same principle used in LinkedPoint. + * + * @private + */ +var LinkedColor = Color.extend({ + // Make sure LinkedColor is displayed as Color in debugger. + initialize: function Color(color, item, setter) { + // Rely on real constructor for instantiation. + paper.Color.apply(this, [color]); + // Store references. + this._item = item; + this._setter = setter; + }, + + // Rely on Color#_changed() method to detect changes. + _changed: function(){ + // Update owner color by calling setter. + this._item[this._setter](this); + } +}); diff --git a/src/style/Style.js b/src/style/Style.js index 5f868e82..5e6a4bf7 100644 --- a/src/style/Style.js +++ b/src/style/Style.js @@ -241,6 +241,12 @@ var Style = Base.extend(new function() { } } } + // Turn group related colors into LinkedColor instances that will + // allow calls like `group.fillColor.hue += 10` to be propagated to + // children. + if (owner instanceof Group && value instanceof Color) { + value = new LinkedColor(value, owner, set); + } return value; }; diff --git a/test/tests/Color.js b/test/tests/Color.js index d8af1967..802bcb72 100644 --- a/test/tests/Color.js +++ b/test/tests/Color.js @@ -302,3 +302,11 @@ test('Gradients with applyMatrix', function() { comparePixels(path, shape); }); + +test('LinkedColor for group colors', function() { + var item = new Group(new Path(), new Path()); + item.strokeColor = 'red'; + item.strokeColor.hue = 50; + item.strokeColor.hue = 100; + expect(0); +});