mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2025-01-05 20:32:00 -05:00
Correctly clone all attributes in Shape#toPath() and Path#toShape()
Also write documentation for both methods. Closes #622.
This commit is contained in:
parent
ba12eec7f5
commit
2cf6cd7a14
4 changed files with 62 additions and 34 deletions
|
@ -1486,36 +1486,50 @@ var Item = Base.extend(Emitter, /** @lends Item# */{
|
||||||
return this._clone(new this.constructor(Item.NO_INSERT), insert);
|
return this._clone(new this.constructor(Item.NO_INSERT), insert);
|
||||||
},
|
},
|
||||||
|
|
||||||
_clone: function(copy, insert) {
|
/**
|
||||||
|
* Clones the item within the same project and places the copy above the
|
||||||
|
* item.
|
||||||
|
*
|
||||||
|
* @param {Boolean} [insert=true] specifies whether the copy should be
|
||||||
|
* inserted into the DOM. When set to {@code true}, it is inserted above the
|
||||||
|
* original.
|
||||||
|
* @return {Item} the newly cloned item
|
||||||
|
*/
|
||||||
|
_clone: function(copy, insert, includeMatrix) {
|
||||||
|
var keys = ['_locked', '_visible', '_blendMode', '_opacity',
|
||||||
|
'_clipMask', '_guide'],
|
||||||
|
children = this._children;
|
||||||
// Copy over style
|
// Copy over style
|
||||||
copy.setStyle(this._style);
|
copy.setStyle(this._style);
|
||||||
// If this item has children, clone and append each of them:
|
// Clone all children and add them to the copy. tell #addChild we're
|
||||||
if (this._children) {
|
// cloning, as needed by CompoundPath#insertChild().
|
||||||
// Clone all children and add them to the copy. tell #addChild we're
|
for (var i = 0, l = children && children.length; i < l; i++) {
|
||||||
// cloning, as needed by CompoundPath#insertChild().
|
copy.addChild(children[i].clone(false), true);
|
||||||
for (var i = 0, l = this._children.length; i < l; i++)
|
|
||||||
copy.addChild(this._children[i].clone(false), true);
|
|
||||||
}
|
}
|
||||||
// Insert is true by default.
|
|
||||||
if (insert || insert === undefined)
|
|
||||||
copy.insertAbove(this);
|
|
||||||
// Only copy over these fields if they are actually defined in 'this',
|
// Only copy over these fields if they are actually defined in 'this',
|
||||||
// meaning the default value has been overwritten (default is on
|
// meaning the default value has been overwritten (default is on
|
||||||
// prototype).
|
// prototype).
|
||||||
var keys = ['_locked', '_visible', '_blendMode', '_opacity',
|
|
||||||
'_clipMask', '_guide', '_applyMatrix'];
|
|
||||||
for (var i = 0, l = keys.length; i < l; i++) {
|
for (var i = 0, l = keys.length; i < l; i++) {
|
||||||
var key = keys[i];
|
var key = keys[i];
|
||||||
if (this.hasOwnProperty(key))
|
if (this.hasOwnProperty(key))
|
||||||
copy[key] = this[key];
|
copy[key] = this[key];
|
||||||
}
|
}
|
||||||
// Use Matrix#initialize to easily copy over values.
|
// Use Matrix#initialize to easily copy over values.
|
||||||
copy._matrix.initialize(this._matrix);
|
if (includeMatrix !== false)
|
||||||
// Copy over _data as well.
|
copy._matrix.initialize(this._matrix);
|
||||||
copy._data = this._data ? Base.clone(this._data) : null;
|
// In case of Path#toShape(), we can't just set _applyMatrix as
|
||||||
|
// Shape won't allow it. Using the setter instead takes care of it.
|
||||||
|
// NOTE: This will also bake in the matrix that we just initialized,
|
||||||
|
// in case #applyMatrix is true.
|
||||||
|
copy.setApplyMatrix(this._applyMatrix);
|
||||||
// Copy over the selection state, use setSelected so the item
|
// Copy over the selection state, use setSelected so the item
|
||||||
// is also added to Project#selectedItems if it is selected.
|
// is also added to Project#selectedItems if it is selected.
|
||||||
copy.setSelected(this._selected);
|
copy.setSelected(this._selected);
|
||||||
|
// Copy over _data as well.
|
||||||
|
copy._data = this._data ? Base.clone(this._data) : null;
|
||||||
|
// Insert is true by default.
|
||||||
|
if (insert || insert === undefined)
|
||||||
|
copy.insertAbove(this);
|
||||||
// Clone the name too, but make sure we're not overriding the original
|
// Clone the name too, but make sure we're not overriding the original
|
||||||
// in the same parent, by passing true for the unique parameter.
|
// in the same parent, by passing true for the unique parameter.
|
||||||
if (this._name)
|
if (this._name)
|
||||||
|
|
|
@ -157,19 +157,29 @@ var Shape = Item.extend(/** @lends Shape# */{
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
|
|
||||||
// DOCS: #toPath([insert=true])
|
/**
|
||||||
|
* Creates a new path item with same geometry as this shape item, and
|
||||||
|
* inherits all settings from it, similar to {@link Item#clone()}.
|
||||||
|
*
|
||||||
|
* @param {Boolean} [insert=true] specifies whether the new path should be
|
||||||
|
* inserted into the DOM. When set to {@code true}, it is inserted above the
|
||||||
|
* shape item.
|
||||||
|
* @return {Shape} the newly created path item with the same geometry as
|
||||||
|
* this shape item.
|
||||||
|
* @see Path#toShape(insert)
|
||||||
|
*/
|
||||||
toPath: function(insert) {
|
toPath: function(insert) {
|
||||||
var path = new Path[Base.capitalize(this._type)]({
|
var path = this._clone(new Path[Base.capitalize(this._type)]({
|
||||||
center: new Point(),
|
center: new Point(),
|
||||||
size: this._size,
|
size: this._size,
|
||||||
radius: this._radius,
|
radius: this._radius,
|
||||||
insert: false
|
insert: false
|
||||||
});
|
}), insert);
|
||||||
path.setStyle(this._style);
|
// The created path will inherit #applyMatrix from this Shape, hence it
|
||||||
path.transform(this._matrix);
|
// will always be false.
|
||||||
// Insert is true by default.
|
// Respect the setting of paper.settings.applyMatrix for new paths:
|
||||||
if (insert || insert === undefined)
|
if (paper.settings.applyMatrix)
|
||||||
path.insertAbove(this);
|
path.setApplyMatrix(true);
|
||||||
return path;
|
return path;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -1356,9 +1356,17 @@ var Path = PathItem.extend(/** @lends Path# */{
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
// DOCS: toShape
|
* Attempts to create a new shape item with same geometry as this path item,
|
||||||
|
* and inherits all settings from it, similar to {@link Item#clone()}.
|
||||||
|
*
|
||||||
|
* @param {Boolean} [insert=true] specifies whether the new shape should be
|
||||||
|
* inserted into the DOM. When set to {@code true}, it is inserted above the
|
||||||
|
* path item.
|
||||||
|
* @return {Shape} the newly created shape item with the same geometry as
|
||||||
|
* this path item if it can be matched, {@code null} otherwise.
|
||||||
|
* @see Shape#toPath(insert)
|
||||||
|
*/
|
||||||
toShape: function(insert) {
|
toShape: function(insert) {
|
||||||
if (!this._closed)
|
if (!this._closed)
|
||||||
return null;
|
return null;
|
||||||
|
@ -1419,18 +1427,14 @@ var Path = PathItem.extend(/** @lends Path# */{
|
||||||
|
|
||||||
if (type) {
|
if (type) {
|
||||||
var center = this.getPosition(true),
|
var center = this.getPosition(true),
|
||||||
shape = new type({
|
shape = this._clone(new type({
|
||||||
center: center,
|
center: center,
|
||||||
size: size,
|
size: size,
|
||||||
radius: radius,
|
radius: radius,
|
||||||
insert: false
|
insert: false
|
||||||
});
|
}), insert, false);
|
||||||
// Determine and apply the shape's angle of rotation.
|
// Determine and apply the shape's angle of rotation.
|
||||||
shape.rotate(topCenter.subtract(center).getAngle() + 90);
|
shape.rotate(topCenter.subtract(center).getAngle() + 90);
|
||||||
shape.setStyle(this._style);
|
|
||||||
// Insert is true by default.
|
|
||||||
if (insert || insert === undefined)
|
|
||||||
shape.insertAbove(this);
|
|
||||||
return shape;
|
return shape;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -50,9 +50,9 @@ var TextItem = Item.extend(/** @lends TextItem# */{
|
||||||
return this._content === item._content;
|
return this._content === item._content;
|
||||||
},
|
},
|
||||||
|
|
||||||
_clone: function _clone(copy, insert) {
|
_clone: function _clone(copy, insert, includeMatrix) {
|
||||||
copy.setContent(this._content);
|
copy.setContent(this._content);
|
||||||
return _clone.base.call(this, copy, insert);
|
return _clone.base.call(this, copy, insert, includeMatrix);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in a new issue