Fix various issues with Path#curves synchronization.

This commit is contained in:
Jürg Lehni 2012-12-31 22:21:50 +01:00
parent 4aa9c83708
commit d2b799f4db
2 changed files with 39 additions and 22 deletions

View file

@ -311,17 +311,19 @@ var Path = this.Path = PathItem.extend(/** @lends Path# */{
} }
} }
// Keep the curves list in sync all the time in case it as requested // Keep the curves list in sync all the time in case it as requested
// already. We need to step one index down from the inserted segment to // already.
// get its curve: if (curves) {
if (curves && --index >= 0) { // We need to step one index down from the inserted segment to
// get its curve, except for the first segment.
// TODO:
if (index > 0)
index--;
// Insert a new curve as well and update the curves above // Insert a new curve as well and update the curves above
curves.splice(index, 0, Curve.create(this, segments[index], for (var i = index, l = index + amount; i < l; i++)
segments[index + 1])); curves.splice(i, 0, Curve.create(this, segments[i],
// Adjust segment1 now for the curves above the inserted one segments[i + 1] || segments[0]));
var curve = curves[index + amount]; // Adjust segments for the curves before and after the removed ones
if (curve) { this._adjustCurves(index - 1, index + amount);
curve._segment1 = segments[index + amount];
}
} }
this._changed(/*#=*/ Change.GEOMETRY); this._changed(/*#=*/ Change.GEOMETRY);
return segs; return segs;
@ -567,7 +569,6 @@ var Path = this.Path = PathItem.extend(/** @lends Path# */{
to = Base.pick(to, this._segments.length); to = Base.pick(to, this._segments.length);
var segments = this._segments, var segments = this._segments,
curves = this._curves, curves = this._curves,
last = to >= segments.length,
removed = segments.splice(from, to - from), removed = segments.splice(from, to - from),
amount = removed.length; amount = removed.length;
if (!amount) if (!amount)
@ -588,23 +589,31 @@ var Path = this.Path = PathItem.extend(/** @lends Path# */{
// If we're removing the last segment, remove the last curve. Also // If we're removing the last segment, remove the last curve. Also
// take into account closed paths, which have one curve more than // take into account closed paths, which have one curve more than
// segments. // segments.
curves.splice(from == segments.length + (this._closed ? 1 : 0) var index = from == segments.length + (this._closed ? 1 : 0)
? from - 1 : from, amount); ? from - 1 : from;
curves.splice(index, amount);
// Adjust segments for the curves before and after the removed ones // Adjust segments for the curves before and after the removed ones
var curve; this._adjustCurves(index - 1, index + amount);
if (curve = curves[from - 1])
curve._segment2 = segments[from];
if (curve = curves[from])
curve._segment1 = segments[from];
// If the last segment of a closing path was removed, we need to
// readjust the last curve of the list now.
if (last && this._closed && (curve = curves[curves.length - 1]))
curve._segment2 = segments[0];
} }
this._changed(/*#=*/ Change.GEOMETRY); this._changed(/*#=*/ Change.GEOMETRY);
return removed; return removed;
}, },
/**
* Adjusts segments of curves before and after inserted / removed segments.
*/
_adjustCurves: function(left, right) {
var segments = this._segments,
curves = this._curves,
curve;
// If it's the first segment, correct the last segment of closed
// paths too:
if (curve = curves[this._closed && left == -1 ? segments.length - 1 : left])
curve._segment2 = segments[left + 1] || segments[0];
if (curve = curves[right])
curve._segment1 = segments[right];
},
/** /**
* Specifies whether an path is selected and will also return {@code true} * Specifies whether an path is selected and will also return {@code true}
* if the path is partially selected, i.e. one or more of its segments is * if the path is partially selected, i.e. one or more of its segments is

View file

@ -46,6 +46,14 @@ test('path.curves Synchronisation', function() {
equals(path.curves[0].length, 200, 'Curve length should be updated when path is transformed'); equals(path.curves[0].length, 200, 'Curve length should be updated when path is transformed');
}); });
test('path.curves on Closed Paths', function() {
var path = new Path.Circle(new Point(100, 100) , 100);
equals(path.curves.toString(), "{ point1: { x: 0, y: 100 }, handle1: { x: 0, y: -55.22847 }, handle2: { x: -55.22847, y: 0 }, point2: { x: 100, y: 0 } },{ point1: { x: 100, y: 0 }, handle1: { x: 55.22847, y: 0 }, handle2: { x: 0, y: -55.22847 }, point2: { x: 200, y: 100 } },{ point1: { x: 200, y: 100 }, handle1: { x: 0, y: 55.22847 }, handle2: { x: 55.22847, y: 0 }, point2: { x: 100, y: 200 } },{ point1: { x: 100, y: 200 }, handle1: { x: -55.22847, y: 0 }, handle2: { x: 0, y: 55.22847 }, point2: { x: 0, y: 100 } }");
path.removeSegments(0, 1);
equals(path.curves.toString(), "{ point1: { x: 100, y: 0 }, handle1: { x: 55.22847, y: 0 }, handle2: { x: 0, y: -55.22847 }, point2: { x: 200, y: 100 } },{ point1: { x: 200, y: 100 }, handle1: { x: 0, y: 55.22847 }, handle2: { x: 55.22847, y: 0 }, point2: { x: 100, y: 200 } },{ point1: { x: 100, y: 200 }, handle1: { x: -55.22847, y: 0 }, handle2: { x: -55.22847, y: 0 }, point2: { x: 100, y: 0 } }");
});
test('path.flatten(maxDistance)', function() { test('path.flatten(maxDistance)', function() {
var path = new Path.Circle(new Size(80, 50), 35); var path = new Path.Circle(new Size(80, 50), 35);