diff --git a/src/path/Curve.js b/src/path/Curve.js index b887d0ad..a5ac86cd 100644 --- a/src/path/Curve.js +++ b/src/path/Curve.js @@ -436,15 +436,16 @@ var Curve = Base.extend(/** @lends Curve# */{ // TODO: adjustThroughPoint /** - * Divides the curve into two curves at the given offset. The curve itself - * is modified and becomes the first part, the second part is returned as a - * new curve. If the modified curve belongs to a path item, the second part - * is also added to the path. + * Divides the curve into two curves at the given offset or location. The + * curve itself is modified and becomes the first part, the second part is + * returned as a new curve. If the curve belongs to a path item, a new + * segment is inserted into the path at the given location, and the second + * part becomes a part of the path as well. * * @param {Number|CurveLocation} location the offset or location on the * curve at which to divide - * @return {Curve} the second part of the divided curve, if the offset is - * within the valid range, {code null} otherwise. + * @return {Curve} the second part of the divided curve if the location is + * valid, {code null} otherwise * @see #divideAtTime(time) */ divideAt: function(location) { diff --git a/src/path/Path.js b/src/path/Path.js index 50573e4d..b9268cd6 100644 --- a/src/path/Path.js +++ b/src/path/Path.js @@ -962,6 +962,27 @@ var Path = PathItem.extend(/** @lends Path# */{ this.setSelected(true); }, + /** + * Divides the path on the curve at the given offset or location into two + * curves, by inserting a new segment at the given location. + * + * @param {Number|CurveLocation} location the offset or location on the + * path at which to divide the existing curve by inserting a new segment + * @return {Segment} the newly inserted segment if the location is valid, + * {code null} otherwise + * @see Curve#divideAt(location) + */ + divideAt: function(location) { + var loc = this.getLocationAt(location); + ret = null; + if (loc) { + var curve = loc.getCurve().divideAt(loc.getCurveOffset()); + if (curve) + ret = curve._segment1; + } + return ret; + }, + /** * Splits the path at the given offset or location. After splitting, the * path will be open. If the path was open already, splitting will result in @@ -1019,8 +1040,8 @@ var Path = PathItem.extend(/** @lends Path# */{ * path.firstSegment.selected = true; */ splitAt: function(location) { - var loc = typeof location === 'number' - ? this.getLocationAt(location) : location, + // NOTE: getLocationAt() handles both offset and location: + var loc = this.getLocationAt(location), index = loc && loc.index, time = loc && loc.time, tMin = /*#=*/Numerical.CURVETIME_EPSILON, @@ -1855,21 +1876,27 @@ var Path = PathItem.extend(/** @lends Path# */{ * @return {CurveLocation} the curve location at the specified offset */ getLocationAt: function(offset) { - var curves = this.getCurves(), - length = 0; - for (var i = 0, l = curves.length; i < l; i++) { - var start = length, - curve = curves[i]; - length += curve.getLength(); - if (length > offset) { - // Found the segment within which the length lies - return curve.getLocationAt(offset - start); + if (typeof offset === 'number') { + var curves = this.getCurves(), + length = 0; + for (var i = 0, l = curves.length; i < l; i++) { + var start = length, + curve = curves[i]; + length += curve.getLength(); + if (length > offset) { + // Found the segment within which the length lies + return curve.getLocationAt(offset - start); + } } + // It may be that through imprecision of getLength, that the end of + // the last curve was missed: + if (curves.length > 0 && offset <= this.getLength()) { + return new CurveLocation(curves[curves.length - 1], 1); + } + } else if (offset && offset.getPath && offset.getPath() === this) { + // offset is already a CurveLocation on this path, just return it. + return offset; } - // It may be that through imprecision of getLength, that the end of the - // last curve was missed: - if (curves.length > 0 && offset <= this.getLength()) - return new CurveLocation(curves[curves.length - 1], 1); return null; }