Seperate Path definition into two parts, one that requires scoped private functions and values, and one that does not, to keep related things closer together and save indentation space.

This commit is contained in:
Jürg Lehni 2011-02-17 20:08:37 +00:00
parent 19121c33b2
commit 5850ef3cfc

View file

@ -1,41 +1,4 @@
Path = PathItem.extend(new function() {
var styleNames = {
fillColor: 'fillStyle',
strokeColor: 'strokeStyle',
strokeWidth: 'lineWidth',
strokeJoin: 'lineJoin',
strokeCap: 'lineCap',
miterLimit: 'miterLimit'
};
/**
* Solves a tri-diagonal system for one of coordinates (x or y) of first
* bezier control points.
*
* @param rhs right hand side vector.
* @return Solution vector.
*/
var getFirstControlPoints = function(rhs) {
var n = rhs.length;
var x = []; // Solution vector.
var tmp = []; // Temporary workspace.
var b = 2;
x[0] = rhs[0] / b;
// Decomposition and forward substitution.
for (var i = 1; i < n; i++) {
tmp[i] = 1 / b;
b = (i < n - 1 ? 4.0 : 2.0) - tmp[i];
x[i] = (rhs[i] - x[i - 1]) / b;
}
// Back-substitution.
for (var i = 1; i < n; i++) {
x[n - i - 1] -= tmp[n - i] * x[n - i];
}
return x;
};
return {
Path = PathItem.extend({
beans: true,
initialize: function(/* segments */) {
@ -64,7 +27,7 @@ Path = PathItem.extend(new function() {
this._segments = segments;
},
/*
/**
* The bounding rectangle of the item excluding stroke width.
*/
getBounds: function() {
@ -358,6 +321,92 @@ Path = PathItem.extend(new function() {
}
},
curveBy: function(throughVector, toVector, parameter) {
throughVector = Point.read(throughVector);
toVector = Point.read(toVector);
var current = this.currentSegment.point;
this.curveTo(current.add(throughVector), current.add(toVector), parameter);
},
arcBy: function(throughVector, toVector) {
throughVector = Point.read(throughVector);
toVector = Point.read(toVector);
var current = this.currentSegment.point;
this.arcBy(current.add(throughVector), current.add(toVector));
},
draw: function(ctx, compound) {
if (!this.visible) return;
if(!compound)
ctx.beginPath();
var cp1;
for (var i = 0, l = this._segments.length; i < l; i++) {
var segment = this._segments[i];
var point = segment.point;
var handleIn = segment.handleIn.add(point);
var handleOut = segment.handleOut.add(point);
if (i == 0) {
ctx.moveTo(point.x, point.y);
} else {
ctx.bezierCurveTo(cp1.x, cp1.y, handleIn.x, handleIn.y,
point.x, point.y);
}
cp1 = handleOut;
}
if (this.closed && this._segments.length > 1) {
var segment = this._segments[0];
var point = segment.point;
var handleIn = segment.handleIn.add(point);
ctx.bezierCurveTo(cp1.x, cp1.y, handleIn.x, handleIn.y,
point.x, point.y);
ctx.closePath();
}
if(!compound) {
this.setCtxStyles(ctx);
if (this.fillColor) ctx.fill();
if (this.strokeColor) ctx.stroke();
}
}
});
// Now inject methods that require scoped private functions and values.
Path.inject(new function() {
/**
* Solves a tri-diagonal system for one of coordinates (x or y) of first
* bezier control points.
*
* @param rhs right hand side vector.
* @return Solution vector.
*/
var getFirstControlPoints = function(rhs) {
var n = rhs.length;
var x = []; // Solution vector.
var tmp = []; // Temporary workspace.
var b = 2;
x[0] = rhs[0] / b;
// Decomposition and forward substitution.
for (var i = 1; i < n; i++) {
tmp[i] = 1 / b;
b = (i < n - 1 ? 4.0 : 2.0) - tmp[i];
x[i] = (rhs[i] - x[i - 1]) / b;
}
// Back-substitution.
for (var i = 1; i < n; i++) {
x[n - i - 1] -= tmp[n - i] * x[n - i];
}
return x;
};
var styleNames = {
fillColor: 'fillStyle',
strokeColor: 'strokeStyle',
strokeWidth: 'lineWidth',
strokeJoin: 'lineJoin',
strokeCap: 'lineCap',
miterLimit: 'miterLimit'
};
return {
smooth: function() {
var segments = this._segments;
@ -387,8 +436,8 @@ Path = PathItem.extend(new function() {
for (var i = 0; i < size; i++)
knots[i + overlap] = segments[i].point;
if (this.closed) {
// If we're averaging, add the 4 last points again at the beginning,
// and the 4 first ones at the end.
// If we're averaging, add the 4 last points again at the
// beginning, and the 4 first ones at the end.
for (var i = 0; i < overlap; i++) {
knots[i] = segments[i + size - overlap].point;
knots[i + size + overlap] = segments[i].point;
@ -457,59 +506,12 @@ Path = PathItem.extend(new function() {
}
},
curveBy: function(throughVector, toVector, parameter) {
throughVector = Point.read(throughVector);
toVector = Point.read(toVector);
var current = this.currentSegment.point;
this.curveTo(current.add(throughVector), current.add(toVector), parameter);
},
arcBy: function(throughVector, toVector) {
throughVector = Point.read(throughVector);
toVector = Point.read(toVector);
var current = this.currentSegment.point;
this.arcBy(current.add(throughVector), current.add(toVector));
},
setCtxStyles: function(ctx) {
for (var i in styleNames) {
var style;
if (style = this[i])
ctx[styleNames[i]] = style;
}
},
draw: function(ctx, compound) {
if (!this.visible) return;
if(!compound)
ctx.beginPath();
var cp1;
for (var i = 0, l = this._segments.length; i < l; i++) {
var segment = this._segments[i];
var point = segment.point;
var handleIn = segment.handleIn.add(point);
var handleOut = segment.handleOut.add(point);
if (i == 0) {
ctx.moveTo(point.x, point.y);
} else {
ctx.bezierCurveTo(cp1.x, cp1.y, handleIn.x, handleIn.y,
point.x, point.y);
}
cp1 = handleOut;
}
if (this.closed && this._segments.length > 1) {
var segment = this._segments[0];
var point = segment.point;
var handleIn = segment.handleIn.add(point);
ctx.bezierCurveTo(cp1.x, cp1.y, handleIn.x, handleIn.y,
point.x, point.y);
ctx.closePath();
}
if(!compound) {
this.setCtxStyles(ctx);
if (this.fillColor) ctx.fill();
if (this.strokeColor) ctx.stroke();
}
}
}
});