diff --git a/CHANGELOG.md b/CHANGELOG.md
index 63c044e8813..156bea65e22 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,15 @@
# Changelog
+## [2.4.1]
+- Fix: Avoid enterEditing if another object is the activeObject [#5261](https://github.com/fabricjs/fabric.js/pull/5261)
+- Fix: clipPath enliving for Image fromObject [#5279](https://github.com/fabricjs/fabric.js/pull/5279)
+- Fix: toDataURL and canvas clipPath [#5278](https://github.com/fabricjs/fabric.js/pull/5278)
+- Fix: early return if no xml is available [#5263](https://github.com/fabricjs/fabric.js/pull/5263)
+- Fix: clipPath svg parsing in nodejs [#5262](https://github.com/fabricjs/fabric.js/pull/5262)
+- Fix: Avoid running selection logic on mouse up [#5259](https://github.com/fabricjs/fabric.js/pull/5259)
+- Fix: fix font size parsing on SVG [#5258](https://github.com/fabricjs/fabric.js/pull/5258)
+- Fix: Avoid extra renders on mouseUp/Down [#5256](https://github.com/fabricjs/fabric.js/pull/5256)
+
## [2.4.0]
- Add: Add clipPath support to canvas and svg import/export. Low compatibility yet.
diff --git a/HEADER.js b/HEADER.js
index f81030b38bd..1b2fe70f8a2 100644
--- a/HEADER.js
+++ b/HEADER.js
@@ -1,6 +1,6 @@
/*! Fabric.js Copyright 2008-2015, Printio (Juriy Zaytsev, Maxim Chernyak) */
-var fabric = fabric || { version: '2.4.0' };
+var fabric = fabric || { version: '2.4.1' };
if (typeof exports !== 'undefined') {
exports.fabric = fabric;
}
diff --git a/dist/fabric.js b/dist/fabric.js
index 9c014815e5f..f0923458154 100644
--- a/dist/fabric.js
+++ b/dist/fabric.js
@@ -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.4.0' };
+var fabric = fabric || { version: '2.4.1' };
if (typeof exports !== 'undefined') {
exports.fabric = fabric;
}
@@ -4056,7 +4056,8 @@ if (typeof console !== 'undefined') {
descendants.filter(function(el) {
return el.nodeName.replace('svg:', '') === 'clipPath';
}).forEach(function(el) {
- clipPaths[el.id] = fabric.util.toArray(el.getElementsByTagName('*')).filter(function(el) {
+ var id = el.getAttribute('id');
+ clipPaths[id] = fabric.util.toArray(el.getElementsByTagName('*')).filter(function(el) {
return fabric.svgValidTagNamesRegEx.test(el.nodeName.replace('svg:', ''));
});
});
@@ -4185,8 +4186,6 @@ if (typeof console !== 'undefined') {
if (element.parentNode && fabric.svgValidParentsRegEx.test(element.parentNode.nodeName)) {
parentAttributes = fabric.parseAttributes(element.parentNode, attributes, svgUid);
}
- fontSize = (parentAttributes && parentAttributes.fontSize ) ||
- element.getAttribute('font-size') || fabric.Text.DEFAULT_SVG_FONT_SIZE;
var ownAttributes = attributes.reduce(function(memo, attr) {
value = element.getAttribute(attr);
@@ -4200,6 +4199,9 @@ if (typeof console !== 'undefined') {
ownAttributes = extend(ownAttributes,
extend(getGlobalStylesForElement(element, svgUid), fabric.parseStyleAttribute(element)));
+ fontSize = (parentAttributes && parentAttributes.fontSize ) ||
+ ownAttributes['font-size'] || fabric.Text.DEFAULT_SVG_FONT_SIZE;
+
var normalizedAttr, normalizedValue, normalizedStyle = {};
for (var attr in ownAttributes) {
normalizedAttr = normalizeAttr(attr);
@@ -4370,6 +4372,7 @@ if (typeof console !== 'undefined') {
}
if (!xml || !xml.documentElement) {
callback && callback(null);
+ return false;
}
fabric.parseSVGDocument(xml.documentElement, function (results, _options, elements, allElements) {
@@ -7469,13 +7472,11 @@ fabric.ElementsParser = function(elements, callback, options, reviver, parsingOp
ctx.restore();
}
if (path) {
- if (path.isCacheDirty()) {
- // needed to setup a couple of variables
- path.shouldCache();
- path.canvas = this;
- path._transformDone = true;
- path.renderCache({ forClipping: true });
- }
+ path.canvas = this;
+ // needed to setup a couple of variables
+ path.shouldCache();
+ path._transformDone = true;
+ path.renderCache({ forClipping: true });
this.drawClipPathOnCanvas(ctx);
}
this._renderOverlay(ctx);
@@ -7494,7 +7495,7 @@ fabric.ElementsParser = function(elements, callback, options, reviver, parsingOp
ctx.save();
ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]);
// DEBUG: uncomment this line, comment the following
- // ctx.globalAlpha = 0.4
+ // ctx.globalAlpha = 0.4;
ctx.globalCompositeOperation = 'destination-in';
path.transform(ctx);
ctx.scale(1 / path.zoomX, 1 / path.zoomY);
@@ -9578,10 +9579,12 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
renderTopLayer: function(ctx) {
if (this.isDrawingMode && this._isCurrentlyDrawing) {
this.freeDrawingBrush && this.freeDrawingBrush._render();
+ this.contextTopDirty = true;
}
// we render the top context - last object
if (this.selection && this._groupSelector) {
this._drawSelection(ctx);
+ this.contextTopDirty = true;
}
},
@@ -9596,7 +9599,6 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
this.clearContext(ctx);
this.renderTopLayer(ctx);
this.fire('after:render');
- this.contextTopDirty = true;
return this;
},
@@ -11176,31 +11178,24 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
* Decides whether the canvas should be redrawn in mouseup and mousedown events.
* @private
* @param {Object} target
- * @param {Object} pointer
*/
- _shouldRender: function(target, pointer) {
+ _shouldRender: function(target) {
var activeObject = this._activeObject;
- if (activeObject && activeObject.isEditing && target === activeObject) {
+ if (
+ !!activeObject !== !!target ||
+ (activeObject && target && (activeObject !== target))
+ ) {
+ // this covers: switch of target, from target to no target, selection of target
+ // multiSelection with key and mouse
+ return true;
+ }
+ else if (activeObject && activeObject.isEditing) {
// if we mouse up/down over a editing textbox a cursor change,
// there is no need to re render
return false;
}
- return !!(
- (target && (
- target.isMoving ||
- target !== activeObject))
- ||
- (!target && !!activeObject)
- ||
- (!target && !activeObject && !this._groupSelector)
- ||
- (pointer &&
- this._previousPointer &&
- this.selection && (
- pointer.x !== this._previousPointer.x ||
- pointer.y !== this._previousPointer.y))
- );
+ return false;
},
/**
@@ -11212,7 +11207,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
*/
__onMouseUp: function (e) {
var target, transform = this._currentTransform,
- groupSelector = this._groupSelector,
+ groupSelector = this._groupSelector, shouldRender = false,
isClick = (!groupSelector || (groupSelector.left === 0 && groupSelector.top === 0));
this._cacheTransformEventData(e);
target = this._target;
@@ -11241,12 +11236,12 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
if (transform) {
this._finalizeCurrentTransform(e);
+ shouldRender = transform.actionPerformed;
}
- var shouldRender = this._shouldRender(target, this._absolutePointer);
-
- if (target || !isClick) {
+ if (!isClick) {
this._maybeGroupObjects(e);
+ shouldRender || (shouldRender = this._shouldRender(target));
}
if (target) {
target.isMoving = false;
@@ -11255,8 +11250,14 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
this._handleEvent(e, 'up', LEFT_CLICK, isClick);
this._groupSelector = null;
this._currentTransform = null;
+ // reset the target information about which corner is selected
target && (target.__corner = 0);
- shouldRender && this.requestRenderAll();
+ if (shouldRender) {
+ this.requestRenderAll();
+ }
+ else if (!isClick) {
+ this.renderTop();
+ }
},
/**
@@ -11469,7 +11470,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
var pointer = this._pointer;
// save pointer for check in __onMouseUp event
this._previousPointer = pointer;
- var shouldRender = this._shouldRender(target, pointer),
+ var shouldRender = this._shouldRender(target),
shouldGroup = this._shouldGroup(e, target);
if (this._shouldClearSelection(e, target)) {
this.discardActiveObject(e);
@@ -11499,7 +11500,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
}
this._handleEvent(e, 'down');
// we must renderAll so that we update the visuals
- shouldRender && this.requestRenderAll();
+ (shouldRender || shouldGroup) && this.requestRenderAll();
},
/**
@@ -13454,7 +13455,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
if (!this._cacheCanvas) {
this._createCacheCanvas();
}
- if (this.isCacheDirty(false)) {
+ if (this.isCacheDirty()) {
this.statefullCache && this.saveState({ propertySet: 'cacheProperties' });
this.drawObject(this._cacheContext, options.forClipping);
this.dirty = false;
@@ -18840,9 +18841,10 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot
* @return {Object} object representation of an instance
*/
toObject: function(propertiesToInclude) {
+ var _includeDefaultValues = this.includeDefaultValues;
var objsToObject = this._objects.map(function(obj) {
var originalDefaults = obj.includeDefaultValues;
- obj.includeDefaultValues = obj.group.includeDefaultValues;
+ obj.includeDefaultValues = _includeDefaultValues;
var _obj = obj.toObject(propertiesToInclude);
obj.includeDefaultValues = originalDefaults;
return _obj;
@@ -18863,9 +18865,10 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot
objsToObject = sourcePath;
}
else {
+ var _includeDefaultValues = this.includeDefaultValues;
objsToObject = this._objects.map(function(obj) {
var originalDefaults = obj.includeDefaultValues;
- obj.includeDefaultValues = obj.group.includeDefaultValues;
+ obj.includeDefaultValues = _includeDefaultValues;
var _obj = obj.toDatalessObject(propertiesToInclude);
obj.includeDefaultValues = originalDefaults;
return _obj;
@@ -19993,8 +19996,11 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot
object.filters = filters || [];
fabric.Image.prototype._initFilters.call(object, [object.resizeFilter], function(resizeFilters) {
object.resizeFilter = resizeFilters[0];
- var image = new fabric.Image(img, object);
- callback(image);
+ fabric.util.enlivenObjects([object.clipPath], function(enlivedProps) {
+ object.clipPath = enlivedProps[0];
+ var image = new fabric.Image(img, object);
+ callback(image);
+ });
});
});
}, null, object.crossOrigin);
@@ -27513,6 +27519,16 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot
return;
}
+ if (this.canvas) {
+ var currentActive = this.canvas._activeObject;
+ if (currentActive && currentActive !== this) {
+ // avoid running this logic when there is an active object
+ // this because is possible with shift click and fast clicks,
+ // to rapidly deselect and reselect this object and trigger an enterEdit
+ return;
+ }
+ }
+
if (this.__lastSelected && !this.__corner) {
this.selected = false;
this.__lastSelected = false;
diff --git a/dist/fabric.min.js b/dist/fabric.min.js
index 260d1497edb..dbc6f97dacf 100644
--- a/dist/fabric.min.js
+++ b/dist/fabric.min.js
@@ -1 +1 @@
-var fabric=fabric||{version:"2.4.0"};function resizeCanvasIfNeeded(t){var e=t.targetCanvas,i=e.width,r=e.height,n=t.destinationWidth,s=t.destinationHeight;i===n&&r===s||(e.width=n,e.height=s)}function copyGLTo2DDrawImage(t,e){var i=t.canvas,r=e.targetCanvas,n=r.getContext("2d");n.translate(0,r.height),n.scale(1,-1);var s=i.height-r.height;n.drawImage(i,0,s,r.width,r.height,0,0,r.width,r.height)}function copyGLTo2DPutImageData(t,e){var i=e.targetCanvas.getContext("2d"),r=e.destinationWidth,n=e.destinationHeight,s=r*n*4,o=new Uint8Array(this.imageBuffer,0,s),a=new Uint8ClampedArray(this.imageBuffer,0,s);t.readPixels(0,0,r,n,t.RGBA,t.UNSIGNED_BYTE,o);var h=new ImageData(a,r,n);i.putImageData(h,0,0)}"undefined"!=typeof exports?exports.fabric=fabric:"function"==typeof define&&define.amd&&define([],function(){return fabric}),"undefined"!=typeof document&&"undefined"!=typeof window?(fabric.document=document,fabric.window=window):(fabric.document=require("jsdom").jsdom(decodeURIComponent("%3C!DOCTYPE%20html%3E%3Chtml%3E%3Chead%3E%3C%2Fhead%3E%3Cbody%3E%3C%2Fbody%3E%3C%2Fhtml%3E"),{features:{FetchExternalResources:["img"]}}),fabric.jsdomImplForWrapper=require("jsdom/lib/jsdom/living/generated/utils").implForWrapper,fabric.nodeCanvas=require("jsdom/lib/jsdom/utils").Canvas,fabric.window=fabric.document.defaultView,DOMParser=require("xmldom").DOMParser),fabric.isTouchSupported="ontouchstart"in fabric.window,fabric.isLikelyNode="undefined"!=typeof Buffer&&"undefined"==typeof window,fabric.SHARED_ATTRIBUTES=["display","transform","fill","fill-opacity","fill-rule","opacity","stroke","stroke-dasharray","stroke-linecap","stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke-width","id","paint-order","instantiated_by_use","clip-path"],fabric.DPI=96,fabric.reNum="(?:[-+]?(?:\\d+|\\d*\\.\\d+)(?:e[-+]?\\d+)?)",fabric.fontPaths={},fabric.iMatrix=[1,0,0,1,0,0],fabric.canvasModule="canvas",fabric.perfLimitSizeTotal=2097152,fabric.maxCacheSideLimit=4096,fabric.minCacheSideLimit=256,fabric.charWidthsCache={},fabric.textureSize=2048,fabric.enableGLFiltering=!0,fabric.devicePixelRatio=fabric.window.devicePixelRatio||fabric.window.webkitDevicePixelRatio||fabric.window.mozDevicePixelRatio||1,fabric.browserShadowBlurConstant=1,fabric.arcToSegmentsCache={},fabric.boundsOfCurveCache={},fabric.cachesBoundsOfCurve=!0,fabric.initFilterBackend=function(){return fabric.enableGLFiltering&&fabric.isWebglSupported&&fabric.isWebglSupported(fabric.textureSize)?(console.log("max texture size: "+fabric.maxTextureSize),new fabric.WebglFilterBackend({tileSize:fabric.textureSize})):fabric.Canvas2dFilterBackend?new fabric.Canvas2dFilterBackend:void 0},"undefined"!=typeof document&&"undefined"!=typeof window&&(window.fabric=fabric),function(){function r(t,e){if(this.__eventListeners[t]){var i=this.__eventListeners[t];e?i[i.indexOf(e)]=!1:fabric.util.array.fill(i,!1)}}function t(t,e){if(this.__eventListeners||(this.__eventListeners={}),1===arguments.length)for(var i in t)this.on(i,t[i]);else this.__eventListeners[t]||(this.__eventListeners[t]=[]),this.__eventListeners[t].push(e);return this}function e(t,e){if(this.__eventListeners){if(0===arguments.length)for(t in this.__eventListeners)r.call(this,t);else if(1===arguments.length&&"object"==typeof t)for(var i in t)r.call(this,i,t[i]);else r.call(this,t,e);return this}}function i(t,e){if(this.__eventListeners){var i=this.__eventListeners[t];if(i){for(var r=0,n=i.length;r/g,">")},graphemeSplit:function(t){var e,i=0,r=[];for(i=0;i/i,"")));e&&e.documentElement||n&&n(null);C.parseSVGDocument(e.documentElement,function(t,e,i,r){n&&n(t,e,i,r)},i,r)}})},loadSVGFromString:function(t,n,e,i){var r;if(t=t.trim(),"undefined"!=typeof DOMParser){var s=new DOMParser;s&&s.parseFromString&&(r=s.parseFromString(t,"text/xml"))}else C.window.ActiveXObject&&((r=new ActiveXObject("Microsoft.XMLDOM")).async="false",r.loadXML(t.replace(//i,"")));C.parseSVGDocument(r.documentElement,function(t,e,i,r){n(t,e,i,r)},e,i)}})}("undefined"!=typeof exports?exports:this),fabric.ElementsParser=function(t,e,i,r,n){this.elements=t,this.callback=e,this.options=i,this.reviver=r,this.svgUid=i&&i.svgUid||0,this.parsingOptions=n,this.regexUrl=/^url\(['"]?#([^'"]+)['"]?\)/g},function(t){t.parse=function(){this.instances=new Array(this.elements.length),this.numElements=this.elements.length,this.createObjects()},t.createObjects=function(){var i=this;this.elements.forEach(function(t,e){t.setAttribute("svgUid",i.svgUid),i.createObject(t,e)})},t.findTag=function(t){return fabric[fabric.util.string.capitalize(t.tagName.replace("svg:",""))]},t.createObject=function(t,e){var i=this.findTag(t);if(i&&i.fromElement)try{i.fromElement(t,this.createCallback(e,t),this.options)}catch(t){fabric.log(t)}else this.checkIfDone()},t.createCallback=function(i,r){var n=this;return function(t){var e;n.resolveGradient(t,"fill"),n.resolveGradient(t,"stroke"),t instanceof fabric.Image&&(e=t.parsePreserveAspectRatioAttribute(r)),t._removeTransformMatrix(e),n.resolveClipPath(t),n.reviver&&n.reviver(r,t),n.instances[i]=t,n.checkIfDone()}},t.extractPropertyDefinition=function(t,e,i){var r=t[e];if(/^url\(/.test(r)){var n=this.regexUrl.exec(r)[1];return this.regexUrl.lastIndex=0,fabric[i][this.svgUid][n]}},t.resolveGradient=function(t,e){var i=this.extractPropertyDefinition(t,e,"gradientDefs");i&&t.set(e,fabric.Gradient.fromElement(i,t))},t.createClipPathCallback=function(t,e){return function(t){t._removeTransformMatrix(),t.fillRule=t.clipRule,e.push(t)}},t.resolveClipPath=function(t){var e,i,r,n,s=this.extractPropertyDefinition(t,"clipPath","clipPaths");if(s){r=[],i=fabric.util.invertTransform(t.calcTransformMatrix());for(var o=0;ot.x&&this.y>t.y},gte:function(t){return this.x>=t.x&&this.y>=t.y},lerp:function(t,e){return void 0===e&&(e=.5),e=Math.max(Math.min(1,e),0),new i(this.x+(t.x-this.x)*e,this.y+(t.y-this.y)*e)},distanceFrom:function(t){var e=this.x-t.x,i=this.y-t.y;return Math.sqrt(e*e+i*i)},midPointFrom:function(t){return this.lerp(t)},min:function(t){return new i(Math.min(this.x,t.x),Math.min(this.y,t.y))},max:function(t){return new i(Math.max(this.x,t.x),Math.max(this.y,t.y))},toString:function(){return this.x+","+this.y},setXY:function(t,e){return this.x=t,this.y=e,this},setX:function(t){return this.x=t,this},setY:function(t){return this.y=t,this},setFromPoint:function(t){return this.x=t.x,this.y=t.y,this},swap:function(t){var e=this.x,i=this.y;this.x=t.x,this.y=t.y,t.x=e,t.y=i},clone:function(){return new i(this.x,this.y)}}}("undefined"!=typeof exports?exports:this),function(t){"use strict";var f=t.fabric||(t.fabric={});function d(t){this.status=t,this.points=[]}f.Intersection?f.warn("fabric.Intersection is already defined"):(f.Intersection=d,f.Intersection.prototype={constructor:d,appendPoint:function(t){return this.points.push(t),this},appendPoints:function(t){return this.points=this.points.concat(t),this}},f.Intersection.intersectLineLine=function(t,e,i,r){var n,s=(r.x-i.x)*(t.y-i.y)-(r.y-i.y)*(t.x-i.x),o=(e.x-t.x)*(t.y-i.y)-(e.y-t.y)*(t.x-i.x),a=(r.y-i.y)*(e.x-t.x)-(r.x-i.x)*(e.y-t.y);if(0!==a){var h=s/a,c=o/a;0<=h&&h<=1&&0<=c&&c<=1?(n=new d("Intersection")).appendPoint(new f.Point(t.x+h*(e.x-t.x),t.y+h*(e.y-t.y))):n=new d}else n=new d(0===s||0===o?"Coincident":"Parallel");return n},f.Intersection.intersectLinePolygon=function(t,e,i){var r,n,s,o,a=new d,h=i.length;for(o=0;os.r2,h=t.width/2,c=t.height/2;for(var l in o.sort(function(t,e){return t.offset-e.offset}),"path"===t.type&&(h-=t.pathOffset.x,c-=t.pathOffset.y),s)"x1"===l||"x2"===l?s[l]+=this.offsetX-h:"y1"!==l&&"y2"!==l||(s[l]+=this.offsetY-c);if(n='id="SVGID_'+this.id+'" gradientUnits="userSpaceOnUse"',this.gradientTransform&&(n+=' gradientTransform="matrix('+this.gradientTransform.join(" ")+')" '),"linear"===this.type?r=["\n']:"radial"===this.type&&(r=["\n']),"radial"===this.type){if(a)for((o=o.concat()).reverse(),e=0,i=o.length;e\n')}return r.push("linear"===this.type?"\n":"\n"),r.join("")},toLive:function(t){var e,i,r,n=fabric.util.object.clone(this.coords);if(this.type){for("linear"===this.type?e=t.createLinearGradient(n.x1,n.y1,n.x2,n.y2):"radial"===this.type&&(e=t.createRadialGradient(n.x1,n.y1,n.r1,n.x2,n.y2,n.r2)),i=0,r=this.colorStops.length;i\n\n\n'},setOptions:function(t){for(var e in t)this[e]=t[e]},toLive:function(t){var e="function"==typeof this.source?this.source():this.source;if(!e)return"";if(void 0!==e.src){if(!e.complete)return"";if(0===e.naturalWidth||0===e.naturalHeight)return""}return t.createPattern(e,this.repeat)}})}(),function(t){"use strict";var o=t.fabric||(t.fabric={}),a=o.util.toFixed;o.Shadow?o.warn("fabric.Shadow is already defined."):(o.Shadow=o.util.createClass({color:"rgb(0,0,0)",blur:0,offsetX:0,offsetY:0,affectStroke:!1,includeDefaultValues:!0,initialize:function(t){for(var e in"string"==typeof t&&(t=this._parseShadow(t)),t)this[e]=t[e];this.id=o.Object.__uid++},_parseShadow:function(t){var e=t.trim(),i=o.Shadow.reOffsetsAndBlur.exec(e)||[];return{color:(e.replace(o.Shadow.reOffsetsAndBlur,"")||"rgb(0,0,0)").trim(),offsetX:parseInt(i[1],10)||0,offsetY:parseInt(i[2],10)||0,blur:parseInt(i[3],10)||0}},toString:function(){return[this.offsetX,this.offsetY,this.blur,this.color].join("px ")},toSVG:function(t){var e=40,i=40,r=o.Object.NUM_FRACTION_DIGITS,n=o.util.rotateVector({x:this.offsetX,y:this.offsetY},o.util.degreesToRadians(-t.angle)),s=new o.Color(this.color);return t.width&&t.height&&(e=100*a((Math.abs(n.x)+this.blur)/t.width,r)+20,i=100*a((Math.abs(n.y)+this.blur)/t.height,r)+20),t.flipX&&(n.x*=-1),t.flipY&&(n.y*=-1),'\n\t\n\t\n\t\n\t\n\t\n\t\t\n\t\t\n\t\n\n'},toObject:function(){if(this.includeDefaultValues)return{color:this.color,blur:this.blur,offsetX:this.offsetX,offsetY:this.offsetY,affectStroke:this.affectStroke};var e={},i=o.Shadow.prototype;return["color","blur","offsetX","offsetY","affectStroke"].forEach(function(t){this[t]!==i[t]&&(e[t]=this[t])},this),e}}),o.Shadow.reOffsetsAndBlur=/(?:\s|^)(-?\d+(?:px)?(?:\s?|$))?(-?\d+(?:px)?(?:\s?|$))?(\d+(?:px)?)?(?:\s?|$)(?:$|\s)/)}("undefined"!=typeof exports?exports:this),function(){"use strict";if(fabric.StaticCanvas)fabric.warn("fabric.StaticCanvas is already defined.");else{var n=fabric.util.object.extend,t=fabric.util.getElementOffset,c=fabric.util.removeFromArray,a=fabric.util.toFixed,s=fabric.util.transformPoint,o=fabric.util.invertTransform,e=new Error("Could not initialize `canvas` element");fabric.StaticCanvas=fabric.util.createClass(fabric.CommonMethods,{initialize:function(t,e){e||(e={}),this.renderAndResetBound=this.renderAndReset.bind(this),this.requestRenderAllBound=this.requestRenderAll.bind(this),this._initStatic(t,e)},backgroundColor:"",backgroundImage:null,overlayColor:"",overlayImage:null,includeDefaultValues:!0,stateful:!1,renderOnAddRemove:!0,clipTo:null,controlsAboveOverlay:!1,allowTouchScrolling:!1,imageSmoothingEnabled:!0,viewportTransform:fabric.iMatrix.concat(),backgroundVpt:!0,overlayVpt:!0,onBeforeScaleRotate:function(){},enableRetinaScaling:!0,vptCoords:{},skipOffscreen:!0,clipPath:void 0,_initStatic:function(t,e){var i=this.requestRenderAllBound;this._objects=[],this._createLowerCanvas(t),this._initOptions(e),this._setImageSmoothing(),this.interactive||this._initRetinaScaling(),e.overlayImage&&this.setOverlayImage(e.overlayImage,i),e.backgroundImage&&this.setBackgroundImage(e.backgroundImage,i),e.backgroundColor&&this.setBackgroundColor(e.backgroundColor,i),e.overlayColor&&this.setOverlayColor(e.overlayColor,i),this.calcOffset()},_isRetinaScaling:function(){return 1!==fabric.devicePixelRatio&&this.enableRetinaScaling},getRetinaScaling:function(){return this._isRetinaScaling()?fabric.devicePixelRatio:1},_initRetinaScaling:function(){this._isRetinaScaling()&&(this.lowerCanvasEl.setAttribute("width",this.width*fabric.devicePixelRatio),this.lowerCanvasEl.setAttribute("height",this.height*fabric.devicePixelRatio),this.contextContainer.scale(fabric.devicePixelRatio,fabric.devicePixelRatio))},calcOffset:function(){return this._offset=t(this.lowerCanvasEl),this},setOverlayImage:function(t,e,i){return this.__setBgOverlayImage("overlayImage",t,e,i)},setBackgroundImage:function(t,e,i){return this.__setBgOverlayImage("backgroundImage",t,e,i)},setOverlayColor:function(t,e){return this.__setBgOverlayColor("overlayColor",t,e)},setBackgroundColor:function(t,e){return this.__setBgOverlayColor("backgroundColor",t,e)},_setImageSmoothing:function(){var t=this.getContext();t.imageSmoothingEnabled=t.imageSmoothingEnabled||t.webkitImageSmoothingEnabled||t.mozImageSmoothingEnabled||t.msImageSmoothingEnabled||t.oImageSmoothingEnabled,t.imageSmoothingEnabled=this.imageSmoothingEnabled},__setBgOverlayImage:function(e,t,i,r){return"string"==typeof t?fabric.util.loadImage(t,function(t){t&&(this[e]=new fabric.Image(t,r)),i&&i(t)},this,r&&r.crossOrigin):(r&&t.setOptions(r),this[e]=t,i&&i(t)),this},__setBgOverlayColor:function(t,e,i){return this[t]=e,this._initGradient(e,t),this._initPattern(e,t,i),this},_createCanvasElement:function(){var t=fabric.util.createCanvasElement();if(!t)throw e;if(t.style||(t.style={}),void 0===t.getContext)throw e;return t},_initOptions:function(t){this._setOptions(t),this.width=this.width||parseInt(this.lowerCanvasEl.width,10)||0,this.height=this.height||parseInt(this.lowerCanvasEl.height,10)||0,this.lowerCanvasEl.style&&(this.lowerCanvasEl.width=this.width,this.lowerCanvasEl.height=this.height,this.lowerCanvasEl.style.width=this.width+"px",this.lowerCanvasEl.style.height=this.height+"px",this.viewportTransform=this.viewportTransform.slice())},_createLowerCanvas:function(t){t&&t.getContext?this.lowerCanvasEl=t:this.lowerCanvasEl=fabric.util.getById(t)||this._createCanvasElement(),fabric.util.addClass(this.lowerCanvasEl,"lower-canvas"),this.interactive&&this._applyCanvasStyle(this.lowerCanvasEl),this.contextContainer=this.lowerCanvasEl.getContext("2d")},getWidth:function(){return this.width},getHeight:function(){return this.height},setWidth:function(t,e){return this.setDimensions({width:t},e)},setHeight:function(t,e){return this.setDimensions({height:t},e)},setDimensions:function(t,e){var i;for(var r in e=e||{},t)i=t[r],e.cssOnly||(this._setBackstoreDimension(r,t[r]),i+="px",this.hasLostContext=!0),e.backstoreOnly||this._setCssDimension(r,i);return this._isCurrentlyDrawing&&this.freeDrawingBrush&&this.freeDrawingBrush._setBrushStyles(),this._initRetinaScaling(),this._setImageSmoothing(),this.calcOffset(),e.cssOnly||this.requestRenderAll(),this},_setBackstoreDimension:function(t,e){return this.lowerCanvasEl[t]=e,this.upperCanvasEl&&(this.upperCanvasEl[t]=e),this.cacheCanvasEl&&(this.cacheCanvasEl[t]=e),this[t]=e,this},_setCssDimension:function(t,e){return this.lowerCanvasEl.style[t]=e,this.upperCanvasEl&&(this.upperCanvasEl.style[t]=e),this.wrapperEl&&(this.wrapperEl.style[t]=e),this},getZoom:function(){return this.viewportTransform[0]},setViewportTransform:function(t){var e,i,r,n=this._activeObject;for(this.viewportTransform=t,i=0,r=this._objects.length;i"),i.join("")},_setSVGPreamble:function(t,e){e.suppressPreamble||t.push('\n','\n')},_setSVGHeader:function(t,e){var i,r=e.width||this.width,n=e.height||this.height,s='viewBox="0 0 '+this.width+" "+this.height+'" ',o=fabric.Object.NUM_FRACTION_DIGITS;e.viewBox?s='viewBox="'+e.viewBox.x+" "+e.viewBox.y+" "+e.viewBox.width+" "+e.viewBox.height+'" ':this.svgViewportTransformation&&(i=this.viewportTransform,s='viewBox="'+a(-i[4]/i[0],o)+" "+a(-i[5]/i[3],o)+" "+a(this.width/i[0],o)+" "+a(this.height/i[3],o)+'" '),t.push("