paper.js/src/color/Gradient.js
Jürg Lehni 7329f4ef77 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.
2012-10-10 19:27:14 -07:00

128 lines
3.2 KiB
JavaScript

/*
* Paper.js
*
* This file is part of Paper.js, a JavaScript Vector Graphics Library,
* based on Scriptographer.org and designed to be largely API compatible.
* http://paperjs.org/
* http://scriptographer.org/
*
* Copyright (c) 2011, Juerg Lehni & Jonathan Puckey
* http://lehni.org/ & http://jonathanpuckey.com/
*
* Distributed under the MIT license. See LICENSE file for details.
*
* All rights reserved.
*/
/**
* @name Gradient
*
* @class The Gradient object.
*/
var Gradient = this.Gradient = Base.extend(/** @lends Gradient# */{
// TODO: Should type here be called 'radial' and have it receive a
// boolean value?
/**
* Creates a gradient object
*
* @param {GradientStop[]} stops
* @param {String} [type='linear'] 'linear' or 'radial'
*/
initialize: function(stops, type) {
this.setStops(stops || ['white', 'black']);
this.type = type || 'linear';
},
/**
* Called by various setters whenever a gradient value changes
*/
_changed: function() {
// Loop through the gradient-colors that use this gradient and notify
// them, so they can notify the items they belong to.
for (var i = 0, l = this._owners && this._owners.length; i < l; i++)
this._owners[i]._changed();
},
/**
* Called by GradientColor#initialize
* This is required to pass on _changed() notifications to the _owners.
*/
_addOwner: function(color) {
if (!this._owners)
this._owners = [];
this._owners.push(color);
},
// TODO: Where and when should this be called:
/**
* Called by GradientColor whenever this gradient stops being used.
*/
_removeOwner: function(color) {
var index = this._owners ? this._owners.indexOf(color) : -1;
if (index != -1) {
this._owners.splice(index, 1);
if (this._owners.length == 0)
delete this._owners;
}
},
/**
* @return {Gradient} a copy of the gradient
*/
clone: function() {
var stops = [];
for (var i = 0, l = this._stops.length; i < l; i++)
stops[i] = this._stops[i].clone();
return new Gradient(stops, this.type);
},
/**
* The gradient stops on the gradient ramp.
*
* @type GradientStop[]
* @bean
*/
getStops: function() {
return this._stops;
},
setStops: function(stops) {
// 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++)
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, 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._owner = this;
if (stop._defaultRamp)
stop.setRampPoint(i / (l - 1));
}
this._changed();
},
/**
* Checks whether the gradient is equal to the supplied gradient.
*
* @param {Gradient} gradient
* @return {Boolean} {@true they are equal}
*/
equals: function(gradient) {
if (gradient.type != this.type)
return false;
if (this._stops.length == gradient._stops.length) {
for (var i = 0, l = this._stops.length; i < l; i++) {
if (!this._stops[i].equals(gradient._stops[i]))
return false;
}
return true;
}
return false;
}
});