diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4bf917064ae..805d71fd53e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,14 @@
+**Version 2.2.4**
+ - Fix getPointer on touch devices [#4866](https://github.com/kangax/fabric.js/pull/4866)
+ - Fix issues with selectionDashArray bleeding into free drawing [#4894](https://github.com/kangax/fabric.js/pull/4894)
+ - Fix blur filter for nodejs [#4905](https://github.com/kangax/fabric.js/pull/4905)
+ - Fix Register mousemove as non passive to help touch devices [#4933](https://github.com/kangax/fabric.js/pull/4933)
+ - Fix modified shadow tosvg for safari compatibility [#4934](https://github.com/kangax/fabric.js/pull/4934)
+ - Fix shader to avoid premultiplied alpha pixel getting dirty in blend filter [#4936](https://github.com/kangax/fabric.js/pull/4936)
+ - Add isPartiallyOnScreen method [#4856](https://github.com/kangax/fabric.js/pull/4856)
+ - Fix isEqual failing on array/null or objects/null/string compare [#4949](https://github.com/kangax/fabric.js/pull/4949)
+ - Fix pencilBrush with alpha and with rerendering canvas [#4938](https://github.com/kangax/fabric.js/pull/4938)
+
**Version 2.2.3**
- improvement: Allow to parse quoted url string. url('#myid') [#4881](https://github.com/kangax/fabric.js/pull/4881)
- improvement: text fromSVG import char-spacing attribute [#3718](https://github.com/kangax/fabric.js/pull/3718)
diff --git a/HEADER.js b/HEADER.js
index 1031cc024a7..ff352cf20f5 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.2.3' };
+var fabric = fabric || { version: '2.2.4' };
if (typeof exports !== 'undefined') {
exports.fabric = fabric;
}
diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md
index b402215fa8b..9e1e9498e9e 100644
--- a/ISSUE_TEMPLATE.md
+++ b/ISSUE_TEMPLATE.md
@@ -25,7 +25,7 @@ Remove the template from below and provide thoughtful commentary *and code sampl
## Version
-2.2.3
+2.2.4
## Test Case
http://jsfiddle.net/fabricjs/Da7SP/
diff --git a/dist/fabric.js b/dist/fabric.js
index 18a5fe02eb7..ddf589d35fc 100644
--- a/dist/fabric.js
+++ b/dist/fabric.js
@@ -1,5 +1,5 @@
var fabric = fabric || {
- version: "2.2.3"
+ version: "2.2.4"
};
if (typeof exports !== "undefined") {
@@ -1191,7 +1191,14 @@ fabric.CommonMethods = {
};
function _getPointer(event, pageProp, clientProp) {
var touchProp = event.type === "touchend" ? "changedTouches" : "touches";
- return event[touchProp] && event[touchProp][0] ? event[touchProp][0][pageProp] - (event[touchProp][0][pageProp] - event[touchProp][0][clientProp]) || event[clientProp] : event[clientProp];
+ var pointer, eventTouchProp = event[touchProp];
+ if (eventTouchProp && eventTouchProp[0]) {
+ pointer = eventTouchProp[0][clientProp];
+ }
+ if (typeof pointer === "undefined") {
+ pointer = event[clientProp];
+ }
+ return pointer;
}
if (fabric.isTouchSupported) {
pointerX = function(event) {
@@ -3397,7 +3404,7 @@ fabric.ElementsParser.prototype.checkIfDone = function() {
var fBoxX = 40, fBoxY = 40, NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS, offset = fabric.util.rotateVector({
x: this.offsetX,
y: this.offsetY
- }, fabric.util.degreesToRadians(-object.angle)), BLUR_BOX = 20;
+ }, fabric.util.degreesToRadians(-object.angle)), BLUR_BOX = 20, color = new fabric.Color(this.color);
if (object.width && object.height) {
fBoxX = toFixed((Math.abs(offset.x) + this.blur) / object.width, NUM_FRACTION_DIGITS) * 100 + BLUR_BOX;
fBoxY = toFixed((Math.abs(offset.y) + this.blur) / object.height, NUM_FRACTION_DIGITS) * 100 + BLUR_BOX;
@@ -3408,7 +3415,7 @@ fabric.ElementsParser.prototype.checkIfDone = function() {
if (object.flipY) {
offset.y *= -1;
}
- return '\n" + '\t\n' + '\t\n' + '\t\n' + '\t\n' + "\t\n" + "\t\t\n" + '\t\t\n' + "\t\n" + "\n";
+ return '\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) {
@@ -3603,6 +3610,7 @@ fabric.ElementsParser.prototype.checkIfDone = function() {
if (!options.cssOnly) {
this._setBackstoreDimension(prop, dimensions[prop]);
cssValue += "px";
+ this.hasLostContext = true;
}
if (!options.backstoreOnly) {
this._setCssDimension(prop, cssValue);
@@ -4227,8 +4235,8 @@ fabric.BaseBrush = fabric.util.createClass({
ctx.lineCap = this.strokeLineCap;
ctx.miterLimit = this.strokeMiterLimit;
ctx.lineJoin = this.strokeLineJoin;
- if (this.strokeDashArray && fabric.StaticCanvas.supports("setLineDash")) {
- ctx.setLineDash(this.strokeDashArray);
+ if (fabric.StaticCanvas.supports("setLineDash")) {
+ ctx.setLineDash(this.strokeDashArray || []);
}
},
_saveAndTransform: function(ctx) {
@@ -4271,15 +4279,20 @@ fabric.BaseBrush = fabric.util.createClass({
},
onMouseMove: function(pointer) {
if (this._captureDrawingPath(pointer) && this._points.length > 1) {
- var points = this._points, length = points.length, ctx = this.canvas.contextTop;
- this._saveAndTransform(ctx);
- if (this.oldEnd) {
- ctx.beginPath();
- ctx.moveTo(this.oldEnd.x, this.oldEnd.y);
+ if (this.needsFullRender) {
+ this.canvas.clearContext(this.canvas.contextTop);
+ this._render();
+ } else {
+ var points = this._points, length = points.length, ctx = this.canvas.contextTop;
+ this._saveAndTransform(ctx);
+ if (this.oldEnd) {
+ ctx.beginPath();
+ ctx.moveTo(this.oldEnd.x, this.oldEnd.y);
+ }
+ this.oldEnd = this._drawSegment(ctx, points[length - 2], points[length - 1], true);
+ ctx.stroke();
+ ctx.restore();
}
- this.oldEnd = this._drawSegment(ctx, points[length - 2], points[length - 1], true);
- ctx.stroke();
- ctx.restore();
}
},
onMouseUp: function() {
@@ -4302,6 +4315,8 @@ fabric.BaseBrush = fabric.util.createClass({
_reset: function() {
this._points.length = 0;
this._setBrushStyles();
+ var color = new fabric.Color(this.color);
+ this.needsFullRender = color.getAlpha() < 1;
this._setShadow();
},
_captureDrawingPath: function(pointer) {
@@ -4698,7 +4713,9 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, {
this.clearContext(this.contextTop);
this.contextTopDirty = false;
}
- this.renderTopLayer(this.contextTop);
+ if (this.hasLostContext) {
+ this.renderTopLayer(this.contextTop);
+ }
var canvasToDrawOn = this.contextContainer;
this.renderCanvas(canvasToDrawOn, this._chooseObjectsToRender());
return this;
@@ -5260,7 +5277,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, {
height: height + "px",
left: 0,
top: 0,
- "touch-action": "none"
+ "touch-action": this.allowTouchScrolling ? "manipulation" : "none"
});
element.width = width;
element.height = height;
@@ -5478,7 +5495,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, {
addListener(fabric.window, "resize", this._onResize);
addListener(this.upperCanvasEl, "mousedown", this._onMouseDown);
addListener(this.upperCanvasEl, "dblclick", this._onDoubleClick);
- addListener(this.upperCanvasEl, "mousemove", this._onMouseMove);
+ addListener(this.upperCanvasEl, "mousemove", this._onMouseMove, addEventOptions);
addListener(this.upperCanvasEl, "mouseout", this._onMouseOut);
addListener(this.upperCanvasEl, "mouseenter", this._onMouseEnter);
addListener(this.upperCanvasEl, "wheel", this._onMouseWheel);
@@ -5609,7 +5626,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, {
addListener(fabric.document, "touchend", this._onMouseUp, addEventOptions);
addListener(fabric.document, "touchmove", this._onMouseMove, addEventOptions);
removeListener(this.upperCanvasEl, "mousemove", this._onMouseMove);
- removeListener(this.upperCanvasEl, "touchmove", this._onMouseMove, addEventOptions);
+ removeListener(this.upperCanvasEl, "touchmove", this._onMouseMove);
if (e.type === "touchstart") {
removeListener(this.upperCanvasEl, "mousedown", this._onMouseDown);
} else {
@@ -5622,8 +5639,8 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, {
removeListener(fabric.document, "mouseup", this._onMouseUp);
removeListener(fabric.document, "touchend", this._onMouseUp, addEventOptions);
removeListener(fabric.document, "mousemove", this._onMouseMove);
- removeListener(fabric.document, "touchmove", this._onMouseMove, addEventOptions);
- addListener(this.upperCanvasEl, "mousemove", this._onMouseMove);
+ removeListener(fabric.document, "touchmove", this._onMouseMove);
+ addListener(this.upperCanvasEl, "mousemove", this._onMouseMove, addEventOptions);
addListener(this.upperCanvasEl, "touchmove", this._onMouseMove, addEventOptions);
if (e.type === "touchend") {
var _this = this;
@@ -7159,6 +7176,9 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
if (this.intersectsWithRect(pointTL, pointBR, true, calculate)) {
return true;
}
+ return this._containsCenterOfCanvas(pointTL, pointBR, calculate);
+ },
+ _containsCenterOfCanvas: function(pointTL, pointBR, calculate) {
var centerPoint = {
x: (pointTL.x + pointBR.x) / 2,
y: (pointTL.y + pointBR.y) / 2
@@ -7168,6 +7188,16 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
}
return false;
},
+ isPartiallyOnScreen: function(calculate) {
+ if (!this.canvas) {
+ return false;
+ }
+ var pointTL = this.canvas.vptCoords.tl, pointBR = this.canvas.vptCoords.br;
+ if (this.intersectsWithRect(pointTL, pointBR, true, calculate)) {
+ return true;
+ }
+ return this._containsCenterOfCanvas(pointTL, pointBR, calculate);
+ },
_getImageLines: function(oCoords) {
return {
topline: {
@@ -7542,7 +7572,7 @@ fabric.util.object.extend(fabric.Object.prototype, {
if (origValue === currentValue) {
return true;
} else if (Array.isArray(origValue)) {
- if (origValue.length !== currentValue.length) {
+ if (!Array.isArray(currentValue) || origValue.length !== currentValue.length) {
return false;
}
for (var i = 0, len = origValue.length; i < len; i++) {
@@ -7553,7 +7583,7 @@ fabric.util.object.extend(fabric.Object.prototype, {
return true;
} else if (origValue && typeof origValue === "object") {
var keys = Object.keys(origValue), key;
- if (!firstPass && keys.length !== Object.keys(currentValue).length) {
+ if (!currentValue || typeof currentValue !== "object" || !firstPass && keys.length !== Object.keys(currentValue).length) {
return false;
}
for (var i = 0, len = keys.length; i < len; i++) {
@@ -9865,7 +9895,11 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
canvas.width = width;
canvas.height = height;
var glOptions = {
- premultipliedAlpha: false
+ alpha: true,
+ premultipliedAlpha: false,
+ depth: false,
+ stencil: false,
+ antialias: false
}, gl = canvas.getContext("webgl", glOptions);
if (!gl) {
gl = canvas.getContext("experimental-webgl", glOptions);
@@ -10150,7 +10184,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass({
return {};
},
sendAttributeData: function(gl, attributeLocations, aPositionData) {
- var attributeLocation = attributeLocations.aPostion;
+ var attributeLocation = attributeLocations.aPosition;
var buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.enableVertexAttribArray(attributeLocation);
@@ -10675,21 +10709,24 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) {
mode: "multiply",
alpha: 1,
fragmentSource: {
- multiply: "precision highp float;\n" + "uniform sampler2D uTexture;\n" + "uniform vec4 uColor;\n" + "varying vec2 vTexCoord;\n" + "void main() {\n" + "vec4 color = texture2D(uTexture, vTexCoord);\n" + "color.rgb *= uColor.rgb;\n" + "gl_FragColor = color;\n" + "}",
- screen: "precision highp float;\n" + "uniform sampler2D uTexture;\n" + "uniform vec4 uColor;\n" + "varying vec2 vTexCoord;\n" + "void main() {\n" + "vec4 color = texture2D(uTexture, vTexCoord);\n" + "color.rgb = 1.0 - (1.0 - color.rgb) * (1.0 - uColor.rgb);\n" + "gl_FragColor = color;\n" + "}",
- add: "precision highp float;\n" + "uniform sampler2D uTexture;\n" + "uniform vec4 uColor;\n" + "varying vec2 vTexCoord;\n" + "void main() {\n" + "gl_FragColor = texture2D(uTexture, vTexCoord);\n" + "gl_FragColor.rgb += uColor.rgb;\n" + "}",
- diff: "precision highp float;\n" + "uniform sampler2D uTexture;\n" + "uniform vec4 uColor;\n" + "varying vec2 vTexCoord;\n" + "void main() {\n" + "gl_FragColor = texture2D(uTexture, vTexCoord);\n" + "gl_FragColor.rgb = abs(gl_FragColor.rgb - uColor.rgb);\n" + "}",
- subtract: "precision highp float;\n" + "uniform sampler2D uTexture;\n" + "uniform vec4 uColor;\n" + "varying vec2 vTexCoord;\n" + "void main() {\n" + "gl_FragColor = texture2D(uTexture, vTexCoord);\n" + "gl_FragColor.rgb -= uColor.rgb;\n" + "}",
- lighten: "precision highp float;\n" + "uniform sampler2D uTexture;\n" + "uniform vec4 uColor;\n" + "varying vec2 vTexCoord;\n" + "void main() {\n" + "gl_FragColor = texture2D(uTexture, vTexCoord);\n" + "gl_FragColor.rgb = max(gl_FragColor.rgb, uColor.rgb);\n" + "}",
- darken: "precision highp float;\n" + "uniform sampler2D uTexture;\n" + "uniform vec4 uColor;\n" + "varying vec2 vTexCoord;\n" + "void main() {\n" + "gl_FragColor = texture2D(uTexture, vTexCoord);\n" + "gl_FragColor.rgb = min(gl_FragColor.rgb, uColor.rgb);\n" + "}",
- exclusion: "precision highp float;\n" + "uniform sampler2D uTexture;\n" + "uniform vec4 uColor;\n" + "varying vec2 vTexCoord;\n" + "void main() {\n" + "gl_FragColor = texture2D(uTexture, vTexCoord);\n" + "gl_FragColor.rgb += uColor.rgb - 2.0 * (uColor.rgb * gl_FragColor.rgb);\n" + "}",
- overlay: "precision highp float;\n" + "uniform sampler2D uTexture;\n" + "uniform vec4 uColor;\n" + "varying vec2 vTexCoord;\n" + "void main() {\n" + "gl_FragColor = texture2D(uTexture, vTexCoord);\n" + "if (uColor.r < 0.5) {\n" + "gl_FragColor.r *= 2.0 * uColor.r;\n" + "} else {\n" + "gl_FragColor.r = 1.0 - 2.0 * (1.0 - gl_FragColor.r) * (1.0 - uColor.r);\n" + "}\n" + "if (uColor.g < 0.5) {\n" + "gl_FragColor.g *= 2.0 * uColor.g;\n" + "} else {\n" + "gl_FragColor.g = 1.0 - 2.0 * (1.0 - gl_FragColor.g) * (1.0 - uColor.g);\n" + "}\n" + "if (uColor.b < 0.5) {\n" + "gl_FragColor.b *= 2.0 * uColor.b;\n" + "} else {\n" + "gl_FragColor.b = 1.0 - 2.0 * (1.0 - gl_FragColor.b) * (1.0 - uColor.b);\n" + "}\n" + "}",
- tint: "precision highp float;\n" + "uniform sampler2D uTexture;\n" + "uniform vec4 uColor;\n" + "varying vec2 vTexCoord;\n" + "void main() {\n" + "gl_FragColor = texture2D(uTexture, vTexCoord);\n" + "gl_FragColor.rgb *= (1.0 - uColor.a);\n" + "gl_FragColor.rgb += uColor.rgb;\n" + "}"
+ multiply: "gl_FragColor.rgb *= uColor.rgb;\n",
+ screen: "gl_FragColor.rgb = 1.0 - (1.0 - gl_FragColor.rgb) * (1.0 - uColor.rgb);\n",
+ add: "gl_FragColor.rgb += uColor.rgb;\n",
+ diff: "gl_FragColor.rgb = abs(gl_FragColor.rgb - uColor.rgb);\n",
+ subtract: "gl_FragColor.rgb -= uColor.rgb;\n",
+ lighten: "gl_FragColor.rgb = max(gl_FragColor.rgb, uColor.rgb);\n",
+ darken: "gl_FragColor.rgb = min(gl_FragColor.rgb, uColor.rgb);\n",
+ exclusion: "gl_FragColor.rgb += uColor.rgb - 2.0 * (uColor.rgb * gl_FragColor.rgb);\n",
+ overlay: "if (uColor.r < 0.5) {\n" + "gl_FragColor.r *= 2.0 * uColor.r;\n" + "} else {\n" + "gl_FragColor.r = 1.0 - 2.0 * (1.0 - gl_FragColor.r) * (1.0 - uColor.r);\n" + "}\n" + "if (uColor.g < 0.5) {\n" + "gl_FragColor.g *= 2.0 * uColor.g;\n" + "} else {\n" + "gl_FragColor.g = 1.0 - 2.0 * (1.0 - gl_FragColor.g) * (1.0 - uColor.g);\n" + "}\n" + "if (uColor.b < 0.5) {\n" + "gl_FragColor.b *= 2.0 * uColor.b;\n" + "} else {\n" + "gl_FragColor.b = 1.0 - 2.0 * (1.0 - gl_FragColor.b) * (1.0 - uColor.b);\n" + "}\n",
+ tint: "gl_FragColor.rgb *= (1.0 - uColor.a);\n" + "gl_FragColor.rgb += uColor.rgb;\n"
+ },
+ buildSource: function(mode) {
+ return "precision highp float;\n" + "uniform sampler2D uTexture;\n" + "uniform vec4 uColor;\n" + "varying vec2 vTexCoord;\n" + "void main() {\n" + "vec4 color = texture2D(uTexture, vTexCoord);\n" + "gl_FragColor = color;\n" + "if (color.a > 0.0) {\n" + this.fragmentSource[mode] + "}\n" + "}";
},
retrieveShader: function(options) {
- var cacheKey = this.type + "_" + this.mode;
- var shaderSource = this.fragmentSource[this.mode];
+ var cacheKey = this.type + "_" + this.mode, shaderSource;
if (!options.programCache.hasOwnProperty(cacheKey)) {
+ shaderSource = this.buildSource(this.mode);
options.programCache[cacheKey] = this.createProgram(options.context, shaderSource);
}
return options.programCache[cacheKey];
@@ -11267,8 +11304,8 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) {
simpleBlur: function(options) {
var resources = options.filterBackend.resources, canvas1, canvas2, width = options.imageData.width, height = options.imageData.height;
if (!resources.blurLayer1) {
- resources.blurLayer1 = document.createElement("canvas");
- resources.blurLayer2 = document.createElement("canvas");
+ resources.blurLayer1 = fabric.util.createCanvasElement();
+ resources.blurLayer2 = fabric.util.createCanvasElement();
}
canvas1 = resources.blurLayer1;
canvas2 = resources.blurLayer2;
diff --git a/dist/fabric.min.js b/dist/fabric.min.js
index e16458d934d..3b78b669e03 100644
--- a/dist/fabric.min.js
+++ b/dist/fabric.min.js
@@ -1 +1 @@
-var fabric=fabric||{version:"2.2.3"};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"],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.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);x.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 x.window.ActiveXObject&&((r=new ActiveXObject("Microsoft.XMLDOM")).async="false",r.loadXML(t.replace(//i,"")));x.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},fabric.ElementsParser.prototype.parse=function(){this.instances=new Array(this.elements.length),this.numElements=this.elements.length,this.createObjects()},fabric.ElementsParser.prototype.createObjects=function(){for(var t=0,e=this.elements.length;tt.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 s=t.fabric||(t.fabric={}),o=s.util.toFixed;s.Shadow?s.warn("fabric.Shadow is already defined."):(s.Shadow=s.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=s.Object.__uid++},_parseShadow:function(t){var e=t.trim(),i=s.Shadow.reOffsetsAndBlur.exec(e)||[];return{color:(e.replace(s.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=s.Object.NUM_FRACTION_DIGITS,n=s.util.rotateVector({x:this.offsetX,y:this.offsetY},s.util.degreesToRadians(-t.angle));return t.width&&t.height&&(e=100*o((Math.abs(n.x)+this.blur)/t.width,r)+20,i=100*o((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=s.Shadow.prototype;return["color","blur","offsetX","offsetY","affectStroke"].forEach(function(t){this[t]!==i[t]&&(e[t]=this[t])},this),e}}),s.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 r=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,_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"),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("