mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2025-01-01 02:38:43 -05:00
Boolean: Implement options.trace, and add unit tests for options.trace = false
Relates to #1221
This commit is contained in:
parent
ffa7e16f48
commit
3c9d2eea1d
3 changed files with 77 additions and 15 deletions
|
@ -78,12 +78,12 @@ PathItem.inject(new function() {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function computeBoolean(path1, path2, operation, options) {
|
function traceBoolean(path1, path2, operation, options) {
|
||||||
// Only support subtract and intersect operations when computing stroke
|
// Only support subtract and intersect operations when computing stroke
|
||||||
// based boolean operations.
|
// based boolean operations (options.split = true).
|
||||||
if (options && options.stroke &&
|
if (options && (options.trace == false || options.stroke) &&
|
||||||
/^(subtract|intersect)$/.test(operation))
|
/^(subtract|intersect)$/.test(operation))
|
||||||
return computeStrokeBoolean(path1, path2, operation === 'subtract');
|
return splitBoolean(path1, path2, operation === 'subtract');
|
||||||
// We do not modify the operands themselves, but create copies instead,
|
// We do not modify the operands themselves, but create copies instead,
|
||||||
// fas produced by the calls to preparePath().
|
// fas produced by the calls to preparePath().
|
||||||
// NOTE: The result paths might not belong to the same type i.e.
|
// NOTE: The result paths might not belong to the same type i.e.
|
||||||
|
@ -160,7 +160,7 @@ PathItem.inject(new function() {
|
||||||
return createResult(CompoundPath, paths, true, path1, path2, options);
|
return createResult(CompoundPath, paths, true, path1, path2, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
function computeStrokeBoolean(path1, path2, subtract) {
|
function splitBoolean(path1, path2, subtract) {
|
||||||
var _path1 = preparePath(path1),
|
var _path1 = preparePath(path1),
|
||||||
_path2 = preparePath(path2),
|
_path2 = preparePath(path2),
|
||||||
crossings = _path1.getCrossings(_path2),
|
crossings = _path1.getCrossings(_path2),
|
||||||
|
@ -194,7 +194,7 @@ PathItem.inject(new function() {
|
||||||
}
|
}
|
||||||
// At the end, add what's left from our path after all the splitting.
|
// At the end, add what's left from our path after all the splitting.
|
||||||
addPath(_path1);
|
addPath(_path1);
|
||||||
return createResult(Group, paths, false, path1, path2);
|
return createResult(CompoundPath, paths, true, path1, path2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1042,7 +1042,7 @@ PathItem.inject(new function() {
|
||||||
* @return {PathItem} the resulting path item
|
* @return {PathItem} the resulting path item
|
||||||
*/
|
*/
|
||||||
unite: function(path, options) {
|
unite: function(path, options) {
|
||||||
return computeBoolean(this, path, 'unite', options);
|
return traceBoolean(this, path, 'unite', options);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1060,7 +1060,7 @@ PathItem.inject(new function() {
|
||||||
* @return {PathItem} the resulting path item
|
* @return {PathItem} the resulting path item
|
||||||
*/
|
*/
|
||||||
intersect: function(path, options) {
|
intersect: function(path, options) {
|
||||||
return computeBoolean(this, path, 'intersect', options);
|
return traceBoolean(this, path, 'intersect', options);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1078,7 +1078,7 @@ PathItem.inject(new function() {
|
||||||
* @return {PathItem} the resulting path item
|
* @return {PathItem} the resulting path item
|
||||||
*/
|
*/
|
||||||
subtract: function(path, options) {
|
subtract: function(path, options) {
|
||||||
return computeBoolean(this, path, 'subtract', options);
|
return traceBoolean(this, path, 'subtract', options);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1094,7 +1094,7 @@ PathItem.inject(new function() {
|
||||||
* @return {PathItem} the resulting group item
|
* @return {PathItem} the resulting group item
|
||||||
*/
|
*/
|
||||||
exclude: function(path, options) {
|
exclude: function(path, options) {
|
||||||
return computeBoolean(this, path, 'exclude', options);
|
return traceBoolean(this, path, 'exclude', options);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -144,9 +144,15 @@ var comparePixels = function(actual, expected, message, options) {
|
||||||
function rasterize(item, group, resolution) {
|
function rasterize(item, group, resolution) {
|
||||||
var raster = null;
|
var raster = null;
|
||||||
if (group) {
|
if (group) {
|
||||||
|
var parent = item.parent,
|
||||||
|
index = item.index;
|
||||||
group.addChild(item);
|
group.addChild(item);
|
||||||
raster = group.rasterize(resolution, false);
|
raster = group.rasterize(resolution, false);
|
||||||
item.remove();
|
if (parent) {
|
||||||
|
parent.insertChild(index, item);
|
||||||
|
} else {
|
||||||
|
item.remove();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return raster;
|
return raster;
|
||||||
}
|
}
|
||||||
|
@ -471,8 +477,9 @@ var compareBoolean = function(actual, expected, message, options) {
|
||||||
}
|
}
|
||||||
var style = {
|
var style = {
|
||||||
strokeColor: 'black',
|
strokeColor: 'black',
|
||||||
fillColor: expected &&
|
fillColor: expected && (expected.closed
|
||||||
(expected.closed || expected.children && 'yellow') || null
|
|| expected.firstChild && expected.firstChild.closed && 'yellow')
|
||||||
|
|| null
|
||||||
};
|
};
|
||||||
if (actual)
|
if (actual)
|
||||||
actual.style = style;
|
actual.style = style;
|
||||||
|
|
|
@ -177,7 +177,7 @@ test('#719', function() {
|
||||||
compareBoolean(result, expected);
|
compareBoolean(result, expected);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('#757 (path1.intersect(pat2, { stroke: true }))', function() {
|
test('#757 (path1.intersect(pat2, { trace: false }))', function() {
|
||||||
var rect = new Path.Rectangle({
|
var rect = new Path.Rectangle({
|
||||||
from: [100, 250],
|
from: [100, 250],
|
||||||
to: [350, 350]
|
to: [350, 350]
|
||||||
|
@ -194,7 +194,7 @@ test('#757 (path1.intersect(pat2, { stroke: true }))', function() {
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
var res = line.intersect(rect, { stroke: true });
|
var res = line.intersect(rect, { trace: false });
|
||||||
|
|
||||||
var children = res.removeChildren();
|
var children = res.removeChildren();
|
||||||
var first = children[0];
|
var first = children[0];
|
||||||
|
@ -864,6 +864,61 @@ test('#1123', function() {
|
||||||
'M100,200v-100h100v100zM180,180v-60h-60v60z');
|
'M100,200v-100h100v100zM180,180v-60h-60v60z');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('#1221', function() {
|
||||||
|
var rect1 = new Path.Rectangle({
|
||||||
|
point: [100, 100],
|
||||||
|
size: [200, 200]
|
||||||
|
});
|
||||||
|
|
||||||
|
var circle = new Path.Circle({
|
||||||
|
center: [100, 100],
|
||||||
|
radius: 100
|
||||||
|
});
|
||||||
|
|
||||||
|
compareBoolean(function() { return rect1.subtract(circle, { trace: false }); },
|
||||||
|
'M200,100h100v200h-200v-100');
|
||||||
|
compareBoolean(function() { return rect1.subtract(circle, { trace: true }); },
|
||||||
|
'M100,300v-100c55.22847,0 100,-44.77153 100,-100h100v200z');
|
||||||
|
|
||||||
|
|
||||||
|
var blob = PathItem.create("M534,273C171.7,111,60.5,117.1,30,158c-40.5,54.3,31.5,210.2,111,222c60.8,9,88-71.9,159-66c81.6,6.8,99.6,118.3,179,128c33.8,4.1,83.1-9.7,150-90")
|
||||||
|
var rect2 = new Path.Rectangle({
|
||||||
|
point: [150, 100],
|
||||||
|
size: [300, 300]
|
||||||
|
});
|
||||||
|
|
||||||
|
compareBoolean(function() { return blob.subtract(rect2, { trace: false }); },
|
||||||
|
'M534,273c-29.65069,-13.2581 -57.61955,-25.39031 -84,-36.46967M150,138.13156c-71.67127,-11.53613 -105.25987,0.10217 -120,19.86844c-40.5,54.3 31.5,210.2 111,222c3.08303,0.45637 6.07967,0.68158 9,0.69867M409.85616,400c18.87105,20.95032 39.82014,38.41763 69.14384,42c33.8,4.1 83.1,-9.7 150,-90');
|
||||||
|
compareBoolean(function() { return blob.subtract(rect2, { trace: true }); },
|
||||||
|
'M629,352c-66.9,80.3 -116.2,94.1 -150,90c-29.3237,-3.58237 -50.27279,-21.04968 -69.14384,-42h40.14384v-163.46967c26.38045,11.07937 54.34931,23.21157 84,36.46967M141,380c-79.5,-11.8 -151.5,-167.7 -111,-222c14.74013,-19.76627 48.32873,-31.40457 120,-19.86844v242.56712c-2.92033,-0.01709 -5.91697,-0.24231 -9,-0.69867z');
|
||||||
|
|
||||||
|
var rect3 = new Path.Rectangle({
|
||||||
|
point: [150, 100],
|
||||||
|
size: [300, 150]
|
||||||
|
});
|
||||||
|
|
||||||
|
compareBoolean(function() { return blob.subtract(rect3, { trace: false }); },
|
||||||
|
'M534,273c-29.65069,-13.2581 -57.61955,-25.39031 -84,-36.46967M150,138.13156c-71.67127,-11.53613 -105.25987,0.10217 -120,19.86844c-40.5,54.3 31.5,210.2 111,222c60.8,9 88,-71.9 159,-66c81.6,6.8 99.6,118.3 179,128c33.8,4.1 83.1,-9.7 150,-90');
|
||||||
|
compareBoolean(function() { return blob.subtract(rect3, { trace: true }); },
|
||||||
|
'M629,352c-66.9,80.3 -116.2,94.1 -150,90c-79.4,-9.7 -97.4,-121.2 -179,-128c-71,-5.9 -98.2,75 -159,66c-79.5,-11.8 -151.5,-167.7 -111,-222c14.74013,-19.76627 48.32873,-31.40457 120,-19.86844v111.86844h300v-13.46967c26.38045,11.07937 54.34931,23.21157 84,36.46967');
|
||||||
|
|
||||||
|
|
||||||
|
var rect4 = new Path.Rectangle({
|
||||||
|
point: [200, 200],
|
||||||
|
size: [400, 200]
|
||||||
|
});
|
||||||
|
|
||||||
|
var line = new Path.Line({
|
||||||
|
from: [400, 300],
|
||||||
|
to: [400, 600]
|
||||||
|
});
|
||||||
|
|
||||||
|
var division = line.divide(rect4, { trace: false });
|
||||||
|
equals(function() { return division.children.length; }, 2);
|
||||||
|
compareBoolean(function() { return division.children[0]; }, 'M400,400v200');
|
||||||
|
compareBoolean(function() { return division.children[1]; }, 'M400,300v100');
|
||||||
|
});
|
||||||
|
|
||||||
test('#1239 / #1073', function() {
|
test('#1239 / #1073', function() {
|
||||||
var p1 = new Path([[890.91, 7.52, 0, 0, 85.40999999999997, 94.02], [1024, 351.78, 0, -127.03999999999996, 0, 127.14999999999998], [890.69, 696.28, 85.54999999999995, -94.03999999999996, 0, 0], [843.44, 653.28, 0, 0, 75.20000000000005, -82.66999999999996], [960, 351.78, 0, 111.75, 0, -111.63], [843.65, 50.51999999999998, 75.07000000000005, 82.63999999999999, 0, 0], true]);
|
var p1 = new Path([[890.91, 7.52, 0, 0, 85.40999999999997, 94.02], [1024, 351.78, 0, -127.03999999999996, 0, 127.14999999999998], [890.69, 696.28, 85.54999999999995, -94.03999999999996, 0, 0], [843.44, 653.28, 0, 0, 75.20000000000005, -82.66999999999996], [960, 351.78, 0, 111.75, 0, -111.63], [843.65, 50.51999999999998, 75.07000000000005, 82.63999999999999, 0, 0], true]);
|
||||||
var p2 = new Path([[960, 352, -0.05999999999994543, 111.67999999999995, 0, 0], [1024, 352, 0, 0, -0.05999999999994543, 127.07], [890.69, 696.28, 85.5, -93.98000000000002, 0, 0], [843.44, 653.28, 0, 0, 75.14999999999998, -82.61000000000001], true]);
|
var p2 = new Path([[960, 352, -0.05999999999994543, 111.67999999999995, 0, 0], [1024, 352, 0, 0, -0.05999999999994543, 127.07], [890.69, 696.28, 85.5, -93.98000000000002, 0, 0], [843.44, 653.28, 0, 0, 75.14999999999998, -82.61000000000001], true]);
|
||||||
|
|
Loading…
Reference in a new issue