mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2025-01-01 02:38:43 -05:00
Fix Item#importJSON() to preserve #parent on existing, already inserted items.
Closes #1041
This commit is contained in:
parent
e7f7d7c5d1
commit
ed3e283802
5 changed files with 33 additions and 20 deletions
13
CHANGELOG.md
13
CHANGELOG.md
|
@ -35,12 +35,11 @@ contribute to the code.
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
- Significant overhaul and improvements of boolean path operations
|
- Significant overhaul and improvements of boolean path operations
|
||||||
`PathItem#unite()`, `#subtract()`, `#intersect()`, `#exclude()`, `#divide()`
|
`PathItem#unite()`, `#subtract()`, `#intersect()`, `#exclude()`, `#divide()`:
|
||||||
(#936):
|
|
||||||
- Improve handling of self-intersecting paths and non-zero fill-rules.
|
- Improve handling of self-intersecting paths and non-zero fill-rules.
|
||||||
- Handle operations on identical paths.
|
- Handle operations on identical paths.
|
||||||
- Improve handling of near-collinear lines.
|
- Improve handling of near-collinear lines.
|
||||||
- Better handle self-intersecting paths that merely "touch" themselves.
|
- Handle self-intersecting paths that merely "touch" themselves.
|
||||||
- Handle situations where all encountered intersections are part of overlaps.
|
- Handle situations where all encountered intersections are part of overlaps.
|
||||||
- Methods that accepted a `time` parameter or boolean second parameter causing
|
- Methods that accepted a `time` parameter or boolean second parameter causing
|
||||||
the argument to be interpreted as curve-time instead of offset are now
|
the argument to be interpreted as curve-time instead of offset are now
|
||||||
|
@ -196,8 +195,6 @@ contribute to the code.
|
||||||
(#453).
|
(#453).
|
||||||
- Don't block touch actions when using paper in JavaScript mode (#686).
|
- Don't block touch actions when using paper in JavaScript mode (#686).
|
||||||
- Convert touch event coordinates to project coordinates (#633).
|
- Convert touch event coordinates to project coordinates (#633).
|
||||||
- Fix problems with group selection structures after `group#importJSON()`
|
|
||||||
(#785).
|
|
||||||
- Fix exceptions when a top-level layer is selected.
|
- Fix exceptions when a top-level layer is selected.
|
||||||
- Don't allow layers to turn up in hit-tests (#608).
|
- Don't allow layers to turn up in hit-tests (#608).
|
||||||
- Maintain `Raster#source` correctly on Node.js (#914).
|
- Maintain `Raster#source` correctly on Node.js (#914).
|
||||||
|
@ -207,7 +204,6 @@ contribute to the code.
|
||||||
when it is a child items array of a `CompoundPath`.
|
when it is a child items array of a `CompoundPath`.
|
||||||
- Correctly handle `#strokeScaling` in `Shape` hit-tests (#697).
|
- Correctly handle `#strokeScaling` in `Shape` hit-tests (#697).
|
||||||
- Support clip-masks in hit-testing (#671).
|
- Support clip-masks in hit-testing (#671).
|
||||||
- `#importJSON()` no longer generates callstack exceeded exceptions (#764).
|
|
||||||
- Fix incorrect `#hitTest()` and `#contains()` cases (#819, #884).
|
- Fix incorrect `#hitTest()` and `#contains()` cases (#819, #884).
|
||||||
- Update documentation to note appropriate use for `#simplify()` (#920).
|
- Update documentation to note appropriate use for `#simplify()` (#920).
|
||||||
- `#importSVG()` now supports percentage dimensions and
|
- `#importSVG()` now supports percentage dimensions and
|
||||||
|
@ -226,6 +222,11 @@ contribute to the code.
|
||||||
- `#importJSON()` and `#exportJSON()` now handle non-`Item` objects correctly
|
- `#importJSON()` and `#exportJSON()` now handle non-`Item` objects correctly
|
||||||
(#392).
|
(#392).
|
||||||
- `#exportSVG()` now exports empty paths if used as a clip-mask.
|
- `#exportSVG()` now exports empty paths if used as a clip-mask.
|
||||||
|
- `#importJSON()` no longer generates callstack exceeded exceptions (#764).
|
||||||
|
- Fix problems with group selection structures after `Group#importJSON()`
|
||||||
|
(#785).
|
||||||
|
- Fix an issue in `Item#importJSON()` where `#parent` is `null` when calling it
|
||||||
|
on existing, already inserted items (#1041).
|
||||||
- Correct issue when using paper-core in Node.js (#975).
|
- Correct issue when using paper-core in Node.js (#975).
|
||||||
- Fix `event.delta` on mousedrag events (#981).
|
- Fix `event.delta` on mousedrag events (#981).
|
||||||
- Improve handling of XML attribute namespaces for IE's XMLSerializer() (#984).
|
- Improve handling of XML attribute namespaces for IE's XMLSerializer() (#984).
|
||||||
|
|
|
@ -502,13 +502,7 @@ Base.inject(/** @lends Base# */{
|
||||||
var useTarget = isRoot && target
|
var useTarget = isRoot && target
|
||||||
&& target.constructor === ctor,
|
&& target.constructor === ctor,
|
||||||
obj = useTarget ? target
|
obj = useTarget ? target
|
||||||
: Base.create(ctor.prototype),
|
: Base.create(ctor.prototype);
|
||||||
// When reusing an object, try to (re)initialize it
|
|
||||||
// through _initialize (Item), fall-back to
|
|
||||||
// initialize (Color & co), then _set.
|
|
||||||
init = useTarget
|
|
||||||
? obj._initialize || obj.initialize || obj._set
|
|
||||||
: ctor;
|
|
||||||
// NOTE: We don't set insert false for layers since we
|
// NOTE: We don't set insert false for layers since we
|
||||||
// want these to be created on the fly in the active
|
// want these to be created on the fly in the active
|
||||||
// project into which we're importing (except for if
|
// project into which we're importing (except for if
|
||||||
|
@ -519,7 +513,9 @@ Base.inject(/** @lends Base# */{
|
||||||
if (Base.isPlainObject(arg))
|
if (Base.isPlainObject(arg))
|
||||||
arg.insert = false;
|
arg.insert = false;
|
||||||
}
|
}
|
||||||
init.apply(obj, args);
|
// When reusing an object, initialize it through #_set()
|
||||||
|
// instead of the constructor function:
|
||||||
|
(useTarget ? obj._set : ctor).apply(obj, args);
|
||||||
// Clear target to only use it once.
|
// Clear target to only use it once.
|
||||||
if (useTarget)
|
if (useTarget)
|
||||||
target = null;
|
target = null;
|
||||||
|
|
|
@ -1044,9 +1044,9 @@ Path.inject(/** @lends Path# */{
|
||||||
intercepts = [];
|
intercepts = [];
|
||||||
for (var i = 0, l = curves.length; i < l; i++) {
|
for (var i = 0, l = curves.length; i < l; i++) {
|
||||||
var values = curves[i].values;
|
var values = curves[i].values;
|
||||||
if ((curves[i].winding === 1
|
if (curves[i].winding === 1
|
||||||
&& y > values[1] && y <= values[7]
|
&& y > values[1] && y <= values[7]
|
||||||
|| y >= values[7] && y < values[1])) {
|
|| y >= values[7] && y < values[1]) {
|
||||||
var count = Curve.solveCubic(values, 1, y, roots, 0, 1);
|
var count = Curve.solveCubic(values, 1, y, roots, 0, 1);
|
||||||
for (var j = count - 1; j >= 0; j--) {
|
for (var j = count - 1; j >= 0; j--) {
|
||||||
intercepts.push(Curve.getPoint(values, roots[j]).x);
|
intercepts.push(Curve.getPoint(values, roots[j]).x);
|
||||||
|
|
|
@ -485,6 +485,7 @@ var Color = Base.extend(new function() {
|
||||||
// We are storing color internally as an array of components
|
// We are storing color internally as an array of components
|
||||||
var slice = Array.prototype.slice,
|
var slice = Array.prototype.slice,
|
||||||
args = arguments,
|
args = arguments,
|
||||||
|
reading = this.__read,
|
||||||
read = 0,
|
read = 0,
|
||||||
type,
|
type,
|
||||||
components,
|
components,
|
||||||
|
@ -508,7 +509,7 @@ var Color = Base.extend(new function() {
|
||||||
alpha = args[2];
|
alpha = args[2];
|
||||||
} else {
|
} else {
|
||||||
// For deserialization, shift out and process normally.
|
// For deserialization, shift out and process normally.
|
||||||
if (this.__read)
|
if (reading)
|
||||||
read = 1; // Will be increased below
|
read = 1; // Will be increased below
|
||||||
// Shift type out of the arguments, and process normally.
|
// Shift type out of the arguments, and process normally.
|
||||||
args = slice.call(args, 1);
|
args = slice.call(args, 1);
|
||||||
|
@ -536,10 +537,11 @@ var Color = Base.extend(new function() {
|
||||||
: 'gray';
|
: 'gray';
|
||||||
var length = types[type].length;
|
var length = types[type].length;
|
||||||
alpha = values[length];
|
alpha = values[length];
|
||||||
if (this.__read)
|
if (reading) {
|
||||||
read += values === arguments
|
read += values === arguments
|
||||||
? length + (alpha != null ? 1 : 0)
|
? length + (alpha != null ? 1 : 0)
|
||||||
: 1;
|
: 1;
|
||||||
|
}
|
||||||
if (values.length > length)
|
if (values.length > length)
|
||||||
values = slice.call(values, 0, length);
|
values = slice.call(values, 0, length);
|
||||||
} else if (argType === 'string') {
|
} else if (argType === 'string') {
|
||||||
|
@ -601,7 +603,7 @@ var Color = Base.extend(new function() {
|
||||||
alpha = arg.alpha;
|
alpha = arg.alpha;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (this.__read && type)
|
if (reading && type)
|
||||||
read = 1;
|
read = 1;
|
||||||
}
|
}
|
||||||
// Default fallbacks: rgb, black
|
// Default fallbacks: rgb, black
|
||||||
|
@ -621,10 +623,13 @@ var Color = Base.extend(new function() {
|
||||||
this._components = components;
|
this._components = components;
|
||||||
this._properties = types[this._type];
|
this._properties = types[this._type];
|
||||||
this._alpha = alpha;
|
this._alpha = alpha;
|
||||||
if (this.__read)
|
if (reading)
|
||||||
this.__read = read;
|
this.__read = read;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Have #_set point to #initialize, as used by Base.importJSON()
|
||||||
|
_set: '#initialize',
|
||||||
|
|
||||||
_serialize: function(options, dictionary) {
|
_serialize: function(options, dictionary) {
|
||||||
var components = this.getComponents();
|
var components = this.getComponents();
|
||||||
return Base.serialize(
|
return Base.serialize(
|
||||||
|
|
|
@ -245,3 +245,14 @@ test('Color#importJSON()', function() {
|
||||||
return color.equals(path.fillColor);
|
return color.equals(path.fillColor);
|
||||||
}, true);
|
}, true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('Path#importJSON()', function() {
|
||||||
|
var path = new Path();
|
||||||
|
var layer = project.activeLayer;
|
||||||
|
equals(function() { return path.parent === layer; }, true);
|
||||||
|
path.importJSON('["Path",{"segments":[[[50,100],[0,27.61424],[0,-27.61424]],[[100,50],[-27.61424,0],[27.61424,0]],[[150,100],[0,-27.61424],[0,27.61424]],[[100,150],[27.61424,0],[-27.61424,0]]],"closed":true,"fillColor":[1,0,0]}]');
|
||||||
|
equals(function() { return path.bounds; }, { x: 50, y: 50, width: 100, height: 100 });
|
||||||
|
equals(function() { return path.fillColor; }, { red: 1, green: 0, blue: 0 });
|
||||||
|
equals(function() { return layer.firstChild === path; }, true);
|
||||||
|
equals(function() { return path.parent === layer; }, true);
|
||||||
|
});
|
||||||
|
|
Loading…
Reference in a new issue