Merge Path.Rectangle and Path.RoundRectangle.

This commit is contained in:
Jürg Lehni 2013-04-19 12:36:49 -07:00
parent 922b9b5bd0
commit 9efbc288a1
14 changed files with 65 additions and 69 deletions

View file

@ -38,7 +38,7 @@
var size4 = new Size(100, 100); var size4 = new Size(100, 100);
var rectangle4 = new Rectangle(point4, size4); var rectangle4 = new Rectangle(point4, size4);
var cornerSize4 = new Size(30, 30); var cornerSize4 = new Size(30, 30);
var path4 = new Path.RoundRectangle(rectangle4, cornerSize4); var path4 = new Path.Rectangle(rectangle4, cornerSize4);
path4.strokeColor= 'yellow'; path4.strokeColor= 'yellow';
path4.fillColor='purple'; path4.fillColor='purple';

View file

@ -26,7 +26,7 @@
circle.scale(0.5, 1); circle.scale(0.5, 1);
circle.rotate(40); circle.rotate(40);
var rect = new Path.RoundRectangle(250, 20, 200, 300, 40, 20); var rect = new Path.Rectangle(250, 20, 200, 300, 40, 20);
rect.fillColor = 'yellow'; rect.fillColor = 'yellow';
rect.rotate(-20); rect.rotate(-20);

View file

@ -13,7 +13,7 @@
for (var i = 0; i < amount; i++) { for (var i = 0; i < amount; i++) {
var rect = new Rectangle([0, 0], [25, 25]); var rect = new Rectangle([0, 0], [25, 25]);
rect.center = mousePoint; rect.center = mousePoint;
var path = new Path.RoundRectangle(rect, 6); var path = new Path.Rectangle(rect, 6);
path.fillColor = colors[i % 4]; path.fillColor = colors[i % 4];
var scale = (1 - i / amount) * 20; var scale = (1 - i / amount) * 20;
path.scale(scale); path.scale(scale);

View file

@ -38,7 +38,7 @@
var spacing = 5; var spacing = 5;
for (var i = 1; i <= amount; i++) { for (var i = 1; i <= amount; i++) {
var radius = 8 - (i / amount * 4); var radius = 8 - (i / amount * 4);
new Path.RoundRectangle({ new Path.Rectangle({
point: { point: {
length: spacing * Math.sqrt(i), length: spacing * Math.sqrt(i),
angle: i * rotation angle: i * rotation

View file

@ -38,7 +38,7 @@
var size4 = new Size(100, 100); var size4 = new Size(100, 100);
var rectangle4 = new Rectangle(point4, size4); var rectangle4 = new Rectangle(point4, size4);
var cornerSize4 = new Size(30, 30); var cornerSize4 = new Size(30, 30);
var path4 = new Path.RoundRectangle(rectangle4, cornerSize4); var path4 = new Path.Rectangle(rectangle4, cornerSize4);
path4.strokeColor= 'yellow'; path4.strokeColor= 'yellow';
path4.fillColor='purple'; path4.fillColor='purple';

View file

@ -26,7 +26,7 @@
circle.scale(0.5, 1); circle.scale(0.5, 1);
circle.rotate(40); circle.rotate(40);
var rect = new Path.RoundRectangle(250, 20, 200, 300, 40, 20); var rect = new Path.Rectangle(250, 20, 200, 300, 40, 20);
rect.fillColor = 'yellow'; rect.fillColor = 'yellow';
rect.rotate(-20); rect.rotate(-20);
rect.data = { rect.data = {

View file

@ -11,7 +11,7 @@
function onFrame(event) { function onFrame(event) {
if (path) if (path)
path.remove(); path.remove();
path = new Path.RoundRectangle({ path = new Path.Rectangle({
radius: Math.abs(Math.sin(event.count / 40)) * 150 + 10, radius: Math.abs(Math.sin(event.count / 40)) * 150 + 10,
rectangle: { rectangle: {
size: [300, 300] size: [300, 300]

View file

@ -235,9 +235,10 @@ this.Base = Base.inject(/** @lends Base# */{
* @param {Number} start the index at which to start reading in the list * @param {Number} start the index at which to start reading in the list
* @param {String} name the property name to read from. * @param {String} name the property name to read from.
*/ */
readNamed: function(list, name) { readNamed: function(list, name, start, length, clone, readNull) {
var value = this.getNamed(list, name); var value = this.getNamed(list, name);
return this.read(value != null ? [value] : list); return this.read(value != null ? [value] : list, start, length,
clone, readNull);
}, },
/** /**

View file

@ -22,17 +22,36 @@ Path.inject({ statics: new function() {
function createRectangle(/* rect */) { function createRectangle(/* rect */) {
var rect = Rectangle.readNamed(arguments, 'rectangle'), var rect = Rectangle.readNamed(arguments, 'rectangle'),
left = rect.getLeft(), radius = Size.readNamed(arguments, 'radius', 0, 0, false, true), // readNull
top = rect.getTop(), bl = rect.getBottomLeft(true),
right = rect.getRight(), tl = rect.getTopLeft(true),
bottom = rect.getBottom(), tr = rect.getTopRight(true),
br = rect.getBottomRight(true),
path = createPath(arguments); path = createPath(arguments);
path._add([ if (!radius || radius.isZero()) {
new Segment(Point.create(left, bottom)), path._add([
new Segment(Point.create(left, top)), new Segment(bl),
new Segment(Point.create(right, top)), new Segment(tl),
new Segment(Point.create(right, bottom)) new Segment(tr),
]); new Segment(br)
]);
} else {
radius = Size.min(radius, rect.getSize(true).divide(2));
var h = radius.multiply(kappa * 2); // handle vector
path._add([
new Segment(bl.add(radius.width, 0), null, [-h.width, 0]),
new Segment(bl.subtract(0, radius.height), [0, h.height], null),
new Segment(tl.add(0, radius.height), null, [0, -h.height]),
new Segment(tl.add(radius.width, 0), [-h.width, 0], null),
new Segment(tr.subtract(radius.width, 0), null, [h.width, 0]),
new Segment(tr.add(0, radius.height), [0, -h.height], null),
new Segment(br.subtract(0, radius.height), null, [0, h.height]),
new Segment(br.subtract(radius.width, 0), [h.width, 0], null)
]);
}
path._closed = true; path._closed = true;
return path; return path;
} }
@ -145,6 +164,7 @@ Path.inject({ statics: new function() {
* Creates a rectangle shaped Path Item from the passed abstract * Creates a rectangle shaped Path Item from the passed abstract
* {@link Rectangle}. * {@link Rectangle}.
* *
* @name Path.Rectangle
* @param {Rectangle} rectangle * @param {Rectangle} rectangle
* @return {Path} the newly created path * @return {Path} the newly created path
* *
@ -167,11 +187,10 @@ Path.inject({ statics: new function() {
* strokeColor: 'black' * strokeColor: 'black'
* }); * });
*/ */
Rectangle: createRectangle,
/** /**
* Creates a rectangular Path Item with rounded corners. * Creates a rectangular Path Item with rounded corners.
* *
* @name Path.Rectangle
* @param {Rectangle} rectangle * @param {Rectangle} rectangle
* @param {Size} radius the size of the rounded corners * @param {Size} radius the size of the rounded corners
* @return {Path} the newly created path * @return {Path} the newly created path
@ -182,11 +201,11 @@ Path.inject({ statics: new function() {
* size: new Size(60, 60) * size: new Size(60, 60)
* }); * });
* var cornerSize = new Size(10, 10); * var cornerSize = new Size(10, 10);
* var path = new Path.RoundRectangle(rectangle, cornerSize); * var path = new Path.Rectangle(rectangle, cornerSize);
* path.strokeColor = 'black'; * path.strokeColor = 'black';
* *
* @example {@paperscript} * @example {@paperscript}
* var path = new Path.RoundRectangle({ * var path = new Path.Rectangle({
* rectangle: { * rectangle: {
* point: [20, 20], * point: [20, 20],
* size: [60, 60] * size: [60, 60]
@ -195,37 +214,15 @@ Path.inject({ statics: new function() {
* strokeColor: 'black' * strokeColor: 'black'
* }); * });
*/ */
RoundRectangle: function(/* rect, radius */) { Rectangle: createRectangle,
var rect = Rectangle.readNamed(arguments, 'rectangle'),
radius = Size.readNamed(arguments, 'radius');
if (radius.isZero())
return createRectangle(rect);
radius = Size.min(radius, rect.getSize(true).divide(2));
var bl = rect.getBottomLeft(true),
tl = rect.getTopLeft(true),
tr = rect.getTopRight(true),
br = rect.getBottomRight(true),
h = radius.multiply(kappa * 2), // handle vector
path = createPath(arguments);
path._add([
new Segment(bl.add(radius.width, 0), null, [-h.width, 0]),
new Segment(bl.subtract(0, radius.height), [0, h.height], null),
new Segment(tl.add(0, radius.height), null, [0, -h.height]),
new Segment(tl.add(radius.width, 0), [-h.width, 0], null),
new Segment(tr.subtract(radius.width, 0), null, [h.width, 0]),
new Segment(tr.add(0, radius.height), [0, -h.height], null),
new Segment(br.subtract(0, radius.height), null, [0, h.height]),
new Segment(br.subtract(radius.width, 0), [h.width, 0], null)
]);
path._closed = true;
return path;
},
/** /**
* Creates an ellipse shaped Path Item. * @deprecated use {@link #Path.Rectangle(rectangle, size)} instead.
*/
RoundRectangle: createRectangle,
/**
* Creates an ellipse shaped Path Item.
* *
* @param {Rectangle} rectangle * @param {Rectangle} rectangle
* @param {Boolean} [circumscribed=false] when set to {@code true} the * @param {Boolean} [circumscribed=false] when set to {@code true} the
@ -252,7 +249,7 @@ Path.inject({ statics: new function() {
Ellipse: createEllipse, Ellipse: createEllipse,
/** /**
* @deprecated use {@link #Path.Ellipse(rect)} instead. * @deprecated use {@link #Path.Ellipse(rectangle)} instead.
*/ */
Oval: createEllipse, Oval: createEllipse,

View file

@ -238,9 +238,7 @@ new function() {
var point = getPoint(node, 'x', 'y'), var point = getPoint(node, 'x', 'y'),
size = getSize(node, 'width', 'height'), size = getSize(node, 'width', 'height'),
radius = getSize(node, 'rx', 'ry'); radius = getSize(node, 'rx', 'ry');
// If radius is 0, Path.RoundRectangle automatically produces a return new Path.Rectangle(new Rectangle(point, size), radius);
// normal rectangle for us.
return new Path.RoundRectangle(new Rectangle(point, size), radius);
}, },
// http://www.w3.org/TR/SVG/shapes.html#LineElement // http://www.w3.org/TR/SVG/shapes.html#LineElement

View file

@ -111,7 +111,7 @@ test('Rectangle testing', function() {
var size4 = new Size(100, 100); var size4 = new Size(100, 100);
var rectangle4 = new Rectangle(point4, size4); var rectangle4 = new Rectangle(point4, size4);
var cornerSize4 = new Size(30, 30); var cornerSize4 = new Size(30, 30);
var path4 = new Path.RoundRectangle(rectangle4, cornerSize4); var path4 = new Path.Rectangle(rectangle4, cornerSize4);
path4.strokeColor= 'yellow'; path4.strokeColor= 'yellow';
path4.fillColor='purple'; path4.fillColor='purple';
testExportImportJson(paper.project); testExportImportJson(paper.project);

View file

@ -41,27 +41,27 @@ test('new Path.Ellipse(rect)', function() {
equals(path.segments.toString(), '{ point: { x: 500, y: 875 }, handleIn: { x: 0, y: 207.10678 }, handleOut: { x: 0, y: -207.10678 } },{ point: { x: 1000, y: 500 }, handleIn: { x: -276.14237, y: 0 }, handleOut: { x: 276.14237, y: 0 } },{ point: { x: 1500, y: 875 }, handleIn: { x: 0, y: -207.10678 }, handleOut: { x: 0, y: 207.10678 } },{ point: { x: 1000, y: 1250 }, handleIn: { x: 276.14237, y: 0 }, handleOut: { x: -276.14237, y: 0 } }'); equals(path.segments.toString(), '{ point: { x: 500, y: 875 }, handleIn: { x: 0, y: 207.10678 }, handleOut: { x: 0, y: -207.10678 } },{ point: { x: 1000, y: 500 }, handleIn: { x: -276.14237, y: 0 }, handleOut: { x: 276.14237, y: 0 } },{ point: { x: 1500, y: 875 }, handleIn: { x: 0, y: -207.10678 }, handleOut: { x: 0, y: 207.10678 } },{ point: { x: 1000, y: 1250 }, handleIn: { x: 276.14237, y: 0 }, handleOut: { x: -276.14237, y: 0 } }');
}); });
test('new Path.RoundRectangle(rectangle, radius)', function() { test('new Path.Rectangle(rectangle, radius)', function() {
var rectangle = new Rectangle([50, 50], [200, 100]) var rectangle = new Rectangle([50, 50], [200, 100])
var path = new Path.RoundRectangle(rectangle, 20); var path = new Path.Rectangle(rectangle, 20);
equals(path.segments.toString(), '{ point: { x: 70, y: 150 }, handleOut: { x: -11.04569, y: 0 } },{ point: { x: 50, y: 130 }, handleIn: { x: 0, y: 11.04569 } },{ point: { x: 50, y: 70 }, handleOut: { x: 0, y: -11.04569 } },{ point: { x: 70, y: 50 }, handleIn: { x: -11.04569, y: 0 } },{ point: { x: 230, y: 50 }, handleOut: { x: 11.04569, y: 0 } },{ point: { x: 250, y: 70 }, handleIn: { x: 0, y: -11.04569 } },{ point: { x: 250, y: 130 }, handleOut: { x: 0, y: 11.04569 } },{ point: { x: 230, y: 150 }, handleIn: { x: 11.04569, y: 0 } }'); equals(path.segments.toString(), '{ point: { x: 70, y: 150 }, handleOut: { x: -11.04569, y: 0 } },{ point: { x: 50, y: 130 }, handleIn: { x: 0, y: 11.04569 } },{ point: { x: 50, y: 70 }, handleOut: { x: 0, y: -11.04569 } },{ point: { x: 70, y: 50 }, handleIn: { x: -11.04569, y: 0 } },{ point: { x: 230, y: 50 }, handleOut: { x: 11.04569, y: 0 } },{ point: { x: 250, y: 70 }, handleIn: { x: 0, y: -11.04569 } },{ point: { x: 250, y: 130 }, handleOut: { x: 0, y: 11.04569 } },{ point: { x: 230, y: 150 }, handleIn: { x: 11.04569, y: 0 } }');
}); });
test('new Path.RoundRectangle({ rectangle: rectangle, radius: radius })', function() { test('new Path.Rectangle({ rectangle: rectangle, radius: radius })', function() {
var rect = new Rectangle({ var rect = new Rectangle({
point: [50, 50], point: [50, 50],
size: [200, 100] size: [200, 100]
}); });
var path = new Path.RoundRectangle({ var path = new Path.Rectangle({
rectangle: rect, rectangle: rect,
radius: 20 radius: 20
}); });
equals(path.segments.toString(), '{ point: { x: 70, y: 150 }, handleOut: { x: -11.04569, y: 0 } },{ point: { x: 50, y: 130 }, handleIn: { x: 0, y: 11.04569 } },{ point: { x: 50, y: 70 }, handleOut: { x: 0, y: -11.04569 } },{ point: { x: 70, y: 50 }, handleIn: { x: -11.04569, y: 0 } },{ point: { x: 230, y: 50 }, handleOut: { x: 11.04569, y: 0 } },{ point: { x: 250, y: 70 }, handleIn: { x: 0, y: -11.04569 } },{ point: { x: 250, y: 130 }, handleOut: { x: 0, y: 11.04569 } },{ point: { x: 230, y: 150 }, handleIn: { x: 11.04569, y: 0 } }'); equals(path.segments.toString(), '{ point: { x: 70, y: 150 }, handleOut: { x: -11.04569, y: 0 } },{ point: { x: 50, y: 130 }, handleIn: { x: 0, y: 11.04569 } },{ point: { x: 50, y: 70 }, handleOut: { x: 0, y: -11.04569 } },{ point: { x: 70, y: 50 }, handleIn: { x: -11.04569, y: 0 } },{ point: { x: 230, y: 50 }, handleOut: { x: 11.04569, y: 0 } },{ point: { x: 250, y: 70 }, handleIn: { x: 0, y: -11.04569 } },{ point: { x: 250, y: 130 }, handleOut: { x: 0, y: 11.04569 } },{ point: { x: 230, y: 150 }, handleIn: { x: 11.04569, y: 0 } }');
}); });
test('new Path.RoundRectangle(rect, size) - too large size', function() { test('new Path.Rectangle(rect, size) - too large size', function() {
var rect = new Rectangle([50, 50], [200, 100]) var rect = new Rectangle([50, 50], [200, 100])
var path = new Path.RoundRectangle(rect, 200); var path = new Path.Rectangle(rect, 200);
equals(path.segments.toString(), '{ point: { x: 150, y: 150 }, handleOut: { x: -55.22847, y: 0 } },{ point: { x: 50, y: 100 }, handleIn: { x: 0, y: 27.61424 } },{ point: { x: 50, y: 100 }, handleOut: { x: 0, y: -27.61424 } },{ point: { x: 150, y: 50 }, handleIn: { x: -55.22847, y: 0 } },{ point: { x: 150, y: 50 }, handleOut: { x: 55.22847, y: 0 } },{ point: { x: 250, y: 100 }, handleIn: { x: 0, y: -27.61424 } },{ point: { x: 250, y: 100 }, handleOut: { x: 0, y: 27.61424 } },{ point: { x: 150, y: 150 }, handleIn: { x: 55.22847, y: 0 } }'); equals(path.segments.toString(), '{ point: { x: 150, y: 150 }, handleOut: { x: -55.22847, y: 0 } },{ point: { x: 50, y: 100 }, handleIn: { x: 0, y: 27.61424 } },{ point: { x: 50, y: 100 }, handleOut: { x: 0, y: -27.61424 } },{ point: { x: 150, y: 50 }, handleIn: { x: -55.22847, y: 0 } },{ point: { x: 150, y: 50 }, handleOut: { x: 55.22847, y: 0 } },{ point: { x: 250, y: 100 }, handleIn: { x: 0, y: -27.61424 } },{ point: { x: 250, y: 100 }, handleOut: { x: 0, y: 27.61424 } },{ point: { x: 150, y: 150 }, handleIn: { x: 55.22847, y: 0 } }');
}); });

View file

@ -234,7 +234,7 @@ test('compare rounded rectangle values', function() {
var size = new Size(width, height); var size = new Size(width, height);
var cornerSize = new Size(rx, ry); var cornerSize = new Size(rx, ry);
var rect = new Rectangle(topLeft, size); var rect = new Rectangle(topLeft, size);
var roundRect = new Path.RoundRectangle(rect, cornerSize); var roundRect = new Path.Rectangle(rect, cornerSize);
var exportedRectangle = rect.exportSvg(); var exportedRectangle = rect.exportSvg();
@ -278,7 +278,7 @@ test('compare negative rounded rectangle values', function() {
var size = new Size(width, height); var size = new Size(width, height);
var cornerSize = new Size(rx, ry); var cornerSize = new Size(rx, ry);
var rect = new Rectangle(topLeft, size); var rect = new Rectangle(topLeft, size);
var roundRect = new Path.RoundRectangle(rect, cornerSize); var roundRect = new Path.Rectangle(rect, cornerSize);
var exportedRectangle = rect.exportSvg(); var exportedRectangle = rect.exportSvg();
@ -322,7 +322,7 @@ test('compare invalid rounded rectangle values', function() {
var size = new Size(width, height); var size = new Size(width, height);
var cornerSize = new Size(rx, ry); var cornerSize = new Size(rx, ry);
var rect = new Rectangle(topLeft, size); var rect = new Rectangle(topLeft, size);
var roundRect = new Path.RoundRectangle(rect, cornerSize); var roundRect = new Path.Rectangle(rect, cornerSize);
var exportedRectangle = rect.exportSvg(); var exportedRectangle = rect.exportSvg();

View file

@ -138,7 +138,7 @@ test('compare round rectangle values', function() {
var size = new Size(width, height); var size = new Size(width, height);
var cornerSize = new Size(rx, ry); var cornerSize = new Size(rx, ry);
var rectangle = new Rectangle(topLeft, size); var rectangle = new Rectangle(topLeft, size);
var roundRect = new Path.RoundRectangle(rectangle, cornerSize); var roundRect = new Path.Rectangle(rectangle, cornerSize);
compareSegmentLists(importedRectangle.segments, roundRect.segments, true); compareSegmentLists(importedRectangle.segments, roundRect.segments, true);
}); });
@ -165,7 +165,7 @@ test('compare negative round rectangle values', function() {
var size = new Size(width, height); var size = new Size(width, height);
var cornerSize = new Size(rx, ry); var cornerSize = new Size(rx, ry);
var rectangle = new Rectangle(topLeft, size); var rectangle = new Rectangle(topLeft, size);
var roundRect = new Path.RoundRectangle(rectangle, cornerSize); var roundRect = new Path.Rectangle(rectangle, cornerSize);
compareSegmentLists(importedRectangle.segments, roundRect.segments, true); compareSegmentLists(importedRectangle.segments, roundRect.segments, true);
}); });
@ -192,7 +192,7 @@ test('compare invalid round rectangle values', function() {
var size = new Size(width, height); var size = new Size(width, height);
var cornerSize = new Size(rx, ry); var cornerSize = new Size(rx, ry);
var rectangle = new Rectangle(topLeft, size); var rectangle = new Rectangle(topLeft, size);
var roundRect = new Path.RoundRectangle(rectangle, cornerSize); var roundRect = new Path.Rectangle(rectangle, cornerSize);
compareSegmentLists(importedRectangle.segments, roundRect.segments, true); compareSegmentLists(importedRectangle.segments, roundRect.segments, true);
}); });