paper.js/src/path/PathItem.js

388 lines
11 KiB
JavaScript
Raw Normal View History

2011-03-06 19:50:44 -05:00
/*
* Paper.js
*
2011-03-06 19:50:44 -05:00
* This file is part of Paper.js, a JavaScript Vector Graphics Library,
* based on Scriptographer.org and designed to be largely API compatible.
2011-03-07 20:41:50 -05:00
* http://paperjs.org/
2011-03-06 19:50:44 -05:00
* http://scriptographer.org/
*
2011-03-06 19:50:44 -05:00
* Copyright (c) 2011, Juerg Lehni & Jonathan Puckey
* http://lehni.org/ & 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
*/
/**
* @name PathItem
2011-07-01 05:22:33 -04:00
*
* @class The PathItem class is the base for any items that describe paths
* and offer standardised methods for drawing and path manipulation, such as
* {@link Path} and {@link CompoundPath}.
*
* @extends Item
*/
var PathItem = this.PathItem = Item.extend(/** @lends PathItem# */{
/**
* Returns all interesections between two {@link PathItem} items as an array
* of {@link CurveLocation} objects. {@link CompoundPath} items are also
* supported.
*
* @param {PathItem} the other item to find the intersections to.
* @return {CurveLocation[]} the locations of all intersection between the
* paths
*/
getIntersections: function(path) {
// First check the bounds of the two paths. If they don't intersect,
// we don't need to iterate through the whole path.
if (!this.getBounds().intersects(path.getBounds()))
return [];
var locations = [],
curves1 = this.getCurves(),
curves2 = path.getCurves(),
length2 = curves2.length,
values2 = [];
for (var i = 0; i < length2; i++)
values2[i] = curves2[i].getValues();
for (var i = 0, l = curves1.length; i < l; i++) {
var curve = curves1[i],
values1 = curve.getValues();
for (var j = 0; j < length2; j++)
Curve._addIntersections(values1, values2[j], curve, locations);
}
return locations;
}
/**
* Smooth bezier curves without changing the amount of segments or their
* points, by only smoothing and adjusting their handle points, for both
* open ended and closed paths.
*
* @name PathItem#smooth
* @function
*
* @example {@paperscript}
* // Smoothing a closed shape:
*
* // Create a rectangular path with its top-left point at
* // {x: 30, y: 25} and a size of {width: 50, height: 50}:
* var path = new Path.Rectangle(new Point(30, 25), new Size(50, 50));
* path.strokeColor = 'black';
*
* // Select the path, so we can see its handles:
* path.fullySelected = true;
*
* // Create a copy of the path and move it 100pt to the right:
* var copy = path.clone();
* copy.position.x += 100;
*
* // Smooth the segments of the copy:
* copy.smooth();
*
* @example {@paperscript height=220}
* var path = new Path();
* path.strokeColor = 'black';
*
* path.add(new Point(30, 50));
*
* var y = 5;
* var x = 3;
*
* for (var i = 0; i < 28; i++) {
* y *= -1.1;
* x *= 1.1;
* path.lineBy(x, y);
* }
*
* // Create a copy of the path and move it 100pt down:
* var copy = path.clone();
* copy.position.y += 120;
*
* // Set its stroke color to red:
* copy.strokeColor = 'red';
*
* // Smooth the segments of the copy:
* copy.smooth();
*/
/**
* {@grouptitle Postscript Style Drawing Commands}
*
2012-10-05 19:09:15 -04:00
* On a normal empty {@link Path}, the point is simply added as the path's
* first segment. If called on a {@link CompoundPath}, a new {@link Path} is
* created as a child and the point is added as its first segment.
*
* @name PathItem#moveTo
* @function
* @param {Point} point
*/
2011-12-23 16:47:10 -05:00
// DOCS: Document #lineTo()
/**
* @name PathItem#lineTo
* @function
* @param {Point} point
*/
/**
* Adds a cubic bezier curve to the path, defined by two handles and a to
* point.
*
* @name PathItem#cubicCurveTo
* @function
* @param {Point} handle1
* @param {Point} handle2
* @param {Point} to
*/
/**
* Adds a quadratic bezier curve to the path, defined by a handle and a to
* point.
*
* @name PathItem#quadraticCurveTo
* @function
* @param {Point} handle
* @param {Point} to
*/
2011-12-23 16:47:10 -05:00
// DOCS: Document PathItem#curveTo() 'paramater' param.
/**
* Draws a curve from the position of the last segment point in the path
* that goes through the specified {@code through} point, to the specified
* {@code to} point by adding one segment to the path.
*
* @name PathItem#curveTo
* @function
* @param {Point} through the point through which the curve should go
* @param {Point} to the point where the curve should end
* @param {Number} [parameter=0.5]
*
* @example {@paperscript height=300}
* // Interactive example. Click and drag in the view below:
*
* var myPath;
* function onMouseDrag(event) {
* // If we created a path before, remove it:
* if (myPath) {
* myPath.remove();
* }
*
* // Create a new path and add a segment point to it
* // at {x: 150, y: 150):
* myPath = new Path();
* myPath.add(150, 150);
*
* // Draw a curve through the position of the mouse to 'toPoint'
* var toPoint = new Point(350, 150);
* myPath.curveTo(event.point, toPoint);
*
* // Select the path, so we can see its segments:
* myPath.selected = true;
* }
*
* // When the mouse is released, deselect the path
* // and set its stroke-color to black:
* function onMouseUp(event) {
* myPath.selected = false;
* myPath.strokeColor = 'black';
* }
*/
/**
* Draws an arc from the position of the last segment point in the path that
* goes through the specified {@code through} point, to the specified
* {@code to} point by adding one or more segments to the path.
*
* @name PathItem#arcTo
* @function
* @param {Point} through the point where the arc should pass through
* @param {Point} to the point where the arc should end
*
* @example {@paperscript}
* var path = new Path();
* path.strokeColor = 'black';
*
* var firstPoint = new Point(30, 75);
* path.add(firstPoint);
*
* // The point through which we will create the arc:
* var throughPoint = new Point(40, 40);
*
* // The point at which the arc will end:
* var toPoint = new Point(130, 75);
*
* // Draw an arc through 'throughPoint' to 'toPoint'
* path.arcTo(throughPoint, toPoint);
*
* // Add a red circle shaped path at the position of 'throughPoint':
* var circle = new Path.Circle(throughPoint, 3);
* circle.fillColor = 'red';
*
* @example {@paperscript height=300}
* // Interactive example. Click and drag in the view below:
*
* var myPath;
* function onMouseDrag(event) {
* // If we created a path before, remove it:
* if (myPath) {
* myPath.remove();
* }
*
* // Create a new path and add a segment point to it
* // at {x: 150, y: 150):
* myPath = new Path();
* myPath.add(150, 150);
*
* // Draw an arc through the position of the mouse to 'toPoint'
* var toPoint = new Point(350, 150);
* myPath.arcTo(event.point, toPoint);
*
* // Select the path, so we can see its segments:
* myPath.selected = true;
* }
*
* // When the mouse is released, deselect the path
* // and fill it with black.
* function onMouseUp(event) {
* myPath.selected = false;
* myPath.fillColor = 'black';
* }
*/
/**
* Draws an arc from the position of the last segment point in the path to
* the specified point by adding one or more segments to the path.
*
* @name PathItem#arcTo
* @function
2011-06-16 17:38:58 -04:00
* @param {Point} to the point where the arc should end
* @param {Boolean} [clockwise=true] specifies whether the arc should be
* drawn in clockwise direction.
*
* @example {@paperscript}
* var path = new Path();
* path.strokeColor = 'black';
*
* path.add(new Point(30, 75));
* path.arcTo(new Point(130, 75));
*
* var path2 = new Path();
* path2.strokeColor = 'red';
* path2.add(new Point(180, 25));
*
* // To draw an arc in anticlockwise direction,
* // we pass 'false' as the second argument to arcTo:
* path2.arcTo(new Point(280, 25), false);
*
* @example {@paperscript height=300}
* // Interactive example. Click and drag in the view below:
* var myPath;
*
* // The mouse has to move at least 20 points before
* // the next mouse drag event is fired:
* tool.minDistance = 20;
*
* // When the user clicks, create a new path and add
* // the current mouse position to it as its first segment:
* function onMouseDown(event) {
* myPath = new Path();
* myPath.strokeColor = 'black';
* myPath.add(event.point);
* }
*
* // On each mouse drag event, draw an arc to the current
* // position of the mouse:
* function onMouseDrag(event) {
* myPath.arcTo(event.point);
* }
*/
/**
* Closes the path. When closed, Paper.js connects the first and last
* segments.
*
* @name PathItem#closePath
* @function
* @see Path#closed
*/
/**
* {@grouptitle Relative Drawing Commands}
*
* If called on a {@link CompoundPath}, a new {@link Path} is created as a
2012-10-05 19:09:15 -04:00
* child and a point is added as its first segment relative to the
* position of the last segment of the current path.
*
* @name PathItem#moveBy
* @function
2012-10-05 19:09:15 -04:00
* @param {Point} vector
*/
/**
* Adds a segment relative to the last segment point of the path.
*
* @name PathItem#lineBy
* @function
* @param {Point} vector The vector which is added to the position of the
* last segment of the path, to become the new segment.
*
* @example {@paperscript}
* var path = new Path();
* path.strokeColor = 'black';
*
* // Add a segment at {x: 50, y: 50}
* path.add(25, 25);
*
* // Add a segment relative to the last segment of the path.
* // 50 in x direction and 0 in y direction, becomes {x: 75, y: 25}
* path.lineBy(50, 0);
*
* // 0 in x direction and 50 in y direction, becomes {x: 75, y: 75}
* path.lineBy(0, 50);
*
* @example {@paperscript height=300}
* // Drawing a spiral using lineBy:
* var path = new Path();
* path.strokeColor = 'black';
*
* // Add the first segment at {x: 50, y: 50}
* path.add(view.center);
*
* // Loop 500 times:
* for (var i = 0; i < 500; i++) {
* // Create a vector with an ever increasing length
* // and an angle in increments of 45 degrees
* var vector = new Point({
* angle: i * 45,
* length: i / 2
* });
* // Add the vector relatively to the last segment point:
* path.lineBy(vector);
* }
*
* // Smooth the handles of the path:
* path.smooth();
*
* // Uncomment the following line and click on 'run' to see
* // the construction of the path:
* // path.selected = true;
*/
2011-12-23 16:47:10 -05:00
// DOCS: Document Path#curveBy()
/**
* @name PathItem#curveBy
* @function
* @param {Point} throughVector
* @param {Point} toVector
* @param {Number} [parameter=0.5]
*/
2011-12-23 16:47:10 -05:00
// DOCS: Document Path#arcBy()
/**
* @name PathItem#arcBy
* @function
* @param {Point} throughVector
* @param {Point} toVector
*/
});