mirror of
https://github.com/Hopiu/fabric.js.git
synced 2026-03-16 22:10:32 +00:00
Add test and failing visual tests for clipPath toSVG (#5236)
* more visual tests; * try * fix
This commit is contained in:
parent
5482ac350a
commit
5138496163
4 changed files with 327 additions and 7 deletions
|
|
@ -73,7 +73,7 @@ jobs:
|
|||
- stage: Unit Tests
|
||||
node_js: "4"
|
||||
- stage: Visual Tests
|
||||
env: LAUNCHER=Node
|
||||
env: LAUNCHER=Node CANFAIL=TRUE
|
||||
node_js: "8"
|
||||
script: npm run build:fast && npm run test:visual
|
||||
- stage: Visual Tests
|
||||
|
|
|
|||
|
|
@ -97,6 +97,9 @@
|
|||
}
|
||||
|
||||
return function testCallback(testObj) {
|
||||
if (testObj.disabled) {
|
||||
return;
|
||||
}
|
||||
var testName = testObj.test;
|
||||
var code = testObj.code;
|
||||
var percentage = testObj.percentage;
|
||||
|
|
|
|||
|
|
@ -13,11 +13,6 @@
|
|||
enableRetinaScaling: false, renderOnAddRemove: false, width: 200, height: 200,
|
||||
});
|
||||
|
||||
// function getFixtureName(filename) {
|
||||
// var finalName = '/fixtures/' + filename;
|
||||
// return fabric.isLikelyNode ? (__dirname + '/..' + finalName) : getAbsolutePath('/test' + finalName);
|
||||
// }
|
||||
|
||||
var tests = [];
|
||||
|
||||
function clipping0(canvas, callback) {
|
||||
|
|
@ -50,7 +45,6 @@
|
|||
test: 'A clippath ignores fill and stroke for drawing, not positioning',
|
||||
code: clipping01,
|
||||
golden: 'clipping01.png',
|
||||
newModule: 'Clipping shapes',
|
||||
percentage: 0.06,
|
||||
});
|
||||
|
||||
|
|
|
|||
323
test/visual/svg_export.js
Normal file
323
test/visual/svg_export.js
Normal file
|
|
@ -0,0 +1,323 @@
|
|||
(function() {
|
||||
fabric.enableGLFiltering = false;
|
||||
fabric.isWebglSupported = false;
|
||||
fabric.Object.prototype.objectCaching = true;
|
||||
var visualTestLoop;
|
||||
if (fabric.isLikelyNode) {
|
||||
visualTestLoop = global.visualTestLoop;
|
||||
}
|
||||
else {
|
||||
visualTestLoop = window.visualTestLoop;
|
||||
}
|
||||
var fabricCanvas = this.canvas = new fabric.Canvas(null, {
|
||||
enableRetinaScaling: false, renderOnAddRemove: false, width: 200, height: 200,
|
||||
});
|
||||
|
||||
function svgToDataURL(svgStr) {
|
||||
var encoded = encodeURIComponent(svgStr)
|
||||
.replace(/'/g, '%27')
|
||||
.replace(/"/g, '%22');
|
||||
return 'data:image/svg+xml,' + encoded;
|
||||
}
|
||||
|
||||
function toSVGCanvas(canvas, callback) {
|
||||
var svg = canvas.toSVG();
|
||||
var dataUrl = svgToDataURL(svg);
|
||||
var image = fabric.document.createElement('img');
|
||||
image.onload = function() {
|
||||
var newCanvas = fabric.util.createCanvasElement();
|
||||
newCanvas.width = canvas.width;
|
||||
newCanvas.height = canvas.height;
|
||||
newCanvas.getContext('2d').drawImage(image, 0, 0, canvas.width, canvas.height);
|
||||
callback(newCanvas);
|
||||
};
|
||||
image.onerror = console.log;
|
||||
if (fabric.isLikelyNode) {
|
||||
image.src = dataUrl;
|
||||
}
|
||||
else {
|
||||
image.src = dataUrl;
|
||||
}
|
||||
}
|
||||
|
||||
var tests = [];
|
||||
|
||||
function clipping0(canvas, callback) {
|
||||
var clipPath = new fabric.Circle({ radius: 100, strokeWidth: 0, top: -10, left: -10 });
|
||||
var obj = new fabric.Rect({ top: 0, left: 0, strokeWidth: 0, width: 200, height: 200, fill: 'rgba(0,255,0,0.5)'});
|
||||
obj.clipPath = clipPath;
|
||||
canvas.add(obj);
|
||||
toSVGCanvas(canvas, callback);
|
||||
}
|
||||
|
||||
tests.push({
|
||||
test: 'Clip a rect with a circle, no zoom',
|
||||
code: clipping0,
|
||||
golden: 'clipping0.png',
|
||||
newModule: 'Export clippaths to SVG',
|
||||
percentage: 0.06,
|
||||
});
|
||||
|
||||
function clipping01(canvas, callback) {
|
||||
var clipPath = new fabric.Circle({ radius: 50, strokeWidth: 40, top: -50, left: -50, fill: 'transparent' });
|
||||
var obj = new fabric.Rect({ top: 0, left: 0, strokeWidth: 0, width: 200, height: 200, fill: 'rgba(0,255,0,0.5)'});
|
||||
obj.clipPath = clipPath;
|
||||
canvas.add(obj);
|
||||
toSVGCanvas(canvas, callback);
|
||||
}
|
||||
|
||||
tests.push({
|
||||
test: 'A clippath ignores fill and stroke for drawing, not positioning',
|
||||
code: clipping01,
|
||||
golden: 'clipping01.png',
|
||||
percentage: 0.06,
|
||||
});
|
||||
|
||||
function clipping1(canvas, callback) {
|
||||
var zoom = 20;
|
||||
canvas.setZoom(zoom);
|
||||
var clipPath = new fabric.Circle({ radius: 5, strokeWidth: 0, top: -2, left: -2 });
|
||||
var obj = new fabric.Rect({ top: 0, left: 0, strokeWidth: 0, width: 10, height: 10, fill: 'rgba(255,0,0,0.5)'});
|
||||
obj.clipPath = clipPath;
|
||||
canvas.add(obj);
|
||||
toSVGCanvas(canvas, callback);
|
||||
}
|
||||
|
||||
tests.push({
|
||||
test: 'Clip a rect with a circle, with zoom',
|
||||
code: clipping1,
|
||||
golden: 'clipping1.png',
|
||||
percentage: 0.06,
|
||||
});
|
||||
|
||||
function clipping2(canvas, callback) {
|
||||
var clipPath = new fabric.Circle({
|
||||
radius: 100,
|
||||
top: -100,
|
||||
left: -100
|
||||
});
|
||||
var group = new fabric.Group([
|
||||
new fabric.Rect({ strokeWidth: 0, width: 100, height: 100, fill: 'red' }),
|
||||
new fabric.Rect({ strokeWidth: 0, width: 100, height: 100, fill: 'yellow', left: 100 }),
|
||||
new fabric.Rect({ strokeWidth: 0, width: 100, height: 100, fill: 'blue', top: 100 }),
|
||||
new fabric.Rect({ strokeWidth: 0, width: 100, height: 100, fill: 'green', left: 100, top: 100 })
|
||||
], { strokeWidth: 0 });
|
||||
group.clipPath = clipPath;
|
||||
canvas.add(group);
|
||||
toSVGCanvas(canvas, callback);
|
||||
}
|
||||
|
||||
tests.push({
|
||||
test: 'Clip a group with a circle',
|
||||
code: clipping2,
|
||||
golden: 'clipping2.png',
|
||||
percentage: 0.06,
|
||||
});
|
||||
|
||||
function clipping3(canvas, callback) {
|
||||
var clipPath = new fabric.Circle({ radius: 100, top: -100, left: -100 });
|
||||
var small = new fabric.Circle({ radius: 50, top: -50, left: -50 });
|
||||
var small2 = new fabric.Rect({ width: 30, height: 30, top: -50, left: -50 });
|
||||
var group = new fabric.Group([
|
||||
new fabric.Rect({ strokeWidth: 0, width: 100, height: 100, fill: 'red', clipPath: small }),
|
||||
new fabric.Rect({ strokeWidth: 0, width: 100, height: 100, fill: 'yellow', left: 100 }),
|
||||
new fabric.Rect({ strokeWidth: 0, width: 100, height: 100, fill: 'blue', top: 100, clipPath: small2 }),
|
||||
new fabric.Rect({ strokeWidth: 0, width: 100, height: 100, fill: 'green', left: 100, top: 100 })
|
||||
], { strokeWidth: 0 });
|
||||
group.clipPath = clipPath;
|
||||
canvas.add(group);
|
||||
toSVGCanvas(canvas, callback);
|
||||
}
|
||||
|
||||
tests.push({
|
||||
test: 'Isolation of clipPath of group and inner objects',
|
||||
code: clipping3,
|
||||
golden: 'clipping3.png',
|
||||
percentage: 0.06,
|
||||
disabled: true,
|
||||
});
|
||||
|
||||
function clipping4(canvas, callback) {
|
||||
var clipPath = new fabric.Circle({ radius: 20, strokeWidth: 0, top: -10, left: -10, scaleX: 2, skewY: 45 });
|
||||
var obj = new fabric.Rect({ top: 0, left: 0, strokeWidth: 0, width: 200, height: 200, fill: 'rgba(0,255,0,0.5)'});
|
||||
obj.fill = new fabric.Gradient({
|
||||
type: 'linear',
|
||||
coords: {
|
||||
x1: 0,
|
||||
y1: 0,
|
||||
x2: 200,
|
||||
y2: 200,
|
||||
},
|
||||
colorStops: [
|
||||
{
|
||||
offset: 0,
|
||||
color: 'red',
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: 'blue',
|
||||
}
|
||||
]
|
||||
});
|
||||
obj.clipPath = clipPath;
|
||||
canvas.add(obj);
|
||||
toSVGCanvas(canvas, callback);
|
||||
}
|
||||
|
||||
tests.push({
|
||||
test: 'ClipPath can be transformed',
|
||||
code: clipping4,
|
||||
golden: 'clipping4.png',
|
||||
percentage: 0.06,
|
||||
});
|
||||
|
||||
function clipping5(canvas, callback) {
|
||||
var clipPath = new fabric.Circle({ radius: 20, strokeWidth: 0, top: -10, left: -10, scaleX: 2, skewY: 45 });
|
||||
var clipPath1 = new fabric.Circle({ radius: 15, rotate: 45, strokeWidth: 0, top: -100, left: -50, scaleX: 2, skewY: 45 });
|
||||
var clipPath2 = new fabric.Circle({ radius: 10, strokeWidth: 0, top: -20, left: -20, scaleY: 2, skewX: 45 });
|
||||
var group = new fabric.Group([clipPath, clipPath1, clipPath2]);
|
||||
var obj = new fabric.Rect({ top: 0, left: 0, strokeWidth: 0, width: 200, height: 200, fill: 'rgba(0,255,0,0.5)'});
|
||||
obj.fill = new fabric.Gradient({
|
||||
type: 'linear',
|
||||
coords: {
|
||||
x1: 0,
|
||||
y1: 0,
|
||||
x2: 200,
|
||||
y2: 200,
|
||||
},
|
||||
colorStops: [
|
||||
{
|
||||
offset: 0,
|
||||
color: 'red',
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: 'blue',
|
||||
}
|
||||
]
|
||||
});
|
||||
obj.clipPath = group;
|
||||
canvas.add(obj);
|
||||
toSVGCanvas(canvas, callback);
|
||||
}
|
||||
|
||||
tests.push({
|
||||
test: 'ClipPath can be a group with many objects',
|
||||
code: clipping5,
|
||||
golden: 'clipping5.png',
|
||||
percentage: 0.06,
|
||||
disabled: true,
|
||||
});
|
||||
|
||||
function clipping6(canvas, callback) {
|
||||
var clipPath = new fabric.Circle({ radius: 20, strokeWidth: 0, top: -10, left: -10, scaleX: 2, skewY: 45 });
|
||||
var clipPath1 = new fabric.Circle({ radius: 15, rotate: 45, strokeWidth: 0, top: -100, left: -50, scaleX: 2, skewY: 45 });
|
||||
var clipPath2 = new fabric.Circle({ radius: 10, strokeWidth: 0, top: -20, left: -20, scaleY: 2, skewX: 45 });
|
||||
var group = new fabric.Group([clipPath, clipPath1, clipPath2]);
|
||||
var obj = new fabric.Rect({ top: 0, left: 0, strokeWidth: 0, width: 200, height: 200, fill: 'rgba(0,255,0,0.5)'});
|
||||
obj.fill = new fabric.Gradient({
|
||||
type: 'linear',
|
||||
coords: {
|
||||
x1: 0,
|
||||
y1: 0,
|
||||
x2: 200,
|
||||
y2: 200,
|
||||
},
|
||||
colorStops: [
|
||||
{
|
||||
offset: 0,
|
||||
color: 'red',
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: 'blue',
|
||||
}
|
||||
]
|
||||
});
|
||||
obj.clipPath = group;
|
||||
group.inverted = true;
|
||||
canvas.add(obj);
|
||||
toSVGCanvas(canvas, callback);
|
||||
}
|
||||
|
||||
tests.push({
|
||||
test: 'ClipPath can be inverted, it will clip what is outside the clipPath',
|
||||
code: clipping6,
|
||||
golden: 'clipping6.png',
|
||||
percentage: 0.06,
|
||||
disabled: true,
|
||||
});
|
||||
|
||||
function clipping7(canvas, callback) {
|
||||
var clipPath = new fabric.Circle({ radius: 30, strokeWidth: 0, top: -30, left: -30, skewY: 45 });
|
||||
var obj1 = new fabric.Rect({ top: 0, left: 100, strokeWidth: 0, width: 100, height: 100, fill: 'rgba(0,255,0,0.8)'});
|
||||
var obj2 = new fabric.Rect({ top: 0, left: 0, strokeWidth: 0, width: 100, height: 100, fill: 'rgba(255,255,0,0.8)'});
|
||||
var obj3 = new fabric.Rect({ top: 100, left: 0, strokeWidth: 0, width: 100, height: 100, fill: 'rgba(0,255,255,0.8)'});
|
||||
var obj4 = new fabric.Rect({ top: 100, left: 100, strokeWidth: 0, width: 100, height: 100, fill: 'rgba(255,0,0,0.8)'});
|
||||
obj1.clipPath = clipPath;
|
||||
obj2.clipPath = clipPath;
|
||||
obj3.clipPath = clipPath;
|
||||
obj4.clipPath = clipPath;
|
||||
canvas.add(obj1);
|
||||
canvas.add(obj2);
|
||||
canvas.add(obj3);
|
||||
canvas.add(obj4);
|
||||
toSVGCanvas(canvas, callback);
|
||||
}
|
||||
|
||||
tests.push({
|
||||
test: 'Many Objects can share the same clipPath',
|
||||
code: clipping7,
|
||||
golden: 'clipping7.png',
|
||||
percentage: 0.06,
|
||||
disabled: true,
|
||||
});
|
||||
|
||||
function clipping8(canvas, callback) {
|
||||
var clipPath = new fabric.Circle({ radius: 60, strokeWidth: 0, top: 40, left: 40, absolutePositioned: true });
|
||||
var obj1 = new fabric.Rect({ top: 0, left: 100, strokeWidth: 0, width: 100, height: 100, fill: 'rgba(0,255,0,0.8)'});
|
||||
var obj2 = new fabric.Rect({ top: 0, left: 0, strokeWidth: 0, width: 100, height: 100, fill: 'rgba(255,255,0,0.8)'});
|
||||
var obj3 = new fabric.Rect({ top: 100, left: 0, strokeWidth: 0, width: 100, height: 100, fill: 'rgba(0,255,255,0.8)'});
|
||||
var obj4 = new fabric.Rect({ top: 100, left: 100, strokeWidth: 0, width: 100, height: 100, fill: 'rgba(255,0,0,0.8)'});
|
||||
obj1.clipPath = clipPath;
|
||||
obj2.clipPath = clipPath;
|
||||
obj3.clipPath = clipPath;
|
||||
canvas.add(obj1);
|
||||
canvas.add(obj2);
|
||||
canvas.add(obj3);
|
||||
canvas.add(obj4);
|
||||
toSVGCanvas(canvas, callback);
|
||||
}
|
||||
|
||||
tests.push({
|
||||
test: 'an absolute positioned clipPath, shared',
|
||||
code: clipping8,
|
||||
golden: 'clipping8.png',
|
||||
percentage: 0.06,
|
||||
disabled: true,
|
||||
});
|
||||
|
||||
function clipping9(canvas, callback) {
|
||||
var clipPath = new fabric.Circle({ radius: 60, strokeWidth: 0, top: 10, left: 10 });
|
||||
var obj1 = new fabric.Rect({ top: 0, left: 100, strokeWidth: 0, width: 100, height: 100, fill: 'rgba(0,255,0,0.8)'});
|
||||
var obj2 = new fabric.Rect({ top: 0, left: 0, strokeWidth: 0, width: 100, height: 100, fill: 'rgba(255,255,0,0.8)'});
|
||||
var obj3 = new fabric.Rect({ top: 100, left: 0, strokeWidth: 0, width: 100, height: 100, fill: 'rgba(0,255,255,0.8)'});
|
||||
var obj4 = new fabric.Rect({ top: 100, left: 100, strokeWidth: 0, width: 100, height: 100, fill: 'rgba(255,0,0,0.8)'});
|
||||
canvas.add(obj1);
|
||||
canvas.add(obj2);
|
||||
canvas.add(obj3);
|
||||
canvas.add(obj4);
|
||||
canvas.clipPath = clipPath;
|
||||
toSVGCanvas(canvas, callback);
|
||||
}
|
||||
|
||||
tests.push({
|
||||
test: 'a clipPath on the canvas',
|
||||
code: clipping9,
|
||||
golden: 'clipping9.png',
|
||||
percentage: 0.06,
|
||||
disabled: true,
|
||||
});
|
||||
|
||||
tests.forEach(visualTestLoop(fabricCanvas, QUnit));
|
||||
})();
|
||||
Loading…
Reference in a new issue