mirror of
https://github.com/Hopiu/fabric.js.git
synced 2026-03-16 22:10:32 +00:00
Rework SVG code to have clipPath friendly transformations (#5284)
* so far i think i broke everything * halp super hard * this is what i wanted * fixed error * some fixes * svg-working * less code * fixed shadow for text and groups * fixed tests * one file test more * fixed lint * works * ok more tests * remove a lint issue * removed unused method
This commit is contained in:
parent
2ab5c5f851
commit
a7ff2bfb10
25 changed files with 386 additions and 242 deletions
|
|
@ -11,12 +11,11 @@
|
|||
* @return {String} svg representation of an instance
|
||||
*/
|
||||
toSVG: function(reviver) {
|
||||
var markup = this._createBaseSVGMarkup(),
|
||||
offsets = this._getSVGLeftTopOffsets(),
|
||||
textAndBg = this._getSVGTextAndBg(offsets.textTop, offsets.textLeft);
|
||||
this._wrapSVGTextAndBg(markup, textAndBg);
|
||||
|
||||
return reviver ? reviver(markup.join('')) : markup.join('');
|
||||
var offsets = this._getSVGLeftTopOffsets(),
|
||||
textAndBg = this._getSVGTextAndBg(offsets.textTop, offsets.textLeft),
|
||||
internalMarkup = this._wrapSVGTextAndBg(textAndBg);
|
||||
return this._createBaseSVGMarkup(
|
||||
internalMarkup, { reviver: reviver, noStyle: true, withShadow: true });
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
@ -33,13 +32,10 @@
|
|||
/**
|
||||
* @private
|
||||
*/
|
||||
_wrapSVGTextAndBg: function(markup, textAndBg) {
|
||||
var noShadow = true, filter = this.getSvgFilter(),
|
||||
style = filter === '' ? '' : ' style="' + filter + '"',
|
||||
_wrapSVGTextAndBg: function(textAndBg) {
|
||||
var noShadow = true,
|
||||
textDecoration = this.getSvgTextDecoration(this);
|
||||
markup.push(
|
||||
'\t<g ', this.getSvgCommons(), 'transform="', this.getSvgTransform(), this.getSvgTransformMatrix(), '"',
|
||||
style, '>\n',
|
||||
return [
|
||||
textAndBg.textBgRects.join(''),
|
||||
'\t\t<text xml:space="preserve" ',
|
||||
(this.fontFamily ? 'font-family="' + this.fontFamily.replace(/"/g, '\'') + '" ' : ''),
|
||||
|
|
@ -49,9 +45,8 @@
|
|||
(textDecoration ? 'text-decoration="' + textDecoration + '" ' : ''),
|
||||
'style="', this.getSvgStyles(noShadow), '"', this.addPaintOrder(), ' >',
|
||||
textAndBg.textSpans.join(''),
|
||||
'</text>\n',
|
||||
'\t</g>\n'
|
||||
);
|
||||
'</text>\n'
|
||||
];
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
*/
|
||||
getSvgStyles: function(skipShadow) {
|
||||
|
||||
var fillRule = this.fillRule,
|
||||
var fillRule = this.fillRule ? this.fillRule : 'nonzero',
|
||||
strokeWidth = this.strokeWidth ? this.strokeWidth : '0',
|
||||
strokeDashArray = this.strokeDashArray ? this.strokeDashArray.join(' ') : 'none',
|
||||
strokeLineCap = this.strokeLineCap ? this.strokeLineCap : 'butt',
|
||||
|
|
@ -128,45 +128,16 @@
|
|||
|
||||
/**
|
||||
* Returns transform-string for svg-export
|
||||
* @param {Boolean} use the full transform or the single object one.
|
||||
* @return {String}
|
||||
*/
|
||||
getSvgTransform: function() {
|
||||
var angle = this.angle,
|
||||
skewX = (this.skewX % 360),
|
||||
skewY = (this.skewY % 360),
|
||||
center = this.getCenterPoint(),
|
||||
|
||||
NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS,
|
||||
|
||||
translatePart = 'translate(' +
|
||||
toFixed(center.x, NUM_FRACTION_DIGITS) +
|
||||
' ' +
|
||||
toFixed(center.y, NUM_FRACTION_DIGITS) +
|
||||
')',
|
||||
|
||||
anglePart = angle !== 0
|
||||
? (' rotate(' + toFixed(angle, NUM_FRACTION_DIGITS) + ')')
|
||||
: '',
|
||||
|
||||
scalePart = (this.scaleX === 1 && this.scaleY === 1)
|
||||
? '' :
|
||||
(' scale(' +
|
||||
toFixed(this.scaleX, NUM_FRACTION_DIGITS) +
|
||||
' ' +
|
||||
toFixed(this.scaleY, NUM_FRACTION_DIGITS) +
|
||||
')'),
|
||||
|
||||
skewXPart = skewX !== 0 ? ' skewX(' + toFixed(skewX, NUM_FRACTION_DIGITS) + ')' : '',
|
||||
|
||||
skewYPart = skewY !== 0 ? ' skewY(' + toFixed(skewY, NUM_FRACTION_DIGITS) + ')' : '',
|
||||
|
||||
flipXPart = this.flipX ? ' matrix(-1 0 0 1 0 0) ' : '',
|
||||
|
||||
flipYPart = this.flipY ? ' matrix(1 0 0 -1 0 0)' : '';
|
||||
|
||||
return [
|
||||
translatePart, anglePart, scalePart, flipXPart, flipYPart, skewXPart, skewYPart
|
||||
].join('');
|
||||
getSvgTransform: function(full, additionalTransform) {
|
||||
var transform = full ? this.calcTransformMatrix() : this.calcOwnMatrix(),
|
||||
svgTransform = transform.map(function(value) {
|
||||
return toFixed(value, fabric.Object.NUM_FRACTION_DIGITS);
|
||||
}).join(' ');
|
||||
return 'transform="matrix(' + svgTransform + ')' +
|
||||
(additionalTransform || '') + this.getSvgTransformMatrix() + '" ';
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
@ -174,7 +145,7 @@
|
|||
* @return {String}
|
||||
*/
|
||||
getSvgTransformMatrix: function() {
|
||||
return this.transformMatrix ? ' matrix(' + this.transformMatrix.join(' ') + ') ' : '';
|
||||
return this.transformMatrix ? ' matrix(' + this.transformMatrix.join(' ') + ')' : '';
|
||||
},
|
||||
|
||||
_setSVGBg: function(textBgRects) {
|
||||
|
|
@ -195,12 +166,77 @@
|
|||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns svg representation of an instance
|
||||
* @param {Function} [reviver] Method for further parsing of svg representation.
|
||||
* @return {String} svg representation of an instance
|
||||
*/
|
||||
toSVG: function(reviver) {
|
||||
return this._createBaseSVGMarkup(this._toSVG(), { reviver: reviver });
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns svg clipPath representation of an instance
|
||||
* @param {Function} [reviver] Method for further parsing of svg representation.
|
||||
* @return {String} svg representation of an instance
|
||||
*/
|
||||
toClipPathSVG: function(reviver) {
|
||||
return '\t' + this._createBaseClipPathSVGMarkup(this._toSVG(), { reviver: reviver });
|
||||
},
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_createBaseSVGMarkup: function() {
|
||||
var markup = [], clipPath = this.clipPath;
|
||||
_createBaseClipPathSVGMarkup: function(objectMarkup, options) {
|
||||
options = options || {};
|
||||
var reviver = options.reviver,
|
||||
additionalTransform = options.additionalTransform || '',
|
||||
commonPieces = [
|
||||
this.getSvgTransform(true, additionalTransform),
|
||||
this.getSvgCommons(),
|
||||
].join(''),
|
||||
// insert commons in the markup, style and svgCommons
|
||||
index = objectMarkup.indexOf('COMMON_PARTS');
|
||||
objectMarkup[index] = commonPieces;
|
||||
return reviver ? reviver(objectMarkup.join('')) : objectMarkup.join('');
|
||||
},
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_createBaseSVGMarkup: function(objectMarkup, options) {
|
||||
options = options || {};
|
||||
var noStyle = options.noStyle, withShadow = options.withShadow,
|
||||
reviver = options.reviver,
|
||||
styleInfo = noStyle ? '' : 'style="' + this.getSvgStyles() + '" ',
|
||||
shadowInfo = withShadow ? 'style="' + this.getSvgFilter() + '" ' : '',
|
||||
clipPath = this.clipPath,
|
||||
absoluteClipPath = this.clipPath && this.clipPath.absolutePositioned,
|
||||
commonPieces, markup = [], clipPathMarkup,
|
||||
// insert commons in the markup, style and svgCommons
|
||||
index = objectMarkup.indexOf('COMMON_PARTS');
|
||||
if (clipPath) {
|
||||
clipPath.clipPathId = 'CLIPPATH_' + fabric.Object.__uid++;
|
||||
clipPathMarkup = '<clipPath id="' + clipPath.clipPathId + '" >\n' +
|
||||
this.clipPath.toClipPathSVG(reviver) +
|
||||
'</clipPath>\n';
|
||||
}
|
||||
if (absoluteClipPath) {
|
||||
markup.push(
|
||||
'<g ', shadowInfo, this.getSvgCommons(), ' >\n'
|
||||
);
|
||||
}
|
||||
markup.push(
|
||||
'<g ',
|
||||
this.getSvgTransform(false),
|
||||
!absoluteClipPath ? shadowInfo + this.getSvgCommons() : '',
|
||||
' >\n'
|
||||
);
|
||||
commonPieces = [
|
||||
styleInfo,
|
||||
noStyle ? '' : this.addPaintOrder(), ' '
|
||||
].join('');
|
||||
objectMarkup[index] = commonPieces;
|
||||
if (this.fill && this.fill.toLive) {
|
||||
markup.push(this.fill.toSVG(this, false));
|
||||
}
|
||||
|
|
@ -211,14 +247,12 @@
|
|||
markup.push(this.shadow.toSVG(this));
|
||||
}
|
||||
if (clipPath) {
|
||||
clipPath.clipPathId = 'CLIPPATH_' + fabric.Object.__uid++;
|
||||
markup.push(
|
||||
'<clipPath id="' + clipPath.clipPathId + '" >\n\t',
|
||||
this.clipPath.toSVG(),
|
||||
'</clipPath>\n'
|
||||
);
|
||||
markup.push(clipPathMarkup);
|
||||
}
|
||||
return markup;
|
||||
markup.push(objectMarkup.join(''));
|
||||
markup.push('</g>\n');
|
||||
absoluteClipPath && markup.push('</g>\n');
|
||||
return reviver ? reviver(markup.join('')) : markup.join('');
|
||||
},
|
||||
|
||||
addPaintOrder: function() {
|
||||
|
|
|
|||
|
|
@ -78,26 +78,23 @@
|
|||
},
|
||||
|
||||
/* _TO_SVG_START_ */
|
||||
|
||||
/**
|
||||
* Returns svg representation of an instance
|
||||
* @param {Function} [reviver] Method for further parsing of svg representation.
|
||||
* @return {String} svg representation of an instance
|
||||
* @return {Array} an array of strings with the specific svg representation
|
||||
* of the instance
|
||||
*/
|
||||
toSVG: function(reviver) {
|
||||
var markup = this._createBaseSVGMarkup(), x = 0, y = 0,
|
||||
_toSVG: function() {
|
||||
var svgString, x = 0, y = 0,
|
||||
angle = (this.endAngle - this.startAngle) % ( 2 * pi);
|
||||
|
||||
if (angle === 0) {
|
||||
markup.push(
|
||||
'<circle ', this.getSvgCommons(),
|
||||
svgString = [
|
||||
'<circle ', 'COMMON_PARTS',
|
||||
'cx="' + x + '" cy="' + y + '" ',
|
||||
'r="', this.radius,
|
||||
'" style="', this.getSvgStyles(),
|
||||
'" transform="', this.getSvgTransform(),
|
||||
' ', this.getSvgTransformMatrix(), '"',
|
||||
this.addPaintOrder(),
|
||||
'/>\n'
|
||||
);
|
||||
'" />\n'
|
||||
];
|
||||
}
|
||||
else {
|
||||
var startX = fabric.util.cos(this.startAngle) * this.radius,
|
||||
|
|
@ -105,20 +102,14 @@
|
|||
endX = fabric.util.cos(this.endAngle) * this.radius,
|
||||
endY = fabric.util.sin(this.endAngle) * this.radius,
|
||||
largeFlag = angle > pi ? '1' : '0';
|
||||
|
||||
markup.push(
|
||||
svgString = [
|
||||
'<path d="M ' + startX + ' ' + startY,
|
||||
' A ' + this.radius + ' ' + this.radius,
|
||||
' 0 ', +largeFlag + ' 1', ' ' + endX + ' ' + endY,
|
||||
'" style="', this.getSvgStyles(),
|
||||
'" transform="', this.getSvgTransform(),
|
||||
' ', this.getSvgTransformMatrix(), '"',
|
||||
this.addPaintOrder(),
|
||||
'/>\n'
|
||||
);
|
||||
'"', 'COMMON_PARTS', ' />\n'
|
||||
];
|
||||
}
|
||||
|
||||
return reviver ? reviver(markup.join('')) : markup.join('');
|
||||
return svgString;
|
||||
},
|
||||
/* _TO_SVG_END_ */
|
||||
|
||||
|
|
|
|||
|
|
@ -105,24 +105,17 @@
|
|||
/* _TO_SVG_START_ */
|
||||
/**
|
||||
* Returns svg representation of an instance
|
||||
* @param {Function} [reviver] Method for further parsing of svg representation.
|
||||
* @return {String} svg representation of an instance
|
||||
* @return {Array} an array of strings with the specific svg representation
|
||||
* of the instance
|
||||
*/
|
||||
toSVG: function(reviver) {
|
||||
var markup = this._createBaseSVGMarkup();
|
||||
markup.push(
|
||||
'<ellipse ', this.getSvgCommons(),
|
||||
_toSVG: function() {
|
||||
return [
|
||||
'<ellipse ', 'COMMON_PARTS',
|
||||
'cx="0" cy="0" ',
|
||||
'rx="', this.rx,
|
||||
'" ry="', this.ry,
|
||||
'" style="', this.getSvgStyles(),
|
||||
'" transform="', this.getSvgTransform(),
|
||||
this.getSvgTransformMatrix(), '"',
|
||||
this.addPaintOrder(),
|
||||
'/>\n'
|
||||
);
|
||||
|
||||
return reviver ? reviver(markup.join('')) : markup.join('');
|
||||
'" />\n'
|
||||
];
|
||||
},
|
||||
/* _TO_SVG_END_ */
|
||||
|
||||
|
|
|
|||
|
|
@ -521,24 +521,30 @@
|
|||
* @return {String} svg representation of an instance
|
||||
*/
|
||||
toSVG: function(reviver) {
|
||||
var markup = this._createBaseSVGMarkup();
|
||||
markup.push(
|
||||
'<g ', this.getSvgCommons(), 'transform="',
|
||||
/* avoiding styles intentionally */
|
||||
this.getSvgTransform(),
|
||||
this.getSvgTransformMatrix(),
|
||||
'" style="',
|
||||
this.getSvgFilter(),
|
||||
'">\n'
|
||||
);
|
||||
var svgString = [];
|
||||
|
||||
for (var i = 0, len = this._objects.length; i < len; i++) {
|
||||
markup.push('\t', this._objects[i].toSVG(reviver));
|
||||
svgString.push('\t', this._objects[i].toSVG(reviver));
|
||||
}
|
||||
|
||||
markup.push('</g>\n');
|
||||
return this._createBaseSVGMarkup(
|
||||
svgString,
|
||||
{ reviver: reviver, noStyle: true, withShadow: true });
|
||||
},
|
||||
|
||||
return reviver ? reviver(markup.join('')) : markup.join('');
|
||||
/**
|
||||
* Returns svg clipPath representation of an instance
|
||||
* @param {Function} [reviver] Method for further parsing of svg representation.
|
||||
* @return {String} svg representation of an instance
|
||||
*/
|
||||
toClipPathSVG: function(reviver) {
|
||||
var svgString = [];
|
||||
|
||||
for (var i = 0, len = this._objects.length; i < len; i++) {
|
||||
svgString.push('\t', this._objects[i].toClipPathSVG(reviver));
|
||||
}
|
||||
|
||||
return this._createBaseClipPathSVGMarkup(svgString, { reviver: reviver });
|
||||
},
|
||||
/* _TO_SVG_END_ */
|
||||
});
|
||||
|
|
|
|||
|
|
@ -286,53 +286,51 @@
|
|||
|
||||
/* _TO_SVG_START_ */
|
||||
/**
|
||||
* Returns SVG representation of an instance
|
||||
* @param {Function} [reviver] Method for further parsing of svg representation.
|
||||
* @return {String} svg representation of an instance
|
||||
* Returns svg representation of an instance
|
||||
* @return {Array} an array of strings with the specific svg representation
|
||||
* of the instance
|
||||
*/
|
||||
toSVG: function(reviver) {
|
||||
var markup = this._createBaseSVGMarkup(), x = -this.width / 2, y = -this.height / 2, clipPath = '';
|
||||
_toSVG: function() {
|
||||
var svgString = [], imageMarkup = [], strokeSvg,
|
||||
x = -this.width / 2, y = -this.height / 2, clipPath = '';
|
||||
if (this.hasCrop()) {
|
||||
var clipPathId = fabric.Object.__uid++;
|
||||
markup.push(
|
||||
svgString.push(
|
||||
'<clipPath id="imageCrop_' + clipPathId + '">\n',
|
||||
'\t<rect x="' + x + '" y="' + y + '" width="' + this.width + '" height="' + this.height + '" />\n',
|
||||
'</clipPath>\n'
|
||||
);
|
||||
clipPath = ' clip-path="url(#imageCrop_' + clipPathId + ')" ';
|
||||
}
|
||||
markup.push('<g transform="', this.getSvgTransform(), this.getSvgTransformMatrix(), '">\n');
|
||||
var imageMarkup = ['\t<image ', this.getSvgCommons(), 'xlink:href="', this.getSvgSrc(true),
|
||||
imageMarkup.push('\t<image ', 'COMMON_PARTS', 'xlink:href="', this.getSvgSrc(true),
|
||||
'" x="', x - this.cropX, '" y="', y - this.cropY,
|
||||
'" style="', this.getSvgStyles(),
|
||||
// we're essentially moving origin of transformation from top/left corner to the center of the shape
|
||||
// by wrapping it in container <g> element with actual transformation, then offsetting object to the top/left
|
||||
// so that object's center aligns with container's left/top
|
||||
'" width="', this._element.width || this._element.naturalWidth,
|
||||
'" height="', this._element.height || this._element.height,
|
||||
'"', clipPath,
|
||||
'></image>\n'];
|
||||
if (this.paintFirst === 'fill') {
|
||||
Array.prototype.push.apply(markup, imageMarkup);
|
||||
}
|
||||
'></image>\n');
|
||||
|
||||
if (this.stroke || this.strokeDashArray) {
|
||||
var origFill = this.fill;
|
||||
this.fill = null;
|
||||
markup.push(
|
||||
strokeSvg = [
|
||||
'\t<rect ',
|
||||
'x="', x, '" y="', y,
|
||||
'" width="', this.width, '" height="', this.height,
|
||||
'" style="', this.getSvgStyles(),
|
||||
'"/>\n'
|
||||
);
|
||||
];
|
||||
this.fill = origFill;
|
||||
}
|
||||
if (this.paintFirst !== 'fill') {
|
||||
Array.prototype.push.apply(markup, imageMarkup);
|
||||
svgString = svgString.concat(strokeSvg, imageMarkup);
|
||||
}
|
||||
markup.push('</g>\n');
|
||||
|
||||
return reviver ? reviver(markup.join('')) : markup.join('');
|
||||
else {
|
||||
svgString = svgString.concat(imageMarkup, strokeSvg);
|
||||
}
|
||||
return svgString;
|
||||
},
|
||||
/* _TO_SVG_END_ */
|
||||
|
||||
|
|
|
|||
|
|
@ -247,26 +247,20 @@
|
|||
|
||||
/* _TO_SVG_START_ */
|
||||
/**
|
||||
* Returns SVG representation of an instance
|
||||
* @param {Function} [reviver] Method for further parsing of svg representation.
|
||||
* @return {String} svg representation of an instance
|
||||
* Returns svg representation of an instance
|
||||
* @return {Array} an array of strings with the specific svg representation
|
||||
* of the instance
|
||||
*/
|
||||
toSVG: function(reviver) {
|
||||
var markup = this._createBaseSVGMarkup(),
|
||||
p = this.calcLinePoints();
|
||||
markup.push(
|
||||
'<line ', this.getSvgCommons(),
|
||||
_toSVG: function() {
|
||||
var p = this.calcLinePoints();
|
||||
return [
|
||||
'<line ', 'COMMON_PARTS',
|
||||
'x1="', p.x1,
|
||||
'" y1="', p.y1,
|
||||
'" x2="', p.x2,
|
||||
'" y2="', p.y2,
|
||||
'" style="', this.getSvgStyles(),
|
||||
'" transform="', this.getSvgTransform(),
|
||||
this.getSvgTransformMatrix(),
|
||||
'"/>\n'
|
||||
);
|
||||
|
||||
return reviver ? reviver(markup.join('')) : markup.join('');
|
||||
'" />\n'
|
||||
];
|
||||
},
|
||||
/* _TO_SVG_END_ */
|
||||
});
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
extend = fabric.util.object.extend,
|
||||
_toString = Object.prototype.toString,
|
||||
drawArc = fabric.util.drawArc,
|
||||
toFixed = fabric.util.toFixed,
|
||||
commandLengths = {
|
||||
m: 2,
|
||||
l: 2,
|
||||
|
|
@ -466,29 +467,39 @@
|
|||
/* _TO_SVG_START_ */
|
||||
/**
|
||||
* Returns svg representation of an instance
|
||||
* @return {Array} an array of strings with the specific svg representation
|
||||
* of the instance
|
||||
*/
|
||||
_toSVG: function() {
|
||||
var specificTransform = this._getOffsetTransform(),
|
||||
path = this.path.map(function(path) {
|
||||
return path.join(' ');
|
||||
}).join(' ');
|
||||
return [
|
||||
'<path ', 'COMMON_PARTS',
|
||||
'd="', path,
|
||||
'" stroke-linecap="round" ',
|
||||
'transform="' + specificTransform + '" ',
|
||||
'/>\n'
|
||||
];
|
||||
},
|
||||
|
||||
_getOffsetTransform: function() {
|
||||
var digits = fabric.Object.NUM_FRACTION_DIGITS;
|
||||
return ' translate(' + toFixed(-this.pathOffset.x, digits) + ', ' +
|
||||
toFixed(-this.pathOffset.y, digits) + ')';
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns svg clipPath representation of an instance
|
||||
* @param {Function} [reviver] Method for further parsing of svg representation.
|
||||
* @return {String} svg representation of an instance
|
||||
*/
|
||||
toSVG: function(reviver) {
|
||||
var chunks = [],
|
||||
markup = this._createBaseSVGMarkup(), addTransform = '';
|
||||
|
||||
for (var i = 0, len = this.path.length; i < len; i++) {
|
||||
chunks.push(this.path[i].join(' '));
|
||||
}
|
||||
var path = chunks.join(' ');
|
||||
addTransform = ' translate(' + (-this.pathOffset.x) + ', ' + (-this.pathOffset.y) + ') ';
|
||||
markup.push(
|
||||
'<path ', this.getSvgCommons(),
|
||||
'd="', path,
|
||||
'" style="', this.getSvgStyles(),
|
||||
'" transform="', this.getSvgTransform(), addTransform,
|
||||
this.getSvgTransformMatrix(), '" stroke-linecap="round" ',
|
||||
this.addPaintOrder(),
|
||||
'/>\n'
|
||||
toClipPathSVG: function(reviver) {
|
||||
var additionalTransform = this._getOffsetTransform();
|
||||
return '\t' + this._createBaseClipPathSVGMarkup(
|
||||
this._toSVG(), { reviver: reviver, additionalTransform: additionalTransform }
|
||||
);
|
||||
|
||||
return reviver ? reviver(markup.join('')) : markup.join('');
|
||||
},
|
||||
/* _TO_SVG_END_ */
|
||||
|
||||
|
|
|
|||
|
|
@ -117,12 +117,11 @@
|
|||
/* _TO_SVG_START_ */
|
||||
/**
|
||||
* Returns svg representation of an instance
|
||||
* @param {Function} [reviver] Method for further parsing of svg representation.
|
||||
* @return {String} svg representation of an instance
|
||||
* @return {Array} an array of strings with the specific svg representation
|
||||
* of the instance
|
||||
*/
|
||||
toSVG: function(reviver) {
|
||||
_toSVG: function() {
|
||||
var points = [], diffX = this.pathOffset.x, diffY = this.pathOffset.y,
|
||||
markup = this._createBaseSVGMarkup(),
|
||||
NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS;
|
||||
|
||||
for (var i = 0, len = this.points.length; i < len; i++) {
|
||||
|
|
@ -131,17 +130,11 @@
|
|||
toFixed(this.points[i].y - diffY, NUM_FRACTION_DIGITS), ' '
|
||||
);
|
||||
}
|
||||
markup.push(
|
||||
'<', this.type, ' ', this.getSvgCommons(),
|
||||
return [
|
||||
'<' + this.type + ' ', 'COMMON_PARTS',
|
||||
'points="', points.join(''),
|
||||
'" style="', this.getSvgStyles(),
|
||||
'" transform="', this.getSvgTransform(),
|
||||
' ', this.getSvgTransformMatrix(), '"',
|
||||
this.addPaintOrder(),
|
||||
'/>\n'
|
||||
);
|
||||
|
||||
return reviver ? reviver(markup.join('')) : markup.join('');
|
||||
'" />\n'
|
||||
];
|
||||
},
|
||||
/* _TO_SVG_END_ */
|
||||
|
||||
|
|
|
|||
|
|
@ -144,23 +144,18 @@
|
|||
/* _TO_SVG_START_ */
|
||||
/**
|
||||
* Returns svg representation of an instance
|
||||
* @param {Function} [reviver] Method for further parsing of svg representation.
|
||||
* @return {String} svg representation of an instance
|
||||
* @return {Array} an array of strings with the specific svg representation
|
||||
* of the instance
|
||||
*/
|
||||
toSVG: function(reviver) {
|
||||
var markup = this._createBaseSVGMarkup(), x = -this.width / 2, y = -this.height / 2;
|
||||
markup.push(
|
||||
'<rect ', this.getSvgCommons(),
|
||||
_toSVG: function() {
|
||||
var x = -this.width / 2, y = -this.height / 2;
|
||||
return [
|
||||
'<rect ', 'COMMON_PARTS',
|
||||
'x="', x, '" y="', y,
|
||||
'" rx="', this.get('rx'), '" ry="', this.get('ry'),
|
||||
'" rx="', this.rx, '" ry="', this.ry,
|
||||
'" width="', this.width, '" height="', this.height,
|
||||
'" style="', this.getSvgStyles(),
|
||||
'" transform="', this.getSvgTransform(),
|
||||
this.getSvgTransformMatrix(), '"',
|
||||
this.addPaintOrder(),
|
||||
'/>\n');
|
||||
|
||||
return reviver ? reviver(markup.join('')) : markup.join('');
|
||||
'" />\n'
|
||||
];
|
||||
},
|
||||
/* _TO_SVG_END_ */
|
||||
});
|
||||
|
|
|
|||
|
|
@ -73,31 +73,23 @@
|
|||
|
||||
/* _TO_SVG_START_ */
|
||||
/**
|
||||
* Returns SVG representation of an instance
|
||||
* @param {Function} [reviver] Method for further parsing of svg representation.
|
||||
* @return {String} svg representation of an instance
|
||||
* Returns svg representation of an instance
|
||||
* @return {Array} an array of strings with the specific svg representation
|
||||
* of the instance
|
||||
*/
|
||||
toSVG: function(reviver) {
|
||||
var markup = this._createBaseSVGMarkup(),
|
||||
widthBy2 = this.width / 2,
|
||||
_toSVG: function() {
|
||||
var widthBy2 = this.width / 2,
|
||||
heightBy2 = this.height / 2,
|
||||
points = [
|
||||
-widthBy2 + ' ' + heightBy2,
|
||||
'0 ' + -heightBy2,
|
||||
widthBy2 + ' ' + heightBy2
|
||||
]
|
||||
.join(',');
|
||||
|
||||
markup.push(
|
||||
'<polygon ', this.getSvgCommons(),
|
||||
].join(',');
|
||||
return [
|
||||
'<polygon ', 'COMMON_PARTS',
|
||||
'points="', points,
|
||||
'" style="', this.getSvgStyles(),
|
||||
'" transform="', this.getSvgTransform(), '"',
|
||||
this.addPaintOrder(),
|
||||
'/>'
|
||||
);
|
||||
|
||||
return reviver ? reviver(markup.join('')) : markup.join('');
|
||||
'" />'
|
||||
];
|
||||
},
|
||||
/* _TO_SVG_END_ */
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1288,7 +1288,7 @@
|
|||
*/
|
||||
toSVG: function(options, reviver) {
|
||||
options || (options = { });
|
||||
|
||||
options.reviver = reviver;
|
||||
var markup = [];
|
||||
|
||||
this._setSVGPreamble(markup, options);
|
||||
|
|
@ -1296,9 +1296,13 @@
|
|||
|
||||
this._setSVGBgOverlayColor(markup, 'backgroundColor');
|
||||
this._setSVGBgOverlayImage(markup, 'backgroundImage', reviver);
|
||||
|
||||
if (this.clipPath) {
|
||||
markup.push('<g clip-path="url(#' + this.clipPath.clipPathId + ')" >\n');
|
||||
}
|
||||
this._setSVGObjects(markup, reviver);
|
||||
|
||||
if (this.clipPath) {
|
||||
markup.push('</g>\n');
|
||||
}
|
||||
this._setSVGBgOverlayColor(markup, 'overlayColor');
|
||||
this._setSVGBgOverlayImage(markup, 'overlayImage', reviver);
|
||||
|
||||
|
|
@ -1361,10 +1365,22 @@
|
|||
'<defs>\n',
|
||||
this.createSVGFontFacesMarkup(),
|
||||
this.createSVGRefElementsMarkup(),
|
||||
this.createSVGClipPathMarkup(options),
|
||||
'</defs>\n'
|
||||
);
|
||||
},
|
||||
|
||||
createSVGClipPathMarkup: function(options) {
|
||||
var clipPath = this.clipPath;
|
||||
if (clipPath) {
|
||||
clipPath.clipPathId = 'CLIPPATH_' + fabric.Object.__uid++;
|
||||
return '<clipPath id="' + clipPath.clipPathId + '" >\n' +
|
||||
this.clipPath.toClipPathSVG(options.reviver) +
|
||||
'</clipPath>\n';
|
||||
}
|
||||
return '';
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates markup containing SVG referenced elements like patterns, gradients etc.
|
||||
* @return {String}
|
||||
|
|
|
|||
|
|
@ -155,6 +155,7 @@
|
|||
|
||||
QUnit.module('fabric.StaticCanvas', {
|
||||
beforeEach: function() {
|
||||
fabric.Object.__uid = 0;
|
||||
canvas.clear();
|
||||
canvas.backgroundColor = fabric.StaticCanvas.prototype.backgroundColor;
|
||||
canvas.backgroundImage = fabric.StaticCanvas.prototype.backgroundImage;
|
||||
|
|
@ -866,6 +867,15 @@
|
|||
canvas.renderOnAddRemove = true;
|
||||
});
|
||||
|
||||
QUnit.test('toSVG with a clipPath', function(assert) {
|
||||
var canvasClip = new fabric.StaticCanvas(null, { width: 400, height: 400 });
|
||||
canvasClip.clipPath = new fabric.Rect({ width: 200, height: 200 });
|
||||
canvasClip.add(new fabric.Circle({ radius: 200 }));
|
||||
var svg = canvasClip.toSVG();
|
||||
var expectedSVG = '<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>\n<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" version=\"1.1\" width=\"400\" height=\"400\" viewBox=\"0 0 400 400\" xml:space=\"preserve\">\n<desc>Created with Fabric.js 2.4.1</desc>\n<defs>\n<clipPath id=\"CLIPPATH_0\" >\n\t<rect transform=\"matrix(1 0 0 1 100.5 100.5)\" x=\"-100\" y=\"-100\" rx=\"0\" ry=\"0\" width=\"200\" height=\"200\" />\n</clipPath>\n</defs>\n<g clip-path=\"url(#CLIPPATH_0)\" >\n<g transform=\"matrix(1 0 0 1 200.5 200.5)\" >\n<circle style=\"stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;\" cx=\"0\" cy=\"0\" r=\"200\" />\n</g>\n</g>\n</svg>';
|
||||
assert.equal(svg, expectedSVG, 'SVG with clipPath should match');
|
||||
});
|
||||
|
||||
QUnit.test('toSVG with exclude from export background', function(assert) {
|
||||
var image = fabric.document.createElement('img'),
|
||||
imageBG = new fabric.Image(image, {width: 0, height: 0}),
|
||||
|
|
@ -874,7 +884,7 @@
|
|||
canvas.renderOnAddRemove = false;
|
||||
canvas.backgroundImage = imageBG;
|
||||
canvas.overlayImage = imageOL;
|
||||
var expectedSVG = '<?xml version="1.0" encoding="UTF-8" standalone="no" ?>\n<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\n<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="600" height="600" viewBox="0 0 600 600" xml:space="preserve">\n<desc>Created with Fabric.js ' + fabric.version + '</desc>\n<defs>\n</defs>\n<g transform="translate(0 0)">\n\t<image xlink:href="" x="0" y="0" style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;" width="0" height="0"></image>\n</g>\n<g transform="translate(0 0)">\n\t<image xlink:href="" x="0" y="0" style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;" width="0" height="0"></image>\n</g>\n</svg>';
|
||||
var expectedSVG = '<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>\n<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" version=\"1.1\" width=\"600\" height=\"600\" viewBox=\"0 0 600 600\" xml:space=\"preserve\">\n<desc>Created with Fabric.js 2.4.1</desc>\n<defs>\n</defs>\n<g transform=\"matrix(1 0 0 1 0 0)\" >\n\t<image style=\"stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;\" xlink:href=\"\" x=\"0\" y=\"0\" width=\"0\" height=\"0\"></image>\n</g>\n<g transform=\"matrix(1 0 0 1 0 0)\" >\n\t<image style=\"stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;\" xlink:href=\"\" x=\"0\" y=\"0\" width=\"0\" height=\"0\"></image>\n</g>\n</svg>';
|
||||
var svg1 = canvas.toSVG();
|
||||
assert.equal(svg1, expectedSVG, 'svg with bg and overlay do not match');
|
||||
imageBG.excludeFromExport = true;
|
||||
|
|
|
|||
|
|
@ -140,15 +140,17 @@
|
|||
QUnit.test('toSVG with full circle', function(assert) {
|
||||
var circle = new fabric.Circle({ width: 100, height: 100, radius: 10 });
|
||||
var svg = circle.toSVG();
|
||||
|
||||
assert.equal(svg, '<circle cx="0" cy="0" r="10" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;" transform="translate(10.5 10.5) "/>\n');
|
||||
var svgClipPath = circle.toClipPathSVG();
|
||||
assert.equal(svg, '<g transform=\"matrix(1 0 0 1 10.5 10.5)\" >\n<circle style=\"stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;\" cx=\"0\" cy=\"0\" r=\"10\" />\n</g>\n');
|
||||
assert.equal(svgClipPath, '\t<circle transform=\"matrix(1 0 0 1 10.5 10.5)\" cx=\"0\" cy=\"0\" r=\"10\" />\n', 'circle as clipPath');
|
||||
});
|
||||
|
||||
QUnit.test('toSVG with half circle', function(assert) {
|
||||
var circle = new fabric.Circle({ width: 100, height: 100, radius: 10, endAngle: Math.PI });
|
||||
var svg = circle.toSVG();
|
||||
|
||||
assert.equal(svg, '<path d="M 10 0 A 10 10 0 0 1 -10 0" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;" transform="translate(10.5 10.5) "/>\n');
|
||||
var svgClipPath = circle.toClipPathSVG();
|
||||
assert.equal(svg, '<g transform=\"matrix(1 0 0 1 10.5 10.5)\" >\n<path d=\"M 10 0 A 10 10 0 0 1 -10 0\"style=\"stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;\" />\n</g>\n');
|
||||
assert.equal(svgClipPath, '\t<path d=\"M 10 0 A 10 10 0 0 1 -10 0\"transform=\"matrix(1 0 0 1 10.5 10.5)\" />\n', 'half circle as clipPath');
|
||||
});
|
||||
|
||||
QUnit.test('fromElement', function(assert) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,10 @@
|
|||
(function(){
|
||||
|
||||
QUnit.module('fabric.Ellipse');
|
||||
QUnit.module('fabric.Ellipse', {
|
||||
beforeEach: function() {
|
||||
fabric.Object.__uid = 0;
|
||||
}
|
||||
});
|
||||
|
||||
QUnit.test('constructor', function(assert) {
|
||||
assert.ok(fabric.Ellipse);
|
||||
|
|
@ -93,6 +97,25 @@
|
|||
assert.equal(wasRenderCalled, false, 'should not render when rx/ry are 0');
|
||||
});
|
||||
|
||||
QUnit.test('toSVG', function(assert) {
|
||||
var ellipse = new fabric.Ellipse({ rx: 100, ry: 12, fill: 'red', stroke: 'blue' });
|
||||
assert.equal(ellipse.toSVG(), '<g transform=\"matrix(1 0 0 1 100.5 12.5)\" >\n<ellipse style=\"stroke: rgb(0,0,255); stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(255,0,0); fill-rule: nonzero; opacity: 1;\" cx=\"0\" cy=\"0\" rx=\"100\" ry=\"12\" />\n</g>\n', 'SVG should match');
|
||||
assert.equal(ellipse.toClipPathSVG(), '\t<ellipse transform=\"matrix(1 0 0 1 100.5 12.5)\" cx=\"0\" cy=\"0\" rx=\"100\" ry=\"12\" />\n', 'SVG clippath should match');
|
||||
});
|
||||
|
||||
QUnit.test('toSVG with a clipPath', function(assert) {
|
||||
var ellipse = new fabric.Ellipse({ rx: 100, ry: 12, fill: 'red', stroke: 'blue' });
|
||||
ellipse.clipPath = new fabric.Ellipse({ rx: 12, ry: 100, left: 60, top: -50 });
|
||||
assert.equal(ellipse.toSVG(), '<g transform=\"matrix(1 0 0 1 100.5 12.5)\" clip-path=\"url(#CLIPPATH_0)\" >\n<clipPath id=\"CLIPPATH_0\" >\n\t<ellipse transform=\"matrix(1 0 0 1 72.5 50.5)\" cx=\"0\" cy=\"0\" rx=\"12\" ry=\"100\" />\n</clipPath>\n<ellipse style=\"stroke: rgb(0,0,255); stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(255,0,0); fill-rule: nonzero; opacity: 1;\" cx=\"0\" cy=\"0\" rx=\"100\" ry=\"12\" />\n</g>\n', 'SVG with clipPath should match');
|
||||
});
|
||||
|
||||
QUnit.test('toSVG with a clipPath absolute positioned', function(assert) {
|
||||
var ellipse = new fabric.Ellipse({ rx: 100, ry: 12, fill: 'red', stroke: 'blue' });
|
||||
ellipse.clipPath = new fabric.Ellipse({ rx: 12, ry: 100, left: 60, top: -50 });
|
||||
ellipse.clipPath.absolutePositioned = true;
|
||||
assert.equal(ellipse.toSVG(), '<g clip-path=\"url(#CLIPPATH_0)\" >\n<g transform=\"matrix(1 0 0 1 100.5 12.5)\" >\n<clipPath id=\"CLIPPATH_0\" >\n\t<ellipse transform=\"matrix(1 0 0 1 72.5 50.5)\" cx=\"0\" cy=\"0\" rx=\"12\" ry=\"100\" />\n</clipPath>\n<ellipse style=\"stroke: rgb(0,0,255); stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(255,0,0); fill-rule: nonzero; opacity: 1;\" cx=\"0\" cy=\"0\" rx=\"100\" ry=\"12\" />\n</g>\n</g>\n', 'SVG with clipPath should match');
|
||||
});
|
||||
|
||||
QUnit.test('fromElement', function(assert) {
|
||||
assert.ok(typeof fabric.Ellipse.fromElement === 'function');
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
|
||||
QUnit.module('fabric.Group', {
|
||||
afterEach: function() {
|
||||
fabric.Object.__uid = 0;
|
||||
canvas.clear();
|
||||
canvas.backgroundColor = fabric.Canvas.prototype.backgroundColor;
|
||||
canvas.calcOffset();
|
||||
|
|
@ -414,7 +415,32 @@
|
|||
var group = makeGroupWith2Objects();
|
||||
assert.ok(typeof group.toSVG === 'function');
|
||||
|
||||
var expectedSVG = '<g transform="translate(90 130)" style="">\n\t<rect x="-15" y="-5" rx="0" ry="0" width="30" height="10" style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;" transform="translate(25 -25)"/>\n\t<rect x="-5" y="-20" rx="0" ry="0" width="10" height="40" style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;" transform="translate(-35 10)"/>\n</g>\n';
|
||||
var expectedSVG = '<g transform=\"matrix(1 0 0 1 90 130)\" style=\"\" >\n\t<g transform=\"matrix(1 0 0 1 25 -25)\" >\n<rect style=\"stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;\" x=\"-15\" y=\"-5\" rx=\"0\" ry=\"0\" width=\"30\" height=\"10\" />\n</g>\n\t<g transform=\"matrix(1 0 0 1 -35 10)\" >\n<rect style=\"stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;\" x=\"-5\" y=\"-20\" rx=\"0\" ry=\"0\" width=\"10\" height=\"40\" />\n</g>\n</g>\n';
|
||||
assert.equal(group.toSVG(), expectedSVG);
|
||||
});
|
||||
|
||||
QUnit.test('toSVG with a clipPath', function(assert) {
|
||||
var group = makeGroupWith2Objects();
|
||||
assert.ok(typeof group.toSVG === 'function');
|
||||
group.clipPath = new fabric.Rect({ width: 100, height: 100 });
|
||||
var expectedSVG = '<g transform=\"matrix(1 0 0 1 90 130)\" style=\"\" clip-path=\"url(#CLIPPATH_0)\" >\n<clipPath id=\"CLIPPATH_0\" >\n\t<rect transform=\"matrix(1 0 0 1 50.5 50.5)\" x=\"-50\" y=\"-50\" rx=\"0\" ry=\"0\" width=\"100\" height=\"100\" />\n</clipPath>\n\t<g transform=\"matrix(1 0 0 1 25 -25)\" >\n<rect style=\"stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;\" x=\"-15\" y=\"-5\" rx=\"0\" ry=\"0\" width=\"30\" height=\"10\" />\n</g>\n\t<g transform=\"matrix(1 0 0 1 -35 10)\" >\n<rect style=\"stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;\" x=\"-5\" y=\"-20\" rx=\"0\" ry=\"0\" width=\"10\" height=\"40\" />\n</g>\n</g>\n';
|
||||
assert.equal(group.toSVG(), expectedSVG);
|
||||
});
|
||||
|
||||
QUnit.test('toSVG with a clipPath absolutePositioned', function(assert) {
|
||||
var group = makeGroupWith2Objects();
|
||||
assert.ok(typeof group.toSVG === 'function');
|
||||
group.clipPath = new fabric.Rect({ width: 100, height: 100 });
|
||||
group.clipPath.absolutePositioned = true;
|
||||
var expectedSVG = '<g style=\"\" clip-path=\"url(#CLIPPATH_0)\" >\n<g transform=\"matrix(1 0 0 1 90 130)\" >\n<clipPath id=\"CLIPPATH_0\" >\n\t<rect transform=\"matrix(1 0 0 1 50.5 50.5)\" x=\"-50\" y=\"-50\" rx=\"0\" ry=\"0\" width=\"100\" height=\"100\" />\n</clipPath>\n\t<g transform=\"matrix(1 0 0 1 25 -25)\" >\n<rect style=\"stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;\" x=\"-15\" y=\"-5\" rx=\"0\" ry=\"0\" width=\"30\" height=\"10\" />\n</g>\n\t<g transform=\"matrix(1 0 0 1 -35 10)\" >\n<rect style=\"stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;\" x=\"-5\" y=\"-20\" rx=\"0\" ry=\"0\" width=\"10\" height=\"40\" />\n</g>\n</g>\n</g>\n';
|
||||
assert.equal(group.toSVG(), expectedSVG);
|
||||
});
|
||||
|
||||
QUnit.test('toSVG with a group as a clipPath', function(assert) {
|
||||
var group = makeGroupWith2Objects();
|
||||
assert.ok(typeof group.toSVG === 'function');
|
||||
group.clipPath = makeGroupWith2Objects();
|
||||
var expectedSVG = '<g transform=\"matrix(1 0 0 1 90 130)\" style=\"\" clip-path=\"url(#CLIPPATH_0)\" >\n<clipPath id=\"CLIPPATH_0\" >\n\t\t<rect transform=\"matrix(1 0 0 1 115 105)\" x=\"-15\" y=\"-5\" rx=\"0\" ry=\"0\" width=\"30\" height=\"10\" />\n\t\t<rect transform=\"matrix(1 0 0 1 55 140)\" x=\"-5\" y=\"-20\" rx=\"0\" ry=\"0\" width=\"10\" height=\"40\" />\n</clipPath>\n\t<g transform=\"matrix(1 0 0 1 25 -25)\" >\n<rect style=\"stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;\" x=\"-15\" y=\"-5\" rx=\"0\" ry=\"0\" width=\"30\" height=\"10\" />\n</g>\n\t<g transform=\"matrix(1 0 0 1 -35 10)\" >\n<rect style=\"stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;\" x=\"-5\" y=\"-20\" rx=\"0\" ry=\"0\" width=\"10\" height=\"40\" />\n</g>\n</g>\n';
|
||||
assert.equal(group.toSVG(), expectedSVG);
|
||||
});
|
||||
|
||||
|
|
|
|||
17
test/unit/header.js
Normal file
17
test/unit/header.js
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
(function() {
|
||||
QUnit.module('fabric header.js');
|
||||
|
||||
QUnit.test('default values', function(assert) {
|
||||
assert.ok(typeof fabric.document !== 'undefined', 'document is set');
|
||||
assert.ok(typeof fabric.window !== 'undefined', 'window is set');
|
||||
assert.ok(typeof fabric.isTouchSupported !== 'undefined', 'isTouchSupported is set');
|
||||
assert.ok(typeof fabric.isLikelyNode !== 'undefined', 'isLikelyNode is set');
|
||||
assert.equal(fabric.SHARED_ATTRIBUTES.length, 17, 'SHARED_ATTRIBUTES is set');
|
||||
});
|
||||
|
||||
QUnit.test('initFilterBackend', function(assert) {
|
||||
assert.ok(typeof fabric.initFilterBackend === 'function', 'initFilterBackend is a function');
|
||||
assert.ok(typeof fabric.maxTextureSize === 'undefined', 'maxTextureSize is not set yet');
|
||||
fabric.initFilterBackend();
|
||||
});
|
||||
})();
|
||||
|
|
@ -220,7 +220,7 @@
|
|||
});
|
||||
});
|
||||
|
||||
QUnit.test('toSVG wit crop', function(assert) {
|
||||
QUnit.test('toSVG with crop', function(assert) {
|
||||
var done = assert.async();
|
||||
createImageObject(function(image) {
|
||||
image.cropX = 1;
|
||||
|
|
@ -228,7 +228,7 @@
|
|||
image.width -= 2;
|
||||
image.height -= 2;
|
||||
fabric.Object.__uid = 1;
|
||||
var expectedSVG = '<clipPath id="imageCrop_1">\n\t<rect x="-137" y="-54" width="274" height="108" />\n</clipPath>\n<g transform="translate(137 54)">\n\t<image xlink:href="' + IMG_SRC + '" x="-138" y="-55" style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;" width="276" height="110" clip-path="url(#imageCrop_1)" ></image>\n</g>\n';
|
||||
var expectedSVG = '<g transform=\"matrix(1 0 0 1 137 54)\" >\n<clipPath id=\"imageCrop_1\">\n\t<rect x=\"-137\" y=\"-54\" width=\"274\" height=\"108\" />\n</clipPath>\n\t<image style=\"stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;\" xlink:href=\"' + IMG_SRC + '\" x=\"-138\" y=\"-55\" width=\"276\" height=\"110\" clip-path=\"url(#imageCrop_1)\" ></image>\n</g>\n';
|
||||
assert.equal(image.toSVG(), expectedSVG);
|
||||
done();
|
||||
});
|
||||
|
|
@ -257,7 +257,7 @@
|
|||
var done = assert.async();
|
||||
createImageObject(function(image) {
|
||||
assert.ok(typeof image.toSVG === 'function');
|
||||
var expectedSVG = '<g transform="translate(138 55)">\n\t<image xlink:href="' + IMG_SRC + '" x="-138" y="-55" style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;" width="276" height="110"></image>\n</g>\n';
|
||||
var expectedSVG = '<g transform=\"matrix(1 0 0 1 138 55)\" >\n\t<image style=\"stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;\" xlink:href=\"' + IMG_SRC + '\" x=\"-138\" y=\"-55\" width=\"276\" height=\"110\"></image>\n</g>\n';
|
||||
assert.equal(image.toSVG(), expectedSVG);
|
||||
done();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -67,6 +67,12 @@
|
|||
assert.ok(typeof line.complexity === 'function');
|
||||
});
|
||||
|
||||
QUnit.test('toSVG', function(assert) {
|
||||
var line = new fabric.Line([11, 12, 13, 14]);
|
||||
var EXPECTED_SVG = '<g transform=\"matrix(1 0 0 1 12.5 13.5)\" >\n<line style=\"stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;\" x1=\"-1\" y1=\"-1\" x2=\"1\" y2=\"1\" />\n</g>\n';
|
||||
assert.equal(line.toSVG(), EXPECTED_SVG);
|
||||
});
|
||||
|
||||
QUnit.test('toObject', function(assert) {
|
||||
var line = new fabric.Line([11, 12, 13, 14]);
|
||||
assert.ok(typeof line.toObject === 'function');
|
||||
|
|
|
|||
|
|
@ -55,7 +55,11 @@
|
|||
getPathObject('M 100 100 L 300 100 L 200 300 z', callback);
|
||||
}
|
||||
|
||||
QUnit.module('fabric.Path');
|
||||
QUnit.module('fabric.Path', {
|
||||
beforeEach: function() {
|
||||
fabric.Object.__uid = 0;
|
||||
}
|
||||
});
|
||||
|
||||
QUnit.test('constructor', function(assert) {
|
||||
var done = assert.async();
|
||||
|
|
@ -124,11 +128,35 @@
|
|||
var done = assert.async();
|
||||
makePathObject(function(path) {
|
||||
assert.ok(typeof path.toSVG === 'function');
|
||||
assert.deepEqual(path.toSVG(), '<path d="M 100 100 L 300 100 L 200 300 z" style="stroke: rgb(0,0,255); stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(255,0,0); fill-rule: nonzero; opacity: 1;" transform="translate(200.5 200.5) translate(-200, -200) " stroke-linecap="round" />\n');
|
||||
assert.deepEqual(path.toSVG(), '<g transform=\"matrix(1 0 0 1 200.5 200.5)\" >\n<path style=\"stroke: rgb(0,0,255); stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(255,0,0); fill-rule: nonzero; opacity: 1;\" d=\"M 100 100 L 300 100 L 200 300 z\" stroke-linecap=\"round\" transform=\" translate(-200, -200)\" />\n</g>\n');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
QUnit.test('toSVG with a clipPath path', function(assert) {
|
||||
var done = assert.async();
|
||||
makePathObject(function(path) {
|
||||
makePathObject(function(path2) {
|
||||
path.clipPath = path2;
|
||||
assert.deepEqual(path.toSVG(), '<g transform=\"matrix(1 0 0 1 200.5 200.5)\" clip-path=\"url(#CLIPPATH_0)\" >\n<clipPath id=\"CLIPPATH_0\" >\n\t<path transform=\"matrix(1 0 0 1 200.5 200.5) translate(-200, -200)\" d=\"M 100 100 L 300 100 L 200 300 z\" stroke-linecap=\"round\" transform=\" translate(-200, -200)\" />\n</clipPath>\n<path style=\"stroke: rgb(0,0,255); stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(255,0,0); fill-rule: nonzero; opacity: 1;\" d=\"M 100 100 L 300 100 L 200 300 z\" stroke-linecap=\"round\" transform=\" translate(-200, -200)\" />\n</g>\n', 'path clipPath toSVG should match');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
QUnit.test('toSVG with a clipPath path absolutePositioned', function(assert) {
|
||||
var done = assert.async();
|
||||
makePathObject(function(path) {
|
||||
makePathObject(function(path2) {
|
||||
path.clipPath = path2;
|
||||
path.clipPath.absolutePositioned = true;
|
||||
assert.deepEqual(path.toSVG(), '<g clip-path=\"url(#CLIPPATH_0)\" >\n<g transform=\"matrix(1 0 0 1 200.5 200.5)\" >\n<clipPath id=\"CLIPPATH_0\" >\n\t<path transform=\"matrix(1 0 0 1 200.5 200.5) translate(-200, -200)\" d=\"M 100 100 L 300 100 L 200 300 z\" stroke-linecap=\"round\" transform=\" translate(-200, -200)\" />\n</clipPath>\n<path style=\"stroke: rgb(0,0,255); stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(255,0,0); fill-rule: nonzero; opacity: 1;\" d=\"M 100 100 L 300 100 L 200 300 z\" stroke-linecap=\"round\" transform=\" translate(-200, -200)\" />\n</g>\n</g>\n', 'path clipPath toSVG absolute should match');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
QUnit.test('path array not shared when cloned', function(assert) {
|
||||
var done = assert.async();
|
||||
makePathObject(function(originalPath) {
|
||||
|
|
|
|||
|
|
@ -80,6 +80,13 @@
|
|||
assert.deepEqual(objectWithOriginalPoints, REFERENCE_OBJECT);
|
||||
});
|
||||
|
||||
QUnit.test('toSVG', function(assert) {
|
||||
var polygon = new fabric.Polygon(getPoints(), { fill: 'red', stroke: 'blue' });
|
||||
assert.ok(typeof polygon.toSVG === 'function');
|
||||
var EXPECTED_SVG = '<g transform=\"matrix(1 0 0 1 15.5 17.5)\" >\n<polygon style=\"stroke: rgb(0,0,255); stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(255,0,0); fill-rule: nonzero; opacity: 1;\" points=\"-5,-5 5,5 \" />\n</g>\n';
|
||||
assert.deepEqual(polygon.toSVG(), EXPECTED_SVG);
|
||||
});
|
||||
|
||||
QUnit.test('fromObject', function(assert) {
|
||||
var done = assert.async();
|
||||
assert.ok(typeof fabric.Polygon.fromObject === 'function');
|
||||
|
|
|
|||
|
|
@ -79,6 +79,13 @@
|
|||
assert.deepEqual(objectWithOriginalPoints, REFERENCE_OBJECT);
|
||||
});
|
||||
|
||||
QUnit.test('toSVG', function(assert) {
|
||||
var polyline = new fabric.Polygon(getPoints(), { fill: 'red', stroke: 'blue' });
|
||||
assert.ok(typeof polyline.toSVG === 'function');
|
||||
var EXPECTED_SVG = '<g transform=\"matrix(1 0 0 1 15.5 17.5)\" >\n<polygon style=\"stroke: rgb(0,0,255); stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(255,0,0); fill-rule: nonzero; opacity: 1;\" points=\"-5,-5 5,5 \" />\n</g>\n';
|
||||
assert.deepEqual(polyline.toSVG(), EXPECTED_SVG);
|
||||
});
|
||||
|
||||
QUnit.test('fromObject', function(assert) {
|
||||
var done = assert.async();
|
||||
assert.ok(typeof fabric.Polyline.fromObject === 'function');
|
||||
|
|
|
|||
|
|
@ -172,31 +172,31 @@
|
|||
var rect = new fabric.Rect({ width: 100, height: 100, rx: 20, ry: 30, strokeWidth: 0 });
|
||||
var svg = rect.toSVG();
|
||||
|
||||
assert.equal(svg, '<rect x="-50" y="-50" rx="20" ry="30" width="100" height="100" style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;" transform="translate(50 50)"/>\n');
|
||||
assert.equal(svg, '<g transform=\"matrix(1 0 0 1 50 50)\" >\n<rect style=\"stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;\" x=\"-50\" y=\"-50\" rx=\"20\" ry=\"30\" width=\"100\" height=\"100\" />\n</g>\n');
|
||||
});
|
||||
|
||||
QUnit.test('toSVG with alpha colors fill', function(assert) {
|
||||
var rect = new fabric.Rect({ width: 100, height: 100, strokeWidth: 0, fill: 'rgba(255, 0, 0, 0.5)' });
|
||||
var svg = rect.toSVG();
|
||||
assert.equal(svg, '<rect x="-50" y="-50" rx="0" ry="0" width="100" height="100" style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(255,0,0); fill-opacity: 0.5; fill-rule: nonzero; opacity: 1;" transform="translate(50 50)"/>\n');
|
||||
assert.equal(svg, '<g transform=\"matrix(1 0 0 1 50 50)\" >\n<rect style=\"stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(255,0,0); fill-opacity: 0.5; fill-rule: nonzero; opacity: 1;\" x=\"-50\" y=\"-50\" rx=\"0\" ry=\"0\" width=\"100\" height=\"100\" />\n</g>\n');
|
||||
});
|
||||
|
||||
QUnit.test('toSVG with id', function(assert) {
|
||||
var rect = new fabric.Rect({id: 'myRect', width: 100, height: 100, strokeWidth: 0, fill: 'rgba(255, 0, 0, 0.5)' });
|
||||
var svg = rect.toSVG();
|
||||
assert.equal(svg, '<rect id="myRect" x="-50" y="-50" rx="0" ry="0" width="100" height="100" style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(255,0,0); fill-opacity: 0.5; fill-rule: nonzero; opacity: 1;" transform="translate(50 50)"/>\n');
|
||||
assert.equal(svg, '<g transform=\"matrix(1 0 0 1 50 50)\" id=\"myRect\" >\n<rect style=\"stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(255,0,0); fill-opacity: 0.5; fill-rule: nonzero; opacity: 1;\" x=\"-50\" y=\"-50\" rx=\"0\" ry=\"0\" width=\"100\" height=\"100\" />\n</g>\n');
|
||||
});
|
||||
|
||||
QUnit.test('toSVG with alpha colors stroke', function(assert) {
|
||||
var rect = new fabric.Rect({ width: 100, height: 100, strokeWidth: 0, fill: '', stroke: 'rgba(255, 0, 0, 0.5)' });
|
||||
var svg = rect.toSVG();
|
||||
assert.equal(svg, '<rect x="-50" y="-50" rx="0" ry="0" width="100" height="100" style="stroke: rgb(255,0,0); stroke-opacity: 0.5; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: none; fill-rule: nonzero; opacity: 1;" transform="translate(50 50)"/>\n');
|
||||
assert.equal(svg, '<g transform=\"matrix(1 0 0 1 50 50)\" >\n<rect style=\"stroke: rgb(255,0,0); stroke-opacity: 0.5; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: none; fill-rule: nonzero; opacity: 1;\" x=\"-50\" y=\"-50\" rx=\"0\" ry=\"0\" width=\"100\" height=\"100\" />\n</g>\n');
|
||||
});
|
||||
|
||||
QUnit.test('toSVG with paintFirst set to stroke', function(assert) {
|
||||
var rect = new fabric.Rect({ width: 100, height: 100, paintFirst: 'stroke' });
|
||||
var svg = rect.toSVG();
|
||||
assert.equal(svg, '<rect x="-50" y="-50" rx="0" ry="0" width="100" height="100" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;" transform="translate(50.5 50.5)" paint-order="stroke" />\n');
|
||||
assert.equal(svg, '<g transform=\"matrix(1 0 0 1 50.5 50.5)\" >\n<rect style=\"stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;\" paint-order=\"stroke\" x=\"-50\" y=\"-50\" rx=\"0\" ry=\"0\" width=\"100\" height=\"100\" />\n</g>\n');
|
||||
});
|
||||
|
||||
QUnit.test('toObject without default values', function(assert) {
|
||||
|
|
|
|||
|
|
@ -1,17 +1,17 @@
|
|||
(function() {
|
||||
function removeTranslate(str) {
|
||||
return str.replace(/translate\(.*?\)/, '');
|
||||
return str.replace(/matrix\(.*?\)/, '');
|
||||
}
|
||||
QUnit.module('fabric.Text');
|
||||
QUnit.test('toSVG', function(assert) {
|
||||
var TEXT_SVG = '\t<g transform="translate(10.5 26.72)">\n\t\t<text xml:space="preserve" font-family="Times New Roman" font-size="40" font-style="normal" font-weight="normal" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1; white-space: pre;" ><tspan x="-10" y="12.57" >x</tspan></text>\n\t</g>\n';
|
||||
var TEXT_SVG = '<g transform=\"\" style=\"\" >\n\t\t<text xml:space=\"preserve\" font-family=\"Times New Roman\" font-size=\"40\" font-style=\"normal\" font-weight=\"normal\" style=\"stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1; white-space: pre;\" ><tspan x=\"-10\" y=\"12.57\" >x</tspan></text>\n</g>\n';
|
||||
var text = new fabric.Text('x');
|
||||
assert.equal(removeTranslate(text.toSVG()), removeTranslate(TEXT_SVG));
|
||||
text.set('fontFamily', 'Arial');
|
||||
assert.equal(removeTranslate(text.toSVG()), removeTranslate(TEXT_SVG.replace('font-family="Times New Roman"', 'font-family="Arial"')));
|
||||
});
|
||||
QUnit.test('toSVG justified', function(assert) {
|
||||
var TEXT_SVG_JUSTIFIED = '\t<g transform="translate(50.5 26.72)">\n\t\t<text xml:space="preserve" font-family="Times New Roman" font-size="40" font-style="normal" font-weight="normal" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1; white-space: pre;" ><tspan x="-60" y="-13.65" >xxxxxx</tspan><tspan x="-60" y="38.78" style="white-space: pre; ">x </tspan><tspan x=\"40\" y=\"38.78\" >y</tspan></text>\n\t</g>\n';
|
||||
var TEXT_SVG_JUSTIFIED = '<g transform=\"\" style=\"\" >\n\t\t<text xml:space=\"preserve\" font-family=\"Times New Roman\" font-size=\"40\" font-style=\"normal\" font-weight=\"normal\" style=\"stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1; white-space: pre;\" ><tspan x=\"-60\" y=\"-13.65\" >xxxxxx</tspan><tspan x=\"-60\" y=\"38.78\" style=\"white-space: pre; \">x </tspan><tspan x=\"40\" y=\"38.78\" >y</tspan></text>\n</g>\n';
|
||||
var text = new fabric.Text('xxxxxx\nx y', {
|
||||
textAlign: 'justify',
|
||||
});
|
||||
|
|
@ -19,13 +19,13 @@
|
|||
assert.equal(removeTranslate(text.toSVG()), removeTranslate(TEXT_SVG_JUSTIFIED));
|
||||
});
|
||||
QUnit.test('toSVG with multiple spaces', function(assert) {
|
||||
var TEXT_SVG_MULTIPLESPACES = '\t<g transform="translate(50.5 26.72)">\n\t\t<text xml:space="preserve" font-family="Times New Roman" font-size="40" font-style="normal" font-weight="normal" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1; white-space: pre;" ><tspan x="-105" y="12.57" style="white-space: pre; ">x y</tspan></text>\n\t</g>\n';
|
||||
var TEXT_SVG_MULTIPLESPACES = '<g transform=\"\" style=\"\" >\n\t\t<text xml:space=\"preserve\" font-family=\"Times New Roman\" font-size=\"40\" font-style=\"normal\" font-weight=\"normal\" style=\"stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1; white-space: pre;\" ><tspan x=\"-105\" y=\"12.57\" style=\"white-space: pre; \">x y</tspan></text>\n</g>\n';
|
||||
var text = new fabric.Text('x y');
|
||||
assert.equal(removeTranslate(text.toSVG()), removeTranslate(TEXT_SVG_MULTIPLESPACES));
|
||||
});
|
||||
QUnit.test('toSVG with deltaY', function(assert) {
|
||||
fabric.Object.NUM_FRACTION_DIGITS = 0;
|
||||
var TEXT_SVG = '\t<g transform="translate(10.5 26.7)">\n\t\t<text xml:space="preserve" font-family="Times New Roman" font-size="40" font-style="normal" font-weight="normal" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1; white-space: pre;" ><tspan x="-16" y="13" >x</tspan><tspan x="4" y="13" dy="-14" style="font-size: 24px; baseline-shift: 14; ">x</tspan></text>\n\t</g>\n';
|
||||
var TEXT_SVG = '<g transform=\"\" style=\"\" >\n\t\t<text xml:space=\"preserve\" font-family=\"Times New Roman\" font-size=\"40\" font-style=\"normal\" font-weight=\"normal\" style=\"stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1; white-space: pre;\" ><tspan x=\"-16\" y=\"13\" >x</tspan><tspan x=\"4\" y=\"13\" dy=\"-14\" style=\"font-size: 24px; baseline-shift: 14; \">x</tspan></text>\n</g>\n';
|
||||
var text = new fabric.Text('xx', {
|
||||
styles: {
|
||||
0: {
|
||||
|
|
@ -41,7 +41,7 @@
|
|||
});
|
||||
|
||||
QUnit.test('toSVG with font', function(assert) {
|
||||
var TEXT_SVG_WITH_FONT = '\t<g transform="translate(50.5 26.72)">\n\t\t<text xml:space="preserve" font-family="Times New Roman" font-size="40" font-style="normal" font-weight="normal" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1; white-space: pre;" ><tspan x="-60" y="-13.65" style="font-family: \'Times New Roman\'; ">xxxxxx</tspan><tspan x="-60" y="38.78" style="white-space: pre; ">x </tspan><tspan x=\"40\" y=\"38.78\" >y</tspan></text>\n\t</g>\n';
|
||||
var TEXT_SVG_WITH_FONT = '<g transform=\"\" style=\"\" >\n\t\t<text xml:space=\"preserve\" font-family=\"Times New Roman\" font-size=\"40\" font-style=\"normal\" font-weight=\"normal\" style=\"stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1; white-space: pre;\" ><tspan x=\"-60\" y=\"-13.65\" style=\"font-family: \'Times New Roman\'; \">xxxxxx</tspan><tspan x=\"-60\" y=\"38.78\" style=\"white-space: pre; \">x </tspan><tspan x=\"40\" y=\"38.78\" >y</tspan></text>\n</g>\n';
|
||||
var text = new fabric.Text('xxxxxx\nx y', {
|
||||
textAlign: 'justify',
|
||||
styles: {0: {
|
||||
|
|
|
|||
|
|
@ -134,7 +134,7 @@
|
|||
code: clipping3,
|
||||
golden: 'clipping3.png',
|
||||
percentage: 0.06,
|
||||
disabled: true,
|
||||
disabled: false,
|
||||
});
|
||||
|
||||
function clipping4(canvas, callback) {
|
||||
|
|
@ -206,7 +206,7 @@
|
|||
code: clipping5,
|
||||
golden: 'clipping5.png',
|
||||
percentage: 0.06,
|
||||
disabled: true,
|
||||
disabled: false,
|
||||
});
|
||||
|
||||
function clipping6(canvas, callback) {
|
||||
|
|
@ -270,7 +270,7 @@
|
|||
code: clipping7,
|
||||
golden: 'clipping7.png',
|
||||
percentage: 0.06,
|
||||
disabled: true,
|
||||
disabled: false,
|
||||
});
|
||||
|
||||
function clipping8(canvas, callback) {
|
||||
|
|
@ -294,7 +294,7 @@
|
|||
code: clipping8,
|
||||
golden: 'clipping8.png',
|
||||
percentage: 0.06,
|
||||
disabled: true,
|
||||
disabled: false,
|
||||
});
|
||||
|
||||
function clipping9(canvas, callback) {
|
||||
|
|
@ -316,7 +316,7 @@
|
|||
code: clipping9,
|
||||
golden: 'clipping9.png',
|
||||
percentage: 0.06,
|
||||
disabled: true,
|
||||
disabled: false,
|
||||
});
|
||||
|
||||
tests.forEach(visualTestLoop(fabricCanvas, QUnit));
|
||||
|
|
|
|||
Loading…
Reference in a new issue