mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2025-01-22 23:39:59 -05:00
Restructure code a bit for easier reading.
This commit is contained in:
parent
ea87be166e
commit
c989d3ee3f
1 changed files with 244 additions and 239 deletions
123
src/path/Path.js
123
src/path/Path.js
|
@ -1761,53 +1761,10 @@ var Path = this.Path = PathItem.extend(/** @lends Path# */{
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}, new function() { // A dedicated scope for the tricky bounds calculations
|
}, new function() { // A dedicated scope for the tricky bounds calculations
|
||||||
/**
|
|
||||||
* Returns the horizontal and vertical padding that a transformed round
|
|
||||||
* stroke adds to the bounding box, by calculating the dimensions of a
|
|
||||||
* rotated ellipse.
|
|
||||||
*/
|
|
||||||
function getPenPadding(radius, matrix) {
|
|
||||||
if (!matrix)
|
|
||||||
return [radius, radius];
|
|
||||||
// If a matrix is provided, we need to rotate the stroke circle
|
|
||||||
// and calculate the bounding box of the resulting rotated elipse:
|
|
||||||
// Get rotated hor and ver vectors, and determine rotation angle
|
|
||||||
// and elipse values from them:
|
|
||||||
var mx = matrix.createShiftless(),
|
|
||||||
hor = mx.transform(new Point(radius, 0)),
|
|
||||||
ver = mx.transform(new Point(0, radius)),
|
|
||||||
phi = hor.getAngleInRadians(),
|
|
||||||
a = hor.getLength(),
|
|
||||||
b = ver.getLength();
|
|
||||||
// Formula for rotated ellipses:
|
|
||||||
// x = cx + a*cos(t)*cos(phi) - b*sin(t)*sin(phi)
|
|
||||||
// y = cy + b*sin(t)*cos(phi) + a*cos(t)*sin(phi)
|
|
||||||
// Derivates (by Wolfram Alpha):
|
|
||||||
// derivative of x = cx + a*cos(t)*cos(phi) - b*sin(t)*sin(phi)
|
|
||||||
// dx/dt = a sin(t) cos(phi) + b cos(t) sin(phi) = 0
|
|
||||||
// derivative of y = cy + b*sin(t)*cos(phi) + a*cos(t)*sin(phi)
|
|
||||||
// dy/dt = b cos(t) cos(phi) - a sin(t) sin(phi) = 0
|
|
||||||
// this can be simplified to:
|
|
||||||
// tan(t) = -b * tan(phi) / a // x
|
|
||||||
// tan(t) = b * cot(phi) / a // y
|
|
||||||
// Solving for t gives:
|
|
||||||
// t = pi * n - arctan(b tan(phi)) // x
|
|
||||||
// t = pi * n + arctan(b cot(phi)) // y
|
|
||||||
var tx = - Math.atan(b * Math.tan(phi)),
|
|
||||||
ty = + Math.atan(b / Math.tan(phi)),
|
|
||||||
// Due to symetry, we don't need to cycle through pi * n solutions:
|
|
||||||
x = a * Math.cos(tx) * Math.cos(phi)
|
|
||||||
- b * Math.sin(tx) * Math.sin(phi),
|
|
||||||
y = b * Math.sin(ty) * Math.cos(phi)
|
|
||||||
+ a * Math.cos(ty) * Math.sin(phi);
|
|
||||||
return [Math.abs(x), Math.abs(y)];
|
|
||||||
}
|
|
||||||
|
|
||||||
var get = {
|
|
||||||
/**
|
/**
|
||||||
* Returns the bounding rectangle of the item excluding stroke width.
|
* Returns the bounding rectangle of the item excluding stroke width.
|
||||||
*/
|
*/
|
||||||
bounds: function(that, matrix, strokePadding) {
|
function getBounds(that, matrix, strokePadding) {
|
||||||
// Code ported and further optimised from:
|
// Code ported and further optimised from:
|
||||||
// http://blog.hackers-cafe.net/2009/06/how-to-calculate-bezier-curves-bounding.html
|
// http://blog.hackers-cafe.net/2009/06/how-to-calculate-bezier-curves-bounding.html
|
||||||
var segments = that._segments,
|
var segments = that._segments,
|
||||||
|
@ -1903,16 +1860,58 @@ var Path = this.Path = PathItem.extend(/** @lends Path# */{
|
||||||
processSegment(first);
|
processSegment(first);
|
||||||
return Rectangle.create(min[0], min[1],
|
return Rectangle.create(min[0], min[1],
|
||||||
max[0] - min[0], max[1] - min[1]);
|
max[0] - min[0], max[1] - min[1]);
|
||||||
},
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the horizontal and vertical padding that a transformed round
|
||||||
|
* stroke adds to the bounding box, by calculating the dimensions of a
|
||||||
|
* rotated ellipse.
|
||||||
|
*/
|
||||||
|
function getPenPadding(radius, matrix) {
|
||||||
|
if (!matrix)
|
||||||
|
return [radius, radius];
|
||||||
|
// If a matrix is provided, we need to rotate the stroke circle
|
||||||
|
// and calculate the bounding box of the resulting rotated elipse:
|
||||||
|
// Get rotated hor and ver vectors, and determine rotation angle
|
||||||
|
// and elipse values from them:
|
||||||
|
var mx = matrix.createShiftless(),
|
||||||
|
hor = mx.transform(new Point(radius, 0)),
|
||||||
|
ver = mx.transform(new Point(0, radius)),
|
||||||
|
phi = hor.getAngleInRadians(),
|
||||||
|
a = hor.getLength(),
|
||||||
|
b = ver.getLength();
|
||||||
|
// Formula for rotated ellipses:
|
||||||
|
// x = cx + a*cos(t)*cos(phi) - b*sin(t)*sin(phi)
|
||||||
|
// y = cy + b*sin(t)*cos(phi) + a*cos(t)*sin(phi)
|
||||||
|
// Derivates (by Wolfram Alpha):
|
||||||
|
// derivative of x = cx + a*cos(t)*cos(phi) - b*sin(t)*sin(phi)
|
||||||
|
// dx/dt = a sin(t) cos(phi) + b cos(t) sin(phi) = 0
|
||||||
|
// derivative of y = cy + b*sin(t)*cos(phi) + a*cos(t)*sin(phi)
|
||||||
|
// dy/dt = b cos(t) cos(phi) - a sin(t) sin(phi) = 0
|
||||||
|
// this can be simplified to:
|
||||||
|
// tan(t) = -b * tan(phi) / a // x
|
||||||
|
// tan(t) = b * cot(phi) / a // y
|
||||||
|
// Solving for t gives:
|
||||||
|
// t = pi * n - arctan(b tan(phi)) // x
|
||||||
|
// t = pi * n + arctan(b cot(phi)) // y
|
||||||
|
var tx = - Math.atan(b * Math.tan(phi)),
|
||||||
|
ty = + Math.atan(b / Math.tan(phi)),
|
||||||
|
// Due to symetry, we don't need to cycle through pi * n solutions:
|
||||||
|
x = a * Math.cos(tx) * Math.cos(phi)
|
||||||
|
- b * Math.sin(tx) * Math.sin(phi),
|
||||||
|
y = b * Math.sin(ty) * Math.cos(phi)
|
||||||
|
+ a * Math.cos(ty) * Math.sin(phi);
|
||||||
|
return [Math.abs(x), Math.abs(y)];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the bounding rectangle of the item including stroke width.
|
* Returns the bounding rectangle of the item including stroke width.
|
||||||
*/
|
*/
|
||||||
strokeBounds: function(that, matrix) {
|
function getStrokeBounds(that, matrix) {
|
||||||
// TODO: Should we access this.getStrokeColor, as we do in _transform?
|
// TODO: Should we access this.getStrokeColor, as we do in _transform?
|
||||||
// TODO: Find a way to reuse 'bounds' cache instead?
|
// TODO: Find a way to reuse 'bounds' cache instead?
|
||||||
if (!that._style._strokeColor || !that._style._strokeWidth)
|
if (!that._style._strokeColor || !that._style._strokeWidth)
|
||||||
return get.bounds(that, matrix);
|
return getBounds(that, matrix);
|
||||||
var width = that.getStrokeWidth(),
|
var width = that.getStrokeWidth(),
|
||||||
radius = width / 2,
|
radius = width / 2,
|
||||||
padding = getPenPadding(radius, matrix),
|
padding = getPenPadding(radius, matrix),
|
||||||
|
@ -1924,8 +1923,8 @@ var Path = this.Path = PathItem.extend(/** @lends Path# */{
|
||||||
segments = that._segments,
|
segments = that._segments,
|
||||||
length = segments.length,
|
length = segments.length,
|
||||||
// It seems to be compatible with Ai we need to pass pen padding
|
// It seems to be compatible with Ai we need to pass pen padding
|
||||||
// untransformed to get.bounds
|
// untransformed to getBounds
|
||||||
bounds = get.bounds(that, matrix, getPenPadding(radius));
|
bounds = getBounds(that, matrix, getPenPadding(radius));
|
||||||
// Create a rectangle of padding size, used for union with bounds
|
// Create a rectangle of padding size, used for union with bounds
|
||||||
// further down
|
// further down
|
||||||
var joinBounds = new Rectangle(new Size(padding).multiply(2));
|
var joinBounds = new Rectangle(new Size(padding).multiply(2));
|
||||||
|
@ -2005,12 +2004,12 @@ var Path = this.Path = PathItem.extend(/** @lends Path# */{
|
||||||
addCap(segments[length - 1], cap, 1);
|
addCap(segments[length - 1], cap, 1);
|
||||||
}
|
}
|
||||||
return bounds;
|
return bounds;
|
||||||
},
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the bounding rectangle of the item including handles.
|
* Returns the bounding rectangle of the item including handles.
|
||||||
*/
|
*/
|
||||||
handleBounds: function(that, matrix, stroke, join) {
|
function getHandleBounds(that, matrix, stroke, join) {
|
||||||
var coords = new Array(6),
|
var coords = new Array(6),
|
||||||
x1 = Infinity,
|
x1 = Infinity,
|
||||||
x2 = -x1,
|
x2 = -x1,
|
||||||
|
@ -2037,22 +2036,28 @@ var Path = this.Path = PathItem.extend(/** @lends Path# */{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Rectangle.create(x1, y1, x2 - x1, y2 - y1);
|
return Rectangle.create(x1, y1, x2 - x1, y2 - y1);
|
||||||
},
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the rough bounding rectangle of the item that is shure to
|
* Returns the rough bounding rectangle of the item that is shure to include
|
||||||
* include all of the drawing, including stroke width.
|
* all of the drawing, including stroke width.
|
||||||
*/
|
*/
|
||||||
roughBounds: function(that, matrix) {
|
function getRoughBounds(that, matrix) {
|
||||||
// Delegate to handleBounds, but pass on radius values for stroke
|
// Delegate to handleBounds, but pass on radius values for stroke and
|
||||||
// and joins. Hanlde miter joins specially, by passing the largets
|
// joins. Hanlde miter joins specially, by passing the largets radius
|
||||||
// radius possible.
|
// possible.
|
||||||
var width = that.getStrokeWidth();
|
var width = that.getStrokeWidth();
|
||||||
return get.handleBounds(that, matrix, width,
|
return getHandleBounds(that, matrix, width,
|
||||||
that.getStrokeJoin() == 'miter'
|
that.getStrokeJoin() == 'miter'
|
||||||
? width * that.getMiterLimit()
|
? width * that.getMiterLimit()
|
||||||
: width);
|
: width);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var get = {
|
||||||
|
bounds: getBounds,
|
||||||
|
strokeBounds: getStrokeBounds,
|
||||||
|
handleBounds: getHandleBounds,
|
||||||
|
roughBounds: getRoughBounds
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
Loading…
Reference in a new issue