mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2025-01-07 13:22:07 -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) {
|
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)
|
||||||
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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: {
|
||||||
|
|
|
@ -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;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue