This is a fix for bug #3038 which was investigated by @BenJamesBen who also proposed a fix in PR #3056 However, after discussing the matter, we agreed it would be better to have a generic method in core to guard against the issue of spurious drawing operations. This commit adds the `Path.clean()` method that does exactly that, as well as its documentation.
This commit is contained in:
parent
d9862326b2
commit
fab1e2f877
2 changed files with 90 additions and 0 deletions
61
markdown/dev/reference/api/path/clean/en.md
Normal file
61
markdown/dev/reference/api/path/clean/en.md
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
---
|
||||||
|
title: Path.clean()
|
||||||
|
---
|
||||||
|
|
||||||
|
The `Path.clean()` method removes spurious drawing operations from a path.
|
||||||
|
|
||||||
|
A _spurious_ drawing operation is one that has no effect, but can still cause
|
||||||
|
problems if left in place. For example, a line from a given point to the same
|
||||||
|
given point will not cause any problems as such, but can trip up things like
|
||||||
|
path offset and other methods. For this reason, such drawing operations can be
|
||||||
|
cleaned up with the `Path.clean()` method.
|
||||||
|
|
||||||
|
As this method is called under the hood to guard against various scenarios
|
||||||
|
where spurious segments could cause an issue, you should have no need to call
|
||||||
|
this method yourself explicitly, but it's there if you need it. path that you
|
||||||
|
pass it.
|
||||||
|
|
||||||
|
## Signature
|
||||||
|
|
||||||
|
```js
|
||||||
|
Path path.clean()
|
||||||
|
```
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
<Example caption="Example of the Path.clean() method">
|
||||||
|
```js
|
||||||
|
({ Point, points, Path, paths, snippets, Snippet, part }) => {
|
||||||
|
|
||||||
|
points.A = new Point(10, 10)
|
||||||
|
points.B = new Point(10, 20)
|
||||||
|
points.C = new Point(10, 30)
|
||||||
|
points.D = new Point(90, 10)
|
||||||
|
points.E = new Point(90, 20)
|
||||||
|
points.F = new Point(90, 30)
|
||||||
|
|
||||||
|
paths.a = new Path()
|
||||||
|
.move(points.A)
|
||||||
|
.line(points.C)
|
||||||
|
.line(points.B)
|
||||||
|
.line(points.B) // spurious op
|
||||||
|
.line(points.E)
|
||||||
|
.line(points.F)
|
||||||
|
.curve_(points.F, points.F) // another spurious op
|
||||||
|
.line(points.D)
|
||||||
|
.addClass('lining')
|
||||||
|
|
||||||
|
paths.b = paths.a
|
||||||
|
.clone()
|
||||||
|
.clean()
|
||||||
|
.addClass('interfacing')
|
||||||
|
|
||||||
|
paths.a.addText(`${paths.a.ops.length} ops in a`, 'center fill-lining')
|
||||||
|
paths.b.addText(`${paths.b.ops.length} ops in b`, 'center fill-note')
|
||||||
|
.attr('data-text-dy', 7)
|
||||||
|
|
||||||
|
return part
|
||||||
|
}
|
||||||
|
```
|
||||||
|
</Example>
|
||||||
|
|
|
@ -166,6 +166,34 @@ Path.prototype.bbox = function () {
|
||||||
return __bbbbox(bbs)
|
return __bbbbox(bbs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns this after cleaning out in-place path operations
|
||||||
|
*
|
||||||
|
* Cleaned means that any in-place ops will be removed
|
||||||
|
* An in-place op is when a drawing operation doesn't draw anything
|
||||||
|
* like a line from the point to the same point
|
||||||
|
*
|
||||||
|
* @return {Path} this - This, but cleaned
|
||||||
|
*/
|
||||||
|
Path.prototype.clean = function () {
|
||||||
|
const ops = []
|
||||||
|
for (const i in this.ops) {
|
||||||
|
const op = this.ops[i]
|
||||||
|
if (['move', 'close', 'noop'].includes(op.type)) ops.push(op)
|
||||||
|
else if (op.type === 'line') {
|
||||||
|
if (!op.to.sitsRoughlyOn(cur)) ops.push(op)
|
||||||
|
} else if (op.type === 'curve') {
|
||||||
|
if (!(op.cp1.sitsRoughlyOn(cur) && op.cp2.sitsRoughlyOn(cur) && op.to.sitsRoughlyOn(cur)))
|
||||||
|
ops.push(ops)
|
||||||
|
}
|
||||||
|
const cur = op?.to
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ops.length < this.ops.length) this.ops = ops
|
||||||
|
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a deep copy of this path
|
* Returns a deep copy of this path
|
||||||
*
|
*
|
||||||
|
@ -1117,6 +1145,7 @@ function __asPath(bezier, log = false) {
|
||||||
new Point(bezier.points[2].x, bezier.points[2].y),
|
new Point(bezier.points[2].x, bezier.points[2].y),
|
||||||
new Point(bezier.points[3].x, bezier.points[3].y)
|
new Point(bezier.points[3].x, bezier.points[3].y)
|
||||||
)
|
)
|
||||||
|
.clean()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue