mirror of
https://github.com/Hopiu/fabric.js.git
synced 2026-03-16 22:10:32 +00:00
parent
133c674697
commit
db292dfb2f
6 changed files with 274 additions and 171 deletions
13
CHANGELOG.md
13
CHANGELOG.md
|
|
@ -1,3 +1,16 @@
|
|||
**Version 2.3.4**
|
||||
- Fix: ToSVG was ignoring excludeFromExport for backgroundImage and OverlayImage. [#5075](https://github.com/fabricjs/fabric.js/pull/5075)
|
||||
- Fix: ToSVG for circle with start and end angles. [#5085](https://github.com/fabricjs/fabric.js/pull/5085)
|
||||
- Fix: Added callback for setPatternFill. [#5101](https://github.com/fabricjs/fabric.js/pull/5101)
|
||||
- Fix: Resize filter taking in account multiple scale sources. [#5117](https://github.com/fabricjs/fabric.js/pull/5117)
|
||||
- Fix: Blend image filter clean after refilter. [#5121](https://github.com/fabricjs/fabric.js/pull/5121)
|
||||
- Fix: Object.toDataURL should not be influenced by zoom. [#5139](https://github.com/fabricjs/fabric.js/pull/5139)
|
||||
- Improvement: requestRenderAllBound add to Canvas instance. [#5138](https://github.com/fabricjs/fabric.js/pull/5138)
|
||||
- Improvement: Make path bounding cache optional and also reacheable/cleanable [#5140](https://github.com/fabricjs/fabric.js/pull/5140)
|
||||
- Improvement: Make the logic of isNeutralState filters work before filtering start. [#5129](https://github.com/fabricjs/fabric.js/pull/5129)
|
||||
- Improvement: Added some code to clean up some memory when canvas is disposed in nodejs. [#5142](https://github.com/fabricjs/fabric.js/pull/5142)
|
||||
- Fix: Make numeric origins work with group creation. [#5143](https://github.com/fabricjs/fabric.js/pull/5143)
|
||||
|
||||
**Version 2.3.3**
|
||||
- Fix: Fixed font generic names for text, measurement of zero width related characters and also trailing of cursor when zooming. [#5048](https://github.com/fabricjs/fabric.js/pull/5048)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*! Fabric.js Copyright 2008-2015, Printio (Juriy Zaytsev, Maxim Chernyak) */
|
||||
|
||||
var fabric = fabric || { version: '2.3.3' };
|
||||
var fabric = fabric || { version: '2.3.4' };
|
||||
if (typeof exports !== 'undefined') {
|
||||
exports.fabric = fabric;
|
||||
}
|
||||
|
|
|
|||
422
dist/fabric.js
vendored
422
dist/fabric.js
vendored
|
|
@ -1,7 +1,7 @@
|
|||
/* build: `node build.js modules=ALL exclude=gestures,accessors requirejs minifier=uglifyjs` */
|
||||
/*! Fabric.js Copyright 2008-2015, Printio (Juriy Zaytsev, Maxim Chernyak) */
|
||||
|
||||
var fabric = fabric || { version: '2.3.3' };
|
||||
var fabric = fabric || { version: '2.3.4' };
|
||||
if (typeof exports !== 'undefined') {
|
||||
exports.fabric = fabric;
|
||||
}
|
||||
|
|
@ -141,6 +141,28 @@ fabric.devicePixelRatio = fabric.window.devicePixelRatio ||
|
|||
*/
|
||||
fabric.browserShadowBlurConstant = 1;
|
||||
|
||||
/**
|
||||
* This object contains the result of arc to beizer conversion for faster retrieving if the same arc needs to be converted again.
|
||||
* It was an internal variable, is accessible since version 2.3.4
|
||||
*/
|
||||
fabric.arcToSegmentsCache = { };
|
||||
|
||||
/**
|
||||
* This object keeps the results of the boundsOfCurve calculation mapped by the joined arguments necessary to calculate it.
|
||||
* It does speed up calculation, if you parse and add always the same paths, but in case of heavy usage of freedrawing
|
||||
* you do not get any speed benefit and you get a big object in memory.
|
||||
* The object was a private variable before, while now is appended to the lib so that you have access to it and you
|
||||
* can eventually clear it.
|
||||
* It was an internal variable, is accessible since version 2.3.4
|
||||
*/
|
||||
fabric.boundsOfCurveCache = { };
|
||||
|
||||
/**
|
||||
* If disabled boundsOfCurveCache is not used. For apps that make heavy usage of pencil drawing probably disabling it is better
|
||||
* @default true
|
||||
*/
|
||||
fabric.cachesBoundsOfCurve = true;
|
||||
|
||||
fabric.initFilterBackend = function() {
|
||||
if (fabric.enableGLFiltering && fabric.isWebglSupported && fabric.isWebglSupported(fabric.textureSize)) {
|
||||
console.log('max texture size: ' + fabric.maxTextureSize);
|
||||
|
|
@ -1223,6 +1245,12 @@ fabric.CommonMethods = {
|
|||
return fabric.util.multiplyTransformMatrices(scaleMatrix, skewMatrixX, true);
|
||||
},
|
||||
|
||||
/**
|
||||
* reset an object transform state to neutral. Top and left are not accounted for
|
||||
* @static
|
||||
* @memberOf fabric.util
|
||||
* @param {fabric.Object} target object to transform
|
||||
*/
|
||||
resetObjectTransform: function (target) {
|
||||
target.scaleX = 1;
|
||||
target.scaleY = 1;
|
||||
|
|
@ -1233,6 +1261,27 @@ fabric.CommonMethods = {
|
|||
target.rotate(0);
|
||||
},
|
||||
|
||||
/**
|
||||
* Extract Object transform values
|
||||
* @static
|
||||
* @memberOf fabric.util
|
||||
* @param {fabric.Object} target object to read from
|
||||
* @return {Object} Components of transform
|
||||
*/
|
||||
saveObjectTransform: function (target) {
|
||||
return {
|
||||
scaleX: target.scaleX,
|
||||
scaleY: target.scaleY,
|
||||
skewX: target.skewX,
|
||||
skewY: target.skewY,
|
||||
angle: target.angle,
|
||||
left: target.left,
|
||||
flipX: target.flipX,
|
||||
flipY: target.flipY,
|
||||
top: target.top
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns string representation of function body
|
||||
* @param {Function} fn Function to get body of
|
||||
|
|
@ -1370,10 +1419,7 @@ fabric.CommonMethods = {
|
|||
|
||||
(function() {
|
||||
|
||||
var arcToSegmentsCache = { },
|
||||
segmentToBezierCache = { },
|
||||
boundsOfCurveCache = { },
|
||||
_join = Array.prototype.join;
|
||||
var _join = Array.prototype.join;
|
||||
|
||||
/* Adapted from http://dxr.mozilla.org/mozilla-central/source/content/svg/content/src/nsSVGPathDataParser.cpp
|
||||
* by Andrea Bogazzi code is under MPL. if you don't have a copy of the license you can take it here
|
||||
|
|
@ -1381,8 +1427,8 @@ fabric.CommonMethods = {
|
|||
*/
|
||||
function arcToSegments(toX, toY, rx, ry, large, sweep, rotateX) {
|
||||
var argsString = _join.call(arguments);
|
||||
if (arcToSegmentsCache[argsString]) {
|
||||
return arcToSegmentsCache[argsString];
|
||||
if (fabric.arcToSegmentsCache[argsString]) {
|
||||
return fabric.arcToSegmentsCache[argsString];
|
||||
}
|
||||
|
||||
var PI = Math.PI, th = rotateX * PI / 180,
|
||||
|
|
@ -1436,16 +1482,11 @@ fabric.CommonMethods = {
|
|||
mTheta = th3;
|
||||
th3 += mDelta;
|
||||
}
|
||||
arcToSegmentsCache[argsString] = result;
|
||||
fabric.arcToSegmentsCache[argsString] = result;
|
||||
return result;
|
||||
}
|
||||
|
||||
function segmentToBezier(th2, th3, cosTh, sinTh, rx, ry, cx1, cy1, mT, fromX, fromY) {
|
||||
var argsString2 = _join.call(arguments);
|
||||
if (segmentToBezierCache[argsString2]) {
|
||||
return segmentToBezierCache[argsString2];
|
||||
}
|
||||
|
||||
var costh2 = fabric.util.cos(th2),
|
||||
sinth2 = fabric.util.sin(th2),
|
||||
costh3 = fabric.util.cos(th3),
|
||||
|
|
@ -1457,12 +1498,11 @@ fabric.CommonMethods = {
|
|||
cp2X = toX + mT * ( cosTh * rx * sinth3 + sinTh * ry * costh3),
|
||||
cp2Y = toY + mT * ( sinTh * rx * sinth3 - cosTh * ry * costh3);
|
||||
|
||||
segmentToBezierCache[argsString2] = [
|
||||
return [
|
||||
cp1X, cp1Y,
|
||||
cp2X, cp2Y,
|
||||
toX, toY
|
||||
];
|
||||
return segmentToBezierCache[argsString2];
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1548,9 +1588,12 @@ fabric.CommonMethods = {
|
|||
*/
|
||||
// taken from http://jsbin.com/ivomiq/56/edit no credits available for that.
|
||||
function getBoundsOfCurve(x0, y0, x1, y1, x2, y2, x3, y3) {
|
||||
var argsString = _join.call(arguments);
|
||||
if (boundsOfCurveCache[argsString]) {
|
||||
return boundsOfCurveCache[argsString];
|
||||
var argsString;
|
||||
if (fabric.cachesBoundsOfCurve) {
|
||||
argsString = _join.call(arguments);
|
||||
if (fabric.boundsOfCurveCache[argsString]) {
|
||||
return fabric.boundsOfCurveCache[argsString];
|
||||
}
|
||||
}
|
||||
|
||||
var sqrt = Math.sqrt,
|
||||
|
|
@ -1620,7 +1663,9 @@ fabric.CommonMethods = {
|
|||
y: max.apply(null, bounds[1])
|
||||
}
|
||||
];
|
||||
boundsOfCurveCache[argsString] = result;
|
||||
if (fabric.cachesBoundsOfCurve) {
|
||||
fabric.boundsOfCurveCache[argsString] = result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -2625,6 +2670,21 @@ fabric.CommonMethods = {
|
|||
return impl._canvas || impl._image;
|
||||
};
|
||||
|
||||
function cleanUpJsdomNode(element) {
|
||||
if (!fabric.isLikelyNode) {
|
||||
return;
|
||||
}
|
||||
var impl = fabric.jsdomImplForWrapper(element);
|
||||
if (impl) {
|
||||
impl._image = null;
|
||||
impl._canvas = null;
|
||||
// unsure if necessary
|
||||
impl._currentSrc = null;
|
||||
impl._attributes = null;
|
||||
impl._classList = null;
|
||||
}
|
||||
}
|
||||
|
||||
fabric.util.getById = getById;
|
||||
fabric.util.toArray = toArray;
|
||||
fabric.util.makeElement = makeElement;
|
||||
|
|
@ -2634,6 +2694,7 @@ fabric.CommonMethods = {
|
|||
fabric.util.getElementOffset = getElementOffset;
|
||||
fabric.util.getElementStyle = getElementStyle;
|
||||
fabric.util.getNodeCanvas = getNodeCanvas;
|
||||
fabric.util.cleanUpJsdomNode = cleanUpJsdomNode;
|
||||
|
||||
})();
|
||||
|
||||
|
|
@ -2646,10 +2707,10 @@ fabric.CommonMethods = {
|
|||
|
||||
var makeXHR = (function() {
|
||||
var factories = [
|
||||
function() { return new fabric.window.XMLHttpRequest(); },
|
||||
function() { return new ActiveXObject('Microsoft.XMLHTTP'); },
|
||||
function() { return new ActiveXObject('Msxml2.XMLHTTP'); },
|
||||
function() { return new ActiveXObject('Msxml2.XMLHTTP.3.0'); },
|
||||
function() { return new XMLHttpRequest(); }
|
||||
function() { return new ActiveXObject('Msxml2.XMLHTTP.3.0'); }
|
||||
];
|
||||
for (var i = factories.length; i--; ) {
|
||||
try {
|
||||
|
|
@ -2676,7 +2737,6 @@ fabric.CommonMethods = {
|
|||
* @return {XMLHttpRequest} request
|
||||
*/
|
||||
function request(url, options) {
|
||||
|
||||
options || (options = { });
|
||||
|
||||
var method = options.method ? options.method.toUpperCase() : 'GET',
|
||||
|
|
@ -7794,7 +7854,7 @@ fabric.ElementsParser.prototype.checkIfDone = function() {
|
|||
* @private
|
||||
*/
|
||||
_setSVGBgOverlayImage: function(markup, property, reviver) {
|
||||
if (this[property] && this[property].toSVG) {
|
||||
if (this[property] && !this[property].excludeFromExport && this[property].toSVG) {
|
||||
markup.push(this[property].toSVG(reviver));
|
||||
}
|
||||
},
|
||||
|
|
@ -8067,11 +8127,18 @@ fabric.ElementsParser.prototype.checkIfDone = function() {
|
|||
object.dispose && object.dispose();
|
||||
});
|
||||
this._objects = [];
|
||||
if (this.backgroundImage && this.backgroundImage.dispose) {
|
||||
this.backgroundImage.dispose();
|
||||
}
|
||||
this.backgroundImage = null;
|
||||
if (this.overlayImage && this.overlayImage.dispose) {
|
||||
this.overlayImage.dispose();
|
||||
}
|
||||
this.overlayImage = null;
|
||||
this._iTextInstances = null;
|
||||
this.lowerCanvasEl = null;
|
||||
this.contextContainer = null;
|
||||
fabric.util.cleanUpJsdomNode(this.lowerCanvasEl);
|
||||
this.lowerCanvasEl = undefined;
|
||||
return this;
|
||||
},
|
||||
|
||||
|
|
@ -8925,7 +8992,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
|
|||
|
||||
var dotWidth = 20,
|
||||
dotDistance = 5,
|
||||
patternCanvas = fabric.document.createElement('canvas'),
|
||||
patternCanvas = fabric.util.createCanvasElement(),
|
||||
patternCtx = patternCanvas.getContext('2d');
|
||||
|
||||
patternCanvas.width = patternCanvas.height = dotWidth + dotDistance;
|
||||
|
|
@ -9038,6 +9105,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
|
|||
initialize: function(el, options) {
|
||||
options || (options = { });
|
||||
this.renderAndResetBound = this.renderAndReset.bind(this);
|
||||
this.requestRenderAllBound = this.requestRenderAll.bind(this);
|
||||
this._initStatic(el, options);
|
||||
this._initInteractive();
|
||||
this._createCacheCanvas();
|
||||
|
|
@ -9679,19 +9747,12 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
|
|||
mouseXSign: 1,
|
||||
mouseYSign: 1,
|
||||
shiftKey: e.shiftKey,
|
||||
altKey: e[this.centeredKey]
|
||||
altKey: e[this.centeredKey],
|
||||
original: fabric.util.saveObjectTransform(target),
|
||||
};
|
||||
|
||||
this._currentTransform.original = {
|
||||
left: target.left,
|
||||
top: target.top,
|
||||
scaleX: target.scaleX,
|
||||
scaleY: target.scaleY,
|
||||
skewX: target.skewX,
|
||||
skewY: target.skewY,
|
||||
originX: origin.x,
|
||||
originY: origin.y
|
||||
};
|
||||
this._currentTransform.original.originX = origin.x;
|
||||
this._currentTransform.original.originY = origin.y;
|
||||
|
||||
this._resetCurrentTransform();
|
||||
this._beforeTransform(e);
|
||||
|
|
@ -10072,18 +10133,6 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
|
|||
this.upperCanvasEl.style.cursor = value;
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {fabric.Object} target to reset transform
|
||||
* @private
|
||||
*/
|
||||
_resetObjectTransform: function (target) {
|
||||
target.scaleX = 1;
|
||||
target.scaleY = 1;
|
||||
target.skewX = 0;
|
||||
target.skewY = 0;
|
||||
target.rotate(0);
|
||||
},
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {CanvasRenderingContext2D} ctx to draw the selection on
|
||||
|
|
@ -10572,10 +10621,12 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
|
|||
this.removeListeners();
|
||||
wrapper.removeChild(this.upperCanvasEl);
|
||||
wrapper.removeChild(this.lowerCanvasEl);
|
||||
this.upperCanvasEl = null;
|
||||
this.cacheCanvasEl = null;
|
||||
this.contextCache = null;
|
||||
this.contextTop = null;
|
||||
['upperCanvasEl', 'cacheCanvasEl'].forEach((function(element) {
|
||||
fabric.util.cleanUpJsdomNode(this[element]);
|
||||
this[element] = undefined;
|
||||
}).bind(this));
|
||||
if (wrapper.parentNode) {
|
||||
wrapper.parentNode.replaceChild(this.lowerCanvasEl, this.wrapperEl);
|
||||
}
|
||||
|
|
@ -12168,7 +12219,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
|
|||
* @param {Object} [callback] Receives cloned instance as a first argument
|
||||
*/
|
||||
cloneWithoutData: function(callback) {
|
||||
var el = fabric.document.createElement('canvas');
|
||||
var el = fabric.util.createCanvasElement();
|
||||
|
||||
el.width = this.width;
|
||||
el.height = this.height;
|
||||
|
|
@ -12783,6 +12834,9 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
|
|||
|
||||
/**
|
||||
* List of properties to consider when checking if cache needs refresh
|
||||
* Those properties are checked by statefullCache ON ( or lazy mode if we want ) or from single
|
||||
* calls to Object.set(key, value). If the key is in this list, the object is marked as dirty
|
||||
* and refreshed at the next render
|
||||
* @type Array
|
||||
*/
|
||||
cacheProperties: (
|
||||
|
|
@ -12806,7 +12860,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
|
|||
*/
|
||||
_createCacheCanvas: function() {
|
||||
this._cacheProperties = {};
|
||||
this._cacheCanvas = fabric.document.createElement('canvas');
|
||||
this._cacheCanvas = fabric.util.createCanvasElement();
|
||||
this._cacheContext = this._cacheCanvas.getContext('2d');
|
||||
this._updateCacheCanvas();
|
||||
// if canvas gets created, is empty, so dirty.
|
||||
|
|
@ -12870,12 +12924,10 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
|
|||
* @return {Object}.zoomY zoomY zoom value to unscale the canvas before drawing cache
|
||||
*/
|
||||
_getCacheCanvasDimensions: function() {
|
||||
var zoom = this.canvas && this.canvas.getZoom() || 1,
|
||||
objectScale = this.getObjectScaling(),
|
||||
retina = this.canvas && this.canvas._isRetinaScaling() ? fabric.devicePixelRatio : 1,
|
||||
var objectScale = this.getTotalObjectScaling(),
|
||||
dim = this._getNonTransformedDimensions(),
|
||||
zoomX = objectScale.scaleX * zoom * retina,
|
||||
zoomY = objectScale.scaleY * zoom * retina,
|
||||
zoomX = objectScale.scaleX,
|
||||
zoomY = objectScale.scaleY,
|
||||
width = dim.x * zoomX,
|
||||
height = dim.y * zoomY;
|
||||
return {
|
||||
|
|
@ -13082,6 +13134,21 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
|
|||
return { scaleX: scaleX, scaleY: scaleY };
|
||||
},
|
||||
|
||||
/**
|
||||
* Return the object scale factor counting also the group scaling, zoom and retina
|
||||
* @return {Object} object with scaleX and scaleY properties
|
||||
*/
|
||||
getTotalObjectScaling: function() {
|
||||
var scale = this.getObjectScaling(), scaleX = scale.scaleX, scaleY = scale.scaleY;
|
||||
if (this.canvas) {
|
||||
var zoom = this.canvas.getZoom();
|
||||
var retina = this.canvas.getRetinaScaling();
|
||||
scaleX *= zoom * retina;
|
||||
scaleY *= zoom * retina;
|
||||
}
|
||||
return { scaleX: scaleX, scaleY: scaleY };
|
||||
},
|
||||
|
||||
/**
|
||||
* Return the object opacity counting also the group property
|
||||
* @return {Number}
|
||||
|
|
@ -13627,17 +13694,24 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
|
|||
* @param {Number} [options.width] Cropping width. Introduced in v1.2.14
|
||||
* @param {Number} [options.height] Cropping height. Introduced in v1.2.14
|
||||
* @param {Boolean} [options.enableRetinaScaling] Enable retina scaling for clone image. Introduce in 1.6.4
|
||||
* @param {Boolean} [options.withoutTransform] Remove current object transform ( no scale , no angle, no flip, no skew ). Introduced in 2.3.4
|
||||
* @return {String} Returns a data: URL containing a representation of the object in the format specified by options.format
|
||||
*/
|
||||
toDataURL: function(options) {
|
||||
options || (options = { });
|
||||
|
||||
var origParams = fabric.util.saveObjectTransform(this);
|
||||
|
||||
if (options.withoutTransform) {
|
||||
fabric.util.resetObjectTransform(this);
|
||||
}
|
||||
|
||||
var el = fabric.util.createCanvasElement(),
|
||||
boundingRect = this.getBoundingRect();
|
||||
// skip canvas zoom and calculate with setCoords now.
|
||||
boundingRect = this.getBoundingRect(true, true);
|
||||
|
||||
el.width = boundingRect.width;
|
||||
el.height = boundingRect.height;
|
||||
fabric.util.wrapElement(el, 'div');
|
||||
var canvas = new fabric.StaticCanvas(el, {
|
||||
enableRetinaScaling: options.enableRetinaScaling,
|
||||
renderOnAddRemove: false,
|
||||
|
|
@ -13652,11 +13726,6 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
|
|||
canvas.backgroundColor = '#fff';
|
||||
}
|
||||
|
||||
var origParams = {
|
||||
left: this.left,
|
||||
top: this.top
|
||||
};
|
||||
|
||||
this.setPositionByOrigin(new fabric.Point(canvas.width / 2, canvas.height / 2), 'center', 'center');
|
||||
|
||||
var originalCanvas = this.canvas;
|
||||
|
|
@ -13780,20 +13849,18 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
|
|||
* @param {String} [options.repeat=repeat] Repeat property of a pattern (one of repeat, repeat-x, repeat-y or no-repeat)
|
||||
* @param {Number} [options.offsetX=0] Pattern horizontal offset from object's left/top corner
|
||||
* @param {Number} [options.offsetY=0] Pattern vertical offset from object's left/top corner
|
||||
* @param {Function} [callback] Callback to invoke when image set as a pattern
|
||||
* @return {fabric.Object} thisArg
|
||||
* @chainable
|
||||
* @see {@link http://jsfiddle.net/fabricjs/QT3pa/|jsFiddle demo}
|
||||
* @example <caption>Set pattern</caption>
|
||||
* fabric.util.loadImage('http://fabricjs.com/assets/escheresque_ste.png', function(img) {
|
||||
* object.setPatternFill({
|
||||
* source: img,
|
||||
* repeat: 'repeat'
|
||||
* });
|
||||
* canvas.renderAll();
|
||||
* });
|
||||
* object.setPatternFill({
|
||||
* source: 'http://fabricjs.com/assets/escheresque_ste.png',
|
||||
* repeat: 'repeat'
|
||||
* },canvas.renderAll.bind(canvas));
|
||||
*/
|
||||
setPatternFill: function(options) {
|
||||
return this.set('fill', new fabric.Pattern(options));
|
||||
setPatternFill: function(options, callback) {
|
||||
return this.set('fill', new fabric.Pattern(options, callback));
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
@ -14706,8 +14773,8 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
|
|||
},
|
||||
|
||||
/**
|
||||
* Sets corner position coordinates based on current angle, width and height
|
||||
* See https://github.com/kangax/fabric.js/wiki/When-to-call-setCoords
|
||||
* Sets corner position coordinates based on current angle, width and height.
|
||||
* See {@link https://github.com/kangax/fabric.js/wiki/When-to-call-setCoords|When-to-call-setCoords}
|
||||
* @param {Boolean} [ignoreZoom] set oCoords with or without the viewport transform.
|
||||
* @param {Boolean} [skipAbsolute] skip calculation of aCoords, usefull in setViewportTransform
|
||||
* @return {fabric.Object} thisArg
|
||||
|
|
@ -16400,7 +16467,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot
|
|||
'" transform="', this.getSvgTransform(),
|
||||
' ', this.getSvgTransformMatrix(), '"',
|
||||
this.addPaintOrder(),
|
||||
'"/>\n'
|
||||
'/>\n'
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -18371,13 +18438,6 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot
|
|||
this._objects[i].group = this;
|
||||
}
|
||||
|
||||
if (options.originX) {
|
||||
this.originX = options.originX;
|
||||
}
|
||||
if (options.originY) {
|
||||
this.originY = options.originY;
|
||||
}
|
||||
|
||||
if (!isAlreadyGrouped) {
|
||||
var center = options && options.centerPoint;
|
||||
// if coming from svg i do not want to calc bounds.
|
||||
|
|
@ -18783,7 +18843,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot
|
|||
}
|
||||
}
|
||||
|
||||
this.set(this._getBounds(aX, aY, onlyWidthHeight));
|
||||
this._getBounds(aX, aY, onlyWidthHeight);
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
@ -18792,28 +18852,14 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot
|
|||
_getBounds: function(aX, aY, onlyWidthHeight) {
|
||||
var minXY = new fabric.Point(min(aX), min(aY)),
|
||||
maxXY = new fabric.Point(max(aX), max(aY)),
|
||||
obj = {
|
||||
width: (maxXY.x - minXY.x) || 0,
|
||||
height: (maxXY.y - minXY.y) || 0
|
||||
};
|
||||
|
||||
top = minXY.y || 0, left = minXY.x || 0,
|
||||
width = (maxXY.x - minXY.x) || 0,
|
||||
height = (maxXY.y - minXY.y) || 0;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
if (!onlyWidthHeight) {
|
||||
obj.left = minXY.x || 0;
|
||||
obj.top = minXY.y || 0;
|
||||
if (this.originX === 'center') {
|
||||
obj.left += obj.width / 2;
|
||||
}
|
||||
if (this.originX === 'right') {
|
||||
obj.left += obj.width;
|
||||
}
|
||||
if (this.originY === 'center') {
|
||||
obj.top += obj.height / 2;
|
||||
}
|
||||
if (this.originY === 'bottom') {
|
||||
obj.top += obj.height;
|
||||
}
|
||||
this.setPositionByOrigin({ x: left, y: top }, 'left', 'top');
|
||||
}
|
||||
return obj;
|
||||
},
|
||||
|
||||
/* _TO_SVG_START_ */
|
||||
|
|
@ -19244,9 +19290,11 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot
|
|||
backend.evictCachesForKey(this.cacheKey);
|
||||
backend.evictCachesForKey(this.cacheKey + '_filtered');
|
||||
}
|
||||
this._originalElement = undefined;
|
||||
this._element = undefined;
|
||||
this._filteredEl = undefined;
|
||||
this._cacheContext = undefined;
|
||||
['_originalElement', '_element', '_filteredEl', '_cacheCanvas'].forEach((function(element) {
|
||||
fabric.util.cleanUpJsdomNode(this[element]);
|
||||
this[element] = undefined;
|
||||
}).bind(this));
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
@ -19445,10 +19493,10 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot
|
|||
|
||||
applyResizeFilters: function() {
|
||||
var filter = this.resizeFilter,
|
||||
retinaScaling = this.canvas ? this.canvas.getRetinaScaling() : 1,
|
||||
minimumScale = this.minimumScaleTrigger,
|
||||
scaleX = this.scaleX * retinaScaling,
|
||||
scaleY = this.scaleY * retinaScaling,
|
||||
objectScale = this.getTotalObjectScaling(),
|
||||
scaleX = objectScale.scaleX,
|
||||
scaleY = objectScale.scaleY,
|
||||
elementToFilter = this._filteredEl || this._originalElement;
|
||||
if (this.group) {
|
||||
this.set('dirty', true);
|
||||
|
|
@ -19457,6 +19505,8 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot
|
|||
this._element = elementToFilter;
|
||||
this._filterScalingX = 1;
|
||||
this._filterScalingY = 1;
|
||||
this._lastScaleX = scaleX;
|
||||
this._lastScaleY = scaleY;
|
||||
return;
|
||||
}
|
||||
if (!fabric.filterBackend) {
|
||||
|
|
@ -19468,8 +19518,8 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot
|
|||
canvasEl.width = sourceWidth;
|
||||
canvasEl.height = sourceHeight;
|
||||
this._element = canvasEl;
|
||||
filter.scaleX = scaleX;
|
||||
filter.scaleY = scaleY;
|
||||
this._lastScaleX = filter.scaleX = scaleX;
|
||||
this._lastScaleY = filter.scaleY = scaleY;
|
||||
fabric.filterBackend.applyFilters(
|
||||
[filter], elementToFilter, sourceWidth, sourceHeight, this._element, cacheKey);
|
||||
this._filterScalingX = canvasEl.width / this._originalElement.width;
|
||||
|
|
@ -19487,7 +19537,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot
|
|||
applyFilters: function(filters) {
|
||||
|
||||
filters = filters || this.filters || [];
|
||||
filters = filters.filter(function(filter) { return filter; });
|
||||
filters = filters.filter(function(filter) { return filter && !filter.isNeutralState(); });
|
||||
if (this.group) {
|
||||
this.set('dirty', true);
|
||||
}
|
||||
|
|
@ -19533,9 +19583,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot
|
|||
* @param {CanvasRenderingContext2D} ctx Context to render on
|
||||
*/
|
||||
_render: function(ctx) {
|
||||
if (this.isMoving === false && this.resizeFilter && this._needsResize()) {
|
||||
this._lastScaleX = this.scaleX;
|
||||
this._lastScaleY = this.scaleY;
|
||||
if (this.isMoving !== true && this.resizeFilter && this._needsResize()) {
|
||||
this.applyResizeFilters();
|
||||
}
|
||||
this._stroke(ctx);
|
||||
|
|
@ -19557,7 +19605,8 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot
|
|||
* @private, needed to check if image needs resize
|
||||
*/
|
||||
_needsResize: function() {
|
||||
return (this.scaleX !== this._lastScaleX || this.scaleY !== this._lastScaleY);
|
||||
var scale = this.getTotalObjectScaling();
|
||||
return (scale.scaleX !== this._lastScaleX || scale.scaleY !== this._lastScaleY);
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
@ -20555,11 +20604,31 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag
|
|||
},
|
||||
|
||||
/**
|
||||
* Intentionally left blank, to be overridden in custom filters
|
||||
* Generic isNeutral implementation for one parameter based filters.
|
||||
* Used only in image applyFilters to discard filters that will not have an effect
|
||||
* on the image
|
||||
* Other filters may need their own verison ( ColorMatrix, HueRotation, gamma, ComposedFilter )
|
||||
* @param {Object} options
|
||||
**/
|
||||
isNeutralState: function(/* options */) {
|
||||
return false;
|
||||
var main = this.mainParameter,
|
||||
_class = fabric.Image.filters[this.type].prototype;
|
||||
if (main) {
|
||||
if (Array.isArray(_class[main])) {
|
||||
for (var i = _class[main].length; i--;) {
|
||||
if (this[main][i] !== _class[main][i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return _class[main] === this[main];
|
||||
}
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
@ -20577,15 +20646,11 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag
|
|||
*/
|
||||
applyTo: function(options) {
|
||||
if (options.webgl) {
|
||||
if (options.passes > 1 && this.isNeutralState(options)) {
|
||||
// avoid doing something that we do not need
|
||||
return;
|
||||
}
|
||||
this._setupFrameBuffer(options);
|
||||
this.applyToWebGL(options);
|
||||
this._swapTextures(options);
|
||||
}
|
||||
else if (!this.isNeutralState()) {
|
||||
else {
|
||||
this.applyTo2d(options);
|
||||
}
|
||||
},
|
||||
|
|
@ -20793,20 +20858,6 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) {
|
|||
this.matrix = this.matrix.slice(0);
|
||||
},
|
||||
|
||||
/**
|
||||
* Intentionally left blank, to be overridden in custom filters
|
||||
* @param {Object} options
|
||||
**/
|
||||
isNeutralState: function(/* options */) {
|
||||
var _class = filters.ColorMatrix;
|
||||
for (var i = 20; i--;) {
|
||||
if (this.matrix[i] !== _class.prototype.matrix[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Apply the ColorMatrix operation to a Uint8Array representing the pixels of an image.
|
||||
*
|
||||
|
|
@ -21485,6 +21536,15 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) {
|
|||
var mode = 1;
|
||||
gl.uniform1i(uniformLocations.uMode, mode);
|
||||
},
|
||||
|
||||
/**
|
||||
* Grayscale filter isNeutralState implementation
|
||||
* The filter is never neutral
|
||||
* on the image
|
||||
**/
|
||||
isNeutralState: function() {
|
||||
return false;
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
|
|
@ -21556,9 +21616,6 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) {
|
|||
* @param {ImageData} options.imageData The Uint8Array to be filtered.
|
||||
*/
|
||||
applyTo2d: function(options) {
|
||||
if (!this.invert) {
|
||||
return;
|
||||
}
|
||||
var imageData = options.imageData,
|
||||
data = imageData.data, i,
|
||||
len = data.length;
|
||||
|
|
@ -21569,6 +21626,16 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) {
|
|||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Invert filter isNeutralState implementation
|
||||
* Used only in image applyFilters to discard filters that will not have an effect
|
||||
* on the image
|
||||
* @param {Object} options
|
||||
**/
|
||||
isNeutralState: function() {
|
||||
return !this.invert;
|
||||
},
|
||||
|
||||
/**
|
||||
* Return WebGL uniform locations for this filter's shader.
|
||||
*
|
||||
|
|
@ -21804,9 +21871,6 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) {
|
|||
* @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.
|
||||
*/
|
||||
applyTo2d: function(options) {
|
||||
if (this.blocksize === 1) {
|
||||
return;
|
||||
}
|
||||
var imageData = options.imageData,
|
||||
data = imageData.data,
|
||||
iLen = imageData.height,
|
||||
|
|
@ -22436,7 +22500,8 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) {
|
|||
mode: 'multiply',
|
||||
|
||||
/**
|
||||
* alpha value. represent the strength of the blend color operation.
|
||||
* alpha value. represent the strength of the blend image operation.
|
||||
* not implemented.
|
||||
**/
|
||||
alpha: 1,
|
||||
|
||||
|
|
@ -22535,21 +22600,24 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) {
|
|||
var imageData = options.imageData,
|
||||
resources = options.filterBackend.resources,
|
||||
data = imageData.data, iLen = data.length,
|
||||
width = options.imageData.width,
|
||||
height = options.imageData.height,
|
||||
width = imageData.width,
|
||||
height = imageData.height,
|
||||
tr, tg, tb, ta,
|
||||
r, g, b, a,
|
||||
canvas1, context, image = this.image, blendData;
|
||||
|
||||
if (!resources.blendImage) {
|
||||
resources.blendImage = document.createElement('canvas');
|
||||
resources.blendImage = fabric.util.createCanvasElement();
|
||||
}
|
||||
canvas1 = resources.blendImage;
|
||||
context = canvas1.getContext('2d');
|
||||
if (canvas1.width !== width || canvas1.height !== height) {
|
||||
canvas1.width = width;
|
||||
canvas1.height = height;
|
||||
}
|
||||
context = canvas1.getContext('2d');
|
||||
else {
|
||||
context.clearRect(0, 0, width, height);
|
||||
}
|
||||
context.setTransform(image.scaleX, 0, 0, image.scaleY, image.left, image.top);
|
||||
context.drawImage(image._element, 0, 0, width, height);
|
||||
blendData = context.getImageData(0, 0, width, height).data;
|
||||
|
|
@ -22668,6 +22736,8 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) {
|
|||
|
||||
/**
|
||||
* Resize type
|
||||
* for webgl resizyType is just lanczos, for canvas2d can be:
|
||||
* bilinear, hermite, sliceHacl, lanczos.
|
||||
* @param {String} resizeType
|
||||
* @default
|
||||
*/
|
||||
|
|
@ -22678,17 +22748,17 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) {
|
|||
* @param {Number} scaleX
|
||||
* @default
|
||||
*/
|
||||
scaleX: 0,
|
||||
scaleX: 1,
|
||||
|
||||
/**
|
||||
* Scale factor for resizing, y axis
|
||||
* @param {Number} scaleY
|
||||
* @default
|
||||
*/
|
||||
scaleY: 0,
|
||||
scaleY: 1,
|
||||
|
||||
/**
|
||||
* LanczosLobes parameter for lanczos filter
|
||||
* LanczosLobes parameter for lanczos filter, valid for resizeType lanczos
|
||||
* @param {Number} lanczosLobes
|
||||
* @default
|
||||
*/
|
||||
|
|
@ -22794,10 +22864,6 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) {
|
|||
*/
|
||||
applyTo: function(options) {
|
||||
if (options.webgl) {
|
||||
if (options.passes > 1 && this.isNeutralState(options)) {
|
||||
// avoid doing something that we do not need
|
||||
return;
|
||||
}
|
||||
options.passes++;
|
||||
this.width = options.sourceWidth;
|
||||
this.horizontal = true;
|
||||
|
|
@ -22822,15 +22888,13 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) {
|
|||
this._swapTextures(options);
|
||||
options.sourceHeight = options.destinationHeight;
|
||||
}
|
||||
else if (!this.isNeutralState(options)) {
|
||||
else {
|
||||
this.applyTo2d(options);
|
||||
}
|
||||
},
|
||||
|
||||
isNeutralState: function(options) {
|
||||
var scaleX = options.scaleX || this.scaleX,
|
||||
scaleY = options.scaleY || this.scaleY;
|
||||
return scaleX === 1 && scaleY === 1;
|
||||
isNeutralState: function() {
|
||||
return this.scaleX === 1 && this.scaleY === 1;
|
||||
},
|
||||
|
||||
lanczosCreate: function(lobes) {
|
||||
|
|
@ -23631,6 +23695,15 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) {
|
|||
*/
|
||||
mainParameter: 'gamma',
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param {Object} [options] Options object
|
||||
*/
|
||||
initialize: function(options) {
|
||||
this.gamma = [1, 1, 1];
|
||||
filters.BaseFilter.prototype.initialize.call(this, options);
|
||||
},
|
||||
|
||||
/**
|
||||
* Apply the Gamma operation to a Uint8Array representing the pixels of an image.
|
||||
*
|
||||
|
|
@ -23754,6 +23827,10 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) {
|
|||
subFilters: this.subFilters.map(function(filter) { return filter.toObject(); }),
|
||||
});
|
||||
},
|
||||
|
||||
isNeutralState: function() {
|
||||
return !this.subFilters.some(function(filter) { return !filter.isNeutralState(); });
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
|
|
@ -23837,6 +23914,17 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) {
|
|||
this.matrix[12] = cos + aThird * OneMinusCos;
|
||||
},
|
||||
|
||||
/**
|
||||
* HueRotation isNeutralState implementation
|
||||
* Used only in image applyFilters to discard filters that will not have an effect
|
||||
* on the image
|
||||
* @param {Object} options
|
||||
**/
|
||||
isNeutralState: function(options) {
|
||||
this.calculateMatrix();
|
||||
return filters.BaseFilter.prototype.isNeutralState.call(this, options);
|
||||
},
|
||||
|
||||
/**
|
||||
* Apply this filter to the input image data provided.
|
||||
*
|
||||
|
|
@ -23852,7 +23940,7 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) {
|
|||
*/
|
||||
applyTo: function(options) {
|
||||
this.calculateMatrix();
|
||||
fabric.Image.filters.BaseFilter.prototype.applyTo.call(this, options);
|
||||
filters.BaseFilter.prototype.applyTo.call(this, options);
|
||||
},
|
||||
|
||||
});
|
||||
|
|
@ -23964,21 +24052,21 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) {
|
|||
|
||||
/**
|
||||
* Text decoration underline.
|
||||
* @type String
|
||||
* @type Boolean
|
||||
* @default
|
||||
*/
|
||||
underline: false,
|
||||
|
||||
/**
|
||||
* Text decoration overline.
|
||||
* @type String
|
||||
* @type Boolean
|
||||
* @default
|
||||
*/
|
||||
overline: false,
|
||||
|
||||
/**
|
||||
* Text decoration linethrough.
|
||||
* @type String
|
||||
* @type Boolean
|
||||
* @default
|
||||
*/
|
||||
linethrough: false,
|
||||
|
|
@ -27320,9 +27408,11 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot
|
|||
this.hiddenTextarea.setAttribute('data-fabric-hiddentextarea', '');
|
||||
this.hiddenTextarea.setAttribute('wrap', 'off');
|
||||
var style = this._calcTextareaPosition();
|
||||
// line-height: 1px; was removed from the style to fix this:
|
||||
// https://bugs.chromium.org/p/chromium/issues/detail?id=870966
|
||||
this.hiddenTextarea.style.cssText = 'position: absolute; top: ' + style.top +
|
||||
'; left: ' + style.left + '; z-index: -999; opacity: 0; width: 1px; height: 1px; font-size: 1px;' +
|
||||
' line-height: 1px; paddingーtop: ' + style.fontSize + ';';
|
||||
' paddingーtop: ' + style.fontSize + ';';
|
||||
fabric.document.body.appendChild(this.hiddenTextarea);
|
||||
|
||||
fabric.util.addListener(this.hiddenTextarea, 'keydown', this.onKeyDown.bind(this));
|
||||
|
|
|
|||
2
dist/fabric.min.js
vendored
2
dist/fabric.min.js
vendored
File diff suppressed because one or more lines are too long
|
|
@ -2,7 +2,7 @@
|
|||
"name": "fabric",
|
||||
"description": "Object model for HTML5 canvas, and SVG-to-canvas parser. Backed by jsdom and node-canvas.",
|
||||
"homepage": "http://fabricjs.com/",
|
||||
"version": "2.3.3",
|
||||
"version": "2.3.4",
|
||||
"author": "Juriy Zaytsev <kangax@gmail.com>",
|
||||
"contributors": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -874,12 +874,12 @@
|
|||
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 2.3.3</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 ' + 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 svg1 = canvas.toSVG();
|
||||
assert.equal(svg1, expectedSVG, 'svg with bg and overlay do not match');
|
||||
imageBG.excludeFromExport = true;
|
||||
imageOL.excludeFromExport = true;
|
||||
var expectedSVG2 = '<?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.3.3</desc>\n<defs>\n</defs>\n</svg>';
|
||||
var expectedSVG2 = '<?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</svg>';
|
||||
var svg2 = canvas.toSVG();
|
||||
assert.equal(svg2, expectedSVG2, 'svg without bg and overlay do not match');
|
||||
canvas.backgroundImage = null;
|
||||
|
|
|
|||
Loading…
Reference in a new issue