2011-07-01 06:17:45 -04:00
/ *
2013-01-28 21:03:27 -05:00
* Paper . js - The Swiss Army Knife of Vector Graphics Scripting .
2011-07-01 06:17:45 -04:00
* http : //paperjs.org/
*
2020-05-23 16:24:42 -04:00
* Copyright ( c ) 2011 - 2020 , Jürg Lehni & Jonathan Puckey
* http : //juerglehni.com/ & https://puckey.studio/
2011-07-01 06:17:45 -04:00
*
* Distributed under the MIT license . See LICENSE file for details .
*
* All rights reserved .
* /
2016-01-27 13:57:07 -05:00
QUnit . module ( 'Path' ) ;
2011-04-11 17:30:08 -04:00
2016-07-25 15:42:06 -04:00
test ( 'Path#length' , function ( ) {
2016-02-02 07:55:36 -05:00
var path = new Path ( [
2016-02-26 06:58:50 -05:00
new Segment ( [ 121 , 334 ] , [ - 19 , 38 ] , [ 30.7666015625 , - 61.53369140625 ] ) ,
new Segment ( [ 248 , 320 ] , [ - 42 , - 74 ] , [ 42 , 74 ] )
2016-02-02 07:55:36 -05:00
] ) ;
2016-02-26 06:58:50 -05:00
equals ( function ( ) {
return path . length ;
} , 172.10112809179614 ) ;
equals ( function ( ) {
return path . curves [ 0 ] . getTimeAt ( path . length / 4 ) ;
} , 0.2255849553116685 ) ;
} ) ;
2016-07-25 15:42:06 -04:00
test ( 'Path#area' , function ( ) {
2016-02-26 06:58:50 -05:00
var rect = new Path . Rectangle ( {
point : [ 0 , 0 ] ,
size : [ 10 , 10 ]
} ) ;
2016-02-02 07:55:36 -05:00
2016-02-26 06:58:50 -05:00
equals ( function ( ) {
return rect . area ;
} , 100 ) ;
var circle = new Path . Circle ( {
center : [ 0 , 0 ] ,
radius : 10
} ) ;
equals ( function ( ) {
return circle . area ;
} , Math . PI * 100 , null , { tolerance : 0.1 } ) ;
2016-02-02 07:55:36 -05:00
} ) ;
2016-07-25 15:42:06 -04:00
test ( 'Path#equals(path)' , function ( ) {
var path1 = new Path ( {
segments : [
[ 1 , 1 ] ,
[ 2 , 2 ] ,
[ 3 , 3 ] ,
]
} ) ;
var path2 = new Path ( {
segments : [
[ 1 , 1 ] ,
[ 2 , 2 ] ,
[ 3 , 3 ] ,
]
} ) ;
equals ( function ( ) {
return path1 . equals ( path2 ) ;
} , true ) ;
path2 . strokeWidth = path1 . strokeWidth ;
equals ( function ( ) {
return path1 . equals ( path2 ) ;
} , true ) ;
path1 . strokeWidth = path2 . strokeWidth ;
equals ( function ( ) {
return path1 . equals ( path2 ) ;
} , true ) ;
path1 . strokeWidth = path2 . strokeWidth = 10 ;
equals ( function ( ) {
return path1 . equals ( path2 ) ;
} , true ) ;
2016-02-02 07:55:36 -05:00
} ) ;
2016-07-25 15:42:06 -04:00
test ( 'Path#join(path)' , function ( ) {
2016-06-11 06:41:23 -04:00
var path1 = new Path ( ) ;
path1 . add ( 0 , 0 ) ;
path1 . add ( 10 , 0 ) ;
2014-08-16 13:24:54 -04:00
var path2 = new Path ( ) ;
path2 . add ( 10 , 0 ) ;
path2 . add ( 20 , 10 ) ;
2016-06-11 06:41:23 -04:00
path1 . join ( path2 ) ;
equals ( path1 . segments . toString ( ) , '{ point: { x: 0, y: 0 } },{ point: { x: 10, y: 0 } },{ point: { x: 20, y: 10 } }' ) ;
equals ( function ( ) { return paper . project . activeLayer . children . length ; } , 1 ) ;
2014-08-16 13:24:54 -04:00
2016-06-11 06:41:23 -04:00
var path1 = new Path ( ) ;
path1 . add ( 0 , 0 ) ;
path1 . add ( 10 , 0 ) ;
2014-08-16 13:24:54 -04:00
var path2 = new Path ( ) ;
path2 . add ( 20 , 10 ) ;
path2 . add ( 10 , 0 ) ;
2016-06-11 06:41:23 -04:00
path1 . join ( path2 ) ;
equals ( path1 . segments . toString ( ) , '{ point: { x: 0, y: 0 } },{ point: { x: 10, y: 0 } },{ point: { x: 20, y: 10 } }' ) ;
2014-08-16 13:24:54 -04:00
2016-06-11 06:41:23 -04:00
var path1 = new Path ( ) ;
path1 . add ( 0 , 0 ) ;
path1 . add ( 10 , 0 ) ;
2014-08-16 13:24:54 -04:00
var path2 = new Path ( ) ;
path2 . add ( 30 , 10 ) ;
path2 . add ( 40 , 0 ) ;
2016-06-11 06:41:23 -04:00
path1 . join ( path2 ) ;
equals ( path1 . segments . toString ( ) , '{ point: { x: 0, y: 0 } },{ point: { x: 10, y: 0 } },{ point: { x: 30, y: 10 } },{ point: { x: 40, y: 0 } }' ) ;
2014-08-16 13:24:54 -04:00
2016-06-11 06:41:23 -04:00
var path1 = new Path ( ) ;
path1 . add ( 0 , 0 ) ;
path1 . add ( 10 , 0 ) ;
path1 . add ( 20 , 10 ) ;
2014-08-16 13:24:54 -04:00
var path2 = new Path ( ) ;
path2 . add ( 0 , 0 ) ;
path2 . add ( 10 , 5 ) ;
path2 . add ( 20 , 10 ) ;
2016-06-11 06:41:23 -04:00
path1 . join ( path2 ) ;
equals ( path1 . segments . toString ( ) , '{ point: { x: 0, y: 0 } },{ point: { x: 10, y: 0 } },{ point: { x: 20, y: 10 } },{ point: { x: 10, y: 5 } }' ) ;
equals ( function ( ) { return path1 . closed ; } , true ) ;
} ) ;
2016-07-25 15:42:06 -04:00
test ( 'Path#join(path, tolerance)' , function ( ) {
2016-06-11 06:41:23 -04:00
var path1 = new Path ( ) ;
path1 . add ( 0 , 0 ) ;
path1 . add ( 10 , 0 ) ;
var path2 = new Path ( ) ;
path2 . add ( path1 . lastSegment . point . add ( 1e-14 ) ) ;
path2 . add ( 20 , 10 ) ;
2014-08-16 13:24:54 -04:00
equals ( function ( ) {
2016-06-11 06:41:23 -04:00
return path1 . clone ( ) . join ( path2 . clone ( ) , 0 ) . segments . length ;
} , 4 ) ;
equals ( function ( ) {
return path1 . clone ( ) . join ( path2 . clone ( ) , 1e-12 ) . segments . length ;
} , 3 ) ;
2011-04-13 10:16:32 -04:00
} ) ;
2016-07-25 15:42:06 -04:00
test ( 'Path#remove()' , function ( ) {
2014-08-16 13:24:54 -04:00
var path = new Path ( ) ;
path . add ( 0 , 0 ) ;
path . add ( 10 , 0 ) ;
path . add ( 20 , 0 ) ;
path . add ( 30 , 0 ) ;
path . removeSegment ( 0 ) ;
equals ( function ( ) {
return path . segments . length ;
} , 3 ) ;
path . removeSegment ( 0 ) ;
equals ( function ( ) {
return path . segments . length ;
} , 2 ) ;
path . removeSegments ( 0 , 1 ) ;
equals ( function ( ) {
return path . segments . length ;
} , 1 ) ;
path . remove ( ) ;
equals ( function ( ) {
return paper . project . activeLayer . children . length ;
} , 0 ) ;
2011-04-22 05:39:12 -04:00
} ) ;
2016-07-25 15:42:06 -04:00
test ( 'Path#removeSegments()' , function ( ) {
2014-08-16 13:24:54 -04:00
var path = new Path ( ) ;
path . add ( 0 , 0 ) ;
path . add ( 10 , 0 ) ;
path . add ( 20 , 0 ) ;
path . add ( 30 , 0 ) ;
path . removeSegments ( ) ;
equals ( function ( ) {
return path . segments . length ;
} , 0 ) ;
2011-06-05 13:50:24 -04:00
} ) ;
2011-04-22 05:39:12 -04:00
2011-04-22 05:40:54 -04:00
test ( 'Is the path deselected after setting a new list of segments?' , function ( ) {
2014-08-16 13:24:54 -04:00
var path = new Path ( [ 0 , 0 ] ) ;
path . selected = true ;
equals ( function ( ) {
return path . selected ;
} , true ) ;
equals ( function ( ) {
return paper . project . selectedItems . length ;
} , 1 ) ;
path . segments = [ [ 0 , 10 ] ] ;
equals ( function ( ) {
return path . selected ;
} , true ) ;
equals ( function ( ) {
return paper . project . selectedItems . length ;
} , 1 ) ;
2011-04-27 06:13:28 -04:00
} ) ;
2013-10-17 06:03:46 -04:00
test ( 'Setting Path#fullySelected=true on an empty path should only set path#selected=true' , function ( ) {
2014-08-16 13:24:54 -04:00
var path = new Path ( ) ;
path . fullySelected = true ;
equals ( function ( ) {
return path . fullySelected ;
} , false ) ;
equals ( function ( ) {
return path . selected ;
} , true ) ;
2011-06-14 06:19:54 -04:00
} ) ;
2013-10-17 06:03:46 -04:00
test ( 'After removing all segments of a fully selected path, it should still be selected.' , function ( ) {
2014-08-16 13:24:54 -04:00
var path = new Path ( [ 10 , 20 ] , [ 30 , 40 ] ) ;
path . fullySelected = true ;
equals ( function ( ) {
return path . fullySelected ;
} , true ) ;
path . removeSegments ( ) ;
equals ( function ( ) {
return path . fullySelected ;
} , false ) ;
equals ( function ( ) {
return path . selected ;
} , true ) ;
2011-06-20 11:00:41 -04:00
} ) ;
test ( 'After removing all segments of a selected path, it should still be selected.' , function ( ) {
2014-08-16 13:24:54 -04:00
var path = new Path ( [ 10 , 20 ] , [ 30 , 40 ] ) ;
path . selected = true ;
path . removeSegments ( ) ;
equals ( function ( ) {
return path . selected ;
} , true ) ;
2011-06-20 11:00:41 -04:00
} ) ;
2011-06-20 13:17:07 -04:00
test ( 'After simplifying a path using #simplify(), the path should stay fullySelected' , function ( ) {
2014-08-16 13:24:54 -04:00
var path = new Path ( ) ;
for ( var i = 0 ; i < 30 ; i ++ ) {
path . add ( i * 10 , 10 ) ;
}
path . fullySelected = true ;
equals ( function ( ) {
return path . selected ;
} , true ) ;
path . simplify ( ) ;
equals ( function ( ) {
return path . selected ;
} , true ) ;
equals ( function ( ) {
return path . fullySelected ;
} , true ) ;
2011-06-20 19:31:07 -04:00
} ) ;
test ( 'After cloning a selected item, it should be added to the Project#selectedItems array' , function ( ) {
2014-08-16 13:24:54 -04:00
var path = new Path . Circle ( new Size ( 80 , 50 ) , 35 ) ;
path . selected = true ;
var copy = path . clone ( ) ;
2011-07-07 10:09:02 -04:00
2014-08-16 13:24:54 -04:00
equals ( function ( ) {
return paper . project . selectedItems . length ;
} , 2 ) ;
2011-06-20 19:31:07 -04:00
} ) ;
2011-06-20 13:17:07 -04:00
test ( 'After simplifying a path using #simplify(), the path should stay selected' , function ( ) {
2014-08-16 13:24:54 -04:00
var path = new Path ( ) ;
for ( var i = 0 ; i < 30 ; i ++ ) {
path . add ( i * 10 , ( i % 2 ? 20 : 40 ) ) ;
}
path . selected = true ;
path . simplify ( ) ;
equals ( function ( ) {
return path . selected ;
} , true ) ;
2011-06-20 10:51:13 -04:00
} ) ;
test ( 'After smoothing a path using #smooth(), the path should stay fullySelected' , function ( ) {
2014-08-16 13:24:54 -04:00
var path = new Path ( ) ;
for ( var i = 0 ; i < 30 ; i ++ ) {
path . add ( i * 10 , ( i % 2 ? 20 : 40 ) ) ;
}
path . fullySelected = true ;
path . smooth ( ) ;
equals ( function ( ) {
return path . fullySelected ;
} , true ) ;
2011-06-20 10:51:13 -04:00
} ) ;
test ( 'After smoothing a path using #smooth(), the path should stay selected' , function ( ) {
2014-08-16 13:24:54 -04:00
var path = new Path ( ) ;
for ( var i = 0 ; i < 30 ; i ++ ) {
path . add ( i * 10 , ( i % 2 ? 20 : 40 ) ) ;
}
path . selected = true ;
path . smooth ( ) ;
equals ( function ( ) {
return path . selected ;
} , true ) ;
2011-06-20 10:51:13 -04:00
} ) ;
2011-06-17 08:10:10 -04:00
test ( 'After selecting a segment, Path#selected should return true' , function ( ) {
2014-08-16 13:24:54 -04:00
var path = new Path ( ) ;
path . add ( [ 10 , 10 ] ) ;
path . firstSegment . selected = true ;
equals ( function ( ) {
return path . selected ;
} , true ) ;
2011-06-17 08:10:10 -04:00
} ) ;
2016-07-25 15:42:06 -04:00
test ( 'Path#reverse()' , function ( ) {
2014-08-16 13:24:54 -04:00
var path = new Path . Circle ( [ 100 , 100 ] , 30 ) ;
path . reverse ( ) ;
equals ( path . segments . toString ( ) , '{ point: { x: 100, y: 130 }, handleIn: { x: -16.56854, y: 0 }, handleOut: { x: 16.56854, y: 0 } },{ point: { x: 130, y: 100 }, handleIn: { x: 0, y: 16.56854 }, handleOut: { x: 0, y: -16.56854 } },{ point: { x: 100, y: 70 }, handleIn: { x: 16.56854, y: 0 }, handleOut: { x: -16.56854, y: 0 } },{ point: { x: 70, y: 100 }, handleIn: { x: 0, y: -16.56854 }, handleOut: { x: 0, y: 16.56854 } }' ) ;
2011-04-27 06:13:28 -04:00
} ) ;
2016-07-25 15:42:06 -04:00
test ( 'Path#reverse() should adjust segment indices' , function ( ) {
2014-08-16 13:24:54 -04:00
var path = new Path ( [ [ 0 , 0 ] , [ 10 , 10 ] , [ 20 , 20 ] ] ) ;
path . reverse ( ) ;
equals ( path . segments [ 0 ] . index , 0 ) ;
equals ( path . segments [ 1 ] . index , 1 ) ;
equals ( path . segments [ 2 ] . index , 2 ) ;
2012-02-18 18:13:23 -05:00
} ) ;
2011-06-05 14:08:46 -04:00
test ( 'Path#fullySelected' , function ( ) {
2014-08-16 13:24:54 -04:00
var path = new Path . Circle ( [ 100 , 100 ] , 10 ) ;
path . fullySelected = true ;
path . segments [ 1 ] . selected = false ;
equals ( function ( ) {
return path . fullySelected ;
} , false ) ;
2012-02-18 18:13:23 -05:00
} ) ;
2013-02-27 11:34:28 -05:00
test ( 'Simplifying a path with three segments of the same position should not throw an error' , function ( ) {
2014-08-16 13:24:54 -04:00
var path = new Path ( [ 20 , 20 ] , [ 20 , 20 ] , [ 20 , 20 ] ) ;
path . simplify ( ) ;
equals ( function ( ) {
return path . segments . length ;
} , 1 ) ;
2016-02-02 16:11:06 -05:00
} ) ;
2016-07-25 15:42:06 -04:00
test ( 'Path#interpolate(from, to, factor)' , function ( ) {
2016-02-02 16:11:06 -05:00
var path = new Path ( ) ,
path0 = new Path . Circle ( {
center : [ 0 , 0 ] ,
radius : 10
} ) ,
path1 = new Path . Ellipse ( {
center : [ 10 , 20 ] ,
radius : [ 20 , 10 ]
} ) ,
halfway = new Path . Ellipse ( {
center : [ 5 , 10 ] ,
radius : [ 15 , 10 ]
} ) ;
path . interpolate ( path0 , path1 , 0 ) ;
equals ( path , path0 ) ;
path . interpolate ( path0 , path1 , 1 ) ;
equals ( path , path1 ) ;
path . interpolate ( path0 , path1 , 0.5 ) ;
equals ( path , halfway ) ;
2013-02-27 11:34:28 -05:00
} ) ;
2016-02-02 07:55:36 -05:00
2016-05-22 15:17:24 -04:00
////////////////////////////////////////////////////////////////////////////////
// Path Curves
2016-02-02 07:55:36 -05:00
2016-07-25 15:42:06 -04:00
test ( 'Path#curves synchronisation' , function ( ) {
2016-02-02 07:55:36 -05:00
var path = new Path ( ) ;
path . add ( new Point ( 100 , 100 ) ) ;
equals ( path . segments . toString ( ) , "{ point: { x: 100, y: 100 } }" , "path.segments: path.add(new Point(100, 100));" ) ;
equals ( path . curves . toString ( ) , "" , "path.curves: path.add(new Point(100, 100));" ) ;
path . insert ( 0 , new Point ( 0 , 100 ) ) ;
equals ( path . segments . toString ( ) , "{ point: { x: 0, y: 100 } },{ point: { x: 100, y: 100 } }" , "path.segments: path.insert(0, new Point(0, 100));" ) ;
equals ( path . curves . toString ( ) , "{ point1: { x: 0, y: 100 }, point2: { x: 100, y: 100 } }" , "path.curves: path.insert(0, new Point(0, 100));" ) ;
path . insert ( 1 , { point : [ 50 , 0 ] , handleIn : [ - 25 , 0 ] , handleOut : [ 25 , 0 ] } ) ;
equals ( path . segments . toString ( ) , "{ point: { x: 0, y: 100 } },{ point: { x: 50, y: 0 }, handleIn: { x: -25, y: 0 }, handleOut: { x: 25, y: 0 } },{ point: { x: 100, y: 100 } }" , "path.segments: path.insert(1, {point:[50, 0], handleIn:[-25, 0], handleOut:[25, 0]});" ) ;
equals ( path . curves . toString ( ) , "{ point1: { x: 0, y: 100 }, handle2: { x: -25, y: 0 }, point2: { x: 50, y: 0 } },{ point1: { x: 50, y: 0 }, handle1: { x: 25, y: 0 }, point2: { x: 100, y: 100 } }" , "path.curves: path.insert(1, {point:[50, 0], handleIn:[-25, 0], handleOut:[25, 0]});" ) ;
path . closed = true ;
equals ( path . segments . toString ( ) , "{ point: { x: 0, y: 100 } },{ point: { x: 50, y: 0 }, handleIn: { x: -25, y: 0 }, handleOut: { x: 25, y: 0 } },{ point: { x: 100, y: 100 } }" , "path.segments: path.closed = true;" ) ;
equals ( path . curves . toString ( ) , "{ point1: { x: 0, y: 100 }, handle2: { x: -25, y: 0 }, point2: { x: 50, y: 0 } },{ point1: { x: 50, y: 0 }, handle1: { x: 25, y: 0 }, point2: { x: 100, y: 100 } },{ point1: { x: 100, y: 100 }, point2: { x: 0, y: 100 } }" , "path.curves: path.closed = true;" ) ;
path . removeSegments ( 2 , 3 ) ;
equals ( path . segments . toString ( ) , "{ point: { x: 0, y: 100 } },{ point: { x: 50, y: 0 }, handleIn: { x: -25, y: 0 }, handleOut: { x: 25, y: 0 } }" , "path.segments: path.removeSegments(2, 3);" ) ;
equals ( path . curves . toString ( ) , "{ point1: { x: 0, y: 100 }, handle2: { x: -25, y: 0 }, point2: { x: 50, y: 0 } },{ point1: { x: 50, y: 0 }, handle1: { x: 25, y: 0 }, point2: { x: 0, y: 100 } }" , "path.curves: path.removeSegments(2, 3);" ) ;
path . add ( new Point ( 100 , 100 ) ) ;
path . removeSegments ( 1 , 2 ) ;
equals ( path . segments . toString ( ) , "{ point: { x: 0, y: 100 } },{ point: { x: 100, y: 100 } }" , "path.segments: path.add(new Point(100, 100));\npath.removeSegments(1, 2);" ) ;
equals ( path . curves . toString ( ) , "{ point1: { x: 0, y: 100 }, point2: { x: 100, y: 100 } },{ point1: { x: 100, y: 100 }, point2: { x: 0, y: 100 } }" , "path.curves: path.add(new Point(100, 100));\npath.removeSegments(1, 2);" ) ;
// Transform the path, and the curves length should be invalidated (first, force-cache the first segment's length by accessing it
var length = path . curves [ 0 ] . length ;
ok ( path . curves [ 0 ] . _length , 'Curve length does not appear to be cached' ) ;
path . scale ( 2 , [ 0 , 0 ] ) ;
equals ( path . curves [ 0 ] . length , 200 , 'Curve length should be updated when path is transformed' ) ;
var points = [ ] ;
for ( var i = 0 ; i < 40 ; i ++ )
points . push ( Point . random ( ) ) ;
var path = new Path ( points ) ;
equals ( path . segments . length , 40 , 'segments.length' ) ;
equals ( path . curves . length , 39 , 'curves.length' ) ;
path . removeSegments ( ) ;
equals ( path . segments . length , 0 , 'segments.length' ) ;
equals ( path . curves . length , 0 , 'curves.length' ) ;
} ) ;
2016-07-25 15:42:06 -04:00
test ( 'Path#curves on closed paths' , function ( ) {
2016-02-02 07:55:36 -05:00
var path = new Path . Circle ( new Point ( 100 , 100 ) , 100 ) ;
equals ( path . curves . toString ( ) , "{ point1: { x: 0, y: 100 }, handle1: { x: 0, y: -55.22847 }, handle2: { x: -55.22847, y: 0 }, point2: { x: 100, y: 0 } },{ point1: { x: 100, y: 0 }, handle1: { x: 55.22847, y: 0 }, handle2: { x: 0, y: -55.22847 }, point2: { x: 200, y: 100 } },{ point1: { x: 200, y: 100 }, handle1: { x: 0, y: 55.22847 }, handle2: { x: 55.22847, y: 0 }, point2: { x: 100, y: 200 } },{ point1: { x: 100, y: 200 }, handle1: { x: -55.22847, y: 0 }, handle2: { x: 0, y: 55.22847 }, point2: { x: 0, y: 100 } }" ) ;
path . removeSegments ( 0 , 1 ) ;
equals ( path . curves . toString ( ) , "{ point1: { x: 100, y: 0 }, handle1: { x: 55.22847, y: 0 }, handle2: { x: 0, y: -55.22847 }, point2: { x: 200, y: 100 } },{ point1: { x: 200, y: 100 }, handle1: { x: 0, y: 55.22847 }, handle2: { x: 55.22847, y: 0 }, point2: { x: 100, y: 200 } },{ point1: { x: 100, y: 200 }, handle1: { x: -55.22847, y: 0 }, handle2: { x: -55.22847, y: 0 }, point2: { x: 100, y: 0 } }" ) ;
} ) ;
2016-07-25 15:42:06 -04:00
test ( 'Path#flatten(maxDistance)' , function ( ) {
2016-02-02 07:55:36 -05:00
var path = new Path . Circle ( new Size ( 80 , 50 ) , 35 ) ;
2016-02-10 08:58:40 -05:00
// Convert its curves to points, with a flatness of 5:
path . flatten ( 5 ) ;
equals ( function ( ) {
return path . segments . length ;
} , 8 , 'Using a flatness of 10, we should end up with 8 segments.' ) ;
2016-02-02 07:55:36 -05:00
equals ( function ( ) {
return path . lastSegment . point . equals ( path . firstSegment . point ) ;
} , false , 'The points of the last and first segments should not be the same.' ) ;
equals ( function ( ) {
2016-02-10 07:26:40 -05:00
return path . lastSegment . point . toString ( ) != path . lastSegment . previous . point . toString ( ) ;
2016-02-02 07:55:36 -05:00
} , true , 'The points of the last and before last segments should not be so close, that calling toString on them returns the same string value.' ) ;
} ) ;
2018-10-15 03:27:50 -04:00
test ( 'Path#single segment closed path flatten (#1338)' , function ( ) {
var p = PathItem . create ( "m445.26701,223.69688c6.1738,8.7566 -7.05172,14.0468 0,0z" ) ;
p . strokeColor = "red" ;
p . flatten ( ) ;
expect ( 0 ) ;
} ) ;
2016-07-25 15:42:06 -04:00
test ( 'Path#curves after removing a segment - 1' , function ( ) {
2016-02-02 07:55:36 -05:00
var path = new paper . Path ( [ 0 , 0 ] , [ 1 , 1 ] , [ 2 , 2 ] ) ;
var prevCurves = path . curves . slice ( ) ;
equals ( function ( ) {
return path . curves . length ;
} , 2 , 'After creating a path with three segments, we should have two curves. By accessing path.curves we also make sure the curves are created internally.' ) ;
equals ( function ( ) {
return path . segments [ 1 ] . remove ( ) ;
} , true , 'Removing the paths second segment should be successful.' ) ;
equals ( function ( ) {
return path . curves . length ;
} , 1 , 'After removing the middle segment, we should be left with one curve.' ) ;
equals ( function ( ) {
return path . curves [ 0 ] === prevCurves [ 0 ] ;
} , true , 'The remaining curve should be the same as in the previous state of the curves array.' ) ;
equals ( function ( ) {
return path . curves [ 0 ] . path === path ;
} , true , 'The remaining curve should stay linked to the path.' ) ;
equals ( function ( ) {
return prevCurves [ 1 ] . path === null ;
} , true , 'The removed curve should not stay linked to the path.' ) ;
} ) ;
2016-07-25 15:42:06 -04:00
test ( 'Path#curves after removing a segment - 2' , function ( ) {
2016-02-02 07:55:36 -05:00
var path = new paper . Path ( [ 0 , 0 ] , [ 1 , 1 ] , [ 2 , 2 ] ) ;
equals ( function ( ) {
return path . curves . length ;
} , 2 , 'After creating a path with three segments, we should have two curves. By accessing path.curves we also make sure the curves are created internally.' ) ;
equals ( function ( ) {
return path . lastSegment . remove ( ) ;
} , true , 'Removing the last segment should be successful.' ) ;
equals ( function ( ) {
return path . curves . length ;
} , 1 , 'After removing the last segment, we should be left with one curve.' ) ;
equals ( function ( ) {
return path . lastSegment . remove ( ) ;
} , true , 'Removing last segment should be successful.' ) ;
equals ( function ( ) {
return path . curves . length ;
} , 0 , 'After removing the last segment, we should be left with no curves.' ) ;
equals ( function ( ) {
return path . lastSegment . remove ( ) ;
} , true , 'Removing the final remaining segment should be successful.' ) ;
equals ( function ( ) {
return path . curves . length ;
} , 0 , 'After removing all segments, we should be left with no curves.' ) ;
path . addSegment ( [ 0 , 0 ] ) ;
path . addSegment ( [ 1 , 1 ] ) ;
equals ( function ( ) {
return path . curves . length ;
} , 1 , 'After adding two new segments, we should have one curve again.' ) ;
path . addSegment ( [ 2 , 2 ] ) ;
equals ( function ( ) {
return path . curves . length ;
} , 2 , 'After adding a new segment, we should have two curves again.' ) ;
equals ( function ( ) {
return path . curves [ 1 ] . segment1 === path . curves [ 0 ] . segment2 ;
} , true , "The newly created curve's first segment needs to be the same as the previous curve's second segment." ) ;
path . addSegments ( [ [ 3 , 3 ] , [ 4 , 4 ] ] ) ;
equals ( function ( ) {
return path . curves . length ;
} , 4 , 'After adding two new segments at the end, we should have four curves now.' ) ;
} ) ;
test ( 'Splitting a straight path should produce segments without handles' , function ( ) {
var path1 = new Path . Line ( [ 0 , 0 ] , [ 50 , 50 ] ) ;
2016-03-14 13:59:09 -04:00
var path2 = path1 . splitAt ( path1 . length / 2 ) ;
2016-02-02 07:55:36 -05:00
equals ( function ( ) {
return ! path1 . lastSegment . hasHandles ( ) && ! path2 . firstSegment . hasHandles ( ) ;
} , true ) ;
} ) ;
test ( 'Splitting a path with one curve in the middle result in two paths of the same length with one curve each' , function ( ) {
var path1 = new Path . Line ( [ 0 , 0 ] , [ 100 , 100 ] ) ;
2016-03-14 13:59:09 -04:00
var loc = path1 . getLocationAt ( path1 . length / 2 ) ;
var path2 = path1 . splitAt ( loc ) ;
2016-02-02 07:55:36 -05:00
equals ( function ( ) {
return path1 . curves . length ;
} , 1 ) ;
equals ( function ( ) {
return path2 . curves . length ;
} , 1 ) ;
equals ( function ( ) {
return path1 . length === path2 . length ;
} , true ) ;
} ) ;
2016-05-22 15:17:24 -04:00
////////////////////////////////////////////////////////////////////////////////
// Path Drawing Commands
2016-02-02 07:55:36 -05:00
2016-07-25 15:42:06 -04:00
test ( 'Path#lineTo(point);' , function ( ) {
2016-02-02 07:55:36 -05:00
var path = new Path ( ) ;
path . moveTo ( [ 50 , 50 ] ) ;
path . lineTo ( [ 100 , 100 ] ) ;
equals ( path . segments . toString ( ) , '{ point: { x: 50, y: 50 } },{ point: { x: 100, y: 100 } }' ) ;
} ) ;
2016-07-25 15:42:06 -04:00
test ( 'Path#arcTo(from, through, to);' , function ( ) {
2016-02-02 07:55:36 -05:00
var path = new Path ( ) ;
path . moveTo ( [ 0 , 20 ] ) ;
path . arcTo ( [ 75 , 75 ] , [ 100 , 0 ] ) ;
equals ( path . segments . toString ( ) , '{ point: { x: 0, y: 20 }, handleOut: { x: -2.62559, y: 23.01251 } },{ point: { x: 30.89325, y: 74.75812 }, handleIn: { x: -21.05455, y: -9.65273 }, handleOut: { x: 21.05455, y: 9.65273 } },{ point: { x: 92.54397, y: 62.42797 }, handleIn: { x: -15.72238, y: 17.00811 }, handleOut: { x: 15.72238, y: -17.00811 } },{ point: { x: 100, y: 0 }, handleIn: { x: 11.27458, y: 20.23247 } }' ) ;
} ) ;
2016-07-25 15:42:06 -04:00
test ( 'Path#arcTo(from, through, to); where from, through and to all share the same y position and through lies in between from and to' , function ( ) {
2016-02-02 07:55:36 -05:00
var path = new Path ( ) ;
path . strokeColor = 'black' ;
path . add ( [ 40 , 75 ] ) ;
path . arcTo ( [ 50 , 75 ] , [ 100 , 75 ] ) ;
equals ( path . lastSegment . point . toString ( ) , '{ x: 100, y: 75 }' , 'We expect the last segment point to be at the position where we wanted to draw the arc to.' ) ;
} ) ;
2016-07-25 15:42:06 -04:00
test ( 'Path#arcTo(from, through, to); where from, through and to all share the same y position and through lies to the right of to' , function ( ) {
2016-02-02 07:55:36 -05:00
var path = new Path ( ) ;
path . strokeColor = 'black' ;
path . add ( [ 40 , 75 ] ) ;
var error = null ;
try {
path . arcTo ( [ 150 , 75 ] , [ 100 , 75 ] ) ;
} catch ( e ) {
error = e ;
}
equals ( error != null , true , 'We expect this arcTo() command to throw an error' ) ;
} ) ;
2016-07-25 15:42:06 -04:00
test ( 'Path#arcTo(from, through, to); where from, through and to all share the same y position and through lies to the left of to' , function ( ) {
2016-02-02 07:55:36 -05:00
var path = new Path ( ) ;
path . strokeColor = 'black' ;
path . add ( [ 40 , 75 ] ) ;
var error = null ;
try {
path . arcTo ( [ 10 , 75 ] , [ 100 , 75 ] ) ;
} catch ( e ) {
error = e ;
}
equals ( error != null , true , 'We expect this arcTo() command to throw an error' ) ;
} ) ;
2018-10-02 08:09:34 -04:00
2018-10-05 03:44:42 -04:00
test ( 'Path#getOffsetsWithTangent()' , function ( ) {
var path = new Path . Circle ( new Point ( 0 , 0 ) , 50 ) ;
var length = path . length ;
equals ( path . getOffsetsWithTangent ( ) , [ ] , 'should return empty array when called without argument' ) ;
equals ( path . getOffsetsWithTangent ( [ 1 , 0 ] ) , [ 0.25 * length , 0.75 * length ] , 'should not return duplicates when tangent is at segment point' ) ;
equals ( path . getOffsetsWithTangent ( [ 1 , 1 ] ) . length , 2 , 'should return 2 values when called on a circle with a diagonal vector' ) ;
} ) ;
2020-05-23 08:54:51 -04:00
2018-10-03 10:45:38 -04:00
test ( 'Path#add() with a lot of segments (#1493)' , function ( ) {
var segments = [ ] ;
for ( var i = 0 ; i < 100000 ; i ++ ) {
segments . push ( new Point ( 0 , 0 ) ) ;
2018-10-02 08:09:34 -04:00
}
2018-10-03 10:45:38 -04:00
var path = new Path ( segments ) ;
2018-10-02 08:09:34 -04:00
path . clone ( ) ;
expect ( 0 ) ;
} ) ;
2018-10-13 09:33:21 -04:00
test ( 'Path#arcTo(through, to) is on through point side (#1477)' , function ( ) {
var p1 = new Point ( 16 , 21.5 ) ;
var p2 = new Point ( 22.5 , 15 ) ;
var p3 = new Point ( 16.000000000000004 , 8.5 ) ;
var path = new Path ( ) ;
path . add ( p1 ) ;
path . arcTo ( p2 , p3 ) ;
equals ( true , path . segments [ 1 ] . point . x > p1 . x ) ;
} ) ;
2018-11-23 05:04:45 -05:00
test ( 'Path#arcTo(to, radius, rotation, clockwise, large) when from and to are equal (#1613)' , function ( ) {
var point = new Point ( 10 , 10 ) ;
var path = new Path ( ) ;
path . moveTo ( point ) ;
path . arcTo ( point , new Size ( 10 ) , 0 , true , true ) ;
expect ( 0 ) ;
} ) ;
2020-05-23 08:54:51 -04:00
test ( 'Path#closed with blend mode' , function ( ) {
new Path ( {
strokeColor : 'black' ,
blendMode : 'negation' ,
closed : true
} ) ;
view . update ( ) ;
expect ( 0 ) ;
} ) ;