UNPKG

paper

Version:

The Swiss Army Knife of Vector Graphics Scripting

1,899 lines (1,258 loc) 205 kB
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>PathItem</title> <base target="class-frame"> <link href="../assets/css/docs.css" rel="stylesheet" type="text/css"> <script src="../assets/js/paper.js"></script> <script src="../assets/js/jquery.js"></script> <script src="../assets/js/codemirror.js"></script> <script src="../assets/js/docs.js"></script> </head> <body> <article class="reference"> <div class="reference-class"> <h1>PathItem</h1> <p> Extends <b><a href="../classes/Item.html"><tt>Item</tt></a></b></p> <p>The PathItem class is the base for any items that describe paths and offer standardised methods for drawing and path manipulation, such as <a href="../classes/Path.html"><tt>Path</tt></a> and <a href="../classes/CompoundPath.html"><tt>CompoundPath</tt></a>.</p> </div> <!-- ================================ properties =========================== --> <div class="reference-members"> <h2>Properties</h2> <div id="interiorpoint" class="member"> <div class="member-link"> <a name="interiorpoint" href="#interiorpoint"><tt><b>interiorPoint</b></tt></a> </div> <div class="member-description hidden"> <div class="member-text"> <p>Returns a point that is guaranteed to be inside the path.</p> <p>Read only.</p> <ul class="member-list"> <h4>Type:</h4> <li> <a href="../classes/Point.html"><tt>Point</tt></a> </li> </ul> </div> </div> </div> <div id="clockwise" class="member"> <div class="member-link"> <a name="clockwise" href="#clockwise"><tt><b>clockwise</b></tt></a> </div> <div class="member-description hidden"> <div class="member-text"> <p>Specifies whether the path as a whole is oriented clock-wise, by looking at the path&rsquo;s area. Note that self-intersecting paths and sub-paths of different orientation can result in areas that cancel each other out.</p> <ul class="member-list"> <h4>Type:</h4> <li> <tt>Boolean</tt> </li> </ul> <ul class="member-list"> <h4>See also:</h4> <li><tt><a href="../classes/Path.html#area"><tt>path.area</tt></a></tt></li> <li><tt><a href="../classes/CompoundPath.html#area"><tt>compoundPath.area</tt></a></tt></li> </ul> </div> </div> </div> <div id="pathdata" class="member"> <div class="member-link"> <a name="pathdata" href="#pathdata"><tt><b>pathData</b></tt></a> </div> <div class="member-description hidden"> <div class="member-text"> <p>The path&rsquo;s geometry, formatted as SVG style path data.</p> <ul class="member-list"> <h4>Type:</h4> <li> <tt>String</tt> </li> </ul> </div> </div> </div> </div> <!-- ============================== methods ================================ --> <div class="reference-members"> <h2>Methods</h2> <h3>Boolean Path Operations</h3> <div id="unite-path" class="member"> <div class="member-link"> <a name="unite-path" href="#unite-path"><tt><b>unite</b>(path[, options])</tt></a> </div> <div class="member-description hidden"> <div class="member-text"> <p>Unites the geometry of the specified path with this path&rsquo;s geometry and returns the result as a new path item.</p> <ul class="member-list"> <h4>Options:</h4> <li><tt>options.insert: <tt>Boolean</tt></tt> &mdash; whether the resulting item should be inserted back into the scene graph, above both paths involved in the operation &mdash;&nbsp;default: <tt>true</tt></li> </ul> <ul class="member-list"> <h4>Parameters:</h4> <li> <tt>path:</tt> <a href="../classes/PathItem.html"><tt>PathItem</tt></a> &mdash;&nbsp;the path to unite with </li> <li> <tt>options:</tt> <tt>Object</tt> &mdash;&nbsp;the boolean operation options &mdash;&nbsp;optional </li> </ul> <ul class="member-list"> <h4>Returns:</h4> <li> <tt><a href="../classes/PathItem.html"><tt>PathItem</tt></a></tt>&nbsp;&mdash;&nbsp;the resulting path item </li> </ul> </div> </div> </div> <div id="intersect-path" class="member"> <div class="member-link"> <a name="intersect-path" href="#intersect-path"><tt><b>intersect</b>(path[, options])</tt></a> </div> <div class="member-description hidden"> <div class="member-text"> <p>Intersects the geometry of the specified path with this path&rsquo;s geometry and returns the result as a new path item.</p> <ul class="member-list"> <h4>Options:</h4> <li><tt>options.insert: <tt>Boolean</tt></tt> &mdash; whether the resulting item should be inserted back into the scene graph, above both paths involved in the operation &mdash;&nbsp;default: <tt>true</tt></li> <li><tt>options.trace: <tt>Boolean</tt></tt> &mdash; whether the tracing method is used, treating both paths as areas when determining which parts of the paths are to be kept in the result, or whether the first path is only to be split at intersections, keeping the parts of the curves that intersect with the area of the second path. &mdash;&nbsp;default: <tt>true</tt></li> </ul> <ul class="member-list"> <h4>Parameters:</h4> <li> <tt>path:</tt> <a href="../classes/PathItem.html"><tt>PathItem</tt></a> &mdash;&nbsp;the path to intersect with </li> <li> <tt>options:</tt> <tt>Object</tt> &mdash;&nbsp;the boolean operation options &mdash;&nbsp;optional </li> </ul> <ul class="member-list"> <h4>Returns:</h4> <li> <tt><a href="../classes/PathItem.html"><tt>PathItem</tt></a></tt>&nbsp;&mdash;&nbsp;the resulting path item </li> </ul> </div> </div> </div> <div id="subtract-path" class="member"> <div class="member-link"> <a name="subtract-path" href="#subtract-path"><tt><b>subtract</b>(path[, options])</tt></a> </div> <div class="member-description hidden"> <div class="member-text"> <p>Subtracts the geometry of the specified path from this path&rsquo;s geometry and returns the result as a new path item.</p> <ul class="member-list"> <h4>Options:</h4> <li><tt>options.insert: <tt>Boolean</tt></tt> &mdash; whether the resulting item should be inserted back into the scene graph, above both paths involved in the operation &mdash;&nbsp;default: <tt>true</tt></li> <li><tt>options.trace: <tt>Boolean</tt></tt> &mdash; whether the tracing method is used, treating both paths as areas when determining which parts of the paths are to be kept in the result, or whether the first path is only to be split at intersections, removing the parts of the curves that intersect with the area of the second path. &mdash;&nbsp;default: <tt>true</tt></li> </ul> <ul class="member-list"> <h4>Parameters:</h4> <li> <tt>path:</tt> <a href="../classes/PathItem.html"><tt>PathItem</tt></a> &mdash;&nbsp;the path to subtract </li> <li> <tt>options:</tt> <tt>Object</tt> &mdash;&nbsp;the boolean operation options &mdash;&nbsp;optional </li> </ul> <ul class="member-list"> <h4>Returns:</h4> <li> <tt><a href="../classes/PathItem.html"><tt>PathItem</tt></a></tt>&nbsp;&mdash;&nbsp;the resulting path item </li> </ul> </div> </div> </div> <div id="exclude-path" class="member"> <div class="member-link"> <a name="exclude-path" href="#exclude-path"><tt><b>exclude</b>(path[, options])</tt></a> </div> <div class="member-description hidden"> <div class="member-text"> <p>Excludes the intersection of the geometry of the specified path with this path&rsquo;s geometry and returns the result as a new path item.</p> <ul class="member-list"> <h4>Options:</h4> <li><tt>options.insert: <tt>Boolean</tt></tt> &mdash; whether the resulting item should be inserted back into the scene graph, above both paths involved in the operation &mdash;&nbsp;default: <tt>true</tt></li> </ul> <ul class="member-list"> <h4>Parameters:</h4> <li> <tt>path:</tt> <a href="../classes/PathItem.html"><tt>PathItem</tt></a> &mdash;&nbsp;the path to exclude the intersection of </li> <li> <tt>options:</tt> <tt>Object</tt> &mdash;&nbsp;the boolean operation options &mdash;&nbsp;optional </li> </ul> <ul class="member-list"> <h4>Returns:</h4> <li> <tt><a href="../classes/PathItem.html"><tt>PathItem</tt></a></tt>&nbsp;&mdash;&nbsp;the resulting path item </li> </ul> </div> </div> </div> <div id="divide-path" class="member"> <div class="member-link"> <a name="divide-path" href="#divide-path"><tt><b>divide</b>(path[, options])</tt></a> </div> <div class="member-description hidden"> <div class="member-text"> <p>Splits the geometry of this path along the geometry of the specified path returns the result as a new group item. This is equivalent to calling <a href="../classes/PathItem.html#subtract-path"><tt>subtract(path)</tt></a> and <a href="../classes/PathItem.html#intersect-path"><tt>intersect(path)</tt></a> and putting the results into a new group.</p> <ul class="member-list"> <h4>Options:</h4> <li><tt>options.insert: <tt>Boolean</tt></tt> &mdash; whether the resulting item should be inserted back into the scene graph, above both paths involved in the operation &mdash;&nbsp;default: <tt>true</tt></li> <li><tt>options.trace: <tt>Boolean</tt></tt> &mdash; whether the tracing method is used, treating both paths as areas when determining which parts of the paths are to be kept in the result, or whether the first path is only to be split at intersections. &mdash;&nbsp;default: <tt>true</tt></li> </ul> <ul class="member-list"> <h4>Parameters:</h4> <li> <tt>path:</tt> <a href="../classes/PathItem.html"><tt>PathItem</tt></a> &mdash;&nbsp;the path to divide by </li> <li> <tt>options:</tt> <tt>Object</tt> &mdash;&nbsp;the boolean operation options &mdash;&nbsp;optional </li> </ul> <ul class="member-list"> <h4>Returns:</h4> <li> <tt><a href="../classes/PathItem.html"><tt>PathItem</tt></a></tt>&nbsp;&mdash;&nbsp;the resulting path item </li> </ul> </div> </div> </div> <div id="reorient" class="member"> <div class="member-link"> <a name="reorient" href="#reorient"><tt><b>reorient</b>([nonZero[, clockwise]])</tt></a> </div> <div class="member-description hidden"> <div class="member-text"> <p>Fixes the orientation of the sub-paths of a compound-path, assuming that non of its sub-paths intersect, by reorienting them so that they are of different winding direction than their containing paths, except for disjoint sub-paths, i.e. islands, which are oriented so that they have the same winding direction as the the biggest path.</p> <ul class="member-list"> <h4>Parameters:</h4> <li> <tt>nonZero:</tt> <tt>Boolean</tt> &mdash;&nbsp;controls if the non-zero fill-rule is to be applied, by counting the winding of each nested path and discarding sub-paths that do not contribute to the final result &mdash;&nbsp;optional, default: <tt>false</tt> </li> <li> <tt>clockwise:</tt> <tt>Boolean</tt> &mdash;&nbsp;if provided, the orientation of the root paths will be set to the orientation specified by <code>clockwise</code>, otherwise the orientation of the largest root child is used. &mdash;&nbsp;optional </li> </ul> <ul class="member-list"> <h4>Returns:</h4> <li> <tt><a href="../classes/PathItem.html"><tt>PathItem</tt></a></tt>&nbsp;&mdash;&nbsp;a reference to the item itself, reoriented </li> </ul> </div> </div> </div> <h3>Path Intersections and Locations</h3> <div id="getintersections-path" class="member"> <div class="member-link"> <a name="getintersections-path" href="#getintersections-path"><tt><b>getIntersections</b>(path[, include])</tt></a> </div> <div class="member-description hidden"> <div class="member-text"> <p>Returns all intersections between two <a href="../classes/PathItem.html"><tt>PathItem</tt></a> items as an array of <a href="../classes/CurveLocation.html"><tt>CurveLocation</tt></a> objects. <a href="../classes/CompoundPath.html"><tt>CompoundPath</tt></a> items are also supported.</p> <ul class="member-list"> <h4>Parameters:</h4> <li> <tt>path:</tt> <a href="../classes/PathItem.html"><tt>PathItem</tt></a> &mdash;&nbsp;the other item to find the intersections with </li> <li> <tt>include:</tt> <tt>Function</tt> &mdash;&nbsp;a callback function that can be used to filter out undesired locations right while they are collected. When defined, it shall return <tt>true</tt> to include a location, <tt>false</tt> otherwise. &mdash;&nbsp;optional </li> </ul> <ul class="member-list"> <h4>Returns:</h4> <li> <tt>Array of <a href="../classes/CurveLocation.html"><tt>CurveLocation</tt></a> objects</tt>&nbsp;&mdash;&nbsp;the locations of all intersection between the paths </li> </ul> <ul class="member-list"> <h4>See also:</h4> <li><tt><a href="../classes/PathItem.html#getcrossings-path"><tt>getCrossings(path)</tt></a></tt></li> </ul> <h4>Example:<span class="description">Finding the intersections between two paths</span></h4> <div class="paperscript split"> <div class="buttons"> <div class="button run">Run</div> </div> <script type="text/paperscript" canvas="canvas-0"> var path = new Path.Rectangle(new Point(30, 25), new Size(50, 50)); path.strokeColor = 'black'; var secondPath = path.clone(); var intersectionGroup = new Group(); function onFrame(event) { secondPath.rotate(1); var intersections = path.getIntersections(secondPath); intersectionGroup.removeChildren(); for (var i = 0; i < intersections.length; i++) { var intersectionPath = new Path.Circle({ center: intersections[i].point, radius: 4, fillColor: 'red', parent: intersectionGroup }); } } </script> <div class="canvas"><canvas width="516" height="100" id="canvas-0"></canvas></div> </div> </div> </div> </div> <div id="getcrossings-path" class="member"> <div class="member-link"> <a name="getcrossings-path" href="#getcrossings-path"><tt><b>getCrossings</b>(path)</tt></a> </div> <div class="member-description hidden"> <div class="member-text"> <p>Returns all crossings between two <a href="../classes/PathItem.html"><tt>PathItem</tt></a> items as an array of <a href="../classes/CurveLocation.html"><tt>CurveLocation</tt></a> objects. <a href="../classes/CompoundPath.html"><tt>CompoundPath</tt></a> items are also supported. Crossings are intersections where the paths actually are crossing each other, as opposed to simply touching.</p> <ul class="member-list"> <h4>Parameters:</h4> <li> <tt>path:</tt> <a href="../classes/PathItem.html"><tt>PathItem</tt></a> &mdash;&nbsp;the other item to find the crossings with </li> </ul> <ul class="member-list"> <h4>Returns:</h4> <li> <tt>Array of <a href="../classes/CurveLocation.html"><tt>CurveLocation</tt></a> objects</tt>&nbsp;&mdash;&nbsp;the locations of all crossings between the paths </li> </ul> <ul class="member-list"> <h4>See also:</h4> <li><tt><a href="../classes/PathItem.html#getintersections-path"><tt>getIntersections(path)</tt></a></tt></li> </ul> </div> </div> </div> <div id="getnearestlocation-point" class="member"> <div class="member-link"> <a name="getnearestlocation-point" href="#getnearestlocation-point"><tt><b>getNearestLocation</b>(point)</tt></a> </div> <div class="member-description hidden"> <div class="member-text"> <p>Returns the nearest location on the path item to the specified point.</p> <ul class="member-list"> <h4>Parameters:</h4> <li> <tt>point:</tt> <a href="../classes/Point.html"><tt>Point</tt></a> &mdash;&nbsp;the point for which we search the nearest location </li> </ul> <ul class="member-list"> <h4>Returns:</h4> <li> <tt><a href="../classes/CurveLocation.html"><tt>CurveLocation</tt></a></tt>&nbsp;&mdash;&nbsp;the location on the path that&rsquo;s the closest to the specified point </li> </ul> </div> </div> </div> <div id="getnearestpoint-point" class="member"> <div class="member-link"> <a name="getnearestpoint-point" href="#getnearestpoint-point"><tt><b>getNearestPoint</b>(point)</tt></a> </div> <div class="member-description hidden"> <div class="member-text"> <p>Returns the nearest point on the path item to the specified point.</p> <ul class="member-list"> <h4>Parameters:</h4> <li> <tt>point:</tt> <a href="../classes/Point.html"><tt>Point</tt></a> &mdash;&nbsp;the point for which we search the nearest point </li> </ul> <ul class="member-list"> <h4>Returns:</h4> <li> <tt><a href="../classes/Point.html"><tt>Point</tt></a></tt>&nbsp;&mdash;&nbsp;the point on the path that&rsquo;s the closest to the specified point </li> </ul> <h4>Example:</h4> <div class="paperscript split"> <div class="buttons"> <div class="button run">Run</div> </div> <script type="text/paperscript" canvas="canvas-1"> var star = new Path.Star({ center: view.center, points: 10, radius1: 30, radius2: 60, strokeColor: 'black' }); var circle = new Path.Circle({ center: view.center, radius: 3, fillColor: 'red' }); function onMouseMove(event) { // Get the nearest point from the mouse position // to the star shaped path: var nearestPoint = star.getNearestPoint(event.point); // Move the red circle to the nearest point: circle.position = nearestPoint; } </script> <div class="canvas"><canvas width="516" height="200" id="canvas-1"></canvas></div> </div> </div> </div> </div> <h3>Path Manipulation</h3> <div id="reverse" class="member"> <div class="member-link"> <a name="reverse" href="#reverse"><tt><b>reverse</b>()</tt></a> </div> <div class="member-description hidden"> <div class="member-text"> <p>Reverses the orientation of the path item. When called on <a href="../classes/CompoundPath.html"><tt>CompoundPath</tt></a> items, each of the nested paths is reversed. On <a href="../classes/Path.html"><tt>Path</tt></a> items, the sequence of <a href="../classes/Path.html#segments"><tt>path.segments</tt></a> is reversed.</p> </div> </div> </div> <div id="flatten" class="member"> <div class="member-link"> <a name="flatten" href="#flatten"><tt><b>flatten</b>([flatness])</tt></a> </div> <div class="member-description hidden"> <div class="member-text"> <p>Flattens the curves in path items to a sequence of straight lines, by subdividing them enough times until the specified maximum error is met.</p> <ul class="member-list"> <h4>Parameters:</h4> <li> <tt>flatness:</tt> <tt>Number</tt> &mdash;&nbsp;the maximum error between the flattened lines and the original curves &mdash;&nbsp;optional, default: <tt>0.25</tt> </li> </ul> <h4>Example:<span class="description">Flattening a circle shaped path:</span></h4> <div class="paperscript split"> <div class="buttons"> <div class="button run">Run</div> </div> <script type="text/paperscript" canvas="canvas-2"> // Create a circle shaped path at { x: 80, y: 50 } // with a radius of 35: var path = new Path.Circle({ center: [80, 50], radius: 35 }); // Select the path, so we can inspect its segments: path.selected = true; // Create a copy of the path and move it by 150 points: var copy = path.clone(); copy.position.x += 150; // Flatten the copied path, with a maximum error of 4 points: copy.flatten(4); </script> <div class="canvas"><canvas width="516" height="100" id="canvas-2"></canvas></div> </div> </div> </div> </div> <div id="smooth" class="member"> <div class="member-link"> <a name="smooth" href="#smooth"><tt><b>smooth</b>([options])</tt></a> </div> <div class="member-description hidden"> <div class="member-text"> <p>Smooths the path item without changing the amount of segments in the path or moving the segments&rsquo; locations, by smoothing and adjusting the angle and length of the segments&rsquo; handles based on the position and distance of neighboring segments.</p> <p>Smoothing works both for open paths and closed paths, and can be applied to the full path, as well as a sub-range of it. If a range is defined using the <code>options.from</code> and <code>options.to</code> properties, only the curve handles inside that range are touched. If one or both limits of the range are specified in negative indices, the indices are wrapped around the end of the curve. That way, a smoothing range in a close path can even wrap around the connection between the last and the first segment.</p> <p>Four different smoothing methods are available:</p> <ul> <li> <p><code>&#39;continuous&#39;</code> smooths the path item by adjusting its curve handles so that the first and second derivatives of all involved curves are continuous across their boundaries.</p> <p>This method tends to result in the smoothest results, but does not allow for further parametrization of the handles.</p> </li> <li> <p><code>&#39;asymmetric&#39;</code> is based on the same principle as <code>&#39;continuous&#39;</code> but uses different factors so that the result is asymmetric. This used to the only method available until v0.10.0, and is currently still the default when no method is specified, for reasons of backward compatibility. It will eventually be removed.</p></li> <li> <p><code>&#39;catmull-rom&#39;</code> uses the Catmull-Rom spline to smooth the segment.</p> <p>The optionally passed factor controls the knot parametrization of the algorithm:</p> <ul> <li><code>0.0</code>: the standard, uniform Catmull-Rom spline</li> <li><code>0.5</code>: the centripetal Catmull-Rom spline, guaranteeing no self-intersections</li> <li><code>1.0</code>: the chordal Catmull-Rom spline</li> </ul> </li> <li> <p><code>&#39;geometric&#39;</code> use a simple heuristic and empiric geometric method to smooth the segment&rsquo;s handles. The handles were weighted, meaning that big differences in distances between the segments will lead to probably undesired results.</p> <p>The optionally passed factor defines the tension parameter (<code>0…1</code>), controlling the amount of smoothing as a factor by which to scale each handle.</p> </li> </ul> <ul class="member-list"> <h4>Options:</h4> <li><tt>options.type: <tt>String</tt></tt> &mdash; the type of smoothing method: <tt>&lsquo;continuous&rsquo;</tt>, <tt>&lsquo;asymmetric&rsquo;</tt>, <tt>&lsquo;catmull-rom&rsquo;</tt>, <tt>&lsquo;geometric&rsquo;</tt> &mdash;&nbsp;default: <tt>&lsquo;asymmetric&rsquo;</tt></li> <li><tt>options.factor: <tt>Number</tt></tt> &mdash; the factor parameterizing the smoothing method — default: <code>0.5</code> for <code>&#39;catmull-rom&#39;</code>, <code>0.4</code> for <code>&#39;geometric&#39;</code></li> <li><tt>options.from: <tt>Number</tt>⟋<a href="../classes/Segment.html"><tt>Segment</tt></a>⟋<a href="../classes/Curve.html"><tt>Curve</tt></a></tt> &mdash; the segment or curve at which to start smoothing, if not the full path shall be smoothed (inclusive). This can either be a segment index, or a segment or curve object that is part of the path. If the passed number is negative, the index is wrapped around the end of the path.</li> <li><tt>options.to: <tt>Number</tt>⟋<a href="../classes/Segment.html"><tt>Segment</tt></a>⟋<a href="../classes/Curve.html"><tt>Curve</tt></a></tt> &mdash; the segment or curve to which the handles of the path shall be processed (inclusive). This can either be a segment index, or a segment or curve object that is part of the path. If the passed number is negative, the index is wrapped around the end of the path.</li> </ul> <ul class="member-list"> <h4>Parameters:</h4> <li> <tt>options:</tt> <tt>Object</tt> &mdash;&nbsp;the smoothing options &mdash;&nbsp;optional </li> </ul> <ul class="member-list"> <h4>See also:</h4> <li><tt><a href="../classes/Segment.html#smooth"><tt>segment.smooth([options])</tt></a></tt></li> </ul> <h4>Example:<span class="description">Smoothing a closed shape:</span></h4> <div class="paperscript split"> <div class="buttons"> <div class="button run">Run</div> </div> <script type="text/paperscript" canvas="canvas-3"> // 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({ point: [30, 25], size: [50, 50], strokeColor: 'black', }); // Select the path, so we can see its handles: path.fullySelected = true; // Create a copy of the path and move it 100 to the right: var copy = path.clone(); copy.position.x += 100; // Smooth the segments of the copy: copy.smooth({ type: 'continuous' }); </script> <div class="canvas"><canvas width="516" height="100" id="canvas-3"></canvas></div> </div> <h4>Example:</h4> <div class="paperscript split"> <div class="buttons"> <div class="button run">Run</div> </div> <script type="text/paperscript" canvas="canvas-4"> 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 100 down: var copy = path.clone(); copy.position.y += 120; // Select the path, so we can see its handles: copy.fullySelected = true; // Smooth the path using centripetal Catmull-Rom splines: copy.smooth({ type: 'catmull-rom', factor: 0.5 }); </script> <div class="canvas"><canvas width="516" height="220" id="canvas-4"></canvas></div> </div> <h4>Example:<span class="description">Smoothing ranges of paths, using segments, curves or indices:</span></h4> <div class="paperscript split"> <div class="buttons"> <div class="button run">Run</div> </div> <script type="text/paperscript" canvas="canvas-5"> // Create 5 rectangles, next to each other: var paths = []; for (var i = 0; i < 5; i++) { paths.push(new Path.Rectangle({ point: [30 + i * 100, 30], size: [50, 50], fullySelected: true })); } // Smooth a range, using segments: paths[1].smooth({ type: 'continuous', from: paths[1].segments[0], to: paths[1].segments[2] }); // Smooth a range, using curves: paths[2].smooth({ type: 'continuous', from: paths[2].curves[0], to: paths[2].curves[1] }); // Smooth a range, using indices: paths[3].smooth({ type: 'continuous', from: 0, to: 2 }); // Smooth a range, using negative indices: paths[4].smooth({ type: 'continuous', from: -1, to: 1 }); </script> <div class="canvas"><canvas width="516" height="110" id="canvas-5"></canvas></div> </div> </div> </div> </div> <div id="simplify" class="member"> <div class="member-link"> <a name="simplify" href="#simplify"><tt><b>simplify</b>([tolerance])</tt></a> </div> <div class="member-description hidden"> <div class="member-text"> <p>Fits a sequence of as few curves as possible through the path&rsquo;s anchor points, ignoring the path items&rsquo;s curve-handles, with an allowed maximum error. When called on <a href="../classes/CompoundPath.html"><tt>CompoundPath</tt></a> items, each of the nested paths is simplified. On <a href="../classes/Path.html"><tt>Path</tt></a> items, the <a href="../classes/Path.html#segments"><tt>path.segments</tt></a> array is processed and replaced by the resulting sequence of fitted curves.</p> <p>This method can be used to process and simplify the point data received from a mouse or touch device.</p> <ul class="member-list"> <h4>Parameters:</h4> <li> <tt>tolerance:</tt> <tt>Number</tt> &mdash;&nbsp;the allowed maximum error when fitting the curves through the segment points &mdash;&nbsp;optional, default: <tt>2.5</tt> </li> </ul> <ul class="member-list"> <h4>Returns:</h4> <li> <tt><tt>Boolean</tt></tt>&nbsp;&mdash;&nbsp;<tt>true</tt> if the method was capable of fitting curves through the path&rsquo;s segment points, <tt>false</tt> otherwise </li> </ul> <h4>Example:<span class="description">Click and drag below to draw to draw a line, when you release the mouse, the is made smooth using path.simplify():</span></h4> <div class="paperscript split"> <div class="buttons"> <div class="button run">Run</div> </div> <script type="text/paperscript" canvas="canvas-6"> var path; function onMouseDown(event) { // If we already made a path before, deselect it: if (path) { path.selected = false; } // Create a new path and add the position of the mouse // as its first segment. Select it, so we can see the // segment points: path = new Path({ segments: [event.point], strokeColor: 'black', selected: true }); } function onMouseDrag(event) { // On every drag event, add a segment to the path // at the position of the mouse: path.add(event.point); } function onMouseUp(event) { // When the mouse is released, simplify the path: path.simplify(); path.selected = true; } </script> <div class="canvas"><canvas width="516" height="300" id="canvas-6"></canvas></div> </div> </div> </div> </div> <div id="interpolate-from-to-factor" class="member"> <div class="member-link"> <a name="interpolate-from-to-factor" href="#interpolate-from-to-factor"><tt><b>interpolate</b>(from, to, factor)</tt></a> </div> <div class="member-description hidden"> <div class="member-text"> <p>Interpolates between the two specified path items and uses the result as the geometry for this path item. The number of children and segments in the two paths involved in the operation should be the same.</p> <ul class="member-list"> <h4>Parameters:</h4> <li> <tt>from:</tt> <a href="../classes/PathItem.html"><tt>PathItem</tt></a> &mdash;&nbsp;the path item defining the geometry when <code>factor</code> is <code>0</code> </li> <li> <tt>to:</tt> <a href="../classes/PathItem.html"><tt>PathItem</tt></a> &mdash;&nbsp;the path item defining the geometry when <code>factor</code> is <code>1</code> </li> <li> <tt>factor:</tt> <tt>Number</tt> &mdash;&nbsp;the interpolation coefficient, typically between <code>0</code> and <code>1</code>, but extrapolation is possible too </li> </ul> </div> </div> </div> <div id="compare-path" class="member"> <div class="member-link"> <a name="compare-path" href="#compare-path"><tt><b>compare</b>(path)</tt></a> </div> <div class="member-description hidden"> <div class="member-text"> <p>Compares the geometry of two paths to see if they describe the same shape, detecting cases where paths start in different segments or even use different amounts of curves to describe the same shape, as long as their orientation is the same, and their segments and handles really result in the same visual appearance of curves.</p> <ul class="member-list"> <h4>Parameters:</h4> <li> <tt>path:</tt> <a href="../classes/PathItem.html"><tt>PathItem</tt></a> &mdash;&nbsp;the path to compare this path&rsquo;s geometry with </li> </ul> <ul class="member-list"> <h4>Returns:</h4> <li> <tt><tt>Boolean</tt></tt>&nbsp;&mdash;&nbsp;<tt>true</tt> if two paths describe the same shape, <tt>false</tt> otherwise </li> </ul> </div> </div> </div> <h3>Postscript Style Drawing Commands</h3> <div id="moveto-point" class="member"> <div class="member-link"> <a name="moveto-point" href="#moveto-point"><tt><b>moveTo</b>(point)</tt></a> </div> <div class="member-description hidden"> <div class="member-text"> <p>On a normal empty <a href="../classes/Path.html"><tt>Path</tt></a>, the point is simply added as the path&rsquo;s first segment. If called on a <a href="../classes/CompoundPath.html"><tt>CompoundPath</tt></a>, a new <a href="../classes/Path.html"><tt>Path</tt></a> is created as a child and the point is added as its first segment.</p> <ul class="member-list"> <h4>Parameters:</h4> <li> <tt>point:</tt> <a href="../classes/Point.html"><tt>Point</tt></a> &mdash;&nbsp;the point in which to start the path </li> </ul> </div> </div> </div> <div id="lineto-point" class="member"> <div class="member-link"> <a name="lineto-point" href="#lineto-point"><tt><b>lineTo</b>(point)</tt></a> </div> <div class="member-description hidden"> <div class="member-text"> <p>Adds a straight curve to the path, from the the last segment in the path to the specified point.</p> <ul class="member-list"> <h4>Parameters:</h4> <li> <tt>point:</tt> <a href="../classes/Point.html"><tt>Point</tt></a> &mdash;&nbsp;the destination point of the newly added straight curve </li> </ul> </div> </div> </div> <div id="arcto-through-to" class="member"> <div class="member-link"> <a name="arcto-through-to" href="#arcto-through-to"><tt><b>arcTo</b>(through, to)</tt></a> </div> <div class="member-description hidden"> <div class="member-text"> <p>Adds an arc from the position of the last segment in the path, passing through the specified <code>through</code> point, to the specified <code>to</code> point, by adding one or more segments to the path.</p> <ul class="member-list"> <h4>Parameters:</h4> <li> <tt>through:</tt> <a href="../classes/Point.html"><tt>Point</tt></a> &mdash;&nbsp;the point where the arc should pass through </li> <li> <tt>to:</tt> <a href="../classes/Point.html"><tt>Point</tt></a> &mdash;&nbsp;the point where the arc should end </li> </ul> <h4>Example:</h4> <div class="paperscript split"> <div class="buttons"> <div class="button run">Run</div> </div> <script type="text/paperscript" canvas="canvas-7"> 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'; </script> <div class="canvas"><canvas width="516" height="100" id="canvas-7"></canvas></div> </div> <h4>Example:<span class="description">Interactive example. Click and drag in the view below:</span></h4> <div class="paperscript split"> <div class="buttons"> <div class="button run">Run</div> </div> <script type="text/paperscript" canvas="canvas-8"> 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'; } </script> <div class="canvas"><canvas width="516" height="300" id="canvas-8"></canvas></div> </div> </div> </div> </div> <div id="arcto-to" class="member"> <div class="member-link"> <a name="arcto-to" href="#arcto-to"><tt><b>arcTo</b>(to[, clockwise])</tt></a> </div> <div class="member-description hidden"> <div class="member-text"> <p>Adds an arc from the position of the last segment in the path to the specified point, by adding one or more segments to the path.</p> <ul class="member-list"> <h4>Parameters:</h4> <li> <tt>to:</tt> <a href="../classes/Point.html"><tt>Point</tt></a> &mdash;&nbsp;the point where the arc should end </li> <li> <tt>clockwise:</tt> <tt>Boolean</tt> &mdash;&nbsp;specifies whether the arc should be drawn in clockwise direction &mdash;&nbsp;optional, default: <tt>true</tt> </li> </ul> <h4>Example:</h4> <div class="paperscript split"> <div class="buttons"> <div class="button run">Run</div> </div> <script type="text/paperscript" canvas="canvas-9"> 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); </script> <div class="canvas"><canvas width="516" height="100" id="canvas-9"></canvas></div> </div> <h4>Example:<span class="description">Interactive example. Click and drag in the view below:</span></h4> <div class="paperscript split"> <div class="buttons"> <div class="button run">Run</div> </div> <script type="text/paperscript" canvas="canvas-10"> 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); } </script> <div class="canvas"><canvas width="516" height="300" id="canvas-10"></canvas></div> </div> </div> </div> </div> <div id="curveto-through-to" class="member"> <div class="member-link"> <a name="curveto-through-to" href="#curveto-through-to"><tt><b>curveTo</b>(through, to[, time])</tt></a> </div> <div class="member-description hidden"> <div class="member-text"> <p>Adds a curve from the last segment in the path through the specified <code>through</code> point, to the specified destination point by adding one segment to the path.</p> <ul class="member-list"> <h4>Parameters:</h4> <li> <tt>through:</tt> <a href="../classes/Point.html"><tt>Point</tt></a> &mdash;&nbsp;the point through which the curve should pass </li> <li> <tt>to:</tt> <a href="../classes/Point.html"><tt>Point</tt></a> &mdash;&nbsp;the destination point of the newly added curve </li> <li> <tt>time:</tt> <tt>Number</tt> &mdash;&nbsp;the curve-time parameter at which the <code>through</code> point is to be located &mdash;&nbsp;optional, default: <tt>0.5</tt> </li> </ul> <h4>Example:<span class="description">Interactive example. Move your mouse around the view below:</span></h4> <div class="paperscript split"> <div class="buttons"> <div class="button run">Run</div> </div> <script type="text/paperscript" canvas="canvas-11"> var myPath; function onMouseMove(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; } </script> <div class="canvas"><canvas width="516" height="300" id="canvas-11"></canvas></div> </div> </div> </div> </div> <div id="cubiccurveto-handle1-handle2-to" class="member"> <div class="member-link"> <a name="cubiccurveto-handle1-handle2-to" href="#cubiccurveto-handle1-handle2-to"><tt><b>cubicCurveTo</b>(handle1, handle2, to)</tt></a> </div> <div class="member-description hidden"> <div class="member-text"> <p>Adds a cubic bezier curve to the path, from the last segment to the specified destination point, with the curve itself defined by two specified handles.</p> <ul class="member-list"> <h4>Parameters:</h4> <li> <tt>handle1:</tt> <a href="../classes/Point.html"><tt>Point</tt></a> &mdash;&nbsp;the location of the first handle of the newly added curve in absolute coordinates, out of which the relative values for <a href="../classes/Segment.html#handleout"><tt>segment.handleOut</tt></a> of its first segment are calculated </li> <li> <tt>handle2:</tt> <a href="../classes/Point.html"><tt>Point</tt></a> &mdash;&nbsp;the location of the second handle of the newly added curve in absolute coordinates, out of which the relative values for <a href="../classes/Segment.html#handlein"><tt>segment.handleIn</tt></a> of its second segment are calculated </li> <li> <tt>to:</tt> <a href="../classes/Point.html"><tt>Point</tt></a> &mdash;&nbsp;the destination point of the newly added curve </li> </ul> </div> </div> </div> <div id="quadraticcurveto-handle-to" class="member"> <div class="member-link"> <a name="quadraticcurveto-handle-to" href="#quadraticcurveto-handle-to"><tt><b>quadraticCurveTo</b>(handle, to)</tt></a> </div> <div class="member-description hidden"> <div class="member-text"> <p>Adds a quadratic bezier curve to the path, from the last segment to the specified destination point, with the curve itself defined by the specified handle.</p> <p>Note that Paper.js only stores cubic curves, so the handle is actually converted.</p> <ul class="member-list"> <h4>Parameters:</h4> <li> <tt>handle:</tt> <a href="../classes/Point.html"><tt>Point</tt></a> &mdash;&nbsp;the location of the handle of the newly added quadratic curve in absolute coordinates, out of which the relative values for <a href="../classes/Segment.html#handleout"><tt>segment.handleOut</tt></a> of the resulting cubic curve&rsquo;s first segment and <a href="../classes/Segment.html#handlein"><tt>segment.handleIn</tt></a> of its second segment are calculated </li> <li> <tt>to:</tt> <a href="../classes/Point.html"><tt>Point</tt></a> &mdash;&nbsp;the destination point of the newly added curve </li> </ul> </div> </div> </div> <div id="closepath" class="member"> <div class="member-link"> <a name="closepath" href="#closepath"><tt><b>closePath</b>()</tt></a> </div> <div class="member-description hidden"> <div class="member-text"> <p>Closes the path. When closed, Paper.js connects the first and last segment of the path with an additional curve. The difference to setting <a href="../classes/Path.html#closed"><tt>path.closed</tt></a> to <code>true</code> is that this will also merge the first segment with the last if they lie in the same location.</p> <ul class="member-list"> <h4>See also:</h4> <li><tt><a href="../classes/Path.html#closed"><tt>path.closed</tt></a></tt></li> </ul> </div> </div> </div> <h3>Relative Drawing Commands</h3> <div id="moveby-to" class="member"> <div class="member-link"> <a name="moveby-to" href="#moveby-to"><tt><b>moveBy</b>(to)</tt></a> </div> <div class="member-description hidden"> <div class="member-text"> <p>If called on a <a href="../classes/CompoundPath.html"><tt>CompoundPath</tt></a>, a new <a href="../classes/Path.html"><tt>Path</tt></a> is created as a child and a point is added as its first segment relative to the position of the last segment of the current path.</p> <ul class="member-list"> <h4>Parameters:</h4> <li> <tt>to:</tt> <a href="../classes/Point.html"><tt>Point</tt></a> </li> </ul> </div> </div> </div> <div id="lineby-point" class="member"> <div class="member-link"> <a name="lineby-point" href="#lineby-point"><tt><b>lineBy</b>(point)</tt></a> </div> <div class="member-description hidden"> <div class="member-text"> <p>Adds a straight curve to the path, from the the last segment in the path to the <code>to</code> vector specified relatively to it.</p> <ul class="member-list"> <h4>Parameters:</h4> <li> <tt>point:</tt> <a href="../classes/Point.html"><tt>Point</tt></a> &mdash;&nbsp;the vector describing the destination of the newly added straight curve </li> </ul> <h4>Example:</h4> <div class="paperscript split"> <div class="buttons"> <div class="button run">Run</div> </div> <script type="text/paperscript" canvas="canvas-12"> 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); </script> <div class="canvas"><canvas width="516" height="100" id="canvas-12"></canvas></div> </div> <h4>Example:<span class="description">Drawing a spiral using lineBy:</span></h4> <div class="paperscript split"> <div class="buttons"> <div class="button run">Run</div> </div> <script type="text/paperscript" canvas="canvas-13"> 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; </script> <div class="canvas"><canvas width="516" height="300" id="canvas-13"></canvas></div> </div> </div> </div> </div> <div id="arcby-through-to" class="member"> <div class="member-link"> <a name="arcby-through-to" href="#arcby-through-to"><tt><b>arcBy</b>(through, to)</tt></a> </div> <div class="member-description hidden"> <div class="member-text"> <p>Adds an arc from the position of the last segment in the path, passing through the specified <code>through</code> vector, to the specified <code>to</code> vector, all specified relatively to it by these given vectors, by adding one or more segments to the path.</p> <ul class="member-list"> <h4>Parameters:</h4> <li> <tt>through:</tt> <a href="../classes/Point.html"><tt>Point</tt></a> &mdash;&nbsp;the vector where the arc should pass through </li> <li> <tt>to:</tt> <a href="../classes/Point.html"><tt>Point</tt></a> &mdash;&nbsp;the vector where the arc should end </li> </ul> </div> </div> </div> <div id="arcby-to" class="member"> <div class="member-link"> <a name="arcby-to" href="#arcby-to"><tt><b>arcBy</b>(to[, clockwise])</tt></a> </div> <div class="member-description hidden"> <div class="member-text"> <p>Adds an arc from the position of the last segment in the path to the <code>to</code> vector specified relatively to it, by adding one or more segments to the path.</p> <ul class="member-list"> <h4>Parameters:</h4> <li> <tt>to:</tt> <a href="../classes/Point.html"><tt>Point</tt></a> &mdash;&nbsp;the vector where the arc should end </li> <li> <tt>clockwise:</tt> <tt>Boolean</tt> &mdash;&nbsp;specifies whether the arc should be drawn in clockwise direction &mdash;&nbsp;optional, default: <tt>true</tt> </li> </ul> </div> </div> </div> <div id="curveby-through-to" class="member"> <div class="member-link"> <a name="curveby-through-to" href="#curveby-through-to"><tt><b>curveBy</b>(through, to[, time])</tt></a> </div> <div class="member-description hidden"> <div class="member-text"> <p>Adds a curve from the last segment in the path through the specified <code>through</code> vector, to the specified <code>to</code> vector, all specified relatively to it by these given vectors, by adding one segment to the path.</p> <ul class="member-list"> <h4>Parameters:</h4> <li> <tt>through:</tt> <a href="../classes/Point.html"><tt>Point</tt></a> &mdash;&nbsp;the vector through which the curve should pass </li> <li> <tt>to:</tt> <a href="../classes/Point.html"><tt>Point</tt></a> &mdash;&nbsp;the destination vector of the newly added curve </li> <li> <tt>time:</tt> <tt>Number</tt> &mdash;&nbsp;the curve-time parameter at which the <code>through</code> point is to be located &mdash;&nbsp;optional, default: <tt>0.5</tt> </li> </ul> </div> </div> </div> <div id="cubiccurveby-handle1-handle2-to" class="member"> <div class="member-link"> <a name="cubiccurveby-handle1-handle2-to" href="#cubiccurveby-handle1-handle2-to"><tt><b>cubicCurveBy</b>(handle1, handle2, to)</tt></a> </div> <div class="member-description hidden"> <div class="member-text"> <p>Adds a cubic bezier curve to the path, from the last segment to the to the specified <code>to</code> vector, with the curve itself defined by two specified handles.</p> <ul class="member-list"> <h4>Parameters:</h4> <li> <tt>handle1:</tt> <a href="../classes/Point.html"><tt>Point</tt></a> &mdash;&nbsp;the location of the first handle of the newly added curve </li> <li> <tt>handle2:</tt> <a href="../classes/Point.html"><tt>Point</tt></a> &mdash;&nbsp;the location of the second handle of the newly added curve </li> <li> <tt>to:</tt> <a href="../classes/Point.html"><tt>Point</tt></a> &mdash;&nbsp;the destination point of the newly added curve </li> </ul> </div> </div> </div> <div id="quadraticcurveby-handle-to" class="member"> <div class="member-link"> <a name="quadraticcurveby-handle-to" href="#quadraticcurveby-handle-to"><tt><b>quadraticCurveBy</b>(handle, to)</tt></a> </div> <div class="member-description hidden"> <div class="member-text"> <p>Adds a quadratic bezier curve to the path, from the last segment to the specified destination point, with the curve itself defined by the specified handle.</p> <p>Note that Paper.js only stores cubic curves, so the handle is actually converted.</p> <ul class="member-list"> <h4>Parameters:</h4> <li> <tt>handle:</tt> <a href="../classes/Point.html"><tt>Point</tt></a> &mdash;&nbsp;the handle of the newly added quadratic curve out of which the values for <a href="../classes/Segment.html#handleout"><tt>segment.handleOut</tt></a> of the resulting cubic curve&rsquo;s first segment and <a href="../classes/Segment.html#handlein"><tt>segment.handleIn</tt></a> of its second segment are calculated </li> <li> <tt>to:</tt> <a href="../classes/Point.html"><tt>Point</tt></a> &mdash;&nbsp;the destination point of the newly added curve </li>