mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2024-12-29 09:22:22 -05:00
Switch to new simpler convention for control of beans creation in straps.js
This commit is contained in:
parent
4d52867b4a
commit
fa9786b344
12 changed files with 352 additions and 352 deletions
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"browser" : true,
|
"browser": true,
|
||||||
"evil": true,
|
"evil": true,
|
||||||
"wsh": true,
|
"wsh": true,
|
||||||
"trailing": false,
|
"trailing": false,
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
"test"
|
"test"
|
||||||
],
|
],
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"straps": "~1.4.3",
|
"straps": "~1.5.0",
|
||||||
"acorn": "git://github.com/paperjs/acorn#0.3.2",
|
"acorn": "git://github.com/paperjs/acorn#0.3.2",
|
||||||
"esprima": "~1.0.3",
|
"esprima": "~1.0.3",
|
||||||
"stats.js": "r11"
|
"stats.js": "r11"
|
||||||
|
|
|
@ -716,17 +716,15 @@ var Matrix = Base.extend(/** @lends Matrix# */{
|
||||||
applyToContext: function(ctx) {
|
applyToContext: function(ctx) {
|
||||||
ctx.transform(this._a, this._c, this._b, this._d, this._tx, this._ty);
|
ctx.transform(this._a, this._c, this._b, this._d, this._tx, this._ty);
|
||||||
}
|
}
|
||||||
}, new function() {
|
}, Base.each(['a', 'c', 'b', 'd', 'tx', 'ty'], function(name) {
|
||||||
// Create getters and setters for all internal attributes.
|
// Create getters and setters for all internal attributes.
|
||||||
return Base.each(['a', 'c', 'b', 'd', 'tx', 'ty'], function(name) {
|
var part = Base.capitalize(name),
|
||||||
var part = Base.capitalize(name),
|
prop = '_' + name;
|
||||||
prop = '_' + name;
|
this['get' + part] = function() {
|
||||||
this['get' + part] = function() {
|
return this[prop];
|
||||||
return this[prop];
|
};
|
||||||
};
|
this['set' + part] = function(value) {
|
||||||
this['set' + part] = function(value) {
|
this[prop] = value;
|
||||||
this[prop] = value;
|
this._changed();
|
||||||
this._changed();
|
};
|
||||||
};
|
}, {}));
|
||||||
}, {});
|
|
||||||
});
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
|
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
|
||||||
* http://paperjs.org/
|
* http://paperjs.org/
|
||||||
|
@ -238,6 +239,246 @@ var Point = Base.extend(/** @lends Point# */{
|
||||||
return [f.number(this.x), f.number(this.y)];
|
return [f.number(this.x), f.number(this.y)];
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The length of the vector that is represented by this point's coordinates.
|
||||||
|
* Each point can be interpreted as a vector that points from the origin
|
||||||
|
* ({@code x = 0}, {@code y = 0}) to the point's location.
|
||||||
|
* Setting the length changes the location but keeps the vector's angle.
|
||||||
|
*
|
||||||
|
* @type Number
|
||||||
|
* @bean
|
||||||
|
*/
|
||||||
|
getLength: function() {
|
||||||
|
return Math.sqrt(this.x * this.x + this.y * this.y);
|
||||||
|
},
|
||||||
|
|
||||||
|
setLength: function(length) {
|
||||||
|
// Whenever chaining both x & y, use #set() instead of direct
|
||||||
|
// assignment, so LinkedPoint does not report changes twice.
|
||||||
|
if (this.isZero()) {
|
||||||
|
var angle = this._angle || 0;
|
||||||
|
this.set(
|
||||||
|
Math.cos(angle) * length,
|
||||||
|
Math.sin(angle) * length
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
var scale = length / this.getLength();
|
||||||
|
// Force calculation of angle now, so it will be preserved even when
|
||||||
|
// x and y are 0
|
||||||
|
if (Numerical.isZero(scale))
|
||||||
|
this.getAngle();
|
||||||
|
this.set(
|
||||||
|
this.x * scale,
|
||||||
|
this.y * scale
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Returns the smaller angle between two vectors. The angle is unsigned, no
|
||||||
|
* information about rotational direction is given.
|
||||||
|
*
|
||||||
|
* @name Point#getAngle
|
||||||
|
* @function
|
||||||
|
* @param {Point} point
|
||||||
|
* @return {Number} the angle in degrees
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* The vector's angle in degrees, measured from the x-axis to the vector.
|
||||||
|
*
|
||||||
|
* @name Point#getAngle
|
||||||
|
* @bean
|
||||||
|
* @type Number
|
||||||
|
*/
|
||||||
|
getAngle: function(/* point */) {
|
||||||
|
return this.getAngleInRadians.apply(this, arguments) * 180 / Math.PI;
|
||||||
|
},
|
||||||
|
|
||||||
|
setAngle: function(angle) {
|
||||||
|
this.setAngleInRadians.call(this, angle * Math.PI / 180);
|
||||||
|
},
|
||||||
|
|
||||||
|
getAngleInDegrees: '#getAngle',
|
||||||
|
setAngleInDegrees: '#setAngle',
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the smaller angle between two vectors in radians. The angle is
|
||||||
|
* unsigned, no information about rotational direction is given.
|
||||||
|
*
|
||||||
|
* @name Point#getAngleInRadians
|
||||||
|
* @function
|
||||||
|
* @param {Point} point
|
||||||
|
* @return {Number} the angle in radians
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* The vector's angle in radians, measured from the x-axis to the vector.
|
||||||
|
*
|
||||||
|
* @name Point#getAngleInRadians
|
||||||
|
* @bean
|
||||||
|
* @type Number
|
||||||
|
*/
|
||||||
|
getAngleInRadians: function(/* point */) {
|
||||||
|
if (!arguments.length) {
|
||||||
|
return this.isZero()
|
||||||
|
// Return the preserved angle in case the vector has no
|
||||||
|
// length, and update the internal _angle in case the
|
||||||
|
// vector has a length. See #setAngle() for more
|
||||||
|
// explanations.
|
||||||
|
? this._angle || 0
|
||||||
|
: this._angle = Math.atan2(this.y, this.x);
|
||||||
|
} else {
|
||||||
|
var point = Point.read(arguments),
|
||||||
|
div = this.getLength() * point.getLength();
|
||||||
|
if (Numerical.isZero(div)) {
|
||||||
|
return NaN;
|
||||||
|
} else {
|
||||||
|
return Math.acos(this.dot(point) / div);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
setAngleInRadians: function(angle) {
|
||||||
|
// We store a reference to _angle internally so we still preserve it
|
||||||
|
// when the vector's length is set to zero, and then anything else.
|
||||||
|
// Note that we cannot rely on it if x and y are something else than 0,
|
||||||
|
// since updating x / y does not automatically change _angle!
|
||||||
|
this._angle = angle;
|
||||||
|
if (!this.isZero()) {
|
||||||
|
var length = this.getLength();
|
||||||
|
// 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
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The quadrant of the {@link #angle} of the point.
|
||||||
|
*
|
||||||
|
* Angles between 0 and 90 degrees are in quadrant {@code 1}. Angles between
|
||||||
|
* 90 and 180 degrees are in quadrant {@code 2}, angles between 180 and 270
|
||||||
|
* degrees are in quadrant {@code 3} and angles between 270 and 360 degrees
|
||||||
|
* are in quadrant {@code 4}.
|
||||||
|
*
|
||||||
|
* @type Number
|
||||||
|
* @bean
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* var point = new Point({
|
||||||
|
* angle: 10,
|
||||||
|
* length: 20
|
||||||
|
* });
|
||||||
|
* console.log(point.quadrant); // 1
|
||||||
|
*
|
||||||
|
* point.angle = 100;
|
||||||
|
* console.log(point.quadrant); // 2
|
||||||
|
*
|
||||||
|
* point.angle = 190;
|
||||||
|
* console.log(point.quadrant); // 3
|
||||||
|
*
|
||||||
|
* point.angle = 280;
|
||||||
|
* console.log(point.quadrant); // 4
|
||||||
|
*/
|
||||||
|
getQuadrant: function() {
|
||||||
|
return this.x >= 0 ? this.y >= 0 ? 1 : 4 : this.y >= 0 ? 2 : 3;
|
||||||
|
}
|
||||||
|
}, /** @lends Point# */{
|
||||||
|
// Explicitly deactivate the creation of beans, as we have functions here
|
||||||
|
// that look like bean getters but actually read arguments.
|
||||||
|
// See #getDirectedAngle(), #getDistance()
|
||||||
|
beans: false,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the angle between two vectors. The angle is directional and
|
||||||
|
* signed, giving information about the rotational direction.
|
||||||
|
*
|
||||||
|
* Read more about angle units and orientation in the description of the
|
||||||
|
* {@link #angle} property.
|
||||||
|
*
|
||||||
|
* @param {Point} point
|
||||||
|
* @return {Number} the angle between the two vectors
|
||||||
|
*/
|
||||||
|
getDirectedAngle: function(/* point */) {
|
||||||
|
var point = Point.read(arguments);
|
||||||
|
return Math.atan2(this.cross(point), this.dot(point)) * 180 / Math.PI;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the distance between the point and another point.
|
||||||
|
*
|
||||||
|
* @param {Point} point
|
||||||
|
* @param {Boolean} [squared=false] Controls whether the distance should
|
||||||
|
* remain squared, or its square root should be calculated.
|
||||||
|
* @return {Number}
|
||||||
|
*/
|
||||||
|
getDistance: function(/* point, squared */) {
|
||||||
|
var point = Point.read(arguments),
|
||||||
|
x = point.x - this.x,
|
||||||
|
y = point.y - this.y,
|
||||||
|
d = x * x + y * y,
|
||||||
|
squared = Base.read(arguments);
|
||||||
|
return squared ? d : Math.sqrt(d);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalize modifies the {@link #length} of the vector to {@code 1} without
|
||||||
|
* changing its angle and returns it as a new point. The optional
|
||||||
|
* {@code length} parameter defines the length to normalize to.
|
||||||
|
* The object itself is not modified!
|
||||||
|
*
|
||||||
|
* @param {Number} [length=1] The length of the normalized vector
|
||||||
|
* @return {Point} the normalized vector of the vector that is represented
|
||||||
|
* by this point's coordinates
|
||||||
|
*/
|
||||||
|
normalize: function(length) {
|
||||||
|
if (length === undefined)
|
||||||
|
length = 1;
|
||||||
|
var current = this.getLength(),
|
||||||
|
scale = current !== 0 ? length / current : 0,
|
||||||
|
point = new Point(this.x * scale, this.y * scale);
|
||||||
|
// Preserve angle.
|
||||||
|
if (scale >= 0)
|
||||||
|
point._angle = this._angle;
|
||||||
|
return point;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rotates the point by the given angle around an optional center point.
|
||||||
|
* The object itself is not modified.
|
||||||
|
*
|
||||||
|
* Read more about angle units and orientation in the description of the
|
||||||
|
* {@link #angle} property.
|
||||||
|
*
|
||||||
|
* @param {Number} angle the rotation angle
|
||||||
|
* @param {Point} center the center point of the rotation
|
||||||
|
* @returns {Point} the rotated point
|
||||||
|
*/
|
||||||
|
rotate: function(angle, center) {
|
||||||
|
if (angle === 0)
|
||||||
|
return this.clone();
|
||||||
|
angle = angle * Math.PI / 180;
|
||||||
|
var point = center ? this.subtract(center) : this,
|
||||||
|
s = Math.sin(angle),
|
||||||
|
c = Math.cos(angle);
|
||||||
|
point = new Point(
|
||||||
|
point.x * c - point.y * s,
|
||||||
|
point.x * s + point.y * c
|
||||||
|
);
|
||||||
|
return center ? point.add(center) : point;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transforms the point by the matrix as a new point. The object itself is
|
||||||
|
* not modified!
|
||||||
|
*
|
||||||
|
* @param {Matrix} matrix
|
||||||
|
* @return {Point} the transformed point
|
||||||
|
*/
|
||||||
|
transform: function(matrix) {
|
||||||
|
return matrix ? matrix._transformPoint(this) : this;
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the addition of the supplied value to both coordinates of
|
* Returns the addition of the supplied value to both coordinates of
|
||||||
* the point as a new point.
|
* the point as a new point.
|
||||||
|
@ -429,255 +670,6 @@ var Point = Base.extend(/** @lends Point# */{
|
||||||
return new Point(-this.x, -this.y);
|
return new Point(-this.x, -this.y);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* Transforms the point by the matrix as a new point. The object itself
|
|
||||||
* is not modified!
|
|
||||||
*
|
|
||||||
* @param {Matrix} matrix
|
|
||||||
* @return {Point} the transformed point
|
|
||||||
*/
|
|
||||||
transform: function(matrix) {
|
|
||||||
return matrix ? matrix._transformPoint(this) : this;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@grouptitle Distance & Length}
|
|
||||||
*
|
|
||||||
* Returns the distance between the point and another point.
|
|
||||||
*
|
|
||||||
* @param {Point} point
|
|
||||||
* @param {Boolean} [squared=false] Controls whether the distance should
|
|
||||||
* remain squared, or its square root should be calculated.
|
|
||||||
* @return {Number}
|
|
||||||
*/
|
|
||||||
getDistance: function(point, squared) {
|
|
||||||
// NOTE: Although we're reading from the argument list, we need the
|
|
||||||
// above arguments to prevent beans from being created (Straps.js issue)
|
|
||||||
// And for browser optimization we shouldn't re-assign an object to it,
|
|
||||||
// but we need to prevent the minifier from removing it again, so:
|
|
||||||
var _point = Point.read(arguments),
|
|
||||||
x = _point.x - this.x,
|
|
||||||
y = _point.y - this.y,
|
|
||||||
d = x * x + y * y;
|
|
||||||
// Reassigning boolean values to arguments is apparently OK.
|
|
||||||
squared = Base.read(arguments);
|
|
||||||
return squared ? d : Math.sqrt(d);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The length of the vector that is represented by this point's coordinates.
|
|
||||||
* Each point can be interpreted as a vector that points from the origin
|
|
||||||
* ({@code x = 0}, {@code y = 0}) to the point's location.
|
|
||||||
* Setting the length changes the location but keeps the vector's angle.
|
|
||||||
*
|
|
||||||
* @type Number
|
|
||||||
* @bean
|
|
||||||
*/
|
|
||||||
getLength: function() {
|
|
||||||
return Math.sqrt(this.x * this.x + this.y * this.y);
|
|
||||||
},
|
|
||||||
|
|
||||||
setLength: function(length) {
|
|
||||||
// Whenever chaining both x & y, use #set() instead of direct
|
|
||||||
// assignment, so LinkedPoint does not report changes twice.
|
|
||||||
if (this.isZero()) {
|
|
||||||
var angle = this._angle || 0;
|
|
||||||
this.set(
|
|
||||||
Math.cos(angle) * length,
|
|
||||||
Math.sin(angle) * length
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
var scale = length / this.getLength();
|
|
||||||
// Force calculation of angle now, so it will be preserved even when
|
|
||||||
// x and y are 0
|
|
||||||
if (Numerical.isZero(scale))
|
|
||||||
this.getAngle();
|
|
||||||
this.set(
|
|
||||||
this.x * scale,
|
|
||||||
this.y * scale
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Normalize modifies the {@link #length} of the vector to {@code 1} without
|
|
||||||
* changing its angle and returns it as a new point. The optional
|
|
||||||
* {@code length} parameter defines the length to normalize to.
|
|
||||||
* The object itself is not modified!
|
|
||||||
*
|
|
||||||
* @param {Number} [length=1] The length of the normalized vector
|
|
||||||
* @return {Point} the normalized vector of the vector that is represented
|
|
||||||
* by this point's coordinates
|
|
||||||
*/
|
|
||||||
normalize: function(length) {
|
|
||||||
if (length === undefined)
|
|
||||||
length = 1;
|
|
||||||
var current = this.getLength(),
|
|
||||||
scale = current !== 0 ? length / current : 0,
|
|
||||||
point = new Point(this.x * scale, this.y * scale);
|
|
||||||
// Preserve angle.
|
|
||||||
if (scale >= 0)
|
|
||||||
point._angle = this._angle;
|
|
||||||
return point;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@grouptitle Angle & Rotation}
|
|
||||||
* Returns the smaller angle between two vectors. The angle is unsigned, no
|
|
||||||
* information about rotational direction is given.
|
|
||||||
*
|
|
||||||
* @name Point#getAngle
|
|
||||||
* @function
|
|
||||||
* @param {Point} point
|
|
||||||
* @return {Number} the angle in degrees
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* The vector's angle in degrees, measured from the x-axis to the vector.
|
|
||||||
*
|
|
||||||
* @name Point#getAngle
|
|
||||||
* @bean
|
|
||||||
* @type Number
|
|
||||||
*/
|
|
||||||
getAngle: function(/* point */) {
|
|
||||||
return this.getAngleInRadians.apply(this, arguments) * 180 / Math.PI;
|
|
||||||
},
|
|
||||||
|
|
||||||
setAngle: function(angle) {
|
|
||||||
this.setAngleInRadians.call(this, angle * Math.PI / 180);
|
|
||||||
},
|
|
||||||
|
|
||||||
getAngleInDegrees: '#getAngle',
|
|
||||||
setAngleInDegrees: '#setAngle',
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the smaller angle between two vectors in radians. The angle is
|
|
||||||
* unsigned, no information about rotational direction is given.
|
|
||||||
*
|
|
||||||
* @name Point#getAngleInRadians
|
|
||||||
* @function
|
|
||||||
* @param {Point} point
|
|
||||||
* @return {Number} the angle in radians
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* The vector's angle in radians, measured from the x-axis to the vector.
|
|
||||||
*
|
|
||||||
* @name Point#getAngleInRadians
|
|
||||||
* @bean
|
|
||||||
* @type Number
|
|
||||||
*/
|
|
||||||
getAngleInRadians: function(/* point */) {
|
|
||||||
if (!arguments.length) {
|
|
||||||
return this.isZero()
|
|
||||||
// Return the preseved angle in case the vector has no
|
|
||||||
// length, and update the internal _angle in case the
|
|
||||||
// vector has a length. See #setAngle() for more
|
|
||||||
// explanations.
|
|
||||||
? this._angle || 0
|
|
||||||
: this._angle = Math.atan2(this.y, this.x);
|
|
||||||
} else {
|
|
||||||
var point = Point.read(arguments),
|
|
||||||
div = this.getLength() * point.getLength();
|
|
||||||
if (Numerical.isZero(div)) {
|
|
||||||
return NaN;
|
|
||||||
} else {
|
|
||||||
return Math.acos(this.dot(point) / div);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
setAngleInRadians: function(angle) {
|
|
||||||
// We store a reference to _angle internally so we still preserve it
|
|
||||||
// when the vector's length is set to zero, and then anything else.
|
|
||||||
// Note that we cannot rely on it if x and y are something else than 0,
|
|
||||||
// since updating x / y does not automatically change _angle!
|
|
||||||
this._angle = angle;
|
|
||||||
if (!this.isZero()) {
|
|
||||||
var length = this.getLength();
|
|
||||||
// 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
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The quadrant of the {@link #angle} of the point.
|
|
||||||
*
|
|
||||||
* Angles between 0 and 90 degrees are in quadrant {@code 1}. Angles between
|
|
||||||
* 90 and 180 degrees are in quadrant {@code 2}, angles between 180 and 270
|
|
||||||
* degrees are in quadrant {@code 3} and angles between 270 and 360 degrees
|
|
||||||
* are in quadrant {@code 4}.
|
|
||||||
*
|
|
||||||
* @type Number
|
|
||||||
* @bean
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* var point = new Point({
|
|
||||||
* angle: 10,
|
|
||||||
* length: 20
|
|
||||||
* });
|
|
||||||
* console.log(point.quadrant); // 1
|
|
||||||
*
|
|
||||||
* point.angle = 100;
|
|
||||||
* console.log(point.quadrant); // 2
|
|
||||||
*
|
|
||||||
* point.angle = 190;
|
|
||||||
* console.log(point.quadrant); // 3
|
|
||||||
*
|
|
||||||
* point.angle = 280;
|
|
||||||
* console.log(point.quadrant); // 4
|
|
||||||
*/
|
|
||||||
getQuadrant: function() {
|
|
||||||
return this.x >= 0 ? this.y >= 0 ? 1 : 4 : this.y >= 0 ? 2 : 3;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the angle between two vectors. The angle is directional and
|
|
||||||
* signed, giving information about the rotational direction.
|
|
||||||
*
|
|
||||||
* Read more about angle units and orientation in the description of the
|
|
||||||
* {@link #angle} property.
|
|
||||||
*
|
|
||||||
* @param {Point} point
|
|
||||||
* @return {Number} the angle between the two vectors
|
|
||||||
*/
|
|
||||||
getDirectedAngle: function(point) {
|
|
||||||
// NOTE: Although we're reading from the argument list, we need the
|
|
||||||
// above arguments to prevent beans from being created (Straps.js issue)
|
|
||||||
// And for browser optimization we shouldn't re-asign an object to it,
|
|
||||||
// but we need to prevent the minifier from removing it again, so:
|
|
||||||
var _point = point;
|
|
||||||
_point = Point.read(arguments);
|
|
||||||
return Math.atan2(this.cross(_point), this.dot(_point)) * 180 / Math.PI;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Rotates the point by the given angle around an optional center point.
|
|
||||||
* The object itself is not modified.
|
|
||||||
*
|
|
||||||
* Read more about angle units and orientation in the description of the
|
|
||||||
* {@link #angle} property.
|
|
||||||
*
|
|
||||||
* @param {Number} angle the rotation angle
|
|
||||||
* @param {Point} center the center point of the rotation
|
|
||||||
* @returns {Point} the rotated point
|
|
||||||
*/
|
|
||||||
rotate: function(angle, center) {
|
|
||||||
if (angle === 0)
|
|
||||||
return this.clone();
|
|
||||||
angle = angle * Math.PI / 180;
|
|
||||||
var point = center ? this.subtract(center) : this,
|
|
||||||
s = Math.sin(angle),
|
|
||||||
c = Math.cos(angle);
|
|
||||||
point = new Point(
|
|
||||||
point.x * c - point.y * s,
|
|
||||||
point.x * s + point.y * c
|
|
||||||
);
|
|
||||||
return center ? point.add(center) : point;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@grouptitle Tests}
|
* {@grouptitle Tests}
|
||||||
*
|
*
|
||||||
|
|
|
@ -21,6 +21,9 @@ var Rectangle = Base.extend(/** @lends Rectangle# */{
|
||||||
_class: 'Rectangle',
|
_class: 'Rectangle',
|
||||||
// Tell Base.read that the Rectangle constructor supports reading with index
|
// Tell Base.read that the Rectangle constructor supports reading with index
|
||||||
_readIndex: true,
|
_readIndex: true,
|
||||||
|
// Enforce creation of beans, as bean getters have hidden parameters.
|
||||||
|
// See #getPoint() below.
|
||||||
|
beans: true,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a Rectangle object.
|
* Creates a Rectangle object.
|
||||||
|
@ -821,7 +824,11 @@ var Rectangle = Base.extend(/** @lends Rectangle# */{
|
||||||
this[setX](point.x);
|
this[setX](point.x);
|
||||||
this[setY](point.y);
|
this[setY](point.y);
|
||||||
};
|
};
|
||||||
}, {});
|
}, {
|
||||||
|
// Enforce creation of beans, as bean getters have hidden parameters
|
||||||
|
// See _dontLink argument above.
|
||||||
|
beans: true
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -476,6 +476,10 @@ var Item = Base.extend(Callback, /** @lends Item# */{
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}, {}), /** @lends Item# */{
|
}, {}), /** @lends Item# */{
|
||||||
|
// Enforce creation of beans, as bean getters have hidden parameters.
|
||||||
|
// See #getPosition() below.
|
||||||
|
beans: true,
|
||||||
|
|
||||||
// Note: These properties have their getter / setters produced in the
|
// Note: These properties have their getter / setters produced in the
|
||||||
// injection scope above.
|
// injection scope above.
|
||||||
|
|
||||||
|
@ -873,14 +877,12 @@ var Item = Base.extend(Callback, /** @lends Item# */{
|
||||||
bounds.height, this, 'setBounds')
|
bounds.height, this, 'setBounds')
|
||||||
: bounds;
|
: bounds;
|
||||||
};
|
};
|
||||||
// As the function defines a _matrix parameter and has no setter,
|
|
||||||
// Straps.js doesn't produce a bean for it. Explicitely define an
|
|
||||||
// accesor now too:
|
|
||||||
this[key] = {
|
|
||||||
get: this[getter]
|
|
||||||
};
|
|
||||||
},
|
},
|
||||||
/** @lends Item# */{
|
/** @lends Item# */{
|
||||||
|
// Enforce creation of beans, as bean getters have hidden parameters.
|
||||||
|
// See _matrix parameter above.
|
||||||
|
beans: true,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Protected method used in all the bounds getters. It loops through all the
|
* Protected method used in all the bounds getters. It loops through all the
|
||||||
* children, gets their bounds and finds the bounds around all of them.
|
* children, gets their bounds and finds the bounds around all of them.
|
||||||
|
@ -1062,6 +1064,10 @@ var Item = Base.extend(Callback, /** @lends Item# */{
|
||||||
* @ignore
|
* @ignore
|
||||||
*/
|
*/
|
||||||
}), /** @lends Item# */{
|
}), /** @lends Item# */{
|
||||||
|
// Enforce creation of beans, as bean getters have hidden parameters.
|
||||||
|
// See #getGlobalMatrix() below.
|
||||||
|
beans: true,
|
||||||
|
|
||||||
_decompose: function() {
|
_decompose: function() {
|
||||||
return this._decomposed = this._matrix.decompose();
|
return this._decomposed = this._matrix.decompose();
|
||||||
},
|
},
|
||||||
|
@ -1146,7 +1152,7 @@ var Item = Base.extend(Callback, /** @lends Item# */{
|
||||||
* @type Matrix
|
* @type Matrix
|
||||||
* @bean
|
* @bean
|
||||||
*/
|
*/
|
||||||
getGlobalMatrix: function() {
|
getGlobalMatrix: function(_internal) {
|
||||||
var matrix = this._globalMatrix,
|
var matrix = this._globalMatrix,
|
||||||
updateVersion = this._project._updateVersion,
|
updateVersion = this._project._updateVersion,
|
||||||
viewMatrix = this.getView()._matrix;
|
viewMatrix = this.getView()._matrix;
|
||||||
|
@ -1164,9 +1170,7 @@ var Item = Base.extend(Callback, /** @lends Item# */{
|
||||||
: viewMatrix);
|
: viewMatrix);
|
||||||
matrix._updateVersion = updateVersion;
|
matrix._updateVersion = updateVersion;
|
||||||
}
|
}
|
||||||
// TODO: Fix Straps.js so we can pass this on as _internal argument and
|
return _internal ? matrix : viewMatrix.inverted().concatenate(matrix);
|
||||||
// still have a bean created.
|
|
||||||
return arguments[0] ? matrix : viewMatrix.inverted().concatenate(matrix);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1194,7 +1198,7 @@ var Item = Base.extend(Callback, /** @lends Item# */{
|
||||||
*/
|
*/
|
||||||
getTransformContent: '#getApplyMatrix',
|
getTransformContent: '#getApplyMatrix',
|
||||||
setTransformContent: '#setApplyMatrix',
|
setTransformContent: '#setApplyMatrix',
|
||||||
|
}, /** @lends Item# */{
|
||||||
/**
|
/**
|
||||||
* {@grouptitle Project Hierarchy}
|
* {@grouptitle Project Hierarchy}
|
||||||
* The project that this item belongs to.
|
* The project that this item belongs to.
|
||||||
|
|
|
@ -219,16 +219,20 @@ var CompoundPath = PathItem.extend(/** @lends CompoundPath# */{
|
||||||
for (var i = 0, l = children.length; i < l; i++)
|
for (var i = 0, l = children.length; i < l; i++)
|
||||||
area += children[i].getArea();
|
area += children[i].getArea();
|
||||||
return area;
|
return area;
|
||||||
},
|
}
|
||||||
|
}, /** @lends CompoundPath# */{
|
||||||
|
// Enforce bean creation for getPathData(), as it has hidden parameters.
|
||||||
|
beans: true,
|
||||||
|
|
||||||
getPathData: function(precision) {
|
getPathData: function(_precision) {
|
||||||
|
// NOTE: #setPathData() is defined in PathItem.
|
||||||
var children = this._children,
|
var children = this._children,
|
||||||
paths = [];
|
paths = [];
|
||||||
for (var i = 0, l = children.length; i < l; i++)
|
for (var i = 0, l = children.length; i < l; i++)
|
||||||
paths.push(children[i].getPathData(precision));
|
paths.push(children[i].getPathData(_precision));
|
||||||
return paths.join(' ');
|
return paths.join(' ');
|
||||||
},
|
}
|
||||||
|
}, /** @lends CompoundPath# */{
|
||||||
_getChildHitTestOptions: function(options) {
|
_getChildHitTestOptions: function(options) {
|
||||||
// If we're not specifically asked to returns paths through
|
// If we're not specifically asked to returns paths through
|
||||||
// options.type == 'path' do not test children for fill, since a
|
// options.type == 'path' do not test children for fill, since a
|
||||||
|
|
|
@ -28,6 +28,10 @@
|
||||||
*/
|
*/
|
||||||
var CurveLocation = Base.extend(/** @lends CurveLocation# */{
|
var CurveLocation = Base.extend(/** @lends CurveLocation# */{
|
||||||
_class: 'CurveLocation',
|
_class: 'CurveLocation',
|
||||||
|
// Enforce creation of beans, as bean getters have hidden parameters.
|
||||||
|
// See #getSegment() below.
|
||||||
|
beans: true,
|
||||||
|
|
||||||
// DOCS: CurveLocation class description: add these back when the mentioned
|
// DOCS: CurveLocation class description: add these back when the mentioned
|
||||||
// functioned have been added: {@link Path#split(location)}
|
// functioned have been added: {@link Path#split(location)}
|
||||||
/**
|
/**
|
||||||
|
@ -82,13 +86,6 @@ var CurveLocation = Base.extend(/** @lends CurveLocation# */{
|
||||||
return this._segment;
|
return this._segment;
|
||||||
},
|
},
|
||||||
|
|
||||||
setSegment: function(segment) {
|
|
||||||
// NOTE: We only include this setter so the above getter can declare
|
|
||||||
// the _preferFirst parameter without having to hide it.
|
|
||||||
// See Straps.js beans conventions.
|
|
||||||
this._segment = segment;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The curve by which the location is defined.
|
* The curve by which the location is defined.
|
||||||
*
|
*
|
||||||
|
@ -109,11 +106,6 @@ var CurveLocation = Base.extend(/** @lends CurveLocation# */{
|
||||||
return this._curve;
|
return this._curve;
|
||||||
},
|
},
|
||||||
|
|
||||||
setCurve: function(curve) {
|
|
||||||
// See #setSegment()
|
|
||||||
this._curve = curve;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The curve location on the intersecting curve, if this location is the
|
* The curve location on the intersecting curve, if this location is the
|
||||||
* result of a call to {@link PathItem#getIntersections(path)} /
|
* result of a call to {@link PathItem#getIntersections(path)} /
|
||||||
|
@ -199,11 +191,6 @@ var CurveLocation = Base.extend(/** @lends CurveLocation# */{
|
||||||
return this._parameter;
|
return this._parameter;
|
||||||
},
|
},
|
||||||
|
|
||||||
setParameter: function(parameter) {
|
|
||||||
// See #setSegment()
|
|
||||||
this._parameter = parameter;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The point which is defined by the {@link #curve} and
|
* The point which is defined by the {@link #curve} and
|
||||||
* {@link #parameter}.
|
* {@link #parameter}.
|
||||||
|
@ -219,11 +206,6 @@ var CurveLocation = Base.extend(/** @lends CurveLocation# */{
|
||||||
return this._point;
|
return this._point;
|
||||||
},
|
},
|
||||||
|
|
||||||
setPoint: function(point) {
|
|
||||||
// See #setSegment()
|
|
||||||
this._point = point;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The tangential vector to the {@link #curve} at the given location.
|
* The tangential vector to the {@link #curve} at the given location.
|
||||||
*
|
*
|
||||||
|
|
|
@ -254,51 +254,6 @@ var Path = PathItem.extend(/** @lends Path# */{
|
||||||
return curves[curves.length - 1];
|
return curves[curves.length - 1];
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* The segments contained within the path, described as SVG style path data.
|
|
||||||
*
|
|
||||||
* @type String
|
|
||||||
* @bean
|
|
||||||
*/
|
|
||||||
getPathData: function(precision) {
|
|
||||||
var segments = this._segments,
|
|
||||||
f = Formatter.instance,
|
|
||||||
parts = [];
|
|
||||||
|
|
||||||
// TODO: Add support for H/V and/or relative commands, where appropriate
|
|
||||||
// and resulting in shorter strings
|
|
||||||
function addCurve(seg1, seg2, skipLine) {
|
|
||||||
var point1 = seg1._point,
|
|
||||||
point2 = seg2._point,
|
|
||||||
handle1 = seg1._handleOut,
|
|
||||||
handle2 = seg2._handleIn;
|
|
||||||
if (handle1.isZero() && handle2.isZero()) {
|
|
||||||
if (!skipLine) {
|
|
||||||
// L = absolute lineto: moving to a point with drawing
|
|
||||||
parts.push('L' + f.point(point2, precision));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// c = relative curveto: handle1, handle2 + end - start,
|
|
||||||
// end - start
|
|
||||||
var end = point2.subtract(point1);
|
|
||||||
parts.push('c' + f.point(handle1, precision)
|
|
||||||
+ ' ' + f.point(end.add(handle2), precision)
|
|
||||||
+ ' ' + f.point(end, precision));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (segments.length === 0)
|
|
||||||
return '';
|
|
||||||
parts.push('M' + f.point(segments[0]._point));
|
|
||||||
for (var i = 0, l = segments.length - 1; i < l; i++)
|
|
||||||
addCurve(segments[i], segments[i + 1], false);
|
|
||||||
if (this._closed) {
|
|
||||||
addCurve(segments[segments.length - 1], segments[0], true);
|
|
||||||
parts.push('z');
|
|
||||||
}
|
|
||||||
return parts.join('');
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specifies whether the path is closed. If it is closed, Paper.js connects
|
* Specifies whether the path is closed. If it is closed, Paper.js connects
|
||||||
* the first and last segments.
|
* the first and last segments.
|
||||||
|
@ -336,7 +291,51 @@ var Path = PathItem.extend(/** @lends Path# */{
|
||||||
// up-to-date and don't need notification.
|
// up-to-date and don't need notification.
|
||||||
this._changed(/*#=*/ Change.SEGMENTS);
|
this._changed(/*#=*/ Change.SEGMENTS);
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
}, /** @lends Path# */{
|
||||||
|
// Enforce bean creation for getPathData(), as it has hidden parameters.
|
||||||
|
beans: true,
|
||||||
|
|
||||||
|
getPathData: function(_precision) {
|
||||||
|
// NOTE: #setPathData() is defined in PathItem.
|
||||||
|
var segments = this._segments,
|
||||||
|
f = Formatter.instance,
|
||||||
|
parts = [];
|
||||||
|
|
||||||
|
// TODO: Add support for H/V and/or relative commands, where appropriate
|
||||||
|
// and resulting in shorter strings
|
||||||
|
function addCurve(seg1, seg2, skipLine) {
|
||||||
|
var point1 = seg1._point,
|
||||||
|
point2 = seg2._point,
|
||||||
|
handle1 = seg1._handleOut,
|
||||||
|
handle2 = seg2._handleIn;
|
||||||
|
if (handle1.isZero() && handle2.isZero()) {
|
||||||
|
if (!skipLine) {
|
||||||
|
// L = absolute lineto: moving to a point with drawing
|
||||||
|
parts.push('L' + f.point(point2, _precision));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// c = relative curveto: handle1, handle2 + end - start,
|
||||||
|
// end - start
|
||||||
|
var end = point2.subtract(point1);
|
||||||
|
parts.push('c' + f.point(handle1, _precision)
|
||||||
|
+ ' ' + f.point(end.add(handle2), _precision)
|
||||||
|
+ ' ' + f.point(end, _precision));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (segments.length === 0)
|
||||||
|
return '';
|
||||||
|
parts.push('M' + f.point(segments[0]._point));
|
||||||
|
for (var i = 0, l = segments.length - 1; i < l; i++)
|
||||||
|
addCurve(segments[i], segments[i + 1], false);
|
||||||
|
if (this._closed) {
|
||||||
|
addCurve(segments[segments.length - 1], segments[0], true);
|
||||||
|
parts.push('z');
|
||||||
|
}
|
||||||
|
return parts.join('');
|
||||||
|
}
|
||||||
|
}, /** @lends Path# */{
|
||||||
|
|
||||||
// TODO: Consider adding getSubPath(a, b), returning a part of the current
|
// TODO: Consider adding getSubPath(a, b), returning a part of the current
|
||||||
// path, with the added benefit that b can be < a, and closed looping is
|
// path, with the added benefit that b can be < a, and closed looping is
|
||||||
|
@ -2439,7 +2438,7 @@ var Path = PathItem.extend(/** @lends Path# */{
|
||||||
z = 4 / 3 * Math.sin(half) / (1 + Math.cos(half)),
|
z = 4 / 3 * Math.sin(half) / (1 + Math.cos(half)),
|
||||||
segments = [];
|
segments = [];
|
||||||
for (var i = 0; i <= count; i++) {
|
for (var i = 0; i <= count; i++) {
|
||||||
// Explicitely use to point for last segment, since depending
|
// Explicitly use to point for last segment, since depending
|
||||||
// on values the calculation adds imprecision:
|
// on values the calculation adds imprecision:
|
||||||
var pt = to,
|
var pt = to,
|
||||||
out = null;
|
out = null;
|
||||||
|
|
|
@ -181,7 +181,16 @@ var PathItem = Item.extend(/** @lends PathItem# */{
|
||||||
return locations;
|
return locations;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The path's geometry, formatted as SVG style path data.
|
||||||
|
*
|
||||||
|
* @name PathItem#getPathData
|
||||||
|
* @type String
|
||||||
|
* @bean
|
||||||
|
*/
|
||||||
|
|
||||||
setPathData: function(data) {
|
setPathData: function(data) {
|
||||||
|
// NOTE: #getPathData() is defined in CompoundPath / Path
|
||||||
// This is a very compact SVG Path Data parser that works both for Path
|
// This is a very compact SVG Path Data parser that works both for Path
|
||||||
// and CompoundPath.
|
// and CompoundPath.
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
*/
|
*/
|
||||||
var Segment = Base.extend(/** @lends Segment# */{
|
var Segment = Base.extend(/** @lends Segment# */{
|
||||||
_class: 'Segment',
|
_class: 'Segment',
|
||||||
|
beans: true,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new Segment object.
|
* Creates a new Segment object.
|
||||||
|
@ -146,7 +147,8 @@ var Segment = Base.extend(/** @lends Segment# */{
|
||||||
_serialize: function(options) {
|
_serialize: function(options) {
|
||||||
// If the Segment is linear, only serialize point, otherwise handles too
|
// If the Segment is linear, only serialize point, otherwise handles too
|
||||||
return Base.serialize(this.isLinear() ? this._point
|
return Base.serialize(this.isLinear() ? this._point
|
||||||
: [this._point, this._handleIn, this._handleOut], options, true);
|
: [this._point, this._handleIn, this._handleOut],
|
||||||
|
options, true);
|
||||||
},
|
},
|
||||||
|
|
||||||
_changed: function(point) {
|
_changed: function(point) {
|
||||||
|
|
|
@ -116,7 +116,10 @@ var Style = Base.extend(new function() {
|
||||||
// Override default fillColor for text items
|
// Override default fillColor for text items
|
||||||
_textDefaults: new Base(defaults, {
|
_textDefaults: new Base(defaults, {
|
||||||
fillColor: new Color() // black
|
fillColor: new Color() // black
|
||||||
})
|
}),
|
||||||
|
// Enforce creation of beans, as bean getters have hidden parameters
|
||||||
|
// See _dontMerge argument below.
|
||||||
|
beans: true
|
||||||
};
|
};
|
||||||
|
|
||||||
Base.each(defaults, function(value, key) {
|
Base.each(defaults, function(value, key) {
|
||||||
|
|
Loading…
Reference in a new issue