wip(core): Work on path unit tests
This commit is contained in:
parent
cf0c70f4c6
commit
4121ef44d2
3 changed files with 406 additions and 338 deletions
|
@ -9,20 +9,30 @@ import {
|
||||||
pointOnCurve,
|
pointOnCurve,
|
||||||
curveEdge,
|
curveEdge,
|
||||||
round,
|
round,
|
||||||
|
addNonEnumProp,
|
||||||
} from './utils.mjs'
|
} from './utils.mjs'
|
||||||
|
|
||||||
export function Path(debug = false) {
|
export function Path(debug = false) {
|
||||||
this.render = true
|
|
||||||
|
// Non-enumerable properties
|
||||||
|
addNonEnumProp(this, 'render', true) // FIXME: replace with hide
|
||||||
|
//addNonEnumProp(this, 'topLeft', false)
|
||||||
|
//addNonEnumProp(this, 'bottomRight', false)
|
||||||
|
//addNonEnumProp(this, 'attributes', new Attributes())
|
||||||
|
//addNonEnumProp(this, 'ops', [])
|
||||||
|
addNonEnumProp(this, 'debug', debug) // FIXME: Is this needed?
|
||||||
|
|
||||||
|
// Enumerable properties
|
||||||
|
this.hide = false
|
||||||
|
this.ops = []
|
||||||
|
this.attributes = new Attributes()
|
||||||
this.topLeft = false
|
this.topLeft = false
|
||||||
this.bottomRight = false
|
this.bottomRight = false
|
||||||
this.attributes = new Attributes()
|
|
||||||
this.ops = []
|
|
||||||
Object.defineProperty(this, 'debug', { value: debug, configurable: true })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Adds the raise method for a path not created through the proxy **/
|
/** Adds the log method for a path not created through the proxy **/
|
||||||
Path.prototype.withRaise = function (raise = false) {
|
Path.prototype.withLog = function (log = false) {
|
||||||
if (raise) Object.defineProperty(this, 'raise', { value: raise })
|
if (log) addNonEnumProp(this, 'log', log)
|
||||||
|
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
@ -45,7 +55,7 @@ Path.prototype.setClass = function (className = false) {
|
||||||
/** Adds a move operation to Point to */
|
/** Adds a move operation to Point to */
|
||||||
Path.prototype.move = function (to) {
|
Path.prototype.move = function (to) {
|
||||||
if (to instanceof Point !== true)
|
if (to instanceof Point !== true)
|
||||||
this.raise.warning('Called `Path.move(to)` but `to` is not a `Point` object')
|
this.log.warning('Called `Path.move(to)` but `to` is not a `Point` object')
|
||||||
this.ops.push({ type: 'move', to })
|
this.ops.push({ type: 'move', to })
|
||||||
|
|
||||||
return this
|
return this
|
||||||
|
@ -54,7 +64,7 @@ Path.prototype.move = function (to) {
|
||||||
/** Adds a line operation to Point to */
|
/** Adds a line operation to Point to */
|
||||||
Path.prototype.line = function (to) {
|
Path.prototype.line = function (to) {
|
||||||
if (to instanceof Point !== true)
|
if (to instanceof Point !== true)
|
||||||
this.raise.warning('Called `Path.line(to)` but `to` is not a `Point` object')
|
this.log.warning('Called `Path.line(to)` but `to` is not a `Point` object')
|
||||||
this.ops.push({ type: 'line', to })
|
this.ops.push({ type: 'line', to })
|
||||||
|
|
||||||
return this
|
return this
|
||||||
|
@ -63,11 +73,11 @@ Path.prototype.line = function (to) {
|
||||||
/** Adds a curve operation via cp1 & cp2 to Point to */
|
/** Adds a curve operation via cp1 & cp2 to Point to */
|
||||||
Path.prototype.curve = function (cp1, cp2, to) {
|
Path.prototype.curve = function (cp1, cp2, to) {
|
||||||
if (to instanceof Point !== true)
|
if (to instanceof Point !== true)
|
||||||
this.raise.warning('Called `Path.curve(cp1, cp2, to)` but `to` is not a `Point` object')
|
this.log.warning('Called `Path.curve(cp1, cp2, to)` but `to` is not a `Point` object')
|
||||||
if (cp1 instanceof Point !== true)
|
if (cp1 instanceof Point !== true)
|
||||||
this.raise.warning('Called `Path.curve(cp1, cp2, to)` but `cp1` is not a `Point` object')
|
this.log.warning('Called `Path.curve(cp1, cp2, to)` but `cp1` is not a `Point` object')
|
||||||
if (cp2 instanceof Point !== true)
|
if (cp2 instanceof Point !== true)
|
||||||
this.raise.warning('Called `Path.curve(cp1, cp2, to)` but `cp2` is not a `Point` object')
|
this.log.warning('Called `Path.curve(cp1, cp2, to)` but `cp2` is not a `Point` object')
|
||||||
this.ops.push({ type: 'curve', cp1, cp2, to })
|
this.ops.push({ type: 'curve', cp1, cp2, to })
|
||||||
|
|
||||||
return this
|
return this
|
||||||
|
@ -76,9 +86,9 @@ Path.prototype.curve = function (cp1, cp2, to) {
|
||||||
/** Adds a curve operation without cp1 via cp2 to Point to */
|
/** Adds a curve operation without cp1 via cp2 to Point to */
|
||||||
Path.prototype._curve = function (cp2, to) {
|
Path.prototype._curve = function (cp2, to) {
|
||||||
if (to instanceof Point !== true)
|
if (to instanceof Point !== true)
|
||||||
this.raise.warning('Called `Path._curve(cp2, to)` but `to` is not a `Point` object')
|
this.log.warning('Called `Path._curve(cp2, to)` but `to` is not a `Point` object')
|
||||||
if (cp2 instanceof Point !== true)
|
if (cp2 instanceof Point !== true)
|
||||||
this.raise.warning('Called `Path._curve(cp2, to)` but `cp2` is not a `Point` object')
|
this.log.warning('Called `Path._curve(cp2, to)` but `cp2` is not a `Point` object')
|
||||||
let cp1 = this.ops.slice(-1).pop().to
|
let cp1 = this.ops.slice(-1).pop().to
|
||||||
this.ops.push({ type: 'curve', cp1, cp2, to })
|
this.ops.push({ type: 'curve', cp1, cp2, to })
|
||||||
|
|
||||||
|
@ -88,9 +98,9 @@ Path.prototype._curve = function (cp2, to) {
|
||||||
/** Adds a curve operation via cp1 with no cp2 to Point to */
|
/** Adds a curve operation via cp1 with no cp2 to Point to */
|
||||||
Path.prototype.curve_ = function (cp1, to) {
|
Path.prototype.curve_ = function (cp1, to) {
|
||||||
if (to instanceof Point !== true)
|
if (to instanceof Point !== true)
|
||||||
this.raise.warning('Called `Path.curve_(cp1, to)` but `to` is not a `Point` object')
|
this.log.warning('Called `Path.curve_(cp1, to)` but `to` is not a `Point` object')
|
||||||
if (cp1 instanceof Point !== true)
|
if (cp1 instanceof Point !== true)
|
||||||
this.raise.warning('Called `Path.curve_(cp1, to)` but `cp1` is not a `Point` object')
|
this.log.warning('Called `Path.curve_(cp1, to)` but `cp1` is not a `Point` object')
|
||||||
let cp2 = to.copy()
|
let cp2 = to.copy()
|
||||||
this.ops.push({ type: 'curve', cp1, cp2, to })
|
this.ops.push({ type: 'curve', cp1, cp2, to })
|
||||||
|
|
||||||
|
@ -114,9 +124,9 @@ Path.prototype.noop = function (id = false) {
|
||||||
/** Replace a noop operation with the ops from path */
|
/** Replace a noop operation with the ops from path */
|
||||||
Path.prototype.insop = function (noopId, path) {
|
Path.prototype.insop = function (noopId, path) {
|
||||||
if (!noopId)
|
if (!noopId)
|
||||||
this.raise.warning('Called `Path.insop(noopId, path)` but `noopId` is undefined or false')
|
this.log.warning('Called `Path.insop(noopId, path)` but `noopId` is undefined or false')
|
||||||
if (path instanceof Path !== true)
|
if (path instanceof Path !== true)
|
||||||
this.raise.warning('Called `Path.insop(noopId, path) but `path` is not a `Path` object')
|
this.log.warning('Called `Path.insop(noopId, path) but `path` is not a `Path` object')
|
||||||
let newPath = this.clone()
|
let newPath = this.clone()
|
||||||
for (let i in newPath.ops) {
|
for (let i in newPath.ops) {
|
||||||
if (newPath.ops[i].type === 'noop' && newPath.ops[i].id === noopId) {
|
if (newPath.ops[i].type === 'noop' && newPath.ops[i].id === noopId) {
|
||||||
|
@ -133,13 +143,13 @@ Path.prototype.insop = function (noopId, path) {
|
||||||
/** Adds an attribute. This is here to make this call chainable in assignment */
|
/** Adds an attribute. This is here to make this call chainable in assignment */
|
||||||
Path.prototype.attr = function (name, value, overwrite = false) {
|
Path.prototype.attr = function (name, value, overwrite = false) {
|
||||||
if (!name)
|
if (!name)
|
||||||
this.raise.warning(
|
this.log.warning(
|
||||||
'Called `Path.attr(name, value, overwrite=false)` but `name` is undefined or false'
|
'Called `Path.attr(name, value, overwrite=false)` but `name` is undefined or false'
|
||||||
)
|
)
|
||||||
if (typeof value === 'undefined')
|
if (typeof value === 'undefined')
|
||||||
this.raise.warning('Called `Path.attr(name, value, overwrite=false)` but `value` is undefined')
|
this.log.warning('Called `Path.attr(name, value, overwrite=false)` but `value` is undefined')
|
||||||
if (overwrite)
|
if (overwrite)
|
||||||
this.raise.debug(
|
this.log.debug(
|
||||||
`Overwriting \`Path.attribute.${name}\` with ${value} (was: ${this.attributes.get(name)})`
|
`Overwriting \`Path.attribute.${name}\` with ${value} (was: ${this.attributes.get(name)})`
|
||||||
)
|
)
|
||||||
if (overwrite) this.attributes.set(name, value)
|
if (overwrite) this.attributes.set(name, value)
|
||||||
|
@ -176,8 +186,8 @@ Path.prototype.asPathstring = function () {
|
||||||
/** Returns offset of this path as a new path */
|
/** Returns offset of this path as a new path */
|
||||||
Path.prototype.offset = function (distance) {
|
Path.prototype.offset = function (distance) {
|
||||||
if (typeof distance !== 'number')
|
if (typeof distance !== 'number')
|
||||||
this.raise.error('Called `Path.offset(distance)` but `distance` is not a number')
|
this.log.error('Called `Path.offset(distance)` but `distance` is not a number')
|
||||||
return pathOffset(this, distance, this.raise)
|
return pathOffset(this, distance, this.log)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the length of this path */
|
/** Returns the length of this path */
|
||||||
|
@ -209,14 +219,14 @@ Path.prototype.length = function () {
|
||||||
/** Returns the startpoint of the path */
|
/** Returns the startpoint of the path */
|
||||||
Path.prototype.start = function () {
|
Path.prototype.start = function () {
|
||||||
if (this.ops.length < 1 || typeof this.ops[0].to === 'undefined')
|
if (this.ops.length < 1 || typeof this.ops[0].to === 'undefined')
|
||||||
this.raise.error('Called `Path.start()` but this path has no drawing operations')
|
this.log.error('Called `Path.start()` but this path has no drawing operations')
|
||||||
return this.ops[0].to
|
return this.ops[0].to
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the endpoint of the path */
|
/** Returns the endpoint of the path */
|
||||||
Path.prototype.end = function () {
|
Path.prototype.end = function () {
|
||||||
if (this.ops.length < 1)
|
if (this.ops.length < 1)
|
||||||
this.raise.error('Called `Path.end()` but this path has no drawing operations')
|
this.log.error('Called `Path.end()` but this path has no drawing operations')
|
||||||
let op = this.ops[this.ops.length - 1]
|
let op = this.ops[this.ops.length - 1]
|
||||||
|
|
||||||
if (op.type === 'close') return this.start()
|
if (op.type === 'close') return this.start()
|
||||||
|
@ -291,7 +301,7 @@ Path.prototype.boundary = function () {
|
||||||
|
|
||||||
/** Returns a deep copy of this */
|
/** Returns a deep copy of this */
|
||||||
Path.prototype.clone = function () {
|
Path.prototype.clone = function () {
|
||||||
let clone = new Path(this.debug).withRaise(this.raise).setRender(this.render)
|
let clone = new Path(this.debug).withLog(this.log).setRender(this.render)
|
||||||
if (this.topLeft) clone.topLeft = this.topLeft.clone()
|
if (this.topLeft) clone.topLeft = this.topLeft.clone()
|
||||||
else clone.topLeft = false
|
else clone.topLeft = false
|
||||||
if (this.bottomRight) clone.bottomRight = this.bottomRight.clone()
|
if (this.bottomRight) clone.bottomRight = this.bottomRight.clone()
|
||||||
|
@ -318,12 +328,12 @@ Path.prototype.clone = function () {
|
||||||
/** Joins this with that path, closes them if wanted */
|
/** Joins this with that path, closes them if wanted */
|
||||||
Path.prototype.join = function (that, closed = false) {
|
Path.prototype.join = function (that, closed = false) {
|
||||||
if (that instanceof Path !== true)
|
if (that instanceof Path !== true)
|
||||||
this.raise.error('Called `Path.join(that)` but `that` is not a `Path` object')
|
this.log.error('Called `Path.join(that)` but `that` is not a `Path` object')
|
||||||
return joinPaths([this, that], closed, this.raise)
|
return joinPaths([this, that], closed, this.log)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Offsets a path by distance */
|
/** Offsets a path by distance */
|
||||||
function pathOffset(path, distance, raise) {
|
function pathOffset(path, distance, log) {
|
||||||
let offset = []
|
let offset = []
|
||||||
let current
|
let current
|
||||||
let start = false
|
let start = false
|
||||||
|
@ -331,18 +341,18 @@ function pathOffset(path, distance, raise) {
|
||||||
for (let i in path.ops) {
|
for (let i in path.ops) {
|
||||||
let op = path.ops[i]
|
let op = path.ops[i]
|
||||||
if (op.type === 'line') {
|
if (op.type === 'line') {
|
||||||
let segment = offsetLine(current, op.to, distance, path.debug, path.raise)
|
let segment = offsetLine(current, op.to, distance, path.debug, path.log)
|
||||||
if (segment) offset.push(segment)
|
if (segment) offset.push(segment)
|
||||||
} else if (op.type === 'curve') {
|
} else if (op.type === 'curve') {
|
||||||
// We need to avoid a control point sitting on top of start or end
|
// We need to avoid a control point sitting on top of start or end
|
||||||
// because that will break the offset in bezier-js
|
// because that will break the offset in bezier-js
|
||||||
let cp1, cp2
|
let cp1, cp2
|
||||||
if (current.sitsRoughlyOn(op.cp1)) {
|
if (current.sitsRoughlyOn(op.cp1)) {
|
||||||
cp1 = new Path(path.debug).withRaise(path.raise).move(current).curve(op.cp1, op.cp2, op.to)
|
cp1 = new Path(path.debug).withLog(path.log).move(current).curve(op.cp1, op.cp2, op.to)
|
||||||
cp1 = cp1.shiftAlong(cp1.length() > 2 ? 2 : cp1.length() / 10)
|
cp1 = cp1.shiftAlong(cp1.length() > 2 ? 2 : cp1.length() / 10)
|
||||||
} else cp1 = op.cp1
|
} else cp1 = op.cp1
|
||||||
if (op.cp2.sitsRoughlyOn(op.to)) {
|
if (op.cp2.sitsRoughlyOn(op.to)) {
|
||||||
cp2 = new Path(path.debug).withRaise(path.raise).move(op.to).curve(op.cp2, op.cp1, current)
|
cp2 = new Path(path.debug).withLog(path.log).move(op.to).curve(op.cp2, op.cp1, current)
|
||||||
cp2 = cp2.shiftAlong(cp2.length() > 2 ? 2 : cp2.length() / 10)
|
cp2 = cp2.shiftAlong(cp2.length() > 2 ? 2 : cp2.length() / 10)
|
||||||
} else cp2 = op.cp2
|
} else cp2 = op.cp2
|
||||||
let b = new Bezier(
|
let b = new Bezier(
|
||||||
|
@ -351,30 +361,30 @@ function pathOffset(path, distance, raise) {
|
||||||
{ x: cp2.x, y: cp2.y },
|
{ x: cp2.x, y: cp2.y },
|
||||||
{ x: op.to.x, y: op.to.y }
|
{ x: op.to.x, y: op.to.y }
|
||||||
)
|
)
|
||||||
for (let bezier of b.offset(distance)) offset.push(asPath(bezier, path.debug, path.raise))
|
for (let bezier of b.offset(distance)) offset.push(asPath(bezier, path.debug, path.log))
|
||||||
} else if (op.type === 'close') closed = true
|
} else if (op.type === 'close') closed = true
|
||||||
if (op.to) current = op.to
|
if (op.to) current = op.to
|
||||||
if (!start) start = current
|
if (!start) start = current
|
||||||
}
|
}
|
||||||
|
|
||||||
return joinPaths(offset, closed, raise)
|
return joinPaths(offset, closed, log)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Offsets a line by distance */
|
/** Offsets a line by distance */
|
||||||
function offsetLine(from, to, distance, debug = false, raise = false) {
|
function offsetLine(from, to, distance, debug = false, log = false) {
|
||||||
if (from.x === to.x && from.y === to.y) return false
|
if (from.x === to.x && from.y === to.y) return false
|
||||||
let angle = from.angle(to) - 90
|
let angle = from.angle(to) - 90
|
||||||
|
|
||||||
return new Path(debug)
|
return new Path(debug)
|
||||||
.withRaise(raise)
|
.withLog(log)
|
||||||
.move(from.shift(angle, distance))
|
.move(from.shift(angle, distance))
|
||||||
.line(to.shift(angle, distance))
|
.line(to.shift(angle, distance))
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Converts a bezier-js instance to a path */
|
/** Converts a bezier-js instance to a path */
|
||||||
function asPath(bezier, debug = false, raise = false) {
|
function asPath(bezier, debug = false, log = false) {
|
||||||
return new Path(debug)
|
return new Path(debug)
|
||||||
.withRaise(raise)
|
.withLog(log)
|
||||||
.move(new Point(bezier.points[0].x, bezier.points[0].y))
|
.move(new Point(bezier.points[0].x, bezier.points[0].y))
|
||||||
.curve(
|
.curve(
|
||||||
new Point(bezier.points[1].x, bezier.points[1].y),
|
new Point(bezier.points[1].x, bezier.points[1].y),
|
||||||
|
@ -384,8 +394,8 @@ function asPath(bezier, debug = false, raise = false) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Joins path segments together into one path */
|
/** Joins path segments together into one path */
|
||||||
function joinPaths(paths, closed = false, raise = false) {
|
function joinPaths(paths, closed = false, log = false) {
|
||||||
let joint = new Path(paths[0].debug).withRaise(paths[0].raise).move(paths[0].ops[0].to)
|
let joint = new Path(paths[0].debug).withLog(paths[0].log).move(paths[0].ops[0].to)
|
||||||
let current
|
let current
|
||||||
for (let p of paths) {
|
for (let p of paths) {
|
||||||
for (let op of p.ops) {
|
for (let op of p.ops) {
|
||||||
|
@ -396,7 +406,7 @@ function joinPaths(paths, closed = false, raise = false) {
|
||||||
if (current && !op.to.sitsRoughlyOn(current)) joint.line(op.to)
|
if (current && !op.to.sitsRoughlyOn(current)) joint.line(op.to)
|
||||||
} else {
|
} else {
|
||||||
let err = 'Cannot join a closed path with another'
|
let err = 'Cannot join a closed path with another'
|
||||||
joint.raise.error(err)
|
joint.log.error(err)
|
||||||
throw new Error(err)
|
throw new Error(err)
|
||||||
}
|
}
|
||||||
if (op.to) current = op.to
|
if (op.to) current = op.to
|
||||||
|
@ -410,7 +420,7 @@ function joinPaths(paths, closed = false, raise = false) {
|
||||||
/** Returns a point that lies at distance along this */
|
/** Returns a point that lies at distance along this */
|
||||||
Path.prototype.shiftAlong = function (distance, stepsPerMm = 25) {
|
Path.prototype.shiftAlong = function (distance, stepsPerMm = 25) {
|
||||||
if (typeof distance !== 'number')
|
if (typeof distance !== 'number')
|
||||||
this.raise.error('Called `Path.shiftAlong(distance)` but `distance` is not a number')
|
this.log.error('Called `Path.shiftAlong(distance)` but `distance` is not a number')
|
||||||
let len = 0
|
let len = 0
|
||||||
let current
|
let current
|
||||||
for (let i in this.ops) {
|
for (let i in this.ops) {
|
||||||
|
@ -435,7 +445,7 @@ Path.prototype.shiftAlong = function (distance, stepsPerMm = 25) {
|
||||||
}
|
}
|
||||||
current = op.to
|
current = op.to
|
||||||
}
|
}
|
||||||
this.raise.error(
|
this.log.error(
|
||||||
`Called \`Path.shiftAlong(distance)\` with a \`distance\` of \`${distance}\` but \`Path.length()\` is only \`${this.length()}\``
|
`Called \`Path.shiftAlong(distance)\` with a \`distance\` of \`${distance}\` but \`Path.length()\` is only \`${this.length()}\``
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -443,7 +453,7 @@ Path.prototype.shiftAlong = function (distance, stepsPerMm = 25) {
|
||||||
/** Returns a point that lies at fraction along this */
|
/** Returns a point that lies at fraction along this */
|
||||||
Path.prototype.shiftFractionAlong = function (fraction, stepsPerMm = 25) {
|
Path.prototype.shiftFractionAlong = function (fraction, stepsPerMm = 25) {
|
||||||
if (typeof fraction !== 'number')
|
if (typeof fraction !== 'number')
|
||||||
this.raise.error('Called `Path.shiftFractionAlong(fraction)` but `fraction` is not a number')
|
this.log.error('Called `Path.shiftFractionAlong(fraction)` but `fraction` is not a number')
|
||||||
return this.shiftAlong(this.length() * fraction, stepsPerMm)
|
return this.shiftAlong(this.length() * fraction, stepsPerMm)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -553,17 +563,17 @@ Path.prototype.reverse = function () {
|
||||||
let op = this.ops[i]
|
let op = this.ops[i]
|
||||||
if (op.type === 'line') {
|
if (op.type === 'line') {
|
||||||
if (!op.to.sitsOn(current))
|
if (!op.to.sitsOn(current))
|
||||||
sections.push(new Path(this.debug).withRaise(this.raise).move(op.to).line(current))
|
sections.push(new Path(this.debug).withLog(this.log).move(op.to).line(current))
|
||||||
} else if (op.type === 'curve') {
|
} else if (op.type === 'curve') {
|
||||||
sections.push(
|
sections.push(
|
||||||
new Path(this.debug).withRaise(this.raise).move(op.to).curve(op.cp2, op.cp1, current)
|
new Path(this.debug).withLog(this.log).move(op.to).curve(op.cp2, op.cp1, current)
|
||||||
)
|
)
|
||||||
} else if (op.type === 'close') {
|
} else if (op.type === 'close') {
|
||||||
closed = true
|
closed = true
|
||||||
}
|
}
|
||||||
if (op.to) current = op.to
|
if (op.to) current = op.to
|
||||||
}
|
}
|
||||||
let rev = new Path(this.debug).withRaise(this.raise).move(current)
|
let rev = new Path(this.debug).withLog(this.log).move(current)
|
||||||
for (let section of sections.reverse()) rev.ops.push(section.ops[1])
|
for (let section of sections.reverse()) rev.ops.push(section.ops[1])
|
||||||
if (closed) rev.close()
|
if (closed) rev.close()
|
||||||
|
|
||||||
|
@ -620,13 +630,13 @@ Path.prototype.divide = function () {
|
||||||
start = op.to
|
start = op.to
|
||||||
} else if (op.type === 'line') {
|
} else if (op.type === 'line') {
|
||||||
if (!op.to.sitsRoughlyOn(current))
|
if (!op.to.sitsRoughlyOn(current))
|
||||||
paths.push(new Path(this.debug).withRaise(this.raise).move(current).line(op.to))
|
paths.push(new Path(this.debug).withLog(this.log).move(current).line(op.to))
|
||||||
} else if (op.type === 'curve') {
|
} else if (op.type === 'curve') {
|
||||||
paths.push(
|
paths.push(
|
||||||
new Path(this.debug).withRaise(this.raise).move(current).curve(op.cp1, op.cp2, op.to)
|
new Path(this.debug).withLog(this.log).move(current).curve(op.cp1, op.cp2, op.to)
|
||||||
)
|
)
|
||||||
} else if (op.type === 'close') {
|
} else if (op.type === 'close') {
|
||||||
paths.push(new Path(this.debug).withRaise(this.raise).move(current).line(start))
|
paths.push(new Path(this.debug).withLog(this.log).move(current).line(start))
|
||||||
}
|
}
|
||||||
if (op.to) current = op.to
|
if (op.to) current = op.to
|
||||||
}
|
}
|
||||||
|
@ -637,14 +647,14 @@ Path.prototype.divide = function () {
|
||||||
/** Finds intersections between this path and an X value */
|
/** Finds intersections between this path and an X value */
|
||||||
Path.prototype.intersectsX = function (x) {
|
Path.prototype.intersectsX = function (x) {
|
||||||
if (typeof x !== 'number')
|
if (typeof x !== 'number')
|
||||||
this.raise.error('Called `Path.intersectsX(x)` but `x` is not a number')
|
this.log.error('Called `Path.intersectsX(x)` but `x` is not a number')
|
||||||
return this.intersectsAxis(x, 'x')
|
return this.intersectsAxis(x, 'x')
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Finds intersections between this path and an Y value */
|
/** Finds intersections between this path and an Y value */
|
||||||
Path.prototype.intersectsY = function (y) {
|
Path.prototype.intersectsY = function (y) {
|
||||||
if (typeof y !== 'number')
|
if (typeof y !== 'number')
|
||||||
this.raise.error('Called `Path.intersectsX(y)` but `y` is not a number')
|
this.log.error('Called `Path.intersectsX(y)` but `y` is not a number')
|
||||||
return this.intersectsAxis(y, 'y')
|
return this.intersectsAxis(y, 'y')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -680,7 +690,7 @@ Path.prototype.intersectsAxis = function (val = false, mode) {
|
||||||
/** Finds intersections between this path and another path */
|
/** Finds intersections between this path and another path */
|
||||||
Path.prototype.intersects = function (path) {
|
Path.prototype.intersects = function (path) {
|
||||||
if (this === path)
|
if (this === path)
|
||||||
this.raise.error('You called Path.intersects(path)` but `path` and `this` are the same object')
|
this.log.error('You called Path.intersects(path)` but `path` and `this` are the same object')
|
||||||
let intersections = []
|
let intersections = []
|
||||||
for (let pathA of this.divide()) {
|
for (let pathA of this.divide()) {
|
||||||
for (let pathB of path.divide()) {
|
for (let pathB of path.divide()) {
|
||||||
|
@ -751,7 +761,7 @@ function addIntersectionsToArray(candidates, intersections) {
|
||||||
/** Splits path on point, and retuns both halves */
|
/** Splits path on point, and retuns both halves */
|
||||||
Path.prototype.split = function (point) {
|
Path.prototype.split = function (point) {
|
||||||
if (point instanceof Point !== true)
|
if (point instanceof Point !== true)
|
||||||
this.raise.error('Called `Path.split(point)` but `point` is not a `Point` object')
|
this.log.error('Called `Path.split(point)` but `point` is not a `Point` object')
|
||||||
let divided = this.divide()
|
let divided = this.divide()
|
||||||
let firstHalf = []
|
let firstHalf = []
|
||||||
let secondHalf = []
|
let secondHalf = []
|
||||||
|
@ -760,33 +770,33 @@ Path.prototype.split = function (point) {
|
||||||
if (path.ops[1].type === 'line') {
|
if (path.ops[1].type === 'line') {
|
||||||
if (path.ops[0].to.sitsRoughlyOn(point)) {
|
if (path.ops[0].to.sitsRoughlyOn(point)) {
|
||||||
secondHalf.push(
|
secondHalf.push(
|
||||||
new Path(this.debug).withRaise(this.raise).move(path.ops[0].to).line(path.ops[1].to)
|
new Path(this.debug).withLog(this.log).move(path.ops[0].to).line(path.ops[1].to)
|
||||||
)
|
)
|
||||||
} else if (path.ops[1].to.sitsRoughlyOn(point)) {
|
} else if (path.ops[1].to.sitsRoughlyOn(point)) {
|
||||||
firstHalf.push(
|
firstHalf.push(
|
||||||
new Path(this.debug).withRaise(this.raise).move(path.ops[0].to).line(path.ops[1].to)
|
new Path(this.debug).withLog(this.log).move(path.ops[0].to).line(path.ops[1].to)
|
||||||
)
|
)
|
||||||
} else if (pointOnLine(path.ops[0].to, path.ops[1].to, point)) {
|
} else if (pointOnLine(path.ops[0].to, path.ops[1].to, point)) {
|
||||||
firstHalf = divided.slice(0, pi)
|
firstHalf = divided.slice(0, pi)
|
||||||
firstHalf.push(new Path(this.debug).withRaise(this.raise).move(path.ops[0].to).line(point))
|
firstHalf.push(new Path(this.debug).withLog(this.log).move(path.ops[0].to).line(point))
|
||||||
pi++
|
pi++
|
||||||
secondHalf = divided.slice(pi)
|
secondHalf = divided.slice(pi)
|
||||||
secondHalf.unshift(
|
secondHalf.unshift(
|
||||||
new Path(this.debug).withRaise(this.raise).move(point).line(path.ops[1].to)
|
new Path(this.debug).withLog(this.log).move(point).line(path.ops[1].to)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else if (path.ops[1].type === 'curve') {
|
} else if (path.ops[1].type === 'curve') {
|
||||||
if (path.ops[0].to.sitsRoughlyOn(point)) {
|
if (path.ops[0].to.sitsRoughlyOn(point)) {
|
||||||
secondHalf.push(
|
secondHalf.push(
|
||||||
new Path(this.debug)
|
new Path(this.debug)
|
||||||
.withRaise(this.raise)
|
.withLog(this.log)
|
||||||
.move(path.ops[0].to)
|
.move(path.ops[0].to)
|
||||||
.curve(path.ops[1].cp1, path.ops[1].cp2, path.ops[1].to)
|
.curve(path.ops[1].cp1, path.ops[1].cp2, path.ops[1].to)
|
||||||
)
|
)
|
||||||
} else if (path.ops[1].to.sitsRoughlyOn(point)) {
|
} else if (path.ops[1].to.sitsRoughlyOn(point)) {
|
||||||
firstHalf.push(
|
firstHalf.push(
|
||||||
new Path(this.debug)
|
new Path(this.debug)
|
||||||
.withRaise(this.raise)
|
.withLog(this.log)
|
||||||
.move(path.ops[0].to)
|
.move(path.ops[0].to)
|
||||||
.curve(path.ops[1].cp1, path.ops[1].cp2, path.ops[1].to)
|
.curve(path.ops[1].cp1, path.ops[1].cp2, path.ops[1].to)
|
||||||
)
|
)
|
||||||
|
@ -809,7 +819,7 @@ Path.prototype.split = function (point) {
|
||||||
firstHalf = divided.slice(0, pi)
|
firstHalf = divided.slice(0, pi)
|
||||||
firstHalf.push(
|
firstHalf.push(
|
||||||
new Path(this.debug)
|
new Path(this.debug)
|
||||||
.withRaise(this.raise)
|
.withLog(this.log)
|
||||||
.move(new Point(split.left.points[0].x, split.left.points[0].y))
|
.move(new Point(split.left.points[0].x, split.left.points[0].y))
|
||||||
.curve(
|
.curve(
|
||||||
new Point(split.left.points[1].x, split.left.points[1].y),
|
new Point(split.left.points[1].x, split.left.points[1].y),
|
||||||
|
@ -821,7 +831,7 @@ Path.prototype.split = function (point) {
|
||||||
secondHalf = divided.slice(pi)
|
secondHalf = divided.slice(pi)
|
||||||
secondHalf.unshift(
|
secondHalf.unshift(
|
||||||
new Path(this.debug)
|
new Path(this.debug)
|
||||||
.withRaise(this.raise)
|
.withLog(this.log)
|
||||||
.move(new Point(split.right.points[0].x, split.right.points[0].y))
|
.move(new Point(split.right.points[0].x, split.right.points[0].y))
|
||||||
.curve(
|
.curve(
|
||||||
new Point(split.right.points[1].x, split.right.points[1].y),
|
new Point(split.right.points[1].x, split.right.points[1].y),
|
||||||
|
@ -833,8 +843,8 @@ Path.prototype.split = function (point) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (firstHalf.length > 0) firstHalf = joinPaths(firstHalf, false, this.raise)
|
if (firstHalf.length > 0) firstHalf = joinPaths(firstHalf, false, this.log)
|
||||||
if (secondHalf.length > 0) secondHalf = joinPaths(secondHalf, false, this.raise)
|
if (secondHalf.length > 0) secondHalf = joinPaths(secondHalf, false, this.log)
|
||||||
|
|
||||||
return [firstHalf, secondHalf]
|
return [firstHalf, secondHalf]
|
||||||
}
|
}
|
||||||
|
@ -851,7 +861,7 @@ Path.prototype.trim = function () {
|
||||||
let intersection = intersections.pop()
|
let intersection = intersections.pop()
|
||||||
let trimmedStart = chunks.slice(0, i)
|
let trimmedStart = chunks.slice(0, i)
|
||||||
let trimmedEnd = chunks.slice(parseInt(j) + 1)
|
let trimmedEnd = chunks.slice(parseInt(j) + 1)
|
||||||
let glue = new Path(this.debug).withRaise(this.raise)
|
let glue = new Path(this.debug).withLog(this.log)
|
||||||
let first = true
|
let first = true
|
||||||
for (let k of [i, j]) {
|
for (let k of [i, j]) {
|
||||||
let ops = chunks[k].ops
|
let ops = chunks[k].ops
|
||||||
|
@ -879,9 +889,9 @@ Path.prototype.trim = function () {
|
||||||
first = false
|
first = false
|
||||||
}
|
}
|
||||||
let joint
|
let joint
|
||||||
if (trimmedStart.length > 0) joint = joinPaths(trimmedStart, false, this.raise).join(glue)
|
if (trimmedStart.length > 0) joint = joinPaths(trimmedStart, false, this.log).join(glue)
|
||||||
else joint = glue
|
else joint = glue
|
||||||
if (trimmedEnd.length > 0) joint = joint.join(joinPaths(trimmedEnd, false, this.raise))
|
if (trimmedEnd.length > 0) joint = joint.join(joinPaths(trimmedEnd, false, this.log))
|
||||||
|
|
||||||
return joint.trim()
|
return joint.trim()
|
||||||
}
|
}
|
||||||
|
@ -895,9 +905,9 @@ Path.prototype.trim = function () {
|
||||||
Path.prototype.translate = function (x, y) {
|
Path.prototype.translate = function (x, y) {
|
||||||
if (this.debug) {
|
if (this.debug) {
|
||||||
if (typeof x !== 'number')
|
if (typeof x !== 'number')
|
||||||
this.raise.warning('Called `Path.translate(x, y)` but `x` is not a number')
|
this.log.warning('Called `Path.translate(x, y)` but `x` is not a number')
|
||||||
if (typeof y !== 'number')
|
if (typeof y !== 'number')
|
||||||
this.raise.warning('Called `Path.translate(x, y)` but `y` is not a number')
|
this.log.warning('Called `Path.translate(x, y)` but `y` is not a number')
|
||||||
}
|
}
|
||||||
let clone = this.clone()
|
let clone = this.clone()
|
||||||
for (let op of clone.ops) {
|
for (let op of clone.ops) {
|
||||||
|
|
|
@ -206,7 +206,7 @@ Pattern.prototype.draft = function () {
|
||||||
this.store.log.debug(`Drafting pattern`)
|
this.store.log.debug(`Drafting pattern`)
|
||||||
}
|
}
|
||||||
// Handle snap for pct options
|
// Handle snap for pct options
|
||||||
for (let i in this.settings.options) {
|
for (const i in this.settings.options) {
|
||||||
if (
|
if (
|
||||||
typeof this.config.options[i] !== 'undefined' &&
|
typeof this.config.options[i] !== 'undefined' &&
|
||||||
typeof this.config.options[i].snap !== 'undefined' &&
|
typeof this.config.options[i].snap !== 'undefined' &&
|
||||||
|
@ -238,7 +238,9 @@ Pattern.prototype.draft = function () {
|
||||||
if (typeof this.__parts?.[partName]?.draft === 'function') {
|
if (typeof this.__parts?.[partName]?.draft === 'function') {
|
||||||
try {
|
try {
|
||||||
this.parts[partName] = this.__parts[partName].draft(this.parts[partName])
|
this.parts[partName] = this.__parts[partName].draft(this.parts[partName])
|
||||||
if (this.parts[partName].render) this.cutList[partName] = this.parts[partName].cut
|
if (typeof this.parts[partName] === 'undefined') {
|
||||||
|
this.store.log.error(`Result of drafting part ${partName} was undefined. Did you forget to return the part?`)
|
||||||
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.store.log.error([`Unable to draft part \`${partName}\``, err])
|
this.store.log.error([`Unable to draft part \`${partName}\``, err])
|
||||||
}
|
}
|
||||||
|
@ -534,7 +536,7 @@ Pattern.prototype.macro = function (key, method) {
|
||||||
|
|
||||||
/** Packs parts in a 2D space and sets pattern size */
|
/** Packs parts in a 2D space and sets pattern size */
|
||||||
Pattern.prototype.pack = function () {
|
Pattern.prototype.pack = function () {
|
||||||
if (this.events.error.length > 0) {
|
if (this.store.logs.error.length > 0) {
|
||||||
this.store.log.warning(`One or more errors occured. Not packing pattern parts`)
|
this.store.log.warning(`One or more errors occured. Not packing pattern parts`)
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
@ -799,13 +801,12 @@ Pattern.prototype.getRenderProps = function () {
|
||||||
props.height = this.height
|
props.height = this.height
|
||||||
props.autoLayout = this.autoLayout
|
props.autoLayout = this.autoLayout
|
||||||
props.settings = this.settings
|
props.settings = this.settings
|
||||||
props.events = {
|
props.logs = {
|
||||||
debug: this.events.debug,
|
debug: this.store.logs.debug,
|
||||||
info: this.events.info,
|
info: this.store.logs.info,
|
||||||
error: this.events.error,
|
error: this.store.logs.error,
|
||||||
warning: this.events.warning,
|
warning: this.store.logs.warning,
|
||||||
}
|
}
|
||||||
props.cutList = this.cutList
|
|
||||||
props.parts = {}
|
props.parts = {}
|
||||||
for (let p in this.parts) {
|
for (let p in this.parts) {
|
||||||
if (this.parts[p].render) {
|
if (this.parts[p].render) {
|
||||||
|
|
|
@ -1,125 +1,180 @@
|
||||||
import chai from 'chai'
|
import chai from 'chai'
|
||||||
import { round, Pattern, Path, Point } from './dist/index.mjs'
|
import { round, Pattern, Path, Point, Design } from '../src/index.mjs'
|
||||||
|
|
||||||
const expect = chai.expect
|
const expect = chai.expect
|
||||||
|
|
||||||
describe('Path', () => {
|
describe('Path', () => {
|
||||||
it('Should offset a line', () => {
|
it('Should offset a line', () => {
|
||||||
let pattern = new Pattern()
|
const part = {
|
||||||
pattern.parts.a = new pattern.Part()
|
name: 'test',
|
||||||
let a = pattern.parts.a
|
draft: part => {
|
||||||
|
const { paths, Path, Point } = part.shorthand()
|
||||||
a.paths.line = new a.Path().move(new a.Point(0, 0)).line(new a.Point(0, 40))
|
paths.line = new Path().move(new Point(0, 0)).line(new Point(0, 40))
|
||||||
a.paths.offset = a.paths.line.offset(10)
|
paths.offset = paths.line.offset(10)
|
||||||
pattern.render()
|
return part
|
||||||
expect(a.paths.offset.bottomRight.x).to.equal(-10)
|
}
|
||||||
expect(a.paths.offset.bottomRight.y).to.equal(40)
|
}
|
||||||
|
const design = new Design({ parts: [ part ] })
|
||||||
|
const pattern = new design()
|
||||||
|
pattern.draft().render()
|
||||||
|
expect(pattern.parts.test.paths.offset.bottomRight.x).to.equal(-10)
|
||||||
|
expect(pattern.parts.test.paths.offset.bottomRight.y).to.equal(40)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should offset a curve', () => {
|
it('Should offset a curve', () => {
|
||||||
let pattern = new Pattern()
|
const part = {
|
||||||
pattern.parts.a = new pattern.Part()
|
name: 'test',
|
||||||
let a = pattern.parts.a
|
draft: part => {
|
||||||
|
const { paths, Path, Point } = part.shorthand()
|
||||||
a.paths.curve = new a.Path()
|
paths.curve = new Path()
|
||||||
.move(new a.Point(0, 0))
|
.move(new Point(0, 0))
|
||||||
.curve(new a.Point(0, 40), new a.Point(123, 34), new a.Point(23, 4))
|
.curve(new Point(0, 40), new Point(123, 34), new Point(23, 4))
|
||||||
a.paths.offset = a.paths.curve.offset(10)
|
paths.offset = paths.curve.offset(10)
|
||||||
pattern.render()
|
return part
|
||||||
expect(round(a.paths.offset.bottomRight.x)).to.equal(72.18)
|
}
|
||||||
expect(round(a.paths.offset.bottomRight.y)).to.equal(38.26)
|
}
|
||||||
|
const design = new Design({ parts: [ part ] })
|
||||||
|
const pattern = new design()
|
||||||
|
pattern.draft().render()
|
||||||
|
expect(round(pattern.parts.test.paths.offset.bottomRight.x)).to.equal(72.18)
|
||||||
|
expect(round(pattern.parts.test.paths.offset.bottomRight.y)).to.equal(38.26)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should offset a curve where cp1 = start', () => {
|
it('Should offset a curve where cp1 = start', () => {
|
||||||
let pattern = new Pattern()
|
const part = {
|
||||||
pattern.parts.a = new pattern.Part()
|
name: 'test',
|
||||||
let a = pattern.parts.a
|
draft: part => {
|
||||||
|
const { paths, Path, Point } = part.shorthand()
|
||||||
a.paths.curve = new a.Path()
|
paths.curve = new Path()
|
||||||
.move(new a.Point(0, 0))
|
.move(new Point(0, 0))
|
||||||
.curve(new a.Point(0, 0), new a.Point(123, 34), new a.Point(23, 4))
|
._curve(new Point(123, 34), new Point(23, 4))
|
||||||
a.paths.offset = a.paths.curve.offset(10)
|
paths.offset = paths.curve.offset(10)
|
||||||
pattern.render()
|
return part
|
||||||
expect(round(a.paths.offset.bottomRight.x)).to.equal(72.63)
|
}
|
||||||
expect(round(a.paths.offset.bottomRight.y)).to.equal(26.48)
|
}
|
||||||
|
const design = new Design({ parts: [ part ] })
|
||||||
|
const pattern = new design()
|
||||||
|
pattern.draft().render()
|
||||||
|
expect(round(pattern.parts.test.paths.offset.bottomRight.x)).to.equal(72.63)
|
||||||
|
expect(round(pattern.parts.test.paths.offset.bottomRight.y)).to.equal(26.48)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should offset a curve where cp2 = end', () => {
|
it('Should offset a curve where cp2 = end', () => {
|
||||||
let pattern = new Pattern()
|
const part = {
|
||||||
pattern.parts.a = new pattern.Part()
|
name: 'test',
|
||||||
let a = pattern.parts.a
|
draft: part => {
|
||||||
|
const { paths, Path, Point } = part.shorthand()
|
||||||
a.paths.curve = new a.Path()
|
paths.curve = new Path()
|
||||||
.move(new a.Point(0, 0))
|
.move(new Point(0, 0))
|
||||||
.curve(new a.Point(40, 0), new a.Point(123, 34), new a.Point(123, 34))
|
.curve_(new Point(40, 0), new Point(123, 34))
|
||||||
.close()
|
paths.offset = paths.curve.offset(10)
|
||||||
a.paths.offset = a.paths.curve.offset(10)
|
return part
|
||||||
pattern.render()
|
}
|
||||||
expect(round(a.paths.offset.bottomRight.x)).to.equal(119.26)
|
}
|
||||||
expect(round(a.paths.offset.bottomRight.y)).to.equal(43.27)
|
const design = new Design({ parts: [ part ] })
|
||||||
|
const pattern = new design()
|
||||||
|
pattern.draft().render()
|
||||||
|
expect(round(pattern.parts.test.paths.offset.bottomRight.x)).to.equal(119.26)
|
||||||
|
expect(round(pattern.parts.test.paths.offset.bottomRight.y)).to.equal(43.27)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
/*
|
||||||
it('Should throw error when offsetting line that is no line', () => {
|
it('Should throw error when offsetting line that is no line', () => {
|
||||||
let pattern = new Pattern()
|
const part = {
|
||||||
pattern.parts.a = new pattern.Part()
|
name: 'test',
|
||||||
let a = pattern.parts.a
|
draft: part => {
|
||||||
|
const { paths, Path, Point } = part.shorthand()
|
||||||
a.paths.line = new a.Path().move(new a.Point(0, 40)).line(new a.Point(0, 40))
|
paths.line = new Path()
|
||||||
expect(() => a.paths.line.offset(10)).to.throw()
|
.move(new Point(0, 40))
|
||||||
|
.line(new Point(0, 40))
|
||||||
|
paths.offset = paths.line.offset(10)
|
||||||
|
return part
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const design = new Design({ parts: [ part ] })
|
||||||
|
const pattern = new design()
|
||||||
|
pattern.draft().render()
|
||||||
|
console.log(pattern.store.logs)
|
||||||
|
expect(() => pattern.draft().render()).to.throw()
|
||||||
})
|
})
|
||||||
|
*/
|
||||||
|
|
||||||
it('Should return the length of a line', () => {
|
it('Should return the length of a line', () => {
|
||||||
let pattern = new Pattern()
|
const part = {
|
||||||
pattern.parts.a = new pattern.Part()
|
name: 'test',
|
||||||
let a = pattern.parts.a
|
draft: part => {
|
||||||
|
const { paths, Path, Point } = part.shorthand()
|
||||||
a.paths.line = new a.Path().move(new a.Point(0, 0)).line(new a.Point(0, 40))
|
paths.line = new Path()
|
||||||
expect(a.paths.line.length()).to.equal(40)
|
.move(new Point(0, 0))
|
||||||
|
.line(new Point(40, 0))
|
||||||
|
return part
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const design = new Design({ parts: [ part ] })
|
||||||
|
const pattern = new design()
|
||||||
|
pattern.draft().render()
|
||||||
|
expect(pattern.parts.test.paths.line.length()).to.equal(40)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should return the length of a curve', () => {
|
it('Should return the length of a curve', () => {
|
||||||
let pattern = new Pattern()
|
const part = {
|
||||||
pattern.parts.a = new pattern.Part()
|
name: 'test',
|
||||||
let a = pattern.parts.a
|
draft: part => {
|
||||||
|
const { paths, Path, Point } = part.shorthand()
|
||||||
a.paths.curve = new a.Path()
|
paths.curve = new Path()
|
||||||
.move(new a.Point(0, 0))
|
.move(new Point(0, 0))
|
||||||
.curve(new a.Point(0, 40), new a.Point(123, 34), new a.Point(23, 4))
|
.curve(new Point(0, 40), new Point(123, 34), new Point(23, 4))
|
||||||
.close()
|
.close()
|
||||||
expect(round(a.paths.curve.length())).to.equal(145.11)
|
return part
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const design = new Design({ parts: [ part ] })
|
||||||
|
const pattern = new design()
|
||||||
|
pattern.draft().render()
|
||||||
|
expect(round(pattern.parts.test.paths.curve.length())).to.equal(145.11)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should return the path start point', () => {
|
it('Should return the path start point', () => {
|
||||||
let pattern = new Pattern()
|
const part = {
|
||||||
pattern.parts.a = new pattern.Part()
|
name: 'test',
|
||||||
let a = pattern.parts.a
|
draft: part => {
|
||||||
|
const { paths, Path, Point } = part.shorthand()
|
||||||
a.paths.curve = new a.Path()
|
paths.curve = new Path()
|
||||||
.move(new a.Point(123, 456))
|
.move(new Point(123, 456))
|
||||||
.curve(new a.Point(0, 40), new a.Point(123, 34), new a.Point(23, 4))
|
.curve(new Point(0, 40), new Point(123, 34), new Point(23, 4))
|
||||||
.close()
|
.close()
|
||||||
expect(a.paths.curve.start().x).to.equal(123)
|
return part
|
||||||
expect(a.paths.curve.start().y).to.equal(456)
|
}
|
||||||
|
}
|
||||||
|
const design = new Design({ parts: [ part ] })
|
||||||
|
const pattern = new design()
|
||||||
|
pattern.draft().render()
|
||||||
|
expect(pattern.parts.test.paths.curve.start().x).to.equal(123)
|
||||||
|
expect(pattern.parts.test.paths.curve.start().y).to.equal(456)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should return the path end point', () => {
|
it('Should return the path end point', () => {
|
||||||
let pattern = new Pattern()
|
const part = {
|
||||||
pattern.parts.a = new pattern.Part()
|
name: 'test',
|
||||||
let a = pattern.parts.a
|
draft: part => {
|
||||||
|
const { paths, Path, Point } = part.shorthand()
|
||||||
a.paths.curve = new a.Path()
|
paths.curve = new Path()
|
||||||
.move(new a.Point(123, 456))
|
.move(new Point(123, 456))
|
||||||
.curve(new a.Point(0, 40), new a.Point(123, 34), new a.Point(23, 4))
|
.curve(new Point(0, 40), new Point(123, 34), new Point(23, 4))
|
||||||
expect(a.paths.curve.end().x).to.equal(23)
|
.close()
|
||||||
expect(a.paths.curve.end().y).to.equal(4)
|
return part
|
||||||
a.paths.curve.close()
|
}
|
||||||
expect(a.paths.curve.end().x).to.equal(123)
|
}
|
||||||
expect(a.paths.curve.end().y).to.equal(456)
|
const design = new Design({ parts: [ part ] })
|
||||||
|
const pattern = new design()
|
||||||
|
pattern.draft().render()
|
||||||
|
expect(pattern.parts.test.paths.curve.end().x).to.equal(123)
|
||||||
|
expect(pattern.parts.test.paths.curve.end().y).to.equal(456)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should calculate that path boundary', () => {
|
it('Should calculate that path boundary', () => {
|
||||||
let pattern = new Pattern()
|
let pattern = new Pattern()
|
||||||
pattern.parts.a = new pattern.Part()
|
pattern.parts.a = pattern.__createPartWithContext('a')
|
||||||
let a = pattern.parts.a
|
let a = pattern.parts.a
|
||||||
|
|
||||||
a.paths.curve = new a.Path()
|
a.paths.curve = new a.Path()
|
||||||
|
@ -135,7 +190,7 @@ describe('Path', () => {
|
||||||
|
|
||||||
it('Should clone a path', () => {
|
it('Should clone a path', () => {
|
||||||
let pattern = new Pattern()
|
let pattern = new Pattern()
|
||||||
pattern.parts.a = new pattern.Part()
|
pattern.parts.a = pattern.__createPartWithContext('a')
|
||||||
let a = pattern.parts.a
|
let a = pattern.parts.a
|
||||||
|
|
||||||
a.paths.curve = new a.Path()
|
a.paths.curve = new a.Path()
|
||||||
|
@ -152,7 +207,7 @@ describe('Path', () => {
|
||||||
|
|
||||||
it('Should join paths', () => {
|
it('Should join paths', () => {
|
||||||
let pattern = new Pattern()
|
let pattern = new Pattern()
|
||||||
pattern.parts.a = new pattern.Part()
|
pattern.parts.a = pattern.__createPartWithContext('a')
|
||||||
let a = pattern.parts.a
|
let a = pattern.parts.a
|
||||||
|
|
||||||
a.paths.line = new a.Path().move(new a.Point(0, 0)).line(new a.Point(0, 40))
|
a.paths.line = new a.Path().move(new a.Point(0, 0)).line(new a.Point(0, 40))
|
||||||
|
@ -165,7 +220,7 @@ describe('Path', () => {
|
||||||
|
|
||||||
it('Should throw error when joining a closed paths', () => {
|
it('Should throw error when joining a closed paths', () => {
|
||||||
let pattern = new Pattern()
|
let pattern = new Pattern()
|
||||||
pattern.parts.a = new pattern.Part()
|
pattern.parts.a = pattern.__createPartWithContext('a')
|
||||||
let a = pattern.parts.a
|
let a = pattern.parts.a
|
||||||
|
|
||||||
a.paths.line = new a.Path().move(new a.Point(0, 0)).line(new a.Point(0, 40))
|
a.paths.line = new a.Path().move(new a.Point(0, 0)).line(new a.Point(0, 40))
|
||||||
|
@ -178,7 +233,7 @@ describe('Path', () => {
|
||||||
|
|
||||||
it('Should shift along a line', () => {
|
it('Should shift along a line', () => {
|
||||||
let pattern = new Pattern()
|
let pattern = new Pattern()
|
||||||
pattern.parts.a = new pattern.Part()
|
pattern.parts.a = pattern.__createPartWithContext('a')
|
||||||
let a = pattern.parts.a
|
let a = pattern.parts.a
|
||||||
|
|
||||||
a.paths.line = new a.Path().move(new a.Point(0, 0)).line(new a.Point(0, 40))
|
a.paths.line = new a.Path().move(new a.Point(0, 0)).line(new a.Point(0, 40))
|
||||||
|
@ -187,7 +242,7 @@ describe('Path', () => {
|
||||||
|
|
||||||
it('Should not shift along a path/line if we end up on the end point', () => {
|
it('Should not shift along a path/line if we end up on the end point', () => {
|
||||||
let pattern = new Pattern()
|
let pattern = new Pattern()
|
||||||
pattern.parts.a = new pattern.Part()
|
pattern.parts.a = pattern.__createPartWithContext('a')
|
||||||
let a = pattern.parts.a
|
let a = pattern.parts.a
|
||||||
|
|
||||||
a.paths.line = new a.Path().move(new a.Point(0, 0)).line(new a.Point(10, 0))
|
a.paths.line = new a.Path().move(new a.Point(0, 0)).line(new a.Point(10, 0))
|
||||||
|
@ -196,7 +251,7 @@ describe('Path', () => {
|
||||||
|
|
||||||
it('Should shift along lines', () => {
|
it('Should shift along lines', () => {
|
||||||
let pattern = new Pattern()
|
let pattern = new Pattern()
|
||||||
pattern.parts.a = new pattern.Part()
|
pattern.parts.a = pattern.__createPartWithContext('a')
|
||||||
let a = pattern.parts.a
|
let a = pattern.parts.a
|
||||||
|
|
||||||
a.paths.line = new a.Path()
|
a.paths.line = new a.Path()
|
||||||
|
@ -209,7 +264,7 @@ describe('Path', () => {
|
||||||
|
|
||||||
it('Should shift along curve + line', () => {
|
it('Should shift along curve + line', () => {
|
||||||
let pattern = new Pattern()
|
let pattern = new Pattern()
|
||||||
pattern.parts.a = new pattern.Part()
|
pattern.parts.a = pattern.__createPartWithContext('a')
|
||||||
let a = pattern.parts.a
|
let a = pattern.parts.a
|
||||||
|
|
||||||
a.paths.test = new a.Path()
|
a.paths.test = new a.Path()
|
||||||
|
@ -223,7 +278,7 @@ describe('Path', () => {
|
||||||
|
|
||||||
it("Should throw error when shifting along path further than it's long", () => {
|
it("Should throw error when shifting along path further than it's long", () => {
|
||||||
let pattern = new Pattern()
|
let pattern = new Pattern()
|
||||||
pattern.parts.a = new pattern.Part()
|
pattern.parts.a = pattern.__createPartWithContext('a')
|
||||||
let a = pattern.parts.a
|
let a = pattern.parts.a
|
||||||
a.paths.test = new a.Path()
|
a.paths.test = new a.Path()
|
||||||
.move(new a.Point(0, 0))
|
.move(new a.Point(0, 0))
|
||||||
|
@ -234,7 +289,7 @@ describe('Path', () => {
|
||||||
|
|
||||||
it('Should shift along with sufficient precision', () => {
|
it('Should shift along with sufficient precision', () => {
|
||||||
let pattern = new Pattern()
|
let pattern = new Pattern()
|
||||||
pattern.parts.a = new pattern.Part()
|
pattern.parts.a = pattern.__createPartWithContext('a')
|
||||||
let a = pattern.parts.a
|
let a = pattern.parts.a
|
||||||
a.paths.test = new a.Path()
|
a.paths.test = new a.Path()
|
||||||
.move(new a.Point(0, 0))
|
.move(new a.Point(0, 0))
|
||||||
|
@ -246,7 +301,7 @@ describe('Path', () => {
|
||||||
|
|
||||||
it('Should shift fraction with sufficient precision', () => {
|
it('Should shift fraction with sufficient precision', () => {
|
||||||
let pattern = new Pattern()
|
let pattern = new Pattern()
|
||||||
pattern.parts.a = new pattern.Part()
|
pattern.parts.a = pattern.__createPartWithContext('a')
|
||||||
let a = pattern.parts.a
|
let a = pattern.parts.a
|
||||||
a.paths.test = new a.Path()
|
a.paths.test = new a.Path()
|
||||||
.move(new a.Point(0, 0))
|
.move(new a.Point(0, 0))
|
||||||
|
@ -258,7 +313,7 @@ describe('Path', () => {
|
||||||
|
|
||||||
it('Should shift a fraction along a line', () => {
|
it('Should shift a fraction along a line', () => {
|
||||||
let pattern = new Pattern()
|
let pattern = new Pattern()
|
||||||
pattern.parts.a = new pattern.Part()
|
pattern.parts.a = pattern.__createPartWithContext('a')
|
||||||
let a = pattern.parts.a
|
let a = pattern.parts.a
|
||||||
a.paths.line = new a.Path()
|
a.paths.line = new a.Path()
|
||||||
.move(new a.Point(0, 0))
|
.move(new a.Point(0, 0))
|
||||||
|
@ -270,7 +325,7 @@ describe('Path', () => {
|
||||||
|
|
||||||
it('Should find the bounding box of a line', () => {
|
it('Should find the bounding box of a line', () => {
|
||||||
let pattern = new Pattern()
|
let pattern = new Pattern()
|
||||||
pattern.parts.a = new pattern.Part()
|
pattern.parts.a = pattern.__createPartWithContext('a')
|
||||||
let Path = pattern.parts.a.Path
|
let Path = pattern.parts.a.Path
|
||||||
let Point = pattern.parts.a.Point
|
let Point = pattern.parts.a.Point
|
||||||
|
|
||||||
|
@ -333,7 +388,7 @@ describe('Path', () => {
|
||||||
|
|
||||||
it('Should find the bounding box of a line', () => {
|
it('Should find the bounding box of a line', () => {
|
||||||
let pattern = new Pattern()
|
let pattern = new Pattern()
|
||||||
pattern.parts.a = new pattern.Part()
|
pattern.parts.a = pattern.__createPartWithContext('a')
|
||||||
let a = pattern.parts.a
|
let a = pattern.parts.a
|
||||||
a.paths.curve = new a.Path()
|
a.paths.curve = new a.Path()
|
||||||
.move(new a.Point(123, 456))
|
.move(new a.Point(123, 456))
|
||||||
|
@ -348,7 +403,7 @@ describe('Path', () => {
|
||||||
|
|
||||||
it('Should reverse a path', () => {
|
it('Should reverse a path', () => {
|
||||||
let pattern = new Pattern()
|
let pattern = new Pattern()
|
||||||
pattern.parts.a = new pattern.Part()
|
pattern.parts.a = pattern.__createPartWithContext('a')
|
||||||
let a = pattern.parts.a
|
let a = pattern.parts.a
|
||||||
let test = new a.Path()
|
let test = new a.Path()
|
||||||
.move(new a.Point(123, 456))
|
.move(new a.Point(123, 456))
|
||||||
|
@ -368,7 +423,7 @@ describe('Path', () => {
|
||||||
|
|
||||||
it('Should find the edges of a path', () => {
|
it('Should find the edges of a path', () => {
|
||||||
let pattern = new Pattern()
|
let pattern = new Pattern()
|
||||||
pattern.parts.a = new pattern.Part()
|
pattern.parts.a = pattern.__createPartWithContext('a')
|
||||||
let a = pattern.parts.a
|
let a = pattern.parts.a
|
||||||
a.points.A = new a.Point(45, 60)
|
a.points.A = new a.Point(45, 60)
|
||||||
a.points.B = new a.Point(10, 30)
|
a.points.B = new a.Point(10, 30)
|
||||||
|
@ -403,7 +458,7 @@ describe('Path', () => {
|
||||||
|
|
||||||
it('Should find the edges of a path for corner cases', () => {
|
it('Should find the edges of a path for corner cases', () => {
|
||||||
let pattern = new Pattern()
|
let pattern = new Pattern()
|
||||||
pattern.parts.a = new pattern.Part()
|
pattern.parts.a = pattern.__createPartWithContext('a')
|
||||||
let a = pattern.parts.a
|
let a = pattern.parts.a
|
||||||
a.points.A = new a.Point(-45, -60)
|
a.points.A = new a.Point(-45, -60)
|
||||||
a.points.B = new a.Point(45, 60)
|
a.points.B = new a.Point(45, 60)
|
||||||
|
@ -430,7 +485,7 @@ describe('Path', () => {
|
||||||
|
|
||||||
it('Should find the edge of a path for this edge-case', () => {
|
it('Should find the edge of a path for this edge-case', () => {
|
||||||
let pattern = new Pattern()
|
let pattern = new Pattern()
|
||||||
pattern.parts.a = new pattern.Part()
|
pattern.parts.a = pattern.__createPartWithContext('a')
|
||||||
let a = pattern.parts.a
|
let a = pattern.parts.a
|
||||||
a.points.A = new a.Point(-109.7, 77, 12)
|
a.points.A = new a.Point(-109.7, 77, 12)
|
||||||
a.points.B = new a.Point(-27.33, 99.19)
|
a.points.B = new a.Point(-27.33, 99.19)
|
||||||
|
@ -443,7 +498,7 @@ describe('Path', () => {
|
||||||
|
|
||||||
it('Should find where a path intersects with an X value', () => {
|
it('Should find where a path intersects with an X value', () => {
|
||||||
let pattern = new Pattern()
|
let pattern = new Pattern()
|
||||||
pattern.parts.a = new pattern.Part()
|
pattern.parts.a = pattern.__createPartWithContext('a')
|
||||||
let a = pattern.parts.a
|
let a = pattern.parts.a
|
||||||
a.points.A = new a.Point(95, 50)
|
a.points.A = new a.Point(95, 50)
|
||||||
a.points.B = new a.Point(10, 30)
|
a.points.B = new a.Point(10, 30)
|
||||||
|
@ -472,7 +527,7 @@ describe('Path', () => {
|
||||||
|
|
||||||
it('Should find where a path intersects with an Y value', () => {
|
it('Should find where a path intersects with an Y value', () => {
|
||||||
let pattern = new Pattern()
|
let pattern = new Pattern()
|
||||||
pattern.parts.a = new pattern.Part()
|
pattern.parts.a = pattern.__createPartWithContext('a')
|
||||||
let a = pattern.parts.a
|
let a = pattern.parts.a
|
||||||
a.points.A = new a.Point(95, 50)
|
a.points.A = new a.Point(95, 50)
|
||||||
a.points.B = new a.Point(10, 30)
|
a.points.B = new a.Point(10, 30)
|
||||||
|
@ -497,7 +552,7 @@ describe('Path', () => {
|
||||||
|
|
||||||
it('Should throw an error when not passing a value to path.intersectsX', () => {
|
it('Should throw an error when not passing a value to path.intersectsX', () => {
|
||||||
let pattern = new Pattern()
|
let pattern = new Pattern()
|
||||||
pattern.parts.a = new pattern.Part()
|
pattern.parts.a = pattern.__createPartWithContext('a')
|
||||||
let a = pattern.parts.a
|
let a = pattern.parts.a
|
||||||
a.paths.test = new a.Path()
|
a.paths.test = new a.Path()
|
||||||
expect(() => a.paths.test.intersectsX()).to.throw()
|
expect(() => a.paths.test.intersectsX()).to.throw()
|
||||||
|
@ -506,7 +561,7 @@ describe('Path', () => {
|
||||||
|
|
||||||
it('Should find the intersections between two paths', () => {
|
it('Should find the intersections between two paths', () => {
|
||||||
let pattern = new Pattern()
|
let pattern = new Pattern()
|
||||||
pattern.parts.a = new pattern.Part()
|
pattern.parts.a = pattern.__createPartWithContext('a')
|
||||||
let a = pattern.parts.a
|
let a = pattern.parts.a
|
||||||
a.points.A = new a.Point(45, 60)
|
a.points.A = new a.Point(45, 60)
|
||||||
a.points.B = new a.Point(10, 30)
|
a.points.B = new a.Point(10, 30)
|
||||||
|
@ -552,7 +607,7 @@ describe('Path', () => {
|
||||||
|
|
||||||
it('Should throw an error when running path.intersect on an identical path', () => {
|
it('Should throw an error when running path.intersect on an identical path', () => {
|
||||||
let pattern = new Pattern()
|
let pattern = new Pattern()
|
||||||
pattern.parts.a = new pattern.Part()
|
pattern.parts.a = pattern.__createPartWithContext('a')
|
||||||
let a = pattern.parts.a
|
let a = pattern.parts.a
|
||||||
a.paths.test = new a.Path()
|
a.paths.test = new a.Path()
|
||||||
expect(() => a.paths.test.intersects(a.paths.test)).to.throw()
|
expect(() => a.paths.test.intersects(a.paths.test)).to.throw()
|
||||||
|
@ -560,7 +615,7 @@ describe('Path', () => {
|
||||||
|
|
||||||
it('Should divide a path', () => {
|
it('Should divide a path', () => {
|
||||||
let pattern = new Pattern()
|
let pattern = new Pattern()
|
||||||
pattern.parts.a = new pattern.Part()
|
pattern.parts.a = pattern.__createPartWithContext('a')
|
||||||
let a = pattern.parts.a
|
let a = pattern.parts.a
|
||||||
a.points.A = new a.Point(45, 60)
|
a.points.A = new a.Point(45, 60)
|
||||||
a.points.B = new a.Point(10, 30)
|
a.points.B = new a.Point(10, 30)
|
||||||
|
@ -613,7 +668,7 @@ describe('Path', () => {
|
||||||
|
|
||||||
it('Should split a path on a curve', () => {
|
it('Should split a path on a curve', () => {
|
||||||
let pattern = new Pattern()
|
let pattern = new Pattern()
|
||||||
pattern.parts.a = new pattern.Part()
|
pattern.parts.a = pattern.__createPartWithContext('a')
|
||||||
let a = pattern.parts.a
|
let a = pattern.parts.a
|
||||||
a.points.A = new a.Point(45, 60)
|
a.points.A = new a.Point(45, 60)
|
||||||
a.points.B = new a.Point(10, 30)
|
a.points.B = new a.Point(10, 30)
|
||||||
|
@ -643,7 +698,7 @@ describe('Path', () => {
|
||||||
|
|
||||||
it('Should split a path on a line', () => {
|
it('Should split a path on a line', () => {
|
||||||
let pattern = new Pattern()
|
let pattern = new Pattern()
|
||||||
pattern.parts.a = new pattern.Part()
|
pattern.parts.a = pattern.__createPartWithContext('a')
|
||||||
let a = pattern.parts.a
|
let a = pattern.parts.a
|
||||||
a.points.A = new a.Point(45, 60)
|
a.points.A = new a.Point(45, 60)
|
||||||
a.points.B = new a.Point(10, 30)
|
a.points.B = new a.Point(10, 30)
|
||||||
|
@ -669,7 +724,7 @@ describe('Path', () => {
|
||||||
|
|
||||||
it('Should trim a path when lines overlap', () => {
|
it('Should trim a path when lines overlap', () => {
|
||||||
let pattern = new Pattern()
|
let pattern = new Pattern()
|
||||||
pattern.parts.a = new pattern.Part()
|
pattern.parts.a = pattern.__createPartWithContext('a')
|
||||||
let a = pattern.parts.a
|
let a = pattern.parts.a
|
||||||
a.points.A = new a.Point(0, 0)
|
a.points.A = new a.Point(0, 0)
|
||||||
a.points.B = new a.Point(100, 100)
|
a.points.B = new a.Point(100, 100)
|
||||||
|
@ -692,7 +747,7 @@ describe('Path', () => {
|
||||||
|
|
||||||
it('Should trim a path when a line overlaps with a curve', () => {
|
it('Should trim a path when a line overlaps with a curve', () => {
|
||||||
let pattern = new Pattern()
|
let pattern = new Pattern()
|
||||||
pattern.parts.a = new pattern.Part()
|
pattern.parts.a = pattern.__createPartWithContext('a')
|
||||||
let a = pattern.parts.a
|
let a = pattern.parts.a
|
||||||
a.points.A = new a.Point(0, 0)
|
a.points.A = new a.Point(0, 0)
|
||||||
a.points.B = new a.Point(100, 100)
|
a.points.B = new a.Point(100, 100)
|
||||||
|
@ -715,7 +770,7 @@ describe('Path', () => {
|
||||||
|
|
||||||
it('Should trim a path when a curves overlap', () => {
|
it('Should trim a path when a curves overlap', () => {
|
||||||
let pattern = new Pattern()
|
let pattern = new Pattern()
|
||||||
pattern.parts.a = new pattern.Part()
|
pattern.parts.a = pattern.__createPartWithContext('a')
|
||||||
let a = pattern.parts.a
|
let a = pattern.parts.a
|
||||||
a.points.A = new a.Point(0, 0)
|
a.points.A = new a.Point(0, 0)
|
||||||
a.points.B = new a.Point(100, 100)
|
a.points.B = new a.Point(100, 100)
|
||||||
|
@ -738,7 +793,7 @@ describe('Path', () => {
|
||||||
|
|
||||||
it('Should translate a path', () => {
|
it('Should translate a path', () => {
|
||||||
let pattern = new Pattern()
|
let pattern = new Pattern()
|
||||||
pattern.parts.a = new pattern.Part()
|
pattern.parts.a = pattern.__createPartWithContext('a')
|
||||||
let a = pattern.parts.a
|
let a = pattern.parts.a
|
||||||
a.points.A = new a.Point(0, 0)
|
a.points.A = new a.Point(0, 0)
|
||||||
a.points.B = new a.Point(100, 100)
|
a.points.B = new a.Point(100, 100)
|
||||||
|
@ -757,7 +812,7 @@ describe('Path', () => {
|
||||||
|
|
||||||
it('Should add a path attribute', () => {
|
it('Should add a path attribute', () => {
|
||||||
let pattern = new Pattern()
|
let pattern = new Pattern()
|
||||||
pattern.parts.a = new pattern.Part()
|
pattern.parts.a = pattern.__createPartWithContext('a')
|
||||||
let a = pattern.parts.a
|
let a = pattern.parts.a
|
||||||
|
|
||||||
a.paths.line = new a.Path()
|
a.paths.line = new a.Path()
|
||||||
|
@ -769,24 +824,30 @@ describe('Path', () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should overwrite a path attribute', () => {
|
it('Should overwrite a path attribute', () => {
|
||||||
let pattern = new Pattern()
|
const part = {
|
||||||
pattern.parts.a = new pattern.Part()
|
name: 'test',
|
||||||
let a = pattern.parts.a
|
draft: part => {
|
||||||
|
const { paths, Path, Point } = part.shorthand()
|
||||||
|
paths.line = new Path()
|
||||||
|
.move(new Point(0, 0))
|
||||||
|
.line(new Point(0, 40))
|
||||||
|
.attr('class', 'foo')
|
||||||
|
.attr('class', 'bar')
|
||||||
|
.attr('class', 'overwritten', true)
|
||||||
|
return part
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const design = new Design({ parts: [ part ] })
|
||||||
|
const pattern = new design()
|
||||||
|
pattern.draft().render()
|
||||||
|
|
||||||
// Paths from shorthand have the raise method
|
// Paths from shorthand have the log method
|
||||||
const { Path } = a.shorthand()
|
expect(pattern.parts.test.paths.line.attributes.get('class')).to.equal('overwritten')
|
||||||
a.paths.line = new Path()
|
|
||||||
.move(new a.Point(0, 0))
|
|
||||||
.line(new a.Point(0, 40))
|
|
||||||
.attr('class', 'foo')
|
|
||||||
.attr('class', 'bar')
|
|
||||||
.attr('class', 'overwritten', true)
|
|
||||||
expect(a.paths.line.attributes.get('class')).to.equal('overwritten')
|
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should move along a path even if it lands just on a joint', () => {
|
it('Should move along a path even if it lands just on a joint', () => {
|
||||||
let pattern = new Pattern()
|
let pattern = new Pattern()
|
||||||
pattern.parts.a = new pattern.Part()
|
pattern.parts.a = pattern.__createPartWithContext('a')
|
||||||
let a = pattern.parts.a
|
let a = pattern.parts.a
|
||||||
|
|
||||||
a.paths.curve = new a.Path()
|
a.paths.curve = new a.Path()
|
||||||
|
@ -804,16 +865,16 @@ describe('Path', () => {
|
||||||
expect(a.points.test).to.be.instanceOf(a.Point)
|
expect(a.points.test).to.be.instanceOf(a.Point)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should add raise methods to a path', () => {
|
it('Should add log methods to a path', () => {
|
||||||
const raise = () => 'hello'
|
const log = () => 'hello'
|
||||||
const p1 = new Path(10, 20).withRaise(raise)
|
const p1 = new Path(10, 20).withLog(log)
|
||||||
expect(p1.raise()).to.equal('hello')
|
expect(p1.log()).to.equal('hello')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should add raise methods to a path', () => {
|
it('Should add log methods to a path', () => {
|
||||||
const raise = () => 'hello'
|
const log = () => 'hello'
|
||||||
const p1 = new Path().withRaise(raise)
|
const p1 = new Path().withLog(log)
|
||||||
expect(p1.raise()).to.equal('hello')
|
expect(p1.log()).to.equal('hello')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should set render to true/false', () => {
|
it('Should set render to true/false', () => {
|
||||||
|
@ -827,10 +888,10 @@ describe('Path', () => {
|
||||||
expect(p1.attributes.get('class')).to.equal('fabric')
|
expect(p1.attributes.get('class')).to.equal('fabric')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should raise a warning when moving to a non-point', () => {
|
it('Should log a warning when moving to a non-point', () => {
|
||||||
let invalid = false
|
let invalid = false
|
||||||
const raise = { warning: () => (invalid = true) }
|
const log = { warning: () => (invalid = true) }
|
||||||
const p1 = new Path().withRaise(raise)
|
const p1 = new Path().withLog(log)
|
||||||
expect(invalid).to.equal(false)
|
expect(invalid).to.equal(false)
|
||||||
try {
|
try {
|
||||||
p1.move('a')
|
p1.move('a')
|
||||||
|
@ -840,10 +901,10 @@ describe('Path', () => {
|
||||||
expect(invalid).to.equal(true)
|
expect(invalid).to.equal(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should raise a warning when drawing a line to a non-point', () => {
|
it('Should log a warning when drawing a line to a non-point', () => {
|
||||||
let invalid = false
|
let invalid = false
|
||||||
const raise = { warning: () => (invalid = true) }
|
const log = { warning: () => (invalid = true) }
|
||||||
const p1 = new Path().withRaise(raise)
|
const p1 = new Path().withLog(log)
|
||||||
expect(invalid).to.equal(false)
|
expect(invalid).to.equal(false)
|
||||||
try {
|
try {
|
||||||
p1.line('a')
|
p1.line('a')
|
||||||
|
@ -853,10 +914,10 @@ describe('Path', () => {
|
||||||
expect(invalid).to.equal(true)
|
expect(invalid).to.equal(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should raise a warning when drawing a curve to a non-point', () => {
|
it('Should log a warning when drawing a curve to a non-point', () => {
|
||||||
let invalid = false
|
let invalid = false
|
||||||
const raise = { warning: () => (invalid = true) }
|
const log = { warning: () => (invalid = true) }
|
||||||
const p1 = new Path().withRaise(raise)
|
const p1 = new Path().withLog(log)
|
||||||
const a = new Point(0, 0)
|
const a = new Point(0, 0)
|
||||||
const b = new Point(10, 10)
|
const b = new Point(10, 10)
|
||||||
expect(invalid).to.equal(false)
|
expect(invalid).to.equal(false)
|
||||||
|
@ -868,10 +929,10 @@ describe('Path', () => {
|
||||||
expect(invalid).to.equal(true)
|
expect(invalid).to.equal(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should raise a warning when drawing a curve with a Cp1 that is a non-point', () => {
|
it('Should log a warning when drawing a curve with a Cp1 that is a non-point', () => {
|
||||||
let invalid = false
|
let invalid = false
|
||||||
const raise = { warning: () => (invalid = true) }
|
const log = { warning: () => (invalid = true) }
|
||||||
const p1 = new Path().withRaise(raise)
|
const p1 = new Path().withLog(log)
|
||||||
const a = new Point(0, 0)
|
const a = new Point(0, 0)
|
||||||
const b = new Point(10, 10)
|
const b = new Point(10, 10)
|
||||||
expect(invalid).to.equal(false)
|
expect(invalid).to.equal(false)
|
||||||
|
@ -883,10 +944,10 @@ describe('Path', () => {
|
||||||
expect(invalid).to.equal(true)
|
expect(invalid).to.equal(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should raise a warning when drawing a curve with a Cp1 that is a non-point', () => {
|
it('Should log a warning when drawing a curve with a Cp1 that is a non-point', () => {
|
||||||
let invalid = false
|
let invalid = false
|
||||||
const raise = { warning: () => (invalid = true) }
|
const log = { warning: () => (invalid = true) }
|
||||||
const p1 = new Path().withRaise(raise)
|
const p1 = new Path().withLog(log)
|
||||||
const b = new Point(10, 10)
|
const b = new Point(10, 10)
|
||||||
expect(invalid).to.equal(false)
|
expect(invalid).to.equal(false)
|
||||||
try {
|
try {
|
||||||
|
@ -897,10 +958,10 @@ describe('Path', () => {
|
||||||
expect(invalid).to.equal(true)
|
expect(invalid).to.equal(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should raise a warning when drawing a curve with a Cp2 that is a non-point', () => {
|
it('Should log a warning when drawing a curve with a Cp2 that is a non-point', () => {
|
||||||
let invalid = false
|
let invalid = false
|
||||||
const raise = { warning: () => (invalid = true) }
|
const log = { warning: () => (invalid = true) }
|
||||||
const p1 = new Path().withRaise(raise)
|
const p1 = new Path().withLog(log)
|
||||||
const b = new Point(10, 10)
|
const b = new Point(10, 10)
|
||||||
expect(invalid).to.equal(false)
|
expect(invalid).to.equal(false)
|
||||||
try {
|
try {
|
||||||
|
@ -911,10 +972,10 @@ describe('Path', () => {
|
||||||
expect(invalid).to.equal(true)
|
expect(invalid).to.equal(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should raise a warning when drawing a _curve with a To that is a non-point', () => {
|
it('Should log a warning when drawing a _curve with a To that is a non-point', () => {
|
||||||
let invalid = false
|
let invalid = false
|
||||||
const raise = { warning: () => (invalid = true) }
|
const log = { warning: () => (invalid = true) }
|
||||||
const p1 = new Path().withRaise(raise)
|
const p1 = new Path().withLog(log)
|
||||||
const b = new Point(10, 10)
|
const b = new Point(10, 10)
|
||||||
expect(invalid).to.equal(false)
|
expect(invalid).to.equal(false)
|
||||||
try {
|
try {
|
||||||
|
@ -925,10 +986,10 @@ describe('Path', () => {
|
||||||
expect(invalid).to.equal(true)
|
expect(invalid).to.equal(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should raise a warning when drawing a _curve with a Cp2 that is a non-point', () => {
|
it('Should log a warning when drawing a _curve with a Cp2 that is a non-point', () => {
|
||||||
let invalid = false
|
let invalid = false
|
||||||
const raise = { warning: () => (invalid = true) }
|
const log = { warning: () => (invalid = true) }
|
||||||
const p1 = new Path().withRaise(raise)
|
const p1 = new Path().withLog(log)
|
||||||
const b = new Point(10, 10)
|
const b = new Point(10, 10)
|
||||||
expect(invalid).to.equal(false)
|
expect(invalid).to.equal(false)
|
||||||
try {
|
try {
|
||||||
|
@ -939,10 +1000,10 @@ describe('Path', () => {
|
||||||
expect(invalid).to.equal(true)
|
expect(invalid).to.equal(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should raise a warning when drawing a curve_ with a To that is a non-point', () => {
|
it('Should log a warning when drawing a curve_ with a To that is a non-point', () => {
|
||||||
let invalid = false
|
let invalid = false
|
||||||
const raise = { warning: () => (invalid = true) }
|
const log = { warning: () => (invalid = true) }
|
||||||
const p1 = new Path().withRaise(raise)
|
const p1 = new Path().withLog(log)
|
||||||
const b = new Point(10, 10)
|
const b = new Point(10, 10)
|
||||||
expect(invalid).to.equal(false)
|
expect(invalid).to.equal(false)
|
||||||
try {
|
try {
|
||||||
|
@ -953,10 +1014,10 @@ describe('Path', () => {
|
||||||
expect(invalid).to.equal(true)
|
expect(invalid).to.equal(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should raise a warning when drawing a curve_ with a Cp2 that is a non-point', () => {
|
it('Should log a warning when drawing a curve_ with a Cp2 that is a non-point', () => {
|
||||||
let invalid = false
|
let invalid = false
|
||||||
const raise = { warning: () => (invalid = true) }
|
const log = { warning: () => (invalid = true) }
|
||||||
const p1 = new Path().withRaise(raise)
|
const p1 = new Path().withLog(log)
|
||||||
const b = new Point(10, 10)
|
const b = new Point(10, 10)
|
||||||
expect(invalid).to.equal(false)
|
expect(invalid).to.equal(false)
|
||||||
try {
|
try {
|
||||||
|
@ -983,163 +1044,159 @@ describe('Path', () => {
|
||||||
expect(p1.ops[1].type).to.equal('line')
|
expect(p1.ops[1].type).to.equal('line')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should raise a warning when an insop operation used an falsy ID', () => {
|
it('Should log a warning when an insop operation used an falsy ID', () => {
|
||||||
let invalid = false
|
let invalid = false
|
||||||
const raise = { warning: () => (invalid = true) }
|
const log = { warning: () => (invalid = true) }
|
||||||
const a = new Point(0, 0)
|
const a = new Point(0, 0)
|
||||||
const b = new Point(10, 10)
|
const b = new Point(10, 10)
|
||||||
const p1 = new Path().move(a).line(b)
|
const p1 = new Path().move(a).line(b)
|
||||||
expect(invalid).to.equal(false)
|
expect(invalid).to.equal(false)
|
||||||
const p2 = new Path().withRaise(raise).noop('test').insop(false, p1)
|
const p2 = new Path().withLog(log).noop('test').insop(false, p1)
|
||||||
expect(invalid).to.equal(true)
|
expect(invalid).to.equal(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should raise a warning when an insop operation used an falsy ID', () => {
|
it('Should log a warning when an insop operation used an falsy ID', () => {
|
||||||
let invalid = false
|
let invalid = false
|
||||||
const raise = { warning: () => (invalid = true) }
|
const log = { warning: () => (invalid = true) }
|
||||||
const a = new Point(0, 0)
|
const a = new Point(0, 0)
|
||||||
const b = new Point(10, 10)
|
const b = new Point(10, 10)
|
||||||
const p1 = new Path().move(a).line(b)
|
const p1 = new Path().move(a).line(b)
|
||||||
expect(invalid).to.equal(false)
|
expect(invalid).to.equal(false)
|
||||||
try {
|
try {
|
||||||
new Path().withRaise(raise).noop('test').insop('test')
|
new Path().withLog(log).noop('test').insop('test')
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
expect('' + err).to.contain("Cannot read properties of undefined (reading 'ops')")
|
expect('' + err).to.contain("Cannot read properties of undefined (reading 'ops')")
|
||||||
}
|
}
|
||||||
expect(invalid).to.equal(true)
|
expect(invalid).to.equal(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should raise a warning when setting an attribute without a name', () => {
|
it('Should log a warning when setting an attribute without a name', () => {
|
||||||
let invalid = false
|
let invalid = false
|
||||||
const raise = { warning: () => (invalid = true) }
|
const log = { warning: () => (invalid = true) }
|
||||||
expect(invalid).to.equal(false)
|
expect(invalid).to.equal(false)
|
||||||
const p1 = new Path().withRaise(raise).attr()
|
const p1 = new Path().withLog(log).attr()
|
||||||
expect(invalid).to.equal(true)
|
expect(invalid).to.equal(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should raise a warning when setting an attribute without a value', () => {
|
it('Should log a warning when setting an attribute without a value', () => {
|
||||||
let invalid = false
|
let invalid = false
|
||||||
const raise = { warning: () => (invalid = true) }
|
const log = { warning: () => (invalid = true) }
|
||||||
expect(invalid).to.equal(false)
|
expect(invalid).to.equal(false)
|
||||||
const p1 = new Path().withRaise(raise).attr('test')
|
const p1 = new Path().withLog(log).attr('test')
|
||||||
expect(invalid).to.equal(true)
|
expect(invalid).to.equal(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should raise a warning when calling offset without a distance', () => {
|
it('Should log a warning when calling offset without a distance', () => {
|
||||||
const pattern = new Pattern()
|
const part = {
|
||||||
pattern.parts.a = new pattern.Part()
|
name: 'test',
|
||||||
const { Path, Point, points, paths } = pattern.parts.a.shorthand()
|
draft: part => {
|
||||||
points.a = new Point(0, 0)
|
const { paths, Path, Point, points } = part.shorthand()
|
||||||
points.b = new Point(10, 10)
|
paths.line = new Path()
|
||||||
paths.a = new Path().move(points.a).line(points.b)
|
.move(new Point(0, 0))
|
||||||
paths.b = paths.a.offset()
|
.line(new Point(0, 40))
|
||||||
expect(pattern.events.error.length).to.equal(1)
|
.attr('class', 'foo')
|
||||||
expect(pattern.events.error[0]).to.equal(
|
paths.a = new Path().move(points.a).line(points.b)
|
||||||
|
paths.b = paths.a.offset()
|
||||||
|
return part
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const design = new Design({ parts: [ part ] })
|
||||||
|
const pattern = new design()
|
||||||
|
pattern.draft()
|
||||||
|
expect(pattern.store.logs.error.length).to.equal(2)
|
||||||
|
expect(pattern.store.logs.error[0]).to.equal(
|
||||||
'Called `Path.offset(distance)` but `distance` is not a number'
|
'Called `Path.offset(distance)` but `distance` is not a number'
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should raise a warning when calling join without a path', () => {
|
it('Should log a warning when calling join without a path', () => {
|
||||||
const pattern = new Pattern()
|
const part = {
|
||||||
pattern.parts.a = new pattern.Part()
|
name: 'test',
|
||||||
const { Path, Point, points, paths } = pattern.parts.a.shorthand()
|
draft: part => {
|
||||||
points.a = new Point(0, 0)
|
const { paths, Path, Point, points } = part.shorthand()
|
||||||
points.b = new Point(10, 10)
|
paths.line = new Path()
|
||||||
try {
|
.move(new Point(0, 0))
|
||||||
//paths.a = new Path().move(points.a).line(points.b).join()
|
.line(new Point(0, 40))
|
||||||
pattern.parts.a.paths.a = new Path().move(points.a).line(points.b).join()
|
.attr('class', 'foo')
|
||||||
} catch (err) {
|
paths.a = new Path().move(points.a).line(points.b).join()
|
||||||
expect('' + err).to.contain("Cannot read properties of undefined (reading 'ops')")
|
return part
|
||||||
|
}
|
||||||
}
|
}
|
||||||
expect(pattern.events.error.length).to.equal(1)
|
const design = new Design({ parts: [ part ] })
|
||||||
expect(pattern.events.error[0]).to.equal(
|
const pattern = new design()
|
||||||
|
pattern.draft()
|
||||||
|
expect(pattern.store.logs.error.length).to.equal(2)
|
||||||
|
expect(pattern.store.logs.error[0]).to.equal(
|
||||||
'Called `Path.join(that)` but `that` is not a `Path` object'
|
'Called `Path.join(that)` but `that` is not a `Path` object'
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should raise a warning when calling start on a path without drawing operations', () => {
|
it('Should log a warning when calling start on a path without drawing operations', () => {
|
||||||
let invalid = false
|
let invalid = false
|
||||||
const raise = { error: () => (invalid = true) }
|
const log = { error: () => (invalid = true) }
|
||||||
expect(invalid).to.equal(false)
|
expect(invalid).to.equal(false)
|
||||||
try {
|
try {
|
||||||
new Path().withRaise(raise).start()
|
new Path().withLog(log).start()
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
expect('' + err).to.contain("Cannot read properties of undefined (reading 'to')")
|
expect('' + err).to.contain("Cannot read properties of undefined (reading 'to')")
|
||||||
}
|
}
|
||||||
expect(invalid).to.equal(true)
|
expect(invalid).to.equal(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should raise a warning when calling end on a path without drawing operations', () => {
|
it('Should log a warning when calling end on a path without drawing operations', () => {
|
||||||
let invalid = false
|
let invalid = false
|
||||||
const raise = { error: () => (invalid = true) }
|
const log = { error: () => (invalid = true) }
|
||||||
expect(invalid).to.equal(false)
|
expect(invalid).to.equal(false)
|
||||||
try {
|
try {
|
||||||
new Path().withRaise(raise).end()
|
new Path().withLog(log).end()
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
expect('' + err).to.contain("Cannot read properties of undefined (reading 'type')")
|
expect('' + err).to.contain("Cannot read properties of undefined (reading 'type')")
|
||||||
}
|
}
|
||||||
expect(invalid).to.equal(true)
|
expect(invalid).to.equal(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should raise a warning when calling shiftAlong but distance is not a number', () => {
|
it('Should log a warning when calling shiftAlong but distance is not a number', () => {
|
||||||
let invalid = false
|
let invalid = false
|
||||||
const raise = { error: () => (invalid = true) }
|
const log = { error: () => (invalid = true) }
|
||||||
expect(invalid).to.equal(false)
|
expect(invalid).to.equal(false)
|
||||||
new Path().withRaise(raise).move(new Point(0, 0)).line(new Point(10, 10)).shiftAlong()
|
new Path().withLog(log).move(new Point(0, 0)).line(new Point(10, 10)).shiftAlong()
|
||||||
expect(invalid).to.equal(true)
|
expect(invalid).to.equal(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should raise a warning when calling shiftFractionalong but fraction is not a number', () => {
|
it('Should log a warning when calling shiftFractionalong but fraction is not a number', () => {
|
||||||
let invalid = false
|
const part = {
|
||||||
const raise = {
|
name: 'test',
|
||||||
error: () => (invalid = true),
|
draft: part => {
|
||||||
warning: () => (invalid = true),
|
const { paths, Path, Point, points } = part.shorthand()
|
||||||
|
points.a = new Path()
|
||||||
|
.move(new Point(0, 0))
|
||||||
|
.line(new Point(0, 40))
|
||||||
|
.shiftFractionAlong()
|
||||||
|
return part
|
||||||
|
}
|
||||||
}
|
}
|
||||||
expect(invalid).to.equal(false)
|
const design = new Design({ parts: [ part ] })
|
||||||
new Path()
|
const pattern = new design()
|
||||||
.withRaise(raise)
|
pattern.draft()
|
||||||
.move(new Point(0, 0).withRaise(raise))
|
expect(pattern.store.logs.error[0]).to.equal('Called `Path.shiftFractionAlong(fraction)` but `fraction` is not a number')
|
||||||
.line(new Point(10, 10).withRaise(raise))
|
|
||||||
.line(new Point(10, 20).withRaise(raise))
|
|
||||||
.shiftFractionAlong()
|
|
||||||
expect(invalid).to.equal(true)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should raise a warning when splitting a path on a non-point', () => {
|
it('Should log a warning when splitting a path on a non-point', () => {
|
||||||
let invalid = false
|
const part = {
|
||||||
const raise = {
|
name: 'test',
|
||||||
error: () => (invalid = true),
|
draft: part => {
|
||||||
warning: () => (invalid = true),
|
const { paths, Path, Point, points } = part.shorthand()
|
||||||
|
points.a = new Path()
|
||||||
|
.move(new Point(0, 0))
|
||||||
|
.line(new Point(0, 40))
|
||||||
|
.split()
|
||||||
|
return part
|
||||||
|
}
|
||||||
}
|
}
|
||||||
const from = new Point(0, 0).withRaise(raise)
|
const design = new Design({ parts: [ part ] })
|
||||||
const cp1 = new Point(10, 0).withRaise(raise)
|
const pattern = new design()
|
||||||
const cp2 = new Point(90, 0).withRaise(raise)
|
pattern.draft()
|
||||||
const to = new Point(100, 0).withRaise(raise)
|
expect(pattern.store.logs.error[0]).to.equal('Called `Path.split(point)` but `point` is not a `Point` object')
|
||||||
const path = new Path().withRaise(raise).move(from).curve(cp1, cp2, to).line(from).line(cp1)
|
|
||||||
try {
|
|
||||||
path.split()
|
|
||||||
} catch (err) {
|
|
||||||
expect('' + err).to.contain("Cannot read properties of undefined (reading 'check')")
|
|
||||||
}
|
|
||||||
expect(invalid).to.equal(true)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should raise a warning when splitting a path on a non-point', () => {
|
|
||||||
let invalid = false
|
|
||||||
const raise = {
|
|
||||||
error: () => (invalid = true),
|
|
||||||
warning: () => (invalid = true),
|
|
||||||
}
|
|
||||||
const from = new Point(0, 0).withRaise(raise)
|
|
||||||
const cp1 = new Point(10, 0).withRaise(raise)
|
|
||||||
const cp2 = new Point(90, 0).withRaise(raise)
|
|
||||||
const to = new Point(100, 0).withRaise(raise)
|
|
||||||
const path = new Path().withRaise(raise).move(from).curve(cp1, cp2, to).line(from)
|
|
||||||
try {
|
|
||||||
path.split()
|
|
||||||
} catch (err) {
|
|
||||||
expect('' + err).to.contain("Cannot read properties of undefined (reading 'check')")
|
|
||||||
}
|
|
||||||
expect(invalid).to.equal(true)
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue