Merge remote branch 'origin/master'

This commit is contained in:
Jonathan Puckey 2011-05-02 12:25:32 +02:00
commit 2ee7081c14
7 changed files with 134 additions and 99 deletions

View file

@ -149,29 +149,20 @@ var Point = this.Point = Base.extend({
}, },
setLength: function(length) { setLength: function(length) {
// Whenever setting x/y, use #set() instead of direct assignment,
// so LinkedPoint does not report changes twice.
if (this.isZero()) { if (this.isZero()) {
if (this._angle != null) { var angle = this._angle || 0;
var a = this._angle; this.set(
// Use #set() instead of direct assignment, so LinkedPoint Math.cos(angle) * length,
// can optimise Math.sin(angle) * length
this.set( );
Math.cos(a) * length,
Math.sin(a) * length
);
} else {
// Assume angle = 0
this.x = length;
// y is already 0
}
} else { } else {
var scale = length / this.getLength(); var scale = length / this.getLength();
if (scale == 0) { // Force calculation of angle now, so it will be preserved even when
// Calculate angle now, so it will be preserved even when // x and y are 0
// x and y are 0 if (scale == 0)
this.getAngle(); this.getAngle();
}
// Use #set() instead of direct assignment, so LinkedPoint
// can optimise
this.set( this.set(
this.x * scale, this.x * scale,
this.y * scale this.y * scale
@ -181,30 +172,18 @@ var Point = this.Point = Base.extend({
}, },
normalize: function(length) { normalize: function(length) {
if (length === null) if (length === undefined)
length = 1; length = 1;
var len = this.getLength(); var current = this.getLength(),
var scale = len != 0 ? length / len : 0; scale = current != 0 ? length / current : 0,
var res = Point.create(this.x * scale, this.y * scale); point = Point.create(this.x * scale, this.y * scale);
// Preserve angle. // Preserve angle.
res._angle = this._angle; point._angle = this._angle;
return res; return point;
}, },
getQuadrant: function() { getQuadrant: function() {
if (this.x >= 0) { return this.x >= 0 ? this.y >= 0 ? 1 : 4 : this.y >= 0 ? 2 : 3;
if (this.y >= 0) {
return 1;
} else {
return 4;
}
} else {
if (this.y >= 0) {
return 2;
} else {
return 3;
}
}
}, },
/** /**
@ -230,8 +209,8 @@ var Point = this.Point = Base.extend({
angle = this._angle = angle * Math.PI / 180; angle = this._angle = angle * Math.PI / 180;
if (!this.isZero()) { if (!this.isZero()) {
var length = this.getLength(); var length = this.getLength();
// Use #set() instead of direct assignment, so LinkedPoint // Use #set() instead of direct assignment of x/y, so LinkedPoint
// can optimise // does not report changes twice.
this.set( this.set(
Math.cos(angle) * length, Math.cos(angle) * length,
Math.sin(angle) * length Math.sin(angle) * length
@ -514,7 +493,8 @@ var Point = this.Point = Base.extend({
min: function(point1, point2) { min: function(point1, point2) {
return Point.create( return Point.create(
Math.min(point1.x, point2.x), Math.min(point1.x, point2.x),
Math.min(point1.y, point2.y)); Math.min(point1.y, point2.y)
);
}, },
/** /**
@ -536,7 +516,8 @@ var Point = this.Point = Base.extend({
max: function(point1, point2) { max: function(point1, point2) {
return Point.create( return Point.create(
Math.max(point1.x, point2.x), Math.max(point1.x, point2.x),
Math.max(point1.y, point2.y)); Math.max(point1.y, point2.y)
);
}, },
/** /**

View file

@ -173,15 +173,15 @@ var Color = this.Color = Base.extend(new function() {
}, },
toString: function() { toString: function() {
var string = ''; var parts = [];
for (var i = 0, l = this._components.length; i < l; i++) { for (var i = 0, l = this._components.length; i < l; i++) {
var component = this._components[i]; var component = this._components[i];
var value = this['_' + component]; var value = this['_' + component];
if (component === 'alpha' && value == null) if (component === 'alpha' && value == null)
value = 1; value = 1;
string += (i > 0 ? ', ' : '') + component + ': ' + value; parts.push(component + ': ' + value);
} }
return '{ ' + string + ' }'; return '{ ' + parts.join(', ') + ' }';
}, },
toCssString: function() { toCssString: function() {

View file

@ -35,6 +35,11 @@ var Curve = this.Curve = Base.extend({
} }
}, },
_changed: function() {
// Clear cached values.
delete this._length;
},
_updateSegments: function() { _updateSegments: function() {
if (this._path) { if (this._path) {
this._index2 = this._index1 + 1; this._index2 = this._index1 + 1;
@ -153,11 +158,19 @@ var Curve = this.Curve = Base.extend({
}, },
getLength: function(/* from, to */) { getLength: function(/* from, to */) {
var from = arguments[0],
to = arguments[1];
fullLength = arguments.length == 0 || from == 0 && to == 1;
if (fullLength && this._length != null)
return this._length;
// Hide parameters from Bootstrap so it injects bean too // Hide parameters from Bootstrap so it injects bean too
var args = this.getCurveValues(); var args = this.getCurveValues();
if (arguments.length > 0) if (!fullLength)
args.push(arguments[0], arguments[1]); args.push(from, to);
return Curve.getLength.apply(Curve, args); var length = Curve.getLength.apply(Curve, args);
if (fullLength)
this._length = length;
return length;
}, },
/** /**
@ -203,13 +216,13 @@ var Curve = this.Curve = Base.extend({
}, },
toString: function() { toString: function() {
return '{ point1: ' + this._segment1._point var parts = [ 'point1: ' + this._segment1._point ];
+ (!this._segment1._handleOut.isZero() if (!this._segment1._handleOut.isZero())
? ', handle1: ' + this._segment1._handleOut : '') parts.push('handle1: ' + this._segment1._handleOut);
+ (this._segment2._handleIn.isZero() if (!this._segment2._handleIn.isZero())
? ', handle2: ' + this._segment2._handleIn : '') parts.push('handle2: ' + this._segment2._handleIn);
+ ', point2: ' + this._segment2._point parts.push('point2: ' + this._segment2._point);
+ ' }'; return '{ ' + parts.join(', ') + ' }';
}, },
statics: { statics: {

View file

@ -28,6 +28,13 @@ var Path = this.Path = PathItem.extend({
|| typeof segments[0] !== 'object' ? arguments : segments); || typeof segments[0] !== 'object' ? arguments : segments);
}, },
_changed: function() {
// Clear cached values.
delete this._length;
delete this._bounds;
delete this._strokeBounds;
},
/** /**
* The segments contained within the path. * The segments contained within the path.
*/ */
@ -102,6 +109,7 @@ var Path = this.Path = PathItem.extend({
if (closed) if (closed)
this._curves[i = length - 1] = Curve.create(this, i); this._curves[i = length - 1] = Curve.create(this, i);
} }
this._changed();
} }
}, },
@ -116,6 +124,7 @@ var Path = this.Path = PathItem.extend({
this._segments[i]._transformCoordinates(matrix, coords, true); this._segments[i]._transformCoordinates(matrix, coords, true);
} }
} }
this._changed();
}, },
/** /**
@ -163,6 +172,7 @@ var Path = this.Path = PathItem.extend({
if (this._closed) if (this._closed)
this._curves[l - 1]._updateSegments(); this._curves[l - 1]._updateSegments();
} }
this._changed();
return segment; return segment;
}, },
@ -199,6 +209,7 @@ var Path = this.Path = PathItem.extend({
segment._selectionState = 0; segment._selectionState = 0;
} }
} }
this._changed();
return segments; return segments;
} }
return null; return null;
@ -245,6 +256,7 @@ var Path = this.Path = PathItem.extend({
segment._handleIn = segment._handleOut; segment._handleIn = segment._handleOut;
segment._handleOut = handleIn; segment._handleOut = handleIn;
} }
this._changed();
}, },
join: function(path) { join: function(path) {
@ -282,17 +294,20 @@ var Path = this.Path = PathItem.extend({
last1.remove(); last1.remove();
this.setClosed(true); this.setClosed(true);
} }
this._changed();
return true; return true;
} }
return false; return false;
}, },
getLength: function() { getLength: function() {
var curves = this.getCurves(); if (this._length == null) {
var length = 0; var curves = this.getCurves();
for (var i = 0, l = curves.length; i < l; i++) this._length = 0;
length += curves[i].getLength(); for (var i = 0, l = curves.length; i < l; i++)
return length; this._length += curves[i].getLength();
}
return this._length;
}, },
_getOffset: function(location) { _getOffset: function(location) {
@ -977,9 +992,12 @@ var Path = this.Path = PathItem.extend({
getBounds: function(/* matrix */) { getBounds: function(/* matrix */) {
// Pass the matrix hidden from Bootstrap, so it still inject // Pass the matrix hidden from Bootstrap, so it still inject
// getBounds as bean too. // getBounds as bean too.
var bounds = getBounds(this, arguments[0]); if (!this._bounds) {
return LinkedRectangle.create(this, 'setBounds', var bounds = getBounds(this, arguments[0]);
bounds.x, bounds.y, bounds.width, bounds.height); this._bounds = LinkedRectangle.create(this, 'setBounds',
bounds.x, bounds.y, bounds.width, bounds.height);
}
return this._bounds;
}, },
/** /**

View file

@ -51,6 +51,28 @@ var Segment = this.Segment = Base.extend({
this._handleOut = SegmentPoint.create(this, 0, 0); this._handleOut = SegmentPoint.create(this, 0, 0);
}, },
_changed: function(point) {
if (this._path) {
// Delegate changes to affected curves if they exist
if (this._path._curves) {
var curve = this.getCurve(), other;
if (curve) {
curve._changed();
// Get the other affected curve, which is the previous one
// for _point or _handleIn changing when this segment is
// _segment1 of the curve, for all other cases it's the next
// (e.g. _handleOut or this segment == _segment2)
if (other = (curve[point == this._point
|| point == this._handleIn && curve._segment1 == this
? 'getPrevious' : 'getNext']())) {
other._changed();
}
}
}
this._path._changed();
}
},
getPoint: function() { getPoint: function() {
return this._point; return this._point;
}, },
@ -71,7 +93,7 @@ var Segment = this.Segment = Base.extend({
// See #setPoint: // See #setPoint:
this._handleIn.set(point.x, point.y); this._handleIn.set(point.x, point.y);
// Update corner accordingly // Update corner accordingly
// this.corner = !this._handleIn.isParallel(this._handleOut); // this.corner = !this._handleIn.isColinear(this._handleOut);
}, },
getHandleInIfSet: function() { getHandleInIfSet: function() {
@ -88,7 +110,7 @@ var Segment = this.Segment = Base.extend({
// See #setPoint: // See #setPoint:
this._handleOut.set(point.x, point.y); this._handleOut.set(point.x, point.y);
// Update corner accordingly // Update corner accordingly
// this.corner = !this._handleIn.isParallel(this._handleOut); // this.corner = !this._handleIn.isColinear(this._handleOut);
}, },
getHandleOutIfSet: function() { getHandleOutIfSet: function() {
@ -105,7 +127,7 @@ var Segment = this.Segment = Base.extend({
}, },
getCurve: function() { getCurve: function() {
if (this._path != null) { if (this._path) {
var index = this._index; var index = this._index;
// The last segment of an open path belongs to the last curve // The last segment of an open path belongs to the last curve
if (!this._path._closed && index == this._path._segments.length - 1) if (!this._path._closed && index == this._path._segments.length - 1)
@ -208,12 +230,12 @@ var Segment = this.Segment = Base.extend({
}, },
toString: function() { toString: function() {
return '{ point: ' + this._point var parts = [ 'point: ' + this._point ];
+ (!this._handleIn.isZero() if (!this._handleIn.isZero())
? ', handleIn: ' + this._handleIn : '') parts.push('handleIn: ' + this._handleIn);
+ (this._handleOut.isZero() if (!this._handleOut.isZero())
? ', handleOut: ' + this._handleOut : '') parts.push('handleOut: ' + this._handleOut);
+ ' }'; return '{ ' + parts.join(', ') + ' }';
}, },
_transformCoordinates: function(matrix, coords, change) { _transformCoordinates: function(matrix, coords, change) {
@ -228,47 +250,47 @@ var Segment = this.Segment = Base.extend({
handleIn = matrix && this.getHandleInIfSet() || this._handleIn, handleIn = matrix && this.getHandleInIfSet() || this._handleIn,
handleOut = matrix && this.getHandleOutIfSet() || this._handleOut, handleOut = matrix && this.getHandleOutIfSet() || this._handleOut,
x = point._x, x = point._x,
y = point._y; y = point._y,
i = 2;
coords[0] = x; coords[0] = x;
coords[1] = y; coords[1] = y;
var index = 2;
// We need to convert handles to absolute coordinates in order // We need to convert handles to absolute coordinates in order
// to transform them. // to transform them.
if (handleIn) { if (handleIn) {
coords[index++] = handleIn._x + x; coords[i++] = handleIn._x + x;
coords[index++] = handleIn._y + y; coords[i++] = handleIn._y + y;
} }
if (handleOut) { if (handleOut) {
coords[index++] = handleOut._x + x; coords[i++] = handleOut._x + x;
coords[index++] = handleOut._y + y; coords[i++] = handleOut._y + y;
} }
if (matrix) { if (matrix) {
matrix.transform(coords, 0, coords, 0, index / 2); matrix.transform(coords, 0, coords, 0, i / 2);
x = coords[0]; x = coords[0];
y = coords[1]; y = coords[1];
if (change) { if (change) {
// If change is true, we need to set the new values back // If change is true, we need to set the new values back
point._x = x; point._x = x;
point._y = y; point._y = y;
index = 2; i = 2;
if (handleIn) { if (handleIn) {
handleIn._x = coords[index++] - x; handleIn._x = coords[i++] - x;
handleIn._y = coords[index++] - y; handleIn._y = coords[i++] - y;
} }
if (handleOut) { if (handleOut) {
handleOut._x = coords[index++] - x; handleOut._x = coords[i++] - x;
handleOut._y = coords[index++] - y; handleOut._y = coords[i++] - y;
} }
} else { } else {
// We want to receive the results in coords, so make sure // We want to receive the results in coords, so make sure
// handleIn and out are defined too, even if they're 0 // handleIn and out are defined too, even if they're 0
if (!handleIn) { if (!handleIn) {
coords[index++] = x; coords[i++] = x;
coords[index++] = y; coords[i++] = y;
} }
if (!handleOut) { if (!handleOut) {
coords[index++] = x; coords[i++] = x;
coords[index++] = y; coords[i++] = y;
} }
} }
} }

View file

@ -8,7 +8,7 @@ var SegmentPoint = Point.extend({
set: function(x, y) { set: function(x, y) {
this._x = x; this._x = x;
this._y = y; this._y = y;
// this._segment._markDirty(DirtyFlags.BOUNDS); this._segment._changed(this);
return this; return this;
}, },
@ -18,7 +18,7 @@ var SegmentPoint = Point.extend({
setX: function(x) { setX: function(x) {
this._x = x; this._x = x;
// this._segment._markDirty(DirtyFlags.BOUNDS); this._segment._changed(this);
}, },
getY: function() { getY: function() {
@ -27,7 +27,7 @@ var SegmentPoint = Point.extend({
setY: function(y) { setY: function(y) {
this._y = y; this._y = y;
// this._segment._markDirty(DirtyFlags.BOUNDS); this._segment._changed(this);
}, },
setSelected: function(selected) { setSelected: function(selected) {
@ -39,15 +39,16 @@ var SegmentPoint = Point.extend({
}, },
statics: { statics: {
create: function(segment, arg1, arg2) { create: function(segment, x, y) {
var point; if (y === undefined) {
if (arguments.length == 2) { // Use the normal point constructor to read in point values
point = new SegmentPoint(arg1); var tmp = new Point(x);
} else { x = tmp.x;
point = new SegmentPoint(SegmentPoint.dont); y = tmp.y;
point._x = arg1;
point._y = arg2;
} }
var point = new SegmentPoint(SegmentPoint.dont);
point._x = x;
point._y = y;
point._segment = segment; point._segment = segment;
return point; return point;
} }