paper.js/src/path/Path.Constructors.js

449 lines
13 KiB
JavaScript
Raw Normal View History

2011-03-06 19:50:44 -05:00
/*
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
2011-03-07 20:41:50 -05:00
* http://paperjs.org/
*
2014-01-03 19:47:16 -05:00
* Copyright (c) 2011 - 2014, Juerg Lehni & Jonathan Puckey
* http://scratchdisk.com/ & http://jonathanpuckey.com/
*
2011-07-01 06:17:45 -04:00
* Distributed under the MIT license. See LICENSE file for details.
*
2011-03-07 20:41:50 -05:00
* All rights reserved.
2011-03-06 19:50:44 -05:00
*/
Path.inject({ statics: new function() {
2013-10-16 07:26:08 -04:00
var kappa = Numerical.KAPPA,
ellipseSegments = [
new Segment([-1, 0], [0, kappa ], [0, -kappa]),
new Segment([0, -1], [-kappa, 0], [kappa, 0 ]),
new Segment([1, 0], [0, -kappa], [0, kappa ]),
new Segment([0, 1], [kappa, 0 ], [-kappa, 0])
2013-10-16 07:26:08 -04:00
];
function createEllipse(center, radius, args) {
var path = new Path(),
segments = new Array(4);
for (var i = 0; i < 4; i++) {
var segment = ellipseSegments[i];
segments[i] = new Segment(
segment._point.multiply(radius).add(center),
segment._handleIn.multiply(radius),
segment._handleOut.multiply(radius)
);
}
path._add(segments);
path._closed = true;
// Set named arguments at the end, since some depend on geometry to be
// defined (e.g. #clockwise)
return path.set(Base.getNamed(args));
}
2013-10-16 08:19:25 -04:00
2011-06-22 18:58:50 -04:00
return /** @lends Path */{
2011-05-23 08:33:22 -04:00
/**
* {@grouptitle Shaped Paths}
2011-06-27 06:31:39 -04:00
*
2013-10-16 08:19:25 -04:00
* Creates a linear path item from two points describing a line.
*
2013-03-10 14:09:09 -04:00
* @name Path.Line
2013-10-16 08:19:25 -04:00
* @param {Point} from the line's starting point
* @param {Point} to the line's ending point
2011-05-23 08:33:22 -04:00
* @return {Path} the newly created path
*
* @example {@paperscript}
* var from = new Point(20, 20);
* var to = new Point(80, 80);
* var path = new Path.Line(from, to);
* path.strokeColor = 'black';
2013-10-16 08:19:25 -04:00
*/
/**
* Creates a linear path item from the properties described by an object
* literal.
*
* @name Path.Line
* @param {Object} object an object literal containing properties
* describing the path's attributes
* @return {Path} the newly created path
*
* @example {@paperscript}
* var path = new Path.Line({
2013-03-10 14:09:09 -04:00
* from: [20, 20],
* to: [80, 80],
* strokeColor: 'black'
* });
2011-05-23 08:33:22 -04:00
*/
2012-12-30 12:33:46 -05:00
Line: function(/* from, to */) {
return new Path(
Point.readNamed(arguments, 'from'),
Point.readNamed(arguments, 'to')
).set(Base.getNamed(arguments));
},
/**
2013-10-16 08:19:25 -04:00
* Creates a circular path item.
*
2013-10-16 08:19:25 -04:00
* @name Path.Circle
* @param {Point} center the center point of the circle
* @param {Number} radius the radius of the circle
* @return {Path} the newly created path
*
* @example {@paperscript}
* var path = new Path.Circle(new Point(80, 50), 30);
* path.strokeColor = 'black';
2013-10-16 08:19:25 -04:00
*/
/**
* Creates a circular path item from the properties described by an
* object literal.
*
* @name Path.Circle
* @param {Object} object an object literal containing properties
* describing the path's attributes
* @return {Path} the newly created path
*
2013-10-16 08:19:25 -04:00
* @example {@paperscript}
* var path = new Path.Circle({
* center: [80, 50],
* radius: 30,
* strokeColor: 'black'
* });
*/
Circle: function(/* center, radius */) {
var center = Point.readNamed(arguments, 'center'),
radius = Base.readNamed(arguments, 'radius');
return createEllipse(center, new Size(radius), arguments);
},
2011-05-23 08:33:22 -04:00
/**
2013-10-16 08:19:25 -04:00
* Creates a rectangular path item, with optionally rounded corners.
*
* @name Path.Rectangle
2013-10-16 08:19:25 -04:00
* @param {Rectangle} rectangle the rectangle object describing the
* geometry of the rectangular path to be created.
* @param {Size} [radius=null] the size of the rounded corners
* @return {Path} the newly created path
*
* @example {@paperscript}
* var rectangle = new Rectangle(new Point(20, 20), new Size(60, 60));
* var path = new Path.Rectangle(rectangle);
* path.strokeColor = 'black';
*
* @example {@paperscript} // The same, with rounder corners
* var rectangle = new Rectangle(new Point(20, 20), new Size(60, 60));
* var cornerSize = new Size(10, 10);
* var path = new Path.Rectangle(rectangle, cornerSize);
* path.strokeColor = 'black';
*/
/**
* Creates a rectangular path item from a point and a size object.
*
* @name Path.Rectangle
* @param {Point} point the rectangle's top-left corner.
* @param {Size} size the rectangle's size.
2011-05-23 08:33:22 -04:00
* @return {Path} the newly created path
*
* @example {@paperscript}
* var point = new Point(20, 20);
* var size = new Size(60, 60);
2013-03-10 14:09:09 -04:00
* var path = new Path.Rectangle(point, size);
* path.strokeColor = 'black';
2011-05-23 08:33:22 -04:00
*/
/**
2013-10-16 08:19:25 -04:00
* Creates a rectangular path item from the passed points. These do not
* necessarily need to be the top left and bottom right corners, the
2011-05-23 08:33:22 -04:00
* constructor figures out how to fit a rectangle between them.
*
* @name Path.Rectangle
2013-10-16 08:19:25 -04:00
* @param {Point} from the first point defining the rectangle
* @param {Point} to the second point defining the rectangle
2011-05-23 08:33:22 -04:00
* @return {Path} the newly created path
*
* @example {@paperscript}
* var from = new Point(20, 20);
* var to = new Point(80, 80);
* var path = new Path.Rectangle(from, to);
* path.strokeColor = 'black';
2011-05-23 08:33:22 -04:00
*/
/**
2013-10-16 08:19:25 -04:00
* Creates a rectangular path item from the properties described by an
* object literal.
*
* @name Path.Rectangle
2013-10-16 08:19:25 -04:00
* @param {Object} object an object literal containing properties
* describing the path's attributes
* @return {Path} the newly created path
*
* @example {@paperscript}
2013-10-16 08:19:25 -04:00
* var path = new Path.Rectangle({
* point: [20, 20],
* size: [60, 60],
* strokeColor: 'black'
* });
2013-03-10 14:09:09 -04:00
*
* @example {@paperscript}
* var path = new Path.Rectangle({
2013-10-16 08:19:25 -04:00
* from: [20, 20],
* to: [80, 80],
2013-03-10 14:09:09 -04:00
* strokeColor: 'black'
* });
*
* @example {@paperscript}
* var path = new Path.Rectangle({
2013-03-10 14:09:09 -04:00
* rectangle: {
2013-10-16 08:19:25 -04:00
* topLeft: [20, 20],
* bottomRight: [80, 80]
2013-03-10 14:09:09 -04:00
* },
2013-10-16 08:19:25 -04:00
* strokeColor: 'black'
* });
*
* @example {@paperscript}
* var path = new Path.Rectangle({
* topLeft: [20, 20],
* bottomRight: [80, 80],
2013-03-10 14:09:09 -04:00
* radius: 10,
* strokeColor: 'black'
* });
2011-05-23 08:33:22 -04:00
*/
2013-10-16 07:26:08 -04:00
Rectangle: function(/* rectangle */) {
var rect = Rectangle.readNamed(arguments, 'rectangle'),
radius = Size.readNamed(arguments, 'radius', 0, 0,
{ readNull: true }),
bl = rect.getBottomLeft(true),
tl = rect.getTopLeft(true),
tr = rect.getTopRight(true),
br = rect.getBottomRight(true);
path = new Path();
2013-10-16 07:26:08 -04:00
if (!radius || radius.isZero()) {
path._add([
new Segment(bl),
new Segment(tl),
new Segment(tr),
new Segment(br)
]);
} else {
radius = Size.min(radius, rect.getSize(true).divide(2));
var rx = radius.width,
ry = radius.height,
hx = rx * kappa,
hy = ry * kappa;
path._add([
new Segment(bl.add(rx, 0), null, [-hx, 0]),
new Segment(bl.subtract(0, ry), [0, hy]),
new Segment(tl.add(0, ry), null, [0, -hy]),
new Segment(tl.add(rx, 0), [-hx, 0], null),
new Segment(tr.subtract(rx, 0), null, [hx, 0]),
new Segment(tr.add(0, ry), [0, -hy], null),
new Segment(br.subtract(0, ry), null, [0, hy]),
new Segment(br.subtract(rx, 0), [hx, 0])
]);
}
// No need to use setter for _closed since _add() called _changed().
path._closed = true;
return path.set(Base.getNamed(arguments));
2013-10-16 07:26:08 -04:00
},
/**
* @deprecated use {@link #Path.Rectangle(rectangle, size)} instead.
*/
2013-10-16 07:26:08 -04:00
RoundRectangle: '#Rectangle',
2011-05-23 08:33:22 -04:00
/**
2013-10-16 08:19:25 -04:00
* Creates an elliptical path item.
*
2013-10-16 08:19:25 -04:00
* @name Path.Ellipse
* @param {Rectangle} rectangle the rectangle circumscribing the ellipse
2011-05-23 08:33:22 -04:00
* @return {Path} the newly created path
*
* @example {@paperscript}
2013-10-16 08:19:25 -04:00
* var rectangle = new Rectangle(new Point(20, 20), new Size(180, 60));
* var path = new Path.Ellipse(rectangle);
* path.fillColor = 'black';
2013-10-16 08:19:25 -04:00
*/
/**
* Creates an elliptical path item from the properties described by an
* object literal.
*
* @name Path.Ellipse
* @param {Object} object an object literal containing properties
* describing the path's attributes
* @return {Path} the newly created path
2013-03-10 14:09:09 -04:00
*
2013-10-16 08:19:25 -04:00
* @example {@paperscript}
2013-03-10 14:09:09 -04:00
* var path = new Path.Ellipse({
* point: [20, 20],
* size: [180, 60],
* fillColor: 'black'
* });
2013-10-16 09:03:29 -04:00
*
* @example {@paperscript} // Placing by center and radius
* var shape = new Path.Ellipse({
* center: [110, 50],
* radius: [90, 30],
* fillColor: 'black'
* });
2011-05-23 08:33:22 -04:00
*/
2013-10-16 07:26:08 -04:00
Ellipse: function(/* rectangle */) {
var ellipse = Shape._readEllipse(arguments);
return createEllipse(ellipse.center, ellipse.radius, arguments);
2013-10-16 07:26:08 -04:00
},
/**
* @deprecated use {@link #Path.Ellipse(rectangle)} instead.
*/
2013-10-16 07:26:08 -04:00
Oval: '#Ellipse',
2011-05-23 08:33:22 -04:00
/**
2013-10-16 08:19:25 -04:00
* Creates a circular arc path item.
*
2013-10-16 08:19:25 -04:00
* @name Path.Arc
2011-05-23 08:33:22 -04:00
* @param {Point} from the starting point of the circular arc
* @param {Point} through the point the arc passes through
* @param {Point} to the end point of the arc
* @return {Path} the newly created path
*
* @example {@paperscript}
* var from = new Point(20, 20);
* var through = new Point(60, 20);
* var to = new Point(80, 80);
* var path = new Path.Arc(from, through, to);
* path.strokeColor = 'black';
2013-03-10 14:09:09 -04:00
*
2013-10-16 08:19:25 -04:00
*/
/**
* Creates an circular arc path item from the properties described by an
* object literal.
*
* @name Path.Arc
* @param {Object} object an object literal containing properties
* describing the path's attributes
* @return {Path} the newly created path
*
* @example {@paperscript}
2013-03-10 14:09:09 -04:00
* var path = new Path.Arc({
* from: [20, 20],
* through: [60, 20],
* to: [80, 80],
* strokeColor: 'black'
* });
2011-05-23 08:33:22 -04:00
*/
2012-12-30 12:33:46 -05:00
Arc: function(/* from, through, to */) {
var from = Point.readNamed(arguments, 'from'),
through = Point.readNamed(arguments, 'through'),
to = Point.readNamed(arguments, 'to'),
path = new Path();
2012-12-30 12:33:46 -05:00
path.moveTo(from);
path.arcTo(through, to);
return path.set(Base.getNamed(arguments));
},
2011-05-23 08:33:22 -04:00
/**
2013-10-16 08:19:25 -04:00
* Creates a regular polygon shaped path item.
*
2013-10-16 08:19:25 -04:00
* @name Path.RegularPolygon
2011-05-23 08:33:22 -04:00
* @param {Point} center the center point of the polygon
* @param {Number} sides the number of sides of the polygon
* @param {Number} radius the radius of the polygon
2011-05-23 08:33:22 -04:00
* @return {Path} the newly created path
*
* @example {@paperscript}
* var center = new Point(50, 50);
* var sides = 3;
* var radius = 40;
* var triangle = new Path.RegularPolygon(center, sides, radius);
* triangle.fillColor = 'black';
2013-10-16 08:19:25 -04:00
*/
/**
* Creates a regular polygon shaped path item from the properties
* described by an object literal.
*
2013-10-16 08:19:25 -04:00
* @name Path.RegularPolygon
* @param {Object} object an object literal containing properties
* describing the path's attributes
* @return {Path} the newly created path
*
* @example {@paperscript}
2013-03-10 14:09:09 -04:00
* var triangle = new Path.RegularPolygon({
* center: [50, 50],
* sides: 10,
* radius: 40,
* fillColor: 'black'
* });
2011-05-23 08:33:22 -04:00
*/
RegularPolygon: function(/* center, sides, radius */) {
2012-12-30 12:33:46 -05:00
var center = Point.readNamed(arguments, 'center'),
sides = Base.readNamed(arguments, 'sides'),
2012-12-30 12:33:46 -05:00
radius = Base.readNamed(arguments, 'radius'),
path = new Path(),
step = 360 / sides,
three = !(sides % 3),
2012-12-30 12:33:46 -05:00
vector = new Point(0, three ? -radius : radius),
offset = three ? -1 : 0.5,
segments = new Array(sides);
for (var i = 0; i < sides; i++) {
2012-12-30 12:33:46 -05:00
segments[i] = new Segment(center.add(
vector.rotate((i + offset) * step)));
}
path._add(segments);
path._closed = true;
return path.set(Base.getNamed(arguments));
},
2011-05-23 08:33:22 -04:00
/**
2013-10-16 08:19:25 -04:00
* Creates a star shaped path item.
*
2011-05-23 08:33:22 -04:00
* The largest of {@code radius1} and {@code radius2} will be the outer
* radius of the star. The smallest of radius1 and radius2 will be the
* inner radius.
*
2013-10-16 08:19:25 -04:00
* @name Path.Star
2011-05-23 08:33:22 -04:00
* @param {Point} center the center point of the star
* @param {Number} points the number of points of the star
* @param {Number} radius1
* @param {Number} radius2
2011-05-23 08:33:22 -04:00
* @return {Path} the newly created path
*
* @example {@paperscript}
* var center = new Point(50, 50);
* var points = 12;
* var radius1 = 25;
* var radius2 = 40;
* var path = new Path.Star(center, points, radius1, radius2);
* path.fillColor = 'black';
2013-10-16 08:19:25 -04:00
*/
/**
* Creates a star shaped path item from the properties described by an
* object literal.
2013-03-10 14:09:09 -04:00
*
2013-10-16 08:19:25 -04:00
* @name Path.Star
* @param {Object} object an object literal containing properties
* describing the path's attributes
* @return {Path} the newly created path
*
* @example {@paperscript}
2013-03-10 14:09:09 -04:00
* var path = new Path.Star({
* center: [50, 50],
* points: 12,
* radius1: 25,
* radius2: 40,
* fillColor: 'black'
* });
*/
Star: function(/* center, points, radius1, radius2 */) {
2012-12-30 12:33:46 -05:00
var center = Point.readNamed(arguments, 'center'),
points = Base.readNamed(arguments, 'points') * 2,
2012-12-30 12:33:46 -05:00
radius1 = Base.readNamed(arguments, 'radius1'),
radius2 = Base.readNamed(arguments, 'radius2'),
path = new Path(),
step = 360 / points,
vector = new Point(0, -1),
segments = new Array(points);
for (var i = 0; i < points; i++) {
2012-12-30 12:33:46 -05:00
segments[i] = new Segment(center.add(
vector.rotate(step * i).multiply(i % 2 ? radius2 : radius1)));
}
path._add(segments);
path._closed = true;
return path.set(Base.getNamed(arguments));
}
};
}});