mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2025-01-05 20:32:00 -05:00
Merge remote branch 'origin/master'
This commit is contained in:
commit
2ee7081c14
7 changed files with 134 additions and 99 deletions
|
@ -149,29 +149,20 @@ var Point = this.Point = Base.extend({
|
|||
},
|
||||
|
||||
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._angle != null) {
|
||||
var a = this._angle;
|
||||
// Use #set() instead of direct assignment, so LinkedPoint
|
||||
// can optimise
|
||||
this.set(
|
||||
Math.cos(a) * length,
|
||||
Math.sin(a) * length
|
||||
);
|
||||
} else {
|
||||
// Assume angle = 0
|
||||
this.x = length;
|
||||
// y is already 0
|
||||
}
|
||||
var angle = this._angle || 0;
|
||||
this.set(
|
||||
Math.cos(angle) * length,
|
||||
Math.sin(angle) * length
|
||||
);
|
||||
} else {
|
||||
var scale = length / this.getLength();
|
||||
if (scale == 0) {
|
||||
// Calculate angle now, so it will be preserved even when
|
||||
// x and y are 0
|
||||
// Force calculation of angle now, so it will be preserved even when
|
||||
// x and y are 0
|
||||
if (scale == 0)
|
||||
this.getAngle();
|
||||
}
|
||||
// Use #set() instead of direct assignment, so LinkedPoint
|
||||
// can optimise
|
||||
this.set(
|
||||
this.x * scale,
|
||||
this.y * scale
|
||||
|
@ -181,30 +172,18 @@ var Point = this.Point = Base.extend({
|
|||
},
|
||||
|
||||
normalize: function(length) {
|
||||
if (length === null)
|
||||
if (length === undefined)
|
||||
length = 1;
|
||||
var len = this.getLength();
|
||||
var scale = len != 0 ? length / len : 0;
|
||||
var res = Point.create(this.x * scale, this.y * scale);
|
||||
var current = this.getLength(),
|
||||
scale = current != 0 ? length / current : 0,
|
||||
point = Point.create(this.x * scale, this.y * scale);
|
||||
// Preserve angle.
|
||||
res._angle = this._angle;
|
||||
return res;
|
||||
point._angle = this._angle;
|
||||
return point;
|
||||
},
|
||||
|
||||
getQuadrant: function() {
|
||||
if (this.x >= 0) {
|
||||
if (this.y >= 0) {
|
||||
return 1;
|
||||
} else {
|
||||
return 4;
|
||||
}
|
||||
} else {
|
||||
if (this.y >= 0) {
|
||||
return 2;
|
||||
} else {
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
return this.x >= 0 ? this.y >= 0 ? 1 : 4 : this.y >= 0 ? 2 : 3;
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -230,8 +209,8 @@ var Point = this.Point = Base.extend({
|
|||
angle = this._angle = angle * Math.PI / 180;
|
||||
if (!this.isZero()) {
|
||||
var length = this.getLength();
|
||||
// Use #set() instead of direct assignment, so LinkedPoint
|
||||
// can optimise
|
||||
// Use #set() instead of direct assignment of x/y, so LinkedPoint
|
||||
// does not report changes twice.
|
||||
this.set(
|
||||
Math.cos(angle) * length,
|
||||
Math.sin(angle) * length
|
||||
|
@ -514,7 +493,8 @@ var Point = this.Point = Base.extend({
|
|||
min: function(point1, point2) {
|
||||
return Point.create(
|
||||
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) {
|
||||
return Point.create(
|
||||
Math.max(point1.x, point2.x),
|
||||
Math.max(point1.y, point2.y));
|
||||
Math.max(point1.y, point2.y)
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -173,15 +173,15 @@ var Color = this.Color = Base.extend(new function() {
|
|||
},
|
||||
|
||||
toString: function() {
|
||||
var string = '';
|
||||
var parts = [];
|
||||
for (var i = 0, l = this._components.length; i < l; i++) {
|
||||
var component = this._components[i];
|
||||
var value = this['_' + component];
|
||||
if (component === 'alpha' && value == null)
|
||||
value = 1;
|
||||
string += (i > 0 ? ', ' : '') + component + ': ' + value;
|
||||
parts.push(component + ': ' + value);
|
||||
}
|
||||
return '{ ' + string + ' }';
|
||||
return '{ ' + parts.join(', ') + ' }';
|
||||
},
|
||||
|
||||
toCssString: function() {
|
||||
|
|
|
@ -35,6 +35,11 @@ var Curve = this.Curve = Base.extend({
|
|||
}
|
||||
},
|
||||
|
||||
_changed: function() {
|
||||
// Clear cached values.
|
||||
delete this._length;
|
||||
},
|
||||
|
||||
_updateSegments: function() {
|
||||
if (this._path) {
|
||||
this._index2 = this._index1 + 1;
|
||||
|
@ -153,11 +158,19 @@ var Curve = this.Curve = Base.extend({
|
|||
},
|
||||
|
||||
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
|
||||
var args = this.getCurveValues();
|
||||
if (arguments.length > 0)
|
||||
args.push(arguments[0], arguments[1]);
|
||||
return Curve.getLength.apply(Curve, args);
|
||||
if (!fullLength)
|
||||
args.push(from, to);
|
||||
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() {
|
||||
return '{ point1: ' + this._segment1._point
|
||||
+ (!this._segment1._handleOut.isZero()
|
||||
? ', handle1: ' + this._segment1._handleOut : '')
|
||||
+ (this._segment2._handleIn.isZero()
|
||||
? ', handle2: ' + this._segment2._handleIn : '')
|
||||
+ ', point2: ' + this._segment2._point
|
||||
+ ' }';
|
||||
var parts = [ 'point1: ' + this._segment1._point ];
|
||||
if (!this._segment1._handleOut.isZero())
|
||||
parts.push('handle1: ' + this._segment1._handleOut);
|
||||
if (!this._segment2._handleIn.isZero())
|
||||
parts.push('handle2: ' + this._segment2._handleIn);
|
||||
parts.push('point2: ' + this._segment2._point);
|
||||
return '{ ' + parts.join(', ') + ' }';
|
||||
},
|
||||
|
||||
statics: {
|
||||
|
|
|
@ -28,6 +28,13 @@ var Path = this.Path = PathItem.extend({
|
|||
|| 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.
|
||||
*/
|
||||
|
@ -102,6 +109,7 @@ var Path = this.Path = PathItem.extend({
|
|||
if (closed)
|
||||
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._changed();
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -163,6 +172,7 @@ var Path = this.Path = PathItem.extend({
|
|||
if (this._closed)
|
||||
this._curves[l - 1]._updateSegments();
|
||||
}
|
||||
this._changed();
|
||||
return segment;
|
||||
},
|
||||
|
||||
|
@ -199,6 +209,7 @@ var Path = this.Path = PathItem.extend({
|
|||
segment._selectionState = 0;
|
||||
}
|
||||
}
|
||||
this._changed();
|
||||
return segments;
|
||||
}
|
||||
return null;
|
||||
|
@ -245,6 +256,7 @@ var Path = this.Path = PathItem.extend({
|
|||
segment._handleIn = segment._handleOut;
|
||||
segment._handleOut = handleIn;
|
||||
}
|
||||
this._changed();
|
||||
},
|
||||
|
||||
join: function(path) {
|
||||
|
@ -282,17 +294,20 @@ var Path = this.Path = PathItem.extend({
|
|||
last1.remove();
|
||||
this.setClosed(true);
|
||||
}
|
||||
this._changed();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
getLength: function() {
|
||||
var curves = this.getCurves();
|
||||
var length = 0;
|
||||
for (var i = 0, l = curves.length; i < l; i++)
|
||||
length += curves[i].getLength();
|
||||
return length;
|
||||
if (this._length == null) {
|
||||
var curves = this.getCurves();
|
||||
this._length = 0;
|
||||
for (var i = 0, l = curves.length; i < l; i++)
|
||||
this._length += curves[i].getLength();
|
||||
}
|
||||
return this._length;
|
||||
},
|
||||
|
||||
_getOffset: function(location) {
|
||||
|
@ -977,9 +992,12 @@ var Path = this.Path = PathItem.extend({
|
|||
getBounds: function(/* matrix */) {
|
||||
// Pass the matrix hidden from Bootstrap, so it still inject
|
||||
// getBounds as bean too.
|
||||
var bounds = getBounds(this, arguments[0]);
|
||||
return LinkedRectangle.create(this, 'setBounds',
|
||||
bounds.x, bounds.y, bounds.width, bounds.height);
|
||||
if (!this._bounds) {
|
||||
var bounds = getBounds(this, arguments[0]);
|
||||
this._bounds = LinkedRectangle.create(this, 'setBounds',
|
||||
bounds.x, bounds.y, bounds.width, bounds.height);
|
||||
}
|
||||
return this._bounds;
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -51,6 +51,28 @@ var Segment = this.Segment = Base.extend({
|
|||
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() {
|
||||
return this._point;
|
||||
},
|
||||
|
@ -71,7 +93,7 @@ var Segment = this.Segment = Base.extend({
|
|||
// See #setPoint:
|
||||
this._handleIn.set(point.x, point.y);
|
||||
// Update corner accordingly
|
||||
// this.corner = !this._handleIn.isParallel(this._handleOut);
|
||||
// this.corner = !this._handleIn.isColinear(this._handleOut);
|
||||
},
|
||||
|
||||
getHandleInIfSet: function() {
|
||||
|
@ -88,7 +110,7 @@ var Segment = this.Segment = Base.extend({
|
|||
// See #setPoint:
|
||||
this._handleOut.set(point.x, point.y);
|
||||
// Update corner accordingly
|
||||
// this.corner = !this._handleIn.isParallel(this._handleOut);
|
||||
// this.corner = !this._handleIn.isColinear(this._handleOut);
|
||||
},
|
||||
|
||||
getHandleOutIfSet: function() {
|
||||
|
@ -105,7 +127,7 @@ var Segment = this.Segment = Base.extend({
|
|||
},
|
||||
|
||||
getCurve: function() {
|
||||
if (this._path != null) {
|
||||
if (this._path) {
|
||||
var index = this._index;
|
||||
// The last segment of an open path belongs to the last curve
|
||||
if (!this._path._closed && index == this._path._segments.length - 1)
|
||||
|
@ -208,12 +230,12 @@ var Segment = this.Segment = Base.extend({
|
|||
},
|
||||
|
||||
toString: function() {
|
||||
return '{ point: ' + this._point
|
||||
+ (!this._handleIn.isZero()
|
||||
? ', handleIn: ' + this._handleIn : '')
|
||||
+ (this._handleOut.isZero()
|
||||
? ', handleOut: ' + this._handleOut : '')
|
||||
+ ' }';
|
||||
var parts = [ 'point: ' + this._point ];
|
||||
if (!this._handleIn.isZero())
|
||||
parts.push('handleIn: ' + this._handleIn);
|
||||
if (!this._handleOut.isZero())
|
||||
parts.push('handleOut: ' + this._handleOut);
|
||||
return '{ ' + parts.join(', ') + ' }';
|
||||
},
|
||||
|
||||
_transformCoordinates: function(matrix, coords, change) {
|
||||
|
@ -228,47 +250,47 @@ var Segment = this.Segment = Base.extend({
|
|||
handleIn = matrix && this.getHandleInIfSet() || this._handleIn,
|
||||
handleOut = matrix && this.getHandleOutIfSet() || this._handleOut,
|
||||
x = point._x,
|
||||
y = point._y;
|
||||
y = point._y,
|
||||
i = 2;
|
||||
coords[0] = x;
|
||||
coords[1] = y;
|
||||
var index = 2;
|
||||
// We need to convert handles to absolute coordinates in order
|
||||
// to transform them.
|
||||
if (handleIn) {
|
||||
coords[index++] = handleIn._x + x;
|
||||
coords[index++] = handleIn._y + y;
|
||||
coords[i++] = handleIn._x + x;
|
||||
coords[i++] = handleIn._y + y;
|
||||
}
|
||||
if (handleOut) {
|
||||
coords[index++] = handleOut._x + x;
|
||||
coords[index++] = handleOut._y + y;
|
||||
coords[i++] = handleOut._x + x;
|
||||
coords[i++] = handleOut._y + y;
|
||||
}
|
||||
if (matrix) {
|
||||
matrix.transform(coords, 0, coords, 0, index / 2);
|
||||
matrix.transform(coords, 0, coords, 0, i / 2);
|
||||
x = coords[0];
|
||||
y = coords[1];
|
||||
if (change) {
|
||||
// If change is true, we need to set the new values back
|
||||
point._x = x;
|
||||
point._y = y;
|
||||
index = 2;
|
||||
i = 2;
|
||||
if (handleIn) {
|
||||
handleIn._x = coords[index++] - x;
|
||||
handleIn._y = coords[index++] - y;
|
||||
handleIn._x = coords[i++] - x;
|
||||
handleIn._y = coords[i++] - y;
|
||||
}
|
||||
if (handleOut) {
|
||||
handleOut._x = coords[index++] - x;
|
||||
handleOut._y = coords[index++] - y;
|
||||
handleOut._x = coords[i++] - x;
|
||||
handleOut._y = coords[i++] - y;
|
||||
}
|
||||
} else {
|
||||
// We want to receive the results in coords, so make sure
|
||||
// handleIn and out are defined too, even if they're 0
|
||||
if (!handleIn) {
|
||||
coords[index++] = x;
|
||||
coords[index++] = y;
|
||||
coords[i++] = x;
|
||||
coords[i++] = y;
|
||||
}
|
||||
if (!handleOut) {
|
||||
coords[index++] = x;
|
||||
coords[index++] = y;
|
||||
coords[i++] = x;
|
||||
coords[i++] = y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ var SegmentPoint = Point.extend({
|
|||
set: function(x, y) {
|
||||
this._x = x;
|
||||
this._y = y;
|
||||
// this._segment._markDirty(DirtyFlags.BOUNDS);
|
||||
this._segment._changed(this);
|
||||
return this;
|
||||
},
|
||||
|
||||
|
@ -18,7 +18,7 @@ var SegmentPoint = Point.extend({
|
|||
|
||||
setX: function(x) {
|
||||
this._x = x;
|
||||
// this._segment._markDirty(DirtyFlags.BOUNDS);
|
||||
this._segment._changed(this);
|
||||
},
|
||||
|
||||
getY: function() {
|
||||
|
@ -27,7 +27,7 @@ var SegmentPoint = Point.extend({
|
|||
|
||||
setY: function(y) {
|
||||
this._y = y;
|
||||
// this._segment._markDirty(DirtyFlags.BOUNDS);
|
||||
this._segment._changed(this);
|
||||
},
|
||||
|
||||
setSelected: function(selected) {
|
||||
|
@ -39,15 +39,16 @@ var SegmentPoint = Point.extend({
|
|||
},
|
||||
|
||||
statics: {
|
||||
create: function(segment, arg1, arg2) {
|
||||
var point;
|
||||
if (arguments.length == 2) {
|
||||
point = new SegmentPoint(arg1);
|
||||
} else {
|
||||
point = new SegmentPoint(SegmentPoint.dont);
|
||||
point._x = arg1;
|
||||
point._y = arg2;
|
||||
create: function(segment, x, y) {
|
||||
if (y === undefined) {
|
||||
// Use the normal point constructor to read in point values
|
||||
var tmp = new Point(x);
|
||||
x = tmp.x;
|
||||
y = tmp.y;
|
||||
}
|
||||
var point = new SegmentPoint(SegmentPoint.dont);
|
||||
point._x = x;
|
||||
point._y = y;
|
||||
point._segment = segment;
|
||||
return point;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue