mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2025-01-03 19:45:44 -05:00
Implement PathItem#compare() to support compound-paths.
Still needs testing.
This commit is contained in:
parent
ccac7ec7c5
commit
a5a0e90bee
2 changed files with 53 additions and 17 deletions
|
@ -1548,17 +1548,11 @@ var Path = PathItem.extend(/** @lends Path# */{
|
||||||
|
|
||||||
toPath: '#clone',
|
toPath: '#clone',
|
||||||
|
|
||||||
/**
|
// NOTE: Documentation is in PathItem#compare()
|
||||||
* Compares the geometry of two paths to see if they describe the same
|
compare: function compare(path) {
|
||||||
* shape, detecting cases where paths start in different segments or even
|
// If a compound-path is involved, redirect to PathItem#compare()
|
||||||
* use different amounts of curves to describe the same shape, as long as
|
if (!path || path instanceof CompoundPath)
|
||||||
* their orientation is the same, and their segments and handles really
|
return compare.base.call(this, path);
|
||||||
* result in the same visual appearance of curves.
|
|
||||||
*
|
|
||||||
* @param {Path} path the path to compare this path's geometry with
|
|
||||||
* @return {Boolean} {@true if two paths describe the shame shape}
|
|
||||||
*/
|
|
||||||
compare: function(path) {
|
|
||||||
var curves1 = this.getCurves(),
|
var curves1 = this.getCurves(),
|
||||||
curves2 = path.getCurves(),
|
curves2 = path.getCurves(),
|
||||||
length1 = curves1.length,
|
length1 = curves1.length,
|
||||||
|
@ -1574,15 +1568,15 @@ var Path = PathItem.extend(/** @lends Path# */{
|
||||||
end1 = 0, end2;
|
end1 = 0, end2;
|
||||||
// First, loop through curves2, looking for the start of the overlapping
|
// First, loop through curves2, looking for the start of the overlapping
|
||||||
// sequence with curves1[0]. Also cache curve values for later reuse.
|
// sequence with curves1[0]. Also cache curve values for later reuse.
|
||||||
for (var i2 = 0; i2 < length2; i2++) {
|
for (var i = 0; i < length2; i++) {
|
||||||
var v2 = curves2[i2].getValues();
|
var v2 = curves2[i].getValues();
|
||||||
values2.push(v2);
|
values2.push(v2);
|
||||||
var overlaps = Curve.getOverlaps(v1, v2);
|
var overlaps = Curve.getOverlaps(v1, v2);
|
||||||
if (overlaps) {
|
if (overlaps) {
|
||||||
// If the overlap doesn't start at the beginning of v2, then
|
// If the overlap doesn't start at the beginning of v2, then
|
||||||
// it can only be the a partial overlap with curves2[0], and
|
// it can only be the a partial overlap with curves2[0], and
|
||||||
// the start is at curves2[-1]:
|
// the start is at curves2[-1]:
|
||||||
pos2 = !i2 && overlaps[0][0] > 0 ? length2 - 1 : i2;
|
pos2 = !i && overlaps[0][0] > 0 ? length2 - 1 : i;
|
||||||
// Set end2 to the start of the first overlap on curves2, so
|
// Set end2 to the start of the first overlap on curves2, so
|
||||||
// connection checks further down can work.
|
// connection checks further down can work.
|
||||||
end2 = overlaps[0][1];
|
end2 = overlaps[0][1];
|
||||||
|
@ -1598,7 +1592,7 @@ var Path = PathItem.extend(/** @lends Path# */{
|
||||||
while (v1 && v2) {
|
while (v1 && v2) {
|
||||||
var overlaps = Curve.getOverlaps(v1, v2);
|
var overlaps = Curve.getOverlaps(v1, v2);
|
||||||
if (overlaps) {
|
if (overlaps) {
|
||||||
// Check that the overlaps are joining on curves1
|
// Check that the overlaps are joining on curves1.
|
||||||
var t1 = overlaps[0][0];
|
var t1 = overlaps[0][0];
|
||||||
if (abs(t1 - end1) < epsilon) {
|
if (abs(t1 - end1) < epsilon) {
|
||||||
end1 = overlaps[1][0];
|
end1 = overlaps[1][0];
|
||||||
|
@ -1608,7 +1602,7 @@ var Path = PathItem.extend(/** @lends Path# */{
|
||||||
v1 = ++pos1 < length1 ? curves1[pos1].getValues() : null;
|
v1 = ++pos1 < length1 ? curves1[pos1].getValues() : null;
|
||||||
end1 = 0;
|
end1 = 0;
|
||||||
}
|
}
|
||||||
// Check that the overlaps are joining on curves2
|
// Check that the overlaps are joining on curves2.
|
||||||
var t2 = overlaps[0][1];
|
var t2 = overlaps[0][1];
|
||||||
if (abs(t2 - end2) < epsilon) {
|
if (abs(t2 - end2) < epsilon) {
|
||||||
if (!start2)
|
if (!start2)
|
||||||
|
@ -1627,7 +1621,7 @@ var Path = PathItem.extend(/** @lends Path# */{
|
||||||
// start on curve2, the two paths are not identical.
|
// start on curve2, the two paths are not identical.
|
||||||
return start2[0] === pos2 && start2[1] === end2;
|
return start2[0] === pos2 && start2[1] === end2;
|
||||||
}
|
}
|
||||||
// All good, continue to avoid the break; further down
|
// All good, continue to avoid the break; further down.
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -751,6 +751,48 @@ var PathItem = Item.extend(/** @lends PathItem# */{
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compares the geometry of two paths to see if they describe the same
|
||||||
|
* shape, detecting cases where paths start in different segments or even
|
||||||
|
* use different amounts of curves to describe the same shape, as long as
|
||||||
|
* their orientation is the same, and their segments and handles really
|
||||||
|
* result in the same visual appearance of curves.
|
||||||
|
*
|
||||||
|
* @name PathItem#compare
|
||||||
|
* @function
|
||||||
|
*
|
||||||
|
* @param {PathItem} path the path to compare this path's geometry with
|
||||||
|
* @return {Boolean} {@true if two paths describe the shame shape}
|
||||||
|
*/
|
||||||
|
compare: function(path) {
|
||||||
|
var ok = false;
|
||||||
|
if (path) {
|
||||||
|
var paths1 = this._children || [this],
|
||||||
|
paths2 = path._children.slice() || [path],
|
||||||
|
length1 = paths1.length,
|
||||||
|
length2 = paths2.length,
|
||||||
|
matched = [],
|
||||||
|
count;
|
||||||
|
ok = true;
|
||||||
|
for (var i1 = length1 - 1; i1 >= 0 && ok; i1--) {
|
||||||
|
var path1 = paths1[i1];
|
||||||
|
ok = false;
|
||||||
|
for (var i2 = length2 - 1; i2 >= 0 && !ok; i2--) {
|
||||||
|
if (Path.compare(path1, paths2[i2])) {
|
||||||
|
if (!matched[i2]) {
|
||||||
|
matched[i2] = true;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
ok = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Each path in path2 needs to be matched at least once.
|
||||||
|
ok = ok && count === length2;
|
||||||
|
}
|
||||||
|
return ok;
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@grouptitle Postscript Style Drawing Commands}
|
* {@grouptitle Postscript Style Drawing Commands}
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in a new issue