Cleanup Path constructors by using simple constructor functions instead of Base.extend() classes, use Path.Oval for Path.Circle and optimise Path.Oval through ovalSegments array with real segments (no use to call Segment.read each time).

This commit is contained in:
Jürg Lehni 2011-02-14 02:05:54 +00:00
parent 12d82ece56
commit a6e9ee56d4

View file

@ -1,11 +1,20 @@
Path = PathItem.extend({ Path = PathItem.extend(new function() {
initialize: function() { var kappa = 2 / 3 * (Math.sqrt(2) - 1);
this.base.apply(this, arguments);
}, var ovalSegments = [
new Segment([0, 0.5], [0, kappa ], [0, -kappa]),
statics: { new Segment([0.5, 0], [-kappa, 0], [kappa, 0 ]),
Line: Base.extend({ new Segment([1, 0.5], [0, -kappa], [0, kappa ]),
initialize: function() { new Segment([0.5, 1], [kappa, 0 ], [-kappa, 0])
];
return {
initialize: function() {
this.base.apply(this, arguments);
},
statics: {
Line: function() {
var path = new Path(); var path = new Path();
if (arguments.length == 2) { if (arguments.length == 2) {
path.addSegment(new Segment(arguments[0])); path.addSegment(new Segment(arguments[0]));
@ -15,11 +24,9 @@ Path = PathItem.extend({
path.addSegment(Segment.read(arguments[2], arguments[3])); path.addSegment(Segment.read(arguments[2], arguments[3]));
} }
return path; return path;
} },
}),
Rectangle: function() {
Rectangle: Base.extend({
initialize: function() {
var path = new Path(); var path = new Path();
path.closed = true; path.closed = true;
var rectangle = Rectangle.read(arguments); var rectangle = Rectangle.read(arguments);
@ -28,79 +35,62 @@ Path = PathItem.extend({
path.add(rectangle[corners[i]]); path.add(rectangle[corners[i]]);
} }
return path; return path;
} },
}),
RoundRectangle: Base.extend(new function() {
var u = 4 / 3 * (Math.sqrt(2) - 1);
return {
initialize: function() {
var path = new Path();
var rect, size;
if (arguments.length == 2) {
rect = new Rectangle(arguments[0]);
size = new Size(arguments[1]);
} else {
rect = new Rectangle(arguments[0], arguments[1],
arguments[2], arguments[3]);
size = new Size(arguments[4], arguments[5]);
}
size = Size.min(size, rect.size.divide(2));
uSize = size.multiply(u);
var bl = rect.bottomLeft; RoundRectangle: function() {
path.add(bl.add(size.width, 0), null, [-uSize.width, 0]);
path.add(bl.subtract(0, size.height), [0, uSize.height], null);
var tl = rect.topLeft;
path.add(tl.add(0, size.height), null, [0, -uSize.height]);
path.add(tl.add(size.width, 0), [-uSize.width, 0], null);
var tr = rect.topRight;
path.add(tr.subtract(size.width, 0), null, [uSize.width, 0]);
path.add(tr.add(0, size.height), [0, -uSize.height], null);
var br = rect.bottomRight;
path.add(br.subtract(0, size.height), null, [0, uSize.height]);
path.add(br.subtract(size.width, 0), [uSize.width, 0], null);
path.closed = true;
return path;
}
}
}),
Oval: Base.extend(new function() {
var u = 2 / 3 * (Math.sqrt(2) - 1);
var segments = [
{ handleOut: [0, -u], handleIn: [0, u], point: [ 0, 0.5] },
{ handleOut: [u, 0], handleIn: [-u, 0], point: [ 0.5, 0] },
{ handleOut: [0, u], handleIn: [0, -u], point: [ 1, 0.5] },
{ handleOut: [-u, 0], handleIn: [u, 0], point: [0.5, 1] }
];
return {
initialize: function() {
var path = new Path();
var rect = Rectangle.read(arguments);
var topLeft = rect.topLeft;
var size = new Size(rect.width, rect.height);
for (var i = 0; i < 4; i++) {
var segment = Segment.read([segments[i]]);
segment.handleIn = segment.handleIn.multiply(size);
segment.handleOut = segment.handleOut.multiply(size);
segment.point = segment.point.multiply(size).add(topLeft);
path._segments.push(segment);
}
path.closed = true;
return path;
}
}
}),
Circle: Base.extend({
initialize: function() {
var path = new Path(); var path = new Path();
var rect, size;
if (arguments.length == 2) {
rect = new Rectangle(arguments[0]);
size = new Size(arguments[1]);
} else {
rect = new Rectangle(arguments[0], arguments[1],
arguments[2], arguments[3]);
size = new Size(arguments[4], arguments[5]);
}
size = Size.min(size, rect.size.divide(2));
uSize = size.multiply(kappa * 2);
var bl = rect.bottomLeft;
path.add(bl.add(size.width, 0), null, [-uSize.width, 0]);
path.add(bl.subtract(0, size.height), [0, uSize.height], null);
var tl = rect.topLeft;
path.add(tl.add(0, size.height), null, [0, -uSize.height]);
path.add(tl.add(size.width, 0), [-uSize.width, 0], null);
var tr = rect.topRight;
path.add(tr.subtract(size.width, 0), null, [uSize.width, 0]);
path.add(tr.add(0, size.height), [0, -uSize.height], null);
var br = rect.bottomRight;
path.add(br.subtract(0, size.height), null, [0, uSize.height]);
path.add(br.subtract(size.width, 0), [uSize.width, 0], null);
path.closed = true;
return path;
},
Oval: function() {
var path = new Path();
var rect = Rectangle.read(arguments);
var topLeft = rect.topLeft;
var size = new Size(rect.width, rect.height);
for (var i = 0; i < 4; i++) {
var segment = ovalSegments[i];
path.addSegment(new Segment(
segment.point.multiply(size).add(topLeft),
segment.handleIn.multiply(size),
segment.handleOut.multiply(size)
));
}
path.closed = true;
return path;
},
Circle: function() {
var center, radius; var center, radius;
// TODO: Have Point.read() return consumed index somehow?
if (arguments.length == 3) { if (arguments.length == 3) {
center = new Point(arguments[0], arguments[1]); center = new Point(arguments[0], arguments[1]);
radius = arguments[2]; radius = arguments[2];
@ -108,24 +98,16 @@ Path = PathItem.extend({
center = new Point(arguments[0]); center = new Point(arguments[0]);
radius = arguments[1]; radius = arguments[1];
} }
var left = center.subtract(radius, 0); return Path.Oval(new Rectangle(center.subtract(radius),
path.moveTo(left); new Size(radius * 2, radius * 2)));
path.arcTo(center.add(radius, 0), true); },
path.arcTo(left, true);
var last = path._segments.pop(); Arc: function(from, through, to) {
path._segments[0].handleIn = last.handleIn;
path.closed = true;
return path;
}
}),
Arc: PathItem.extend({
initialize: function(from, through, to) {
var path = new Path(); var path = new Path();
path.moveTo(from); path.moveTo(from);
path.arcTo(through, to); path.arcTo(through, to);
return path; return path;
} }
}) }
} }
}); });