mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2024-12-29 09:22:22 -05:00
665 lines
23 KiB
JavaScript
665 lines
23 KiB
JavaScript
/*
|
|
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
|
|
* http://paperjs.org/
|
|
*
|
|
* Copyright (c) 2011 - 2020, Jürg Lehni & Jonathan Puckey
|
|
* http://juerglehni.com/ & https://puckey.studio/
|
|
*
|
|
* Distributed under the MIT license. See LICENSE file for details.
|
|
*
|
|
* All rights reserved.
|
|
*/
|
|
|
|
QUnit.module('Path');
|
|
|
|
test('Path#length', function() {
|
|
var path = new Path([
|
|
new Segment([121, 334], [-19, 38], [30.7666015625, -61.53369140625]),
|
|
new Segment([248, 320], [-42, -74], [42, 74])
|
|
]);
|
|
|
|
equals(function() {
|
|
return path.length;
|
|
}, 172.10112809179614);
|
|
|
|
equals(function() {
|
|
return path.curves[0].getTimeAt(path.length / 4);
|
|
}, 0.2255849553116685);
|
|
});
|
|
|
|
test('Path#area', function() {
|
|
var rect = new Path.Rectangle({
|
|
point: [0, 0],
|
|
size: [10, 10]
|
|
});
|
|
|
|
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 });
|
|
});
|
|
|
|
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);
|
|
});
|
|
|
|
test('Path#join(path)', function() {
|
|
var path1 = new Path();
|
|
path1.add(0, 0);
|
|
path1.add(10, 0);
|
|
|
|
var path2 = new Path();
|
|
path2.add(10, 0);
|
|
path2.add(20, 10);
|
|
|
|
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);
|
|
|
|
var path1 = new Path();
|
|
path1.add(0, 0);
|
|
path1.add(10, 0);
|
|
|
|
var path2 = new Path();
|
|
path2.add(20, 10);
|
|
path2.add(10, 0);
|
|
path1.join(path2);
|
|
equals(path1.segments.toString(), '{ point: { x: 0, y: 0 } },{ point: { x: 10, y: 0 } },{ point: { x: 20, y: 10 } }');
|
|
|
|
var path1 = new Path();
|
|
path1.add(0, 0);
|
|
path1.add(10, 0);
|
|
|
|
var path2 = new Path();
|
|
path2.add(30, 10);
|
|
path2.add(40, 0);
|
|
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 } }');
|
|
|
|
var path1 = new Path();
|
|
path1.add(0, 0);
|
|
path1.add(10, 0);
|
|
path1.add(20, 10);
|
|
|
|
var path2 = new Path();
|
|
path2.add(0, 0);
|
|
path2.add(10, 5);
|
|
path2.add(20, 10);
|
|
|
|
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);
|
|
});
|
|
|
|
test('Path#join(path, tolerance)', function() {
|
|
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);
|
|
|
|
equals(function() {
|
|
return path1.clone().join(path2.clone(), 0).segments.length;
|
|
}, 4);
|
|
equals(function() {
|
|
return path1.clone().join(path2.clone(), 1e-12).segments.length;
|
|
}, 3);
|
|
});
|
|
|
|
test('Path#remove()', function() {
|
|
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);
|
|
});
|
|
|
|
test('Path#removeSegments()', function() {
|
|
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);
|
|
});
|
|
|
|
test('Is the path deselected after setting a new list of segments?', function() {
|
|
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);
|
|
});
|
|
|
|
test('Setting Path#fullySelected=true on an empty path should only set path#selected=true', function() {
|
|
var path = new Path();
|
|
path.fullySelected = true;
|
|
equals(function() {
|
|
return path.fullySelected;
|
|
}, false);
|
|
equals(function() {
|
|
return path.selected;
|
|
}, true);
|
|
});
|
|
|
|
test('After removing all segments of a fully selected path, it should still be selected.', function() {
|
|
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);
|
|
});
|
|
|
|
test('After removing all segments of a selected path, it should still be selected.', function() {
|
|
var path = new Path([10, 20], [30, 40]);
|
|
path.selected = true;
|
|
path.removeSegments();
|
|
equals(function() {
|
|
return path.selected;
|
|
}, true);
|
|
});
|
|
|
|
test('After simplifying a path using #simplify(), the path should stay fullySelected', function() {
|
|
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);
|
|
});
|
|
|
|
test('After cloning a selected item, it should be added to the Project#selectedItems array', function() {
|
|
var path = new Path.Circle(new Size(80, 50), 35);
|
|
path.selected = true;
|
|
var copy = path.clone();
|
|
|
|
equals(function() {
|
|
return paper.project.selectedItems.length;
|
|
}, 2);
|
|
});
|
|
|
|
test('After simplifying a path using #simplify(), the path should stay selected', function() {
|
|
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);
|
|
});
|
|
|
|
test('After smoothing a path using #smooth(), the path should stay fullySelected', function() {
|
|
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);
|
|
});
|
|
|
|
test('After smoothing a path using #smooth(), the path should stay selected', function() {
|
|
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);
|
|
});
|
|
|
|
test('After selecting a segment, Path#selected should return true', function() {
|
|
var path = new Path();
|
|
path.add([10, 10]);
|
|
path.firstSegment.selected = true;
|
|
equals(function() {
|
|
return path.selected;
|
|
}, true);
|
|
});
|
|
|
|
test('Path#reverse()', function() {
|
|
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 } }');
|
|
});
|
|
|
|
test('Path#reverse() should adjust segment indices', function() {
|
|
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);
|
|
});
|
|
|
|
test('Path#fullySelected', function() {
|
|
var path = new Path.Circle([100, 100], 10);
|
|
path.fullySelected = true;
|
|
path.segments[1].selected = false;
|
|
equals(function() {
|
|
return path.fullySelected;
|
|
}, false);
|
|
});
|
|
|
|
test('Simplifying a path with three segments of the same position should not throw an error', function() {
|
|
var path = new Path([20, 20], [20, 20], [20, 20]);
|
|
path.simplify();
|
|
equals(function() {
|
|
return path.segments.length;
|
|
}, 1);
|
|
});
|
|
|
|
test('Path#interpolate(from, to, factor)', function() {
|
|
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);
|
|
});
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// Path Curves
|
|
|
|
test('Path#curves synchronisation', function() {
|
|
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');
|
|
});
|
|
|
|
test('Path#curves on closed paths', function() {
|
|
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 } }");
|
|
});
|
|
|
|
test('Path#flatten(maxDistance)', function() {
|
|
var path = new Path.Circle(new Size(80, 50), 35);
|
|
|
|
// 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.');
|
|
|
|
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() {
|
|
return path.lastSegment.point.toString() != path.lastSegment.previous.point.toString();
|
|
}, 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.');
|
|
});
|
|
|
|
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);
|
|
});
|
|
|
|
test('Path#curves after removing a segment - 1', function() {
|
|
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.');
|
|
});
|
|
|
|
test('Path#curves after removing a segment - 2', function() {
|
|
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]);
|
|
var path2 = path1.splitAt(path1.length / 2);
|
|
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]);
|
|
var loc = path1.getLocationAt(path1.length / 2);
|
|
var path2 = path1.splitAt(loc);
|
|
equals(function() {
|
|
return path1.curves.length;
|
|
}, 1);
|
|
equals(function() {
|
|
return path2.curves.length;
|
|
}, 1);
|
|
equals(function() {
|
|
return path1.length === path2.length;
|
|
}, true);
|
|
});
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// Path Drawing Commands
|
|
|
|
test('Path#lineTo(point);', function() {
|
|
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 } }');
|
|
});
|
|
|
|
test('Path#arcTo(from, through, to);', function() {
|
|
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 } }');
|
|
});
|
|
|
|
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() {
|
|
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.');
|
|
});
|
|
|
|
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() {
|
|
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');
|
|
});
|
|
|
|
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() {
|
|
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');
|
|
});
|
|
|
|
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');
|
|
});
|
|
|
|
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));
|
|
}
|
|
var path = new Path(segments);
|
|
path.clone();
|
|
expect(0);
|
|
});
|
|
|
|
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);
|
|
});
|
|
|
|
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);
|
|
});
|
|
|
|
test('Path#closed with blend mode', function() {
|
|
new Path({
|
|
strokeColor: 'black',
|
|
blendMode: 'negation',
|
|
closed: true
|
|
});
|
|
view.update();
|
|
expect(0);
|
|
});
|