Clean up handling of #_set(), #set() and #initialize()

Convention:

- #_set() is for actually setting properties, e.g. on Point, Size, so that derived classes can reuse other parts (e.g. SegmentPoint)
- #set() is a shortcut to #initialize() on all basic types, to offer the same amount of flexibility when setting values.
This commit is contained in:
Jürg Lehni 2016-07-18 20:11:01 +02:00
parent acfe6cddeb
commit 32d8c969fb
21 changed files with 272 additions and 214 deletions

View file

@ -72,7 +72,7 @@
"resemblejs": "^2.2.1",
"run-sequence": "^1.2.2",
"stats.js": "0.16.0",
"straps": "^1.9.0"
"straps": "^2.0.1"
},
"browser": {
"canvas": false,

View file

@ -18,9 +18,9 @@
/**
* @name Matrix
*
* @class An affine transform performs a linear mapping from 2D coordinates
* to other 2D coordinates that preserves the "straightness" and
* "parallelness" of lines.
* @class An affine transformation matrix performs a linear mapping from 2D
* coordinates to other 2D coordinates that preserves the "straightness" and
* "parallelness" of lines.
*
* Such a coordinate transformation can be represented by a 3 row by 3
* column matrix with an implied last row of `[ 0 0 1 ]`. This matrix
@ -42,8 +42,15 @@ var Matrix = Base.extend(/** @lends Matrix# */{
_class: 'Matrix',
/**
* Creates a 2D affine transform.
* Creates a 2D affine transformation matrix that describes the identity
* transformation.
*
* @name Matrix#initialize
*/
/**
* Creates a 2D affine transformation matrix.
*
* @name Matrix#initialize
* @param {Number} a the a property of the transform
* @param {Number} c the c property of the transform
* @param {Number} b the b property of the transform
@ -51,16 +58,28 @@ var Matrix = Base.extend(/** @lends Matrix# */{
* @param {Number} tx the tx property of the transform
* @param {Number} ty the ty property of the transform
*/
/**
* Creates a 2D affine transformation matrix.
*
* @name Matrix#initialize
* @param {Number[]} values the matrix values to initialize this matrix with
*/
/**
* Creates a 2D affine transformation matrix.
*
* @name Matrix#initialize
* @param {Matrix} matrix the matrix to copy the values from
*/
initialize: function Matrix(arg) {
var count = arguments.length,
ok = true;
if (count === 6) {
this.set.apply(this, arguments);
this._set.apply(this, arguments);
} else if (count === 1) {
if (arg instanceof Matrix) {
this.set(arg._a, arg._b, arg._c, arg._d, arg._tx, arg._ty);
this._set(arg._a, arg._b, arg._c, arg._d, arg._tx, arg._ty);
} else if (Array.isArray(arg)) {
this.set.apply(this, arg);
this._set.apply(this, arg);
} else {
ok = false;
}
@ -72,20 +91,20 @@ var Matrix = Base.extend(/** @lends Matrix# */{
if (!ok) {
throw new Error('Unsupported matrix parameters');
}
return this;
},
/**
* Sets this transform to the matrix specified by the 6 values.
* Sets the matrix to the passed values. Note that any sequence of
* parameters that is supported by the various {@link Matrix()} constructors
* also work for calls of `set()`.
*
* @param {Number} a the a property of the transform
* @param {Number} b the b property of the transform
* @param {Number} c the c property of the transform
* @param {Number} d the d property of the transform
* @param {Number} tx the tx property of the transform
* @param {Number} ty the ty property of the transform
* @return {Matrix} this affine transform
* @function
*/
set: function(a, b, c, d, tx, ty, _dontNotify) {
set: '#initialize',
// See Point#_set() for an explanation of #_set():
_set: function(a, b, c, d, tx, ty, _dontNotify) {
this._a = a;
this._b = b;
this._c = c;
@ -176,7 +195,7 @@ var Matrix = Base.extend(/** @lends Matrix# */{
},
/**
* Concatenates this transform with a translate transformation.
* Concatenates this matrix with a translate transformation.
*
* @name Matrix#translate
* @function
@ -184,7 +203,7 @@ var Matrix = Base.extend(/** @lends Matrix# */{
* @return {Matrix} this affine transform
*/
/**
* Concatenates this transform with a translate transformation.
* Concatenates this matrix with a translate transformation.
*
* @name Matrix#translate
* @function
@ -203,7 +222,7 @@ var Matrix = Base.extend(/** @lends Matrix# */{
},
/**
* Concatenates this transform with a scaling transformation.
* Concatenates this matrix with a scaling transformation.
*
* @name Matrix#scale
* @function
@ -212,7 +231,7 @@ var Matrix = Base.extend(/** @lends Matrix# */{
* @return {Matrix} this affine transform
*/
/**
* Concatenates this transform with a scaling transformation.
* Concatenates this matrix with a scaling transformation.
*
* @name Matrix#scale
* @function
@ -237,7 +256,7 @@ var Matrix = Base.extend(/** @lends Matrix# */{
},
/**
* Concatenates this transform with a rotation transformation around an
* Concatenates this matrix with a rotation transformation around an
* anchor point.
*
* @name Matrix#rotate
@ -247,7 +266,7 @@ var Matrix = Base.extend(/** @lends Matrix# */{
* @return {Matrix} this affine transform
*/
/**
* Concatenates this transform with a rotation transformation around an
* Concatenates this matrix with a rotation transformation around an
* anchor point.
*
* @name Matrix#rotate
@ -282,7 +301,7 @@ var Matrix = Base.extend(/** @lends Matrix# */{
},
/**
* Concatenates this transform with a shear transformation.
* Concatenates this matrix with a shear transformation.
*
* @name Matrix#shear
* @function
@ -291,7 +310,7 @@ var Matrix = Base.extend(/** @lends Matrix# */{
* @return {Matrix} this affine transform
*/
/**
* Concatenates this transform with a shear transformation.
* Concatenates this matrix with a shear transformation.
*
* @name Matrix#shear
* @function
@ -320,7 +339,7 @@ var Matrix = Base.extend(/** @lends Matrix# */{
},
/**
* Concatenates this transform with a skew transformation.
* Concatenates this matrix with a skew transformation.
*
* @name Matrix#skew
* @function
@ -329,7 +348,7 @@ var Matrix = Base.extend(/** @lends Matrix# */{
* @return {Matrix} this affine transform
*/
/**
* Concatenates this transform with a skew transformation.
* Concatenates this matrix with a skew transformation.
*
* @name Matrix#skew
* @function
@ -473,15 +492,15 @@ var Matrix = Base.extend(/** @lends Matrix# */{
},
/**
* @deprecated, use use {@link #append(matrix)} instead.
* @deprecated use use {@link #append(matrix)} instead.
*/
concatenate: '#append',
/**
* @deprecated, use use {@link #prepend(matrix)} instead.
* @deprecated use use {@link #prepend(matrix)} instead.
*/
preConcatenate: '#prepend',
/**
* @deprecated, use use {@link #appended(matrix)} instead.
* @deprecated use use {@link #appended(matrix)} instead.
*/
chain: '#appended',
@ -501,7 +520,7 @@ var Matrix = Base.extend(/** @lends Matrix# */{
},
/**
* @return {Boolean} whether this transform is the identity transform
* @return {Boolean} whether this matrix is the identity matrix
*/
isIdentity: function() {
return this._a === 1 && this._b === 0 && this._c === 0 && this._d === 1
@ -509,10 +528,10 @@ var Matrix = Base.extend(/** @lends Matrix# */{
},
/**
* Returns whether the transform is invertible. A transform is not
* invertible if the determinant is 0 or any value is non-finite or NaN.
* Checks whether the matrix is invertible. A matrix is not invertible if
* the determinant is 0 or any value is infinite or NaN.
*
* @return {Boolean} whether the transform is invertible
* @return {Boolean} whether the matrix is invertible
*/
isInvertible: function() {
var det = this._a * this._d - this._c * this._b;
@ -566,7 +585,7 @@ var Matrix = Base.extend(/** @lends Matrix# */{
y = point.y;
if (!dest)
dest = new Point();
return dest.set(
return dest._set(
x * this._a + y * this._c + this._tx,
x * this._b + y * this._d + this._ty,
_dontNotify);
@ -611,7 +630,7 @@ var Matrix = Base.extend(/** @lends Matrix# */{
}
if (!dest)
dest = new Rectangle();
return dest.set(min[0], min[1], max[0] - min[0], max[1] - min[1],
return dest._set(min[0], min[1], max[0] - min[0], max[1] - min[1],
_dontNotify);
},
@ -638,7 +657,7 @@ var Matrix = Base.extend(/** @lends Matrix# */{
y = point.y - this._ty;
if (!dest)
dest = new Point();
res = dest.set(
res = dest._set(
(x * d - y * c) / det,
(y * a - x * b) / det,
_dontNotify);
@ -741,7 +760,7 @@ var Matrix = Base.extend(/** @lends Matrix# */{
*/
/**
* The transform values as an array, in the same sequence as they are passed
* The matrix values as an array, in the same sequence as they are passed
* to {@link #initialize(a, b, c, d, tx, ty)}.
*
* @bean

View file

@ -130,40 +130,63 @@ var Point = Base.extend(/** @lends Point# */{
* @name Point#initialize
*/
initialize: function Point(arg0, arg1) {
var type = typeof arg0;
var type = typeof arg0,
reading = this.__read,
read = 0;
if (type === 'number') {
var hasY = typeof arg1 === 'number';
this.x = arg0;
this.y = hasY ? arg1 : arg0;
if (this.__read)
this.__read = hasY ? 2 : 1;
this._set(arg0, hasY ? arg1 : arg0);
if (reading)
read = hasY ? 2 : 1;
} else if (type === 'undefined' || arg0 === null) {
this.x = this.y = 0;
if (this.__read)
this.__read = arg0 === null ? 1 : 0;
this._set(0, 0);
if (reading)
read = arg0 === null ? 1 : 0;
} else {
var obj = type === 'string' ? arg0.split(/[\s,]+/) || [] : arg0;
read = 1;
if (Array.isArray(obj)) {
this.x = obj[0];
this.y = obj.length > 1 ? obj[1] : obj[0];
this._set(+obj[0], +(obj.length > 1 ? obj[1] : obj[0]));
} else if ('x' in obj) {
this.x = obj.x;
this.y = obj.y;
this._set(obj.x || 0, obj.y || 0);
} else if ('width' in obj) {
this.x = obj.width;
this.y = obj.height;
this._set(obj.width || 0, obj.height || 0);
} else if ('angle' in obj) {
this.x = obj.length;
this.y = 0;
this.setAngle(obj.angle);
this._set(obj.length || 0, 0);
this.setAngle(obj.angle || 0);
} else {
this.x = this.y = 0;
if (this.__read)
this.__read = 0;
this._set(0, 0);
read = 0;
}
if (this.__read)
this.__read = 1;
}
if (reading)
this.__read = read;
return this;
},
/**
* Sets the point to the passed values. Note that any sequence of parameters
* that is supported by the various {@link Point()} constructors also work
* for calls of `set()`.
*
* @function
*/
set: '#initialize',
/**
* Internal helper function to directly set the underlying properties.
*
* Convention regarding {@link #set()} VS {@link #_set()}:
*
* - {@link #_set()} is for actually setting properties, e.g. on Point,
* Size, so that derived classes can reuse other parts (e.g. SegmentPoint)
* - {@link #set()} is a shortcut to #initialize() on all basic types, to
* offer the same amount of flexibility when setting values.
*/
_set: function(x, y) {
this.x = x;
this.y = y;
return this;
},
/**
@ -180,12 +203,6 @@ var Point = Base.extend(/** @lends Point# */{
* @type Number
*/
set: function(x, y) {
this.x = x;
this.y = y;
return this;
},
/**
* Checks whether the coordinates of the point are equal to that of the
* supplied point.
@ -257,7 +274,7 @@ var Point = Base.extend(/** @lends Point# */{
// assignment, so LinkedPoint does not report changes twice.
if (this.isZero()) {
var angle = this._angle || 0;
this.set(
this._set(
Math.cos(angle) * length,
Math.sin(angle) * length
);
@ -267,7 +284,7 @@ var Point = Base.extend(/** @lends Point# */{
// x and y are 0
if (Numerical.isZero(scale))
this.getAngle();
this.set(
this._set(
this.x * scale,
this.y * scale
);
@ -347,7 +364,7 @@ var Point = Base.extend(/** @lends Point# */{
var length = this.getLength();
// Use #set() instead of direct assignment of x/y, so LinkedPoint
// does not report changes twice.
this.set(
this._set(
Math.cos(angle) * length,
Math.sin(angle) * length
);
@ -997,7 +1014,8 @@ var LinkedPoint = Point.extend({
this._setter = setter;
},
set: function(x, y, _dontNotify) {
// See Point#_set() for an explanation of #_set():
_set: function(x, y, _dontNotify) {
this._x = x;
this._y = y;
if (!_dontNotify)

View file

@ -77,77 +77,92 @@ var Rectangle = Base.extend(/** @lends Rectangle# */{
*/
initialize: function Rectangle(arg0, arg1, arg2, arg3) {
var type = typeof arg0,
read = 0;
read;
if (type === 'number') {
// new Rectangle(x, y, width, height)
this.x = arg0;
this.y = arg1;
this.width = arg2;
this.height = arg3;
this._set(arg0, arg1, arg2, arg3);
read = 4;
} else if (type === 'undefined' || arg0 === null) {
// new Rectangle(), new Rectangle(null)
this.x = this.y = this.width = this.height = 0;
this._set(0, 0, 0, 0);
read = arg0 === null ? 1 : 0;
} else if (arguments.length === 1) {
// This can either be an array, or an object literal.
if (Array.isArray(arg0)) {
this.x = arg0[0];
this.y = arg0[1];
this.width = arg0[2];
this.height = arg0[3];
this._set.apply(this, arg0);
read = 1;
} else if (arg0.x !== undefined || arg0.width !== undefined) {
// Another rectangle or a simple object literal
// describing one. Use duck typing, and 0 as defaults.
this.x = arg0.x || 0;
this.y = arg0.y || 0;
this.width = arg0.width || 0;
this.height = arg0.height || 0;
this._set(arg0.x || 0, arg0.y || 0,
arg0.width || 0, arg0.height || 0);
read = 1;
} else if (arg0.from === undefined && arg0.to === undefined) {
// Use #_set to support whatever property the rectangle can
// take, but handle from/to separately below.
this.x = this.y = this.width = this.height = 0;
this._set(arg0);
// Use Base.filter() to support whatever property the rectangle
// can take, but handle from/to separately below.
this._set(0, 0, 0, 0);
Base.filter(this, arg0);
read = 1;
}
}
if (!read) {
if (read === undefined) {
// Read a point argument and look at the next value to see whether
// it's a size or a point, then read accordingly.
// We're supporting both reading from a normal arguments list and
// covering the Rectangle({ from: , to: }) constructor, through
// Point.readNamed().
var point = Point.readNamed(arguments, 'from'),
next = Base.peek(arguments);
this.x = point.x;
this.y = point.y;
if (next && next.x !== undefined || Base.hasNamed(arguments, 'to')) {
var frm = Point.readNamed(arguments, 'from'),
next = Base.peek(arguments),
x = frm.x,
y = frm.y,
width,
height;
if (next && next.x !== undefined
|| Base.hasNamed(arguments, 'to')) {
// new Rectangle(from, to)
// Read above why we can use readNamed() to cover both cases.
var to = Point.readNamed(arguments, 'to');
this.width = to.x - point.x;
this.height = to.y - point.y;
width = to.x - x;
height = to.y - y;
// Check if horizontal or vertical order needs to be reversed.
if (this.width < 0) {
this.x = to.x;
this.width = -this.width;
if (width < 0) {
x = to.x;
width = -width;
}
if (this.height < 0) {
this.y = to.y;
this.height = -this.height;
if (height < 0) {
y = to.y;
height = -height;
}
} else {
// new Rectangle(point, size)
var size = Size.read(arguments);
this.width = size.width;
this.height = size.height;
width = size.width;
height = size.height;
}
this._set(x, y, width, height);
read = arguments.__index;
}
if (this.__read)
this.__read = read;
return this;
},
/**
* Sets the rectangle to the passed values. Note that any sequence of
* parameters that is supported by the various {@link Rectangle()}
* constructors also work for calls of `set()`.
*
* @function
*/
set: '#initialize',
// See Point#_set() for an explanation of #_set():
_set: function(x, y, width, height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
return this;
},
/**
@ -178,17 +193,6 @@ var Rectangle = Base.extend(/** @lends Rectangle# */{
* @type Number
*/
/**
* @ignore
*/
set: function(x, y, width, height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
return this;
},
/**
* Returns a copy of the rectangle.
*/
@ -842,12 +846,13 @@ var Rectangle = Base.extend(/** @lends Rectangle# */{
var LinkedRectangle = Rectangle.extend({
// Have LinkedRectangle appear as a normal Rectangle in debugging
initialize: function Rectangle(x, y, width, height, owner, setter) {
this.set(x, y, width, height, true);
this._set(x, y, width, height, true);
this._owner = owner;
this._setter = setter;
},
set: function(x, y, width, height, _dontNotify) {
// See Point#_set() for an explanation of #_set():
_set: function(x, y, width, height, _dontNotify) {
this._x = x;
this._y = y;
this._width = width;

View file

@ -93,36 +93,51 @@ var Size = Base.extend(/** @lends Size# */{
* console.log(size.height); // 50
*/
initialize: function Size(arg0, arg1) {
var type = typeof arg0;
var type = typeof arg0,
reading = this.__read,
read = 0;
if (type === 'number') {
var hasHeight = typeof arg1 === 'number';
this.width = arg0;
this.height = hasHeight ? arg1 : arg0;
if (this.__read)
this.__read = hasHeight ? 2 : 1;
this._set(arg0, hasHeight ? arg1 : arg0);
if (reading)
read = hasHeight ? 2 : 1;
} else if (type === 'undefined' || arg0 === null) {
this.width = this.height = 0;
if (this.__read)
this.__read = arg0 === null ? 1 : 0;
this._set(0, 0);
if (reading)
read = arg0 === null ? 1 : 0;
} else {
var obj = type === 'string' ? arg0.split(/[\s,]+/) || [] : arg0;
read = 1;
if (Array.isArray(obj)) {
this.width = obj[0];
this.height = obj.length > 1 ? obj[1] : obj[0];
this._set(+obj[0], +(obj.length > 1 ? obj[1] : obj[0]));
} else if ('width' in obj) {
this.width = obj.width;
this.height = obj.height;
this._set(obj.width || 0, obj.height || 0);
} else if ('x' in obj) {
this.width = obj.x;
this.height = obj.y;
this._set(obj.x || 0, obj.y || 0);
} else {
this.width = this.height = 0;
if (this.__read)
this.__read = 0;
this._set(0, 0);
read = 0;
}
if (this.__read)
this.__read = 1;
}
if (reading)
this.__read = read;
return this;
},
/**
* Sets the size to the passed values. Note that any sequence of parameters
* that is supported by the various {@link Size()} constructors also work
* for calls of `set()`.
*
* @function
*/
set: '#initialize',
// See Point#_set() for an explanation of #_set():
_set: function(width, height) {
this.width = width;
this.height = height;
return this;
},
/**
@ -139,12 +154,6 @@ var Size = Base.extend(/** @lends Size# */{
* @type Number
*/
set: function(width, height) {
this.width = width;
this.height = height;
return this;
},
/**
* Checks whether the width and height of the size are equal to those of the
* supplied size.
@ -551,7 +560,8 @@ var LinkedSize = Size.extend({
this._setter = setter;
},
set: function(width, height, _dontNotify) {
// See Point#_set() for an explanation of #_set():
_set: function(width, height, _dontNotify) {
this._width = width;
this._height = height;
if (!_dontNotify)

View file

@ -80,11 +80,10 @@ Base.inject(/** @lends Base# */{
/**
* #_set() is part of the mechanism for constructors which take one object
* literal describing all the properties to be set on the created instance.
* Through {@link Base.filter()} it supports `_filtered`
* handling as required by the {@link Base.readNamed()} mechanism.
*
* @param {Object} props an object describing the properties to set
* @param {Object} [exclude] a lookup table listing properties to exclude
* @param {Boolean} [dontCheck=false] whether to perform a
* Base.isPlainObject() check on props or not
* @return {Boolean} {@true if the object is a plain object}
*/
_set: function(props) {
@ -306,8 +305,9 @@ Base.inject(/** @lends Base# */{
/**
* Copies all properties from `source` over to `dest`, supporting
* _filtered handling as required by Base.readNamed() mechanism, as well
* as an optional exclude` object that lists properties to exclude.
* `_filtered` handling as required by {@link Base.readNamed()}
* mechanism, as well as an optional exclude` object that lists
* properties to exclude.
*/
filter: function(dest, source, exclude) {
// If source is a filtering object, we need to get the keys from the
@ -515,7 +515,7 @@ Base.inject(/** @lends Base# */{
}
// When reusing an object, initialize it through #_set()
// instead of the constructor function:
(useTarget ? obj._set : ctor).apply(obj, args);
(useTarget ? obj.set : ctor).apply(obj, args);
// Clear target to only use it once.
if (useTarget)
target = null;

View file

@ -239,8 +239,8 @@ new function() { // Injection scope for various item event handlers
},
/**
* Sets those properties of the passed object literal on this item to
* the values defined in the object literal, if the item has property of the
* Sets the properties of the passed object literal on this item to the
* values defined in the object literal, if the item has property of the
* given name (or a setter defined for it).
*
* @param {Object} props
@ -400,7 +400,7 @@ new function() { // Injection scope for various item event handlers
},
setStyle: function(style) {
// Don't access _style directly so Path#getStyle() can be overriden for
// Don't access _style directly so Path#getStyle() can be overridden for
// CompoundPaths.
this.getStyle().set(style);
}
@ -852,7 +852,7 @@ new function() { // Injection scope for various item event handlers
// Restore to the last revertible matrix stored in _backup, and get
// the bounds again. That way, we can prevent collapsing to 0-size.
if (!_matrix.isInvertible()) {
_matrix.initialize(_matrix._backup
_matrix.set(_matrix._backup
|| new Matrix().translate(_matrix.getTranslation()));
bounds = this.getBounds();
}
@ -1565,7 +1565,7 @@ new function() { // Injection scope for various item event handlers
}
// Use Matrix#initialize to easily copy over values.
if (!excludeMatrix)
this._matrix.initialize(source._matrix);
this._matrix.set(source._matrix);
// We can't just set _applyMatrix as many item types won't allow it,
// e.g. creating a Shape in Path#toShape().
// Using the setter instead takes care of it.

View file

@ -192,7 +192,7 @@ var Project = PaperScopeItem.extend(/** @lends Project# */{
setCurrentStyle: function(style) {
// TODO: Style selected items with the style:
this._currentStyle.initialize(style);
this._currentStyle.set(style);
},
/**

View file

@ -90,8 +90,7 @@ var Shape = Item.extend(/** @lends Shape# */{
height = size.height;
if (type === 'rectangle') {
// Shrink radius accordingly
var radius = Size.min(this._radius, size.divide(2));
this._radius.set(radius.width, radius.height);
this._radius.set(Size.min(this._radius, size.divide(2)));
} else if (type === 'circle') {
// Use average of width and height as new size, then calculate
// radius as a number from that:
@ -99,9 +98,9 @@ var Shape = Item.extend(/** @lends Shape# */{
this._radius = width / 2;
} else if (type === 'ellipse') {
// The radius is a size.
this._radius.set(width / 2, height / 2);
this._radius._set(width / 2, height / 2);
}
this._size.set(width, height);
this._size._set(width, height);
this._changed(/*#=*/Change.GEOMETRY);
}
},
@ -127,7 +126,7 @@ var Shape = Item.extend(/** @lends Shape# */{
return;
var size = radius * 2;
this._radius = radius;
this._size.set(size, size);
this._size._set(size, size);
} else {
radius = Size.read(arguments);
if (!this._radius) {
@ -136,13 +135,13 @@ var Shape = Item.extend(/** @lends Shape# */{
} else {
if (this._radius.equals(radius))
return;
this._radius.set(radius.width, radius.height);
this._radius.set(radius);
if (type === 'rectangle') {
// Grow size accordingly
var size = Size.max(this._size, radius.multiply(2));
this._size.set(size.width, size.height);
this._size.set(size);
} else if (type === 'ellipse') {
this._size.set(radius.width * 2, radius.height * 2);
this._size._set(radius.width * 2, radius.height * 2);
}
}
}

View file

@ -67,7 +67,7 @@ module.exports = function(paper) {
},
/**
* @deprecated, use use {@link #createCanvas(width, height)} instead.
* @deprecated use use {@link #createCanvas(width, height)} instead.
*/
Canvas: '#createCanvas'
});

View file

@ -166,7 +166,7 @@ var Curve = Base.extend(/** @lends Curve# */{
handleOut = segment2._handleOut;
removed = segment2.remove();
if (removed)
this._segment1._handleOut.set(handleOut.x, handleOut.y);
this._segment1._handleOut.set(handleOut);
}
return removed;
},
@ -182,8 +182,7 @@ var Curve = Base.extend(/** @lends Curve# */{
},
setPoint1: function(/* point */) {
var point = Point.read(arguments);
this._segment1._point.set(point.x, point.y);
this._segment1._point.set(Point.read(arguments));
},
/**
@ -197,8 +196,7 @@ var Curve = Base.extend(/** @lends Curve# */{
},
setPoint2: function(/* point */) {
var point = Point.read(arguments);
this._segment2._point.set(point.x, point.y);
this._segment2._point.set(Point.read(arguments));
},
/**
@ -212,8 +210,7 @@ var Curve = Base.extend(/** @lends Curve# */{
},
setHandle1: function(/* point */) {
var point = Point.read(arguments);
this._segment1._handleOut.set(point.x, point.y);
this._segment1._handleOut.set(Point.read(arguments));
},
/**
@ -227,8 +224,7 @@ var Curve = Base.extend(/** @lends Curve# */{
},
setHandle2: function(/* point */) {
var point = Point.read(arguments);
this._segment2._handleIn.set(point.x, point.y);
this._segment2._handleIn.set(Point.read(arguments));
},
/**
@ -487,8 +483,8 @@ var Curve = Base.extend(/** @lends Curve# */{
// Adjust the handles on the existing segments. The new segment
// will be inserted between the existing segment1 and segment2:
// Convert absolute -> relative
segment1._handleOut.set(left[2] - left[0], left[3] - left[1]);
segment2._handleIn.set(right[4] - right[6],right[5] - right[7]);
segment1._handleOut._set(left[2] - left[0], left[3] - left[1]);
segment2._handleIn._set(right[4] - right[6],right[5] - right[7]);
}
// Create the new segment:
var x = left[6], y = left[7],
@ -543,7 +539,7 @@ var Curve = Base.extend(/** @lends Curve# */{
// TODO: Remove in 1.0.0? (deprecated January 2016):
/**
* @deprecated, use use {@link #divideAt(offset)} or
* @deprecated use use {@link #divideAt(offset)} or
* {@link #divideAtTime(time)} instead.
*/
divide: function(offset, isTime) {
@ -553,7 +549,7 @@ var Curve = Base.extend(/** @lends Curve# */{
// TODO: Remove in 1.0.0? (deprecated January 2016):
/**
* @deprecated, use use {@link #splitAt(offset)} or
* @deprecated use use {@link #splitAt(offset)} or
* {@link #splitAtTime(time)} instead.
*/
split: function(offset, isTime) {
@ -576,8 +572,8 @@ var Curve = Base.extend(/** @lends Curve# */{
* turning the curve into a straight line.
*/
clearHandles: function() {
this._segment1._handleOut.set(0, 0);
this._segment2._handleIn.set(0, 0);
this._segment1._handleOut._set(0, 0);
this._segment2._handleIn._set(0, 0);
},
statics: /** @lends Curve */{
@ -1068,7 +1064,7 @@ statics: /** @lends Curve */{
// TODO: Remove in 1.0.0? (deprecated January 2016):
/**
* @deprecated, use use {@link #getTimeOf(point)} instead.
* @deprecated use use {@link #getTimeOf(point)} instead.
*/
getParameterAt: '#getTimeAt',
@ -1121,7 +1117,7 @@ statics: /** @lends Curve */{
// TODO: Remove in 1.0.0? (deprecated January 2016):
/**
* @deprecated, use use {@link #getTimeOf(point)} instead.
* @deprecated use use {@link #getTimeOf(point)} instead.
*/
getParameterOf: '#getTimeOf',

View file

@ -1086,7 +1086,7 @@ var Path = PathItem.extend(/** @lends Path# */{
},
/**
* @deprecated, use use {@link #splitAt(offset)} instead.
* @deprecated use use {@link #splitAt(offset)} instead.
*/
split: function(index, time) {
var curve,

View file

@ -799,8 +799,8 @@ PathItem.inject(new function() {
next = seg.getNext();
if (seg._path && hasOverlap(prev) && hasOverlap(next)) {
seg.remove();
prev._handleOut.set(0, 0);
next._handleIn.set(0, 0);
prev._handleOut._set(0, 0);
next._handleIn._set(0, 0);
var curve = prev.getCurve();
if (curve.isStraight() && curve.getLength() === 0)
prev.remove();

View file

@ -198,10 +198,7 @@ var Segment = Base.extend(/** @lends Segment# */{
},
setPoint: function(/* point */) {
var point = Point.read(arguments);
// Do not replace the internal object but update it instead, so
// references to it are kept alive.
this._point.set(point.x, point.y);
this._point.set(Point.read(arguments));
},
/**
@ -216,9 +213,7 @@ var Segment = Base.extend(/** @lends Segment# */{
},
setHandleIn: function(/* point */) {
var point = Point.read(arguments);
// See #setPoint:
this._handleIn.set(point.x, point.y);
this._handleIn.set(Point.read(arguments));
},
/**
@ -233,9 +228,7 @@ var Segment = Base.extend(/** @lends Segment# */{
},
setHandleOut: function(/* point */) {
var point = Point.read(arguments);
// See #setPoint:
this._handleOut.set(point.x, point.y);
this._handleOut.set(Point.read(arguments));
},
/**
@ -256,8 +249,8 @@ var Segment = Base.extend(/** @lends Segment# */{
* turning the segment into a corner.
*/
clearHandles: function() {
this._handleIn.set(0, 0);
this._handleOut.set(0, 0);
this._handleIn._set(0, 0);
this._handleOut._set(0, 0);
},
getSelection: function() {
@ -527,10 +520,9 @@ var Segment = Base.extend(/** @lends Segment# */{
reverse: function() {
var handleIn = this._handleIn,
handleOut = this._handleOut,
inX = handleIn._x,
inY = handleIn._y;
handleIn.set(handleOut._x, handleOut._y);
handleOut.set(inX, inY);
tmp = handleIn.clone();
handleIn.set(handleOut);
handleOut.set(tmp);
},
/**
@ -603,13 +595,13 @@ var Segment = Base.extend(/** @lends Segment# */{
handleIn2 = to._handleIn,
handleOut2 = to._handleOut,
handleOut1 = from._handleOut;
this._point.set(
this._point._set(
u * point1._x + v * point2._x,
u * point1._y + v * point2._y, true);
this._handleIn.set(
this._handleIn._set(
u * handleIn1._x + v * handleIn2._x,
u * handleIn1._y + v * handleIn2._y, true);
this._handleOut.set(
this._handleOut._set(
u * handleOut1._x + v * handleOut2._x,
u * handleOut1._y + v * handleOut2._y, true);
this._changed();

View file

@ -46,7 +46,8 @@ var SegmentPoint = Point.extend({
this.setSelected(true);
},
set: function(x, y) {
// See Point#_set() for an explanation of #_set():
_set: function(x, y) {
this._x = x;
this._y = y;
this._owner._changed(this);

View file

@ -625,10 +625,17 @@ var Color = Base.extend(new function() {
this._alpha = alpha;
if (reading)
this.__read = read;
return this;
},
// Have #_set point to #initialize, as used by Base.importJSON()
_set: '#initialize',
/**
* Sets the color to the passed values. Note that any sequence of
* parameters that is supported by the various {@link Color()}
* constructors also work for calls of `set()`.
*
* @function
*/
set: '#initialize',
_serialize: function(options, dictionary) {
var components = this.getComponents();

View file

@ -68,10 +68,15 @@ var Gradient = Base.extend(/** @lends Gradient# */{
initialize: function Gradient(stops, radial) {
// Use UID here since Gradients are exported through dictionary.add().
this._id = UID.get();
if (stops && this._set(stops))
if (stops && this._set(stops)) {
// Erase arguments since we used the passed object instead.
stops = radial = null;
if (!this._stops)
}
// As these values might already have been set in the _set() call above,
// only initialize them if that hasn't happened yet.
if (this._stops == null) {
this.setStops(stops || ['white', 'black']);
}
if (this._radial == null) {
// Support old string type argument and new radial boolean.
this.setRadial(typeof radial === 'string' && radial === 'radial'

View file

@ -126,14 +126,15 @@ var Style = Base.extend(new function() {
_class: 'Style',
beans: true,
initialize: function Style(style, owner, project) {
initialize: function Style(style, _owner, _project) {
// We keep values in a separate object that we can iterate over.
this._values = {};
this._owner = owner;
this._project = owner && owner._project || project || paper.project;
this._owner = _owner;
this._project = _owner && _owner._project || _project
|| paper.project;
// Use different defaults based on the owner
this._defaults = !owner || owner instanceof Group ? groupDefaults
: owner instanceof TextItem ? textDefaults
this._defaults = !_owner || _owner instanceof Group ? groupDefaults
: _owner instanceof TextItem ? textDefaults
: itemDefaults;
if (style)
this.set(style);
@ -263,6 +264,7 @@ var Style = Base.extend(new function() {
return fields;
}, /** @lends Style# */{
set: function(style) {
this._values = {}; // Reset already set styles.
// If the passed style object is also a Style, clone its clonable
// fields rather than simply copying them.
var isStyle = style instanceof Style,

View file

@ -389,7 +389,7 @@ var View = Base.extend(Emitter, /** @lends View# */{
if (delta.isZero())
return;
this._setElementSize(width, height);
this._viewSize.set(width, height);
this._viewSize._set(width, height);
// Call onResize handler on any size change
this.emit('resize', {
size: size,

View file

@ -46,6 +46,8 @@ test('new Point("10, 20")', function() {
equals(new Point('10, 20'), new Point(10, 20));
equals(new Point('10,20'), new Point(10, 20));
equals(new Point('10 20'), new Point(10, 20));
// Make sure it's integer values from the string:
equals(new Point('10 20').add(10), new Point(20, 30));
});
test('normalize(length)', function() {

View file

@ -41,4 +41,6 @@ test('new Size("10, 20")', function() {
equals(new Size('10, 20'), new Size(10, 20));
equals(new Size('10,20'), new Size(10, 20));
equals(new Size('10 20'), new Size(10, 20));
// Make sure it's integer values from the string:
equals(new Size('10 20').add(10), new Size(20, 30));
});