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({
initialize: function() {
this.base.apply(this, arguments);
},
statics: {
Line: Base.extend({
initialize: function() {
Path = PathItem.extend(new function() {
var kappa = 2 / 3 * (Math.sqrt(2) - 1);
var ovalSegments = [
new Segment([0, 0.5], [0, kappa ], [0, -kappa]),
new Segment([0.5, 0], [-kappa, 0], [kappa, 0 ]),
new Segment([1, 0.5], [0, -kappa], [0, kappa ]),
new Segment([0.5, 1], [kappa, 0 ], [-kappa, 0])
];
return {
initialize: function() {
this.base.apply(this, arguments);
},
statics: {
Line: function() {
var path = new Path();
if (arguments.length == 2) {
path.addSegment(new Segment(arguments[0]));
@ -15,11 +24,9 @@ Path = PathItem.extend({
path.addSegment(Segment.read(arguments[2], arguments[3]));
}
return path;
}
}),
Rectangle: Base.extend({
initialize: function() {
},
Rectangle: function() {
var path = new Path();
path.closed = true;
var rectangle = Rectangle.read(arguments);
@ -28,79 +35,62 @@ Path = PathItem.extend({
path.add(rectangle[corners[i]]);
}
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;
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() {
RoundRectangle: 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(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;
// TODO: Have Point.read() return consumed index somehow?
if (arguments.length == 3) {
center = new Point(arguments[0], arguments[1]);
radius = arguments[2];
@ -108,24 +98,16 @@ Path = PathItem.extend({
center = new Point(arguments[0]);
radius = arguments[1];
}
var left = center.subtract(radius, 0);
path.moveTo(left);
path.arcTo(center.add(radius, 0), true);
path.arcTo(left, true);
var last = path._segments.pop();
path._segments[0].handleIn = last.handleIn;
path.closed = true;
return path;
}
}),
Arc: PathItem.extend({
initialize: function(from, through, to) {
return Path.Oval(new Rectangle(center.subtract(radius),
new Size(radius * 2, radius * 2)));
},
Arc: function(from, through, to) {
var path = new Path();
path.moveTo(from);
path.arcTo(through, to);
return path;
}
})
}
}
});