fix erase with holes in it, but it still doesn't work if you erase crazy path with crazy path

This commit is contained in:
DD 2017-10-26 18:27:39 -04:00
parent 2be90c1633
commit 819215786f
2 changed files with 66 additions and 41 deletions

View file

@ -157,7 +157,7 @@ class PaperCanvas extends React.Component {
PaperCanvas.propTypes = {
canvasRef: PropTypes.func,
clearUndo: PropTypes.func.isRequired,
mode: PropTypes.instanceOf(Modes),
mode: PropTypes.oneOf(Object.values(Modes)),
onUpdateSvg: PropTypes.func.isRequired,
rotationCenterX: PropTypes.number,
rotationCenterY: PropTypes.number,

View file

@ -248,7 +248,8 @@ class Blobbiness {
let items = getItems({
match: function (item) {
return item.selected && blob.isMergeable(lastPath, item) && blob.touches(lastPath, item);
}
},
class: paper.PathItem
});
// Eraser didn't hit anything selected, so assume they meant to erase from all instead of from subset
// and deselect the selection
@ -257,7 +258,8 @@ class Blobbiness {
items = getItems({
match: function (item) {
return blob.isMergeable(lastPath, item) && blob.touches(lastPath, item);
}
},
class: paper.PathItem
});
}
@ -317,14 +319,23 @@ class Blobbiness {
}
}
if (newPath.children) {
this.separateCompoundPath(newPath);
newPath.remove();
}
items[i].remove();
}
lastPath.remove();
}
separateCompoundPath (compoundPath) {
// Divide topologically separate shapes into their own compound paths, instead of
// everything being stuck together.
// Assume that result of erase operation returns clockwise paths for positive shapes
const clockwiseChildren = [];
const ccwChildren = [];
if (newPath.children) {
for (let j = newPath.children.length - 1; j >= 0; j--) {
const child = newPath.children[j];
for (let j = compoundPath.children.length - 1; j >= 0; j--) {
const child = compoundPath.children[j];
if (child.isClockwise()) {
clockwiseChildren.push(child);
} else {
@ -333,19 +344,19 @@ class Blobbiness {
}
for (let j = 0; j < clockwiseChildren.length; j++) {
const cw = clockwiseChildren[j];
cw.copyAttributes(newPath);
cw.fillColor = newPath.fillColor;
cw.strokeColor = newPath.strokeColor;
cw.strokeWidth = newPath.strokeWidth;
cw.insertAbove(items[i]);
cw.copyAttributes(compoundPath);
cw.fillColor = compoundPath.fillColor;
cw.strokeColor = compoundPath.strokeColor;
cw.strokeWidth = compoundPath.strokeWidth;
cw.insertAbove(compoundPath);
// Go backward since we are deleting elements
let newCw = cw;
for (let k = ccwChildren.length - 1; k >= 0; k--) {
const ccw = ccwChildren[k];
if (this.firstEnclosesSecond(ccw, cw) || this.firstEnclosesSecond(cw, ccw)) {
if (this.firstEnclosesSecond(cw, ccw)) {
const temp = newCw.subtract(ccw);
temp.insertAbove(newCw);
temp.insertAbove(compoundPath);
newCw.remove();
newCw = temp;
ccw.remove();
@ -353,11 +364,6 @@ class Blobbiness {
}
}
}
newPath.remove();
}
items[i].remove();
}
lastPath.remove();
}
colorMatch (existingPath, addedPath) {
@ -388,10 +394,29 @@ class Blobbiness {
return false;
}
matchesAnyChild (group, path) {
for (const child of group.children) {
if (child.children && this.matchesAnyChild(path, child)) {
return true;
}
if (path === child) {
return true;
}
}
return false;
}
isMergeable (newPath, existingPath) {
return existingPath instanceof paper.PathItem && // path or compound path
existingPath !== this.cursorPreview && // don't merge with the mouse preview
existingPath !== newPath; // don't merge with self
// Path or compound path
if (!(existingPath instanceof paper.PathItem)) {
return;
}
if (newPath.children) {
if (this.matchesAnyChild(newPath, existingPath)) { // Don't merge with children of self
return false;
}
}
return existingPath !== newPath; // don't merge with self
}
deactivateTool () {