mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2025-01-03 19:45:44 -05:00
Improve handling of owner referencing in colors.
Allow one owner per Color only and clone colors when setting color styles. Gradient can still have multiple GradientColor owners. Closes #124.
This commit is contained in:
parent
4d1920ee8b
commit
7329f4ef77
4 changed files with 20 additions and 69 deletions
|
@ -354,35 +354,8 @@ var Color = this.Color = Base.extend(new function() {
|
|||
*/
|
||||
_changed: function() {
|
||||
this._cssString = null;
|
||||
// Loop through the items that use this color and notify them about
|
||||
// the style change, so they can redraw.
|
||||
for (var i = 0, l = this._owners && this._owners.length; i < l; i++)
|
||||
this._owners[i]._changed(Change.STYLE);
|
||||
},
|
||||
|
||||
/**
|
||||
* Called by PathStyle whenever this color is used to define an item's style
|
||||
* This is required to pass on _changed() notifications to the _owners.
|
||||
*/
|
||||
_addOwner: function(item) {
|
||||
if (!this._owners)
|
||||
this._owners = [];
|
||||
this._owners.push(item);
|
||||
},
|
||||
|
||||
/**
|
||||
* Called by PathStyle whenever this color stops being used to define an
|
||||
* item's style.
|
||||
* TODO: Should we remove owners that are not used anymore for good, e.g.
|
||||
* in an Item#destroy() method?
|
||||
*/
|
||||
_removeOwner: function(item) {
|
||||
var index = this._owners ? this._owners.indexOf(item) : -1;
|
||||
if (index != -1) {
|
||||
this._owners.splice(index, 1);
|
||||
if (this._owners.length == 0)
|
||||
delete this._owners;
|
||||
}
|
||||
if (this._owner)
|
||||
this._owner._changed(Change.STYLE);
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -90,18 +90,17 @@ var Gradient = this.Gradient = Base.extend(/** @lends Gradient# */{
|
|||
// If this gradient already contains stops, first remove
|
||||
// this gradient as their owner.
|
||||
if (this.stops) {
|
||||
for (var i = 0, l = this._stops.length; i < l; i++) {
|
||||
this._stops[i]._removeOwner(this);
|
||||
}
|
||||
for (var i = 0, l = this._stops.length; i < l; i++)
|
||||
delete this._stops[i]._owner;
|
||||
}
|
||||
if (stops.length < 2)
|
||||
throw new Error(
|
||||
'Gradient stop list needs to contain at least two stops.');
|
||||
this._stops = GradientStop.readAll(stops);
|
||||
this._stops = GradientStop.readAll(stops, 0, true); // clone
|
||||
// Now reassign ramp points if they were not specified.
|
||||
for (var i = 0, l = this._stops.length; i < l; i++) {
|
||||
var stop = this._stops[i];
|
||||
stop._addOwner(this);
|
||||
stop._owner = this;
|
||||
if (stop._defaultRamp)
|
||||
stop.setRampPoint(i / (l - 1));
|
||||
}
|
||||
|
|
|
@ -59,33 +59,10 @@ var GradientStop = this.GradientStop = Base.extend(/** @lends GradientStop# */{
|
|||
// Loop through the gradients that use this stop and notify them about
|
||||
// the change, so they can notify their gradient colors, which in turn
|
||||
// will notify the items they are used in:
|
||||
for (var i = 0, l = this._owners && this._owners.length; i < l; i++)
|
||||
this._owners[i]._changed(Change.STYLE);
|
||||
if (this._owner)
|
||||
this._owner._changed(Change.STYLE);
|
||||
},
|
||||
|
||||
/**
|
||||
* Called by Gradient whenever this stop is used. This is required to pass
|
||||
* on _changed() notifications to the _owners.
|
||||
*/
|
||||
_addOwner: function(gradient) {
|
||||
if (!this._owners)
|
||||
this._owners = [];
|
||||
this._owners.push(gradient);
|
||||
},
|
||||
|
||||
/**
|
||||
* Called by Gradient whenever this GradientStop is no longer used by it.
|
||||
*/
|
||||
_removeOwner: function(gradient) {
|
||||
var index = this._owners ? this._owners.indexOf(gradient) : -1;
|
||||
if (index != -1) {
|
||||
this._owners.splice(index, 1);
|
||||
if (this._owners.length == 0)
|
||||
delete this._owners;
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* The ramp-point of the gradient stop as a value between {@code 0} and
|
||||
* {@code 1}.
|
||||
|
@ -165,12 +142,12 @@ var GradientStop = this.GradientStop = Base.extend(/** @lends GradientStop# */{
|
|||
},
|
||||
|
||||
setColor: function(color) {
|
||||
// If the stop already contained a color,
|
||||
// remove it as an owner:
|
||||
if (this._color)
|
||||
this._color._removeOwner(this);
|
||||
// Make sure newly set colors are cloned, since they can only have
|
||||
// one owner.
|
||||
this._color = Color.read(arguments);
|
||||
this._color._addOwner(this);
|
||||
if (this._color === color)
|
||||
this._color = color.clone();
|
||||
this._color._owner = this;
|
||||
this._changed();
|
||||
},
|
||||
|
||||
|
|
|
@ -70,7 +70,8 @@ var Style = Item.extend({
|
|||
// injected into this class using this.base() further down.
|
||||
src[set] = function(value) {
|
||||
var children = this._item && this._item._children;
|
||||
value = isColor ? Color.read(arguments) : value;
|
||||
// Clone color objects since they reference their owner
|
||||
value = isColor ? Color.read(arguments, 0, 0, true) : value;
|
||||
if (children) {
|
||||
for (var i = 0, l = children.length; i < l; i++)
|
||||
children[i][styleKey][set](value);
|
||||
|
@ -78,13 +79,14 @@ var Style = Item.extend({
|
|||
var old = this['_' + key];
|
||||
if (old != value && !(old && old.equals
|
||||
&& old.equals(value))) {
|
||||
this['_' + key] = value;
|
||||
if (isColor) {
|
||||
if (old)
|
||||
old._removeOwner(this._item);
|
||||
if (value)
|
||||
value._addOwner(this._item);
|
||||
delete old._owner;
|
||||
if (value) {
|
||||
value._owner = this._item;
|
||||
}
|
||||
}
|
||||
this['_' + key] = value;
|
||||
// Notify the item of the style change STYLE is
|
||||
// always set, additional flags come from _flags,
|
||||
// as used for STROKE:
|
||||
|
|
Loading…
Reference in a new issue