From 84b012f9ceb46ab745293d9c9872bf21a3d84cb7 Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Sun, 2 Oct 2016 21:35:37 +0200 Subject: [PATCH] Versione 1.6.5 (#3316) * fix to doc * ver 165 --- CHANGELOG.md | 23 + HEADER.js | 2 +- ISSUE_TEMPLATE.md | 2 +- dist/fabric.js | 2041 +++++++++++++++++--------------- dist/fabric.min.js | 16 +- dist/fabric.min.js.gz | Bin 67345 -> 67614 bytes dist/fabric.require.js | 920 +++++++------- package.json | 2 +- src/mixins/collection.mixin.js | 4 +- src/shapes/itext.class.js | 1 + 10 files changed, 1593 insertions(+), 1418 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fa66dde0..64172d8a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,26 @@ +**Version 1.6.5** + +- Fix: charspacing, do not get subzero with charwidth. +- Improvement: add callback support to all object cloning. [#3212](https://github.com/kangax/fabric.js/pull/3212) +- Improvement: add backgroundColor to all classe [#3248](https://github.com/kangax/fabric.js/pull/3248) +- Fix: add custom properties to backgroundImage and overlayImage [#3250](https://github.com/kangax/fabric.js/pull/3250) +- Fix: Object intersection is calculated on boundingBox and boundingRect, intersection is fired if objects are overlapping [#3252](https://github.com/kangax/fabric.js/pull/3252) +- Change: Restored previous selection behaviour, added key to selection active object under overlaid target [#3254](https://github.com/kangax/fabric.js/pull/3254) +- Improvement: hasStateChanged let you find state changes of complex properties. [#3262](https://github.com/kangax/fabric.js/pull/3262) +- Fix: IText/Textbox shift click selection backward. [#3270](https://github.com/kangax/fabric.js/pull/3270) +- Revert: font family quoting was a bad idea. node-canvas stills use it. [#3276](https://github.com/kangax/fabric.js/pull/3276) +- Fix: fire mouse:over event for activeObject and activeGroup when using findTarget shourtcuts [#3285](https://github.com/kangax/fabric.js/pull/3285) +- Fix: clear method clear all properties of canvas [#3305](https://github.com/kangax/fabric.js/pull/3305) +- Fix: text area position method takes in account canvas offset [#3306](https://github.com/kangax/fabric.js/pull/3306) +- Improvement: Added event on right click and possibility to hide the context menu with a flag [3308](https://github.com/kangax/fabric.js/pull/3308) +- Fix: remove canvas reference from object when object gets removed from canvas [#3307](https://github.com/kangax/fabric.js/pull/3307) +- Improvement: use native stroke dash if available [#3309](https://github.com/kangax/fabric.js/pull/3309) +- Fix: Export correct src when exporting to svg [#3310](https://github.com/kangax/fabric.js/pull/3310) +- Fix: Stop text to go on zero dimensions [#3312](https://github.com/kangax/fabric.js/pull/3312) +- Fix: Error in dataURL with multiplier was outputting very big canvas with retina [#3314](https://github.com/kangax/fabric.js/pull/3314) +- Fix: Error in style map was not respecting style if textbox started with space [#3315](https://github.com/kangax/fabric.js/pull/3315) + + **Version 1.6.4** - Improvement: Ignore svg: namespace during svg import. [#3081](https://github.com/kangax/fabric.js/pull/3081) diff --git a/HEADER.js b/HEADER.js index c7b957a4..577cb842 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: "1.6.4" }; +var fabric = fabric || { version: "1.6.5" }; if (typeof exports !== 'undefined') { exports.fabric = fabric; } diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md index 69683198..2784f9d1 100644 --- a/ISSUE_TEMPLATE.md +++ b/ISSUE_TEMPLATE.md @@ -24,7 +24,7 @@ Remove the template from below and provide thoughtful commentary *and code sampl ## Version -1.6.2 +1.6.5 ## Test Case http://jsfiddle.net/fabricjs/Da7SP/ diff --git a/dist/fabric.js b/dist/fabric.js index 0efd6404..27bdd479 100644 --- a/dist/fabric.js +++ b/dist/fabric.js @@ -1,7 +1,7 @@ /* build: `node build.js modules=ALL exclude=json,gestures minifier=uglifyjs` */ /*! Fabric.js Copyright 2008-2015, Printio (Juriy Zaytsev, Maxim Chernyak) */ -var fabric = fabric || { version: "1.6.4" }; +var fabric = fabric || { version: "1.6.5" }; if (typeof exports !== 'undefined') { exports.fabric = fabric; } @@ -118,7 +118,7 @@ fabric.devicePixelRatio = fabric.window.devicePixelRatio || } else { if (!this.__eventListeners[eventName]) { - this.__eventListeners[eventName] = [ ]; + this.__eventListeners[eventName] = []; } this.__eventListeners[eventName].push(handler); } @@ -213,7 +213,9 @@ fabric.Collection = { _objects: [], /** - * Adds objects to collection, then renders canvas (if `renderOnAddRemove` is not `false`) + * Adds objects to collection, Canvas or Group, then renders canvas + * (if `renderOnAddRemove` is not `false`). + * in case of Group no changes to bounding box are made. * Objects should be instances of (or inherit from) fabric.Object * @param {...fabric.Object} object Zero or more fabric instances * @return {Self} thisArg @@ -602,10 +604,10 @@ fabric.Collection = { } var parts = namespace.split('.'), - len = parts.length, + len = parts.length, i, obj = global || fabric.window; - for (var i = 0; i < len; ++i) { + for (i = 0; i < len; ++i) { obj = obj[parts[i]]; } @@ -663,7 +665,7 @@ fabric.Collection = { * called after each fabric object created. */ enlivenObjects: function(objects, callback, namespace, reviver) { - objects = objects || [ ]; + objects = objects || []; function onLoaded() { if (++numLoadedObjects === numTotalObjects) { @@ -671,7 +673,7 @@ fabric.Collection = { } } - var enlivenedObjects = [ ], + var enlivenedObjects = [], numLoadedObjects = 0, numTotalObjects = objects.length; @@ -792,11 +794,11 @@ fabric.Collection = { */ createCanvasElement: function(canvasEl) { canvasEl || (canvasEl = fabric.document.createElement('canvas')); - //jscs:disable requireCamelCaseOrUpperCaseIdentifiers + /* eslint-disable camelcase */ if (!canvasEl.getContext && typeof G_vmlCanvasManager !== 'undefined') { G_vmlCanvasManager.initElement(canvasEl); } - //jscs:enable requireCamelCaseOrUpperCaseIdentifiers + /* eslint-enable camelcase */ return canvasEl; }, @@ -819,14 +821,15 @@ fabric.Collection = { * @param {Object} klass "Class" to create accessors for */ createAccessors: function(klass) { - var proto = klass.prototype; + var proto = klass.prototype, i, propName, + capitalizedPropName, setterName, getterName; - for (var i = proto.stateProperties.length; i--; ) { + for (i = proto.stateProperties.length; i--; ) { - var propName = proto.stateProperties[i], - capitalizedPropName = propName.charAt(0).toUpperCase() + propName.slice(1), - setterName = 'set' + capitalizedPropName, - getterName = 'get' + capitalizedPropName; + propName = proto.stateProperties[i]; + capitalizedPropName = propName.charAt(0).toUpperCase() + propName.slice(1); + setterName = 'set' + capitalizedPropName; + getterName = 'get' + capitalizedPropName; // using `new Function` for better introspection if (!proto[getterName]) { @@ -952,12 +955,13 @@ fabric.Collection = { } } - var _isTransparent = true, - imageData = ctx.getImageData(x, y, (tolerance * 2) || 1, (tolerance * 2) || 1); + var _isTransparent = true, i, temp, + imageData = ctx.getImageData(x, y, (tolerance * 2) || 1, (tolerance * 2) || 1), + l = imageData.data.length; // Split image data - for tolerance > 1, pixelDataSize = 4; - for (var i = 3, l = imageData.data.length; i < l; i += 4) { - var temp = imageData.data[i]; + for (i = 3; i < l; i += 4) { + temp = imageData.data[i]; _isTransparent = temp <= 0; if (_isTransparent === false) { break; // Stop if colour found @@ -1048,13 +1052,13 @@ fabric.Collection = { root = 0; if (pl < 0) { - var s = Math.sqrt(1 - pl/(rx2 * ry2)); + var s = Math.sqrt(1 - pl / (rx2 * ry2)); rx *= s; ry *= s; } else { root = (large === sweep ? -1.0 : 1.0) * - Math.sqrt( pl /(rx2 * py2 + ry2 * px2)); + Math.sqrt( pl / (rx2 * py2 + ry2 * px2)); } var cx = root * rx * py / ry, @@ -1100,8 +1104,8 @@ fabric.Collection = { sinth3 = Math.sin(th3), toX = cosTh * rx * costh3 - sinTh * ry * sinth3 + cx1, toY = sinTh * rx * costh3 + cosTh * ry * sinth3 + cy1, - cp1X = fromX + mT * ( - cosTh * rx * sinth2 - sinTh * ry * costh2), - cp1Y = fromY + mT * ( - sinTh * rx * sinth2 + cosTh * ry * costh2), + cp1X = fromX + mT * ( -cosTh * rx * sinth2 - sinTh * ry * costh2), + cp1Y = fromY + mT * ( -sinTh * rx * sinth2 + cosTh * ry * costh2), cp2X = toX + mT * ( cosTh * rx * sinth3 + sinTh * ry * costh3), cp2Y = toY + mT * ( sinTh * rx * sinth3 - cosTh * ry * costh3); @@ -1142,7 +1146,7 @@ fabric.Collection = { sweep = coords[4], tx = coords[5], ty = coords[6], - segs = [[ ], [ ], [ ], [ ]], + segs = [[], [], [], []], segsNorm = arcToSegments(tx - fx, ty - fy, rx, ry, large, sweep, rot); for (var i = 0, len = segsNorm.length; i < len; i++) { @@ -1170,9 +1174,9 @@ fabric.Collection = { */ fabric.util.getBoundsOfArc = function(fx, fy, rx, ry, rot, large, sweep, tx, ty) { - var fromX = 0, fromY = 0, bound = [ ], bounds = [ ], - segs = arcToSegments(tx - fx, ty - fy, rx, ry, large, sweep, rot), - boundCopy = [[ ], [ ]]; + var fromX = 0, fromY = 0, bound = [], bounds = [], + segs = arcToSegments(tx - fx, ty - fy, rx, ry, large, sweep, rot), + boundCopy = [[], []]; for (var i = 0, len = segs.length; i < len; i++) { bound = getBoundsOfCurve(fromX, fromY, segs[i][0], segs[i][1], segs[i][2], segs[i][3], segs[i][4], segs[i][5]); @@ -1208,8 +1212,8 @@ fabric.Collection = { var sqrt = Math.sqrt, min = Math.min, max = Math.max, - abs = Math.abs, tvalues = [ ], - bounds = [[ ], [ ]], + abs = Math.abs, tvalues = [], + bounds = [[], []], a, b, c, t, t1, t2, b2ac, sqrtb2ac; b = 6 * x0 - 12 * x1 + 6 * x2; @@ -1349,7 +1353,7 @@ fabric.Collection = { * @return {Array} */ Array.prototype.map = function(fn, context) { - var result = [ ]; + var result = []; for (var i = 0, len = this.length >>> 0; i < len; i++) { if (i in this) { result[i] = fn.call(context, this[i], i, this); @@ -1401,7 +1405,7 @@ fabric.Collection = { * @return {Array} */ Array.prototype.filter = function(fn, context) { - var result = [ ], val; + var result = [], val; for (var i = 0, len = this.length >>> 0; i < len; i++) { if (i in this) { val = this[i]; // in case fn mutates this @@ -1460,7 +1464,7 @@ fabric.Collection = { * @return {Array} */ function invoke(array, method) { - var args = slice.call(arguments, 2), result = [ ]; + var args = slice.call(arguments, 2), result = []; for (var i = 0, len = array.length; i < len; i++) { result[i] = args.length ? array[i][method].apply(array[i], args) : array[i][method].call(array[i]); } @@ -1553,10 +1557,30 @@ fabric.Collection = { * @param {Object} source Where to copy from * @return {Object} */ - function extend(destination, source) { + function extend(destination, source, deep) { // JScript DontEnum bug is not taken care of - for (var property in source) { - destination[property] = source[property]; + // the deep clone is for internal use, is not meant to avoid + // javascript traps or cloning html element or self referenced objects. + if (deep) { + if (source instanceof Array) { + destination = source.map(function(v) { + return clone(v, deep) + }) + } + else if (source instanceof Object) { + for (var property in source) { + destination[property] = clone(source[property], deep) + } + } + else { + // this sounds odd for an extend but is ok for recursive use + destination = source; + } + } + else { + for (var property in source) { + destination[property] = source[property]; + } } return destination; } @@ -1567,8 +1591,8 @@ fabric.Collection = { * @param {Object} object Object to clone * @return {Object} */ - function clone(object) { - return extend({ }, object); + function clone(object, deep) { + return extend({ }, object, deep); } /** @namespace fabric.util.object */ @@ -1645,7 +1669,7 @@ fabric.Collection = { capitalize: capitalize, escapeXml: escapeXml }; -}()); +})(); /* _ES5_COMPAT_START_ */ @@ -1765,7 +1789,7 @@ fabric.Collection = { } klass.superclass = parent; - klass.subclasses = [ ]; + klass.subclasses = []; if (parent) { Subclass.prototype = parent.prototype; @@ -1887,7 +1911,7 @@ fabric.Collection = { listeners[uid] = { }; } if (!listeners[uid][eventName]) { - listeners[uid][eventName] = [ ]; + listeners[uid][eventName] = []; } var listener = createListener(uid, handler); @@ -1916,7 +1940,7 @@ fabric.Collection = { handlers[uid] = { }; } if (!handlers[uid][eventName]) { - handlers[uid][eventName] = [ ]; + handlers[uid][eventName] = []; var existingHandler = element['on' + eventName]; if (existingHandler) { handlers[uid][eventName].push(existingHandler); @@ -1982,12 +2006,12 @@ fabric.Collection = { // looks like in IE (<9) clientX at certain point (apparently when mouseup fires on VML element) // is represented as COM object, with all the consequences, like "unknown" type and error on [[Get]] // need to investigate later - return (typeof event.clientX !== unknown ? event.clientX : 0); - }, + return (typeof event.clientX !== unknown ? event.clientX : 0); + }, - pointerY = function(event) { - return (typeof event.clientY !== unknown ? event.clientY : 0); - }; + pointerY = function(event) { + return (typeof event.clientY !== unknown ? event.clientY : 0); + }; function _getPointer(event, pageProp, clientProp) { var touchProp = event.type === 'touchend' ? 'changedTouches' : 'touches'; @@ -2475,7 +2499,7 @@ fabric.log = function() { }; */ fabric.warn = function() { }; -/* jshint ignore:start */ +/* eslint-disable */ if (typeof console !== 'undefined') { ['log', 'warn'].forEach(function(methodName) { @@ -2489,7 +2513,7 @@ if (typeof console !== 'undefined') { } }); } -/* jshint ignore:end */ +/* eslint-enable */ (function() { @@ -2605,7 +2629,7 @@ if (typeof console !== 'undefined') { * @memberOf fabric.util.ease */ function easeInOutCubic(t, b, c, d) { - t /= d/2; + t /= d / 2; if (t < 1) { return c / 2 * t * t * t + b; } @@ -2871,10 +2895,10 @@ if (typeof console !== 'undefined') { if ((t /= d) < (1 / 2.75)) { return c * (7.5625 * t * t) + b; } - else if (t < (2/2.75)) { + else if (t < (2 / 2.75)) { return c * (7.5625 * (t -= (1.5 / 2.75)) * t + 0.75) + b; } - else if (t < (2.5/2.75)) { + else if (t < (2.5 / 2.75)) { return c * (7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375) + b; } else { @@ -2964,7 +2988,7 @@ if (typeof console !== 'undefined') { easeInOutBounce: easeInOutBounce }; -}()); +})(); (function(global) { @@ -3100,7 +3124,7 @@ if (typeof console !== 'undefined') { * @private */ function _getMultipleNodes(doc, nodeNames) { - var nodeName, nodeArray = [ ], nodeList; + var nodeName, nodeArray = [], nodeList; for (var i = 0; i < nodeNames.length; i++) { nodeName = nodeNames[i]; nodeList = doc.getElementsByTagName(nodeName); @@ -3215,7 +3239,7 @@ if (typeof console !== 'undefined') { // start with identity matrix var matrix = iMatrix.concat(), - matrices = [ ]; + matrices = []; // return if no argument was given or // an argument does not match transform attribute regexp @@ -3226,7 +3250,8 @@ if (typeof console !== 'undefined') { attributeValue.replace(reTransform, function(match) { var m = new RegExp(transform).exec(match).filter(function (match) { - return (match !== '' && match != null); + // match !== '' && match != null + return (!!match); }), operation = m[1], args = m.slice(2).map(parseFloat); @@ -3406,7 +3431,8 @@ if (typeof console !== 'undefined') { attr = attrs.item(j); el3.setAttribute(attr.nodeName, attr.nodeValue); } - while (el2.firstChild != null) { + // el2.firstChild != null + while (el2.firstChild) { el3.appendChild(el2.firstChild); } el2 = el3; @@ -3485,9 +3511,9 @@ if (typeof console !== 'undefined') { return parsedDim; } - minX = -parseFloat(viewBoxAttr[1]), - minY = -parseFloat(viewBoxAttr[2]), - viewBoxWidth = parseFloat(viewBoxAttr[3]), + minX = -parseFloat(viewBoxAttr[1]); + minY = -parseFloat(viewBoxAttr[2]); + viewBoxWidth = parseFloat(viewBoxAttr[3]); viewBoxHeight = parseFloat(viewBoxAttr[4]); if (!missingDimAttr) { @@ -3525,7 +3551,8 @@ if (typeof console !== 'undefined') { if (element.nodeName === 'svg') { el = element.ownerDocument.createElement('g'); - while (element.firstChild != null) { + // element.firstChild != null + while (element.firstChild) { el.appendChild(element.firstChild); } element.appendChild(el); @@ -3545,7 +3572,8 @@ if (typeof console !== 'undefined') { * @function * @memberOf fabric * @param {SVGDocument} doc SVG document to parse - * @param {Function} callback Callback to call when parsing is finished; It's being passed an array of elements (parsed from a document). + * @param {Function} callback Callback to call when parsing is finished; + * It's being passed an array of elements (parsed from a document). * @param {Function} [reviver] Method for further parsing of SVG elements, called after each fabric object created. */ fabric.parseSVGDocument = (function() { @@ -3578,7 +3606,7 @@ if (typeof console !== 'undefined') { // we're likely in node, where "o3-xml" library fails to gEBTN("*") // https://github.com/ajaxorg/node-o3-xml/issues/21 descendants = doc.selectNodes('//*[name(.)!="svg"]'); - var arr = [ ]; + var arr = []; for (var i = 0, len = descendants.length; i < len; i++) { arr[i] = descendants[i]; } @@ -3857,11 +3885,11 @@ if (typeof console !== 'undefined') { points = points.replace(/,/g, ' ').trim(); points = points.split(/\s+/); - var parsedPoints = [ ], i, len; + var parsedPoints = [], i, len; i = 0; len = points.length; - for (; i < len; i+=2) { + for (; i < len; i += 2) { parsedPoints.push({ x: parseFloat(points[i]), y: parseFloat(points[i + 1]) @@ -3903,8 +3931,8 @@ if (typeof console !== 'undefined') { rules.forEach(function(rule) { var match = rule.match(/([\s\S]*?)\s*\{([^}]*)\}/), - ruleObj = { }, declaration = match[2].trim(), - propertyValuePairs = declaration.replace(/;$/, '').split(/\s*;\s*/); + ruleObj = { }, declaration = match[2].trim(), + propertyValuePairs = declaration.replace(/;$/, '').split(/\s*;\s*/); for (var i = 0, len = propertyValuePairs.length; i < len; i++) { var pair = propertyValuePairs[i].split(/\s*:\s*/), @@ -3931,7 +3959,8 @@ if (typeof console !== 'undefined') { }, /** - * Takes url corresponding to an SVG document, and parses it into a set of fabric objects. Note that SVG is fetched via XMLHttpRequest, so it needs to conform to SOP (Same Origin Policy) + * Takes url corresponding to an SVG document, and parses it into a set of fabric objects. + * Note that SVG is fetched via XMLHttpRequest, so it needs to conform to SOP (Same Origin Policy) * @memberOf fabric * @param {String} url * @param {Function} callback @@ -4043,24 +4072,20 @@ if (typeof console !== 'undefined') { for (var j in fontList) { markup += [ - //jscs:disable validateIndentation '\t\t@font-face {\n', - '\t\t\tfont-family: \'', j, '\';\n', - '\t\t\tsrc: url(\'', fontPaths[j], '\');\n', + '\t\t\tfont-family: \'', j, '\';\n', + '\t\t\tsrc: url(\'', fontPaths[j], '\');\n', '\t\t}\n' - //jscs:enable validateIndentation ].join(''); } if (markup) { markup = [ - //jscs:disable validateIndentation '\t\n' - //jscs:enable validateIndentation ].join(''); } @@ -4073,7 +4098,7 @@ if (typeof console !== 'undefined') { * @return {String} */ createSVGRefElementsMarkup: function(canvas) { - var markup = [ ]; + var markup = []; _createSVGPattern(markup, canvas, 'backgroundColor'); _createSVGPattern(markup, canvas, 'overlayColor'); @@ -4103,9 +4128,9 @@ fabric.ElementsParser.prototype.parse = function() { fabric.ElementsParser.prototype.createObjects = function() { for (var i = 0, len = this.elements.length; i < len; i++) { this.elements[i].setAttribute('svgUid', this.svgUid); - (function(_this, i) { + (function(_obj, i) { setTimeout(function() { - _this.createObject(_this.elements[i], i); + _obj.createObject(_obj.elements[i], i); }, 0); })(this, i); } @@ -4167,6 +4192,7 @@ fabric.ElementsParser.prototype.resolveGradient = function(obj, property) { fabric.ElementsParser.prototype.checkIfDone = function() { if (--this.numElements === 0) { this.instances = this.instances.filter(function(el) { + // eslint-disable-next-line no-eq-null, eqeqeq return el != null; }); this.callback(this.instances); @@ -4618,8 +4644,8 @@ fabric.ElementsParser.prototype.checkIfDone = function() { b1, b2, inter; for (var i = 0; i < length; i++) { - b1 = points[i], - b2 = points[(i + 1) % length], + b1 = points[i]; + b2 = points[(i + 1) % length]; inter = Intersection.intersectLineLine(a1, a2, b1, b2); result.appendPoints(inter.points); @@ -4763,7 +4789,7 @@ fabric.ElementsParser.prototype.checkIfDone = function() { * @return {Array} Hsl color */ _rgbToHsl: function(r, g, b) { - r /= 255, g /= 255, b /= 255; + r /= 255; g /= 255; b /= 255; var h, s, l, max = fabric.util.array.max([r, g, b]), @@ -4954,6 +4980,7 @@ fabric.ElementsParser.prototype.checkIfDone = function() { * @field * @memberOf fabric.Color */ + // eslint-disable-next-line max-len fabric.Color.reRGBa = /^rgba?\(\s*(\d{1,3}(?:\.\d+)?\%?)\s*,\s*(\d{1,3}(?:\.\d+)?\%?)\s*,\s*(\d{1,3}(?:\.\d+)?\%?)\s*(?:\s*,\s*(\d+(?:\.\d+)?)\s*)?\)$/; /** @@ -5014,14 +5041,14 @@ fabric.ElementsParser.prototype.checkIfDone = function() { if (t > 1) { t -= 1; } - if (t < 1/6) { + if (t < 1 / 6) { return p + (q - p) * 6 * t; } - if (t < 1/2) { + if (t < 1 / 2) { return q; } - if (t < 2/3) { - return p + (q - p) * (2/3 - t) * 6; + if (t < 2 / 3) { + return p + (q - p) * (2 / 3 - t) * 6; } return p; } @@ -5104,9 +5131,9 @@ fabric.ElementsParser.prototype.checkIfDone = function() { var q = l <= 0.5 ? l * (s + 1) : l + s - l * s, p = l * 2 - q; - r = hue2rgb(p, q, h + 1/3); + r = hue2rgb(p, q, h + 1 / 3); g = hue2rgb(p, q, h); - b = hue2rgb(p, q, h - 1/3); + b = hue2rgb(p, q, h - 1 / 3); } return [ @@ -5373,41 +5400,35 @@ fabric.ElementsParser.prototype.checkIfDone = function() { } if (this.type === 'linear') { markup = [ - //jscs:disable validateIndentation '\n' - //jscs:enable validateIndentation ]; } else if (this.type === 'radial') { markup = [ - //jscs:disable validateIndentation '\n' - //jscs:enable validateIndentation ]; } for (var i = 0; i < this.colorStops.length; i++) { markup.push( - //jscs:disable validateIndentation '\n' - //jscs:enable validateIndentation ); } @@ -5603,7 +5624,7 @@ fabric.ElementsParser.prototype.checkIfDone = function() { gradientUnits === 'objectBoundingBox' && object.rx !== object.ry) { - var scaleFactor = object.ry/object.rx; + var scaleFactor = object.ry / object.rx; ellipseMatrix = ' scale(1, ' + scaleFactor + ')'; if (options.y1) { options.y1 /= scaleFactor; @@ -5872,7 +5893,7 @@ fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ */ _parseShadow: function(shadow) { var shadowStr = shadow.trim(), - offsetsAndBlur = fabric.Shadow.reOffsetsAndBlur.exec(shadowStr) || [ ], + offsetsAndBlur = fabric.Shadow.reOffsetsAndBlur.exec(shadowStr) || [], color = shadowStr.replace(fabric.Shadow.reOffsetsAndBlur, '') || 'rgb(0,0,0)'; return { @@ -5966,6 +5987,7 @@ fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ * @field * @memberOf fabric.Shadow */ + // eslint-disable-next-line max-len fabric.Shadow.reOffsetsAndBlur = /(?:\s|^)(-?\d+(?:px)?(?:\s?|$))?(-?\d+(?:px)?(?:\s?|$))?(\d+(?:px)?)?(?:\s?|$)(?:$|\s)/; })(typeof exports !== 'undefined' ? exports : this); @@ -6152,7 +6174,6 @@ fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ this._createLowerCanvas(el); this._initOptions(options); this._setImageSmoothing(); - // only initialize retina scaling once if (!this.interactive) { this._initRetinaScaling(); @@ -6195,7 +6216,6 @@ fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ if (!this._isRetinaScaling()) { return; } - this.lowerCanvasEl.setAttribute('width', this.width * fabric.devicePixelRatio); this.lowerCanvasEl.setAttribute('height', this.height * fabric.devicePixelRatio); @@ -6432,28 +6452,18 @@ fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ /** * @private */ - _createCanvasElement: function() { - var element = fabric.document.createElement('canvas'); + _createCanvasElement: function(canvasEl) { + var element = fabric.util.createCanvasElement(canvasEl) if (!element.style) { element.style = { }; } if (!element) { throw CANVAS_INIT_ERROR; } - this._initCanvasElement(element); - return element; - }, - - /** - * @private - * @param {HTMLElement} element - */ - _initCanvasElement: function(element) { - fabric.util.createCanvasElement(element); - if (typeof element.getContext === 'undefined') { throw CANVAS_INIT_ERROR; } + return element; }, /** @@ -6487,8 +6497,7 @@ fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ * @param {HTMLElement} [canvasEl] */ _createLowerCanvas: function (canvasEl) { - this.lowerCanvasEl = fabric.util.getById(canvasEl) || this._createCanvasElement(); - this._initCanvasElement(this.lowerCanvasEl); + this.lowerCanvasEl = fabric.util.getById(canvasEl) || this._createCanvasElement(canvasEl); fabric.util.addClass(this.lowerCanvasEl, 'lower-canvas'); @@ -6641,10 +6650,11 @@ fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ * @chainable true */ setViewportTransform: function (vpt) { - var activeGroup = this.getActiveGroup(); + var activeGroup = this._activeGroup, object; this.viewportTransform = vpt; for (var i = 0, len = this._objects.length; i < len; i++) { - this._objects[i].setCoords(); + object = this._objects[i]; + object.group || object.setCoords(); } if (activeGroup) { activeGroup.setCoords(); @@ -6717,22 +6727,6 @@ fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ return this.lowerCanvasEl; }, - /** - * Returns currently selected object, if any - * @return {fabric.Object} - */ - getActiveObject: function() { - return null; - }, - - /** - * Returns currently selected group of object, if any - * @return {fabric.Group} - */ - getActiveGroup: function() { - return null; - }, - /** * @private * @param {fabric.Object} obj Object that was added @@ -6752,6 +6746,7 @@ fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ _onObjectRemoved: function(obj) { this.fire('object:removed', { target: obj }); obj.fire('removed'); + delete obj.canvas; }, /** @@ -6780,6 +6775,10 @@ fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ */ clear: function () { this._objects.length = 0; + this.backgroundImage = null; + this.overlayImage = null; + this.backgroundColor = ''; + this.overlayColor = '' this.clearContext(this.contextContainer); this.fire('canvas:cleared'); this.renderAll(); @@ -6830,14 +6829,6 @@ fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ this.fire('after:render'); }, - /** - * dummy function for organization purpouse. - * @private - */ - drawControls: function() { - // NOOP - }, - /** * @private * @param {CanvasRenderingContext2D} ctx Context to render on @@ -7039,7 +7030,7 @@ fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ objects: this._toObjects(methodName, propertiesToInclude) }; - extend(data, this.__serializeBgOverlay()); + extend(data, this.__serializeBgOverlay(propertiesToInclude)); fabric.util.populateWithProperties(this, data, propertiesToInclude); @@ -7051,10 +7042,10 @@ fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ */ _toObjects: function(methodName, propertiesToInclude) { return this.getObjects().filter(function(object) { - return !object.excludeFromExport; - }).map(function(instance) { - return this._toObject(instance, methodName, propertiesToInclude); - }, this); + return !object.excludeFromExport; + }).map(function(instance) { + return this._toObject(instance, methodName, propertiesToInclude); + }, this); }, /** @@ -7068,76 +7059,33 @@ fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ instance.includeDefaultValues = false; } - //If the object is part of the current selection group, it should - //be transformed appropriately - //i.e. it should be serialised as it would appear if the selection group - //were to be destroyed. - var originalProperties = this._realizeGroupTransformOnObject(instance), - object = instance[methodName](propertiesToInclude); + var object = instance[methodName](propertiesToInclude); if (!this.includeDefaultValues) { instance.includeDefaultValues = originalValue; } - - //Undo the damage we did by changing all of its properties - this._unwindGroupTransformOnObject(instance, originalProperties); - return object; }, - /** - * Realises an object's group transformation on it - * @private - * @param {fabric.Object} [instance] the object to transform (gets mutated) - * @returns the original values of instance which were changed - */ - _realizeGroupTransformOnObject: function(instance) { - var layoutProps = ['angle', 'flipX', 'flipY', 'height', 'left', 'scaleX', 'scaleY', 'top', 'width']; - if (instance.group && instance.group === this.getActiveGroup()) { - //Copy all the positionally relevant properties across now - var originalValues = {}; - layoutProps.forEach(function(prop) { - originalValues[prop] = instance[prop]; - }); - this.getActiveGroup().realizeTransform(instance); - return originalValues; - } - else { - return null; - } - }, - - /** - * Restores the changed properties of instance - * @private - * @param {fabric.Object} [instance] the object to un-transform (gets mutated) - * @param {Object} [originalValues] the original values of instance, as returned by _realizeGroupTransformOnObject - */ - _unwindGroupTransformOnObject: function(instance, originalValues) { - if (originalValues) { - instance.set(originalValues); - } - }, - /** * @private */ - __serializeBgOverlay: function() { + __serializeBgOverlay: function(propertiesToInclude) { var data = { background: (this.backgroundColor && this.backgroundColor.toObject) - ? this.backgroundColor.toObject() + ? this.backgroundColor.toObject(propertiesToInclude) : this.backgroundColor }; if (this.overlayColor) { data.overlay = this.overlayColor.toObject - ? this.overlayColor.toObject() + ? this.overlayColor.toObject(propertiesToInclude) : this.overlayColor; } if (this.backgroundImage) { - data.backgroundImage = this.backgroundImage.toObject(); + data.backgroundImage = this.backgroundImage.toObject(propertiesToInclude); } if (this.overlayImage) { - data.overlayImage = this.overlayImage.toObject(); + data.overlayImage = this.overlayImage.toObject(propertiesToInclude); } return data; @@ -7275,20 +7223,24 @@ fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ * @private */ _setSVGObjects: function(markup, reviver) { - var instance, originalProperties; + var instance; for (var i = 0, objects = this.getObjects(), len = objects.length; i < len; i++) { instance = objects[i]; if (instance.excludeFromExport) { continue; } - //If the object is in a selection group, simulate what would happen to that - //object when the group is deselected - originalProperties = this._realizeGroupTransformOnObject(instance); - markup.push(instance.toSVG(reviver)); - this._unwindGroupTransformOnObject(instance, originalProperties); + this._setSVGObject(markup, instance, reviver); } }, + /** + * push single object svg representation in the markup + * @private + */ + _setSVGObject: function(markup, instance, reviver) { + markup.push(instance.toSVG(reviver)); + }, + /** * @private */ @@ -7340,7 +7292,7 @@ fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ if (!object) { return this; } - var activeGroup = this.getActiveGroup ? this.getActiveGroup() : null, + var activeGroup = this._activeGroup, i, obj, objs; if (object === activeGroup) { objs = activeGroup._objects; @@ -7368,7 +7320,7 @@ fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ if (!object) { return this; } - var activeGroup = this.getActiveGroup ? this.getActiveGroup() : null, + var activeGroup = this._activeGroup, i, obj, objs; if (object === activeGroup) { objs = activeGroup._objects; @@ -7396,7 +7348,7 @@ fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ if (!object) { return this; } - var activeGroup = this.getActiveGroup ? this.getActiveGroup() : null, + var activeGroup = this._activeGroup, i, obj, idx, newIdx, objs; if (object === activeGroup) { @@ -7464,7 +7416,7 @@ fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ if (!object) { return this; } - var activeGroup = this.getActiveGroup ? this.getActiveGroup() : null, + var activeGroup = this._activeGroup, i, obj, idx, newIdx, objs; if (object === activeGroup) { @@ -7645,14 +7597,14 @@ fabric.BaseBrush = fabric.util.createClass(/** @lends fabric.BaseBrush.prototype * @type String * @default */ - color: 'rgb(0, 0, 0)', + color: 'rgb(0, 0, 0)', /** * Width of a brush * @type Number * @default */ - width: 1, + width: 1, /** * Shadow object representing shadow of this shape. @@ -7661,28 +7613,28 @@ fabric.BaseBrush = fabric.util.createClass(/** @lends fabric.BaseBrush.prototype * @type fabric.Shadow * @default */ - shadow: null, + shadow: null, /** * Line endings style of a brush (one of "butt", "round", "square") * @type String * @default */ - strokeLineCap: 'round', + strokeLineCap: 'round', /** * Corner style of a brush (one of "bevil", "round", "miter") * @type String * @default */ - strokeLineJoin: 'round', + strokeLineJoin: 'round', /** * Stroke Dash Array. * @type Array * @default */ - strokeDashArray: null, + strokeDashArray: null, /** * Sets shadow of an object @@ -7757,7 +7709,7 @@ fabric.BaseBrush = fabric.util.createClass(/** @lends fabric.BaseBrush.prototype */ initialize: function(canvas) { this.canvas = canvas; - this._points = [ ]; + this._points = []; }, /** @@ -7907,15 +7859,15 @@ fabric.BaseBrush = fabric.util.createClass(/** @lends fabric.BaseBrush.prototype */ createPath: function(pathData) { var path = new fabric.Path(pathData, { - fill: null, - stroke: this.color, - strokeWidth: this.width, - strokeLineCap: this.strokeLineCap, - strokeLineJoin: this.strokeLineJoin, - strokeDashArray: this.strokeDashArray, - originX: 'center', - originY: 'center' - }); + fill: null, + stroke: this.color, + strokeWidth: this.width, + strokeLineCap: this.strokeLineCap, + strokeLineJoin: this.strokeLineJoin, + strokeDashArray: this.strokeDashArray, + originX: 'center', + originY: 'center' + }); if (this.shadow) { this.shadow.affectStroke = true; @@ -7980,7 +7932,7 @@ fabric.CircleBrush = fabric.util.createClass(fabric.BaseBrush, /** @lends fabric */ initialize: function(canvas) { this.canvas = canvas; - this.points = [ ]; + this.points = []; }, /** @@ -8028,7 +7980,7 @@ fabric.CircleBrush = fabric.util.createClass(fabric.BaseBrush, /** @lends fabric var originalRenderOnAddRemove = this.canvas.renderOnAddRemove; this.canvas.renderOnAddRemove = false; - var circles = [ ]; + var circles = []; for (var i = 0, len = this.points.length; i < len; i++) { var point = this.points[i], @@ -8136,7 +8088,7 @@ fabric.SprayBrush = fabric.util.createClass( fabric.BaseBrush, /** @lends fabric */ initialize: function(canvas) { this.canvas = canvas; - this.sprayChunks = [ ]; + this.sprayChunks = []; }, /** @@ -8168,7 +8120,7 @@ fabric.SprayBrush = fabric.util.createClass( fabric.BaseBrush, /** @lends fabric var originalRenderOnAddRemove = this.canvas.renderOnAddRemove; this.canvas.renderOnAddRemove = false; - var rects = [ ]; + var rects = []; for (var i = 0, ilen = this.sprayChunks.length; i < ilen; i++) { var sprayChunk = this.sprayChunks[i]; @@ -8221,7 +8173,7 @@ fabric.SprayBrush = fabric.util.createClass( fabric.BaseBrush, /** @lends fabric uniqueRects[key] = rects[i]; } } - var uniqueRectsArray = [ ]; + var uniqueRectsArray = []; for (key in uniqueRects) { uniqueRectsArray.push(uniqueRects[key]); } @@ -8254,7 +8206,7 @@ fabric.SprayBrush = fabric.util.createClass( fabric.BaseBrush, /** @lends fabric * @param {Object} pointer */ addSprayChunk: function(pointer) { - this.sprayChunkPoints = [ ]; + this.sprayChunkPoints = []; var x, y, width, radius = this.width / 2; @@ -8356,6 +8308,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab radiansToDegrees = fabric.util.radiansToDegrees, atan2 = Math.atan2, abs = Math.abs, + supportLineDash = fabric.StaticCanvas.supports('setLineDash'), STROKE_OFFSET = 0.5; @@ -8469,13 +8422,23 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab /** * Indicates which key enable multiple click selection - * values: altKey, shiftKey, ctrlKey + * values: altKey, shiftKey, ctrlKey, cmdKey * @since 1.6.2 * @type String * @default */ selectionKey: 'shiftKey', + /** + * Indicates which key enable alternative selection + * in case of target overlapping with active object + * values: altKey, shiftKey, ctrlKey, cmdKey + * @since 1.6.5 + * @type null|String + * @default + */ + altSelectionKey: null, + /** * Color of selection * @type String @@ -8488,7 +8451,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab * If not empty the selection border is dashed * @type Array */ - selectionDashArray: [ ], + selectionDashArray: [], /** * Color of the border of selection (usually slightly darker than color of selection itself) @@ -8578,12 +8541,29 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab isDrawingMode: false, /** - * Indicates whether objects should remain in current stack position when selected. When false objects are brought to top and rendered as part of the selection group + * Indicates whether objects should remain in current stack position when selected. + * When false objects are brought to top and rendered as part of the selection group * @type Boolean * @default */ preserveObjectStacking: false, + /** + * Indicates if the right click on canvas can output the context menu or not + * @type Boolean + * @since 1.6.5 + * @default + */ + stopContextMenu: false, + + /** + * Indicates if the canvas can fire right click events + * @type Boolean + * @since 1.6.5 + * @default + */ + fireRightClick: false, + /** * @private */ @@ -8609,7 +8589,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab _chooseObjectsToRender: function() { var activeGroup = this.getActiveGroup(), activeObject = this.getActiveObject(), - object, objsToRender = [ ], activeGroupObjects = [ ]; + object, objsToRender = [], activeGroupObjects = []; if ((activeGroup || activeObject) && !this.preserveObjectStacking) { for (var i = 0, length = this._objects.length; i < length; i++) { @@ -8748,7 +8728,6 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab vptPointer = this.restorePointerVpt(pointer), p = fabric.util.transformPoint(vptPointer, invertedM); return fabric.util.transformPoint(p, vpt); - //return { x: p.x * vpt[0], y: p.y * vpt[3] }; }, /** @@ -9018,8 +8997,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab actualMouseByOrigin, constraintPosition, dim = target._getTransformedDimensions(); this._changeSkewTransformOrigin(actualMouseByCenter - lastMouseByCenter, t, by); - actualMouseByOrigin = target.toLocalPoint(new fabric.Point(x, y), t.originX, t.originY)[by], - + actualMouseByOrigin = target.toLocalPoint(new fabric.Point(x, y), t.originX, t.originY)[by]; constraintPosition = target.translateToOriginPoint(center, t.originX, t.originY); // Actually skew the object skewed = this._setObjectSkew(actualMouseByOrigin, t, by, dim); @@ -9306,23 +9284,28 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab aleft = abs(left), atop = abs(top); - ctx.fillStyle = this.selectionColor; + if (this.selectionColor) { + ctx.fillStyle = this.selectionColor; - ctx.fillRect( - groupSelector.ex - ((left > 0) ? 0 : -left), - groupSelector.ey - ((top > 0) ? 0 : -top), - aleft, - atop - ); + ctx.fillRect( + groupSelector.ex - ((left > 0) ? 0 : -left), + groupSelector.ey - ((top > 0) ? 0 : -top), + aleft, + atop + ); + } + if (!this.selectionLineWidth || !this.selectionBorderColor) { + return; + } ctx.lineWidth = this.selectionLineWidth; ctx.strokeStyle = this.selectionBorderColor; // selection border - if (this.selectionDashArray.length > 1) { + if (this.selectionDashArray.length > 1 && !supportLineDash) { - var px = groupSelector.ex + STROKE_OFFSET - ((left > 0) ? 0: aleft), - py = groupSelector.ey + STROKE_OFFSET - ((top > 0) ? 0: atop); + var px = groupSelector.ex + STROKE_OFFSET - ((left > 0) ? 0 : aleft), + py = groupSelector.ey + STROKE_OFFSET - ((top > 0) ? 0 : atop); ctx.beginPath(); @@ -9335,6 +9318,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab ctx.stroke(); } else { + fabric.Object.prototype._setLineDash.call(this, ctx, this.selectionDashArray); ctx.strokeRect( groupSelector.ex + STROKE_OFFSET - ((left > 0) ? 0 : aleft), groupSelector.ey + STROKE_OFFSET - ((top > 0) ? 0 : atop), @@ -9357,22 +9341,37 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab var ignoreZoom = true, pointer = this.getPointer(e, ignoreZoom), activeGroup = this.getActiveGroup(), - activeObject = this.getActiveObject(); + activeObject = this.getActiveObject(), + activeTarget; // first check current group (if one exists) // active group does not check sub targets like normal groups. // if active group just exits. if (activeGroup && !skipGroup && this._checkTarget(pointer, activeGroup)) { + this._fireOverOutEvents(activeGroup, e); return activeGroup; } - - if (activeObject && this._checkTarget(pointer, activeObject)) { + // if we hit the corner of an activeObject, let's return that. + if (activeObject && activeObject._findTargetCorner(pointer)) { + this._fireOverOutEvents(activeObject, e); return activeObject; } + if (activeObject && this._checkTarget(pointer, activeObject)) { + if (!this.preserveObjectStacking) { + this._fireOverOutEvents(activeObject, e); + return activeObject; + } + else { + activeTarget = activeObject; + } + } - this.targets = [ ]; + this.targets = []; var target = this._searchPossibleTargets(this._objects, pointer); + if (e[this.altSelectionKey] && target && activeTarget && target !== activeTarget) { + target = activeTarget; + } this._fireOverOutEvents(target, e); return target; }, @@ -9820,6 +9819,66 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab } }, + /** + * @private + */ + _toObject: function(instance, methodName, propertiesToInclude) { + //If the object is part of the current selection group, it should + //be transformed appropriately + //i.e. it should be serialised as it would appear if the selection group + //were to be destroyed. + var originalProperties = this._realizeGroupTransformOnObject(instance), + object = this.callSuper('_toObject', instance, methodName, propertiesToInclude); + //Undo the damage we did by changing all of its properties + this._unwindGroupTransformOnObject(instance, originalProperties); + return object; + }, + + /** + * Realises an object's group transformation on it + * @private + * @param {fabric.Object} [instance] the object to transform (gets mutated) + * @returns the original values of instance which were changed + */ + _realizeGroupTransformOnObject: function(instance) { + var layoutProps = ['angle', 'flipX', 'flipY', 'height', 'left', 'scaleX', 'scaleY', 'top', 'width']; + if (instance.group && instance.group === this.getActiveGroup()) { + //Copy all the positionally relevant properties across now + var originalValues = {}; + layoutProps.forEach(function(prop) { + originalValues[prop] = instance[prop]; + }); + this.getActiveGroup().realizeTransform(instance); + return originalValues; + } + else { + return null; + } + }, + + /** + * Restores the changed properties of instance + * @private + * @param {fabric.Object} [instance] the object to un-transform (gets mutated) + * @param {Object} [originalValues] the original values of instance, as returned by _realizeGroupTransformOnObject + */ + _unwindGroupTransformOnObject: function(instance, originalValues) { + if (originalValues) { + instance.set(originalValues); + } + }, + + /** + * @private + */ + _setSVGObject: function(markup, instance, reviver) { + var originalProperties; + //If the object is in a selection group, simulate what would happen to that + //object when the group is deselected + originalProperties = this._realizeGroupTransformOnObject(instance); + this.callSuper('_setSVGObject', markup, instance, reviver); + this._unwindGroupTransformOnObject(instance, originalProperties); + }, }); // copying static properties manually to work around Opera's bug, @@ -9849,17 +9908,17 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab (function() { var cursorOffset = { - mt: 0, // n - tr: 1, // ne - mr: 2, // e - br: 3, // se - mb: 4, // s - bl: 5, // sw - ml: 6, // w - tl: 7 // nw - }, - addListener = fabric.util.addListener, - removeListener = fabric.util.removeListener; + mt: 0, // n + tr: 1, // ne + mr: 2, // e + br: 3, // se + mb: 4, // s + bl: 5, // sw + ml: 6, // w + tl: 7 // nw + }, + addListener = fabric.util.addListener, + removeListener = fabric.util.removeListener; fabric.util.object.extend(fabric.Canvas.prototype, /** @lends fabric.Canvas.prototype */ { @@ -9893,6 +9952,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab addListener(this.upperCanvasEl, 'mousemove', this._onMouseMove); addListener(this.upperCanvasEl, 'mouseout', this._onMouseOut); addListener(this.upperCanvasEl, 'wheel', this._onMouseWheel); + addListener(this.upperCanvasEl, 'contextmenu', this._onContextMenu); // touch events addListener(this.upperCanvasEl, 'touchstart', this._onMouseDown); @@ -9922,6 +9982,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab this._onOrientationChange = this._onOrientationChange.bind(this); this._onMouseWheel = this._onMouseWheel.bind(this); this._onMouseOut = this._onMouseOut.bind(this); + this._onContextMenu = this._onContextMenu.bind(this); }, /** @@ -9934,6 +9995,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab removeListener(this.upperCanvasEl, 'mousemove', this._onMouseMove); removeListener(this.upperCanvasEl, 'mouseout', this._onMouseOut); removeListener(this.upperCanvasEl, 'wheel', this._onMouseWheel); + removeListener(this.upperCanvasEl, 'contextmenu', this._onContextMenu); removeListener(this.upperCanvasEl, 'touchstart', this._onMouseDown); removeListener(this.upperCanvasEl, 'touchmove', this._onMouseMove); @@ -10011,6 +10073,18 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab this.__onLongPress && this.__onLongPress(e, self); }, + /** + * @private + * @param {Event} e Event object fired on mousedown + */ + _onContextMenu: function (e) { + if (this.stopContextMenu) { + e.stopPropagation() + e.preventDefault(); + } + return false; + }, + /** * @private * @param {Event} e Event object fired on mousedown @@ -10166,7 +10240,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab */ _handleEvent: function(e, eventType, targetObj) { var target = typeof targetObj === undefined ? this.findTarget(e) : targetObj, - targets = this.targets || [ ], + targets = this.targets || [], options = { e: e, target: target, subTargets: targets }; this.fire('mouse:' + eventType, options); @@ -10271,9 +10345,12 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab */ __onMouseDown: function (e) { - // accept only left clicks - var isLeftClick = 'which' in e ? e.which === 1 : e.button === 0; - if (!isLeftClick && !fabric.isTouchSupported) { + // if right click just fire events + var isRightClick = 'which' in e ? e.which === 3 : e.button === 2; + if (isRightClick) { + if (this.fireRightClick) { + this._handleEvent(e, 'down', target ? target : null); + } return; } @@ -10316,7 +10393,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab } } this._handleEvent(e, 'down', target ? target : null); - // we must renderAll so that active image is placed on the top canvas + // we must renderAll so that we update the visuals shouldRender && this.renderAll(); }, @@ -10452,7 +10529,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab var pointer = this.getPointer(e), transform = this._currentTransform; - transform.reset = false, + transform.reset = false; transform.target.isMoving = true; this._beforeScaleTransform(e, transform); @@ -10726,8 +10803,8 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab var objects = this.getObjects(), isActiveLower = objects.indexOf(this._activeObject) < objects.indexOf(target), groupObjects = isActiveLower - ? [ this._activeObject, target ] - : [ target, this._activeObject ]; + ? [this._activeObject, target] + : [target, this._activeObject]; this._activeObject.isEditing && this._activeObject.exitEditing(); return new fabric.Group(groupObjects, { canvas: this @@ -10762,7 +10839,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab * @private */ _collectObjects: function() { - var group = [ ], + var group = [], currentObject, x1 = this._groupSelector.ex, y1 = this._groupSelector.ey, @@ -10821,223 +10898,130 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab })(); -fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.StaticCanvas.prototype */ { +(function () { - /** - * Exports canvas element to a dataurl image. Note that when multiplier is used, cropping is scaled appropriately - * @param {Object} [options] Options object - * @param {String} [options.format=png] The format of the output image. Either "jpeg" or "png" - * @param {Number} [options.quality=1] Quality level (0..1). Only used for jpeg. - * @param {Number} [options.multiplier=1] Multiplier to scale by - * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14 - * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14 - * @param {Number} [options.width] Cropping width. Introduced in v1.2.14 - * @param {Number} [options.height] Cropping height. Introduced in v1.2.14 - * @return {String} Returns a data: URL containing a representation of the object in the format specified by options.format - * @see {@link http://jsfiddle.net/fabricjs/NfZVb/|jsFiddle demo} - * @example Generate jpeg dataURL with lower quality - * var dataURL = canvas.toDataURL({ - * format: 'jpeg', - * quality: 0.8 - * }); - * @example Generate cropped png dataURL (clipping of canvas) - * var dataURL = canvas.toDataURL({ - * format: 'png', - * left: 100, - * top: 100, - * width: 200, - * height: 200 - * }); - * @example Generate double scaled png dataURL - * var dataURL = canvas.toDataURL({ - * format: 'png', - * multiplier: 2 - * }); - */ - toDataURL: function (options) { - options || (options = { }); + var supportQuality = fabric.StaticCanvas.supports('toDataURLWithQuality'); - var format = options.format || 'png', - quality = options.quality || 1, - multiplier = options.multiplier || 1, - cropping = { - left: options.left, - top: options.top, - width: options.width, - height: options.height - }; + fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.StaticCanvas.prototype */ { - if (this._isRetinaScaling()) { - multiplier *= fabric.devicePixelRatio; - } + /** + * Exports canvas element to a dataurl image. Note that when multiplier is used, cropping is scaled appropriately + * @param {Object} [options] Options object + * @param {String} [options.format=png] The format of the output image. Either "jpeg" or "png" + * @param {Number} [options.quality=1] Quality level (0..1). Only used for jpeg. + * @param {Number} [options.multiplier=1] Multiplier to scale by + * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14 + * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14 + * @param {Number} [options.width] Cropping width. Introduced in v1.2.14 + * @param {Number} [options.height] Cropping height. Introduced in v1.2.14 + * @return {String} Returns a data: URL containing a representation of the object in the format specified by options.format + * @see {@link http://jsfiddle.net/fabricjs/NfZVb/|jsFiddle demo} + * @example Generate jpeg dataURL with lower quality + * var dataURL = canvas.toDataURL({ + * format: 'jpeg', + * quality: 0.8 + * }); + * @example Generate cropped png dataURL (clipping of canvas) + * var dataURL = canvas.toDataURL({ + * format: 'png', + * left: 100, + * top: 100, + * width: 200, + * height: 200 + * }); + * @example Generate double scaled png dataURL + * var dataURL = canvas.toDataURL({ + * format: 'png', + * multiplier: 2 + * }); + */ + toDataURL: function (options) { + options || (options = { }); - if (multiplier !== 1) { + var format = options.format || 'png', + quality = options.quality || 1, + multiplier = options.multiplier || 1, + cropping = { + left: options.left || 0, + top: options.top || 0, + width: options.width || 0, + height: options.height || 0, + }; return this.__toDataURLWithMultiplier(format, quality, cropping, multiplier); - } - else { - return this.__toDataURL(format, quality, cropping); - } - }, + }, - /** - * @private - */ - __toDataURL: function(format, quality, cropping) { + /** + * @private + */ + __toDataURLWithMultiplier: function(format, quality, cropping, multiplier) { - this.renderAll(); + var origWidth = this.getWidth(), + origHeight = this.getHeight(), + scaledWidth = (cropping.width || this.getWidth()) * multiplier, + scaledHeight = (cropping.width || this.getHeight()) * multiplier, + zoom = this.getZoom(), + newZoom = zoom * multiplier, + vp = this.viewportTransform, + translateX = (vp[4] - cropping.left) * multiplier, + translateY = (vp[5] - cropping.top) * multiplier, + newVp = [newZoom, 0, 0, newZoom, translateX, translateY], + originalInteractive = this.interactive; - var canvasEl = this.contextContainer.canvas, - croppedCanvasEl = this.__getCroppedCanvas(canvasEl, cropping); + this.viewportTransform = newVp; + // setting interactive to false avoid exporting controls + this.interactive && (this.interactive = false); + if (origWidth !== scaledWidth || origHeight !== scaledHeight) { + // this.setDimensions is going to renderAll also; + this.setDimensions({ width: scaledWidth, height: scaledHeight }); + } + else { + this.renderAll(); + } + var data = this.__toDataURL(format, quality, cropping); + originalInteractive && (this.interactive = originalInteractive); + this.viewportTransform = vp; + //setDimensions with no option object is taking care of: + //this.width, this.height, this.renderAll() + this.setDimensions({ width: origWidth, height: origHeight }); + return data; + }, - // to avoid common confusion https://github.com/kangax/fabric.js/issues/806 - if (format === 'jpg') { - format = 'jpeg'; - } + /** + * @private + */ + __toDataURL: function(format, quality) { - var data = (fabric.StaticCanvas.supports('toDataURLWithQuality')) - ? (croppedCanvasEl || canvasEl).toDataURL('image/' + format, quality) - : (croppedCanvasEl || canvasEl).toDataURL('image/' + format); + var canvasEl = this.contextContainer.canvas; + // to avoid common confusion https://github.com/kangax/fabric.js/issues/806 + if (format === 'jpg') { + format = 'jpeg'; + } - if (croppedCanvasEl) { - croppedCanvasEl = null; - } + var data = supportQuality + ? canvasEl.toDataURL('image/' + format, quality) + : canvasEl.toDataURL('image/' + format); - return data; - }, + return data; + }, - /** - * @private - */ - __getCroppedCanvas: function(canvasEl, cropping) { + /** + * Exports canvas element to a dataurl image (allowing to change image size via multiplier). + * @deprecated since 1.0.13 + * @param {String} format (png|jpeg) + * @param {Number} multiplier + * @param {Number} quality (0..1) + * @return {String} + */ + toDataURLWithMultiplier: function (format, multiplier, quality) { + return this.toDataURL({ + format: format, + multiplier: multiplier, + quality: quality + }); + }, + }); - var croppedCanvasEl, - croppedCtx, - shouldCrop = 'left' in cropping || - 'top' in cropping || - 'width' in cropping || - 'height' in cropping; - - if (shouldCrop) { - - croppedCanvasEl = fabric.util.createCanvasElement(); - croppedCtx = croppedCanvasEl.getContext('2d'); - - croppedCanvasEl.width = cropping.width || this.width; - croppedCanvasEl.height = cropping.height || this.height; - - croppedCtx.drawImage(canvasEl, -cropping.left || 0, -cropping.top || 0); - } - - return croppedCanvasEl; - }, - - /** - * @private - */ - __toDataURLWithMultiplier: function(format, quality, cropping, multiplier) { - - var origWidth = this.getWidth(), - origHeight = this.getHeight(), - scaledWidth = origWidth * multiplier, - scaledHeight = origHeight * multiplier, - activeObject = this.getActiveObject(), - activeGroup = this.getActiveGroup(), - zoom = this.getZoom(), - newZoom = zoom * multiplier / fabric.devicePixelRatio; - - if (multiplier > 1) { - this.setDimensions({ width: scaledWidth, height: scaledHeight }); - } - - this.setZoom(newZoom); - - if (cropping.left) { - cropping.left *= multiplier; - } - if (cropping.top) { - cropping.top *= multiplier; - } - if (cropping.width) { - cropping.width *= multiplier; - } - else if (multiplier < 1) { - cropping.width = scaledWidth; - } - if (cropping.height) { - cropping.height *= multiplier; - } - else if (multiplier < 1) { - cropping.height = scaledHeight; - } - - if (activeGroup) { - // not removing group due to complications with restoring it with correct state afterwords - this._tempRemoveBordersControlsFromGroup(activeGroup); - } - else if (activeObject && this.deactivateAll) { - this.deactivateAll(); - } - - var data = this.__toDataURL(format, quality, cropping); - if (activeGroup) { - this._restoreBordersControlsOnGroup(activeGroup); - } - else if (activeObject && this.setActiveObject) { - this.setActiveObject(activeObject); - } - this.setZoom(zoom); - //setDimensions with no option object is taking care of: - //this.width, this.height, this.renderAll() - this.setDimensions({ width: origWidth, height: origHeight }); - - return data; - }, - - /** - * Exports canvas element to a dataurl image (allowing to change image size via multiplier). - * @deprecated since 1.0.13 - * @param {String} format (png|jpeg) - * @param {Number} multiplier - * @param {Number} quality (0..1) - * @return {String} - */ - toDataURLWithMultiplier: function (format, multiplier, quality) { - return this.toDataURL({ - format: format, - multiplier: multiplier, - quality: quality - }); - }, - - /** - * @private - */ - _tempRemoveBordersControlsFromGroup: function(group) { - group.origHasControls = group.hasControls; - group.origBorderColor = group.borderColor; - - group.hasControls = true; - group.borderColor = 'rgba(0,0,0,0)'; - - group.forEachObject(function(o) { - o.origBorderColor = o.borderColor; - o.borderColor = 'rgba(0,0,0,0)'; - }); - }, - - /** - * @private - */ - _restoreBordersControlsOnGroup: function(group) { - group.hideControls = group.origHideControls; - group.borderColor = group.origBorderColor; - - group.forEachObject(function(o) { - o.borderColor = o.origBorderColor; - delete o.origBorderColor; - }); - } -}); +})(); fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.StaticCanvas.prototype */ { @@ -12040,7 +12024,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati 'top left width height scaleX scaleY flipX flipY originX originY transformMatrix ' + 'stroke strokeWidth strokeDashArray strokeLineCap strokeLineJoin strokeMiterLimit ' + 'angle opacity fill fillRule globalCompositeOperation shadow clipTo visible backgroundColor ' + - 'alignX alignY meetOrSlice skewX skewY' + 'skewX skewY' ).split(' '), /** @@ -12299,7 +12283,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati this[key] = value; if (key === 'width' || key === 'height') { - this.minScaleLimit = Math.min(0.1, 1/Math.max(this.width, this.height)); + this.minScaleLimit = Math.min(0.1, 1 / Math.max(this.width, this.height)); } return this; @@ -12372,13 +12356,14 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati if (!noTransform) { this.transform(ctx); } + this._setOpacity(ctx); + this._setShadow(ctx); + this._renderBackground(ctx); this._setStrokeStyles(ctx); this._setFillStyles(ctx); if (this.transformMatrix) { ctx.transform.apply(ctx, this.transformMatrix); } - this._setOpacity(ctx); - this._setShadow(ctx); this.clipTo && fabric.util.clipContext(this, ctx); this._render(ctx, noTransform); this.clipTo && ctx.restore(); @@ -12386,6 +12371,29 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati ctx.restore(); }, + /** + * Draws a background for the object big as its width and height; + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _renderBackground: function(ctx) { + if (!this.backgroundColor) { + return; + } + + ctx.fillStyle = this.backgroundColor; + + ctx.fillRect( + -this.width / 2, + -this.height / 2, + this.width, + this.height + ); + // if there is background color no other shadows + // should be casted + this._removeShadow(ctx); + }, + /** * @private * @param {CanvasRenderingContext2D} ctx Context to render on @@ -12567,7 +12575,8 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati }, /** - * Clones an instance + * Clones an instance, some objects are async, so using callback method will work for every object. + * Using the direct return does not work for images and groups. * @param {Function} callback Callback is invoked with a clone as a first argument * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output * @return {fabric.Object} clone of an instance @@ -12617,10 +12626,8 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati el.width = boundingRect.width; el.height = boundingRect.height; - fabric.util.wrapElement(el, 'div'); var canvas = new fabric.StaticCanvas(el, { enableRetinaScaling: options.enableRetinaScaling }); - // to avoid common confusion https://github.com/kangax/fabric.js/issues/806 if (options.format === 'jpg') { options.format = 'jpeg'; @@ -13289,7 +13296,9 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati getCoords(other.oCoords) ); - return intersection.status === 'Intersection'; + return intersection.status === 'Intersection' + || other.isContainedWithinObject(this) + || this.isContainedWithinObject(other); }, /** @@ -13298,11 +13307,14 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati * @return {Boolean} true if object is fully contained within area of another object */ isContainedWithinObject: function(other) { - var boundingRect = other.getBoundingRect(), - point1 = new fabric.Point(boundingRect.left, boundingRect.top), - point2 = new fabric.Point(boundingRect.left + boundingRect.width, boundingRect.top + boundingRect.height); - - return this.isContainedWithinRect(point1, point2); + var points = getCoords(this.oCoords), + i = 0; + for (; i < 4; i++) { + if (!other.containsPoint(points[i])) { + return false; + } + } + return true; }, /** @@ -13371,8 +13383,9 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati * @param {fabric.Point} point Point to check * @param {Object} oCoords Coordinates of the object being evaluated */ + // remove yi, not used but left code here just in case. _findCrossPoints: function(point, oCoords) { - var b1, b2, a1, a2, xi, yi, + var b1, b2, a1, a2, xi, // yi, xcount = 0, iLine; @@ -13389,7 +13402,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati // optimisation 3: vertical line case if ((iLine.o.x === iLine.d.x) && (iLine.o.x >= point.x)) { xi = iLine.o.x; - yi = point.y; + // yi = point.y; } // calculate the intersection point else { @@ -13398,8 +13411,8 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati a1 = point.y - b1 * point.x; a2 = iLine.o.y - b2 * iLine.o.x; - xi = - (a1 - a2) / (b1 - b2); - yi = a1 + b1 * xi; + xi = -(a1 - a2) / (b1 - b2); + // yi = a1 + b1 * xi; } // dont count xi < point.x cases if (xi >= point.x) { @@ -13555,10 +13568,10 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati tr = new fabric.Point(tl.x + (currentWidth * cosTh), tl.y + (currentWidth * sinTh)), bl = new fabric.Point(tl.x - (currentHeight * sinTh), tl.y + (currentHeight * cosTh)), br = new fabric.Point(coords.x + offsetX, coords.y + offsetY), - ml = new fabric.Point((tl.x + bl.x)/2, (tl.y + bl.y)/2), - mt = new fabric.Point((tr.x + tl.x)/2, (tr.y + tl.y)/2), - mr = new fabric.Point((br.x + tr.x)/2, (br.y + tr.y)/2), - mb = new fabric.Point((br.x + bl.x)/2, (br.y + bl.y)/2), + ml = new fabric.Point((tl.x + bl.x) / 2, (tl.y + bl.y) / 2), + mt = new fabric.Point((tr.x + tl.x) / 2, (tr.y + tl.y) / 2), + mr = new fabric.Point((br.x + tr.x) / 2, (br.y + tr.y) / 2), + mb = new fabric.Point((br.x + bl.x) / 2, (br.y + bl.y) / 2), mtr = new fabric.Point(mt.x + sinTh * this.rotatingPointOffset, mt.y - cosTh * this.rotatingPointOffset); // debugging @@ -13590,6 +13603,10 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati return this; }, + /* + * calculate rotation matrix of an object + * @return {Array} rotation matrix for the object + */ _calcRotateMatrix: function() { if (this.angle) { var theta = degreesToRadians(this.angle), cos = Math.cos(theta), sin = Math.sin(theta); @@ -13846,7 +13863,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot * @private */ _createBaseSVGMarkup: function() { - var markup = [ ]; + var markup = []; if (this.fill && this.fill.toLive) { markup.push(this.fill.toSVG(this, false)); @@ -13864,60 +13881,89 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot /* _TO_SVG_END_ */ -/* - Depends on `stateProperties` -*/ -fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ { +(function() { - /** - * Returns true if object state (one of its state properties) was changed - * @return {Boolean} true if instance' state has changed since `{@link fabric.Object#saveState}` was called - */ - hasStateChanged: function() { - return this.stateProperties.some(function(prop) { - return this.get(prop) !== this.originalState[prop]; - }, this); - }, + var extend = fabric.util.object.extend; - /** - * Saves state of an object - * @param {Object} [options] Object with additional `stateProperties` array to include when saving state - * @return {fabric.Object} thisArg - */ - saveState: function(options) { - this.stateProperties.forEach(function(prop) { - this.originalState[prop] = this.get(prop); - }, this); - - if (options && options.stateProperties) { - options.stateProperties.forEach(function(prop) { - this.originalState[prop] = this.get(prop); - }, this); - } - - return this; - }, - - /** - * Setups state of an object - * @return {fabric.Object} thisArg - */ - setupState: function() { - this.originalState = { }; - this.saveState(); - - return this; + /* + Depends on `stateProperties` + */ + function saveProps(origin, destination, props) { + var tmpObj = { }, deep = true; + props.forEach(function(prop) { + tmpObj[prop] = origin[prop]; + }); + extend(origin[destination], tmpObj, deep); } -}); + + function _isEqual(origValue, currentValue) { + if (origValue instanceof Array) { + if (origValue.length !== currentValue.length) { + return false + } + var _currentValue = currentValue.concat().sort(), + _origValue = origValue.concat().sort(); + return !_origValue.some(function(v, i) { + return !_isEqual(_currentValue[i], v); + }); + } + else if (origValue instanceof Object) { + for (var key in origValue) { + if (!_isEqual(origValue[key], currentValue[key])) { + return false; + } + } + return true; + } + else { + return origValue === currentValue; + } + } + + + fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ { + + /** + * Returns true if object state (one of its state properties) was changed + * @return {Boolean} true if instance' state has changed since `{@link fabric.Object#saveState}` was called + */ + hasStateChanged: function() { + return !_isEqual(this.originalState, this); + }, + + /** + * Saves state of an object + * @param {Object} [options] Object with additional `stateProperties` array to include when saving state + * @return {fabric.Object} thisArg + */ + saveState: function(options) { + saveProps(this, 'originalState', this.stateProperties); + if (options && options.stateProperties) { + saveProps(this, 'originalState', options.stateProperties); + } + return this; + }, + + /** + * Setups state of an object + * @param {Object} [options] Object with additional `stateProperties` array to include when saving state + * @return {fabric.Object} thisArg + */ + setupState: function(options) { + this.originalState = { }; + this.saveState(options); + return this; + } + }); +})(); (function() { var degreesToRadians = fabric.util.degreesToRadians, - //jscs:disable requireCamelCaseOrUpperCaseIdentifiers + /* eslint-disable camelcase */ isVML = function() { return typeof G_vmlCanvasManager !== 'undefined'; }; - //jscs:enable requireCamelCaseOrUpperCaseIdentifiers - + /* eslint-enable camelcase */ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ { /** @@ -14059,24 +14105,24 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot skewY = this.skewY; } var dimensions = this._getNonTransformedDimensions(), - dimX = dimensions.x /2, dimY = dimensions.y / 2, + dimX = dimensions.x / 2, dimY = dimensions.y / 2, points = [ - { - x: -dimX, - y: -dimY - }, - { - x: dimX, - y: -dimY - }, - { - x: -dimX, - y: dimY - }, - { - x: dimX, - y: dimY - }], + { + x: -dimX, + y: -dimY + }, + { + x: dimX, + y: -dimY + }, + { + x: -dimX, + y: dimY + }, + { + x: dimX, + y: dimY + }], i, transformMatrix = this._calcDimensionsTransformMatrix(skewX, skewY, false), bbox; for (i = 0; i < points.length; i++) { @@ -14107,8 +14153,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot * @chainable */ drawSelectionBackground: function(ctx) { - if (!this.selectionBackgroundColor || this.group - || this !== this.canvas.getActiveObject()) { + if (!this.selectionBackgroundColor || this.group || !this.active) { return this; } ctx.save(); @@ -14118,7 +14163,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot ctx.scale(1 / vpt[0], 1 / vpt[3]); ctx.rotate(degreesToRadians(this.angle)); ctx.fillStyle = this.selectionBackgroundColor; - ctx.fillRect(-wh.x/2, -wh.y/2, wh.x, wh.y); + ctx.fillRect(-wh.x / 2, -wh.y / 2, wh.x, wh.y); ctx.restore(); return this; }, @@ -14255,23 +14300,23 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot // middle-top this._drawControl('mt', ctx, methodName, - left + width/2, + left + width / 2, top); // middle-bottom this._drawControl('mb', ctx, methodName, - left + width/2, + left + width / 2, top + height); // middle-right this._drawControl('mr', ctx, methodName, left + width, - top + height/2); + top + height / 2); // middle-left this._drawControl('ml', ctx, methodName, left, - top + height/2); + top + height / 2); } // middle-top-rotate @@ -14297,7 +14342,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot switch (this.cornerStyle) { case 'circle': ctx.beginPath(); - ctx.arc(left + size/2, top + size/2, size/2, 0, 2 * Math.PI, false); + ctx.arc(left + size / 2, top + size / 2, size / 2, 0, 2 * Math.PI, false); ctx[methodName](); if (stroke) { ctx.stroke(); @@ -14522,7 +14567,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot */ animate: function() { if (arguments[0] && typeof arguments[0] === 'object') { - var propsToAnimate = [ ], prop, skipCallbacks; + var propsToAnimate = [], prop, skipCallbacks; for (prop in arguments[0]) { propsToAnimate.push(prop); } @@ -14910,11 +14955,14 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot * @static * @memberOf fabric.Line * @param {Object} object Object to create an instance from + * @param {function} [callback] invoked with new instance as first argument * @return {fabric.Line} instance of fabric.Line */ - fabric.Line.fromObject = function(object) { - var points = [object.x1, object.y1, object.x2, object.y2]; - return new fabric.Line(points, object); + fabric.Line.fromObject = function(object, callback) { + var points = [object.x1, object.y1, object.x2, object.y2], + line = new fabric.Line(points, object); + callback && callback(line); + return line; }; /** @@ -14931,12 +14979,12 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot return function() { switch (this.get(origin)) { - case nearest: - return Math.min(this.get(axis1), this.get(axis2)); - case center: - return Math.min(this.get(axis1), this.get(axis2)) + (0.5 * this.get(dimension)); - case farthest: - return Math.max(this.get(axis1), this.get(axis2)); + case nearest: + return Math.min(this.get(axis1), this.get(axis2)); + case center: + return Math.min(this.get(axis1), this.get(axis2)) + (0.5 * this.get(dimension)); + case farthest: + return Math.max(this.get(axis1), this.get(axis2)); } }; @@ -15046,7 +15094,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot */ toSVG: function(reviver) { var markup = this._createBaseSVGMarkup(), x = 0, y = 0, - angle = (this.endAngle - this.startAngle) % ( 2 * pi); + angle = (this.endAngle - this.startAngle) % ( 2 * pi); if (angle === 0) { if (this.group && this.group.type === 'path-group') { @@ -15073,7 +15121,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot markup.push( '\n' - //jscs:enable validateIndentation ); return reviver ? reviver(markup.join('')) : markup.join(''); @@ -16737,8 +16799,8 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot * @private */ _parsePath: function() { - var result = [ ], - coords = [ ], + var result = [], + coords = [], currentPath, parsed, re = /([-+]?((\d+\.\d+)|((\d+)|(\.\d+)))(?:e[-+]?\d+)?)/ig, @@ -16755,7 +16817,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot coords.push(match[0]); } - coordsParsed = [ currentPath.charAt(0) ]; + coordsParsed = [currentPath.charAt(0)]; for (var j = 0, jlen = coords.length; j < jlen; j++) { parsed = parseFloat(coords[j]); @@ -16770,7 +16832,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot if (coordsParsed.length - 1 > commandLength) { for (var k = 1, klen = coordsParsed.length; k < klen; k += commandLength) { - result.push([ command ].concat(coordsParsed.slice(k, k + commandLength))); + result.push([command].concat(coordsParsed.slice(k, k + commandLength))); command = repeatedCommand; } } @@ -16810,33 +16872,33 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot case 'l': // lineto, relative x += current[1]; y += current[2]; - bounds = [ ]; + bounds = []; break; case 'L': // lineto, absolute x = current[1]; y = current[2]; - bounds = [ ]; + bounds = []; break; case 'h': // horizontal lineto, relative x += current[1]; - bounds = [ ]; + bounds = []; break; case 'H': // horizontal lineto, absolute x = current[1]; - bounds = [ ]; + bounds = []; break; case 'v': // vertical lineto, relative y += current[1]; - bounds = [ ]; + bounds = []; break; case 'V': // verical lineto, absolute y = current[1]; - bounds = [ ]; + bounds = []; break; case 'm': // moveTo, relative @@ -16844,7 +16906,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot y += current[2]; subpathStartX = x; subpathStartY = y; - bounds = [ ]; + bounds = []; break; case 'M': // moveTo, absolute @@ -16852,7 +16914,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot y = current[2]; subpathStartX = x; subpathStartY = y; - bounds = [ ]; + bounds = []; break; case 'c': // bezierCurveTo, relative @@ -17112,24 +17174,27 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot * @static * @memberOf fabric.Path * @param {Object} object - * @param {Function} callback Callback to invoke when an fabric.Path instance is created + * @param {Function} [callback] Callback to invoke when an fabric.Path instance is created */ fabric.Path.fromObject = function(object, callback) { + // remove this pattern rom 2.0, accept just object. + var path; if (typeof object.path === 'string') { fabric.loadSVGFromURL(object.path, function (elements) { - var path = elements[0], - pathUrl = object.path; - + var pathUrl = object.path; + path = elements[0]; delete object.path; fabric.util.object.extend(path, object); path.setSourcePath(pathUrl); - callback(path); + callback && callback(path); }); } else { - callback(new fabric.Path(object.path, object)); + path = new fabric.Path(object.path, object); + callback && callback(path); + return path; } }; @@ -17214,7 +17279,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot initialize: function(paths, options) { options = options || { }; - this.paths = paths || [ ]; + this.paths = paths || []; for (var i = this.paths.length; i--;) { this.paths[i].group = this; @@ -17236,7 +17301,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot * Calculate width and height based on paths contained */ parseDimensionsFromPaths: function(options) { - var points, p, xC = [ ], yC = [ ], path, height, width, + var points, p, xC = [], yC = [], path, height, width, m; for (var j = this.paths.length; j--;) { path = this.paths[j]; @@ -17281,7 +17346,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot this._setShadow(ctx); this.clipTo && fabric.util.clipContext(this, ctx); - ctx.translate(-this.width/2, -this.height/2); + ctx.translate(-this.width / 2, -this.height / 2); for (var i = 0, l = this.paths.length; i < l; ++i) { this.paths[i].render(ctx, true); } @@ -17411,9 +17476,10 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot * @static * @memberOf fabric.PathGroup * @param {Object} object Object to create an instance from - * @param {Function} callback Callback to invoke when an fabric.PathGroup instance is created + * @param {Function} [callback] Callback to invoke when an fabric.PathGroup instance is created */ fabric.PathGroup.fromObject = function(object, callback) { + // remove this pattern from 2.0 accepts only object if (typeof object.paths === 'string') { fabric.loadSVGFromURL(object.paths, function (elements) { @@ -17971,7 +18037,6 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot * @memberOf fabric.Group * @param {Object} object Object to create a group from * @param {Function} [callback] Callback to invoke when an group instance is created - * @return {fabric.Group} An instance of fabric.Group */ fabric.Group.fromObject = function(object, callback) { fabric.util.enlivenObjects(object.objects, function(enlivenedObjects) { @@ -18007,6 +18072,13 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot return; } + var stateProperties = fabric.Object.prototype.stateProperties.concat(); + stateProperties.push( + 'alignX', + 'alignY', + 'meetOrSlice' + ); + /** * Image class * @class fabric.Image @@ -18091,6 +18163,14 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot */ minimumScaleTrigger: 0.5, + /** + * List of properties to consider when checking if + * state of an object is changed ({@link fabric.Object#hasStateChanged}) + * as well as for history (undo/redo) purposes + * @type Array + */ + stateProperties: stateProperties, + /** * Constructor * @param {HTMLImageElement | String} element Image element @@ -18100,8 +18180,8 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot */ initialize: function(element, options, callback) { options || (options = { }); - this.filters = [ ]; - this.resizeFilters = [ ]; + this.filters = []; + this.resizeFilters = []; this.callSuper('initialize', options); this._initElement(element, options, callback); }, @@ -18222,7 +18302,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot * @return {Object} Object representation of an instance */ toObject: function(propertiesToInclude) { - var filters = [ ], resizeFilters = [ ], + var filters = [], resizeFilters = [], scaleX = 1, scaleY = 1; this.filters.forEach(function(filterObj) { @@ -18267,7 +18347,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot */ toSVG: function(reviver) { var markup = this._createBaseSVGMarkup(), x = -this.width / 2, y = -this.height / 2, - preserveAspectRatio = 'none'; + preserveAspectRatio = 'none', filtered = true; if (this.group && this.group.type === 'path-group') { x = this.left; y = this.top; @@ -18277,7 +18357,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot } markup.push( '\n', - ''; }, - /** - * Returns a clone of an instance - * @param {Function} callback Callback is invoked with a clone as a first argument - * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output - */ - clone: function(callback, propertiesToInclude) { - this.constructor.fromObject(this.toObject(propertiesToInclude), callback); - }, - /** * Applies filters assigned to this image (from "filters" array) * @method applyFilters @@ -18608,14 +18680,14 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot * Creates an instance of fabric.Image from its object representation * @static * @param {Object} object Object to create an instance from - * @param {Function} [callback] Callback to invoke when an image instance is created + * @param {Function} callback Callback to invoke when an image instance is created */ fabric.Image.fromObject = function(object, callback) { fabric.util.loadImage(object.src, function(img) { fabric.Image.prototype._initFilters.call(object, object.filters, function(filters) { - object.filters = filters || [ ]; + object.filters = filters || []; fabric.Image.prototype._initFilters.call(object, object.resizeFilters, function(resizeFilters) { - object.resizeFilters = resizeFilters || [ ]; + object.resizeFilters = resizeFilters || []; return new fabric.Image(img, object, callback); }); }); @@ -18841,7 +18913,9 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag 'use strict'; var fabric = global.fabric || (global.fabric = { }), - extend = fabric.util.object.extend; + extend = fabric.util.object.extend, + filters = fabric.Image.filters, + createClass = fabric.util.createClass; /** * Brightness filter class @@ -18857,7 +18931,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag * object.filters.push(filter); * object.applyFilters(canvas.renderAll.bind(canvas)); */ - fabric.Image.filters.Brightness = fabric.util.createClass(fabric.Image.filters.BaseFilter, /** @lends fabric.Image.filters.Brightness.prototype */ { + filters.Brightness = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Brightness.prototype */ { /** * Filter type @@ -18925,7 +18999,9 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag 'use strict'; var fabric = global.fabric || (global.fabric = { }), - extend = fabric.util.object.extend; + extend = fabric.util.object.extend, + filters = fabric.Image.filters, + createClass = fabric.util.createClass; /** * Adapted from html5rocks article @@ -18968,7 +19044,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag * object.filters.push(filter); * object.applyFilters(canvas.renderAll.bind(canvas)); */ - fabric.Image.filters.Convolute = fabric.util.createClass(fabric.Image.filters.BaseFilter, /** @lends fabric.Image.filters.Convolute.prototype */ { + filters.Convolute = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Convolute.prototype */ { /** * Filter type @@ -19006,7 +19082,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag pixels = context.getImageData(0, 0, canvasEl.width, canvasEl.height), side = Math.round(Math.sqrt(weights.length)), - halfSide = Math.floor(side/2), + halfSide = Math.floor(side / 2), src = pixels.data, sw = pixels.width, sh = pixels.height, @@ -19029,7 +19105,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag scy = y + cy - halfSide; scx = x + cx - halfSide; - /* jshint maxdepth:5 */ + // eslint-disable-next-line max-depth if (scy < 0 || scy > sh || scx < 0 || scx > sw) { continue; } @@ -19083,7 +19159,9 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag 'use strict'; var fabric = global.fabric || (global.fabric = { }), - extend = fabric.util.object.extend; + extend = fabric.util.object.extend, + filters = fabric.Image.filters, + createClass = fabric.util.createClass; /** * GradientTransparency filter class @@ -19099,7 +19177,8 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag * object.filters.push(filter); * object.applyFilters(canvas.renderAll.bind(canvas)); */ - fabric.Image.filters.GradientTransparency = fabric.util.createClass(fabric.Image.filters.BaseFilter, /** @lends fabric.Image.filters.GradientTransparency.prototype */ { + // eslint-disable-next-line max-len + filters.GradientTransparency = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.GradientTransparency.prototype */ { /** * Filter type @@ -19165,7 +19244,9 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag 'use strict'; - var fabric = global.fabric || (global.fabric = { }); + var fabric = global.fabric || (global.fabric = { }), + filters = fabric.Image.filters, + createClass = fabric.util.createClass; /** * Grayscale image filter class @@ -19178,7 +19259,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag * object.filters.push(filter); * object.applyFilters(canvas.renderAll.bind(canvas)); */ - fabric.Image.filters.Grayscale = fabric.util.createClass(fabric.Image.filters.BaseFilter, /** @lends fabric.Image.filters.Grayscale.prototype */ { + filters.Grayscale = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Grayscale.prototype */ { /** * Filter type @@ -19228,7 +19309,9 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag 'use strict'; - var fabric = global.fabric || (global.fabric = { }); + var fabric = global.fabric || (global.fabric = { }), + filters = fabric.Image.filters, + createClass = fabric.util.createClass; /** * Invert filter class @@ -19241,7 +19324,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag * object.filters.push(filter); * object.applyFilters(canvas.renderAll.bind(canvas)); */ - fabric.Image.filters.Invert = fabric.util.createClass(fabric.Image.filters.BaseFilter, /** @lends fabric.Image.filters.Invert.prototype */ { + filters.Invert = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Invert.prototype */ { /** * Filter type @@ -19261,7 +19344,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag data = imageData.data, iLen = data.length, i; - for (i = 0; i < iLen; i+=4) { + for (i = 0; i < iLen; i += 4) { data[i] = 255 - data[i]; data[i + 1] = 255 - data[i + 1]; data[i + 2] = 255 - data[i + 2]; @@ -19288,7 +19371,9 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag 'use strict'; var fabric = global.fabric || (global.fabric = { }), - extend = fabric.util.object.extend; + extend = fabric.util.object.extend, + filters = fabric.Image.filters, + createClass = fabric.util.createClass; /** * Mask filter class @@ -19298,7 +19383,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag * @extends fabric.Image.filters.BaseFilter * @see {@link fabric.Image.filters.Mask#initialize} for constructor definition */ - fabric.Image.filters.Mask = fabric.util.createClass(fabric.Image.filters.BaseFilter, /** @lends fabric.Image.filters.Mask.prototype */ { + filters.Mask = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Mask.prototype */ { /** * Filter type @@ -19318,7 +19403,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag options = options || { }; this.mask = options.mask; - this.channel = [ 0, 1, 2, 3 ].indexOf(options.channel) > -1 ? options.channel : 0; + this.channel = [0, 1, 2, 3].indexOf(options.channel) > -1 ? options.channel : 0; }, /** @@ -19395,7 +19480,9 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag 'use strict'; var fabric = global.fabric || (global.fabric = { }), - extend = fabric.util.object.extend; + extend = fabric.util.object.extend, + filters = fabric.Image.filters, + createClass = fabric.util.createClass; /** * Noise filter class @@ -19411,7 +19498,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag * object.filters.push(filter); * object.applyFilters(canvas.renderAll.bind(canvas)); */ - fabric.Image.filters.Noise = fabric.util.createClass(fabric.Image.filters.BaseFilter, /** @lends fabric.Image.filters.Noise.prototype */ { + filters.Noise = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Noise.prototype */ { /** * Filter type @@ -19482,7 +19569,9 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag 'use strict'; var fabric = global.fabric || (global.fabric = { }), - extend = fabric.util.object.extend; + extend = fabric.util.object.extend, + filters = fabric.Image.filters, + createClass = fabric.util.createClass; /** * Pixelate filter class @@ -19498,7 +19587,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag * object.filters.push(filter); * object.applyFilters(canvas.renderAll.bind(canvas)); */ - fabric.Image.filters.Pixelate = fabric.util.createClass(fabric.Image.filters.BaseFilter, /** @lends fabric.Image.filters.Pixelate.prototype */ { + filters.Pixelate = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Pixelate.prototype */ { /** * Filter type @@ -19594,7 +19683,9 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag 'use strict'; var fabric = global.fabric || (global.fabric = { }), - extend = fabric.util.object.extend; + extend = fabric.util.object.extend, + filters = fabric.Image.filters, + createClass = fabric.util.createClass; /** * Remove white filter class @@ -19611,7 +19702,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag * object.filters.push(filter); * object.applyFilters(canvas.renderAll.bind(canvas)); */ - fabric.Image.filters.RemoveWhite = fabric.util.createClass(fabric.Image.filters.BaseFilter, /** @lends fabric.Image.filters.RemoveWhite.prototype */ { + filters.RemoveWhite = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.RemoveWhite.prototype */ { /** * Filter type @@ -19695,7 +19786,9 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag 'use strict'; - var fabric = global.fabric || (global.fabric = { }); + var fabric = global.fabric || (global.fabric = { }), + filters = fabric.Image.filters, + createClass = fabric.util.createClass; /** * Sepia filter class @@ -19708,7 +19801,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag * object.filters.push(filter); * object.applyFilters(canvas.renderAll.bind(canvas)); */ - fabric.Image.filters.Sepia = fabric.util.createClass(fabric.Image.filters.BaseFilter, /** @lends fabric.Image.filters.Sepia.prototype */ { + filters.Sepia = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Sepia.prototype */ { /** * Filter type @@ -19728,7 +19821,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag data = imageData.data, iLen = data.length, i, avg; - for (i = 0; i < iLen; i+=4) { + for (i = 0; i < iLen; i += 4) { avg = 0.3 * data[i] + 0.59 * data[i + 1] + 0.11 * data[i + 2]; data[i] = avg + 100; data[i + 1] = avg + 50; @@ -19755,7 +19848,9 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag 'use strict'; - var fabric = global.fabric || (global.fabric = { }); + var fabric = global.fabric || (global.fabric = { }), + filters = fabric.Image.filters, + createClass = fabric.util.createClass; /** * Sepia2 filter class @@ -19768,7 +19863,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag * object.filters.push(filter); * object.applyFilters(canvas.renderAll.bind(canvas)); */ - fabric.Image.filters.Sepia2 = fabric.util.createClass(fabric.Image.filters.BaseFilter, /** @lends fabric.Image.filters.Sepia2.prototype */ { + filters.Sepia2 = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Sepia2.prototype */ { /** * Filter type @@ -19788,7 +19883,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag data = imageData.data, iLen = data.length, i, r, g, b; - for (i = 0; i < iLen; i+=4) { + for (i = 0; i < iLen; i += 4) { r = data[i]; g = data[i + 1]; b = data[i + 2]; @@ -19819,7 +19914,9 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag 'use strict'; var fabric = global.fabric || (global.fabric = { }), - extend = fabric.util.object.extend; + extend = fabric.util.object.extend, + filters = fabric.Image.filters, + createClass = fabric.util.createClass; /** * Tint filter class @@ -19843,7 +19940,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag * object.filters.push(filter); * object.applyFilters(canvas.renderAll.bind(canvas)); */ - fabric.Image.filters.Tint = fabric.util.createClass(fabric.Image.filters.BaseFilter, /** @lends fabric.Image.filters.Tint.prototype */ { + filters.Tint = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Tint.prototype */ { /** * Filter type @@ -19889,7 +19986,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag alpha1 = 1 - this.opacity; - for (i = 0; i < iLen; i+=4) { + for (i = 0; i < iLen; i += 4) { r = data[i]; g = data[i + 1]; b = data[i + 2]; @@ -19933,7 +20030,9 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag 'use strict'; var fabric = global.fabric || (global.fabric = { }), - extend = fabric.util.object.extend; + extend = fabric.util.object.extend, + filters = fabric.Image.filters, + createClass = fabric.util.createClass; /** * Multiply filter class @@ -19954,7 +20053,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag * object.filters.push(filter); * object.applyFilters(canvas.renderAll.bind(canvas)); */ - fabric.Image.filters.Multiply = fabric.util.createClass(fabric.Image.filters.BaseFilter, /** @lends fabric.Image.filters.Multiply.prototype */ { + filters.Multiply = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Multiply.prototype */ { /** * Filter type @@ -19988,7 +20087,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag source = new fabric.Color(this.color).getSource(); - for (i = 0; i < iLen; i+=4) { + for (i = 0; i < iLen; i += 4) { data[i] *= source[0] / 255; data[i + 1] *= source[1] / 255; data[i + 2] *= source[2] / 255; @@ -20024,7 +20123,9 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag (function(global) { 'use strict'; - var fabric = global.fabric; + var fabric = global.fabric, + filters = fabric.Image.filters, + createClass = fabric.util.createClass; /** * Color Blend filter class @@ -20046,7 +20147,8 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag * object.filters.push(filter); * object.applyFilters(canvas.renderAll.bind(canvas)); */ - fabric.Image.filters.Blend = fabric.util.createClass(fabric.Image.filters.BaseFilter, /** @lends fabric.Image.filters.Blend.prototype */{ + + filters.Blend = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Blend.prototype */ { type: 'Blend', initialize: function(options) { @@ -20174,7 +20276,9 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag var fabric = global.fabric || (global.fabric = { }), pow = Math.pow, floor = Math.floor, sqrt = Math.sqrt, abs = Math.abs, max = Math.max, round = Math.round, sin = Math.sin, - ceil = Math.ceil; + ceil = Math.ceil, + filters = fabric.Image.filters, + createClass = fabric.util.createClass; /** * Resize image filter class @@ -20187,7 +20291,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag * object.filters.push(filter); * object.applyFilters(canvas.renderAll.bind(canvas)); */ - fabric.Image.filters.Resize = fabric.util.createClass(fabric.Image.filters.BaseFilter, /** @lends fabric.Image.filters.Resize.prototype */ { + filters.Resize = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Resize.prototype */ { /** * Filter type @@ -20351,7 +20455,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag for (v = 0; v < dH; v++) { center.y = (v + 0.5) * ratioY; icenter.y = floor(center.y); - a = 0, red = 0, green = 0, blue = 0, alpha = 0; + a = 0; red = 0; green = 0; blue = 0; alpha = 0; for (i = icenter.x - range2X; i <= icenter.x + range2X; i++) { if (i < 0 || i >= oW) { continue; @@ -20472,7 +20576,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag for (var xx = floor(i * ratioW); xx < (i + 1) * ratioW; xx++) { var dx = abs(centerX - (xx + 0.5)) / ratioWHalf, w = sqrt(w0 + dx * dx); - /*jshint maxdepth:5 */ + /* eslint-disable max-depth */ if (w > 1 && w < -1) { continue; } @@ -20484,17 +20588,15 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag gxA += weight * data[dx + 3]; weightsAlpha += weight; //colors - /*jshint maxdepth:6 */ if (data[dx + 3] < 255) { weight = weight * data[dx + 3] / 250; } - /*jshint maxdepth:5 */ gxR += weight * data[dx]; gxG += weight * data[dx + 1]; gxB += weight * data[dx + 2]; weights += weight; } - /*jshint maxdepth:4 */ + /* eslint-enable max-depth */ } } data2[x2] = gxR / weights; @@ -20538,7 +20640,9 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag 'use strict'; var fabric = global.fabric || (global.fabric = { }), - extend = fabric.util.object.extend; + extend = fabric.util.object.extend, + filters = fabric.Image.filters, + createClass = fabric.util.createClass; /** * Color Matrix filter class @@ -20561,7 +20665,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag * object.filters.push(filter); * object.applyFilters(canvas.renderAll.bind(canvas)); */ - fabric.Image.filters.ColorMatrix = fabric.util.createClass(fabric.Image.filters.BaseFilter, /** @lends fabric.Image.filters.ColorMatrix.prototype */ { + filters.ColorMatrix = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.ColorMatrix.prototype */ { /** * Filter type @@ -20579,11 +20683,11 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag initialize: function( options ) { options || ( options = {} ); this.matrix = options.matrix || [ - 1, 0, 0, 0, 0, - 0, 1, 0, 0, 0, - 0, 0, 1, 0, 0, - 0, 0, 0, 1, 0 - ]; + 1, 0, 0, 0, 0, + 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, + 0, 0, 0, 1, 0 + ]; }, /** @@ -20592,15 +20696,15 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag */ applyTo: function( canvasEl ) { var context = canvasEl.getContext( '2d' ), - imageData = context.getImageData( 0, 0, canvasEl.width, canvasEl.height ), - data = imageData.data, - iLen = data.length, - i, - r, - g, - b, - a, - m = this.matrix; + imageData = context.getImageData( 0, 0, canvasEl.width, canvasEl.height ), + data = imageData.data, + iLen = data.length, + i, + r, + g, + b, + a, + m = this.matrix; for ( i = 0; i < iLen; i += 4 ) { r = data[ i ]; @@ -20650,7 +20754,8 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag extend = fabric.util.object.extend, clone = fabric.util.object.clone, toFixed = fabric.util.toFixed, - NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS; + NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS, + MIN_TEXT_WIDTH = 2; if (fabric.Text) { fabric.warn('fabric.Text is already defined'); @@ -20694,7 +20799,6 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag text: true, charSpacing: true, textAlign: true, - stroke: false, strokeWidth: false, }, @@ -21004,7 +21108,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag } this._textLines = this._splitTextIntoLines(); this._clearCache(); - this.width = this._getTextWidth(ctx); + this.width = this._getTextWidth(ctx) || this.cursorWidth || MIN_TEXT_WIDTH; this.height = this._getTextHeight(ctx); }, @@ -21279,32 +21383,10 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag * @param {CanvasRenderingContext2D} ctx Context to render on */ _renderTextBackground: function(ctx) { - this._renderTextBoxBackground(ctx); + this._renderBackground(ctx); this._renderTextLinesBackground(ctx); }, - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _renderTextBoxBackground: function(ctx) { - if (!this.backgroundColor) { - return; - } - - ctx.fillStyle = this.backgroundColor; - - ctx.fillRect( - this._getLeftOffset(), - this._getTopOffset(), - this.width, - this.height - ); - // if there is background color no other shadows - // should be casted - this._removeShadow(ctx); - }, - /** * @private * @param {CanvasRenderingContext2D} ctx Context to render on @@ -21355,8 +21437,8 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag * @private */ _clearCache: function() { - this.__lineWidths = [ ]; - this.__lineHeights = [ ]; + this.__lineWidths = []; + this.__lineHeights = []; }, /** @@ -21450,8 +21532,8 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag for (i = 0, len = _this._textLines.length; i < len; i++) { - lineWidth = _this._getLineWidth(ctx, i), - lineLeftOffset = _this._getLineLeftOffset(lineWidth), + lineWidth = _this._getLineWidth(ctx, i); + lineLeftOffset = _this._getLineLeftOffset(lineWidth); heightOfLine = _this._getHeightOfLine(ctx, i); for (j = 0, oLen = offsets.length; j < oLen; j++) { @@ -21489,7 +21571,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag (fabric.isLikelyNode ? this.fontWeight : this.fontStyle), (fabric.isLikelyNode ? this.fontStyle : this.fontWeight), this.fontSize + 'px', - '"' + this.fontFamily + '"' + (fabric.isLikelyNode ? ('"' + this.fontFamily + '"') : this.fontFamily) ].join(' '); }, @@ -21601,11 +21683,11 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag style, '>\n', textAndBg.textBgRects.join(''), '\t\t\n', textAndBg.textSpans.join(''), '\t\t\n', @@ -21620,8 +21702,8 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag * @return {Object} */ _getSVGTextAndBg: function(textTopOffset, textLeftOffset) { - var textSpans = [ ], - textBgRects = [ ], + var textSpans = [], + textBgRects = [], height = 0; // bounding-box background this._setSVGBg(textBgRects); @@ -21869,10 +21951,13 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag * @static * @memberOf fabric.Text * @param {Object} object Object to create an instance from + * @param {Function} [callback] Callback to invoke when an fabric.Text instance is created * @return {fabric.Text} Instance of fabric.Text */ - fabric.Text.fromObject = function(object) { - return new fabric.Text(object.text, clone(object)); + fabric.Text.fromObject = function(object, callback) { + var text = new fabric.Text(object.text, clone(object)); + callback && callback(text); + return text; }; fabric.util.createAccessors(fabric.Text); @@ -22047,7 +22132,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag /** * @private */ - __widthOfSpace: [ ], + __widthOfSpace: [], /** * Constructor @@ -22066,7 +22151,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag */ _clearCache: function() { this.callSuper('_clearCache'); - this.__widthOfSpace = [ ]; + this.__widthOfSpace = []; }, /** @@ -22080,7 +22165,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag for (var p1 in obj) { for (var p2 in obj[p1]) { - /*jshint unused:false */ + // eslint-disable-next-line no-unused-vars for (var p3 in obj[p1][p2]) { return false; } @@ -22138,7 +22223,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag getSelectionStyles: function(startIndex, endIndex) { if (arguments.length === 2) { - var styles = [ ]; + var styles = []; for (var i = startIndex; i < endIndex; i++) { styles.push(this.getSelectionStyles(i)); } @@ -22400,7 +22485,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag ctx.globalAlpha = this.__isMousedown ? 1 : this._currentCursorOpacity; ctx.fillRect( - boundaries.left + leftOffset - cursorWidth/2, + boundaries.left + leftOffset - cursorWidth / 2, boundaries.top + boundaries.topOffset, cursorWidth, charHeight); @@ -22770,6 +22855,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag styleDeclaration.scaleX = this.scaleX; styleDeclaration.scaleY = this.scaleY; styleDeclaration.canvas = this.canvas; + styleDeclaration.getObjectScaling = this.getObjectScaling; this._setShadow.call(styleDeclaration, ctx); } @@ -23021,10 +23107,13 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag * @static * @memberOf fabric.IText * @param {Object} object Object to create an instance from + * @param {function} [callback] invoked with new instance as argument * @return {fabric.IText} instance of fabric.IText */ - fabric.IText.fromObject = function(object) { - return new fabric.IText(object.text, clone(object)); + fabric.IText.fromObject = function(object, callback) { + var iText = new fabric.IText(object.text, clone(object)); + callback && callback(iText); + return iText; }; })(); @@ -23527,6 +23616,10 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag p.y = maxHeight; } + // add canvas offset on document + p.x += this.canvas._offset.left; + p.y += this.canvas._offset.top; + return { left: p.x + 'px', top: p.y + 'px', fontSize: charHeight }; }, @@ -23855,6 +23948,58 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag */ insertNewline: function() { this.insertChars('\n'); + }, + + /** + * Set the selectionStart and selectionEnd according to the ne postion of cursor + * mimic the key - mouse navigation when shift is pressed. + */ + setSelectionStartEndWithShift: function(start, end, newSelection) { + if (newSelection <= start) { + if (end === start) { + this._selectionDirection = 'left'; + } + else if (this._selectionDirection === 'right') { + this._selectionDirection = 'left'; + this.selectionEnd = start; + } + this.selectionStart = newSelection; + } + else if (newSelection > start && newSelection < end) { + if (this._selectionDirection === 'right') { + this.selectionEnd = newSelection; + } + else { + this.selectionStart = newSelection; + } + } + else { + // newSelection is > selection start and end + if (end === start) { + this._selectionDirection = 'right'; + } + else if (this._selectionDirection === 'left') { + this._selectionDirection = 'right'; + this.selectionStart = end; + } + this.selectionEnd = newSelection; + } + }, + + setSelectionInBoundaries: function() { + var length = this.text.length; + if (this.selectionStart > length) { + this.selectionStart = length; + } + else if (this.selectionStart < 0) { + this.selectionStart = 0; + } + if (this.selectionEnd > length) { + this.selectionEnd = length; + } + else if (this.selectionEnd < 0) { + this.selectionEnd = 0; + } } }); })(); @@ -24007,20 +24152,14 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot * @param {Event} e Event object */ setCursorByClick: function(e) { - var newSelectionStart = this.getSelectionStartFromPointer(e); - + var newSelection = this.getSelectionStartFromPointer(e), + start = this.selectionStart, end = this.selectionEnd; if (e.shiftKey) { - if (newSelectionStart < this.selectionStart) { - this.selectionEnd = this.selectionStart; - this.selectionStart = newSelectionStart; - } - else { - this.selectionEnd = newSelectionStart; - } + this.setSelectionStartEndWithShift(start, end, newSelection); } else { - this.selectionStart = newSelectionStart; - this.selectionEnd = newSelectionStart; + this.selectionStart = newSelection; + this.selectionEnd = newSelection; } this._fireSelectionChanged(); this._updateTextarea(); @@ -24359,6 +24498,25 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot return (e && e.clipboardData) || fabric.window.clipboardData; }, + /** + * Finds the width in pixels before the cursor on the same line + * @private + * @param {Number} lineIndex + * @param {Number} charIndex + * @return {Number} widthBeforeCursor width before cursor + */ + _getWidthBeforeCursor: function(lineIndex, charIndex) { + var textBeforeCursor = this._textLines[lineIndex].slice(0, charIndex), + widthOfLine = this._getLineWidth(this.ctx, lineIndex), + widthBeforeCursor = this._getLineLeftOffset(widthOfLine), _char; + + for (var i = 0, len = textBeforeCursor.length; i < len; i++) { + _char = textBeforeCursor[i]; + widthBeforeCursor += this._getWidthOfChar(this.ctx, _char, lineIndex, i); + } + return widthBeforeCursor; + }, + /** * Gets start offset of a selection * @param {Event} e Event object @@ -24366,64 +24524,89 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot * @return {Number} */ getDownCursorOffset: function(e, isRight) { - var selectionProp = isRight ? this.selectionEnd : this.selectionStart, + var selectionProp = this._getSelectionForOffset(e, isRight), cursorLocation = this.get2DCursorLocation(selectionProp), - _char, lineLeftOffset, lineIndex = cursorLocation.lineIndex, - textOnSameLineBeforeCursor = this._textLines[lineIndex].slice(0, cursorLocation.charIndex), - textOnSameLineAfterCursor = this._textLines[lineIndex].slice(cursorLocation.charIndex), - textOnNextLine = this._textLines[lineIndex + 1] || ''; - + lineIndex = cursorLocation.lineIndex; // if on last line, down cursor goes to end of line if (lineIndex === this._textLines.length - 1 || e.metaKey || e.keyCode === 34) { - // move to the end of a text return this.text.length - selectionProp; } + var charIndex = cursorLocation.charIndex, + widthBeforeCursor = this._getWidthBeforeCursor(lineIndex, charIndex), + indexOnOtherLine = this._getIndexOnLine(lineIndex + 1, widthBeforeCursor), + textAfterCursor = this._textLines[lineIndex].slice(charIndex); - var widthOfSameLineBeforeCursor = this._getLineWidth(this.ctx, lineIndex); - lineLeftOffset = this._getLineLeftOffset(widthOfSameLineBeforeCursor); - - var widthOfCharsOnSameLineBeforeCursor = lineLeftOffset; - - for (var i = 0, len = textOnSameLineBeforeCursor.length; i < len; i++) { - _char = textOnSameLineBeforeCursor[i]; - widthOfCharsOnSameLineBeforeCursor += this._getWidthOfChar(this.ctx, _char, lineIndex, i); - } - - var indexOnNextLine = this._getIndexOnNextLine( - cursorLocation, textOnNextLine, widthOfCharsOnSameLineBeforeCursor); - - return textOnSameLineAfterCursor.length + 1 + indexOnNextLine; + return textAfterCursor.length + indexOnOtherLine + 2; }, /** + * private + * Helps finding if the offset should be counted from Start or End + * @param {Event} e Event object + * @param {Boolean} isRight + * @return {Number} + */ + _getSelectionForOffset: function(e, isRight) { + if (e.shiftKey && this.selectionStart !== this.selectionEnd && isRight) { + return this.selectionEnd; + } + else { + return this.selectionStart; + } + }, + + /** + * @param {Event} e Event object + * @param {Boolean} isRight + * @return {Number} + */ + getUpCursorOffset: function(e, isRight) { + var selectionProp = this._getSelectionForOffset(e, isRight), + cursorLocation = this.get2DCursorLocation(selectionProp), + lineIndex = cursorLocation.lineIndex; + if (lineIndex === 0 || e.metaKey || e.keyCode === 33) { + // if on first line, up cursor goes to start of line + return -selectionProp; + } + var charIndex = cursorLocation.charIndex, + widthBeforeCursor = this._getWidthBeforeCursor(lineIndex, charIndex), + indexOnOtherLine = this._getIndexOnLine(lineIndex - 1, widthBeforeCursor), + textBeforeCursor = this._textLines[lineIndex].slice(0, charIndex); + // return a negative offset + return -this._textLines[lineIndex - 1].length + indexOnOtherLine - textBeforeCursor.length; + }, + + /** + * find for a given width it founds the matching character. * @private */ - _getIndexOnNextLine: function(cursorLocation, textOnNextLine, widthOfCharsOnSameLineBeforeCursor) { - var lineIndex = cursorLocation.lineIndex + 1, - widthOfNextLine = this._getLineWidth(this.ctx, lineIndex), - lineLeftOffset = this._getLineLeftOffset(widthOfNextLine), - widthOfCharsOnNextLine = lineLeftOffset, - indexOnNextLine = 0, + _getIndexOnLine: function(lineIndex, width) { + + var widthOfLine = this._getLineWidth(this.ctx, lineIndex), + textOnLine = this._textLines[lineIndex], + lineLeftOffset = this._getLineLeftOffset(widthOfLine), + widthOfCharsOnLine = lineLeftOffset, + indexOnLine = 0, foundMatch; - for (var j = 0, jlen = textOnNextLine.length; j < jlen; j++) { + for (var j = 0, jlen = textOnLine.length; j < jlen; j++) { - var _char = textOnNextLine[j], + var _char = textOnLine[j], widthOfChar = this._getWidthOfChar(this.ctx, _char, lineIndex, j); - widthOfCharsOnNextLine += widthOfChar; + widthOfCharsOnLine += widthOfChar; - if (widthOfCharsOnNextLine > widthOfCharsOnSameLineBeforeCursor) { + if (widthOfCharsOnLine > width) { foundMatch = true; - var leftEdge = widthOfCharsOnNextLine - widthOfChar, - rightEdge = widthOfCharsOnNextLine, - offsetFromLeftEdge = Math.abs(leftEdge - widthOfCharsOnSameLineBeforeCursor), - offsetFromRightEdge = Math.abs(rightEdge - widthOfCharsOnSameLineBeforeCursor); + var leftEdge = widthOfCharsOnLine - widthOfChar, + rightEdge = widthOfCharsOnLine, + offsetFromLeftEdge = Math.abs(leftEdge - width), + offsetFromRightEdge = Math.abs(rightEdge - width); - indexOnNextLine = offsetFromRightEdge < offsetFromLeftEdge ? j + 1 : j; + indexOnLine = offsetFromRightEdge < offsetFromLeftEdge ? j : (j - 1); break; } @@ -24431,12 +24614,13 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot // reached end if (!foundMatch) { - indexOnNextLine = textOnNextLine.length; + indexOnLine = textOnLine.length - 1; } - return indexOnNextLine; + return indexOnLine; }, + /** * Moves cursor down * @param {Event} e Event object @@ -24448,124 +24632,6 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot this._moveCursorUpOrDown('Down', e); }, - /** - * Moves cursor down without keeping selection - * @param {Number} offset - */ - moveCursorDownWithoutShift: function(offset) { - this._selectionDirection = 'right'; - this.selectionEnd = this.selectionEnd + offset; - this.selectionStart = this.selectionEnd; - return offset !== 0; - }, - - /** - * private - */ - swapSelectionPoints: function() { - var swapSel = this.selectionEnd; - this.selectionEnd = this.selectionStart; - this.selectionStart = swapSel; - }, - - /** - * Moves cursor down while keeping selection - * @param {Number} offset - */ - moveCursorDownWithShift: function(offset) { - if (this.selectionEnd === this.selectionStart) { - this._selectionDirection = 'right'; - } - if (this._selectionDirection === 'right') { - this.selectionEnd += offset; - } - else { - this.selectionStart += offset; - } - if (this.selectionEnd < this.selectionStart && this._selectionDirection === 'left') { - this.swapSelectionPoints(); - this._selectionDirection = 'right'; - } - if (this.selectionEnd > this.text.length) { - this.selectionEnd = this.text.length; - } - return offset !== 0; - }, - - /** - * @param {Event} e Event object - * @param {Boolean} isRight - * @return {Number} - */ - getUpCursorOffset: function(e, isRight) { - var selectionProp = isRight ? this.selectionEnd : this.selectionStart, - cursorLocation = this.get2DCursorLocation(selectionProp), - lineIndex = cursorLocation.lineIndex; - // if on first line, up cursor goes to start of line - if (lineIndex === 0 || e.metaKey || e.keyCode === 33) { - return selectionProp; - } - - var textOnSameLineBeforeCursor = this._textLines[lineIndex].slice(0, cursorLocation.charIndex), - textOnPreviousLine = this._textLines[lineIndex - 1] || '', - _char, - widthOfSameLineBeforeCursor = this._getLineWidth(this.ctx, cursorLocation.lineIndex), - lineLeftOffset = this._getLineLeftOffset(widthOfSameLineBeforeCursor), - widthOfCharsOnSameLineBeforeCursor = lineLeftOffset; - - for (var i = 0, len = textOnSameLineBeforeCursor.length; i < len; i++) { - _char = textOnSameLineBeforeCursor[i]; - widthOfCharsOnSameLineBeforeCursor += this._getWidthOfChar(this.ctx, _char, lineIndex, i); - } - - var indexOnPrevLine = this._getIndexOnPrevLine( - cursorLocation, textOnPreviousLine, widthOfCharsOnSameLineBeforeCursor); - - return textOnPreviousLine.length - indexOnPrevLine + textOnSameLineBeforeCursor.length; - }, - - /** - * @private - */ - _getIndexOnPrevLine: function(cursorLocation, textOnPreviousLine, widthOfCharsOnSameLineBeforeCursor) { - - var lineIndex = cursorLocation.lineIndex - 1, - widthOfPreviousLine = this._getLineWidth(this.ctx, lineIndex), - lineLeftOffset = this._getLineLeftOffset(widthOfPreviousLine), - widthOfCharsOnPreviousLine = lineLeftOffset, - indexOnPrevLine = 0, - foundMatch; - - for (var j = 0, jlen = textOnPreviousLine.length; j < jlen; j++) { - - var _char = textOnPreviousLine[j], - widthOfChar = this._getWidthOfChar(this.ctx, _char, lineIndex, j); - - widthOfCharsOnPreviousLine += widthOfChar; - - if (widthOfCharsOnPreviousLine > widthOfCharsOnSameLineBeforeCursor) { - - foundMatch = true; - - var leftEdge = widthOfCharsOnPreviousLine - widthOfChar, - rightEdge = widthOfCharsOnPreviousLine, - offsetFromLeftEdge = Math.abs(leftEdge - widthOfCharsOnSameLineBeforeCursor), - offsetFromRightEdge = Math.abs(rightEdge - widthOfCharsOnSameLineBeforeCursor); - - indexOnPrevLine = offsetFromRightEdge < offsetFromLeftEdge ? j : (j - 1); - - break; - } - } - - // reached end - if (!foundMatch) { - indexOnPrevLine = textOnPreviousLine.length - 1; - } - - return indexOnPrevLine; - }, - /** * Moves cursor up * @param {Event} e Event object @@ -24583,16 +24649,18 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot * @param {Event} e Event object */ _moveCursorUpOrDown: function(direction, e) { + // getUpCursorOffset + // getDownCursorOffset var action = 'get' + direction + 'CursorOffset', - moveAction = 'moveCursor' + direction, offset = this[action](e, this._selectionDirection === 'right'); if (e.shiftKey) { - moveAction += 'WithShift'; + this.moveCursorWithShift(offset); } else { - moveAction += 'WithoutShift'; + this.moveCursorWithoutShift(offset); } - if (this[moveAction](offset)) { + if (offset !== 0) { + this.setSelectionInBoundaries(); this.abortCursorAnimation(); this._currentCursorOpacity = 1; this.initDelayedCursor(); @@ -24602,23 +24670,14 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot }, /** - * Moves cursor up with shift + * Moves cursor with shift * @param {Number} offset */ - moveCursorUpWithShift: function(offset) { - if (this.selectionEnd === this.selectionStart) { - this._selectionDirection = 'left'; - } - if (this._selectionDirection === 'right') { - this.selectionEnd -= offset; - } - else { - this.selectionStart -= offset; - } - if (this.selectionEnd < this.selectionStart && this._selectionDirection === 'right') { - this.swapSelectionPoints(); - this._selectionDirection = 'left'; - } + moveCursorWithShift: function(offset) { + var newSelection = this._selectionDirection === 'left' + ? this.selectionStart + offset + : this.selectionEnd + offset; + this.setSelectionStartEndWithShift(this.selectionStart, this.selectionEnd, newSelection); return offset !== 0; }, @@ -24626,10 +24685,15 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot * Moves cursor up without shift * @param {Number} offset */ - moveCursorUpWithoutShift: function(offset) { - this._selectionDirection = 'left'; - this.selectionStart -= offset; - this.selectionEnd = this.selectionStart; + moveCursorWithoutShift: function(offset) { + if (offset < 0) { + this.selectionStart += offset; + this.selectionEnd = this.selectionStart; + } + else { + this.selectionEnd += offset; + this.selectionStart = this.selectionEnd; + } return offset !== 0; }, @@ -24902,14 +24966,12 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot */ _createTextCharBg: function(styleDecl, lineLeftOffset, lineTopOffset, heightOfLine, charWidth, charOffset) { return [ - //jscs:disable validateIndentation '\t\t\n' - //jscs:enable validateIndentation ].join(''); }, @@ -24927,18 +24989,16 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot }, styleDecl)); return [ - //jscs:disable validateIndentation '\t\t\t', - fabric.util.string.escapeXml(_char), + toFixed(lineTopOffset - this.height / 2, NUM_FRACTION_DIGITS), '" ', + (styleDecl.fontFamily ? 'font-family="' + styleDecl.fontFamily.replace(/"/g, '\'') + '" ' : ''), + (styleDecl.fontSize ? 'font-size="' + styleDecl.fontSize + '" ' : ''), + (styleDecl.fontStyle ? 'font-style="' + styleDecl.fontStyle + '" ' : ''), + (styleDecl.fontWeight ? 'font-weight="' + styleDecl.fontWeight + '" ' : ''), + (styleDecl.textDecoration ? 'text-decoration="' + styleDecl.textDecoration + '" ' : ''), + 'style="', fillStyles, '">', + fabric.util.string.escapeXml(_char), '\n' - //jscs:enable validateIndentation ].join(''); } }); @@ -24982,10 +25042,12 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot /** * Minimum calculated width of a textbox, in pixels. + * fixed to 2 so that an empty textbox cannot go to 0 + * and is still selectable without text. * @type Number * @default */ - dynamicMinWidth: 0, + dynamicMinWidth: 2, /** * Cached array of text wrapping. @@ -25066,12 +25128,12 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot map = {}; for (var i = 0; i < this._textLines.length; i++) { - if (this.text[charCount] === '\n') { + if (this.text[charCount] === '\n' && i > 0) { realLineCharCount = 0; charCount++; realLineCount++; } - else if (this.text[charCount] === ' ') { + else if (this.text[charCount] === ' ' && i > 0) { // this case deals with space's that are removed from end of lines when wrapping realLineCharCount++; charCount++; @@ -25391,10 +25453,13 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot * @static * @memberOf fabric.Textbox * @param {Object} object Object to create an instance from + * @param {Function} [callback] Callback to invoke when an fabric.Textbox instance is created * @return {fabric.Textbox} instance of fabric.Textbox */ - fabric.Textbox.fromObject = function(object) { - return new fabric.Textbox(object.text, clone(object)); + fabric.Textbox.fromObject = function(object, callback) { + var textbox = new fabric.Textbox(object.text, clone(object)); + callback && callback(textbox); + return textbox; }; /** * Returns the default controls visibility required for Textboxes. @@ -25730,6 +25795,7 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot fabric.util.getScript = function(url, callback) { request(url, '', function(body) { + // eslint-disable-next-line no-eval eval(body); callback && callback(); }); @@ -25759,19 +25825,30 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot canvasEl.width = nodeCanvas.width; canvasEl.height = nodeCanvas.height; - + options = options || { }; + options.nodeCanvas = nodeCanvas; + options.nodeCacheCanvas = nodeCacheCanvas; var FabricCanvas = fabric.Canvas || fabric.StaticCanvas, fabricCanvas = new FabricCanvas(canvasEl, options); - - fabricCanvas.contextContainer = nodeCanvas.getContext('2d'); fabricCanvas.nodeCanvas = nodeCanvas; - fabricCanvas.contextCache = nodeCacheCanvas.getContext('2d'); fabricCanvas.nodeCacheCanvas = nodeCacheCanvas; + fabricCanvas.contextContainer = nodeCanvas.getContext('2d'); + fabricCanvas.contextCache = nodeCacheCanvas.getContext('2d'); fabricCanvas.Font = Canvas.Font; - return fabricCanvas; }; + var originaInitStatic = fabric.StaticCanvas.prototype._initStatic; + fabric.StaticCanvas.prototype._initStatic = function(el, options) { + el = el || fabric.document.createElement('canvas'); + this.nodeCanvas = new Canvas(el.width, el.height); + this.nodeCacheCanvas = new Canvas(el.width, el.height); + originaInitStatic.call(this, el, options); + this.contextContainer = this.nodeCanvas.getContext('2d'); + this.contextCache = this.nodeCacheCanvas.getContext('2d'); + this.Font = Canvas.Font; + } + /** @ignore */ fabric.StaticCanvas.prototype.createPNGStream = function() { return this.nodeCanvas.createPNGStream(); @@ -25781,24 +25858,30 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot return this.nodeCanvas.createJPEGStream(opts); }; - var origSetWidth = fabric.StaticCanvas.prototype.setWidth; - fabric.StaticCanvas.prototype.setWidth = function(width, options) { - origSetWidth.call(this, width, options); - this.nodeCanvas.width = width; + fabric.StaticCanvas.prototype._initRetinaScaling = function() { + if (!this._isRetinaScaling()) { + return; + } + + this.lowerCanvasEl.setAttribute('width', this.width * fabric.devicePixelRatio); + this.lowerCanvasEl.setAttribute('height', this.height * fabric.devicePixelRatio); + this.nodeCanvas.width = this.width * fabric.devicePixelRatio; + this.nodeCanvas.height = this.height * fabric.devicePixelRatio; + this.contextContainer.scale(fabric.devicePixelRatio, fabric.devicePixelRatio); return this; }; if (fabric.Canvas) { - fabric.Canvas.prototype.setWidth = fabric.StaticCanvas.prototype.setWidth; + fabric.Canvas.prototype._initRetinaScaling = fabric.StaticCanvas.prototype._initRetinaScaling; } - var origSetHeight = fabric.StaticCanvas.prototype.setHeight; - fabric.StaticCanvas.prototype.setHeight = function(height, options) { - origSetHeight.call(this, height, options); - this.nodeCanvas.height = height; + var origSetBackstoreDimension = fabric.StaticCanvas.prototype._setBackstoreDimension; + fabric.StaticCanvas.prototype._setBackstoreDimension = function(prop, value) { + origSetBackstoreDimension.call(this, prop, value); + this.nodeCanvas[prop] = value; return this; }; if (fabric.Canvas) { - fabric.Canvas.prototype.setHeight = fabric.StaticCanvas.prototype.setHeight; + fabric.Canvas.prototype._setBackstoreDimension = fabric.StaticCanvas.prototype._setBackstoreDimension; } })(); diff --git a/dist/fabric.min.js b/dist/fabric.min.js index 36f62d22..8ed014f0 100644 --- a/dist/fabric.min.js +++ b/dist/fabric.min.js @@ -1,8 +1,8 @@ -var fabric=fabric||{version:"1.6.4"};"undefined"!=typeof exports&&(exports.fabric=fabric),"undefined"!=typeof document&&"undefined"!=typeof window?(fabric.document=document,fabric.window=window,window.fabric=fabric):(fabric.document=require("jsdom").jsdom(""),fabric.document.createWindow?fabric.window=fabric.document.createWindow():fabric.window=fabric.document.parentWindow),fabric.isTouchSupported="ontouchstart"in fabric.document.documentElement,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"],fabric.DPI=96,fabric.reNum="(?:[-+]?(?:\\d+|\\d*\\.\\d+)(?:e[-+]?\\d+)?)",fabric.fontPaths={},fabric.charWidthsCache={},fabric.devicePixelRatio=fabric.window.devicePixelRatio||fabric.window.webkitDevicePixelRatio||fabric.window.mozDevicePixelRatio||1,function(){function t(t,e){if(this.__eventListeners[t]){var i=this.__eventListeners[t];e?i[i.indexOf(e)]=!1:fabric.util.array.fill(i,!1)}}function e(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 i(e,i){if(this.__eventListeners){if(0===arguments.length)for(e in this.__eventListeners)t.call(this,e);else if(1===arguments.length&&"object"==typeof arguments[0])for(var r in e)t.call(this,r,e[r]);else t.call(this,e,i);return this}}function r(t,e){if(this.__eventListeners){var i=this.__eventListeners[t];if(i){for(var r=0,n=i.length;r-1},complexity:function(){return this.getObjects().reduce(function(t,e){return t+=e.complexity?e.complexity():0},0)}},function(t){var e=Math.sqrt,i=Math.atan2,r=Math.pow,n=Math.abs,s=Math.PI/180;fabric.util={removeFromArray:function(t,e){var i=t.indexOf(e);return i!==-1&&t.splice(i,1),t},getRandomInt:function(t,e){return Math.floor(Math.random()*(e-t+1))+t},degreesToRadians:function(t){return t*s},radiansToDegrees:function(t){return t/s},rotatePoint:function(t,e,i){t.subtractEquals(e);var r=fabric.util.rotateVector(t,i);return new fabric.Point(r.x,r.y).addEquals(e)},rotateVector:function(t,e){var i=Math.sin(e),r=Math.cos(e),n=t.x*r-t.y*i,s=t.x*i+t.y*r;return{x:n,y:s}},transformPoint:function(t,e,i){return i?new fabric.Point(e[0]*t.x+e[2]*t.y,e[1]*t.x+e[3]*t.y):new fabric.Point(e[0]*t.x+e[2]*t.y+e[4],e[1]*t.x+e[3]*t.y+e[5])},makeBoundingBoxFromPoints:function(t){var e=[t[0].x,t[1].x,t[2].x,t[3].x],i=fabric.util.array.min(e),r=fabric.util.array.max(e),n=Math.abs(i-r),s=[t[0].y,t[1].y,t[2].y,t[3].y],o=fabric.util.array.min(s),a=fabric.util.array.max(s),h=Math.abs(o-a);return{left:i,top:o,width:n,height:h}},invertTransform:function(t){var e=1/(t[0]*t[3]-t[1]*t[2]),i=[e*t[3],-e*t[1],-e*t[2],e*t[0]],r=fabric.util.transformPoint({x:t[4],y:t[5]},i,!0);return i[4]=-r.x,i[5]=-r.y,i},toFixed:function(t,e){return parseFloat(Number(t).toFixed(e))},parseUnit:function(t,e){var i=/\D{0,2}$/.exec(t),r=parseFloat(t);switch(e||(e=fabric.Text.DEFAULT_SVG_FONT_SIZE),i[0]){case"mm":return r*fabric.DPI/25.4;case"cm":return r*fabric.DPI/2.54;case"in":return r*fabric.DPI;case"pt":return r*fabric.DPI/72;case"pc":return r*fabric.DPI/72*12;case"em":return r*e;default:return r}},falseFunction:function(){return!1},getKlass:function(t,e){return t=fabric.util.string.camelize(t.charAt(0).toUpperCase()+t.slice(1)),fabric.util.resolveNamespace(e)[t]},resolveNamespace:function(e){if(!e)return fabric;for(var i=e.split("."),r=i.length,n=t||fabric.window,s=0;sr;)r+=a[d++%f],r>l&&(r=l),t[g?"lineTo":"moveTo"](r,0),g=!g;t.restore()},createCanvasElement:function(t){return t||(t=fabric.document.createElement("canvas")),t.getContext||"undefined"==typeof G_vmlCanvasManager||G_vmlCanvasManager.initElement(t),t},createImage:function(){return fabric.isLikelyNode?new(require("canvas").Image):fabric.document.createElement("img")},createAccessors:function(t){for(var e=t.prototype,i=e.stateProperties.length;i--;){var r=e.stateProperties[i],n=r.charAt(0).toUpperCase()+r.slice(1),s="set"+n,o="get"+n;e[o]||(e[o]=function(t){return new Function('return this.get("'+t+'")')}(r)),e[s]||(e[s]=function(t){return new Function("value",'return this.set("'+t+'", value)')}(r))}},clipContext:function(t,e){e.save(),e.beginPath(),t.clipTo(e),e.clip()},multiplyTransformMatrices:function(t,e,i){return[t[0]*e[0]+t[2]*e[1],t[1]*e[0]+t[3]*e[1],t[0]*e[2]+t[2]*e[3],t[1]*e[2]+t[3]*e[3],i?0:t[0]*e[4]+t[2]*e[5]+t[4],i?0:t[1]*e[4]+t[3]*e[5]+t[5]]},qrDecompose:function(t){var n=i(t[1],t[0]),o=r(t[0],2)+r(t[1],2),a=e(o),h=(t[0]*t[3]-t[2]*t[1])/a,c=i(t[0]*t[2]+t[1]*t[3],o);return{angle:n/s,scaleX:a,scaleY:h,skewX:c/s,skewY:0,translateX:t[4],translateY:t[5]}},customTransformMatrix:function(t,e,i){var r=[1,0,n(Math.tan(i*s)),1],o=[n(t),0,0,n(e)];return fabric.util.multiplyTransformMatrices(o,r,!0)},resetObjectTransform:function(t){t.scaleX=1,t.scaleY=1,t.skewX=0,t.skewY=0,t.flipX=!1,t.flipY=!1,t.setAngle(0)},getFunctionBody:function(t){return(String(t).match(/function[^{]*\{([\s\S]*)\}/)||{})[1]},isTransparent:function(t,e,i,r){r>0&&(e>r?e-=r:e=0,i>r?i-=r:i=0);for(var n=!0,s=t.getImageData(e,i,2*r||1,2*r||1),o=3,a=s.data.length;o0?I-=2*f:1===c&&I<0&&(I+=2*f);for(var L=Math.ceil(Math.abs(I/f*2)),E=[],D=I/L,R=8/3*Math.sin(D/4)*Math.sin(D/4)/Math.sin(D/2),F=P+D,B=0;B=n?s-n:2*Math.PI-(n-s)}function r(t,e,i,r,n,s,h,c){var l=a.call(arguments);if(o[l])return o[l];var u,f,d,g,p,v,b,m,y=Math.sqrt,_=Math.min,x=Math.max,S=Math.abs,C=[],w=[[],[]];f=6*t-12*i+6*n,u=-3*t+9*i-9*n+3*h,d=3*i-3*t;for(var O=0;O<2;++O)if(O>0&&(f=6*e-12*r+6*s,u=-3*e+9*r-9*s+3*c,d=3*r-3*e),S(u)<1e-12){if(S(f)<1e-12)continue;g=-d/f,0=e})}function i(t,e){return n(t,e,function(t,e){return t>>0;if(0===i)return-1;var r=0;if(arguments.length>0&&(r=Number(arguments[1]),r!==r?r=0:0!==r&&r!==Number.POSITIVE_INFINITY&&r!==Number.NEGATIVE_INFINITY&&(r=(r>0||-1)*Math.floor(Math.abs(r)))),r>=i)return-1;for(var n=r>=0?r:Math.max(i-Math.abs(r),0);n>>0;i>>0;r>>0;i>>0;i>>0;n>>0,r=0;if(arguments.length>1)e=arguments[1];else for(;;){if(r in this){e=this[r++];break}if(++r>=i)throw new TypeError}for(;r/g,">")}String.prototype.trim||(String.prototype.trim=function(){return this.replace(/^[\s\xA0]+/,"").replace(/[\s\xA0]+$/,"")}),fabric.util.string={camelize:t,capitalize:e,escapeXml:i}}(),function(){var t=Array.prototype.slice,e=Function.prototype.apply,i=function(){};Function.prototype.bind||(Function.prototype.bind=function(r){var n,s=this,o=t.call(arguments,1);return n=o.length?function(){return e.call(s,this instanceof i?this:r,o.concat(t.call(arguments)))}:function(){return e.call(s,this instanceof i?this:r,arguments)},i.prototype=this.prototype,n.prototype=new i,n})}(),function(){function t(){}function e(t){var e=this.constructor.superclass.prototype[t];return arguments.length>1?e.apply(this,r.call(arguments,1)):e.call(this)}function i(){function i(){this.initialize.apply(this,arguments)}var s=null,a=r.call(arguments,0);"function"==typeof a[0]&&(s=a.shift()),i.superclass=s,i.subclasses=[],s&&(t.prototype=s.prototype,i.prototype=new t,s.subclasses.push(i));for(var h=0,c=a.length;h-1?t.prototype[r]=function(t){return function(){var r=this.constructor.superclass;this.constructor.superclass=i;var n=e[t].apply(this,arguments);if(this.constructor.superclass=r,"initialize"!==t)return n}}(r):t.prototype[r]=e[r],s&&(e.toString!==Object.prototype.toString&&(t.prototype.toString=e.toString),e.valueOf!==Object.prototype.valueOf&&(t.prototype.valueOf=e.valueOf))};fabric.util.createClass=i}(),function(){function t(t){var e,i,r=Array.prototype.slice.call(arguments,1),n=r.length;for(i=0;i-1?s(t,e.match(/opacity:\s*(\d?\.?\d*)/)[1]):t;for(var r in e)if("opacity"===r)s(t,e[r]);else{var n="float"===r||"cssFloat"===r?"undefined"==typeof i.styleFloat?"cssFloat":"styleFloat":r;i[n]=e[r]}return t}var e=fabric.document.createElement("div"),i="string"==typeof e.style.opacity,r="string"==typeof e.style.filter,n=/alpha\s*\(\s*opacity\s*=\s*([^\)]+)\)/,s=function(t){return t};i?s=function(t,e){return t.style.opacity=e,t}:r&&(s=function(t,e){var i=t.style;return t.currentStyle&&!t.currentStyle.hasLayout&&(i.zoom=1),n.test(i.filter)?(e=e>=.9999?"":"alpha(opacity="+100*e+")",i.filter=i.filter.replace(n,e)):i.filter+=" alpha(opacity="+100*e+")",t}),fabric.util.setStyle=t}(),function(){function t(t){return"string"==typeof t?fabric.document.getElementById(t):t}function e(t,e){var i=fabric.document.createElement(t);for(var r in e)"class"===r?i.className=e[r]:"for"===r?i.htmlFor=e[r]:i.setAttribute(r,e[r]);return i}function i(t,e){t&&(" "+t.className+" ").indexOf(" "+e+" ")===-1&&(t.className+=(t.className?" ":"")+e)}function r(t,i,r){return"string"==typeof i&&(i=e(i,r)),t.parentNode&&t.parentNode.replaceChild(i,t),i.appendChild(t),i}function n(t){for(var e=0,i=0,r=fabric.document.documentElement,n=fabric.document.body||{scrollLeft:0,scrollTop:0};t&&(t.parentNode||t.host)&&(t=t.parentNode||t.host,t===fabric.document?(e=n.scrollLeft||r.scrollLeft||0,i=n.scrollTop||r.scrollTop||0):(e+=t.scrollLeft||0,i+=t.scrollTop||0),1!==t.nodeType||"fixed"!==fabric.util.getElementStyle(t,"position")););return{left:e,top:i}}function s(t){var e,i,r=t&&t.ownerDocument,s={left:0,top:0},o={left:0,top:0},a={borderLeftWidth:"left",borderTopWidth:"top",paddingLeft:"left",paddingTop:"top"};if(!r)return o;for(var h in a)o[a[h]]+=parseInt(c(t,h),10)||0;return e=r.documentElement,"undefined"!=typeof t.getBoundingClientRect&&(s=t.getBoundingClientRect()),i=n(t),{left:s.left+i.left-(e.clientLeft||0)+o.left,top:s.top+i.top-(e.clientTop||0)+o.top}}var o,a=Array.prototype.slice,h=function(t){return a.call(t,0)};try{o=h(fabric.document.childNodes)instanceof Array}catch(t){}o||(h=function(t){for(var e=new Array(t.length),i=t.length;i--;)e[i]=t[i];return e});var c;c=fabric.document.defaultView&&fabric.document.defaultView.getComputedStyle?function(t,e){var i=fabric.document.defaultView.getComputedStyle(t,null);return i?i[e]:void 0}:function(t,e){var i=t.style[e];return!i&&t.currentStyle&&(i=t.currentStyle[e]),i},function(){function t(t){return"undefined"!=typeof t.onselectstart&&(t.onselectstart=fabric.util.falseFunction),r?t.style[r]="none":"string"==typeof t.unselectable&&(t.unselectable="on"),t}function e(t){return"undefined"!=typeof t.onselectstart&&(t.onselectstart=null),r?t.style[r]="":"string"==typeof t.unselectable&&(t.unselectable=""),t}var i=fabric.document.documentElement.style,r="userSelect"in i?"userSelect":"MozUserSelect"in i?"MozUserSelect":"WebkitUserSelect"in i?"WebkitUserSelect":"KhtmlUserSelect"in i?"KhtmlUserSelect":"";fabric.util.makeElementUnselectable=t,fabric.util.makeElementSelectable=e}(),function(){function t(t,e){var i=fabric.document.getElementsByTagName("head")[0],r=fabric.document.createElement("script"),n=!0;r.onload=r.onreadystatechange=function(t){if(n){if("string"==typeof this.readyState&&"loaded"!==this.readyState&&"complete"!==this.readyState)return;n=!1,e(t||fabric.window.event),r=r.onload=r.onreadystatechange=null}},r.src=t,i.appendChild(r)}fabric.util.getScript=t}(),fabric.util.getById=t,fabric.util.toArray=h,fabric.util.makeElement=e,fabric.util.addClass=i,fabric.util.wrapElement=r,fabric.util.getScrollLeftTop=n,fabric.util.getElementOffset=s,fabric.util.getElementStyle=c}(),function(){function t(t,e){return t+(/\?/.test(t)?"&":"?")+e}function e(){}function i(i,n){n||(n={});var s=n.method?n.method.toUpperCase():"GET",o=n.onComplete||function(){},a=r(),h=n.body||n.parameters;return a.onreadystatechange=function(){4===a.readyState&&(o(a),a.onreadystatechange=e)},"GET"===s&&(h=null,"string"==typeof n.parameters&&(i=t(i,n.parameters))),a.open(s,i,!0),"POST"!==s&&"PUT"!==s||a.setRequestHeader("Content-Type","application/x-www-form-urlencoded"),a.send(h),a}var r=function(){for(var t=[function(){return new ActiveXObject("Microsoft.XMLHTTP")},function(){return new ActiveXObject("Msxml2.XMLHTTP")},function(){return new ActiveXObject("Msxml2.XMLHTTP.3.0")},function(){return new XMLHttpRequest}],e=t.length;e--;)try{var i=t[e]();if(i)return t[e]}catch(t){}}();fabric.util.request=i}(),fabric.log=function(){},fabric.warn=function(){},"undefined"!=typeof console&&["log","warn"].forEach(function(t){"undefined"!=typeof console[t]&&"function"==typeof console[t].apply&&(fabric[t]=function(){return console[t].apply(console,arguments)})}),function(){function t(t){e(function(i){t||(t={});var r,n=i||+new Date,s=t.duration||500,o=n+s,a=t.onChange||function(){},h=t.abort||function(){return!1},c=t.easing||function(t,e,i,r){return-i*Math.cos(t/r*(Math.PI/2))+i+e},l="startValue"in t?t.startValue:0,u="endValue"in t?t.endValue:100,f=t.byValue||u-l;t.onStart&&t.onStart(),function i(u){r=u||+new Date;var d=r>o?s:r-n;return h()?void(t.onComplete&&t.onComplete()):(a(c(d,l,f,s)),r>o?void(t.onComplete&&t.onComplete()):void e(i))}(n)})}function e(){return i.apply(fabric.window,arguments)}var i=fabric.window.requestAnimationFrame||fabric.window.webkitRequestAnimationFrame||fabric.window.mozRequestAnimationFrame||fabric.window.oRequestAnimationFrame||fabric.window.msRequestAnimationFrame||function(t){fabric.window.setTimeout(t,1e3/60)};fabric.util.animate=t,fabric.util.requestAnimFrame=e}(),function(){function t(t,e,i,r){return ta?a:o),1===o&&1===a&&0===h&&0===c&&0===f&&0===d)return y;if((f||d)&&(_=" translate("+x(f)+" "+x(d)+") "),r=_+" matrix("+o+" 0 0 "+a+" "+h*o+" "+c*a+") ","svg"===t.nodeName){for(n=t.ownerDocument.createElement("g");null!=t.firstChild;)n.appendChild(t.firstChild);t.appendChild(n)}else n=t,r=n.getAttribute("transform")+r;return n.setAttribute("transform",r),y}function g(t){var e=t.objects,i=t.options;return e=e.map(function(t){return v[m(t.type)].fromObject(t)}),{objects:e,options:i}}function p(t,e,i){e[i]&&e[i].toSVG&&t.push('\t\n','\t\t\n\t\n')}var v=t.fabric||(t.fabric={}),b=v.util.object.extend,m=v.util.string.capitalize,y=v.util.object.clone,_=v.util.toFixed,x=v.util.parseUnit,S=v.util.multiplyTransformMatrices,C=/^(path|circle|polygon|polyline|ellipse|rect|line|image|text)$/i,w=/^(symbol|image|marker|pattern|view|svg)$/i,O=/^(?:pattern|defs|symbol|metadata)$/i,T=/^(symbol|g|a|svg)$/i,k={cx:"left",x:"left",r:"radius",cy:"top",y:"top",display:"visible",visibility:"visible",transform:"transformMatrix","fill-opacity":"fillOpacity","fill-rule":"fillRule","font-family":"fontFamily","font-size":"fontSize","font-style":"fontStyle","font-weight":"fontWeight","stroke-dasharray":"strokeDashArray","stroke-linecap":"strokeLineCap","stroke-linejoin":"strokeLineJoin","stroke-miterlimit":"strokeMiterLimit","stroke-opacity":"strokeOpacity","stroke-width":"strokeWidth","text-decoration":"textDecoration","text-anchor":"originX"},j={stroke:"strokeOpacity",fill:"fillOpacity"};v.cssRules={},v.gradientDefs={},v.parseTransformAttribute=function(){function t(t,e){var i=e[0],r=3===e.length?e[1]:0,n=3===e.length?e[2]:0;t[0]=Math.cos(i),t[1]=Math.sin(i),t[2]=-Math.sin(i),t[3]=Math.cos(i),t[4]=r-(t[0]*r+t[2]*n),t[5]=n-(t[1]*r+t[3]*n)}function e(t,e){var i=e[0],r=2===e.length?e[1]:e[0];t[0]=i,t[3]=r}function i(t,e){t[2]=Math.tan(v.util.degreesToRadians(e[0]))}function r(t,e){t[1]=Math.tan(v.util.degreesToRadians(e[0]))}function n(t,e){t[4]=e[0],2===e.length&&(t[5]=e[1])}var s=[1,0,0,1,0,0],o=v.reNum,a="(?:\\s+,?\\s*|,\\s*)",h="(?:(skewX)\\s*\\(\\s*("+o+")\\s*\\))",c="(?:(skewY)\\s*\\(\\s*("+o+")\\s*\\))",l="(?:(rotate)\\s*\\(\\s*("+o+")(?:"+a+"("+o+")"+a+"("+o+"))?\\s*\\))",u="(?:(scale)\\s*\\(\\s*("+o+")(?:"+a+"("+o+"))?\\s*\\))",f="(?:(translate)\\s*\\(\\s*("+o+")(?:"+a+"("+o+"))?\\s*\\))",d="(?:(matrix)\\s*\\(\\s*("+o+")"+a+"("+o+")"+a+"("+o+")"+a+"("+o+")"+a+"("+o+")"+a+"("+o+")\\s*\\))",g="(?:"+d+"|"+f+"|"+u+"|"+l+"|"+h+"|"+c+")",p="(?:"+g+"(?:"+a+"*"+g+")*)",b="^\\s*(?:"+p+"?)\\s*$",m=new RegExp(b),y=new RegExp(g,"g"); -return function(o){var a=s.concat(),h=[];if(!o||o&&!m.test(o))return a;o.replace(y,function(o){var c=new RegExp(g).exec(o).filter(function(t){return""!==t&&null!=t}),l=c[1],u=c.slice(2).map(parseFloat);switch(l){case"translate":n(a,u);break;case"rotate":u[0]=v.util.degreesToRadians(u[0]),t(a,u);break;case"scale":e(a,u);break;case"skewX":i(a,u);break;case"skewY":r(a,u);break;case"matrix":a=u}h.push(a.concat()),a=s.concat()});for(var c=h[0];h.length>1;)h.shift(),c=v.util.multiplyTransformMatrices(c,h[0]);return c}}();var A=new RegExp("^\\s*("+v.reNum+"+)\\s*,?\\s*("+v.reNum+"+)\\s*,?\\s*("+v.reNum+"+)\\s*,?\\s*("+v.reNum+"+)\\s*$");v.parseSVGDocument=function(){function t(t,e){for(;t&&(t=t.parentNode);)if(t.nodeName&&e.test(t.nodeName.replace("svg:",""))&&!t.getAttribute("instantiated_by_use"))return!0;return!1}return function(e,i,r){if(e){f(e);var n=new Date,s=v.Object.__uid++,o=d(e),a=v.util.toArray(e.getElementsByTagName("*"));if(o.svgUid=s,0===a.length&&v.isLikelyNode){a=e.selectNodes('//*[name(.)!="svg"]');for(var h=[],c=0,l=a.length;c/i,""))),n&&n.documentElement||e&&e(null),v.parseSVGDocument(n.documentElement,function(i,r){M.set(t,{objects:v.util.array.invoke(i,"toObject"),options:r}),e&&e(i,r)},i)}t=t.replace(/^\n\s*/,"").trim(),M.has(t,function(i){i?M.get(t,function(t){var i=g(t);e(i.objects,i.options)}):new v.util.request(t,{method:"get",onComplete:r})})},loadSVGFromString:function(t,e,i){t=t.trim();var r;if("undefined"!=typeof DOMParser){var n=new DOMParser;n&&n.parseFromString&&(r=n.parseFromString(t,"text/xml"))}else v.window.ActiveXObject&&(r=new ActiveXObject("Microsoft.XMLDOM"),r.async="false",r.loadXML(t.replace(//i,"")));v.parseSVGDocument(r.documentElement,function(t,i){e(t,i)},i)},createSVGFontFacesMarkup:function(t){for(var e,i,r,n,s,o,a,h="",c={},l=v.fontPaths,u=0,f=t.length;u',"","\n"].join("")),h},createSVGRefElementsMarkup:function(t){var e=[];return p(e,t,"backgroundColor"),p(e,t,"overlayColor"),e.join("")}})}("undefined"!=typeof exports?exports:this),fabric.ElementsParser=function(t,e,i,r){this.elements=t,this.callback=e,this.options=i,this.reviver=r,this.svgUid=i&&i.svgUid||0},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,i){return"undefined"==typeof i&&(i=.5),i=Math.max(Math.min(1,i),0),new e(this.x+(t.x-this.x)*i,this.y+(t.y-this.y)*i)},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 e(Math.min(this.x,t.x),Math.min(this.y,t.y))},max:function(t){return new e(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 e(this.x,this.y)}}))}("undefined"!=typeof exports?exports:this),function(t){"use strict";function e(t){this.status=t,this.points=[]}var i=t.fabric||(t.fabric={});return i.Intersection?void i.warn("fabric.Intersection is already defined"):(i.Intersection=e,i.Intersection.prototype={constructor:e,appendPoint:function(t){return this.points.push(t),this},appendPoints:function(t){return this.points=this.points.concat(t),this}},i.Intersection.intersectLineLine=function(t,r,n,s){var o,a=(s.x-n.x)*(t.y-n.y)-(s.y-n.y)*(t.x-n.x),h=(r.x-t.x)*(t.y-n.y)-(r.y-t.y)*(t.x-n.x),c=(s.y-n.y)*(r.x-t.x)-(s.x-n.x)*(r.y-t.y);if(0!==c){var l=a/c,u=h/c;0<=l&&l<=1&&0<=u&&u<=1?(o=new e("Intersection"),o.appendPoint(new i.Point(t.x+l*(r.x-t.x),t.y+l*(r.y-t.y)))):o=new e}else o=new e(0===a||0===h?"Coincident":"Parallel");return o},i.Intersection.intersectLinePolygon=function(t,i,r){for(var n,s,o,a=new e,h=r.length,c=0;c0&&(a.status="Intersection"),a},i.Intersection.intersectPolygonPolygon=function(t,i){for(var r=new e,n=t.length,s=0;s0&&(r.status="Intersection"),r},void(i.Intersection.intersectPolygonRectangle=function(t,r,n){var s=r.min(n),o=r.max(n),a=new i.Point(o.x,s.y),h=new i.Point(s.x,o.y),c=e.intersectLinePolygon(s,a,t),l=e.intersectLinePolygon(a,o,t),u=e.intersectLinePolygon(o,h,t),f=e.intersectLinePolygon(h,s,t),d=new e;return d.appendPoints(c.points),d.appendPoints(l.points),d.appendPoints(u.points),d.appendPoints(f.points),d.points.length>0&&(d.status="Intersection"),d}))}("undefined"!=typeof exports?exports:this),function(t){"use strict";function e(t){t?this._tryParsingColor(t):this.setSource([0,0,0,1])}function i(t,e,i){return i<0&&(i+=1),i>1&&(i-=1),i<1/6?t+6*(e-t)*i:i<.5?e:i<2/3?t+(e-t)*(2/3-i)*6:t}var r=t.fabric||(t.fabric={});return r.Color?void r.warn("fabric.Color is already defined."):(r.Color=e,r.Color.prototype={_tryParsingColor:function(t){var i;t in e.colorNameMap&&(t=e.colorNameMap[t]),"transparent"===t&&(i=[255,255,255,0]),i||(i=e.sourceFromHex(t)),i||(i=e.sourceFromRgb(t)),i||(i=e.sourceFromHsl(t)),i||(i=[0,0,0,1]),i&&this.setSource(i)},_rgbToHsl:function(t,e,i){t/=255,e/=255,i/=255;var n,s,o,a=r.util.array.max([t,e,i]),h=r.util.array.min([t,e,i]);if(o=(a+h)/2,a===h)n=s=0;else{var c=a-h;switch(s=o>.5?c/(2-a-h):c/(a+h),a){case t:n=(e-i)/c+(e1?1:s,n){var o=n.split(/\s*;\s*/);""===o[o.length-1]&&o.pop();for(var a=o.length;a--;){var h=o[a].split(/\s*:\s*/),c=h[0].trim(),l=h[1].trim();"stop-color"===c?e=l:"stop-opacity"===c&&(r=l)}}return e||(e=t.getAttribute("stop-color")||"rgb(0,0,0)"),r||(r=t.getAttribute("stop-opacity")),e=new fabric.Color(e),i=e.getAlpha(),r=isNaN(parseFloat(r))?1:parseFloat(r),r*=i,{offset:s,color:e.toRgb(),opacity:r}}function e(t){return{x1:t.getAttribute("x1")||0,y1:t.getAttribute("y1")||0,x2:t.getAttribute("x2")||"100%",y2:t.getAttribute("y2")||0}}function i(t){return{x1:t.getAttribute("fx")||t.getAttribute("cx")||"50%",y1:t.getAttribute("fy")||t.getAttribute("cy")||"50%",r1:0,x2:t.getAttribute("cx")||"50%",y2:t.getAttribute("cy")||"50%",r2:t.getAttribute("r")||"50%"}}function r(t,e,i){var r,n=0,s=1,o="";for(var a in e)"Infinity"===e[a]?e[a]=1:"-Infinity"===e[a]&&(e[a]=0),r=parseFloat(e[a],10),s="string"==typeof e[a]&&/^\d+%$/.test(e[a])?.01:1,"x1"===a||"x2"===a||"r2"===a?(s*="objectBoundingBox"===i?t.width:1,n="objectBoundingBox"===i?t.left||0:0):"y1"!==a&&"y2"!==a||(s*="objectBoundingBox"===i?t.height:1,n="objectBoundingBox"===i?t.top||0:0),e[a]=r*s+n;if("ellipse"===t.type&&null!==e.r2&&"objectBoundingBox"===i&&t.rx!==t.ry){var h=t.ry/t.rx;o=" scale(1, "+h+")",e.y1&&(e.y1/=h),e.y2&&(e.y2/=h)}return o}fabric.Gradient=fabric.util.createClass({offsetX:0,offsetY:0,initialize:function(t){t||(t={});var e={};this.id=fabric.Object.__uid++,this.type=t.type||"linear",e={x1:t.coords.x1||0,y1:t.coords.y1||0,x2:t.coords.x2||0,y2:t.coords.y2||0},"radial"===this.type&&(e.r1=t.coords.r1||0,e.r2=t.coords.r2||0),this.coords=e,this.colorStops=t.colorStops.slice(),t.gradientTransform&&(this.gradientTransform=t.gradientTransform),this.offsetX=t.offsetX||this.offsetX,this.offsetY=t.offsetY||this.offsetY},addColorStop:function(t){for(var e in t){var i=new fabric.Color(t[e]);this.colorStops.push({offset:e,color:i.toRgb(),opacity:i.getAlpha()})}return this},toObject:function(){return{type:this.type,coords:this.coords,colorStops:this.colorStops,offsetX:this.offsetX,offsetY:this.offsetY,gradientTransform:this.gradientTransform?this.gradientTransform.concat():this.gradientTransform}},toSVG:function(t){var e,i,r=fabric.util.object.clone(this.coords);if(this.colorStops.sort(function(t,e){return t.offset-e.offset}),!t.group||"path-group"!==t.group.type)for(var n in r)"x1"===n||"x2"===n||"r2"===n?r[n]+=this.offsetX-t.width/2:"y1"!==n&&"y2"!==n||(r[n]+=this.offsetY-t.height/2);i='id="SVGID_'+this.id+'" gradientUnits="userSpaceOnUse"',this.gradientTransform&&(i+=' gradientTransform="matrix('+this.gradientTransform.join(" ")+')" '),"linear"===this.type?e=["\n']:"radial"===this.type&&(e=["\n']);for(var s=0;s\n');return e.push("linear"===this.type?"\n":"\n"),e.join("")},toLive:function(t,e){var i,r,n=fabric.util.object.clone(this.coords);if(this.type){if(e.group&&"path-group"===e.group.type)for(r in n)"x1"===r||"x2"===r?n[r]+=-this.offsetX+e.width/2:"y1"!==r&&"y2"!==r||(n[r]+=-this.offsetY+e.height/2);"linear"===this.type?i=t.createLinearGradient(n.x1,n.y1,n.x2,n.y2):"radial"===this.type&&(i=t.createRadialGradient(n.x1,n.y1,n.r1,n.x2,n.y2,n.r2));for(var s=0,o=this.colorStops.length;s\n\n\n'},toLive:function(t){var e="function"==typeof this.source?this.source():this.source;if(!e)return"";if("undefined"!=typeof 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 e=t.fabric||(t.fabric={}),i=e.util.toFixed;return e.Shadow?void e.warn("fabric.Shadow is already defined."):(e.Shadow=e.util.createClass({color:"rgb(0,0,0)",blur:0,offsetX:0,offsetY:0,affectStroke:!1,includeDefaultValues:!0,initialize:function(t){"string"==typeof t&&(t=this._parseShadow(t));for(var i in t)this[i]=t[i];this.id=e.Object.__uid++},_parseShadow:function(t){var i=t.trim(),r=e.Shadow.reOffsetsAndBlur.exec(i)||[],n=i.replace(e.Shadow.reOffsetsAndBlur,"")||"rgb(0,0,0)";return{color:n.trim(),offsetX:parseInt(r[1],10)||0,offsetY:parseInt(r[2],10)||0,blur:parseInt(r[3],10)||0}},toString:function(){return[this.offsetX,this.offsetY,this.blur,this.color].join("px ")},toSVG:function(t){var r=40,n=40,s=e.Object.NUM_FRACTION_DIGITS,o=e.util.rotateVector({x:this.offsetX,y:this.offsetY},e.util.degreesToRadians(-t.angle)),a=20;return t.width&&t.height&&(r=100*i((Math.abs(o.x)+this.blur)/t.width,s)+a,n=100*i((Math.abs(o.y)+this.blur)/t.height,s)+a),t.flipX&&(o.x*=-1),t.flipY&&(o.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 t={},i=e.Shadow.prototype;return["color","blur","offsetX","offsetY","affectStroke"].forEach(function(e){this[e]!==i[e]&&(t[e]=this[e])},this),t}}),void(e.Shadow.reOffsetsAndBlur=/(?:\s|^)(-?\d+(?:px)?(?:\s?|$))?(-?\d+(?:px)?(?:\s?|$))?(\d+(?:px)?)?(?:\s?|$)(?:$|\s)/))}("undefined"!=typeof exports?exports:this),function(){"use strict";if(fabric.StaticCanvas)return void fabric.warn("fabric.StaticCanvas is already defined.");var t=fabric.util.object.extend,e=fabric.util.getElementOffset,i=fabric.util.removeFromArray,r=fabric.util.toFixed,n=new Error("Could not initialize `canvas` element");fabric.StaticCanvas=fabric.util.createClass({initialize:function(t,e){e||(e={}),this._initStatic(t,e)},backgroundColor:"",backgroundImage:null,overlayColor:"",overlayImage:null,includeDefaultValues:!0,stateful:!0,renderOnAddRemove:!0,clipTo:null,controlsAboveOverlay:!1,allowTouchScrolling:!1,imageSmoothingEnabled:!0,viewportTransform:[1,0,0,1,0,0],backgroundVpt:!0,overlayVpt:!0,onBeforeScaleRotate:function(){},enableRetinaScaling:!0,_initStatic:function(t,e){var i=fabric.StaticCanvas.prototype.renderAll.bind(this);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=e(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(t,e,i,r){return"string"==typeof e?fabric.util.loadImage(e,function(e){e&&(this[t]=new fabric.Image(e,r)),i&&i(e)},this,r&&r.crossOrigin):(r&&e.setOptions(r),this[t]=e,i&&i(e)),this},__setBgOverlayColor:function(t,e,i){if(e&&e.source){var r=this;fabric.util.loadImage(e.source,function(n){r[t]=new fabric.Pattern({source:n,repeat:e.repeat,offsetX:e.offsetX,offsetY:e.offsetY}),i&&i()})}else this[t]=e,i&&i();return this},_createCanvasElement:function(){var t=fabric.document.createElement("canvas");if(t.style||(t.style={}),!t)throw n;return this._initCanvasElement(t),t},_initCanvasElement:function(t){if(fabric.util.createCanvasElement(t),"undefined"==typeof t.getContext)throw n},_initOptions:function(t){for(var e in t)this[e]=t[e];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){this.lowerCanvasEl=fabric.util.getById(t)||this._createCanvasElement(),this._initCanvasElement(this.lowerCanvasEl),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;e=e||{};for(var r in t)i=t[r],e.cssOnly||(this._setBackstoreDimension(r,t[r]),i+="px"),e.backstoreOnly||this._setCssDimension(r,i);return this._initRetinaScaling(),this._setImageSmoothing(),this.calcOffset(),e.cssOnly||this.renderAll(),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 Math.sqrt(this.viewportTransform[0]*this.viewportTransform[3])},setViewportTransform:function(t){var e=this.getActiveGroup();this.viewportTransform=t;for(var 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,n=e.width||this.width,s=e.height||this.height,o='viewBox="0 0 '+this.width+" "+this.height+'" ',a=fabric.Object.NUM_FRACTION_DIGITS;e.viewBox?o='viewBox="'+e.viewBox.x+" "+e.viewBox.y+" "+e.viewBox.width+" "+e.viewBox.height+'" ':this.svgViewportTransformation&&(i=this.viewportTransform,o='viewBox="'+r(-i[4]/i[0],a)+" "+r(-i[5]/i[3],a)+" "+r(this.width/i[0],a)+" "+r(this.height/i[3],a)+'" '),t.push("\n',"Created with Fabric.js ",fabric.version,"\n","",fabric.createSVGFontFacesMarkup(this.getObjects()),fabric.createSVGRefElementsMarkup(this),"\n")},_setSVGObjects:function(t,e){for(var i,r,n=0,s=this.getObjects(),o=s.length;n\n"):this[e]&&"overlayColor"===e&&t.push('\n")},sendToBack:function(t){if(!t)return this;var e,r,n,s=this.getActiveGroup?this.getActiveGroup():null;if(t===s)for(n=s._objects,e=n.length;e--;)r=n[e],i(this._objects,r),this._objects.unshift(r);else i(this._objects,t),this._objects.unshift(t);return this.renderAll&&this.renderAll()},bringToFront:function(t){if(!t)return this;var e,r,n,s=this.getActiveGroup?this.getActiveGroup():null;if(t===s)for(n=s._objects,e=0;e=0;--n){var s=t.intersectsWithObject(this._objects[n])||t.isContainedWithinObject(this._objects[n])||this._objects[n].isContainedWithinObject(t);if(s){r=n;break}}}else r=e-1;return r},bringForward:function(t,e){if(!t)return this;var r,n,s,o,a,h=this.getActiveGroup?this.getActiveGroup():null;if(t===h)for(a=h._objects,r=a.length;r--;)n=a[r],s=this._objects.indexOf(n),s!==this._objects.length-1&&(o=s+1,i(this._objects,n),this._objects.splice(o,0,n));else s=this._objects.indexOf(t),s!==this._objects.length-1&&(o=this._findNewUpperIndex(t,s,e),i(this._objects,t),this._objects.splice(o,0,t));return this.renderAll&&this.renderAll(),this},_findNewUpperIndex:function(t,e,i){var r;if(i){r=e;for(var n=e+1;n"}}),t(fabric.StaticCanvas.prototype,fabric.Observable),t(fabric.StaticCanvas.prototype,fabric.Collection),t(fabric.StaticCanvas.prototype,fabric.DataURLExporter),t(fabric.StaticCanvas,{EMPTY_JSON:'{"objects": [], "background": "white"}',supports:function(t){var e=fabric.util.createCanvasElement();if(!e||!e.getContext)return null;var i=e.getContext("2d");if(!i)return null;switch(t){case"getImageData":return"undefined"!=typeof i.getImageData;case"setLineDash":return"undefined"!=typeof i.setLineDash;case"toDataURL":return"undefined"!=typeof e.toDataURL;case"toDataURLWithQuality":try{return e.toDataURL("image/jpeg",0),!0}catch(t){}return!1;default:return null}}}),fabric.StaticCanvas.prototype.toJSON=fabric.StaticCanvas.prototype.toObject}(),fabric.BaseBrush=fabric.util.createClass({color:"rgb(0, 0, 0)",width:1,shadow:null,strokeLineCap:"round",strokeLineJoin:"round",strokeDashArray:null,setShadow:function(t){return this.shadow=new fabric.Shadow(t),this},_setBrushStyles:function(){var t=this.canvas.contextTop;t.strokeStyle=this.color,t.lineWidth=this.width,t.lineCap=this.strokeLineCap,t.lineJoin=this.strokeLineJoin,this.strokeDashArray&&fabric.StaticCanvas.supports("setLineDash")&&t.setLineDash(this.strokeDashArray)},_setShadow:function(){if(this.shadow){var t=this.canvas.contextTop;t.shadowColor=this.shadow.color,t.shadowBlur=this.shadow.blur,t.shadowOffsetX=this.shadow.offsetX,t.shadowOffsetY=this.shadow.offsetY}},_resetShadow:function(){var t=this.canvas.contextTop;t.shadowColor="",t.shadowBlur=t.shadowOffsetX=t.shadowOffsetY=0}}),function(){fabric.PencilBrush=fabric.util.createClass(fabric.BaseBrush,{initialize:function(t){this.canvas=t,this._points=[]},onMouseDown:function(t){this._prepareForDrawing(t),this._captureDrawingPath(t),this._render()},onMouseMove:function(t){this._captureDrawingPath(t),this.canvas.clearContext(this.canvas.contextTop),this._render()},onMouseUp:function(){this._finalizeAndAddPath()},_prepareForDrawing:function(t){var e=new fabric.Point(t.x,t.y);this._reset(),this._addPoint(e),this.canvas.contextTop.moveTo(e.x,e.y)},_addPoint:function(t){this._points.push(t)},_reset:function(){this._points.length=0,this._setBrushStyles(),this._setShadow()},_captureDrawingPath:function(t){var e=new fabric.Point(t.x,t.y);this._addPoint(e)},_render:function(){var t=this.canvas.contextTop,e=this.canvas.viewportTransform,i=this._points[0],r=this._points[1];t.save(),t.transform(e[0],e[1],e[2],e[3],e[4],e[5]),t.beginPath(),2===this._points.length&&i.x===r.x&&i.y===r.y&&(i.x-=.5,r.x+=.5),t.moveTo(i.x,i.y);for(var n=1,s=this._points.length;n0?1:-1,"y"===i&&(s=e.target.skewY,o="top",a="bottom",r="originY"),n[-1]=o,n[1]=a,e.target.flipX&&(c*=-1),e.target.flipY&&(c*=-1),0===s?(e.skewSign=-h*t*c,e[r]=n[-t]):(s=s>0?1:-1,e.skewSign=s,e[r]=n[s*h*c])},_skewObject:function(t,e,i){var r=this._currentTransform,n=r.target,s=!1,o=n.get("lockSkewingX"),a=n.get("lockSkewingY");if(o&&"x"===i||a&&"y"===i)return!1;var h,c,l=n.getCenterPoint(),u=n.toLocalPoint(new fabric.Point(t,e),"center","center")[i],f=n.toLocalPoint(new fabric.Point(r.lastX,r.lastY),"center","center")[i],d=n._getTransformedDimensions();return this._changeSkewTransformOrigin(u-f,r,i),h=n.toLocalPoint(new fabric.Point(t,e),r.originX,r.originY)[i],c=n.translateToOriginPoint(l,r.originX,r.originY),s=this._setObjectSkew(h,r,i,d),r.lastX=t,r.lastY=e,n.setPositionByOrigin(c,r.originX,r.originY),s},_setObjectSkew:function(t,e,i,r){var n,s,o,a,h,c,l,u,f,d=e.target,g=!1,p=e.skewSign;return"x"===i?(a="y",h="Y",c="X",u=0,f=d.skewY):(a="x",h="X",c="Y",u=d.skewX,f=0),o=d._getTransformedDimensions(u,f),l=2*Math.abs(t)-o[i],l<=2?n=0:(n=p*Math.atan(l/d["scale"+c]/(o[a]/d["scale"+h])),n=fabric.util.radiansToDegrees(n)),g=d["skew"+c]!==n,d.set("skew"+c,n),0!==d["skew"+h]&&(s=d._getTransformedDimensions(),n=r[a]/s[a]*d["scale"+h],d.set("scale"+h,n)),g},_scaleObject:function(t,e,i){var r=this._currentTransform,n=r.target,s=n.get("lockScalingX"),o=n.get("lockScalingY"),a=n.get("lockScalingFlip");if(s&&o)return!1;var h=n.translateToOriginPoint(n.getCenterPoint(),r.originX,r.originY),c=n.toLocalPoint(new fabric.Point(t,e),r.originX,r.originY),l=n._getTransformedDimensions(),u=!1;return this._setLocalMouse(c,r),u=this._setObjectScale(c,r,s,o,i,a,l),n.setPositionByOrigin(h,r.originX,r.originY),u},_setObjectScale:function(t,e,i,r,n,s,o){var a,h,c,l,u=e.target,f=!1,d=!1,g=!1;return c=t.x*u.scaleX/o.x,l=t.y*u.scaleY/o.y,a=u.scaleX!==c,h=u.scaleY!==l,s&&c<=0&&ci.padding?t.x<0?t.x+=i.padding:t.x-=i.padding:t.x=0,n(t.y)>i.padding?t.y<0?t.y+=i.padding:t.y-=i.padding:t.y=0},_rotateObject:function(t,e){var n=this._currentTransform;if(n.target.get("lockRotation"))return!1;var s=r(n.ey-n.top,n.ex-n.left),o=r(e-n.top,t-n.left),a=i(o-s+n.theta);return a<0&&(a=360+a),n.target.angle=a%360,!0},setCursor:function(t){this.upperCanvasEl.style.cursor=t},_resetObjectTransform:function(t){t.scaleX=1,t.scaleY=1,t.skewX=0,t.skewY=0,t.setAngle(0)},_drawSelection:function(t){var e=this._groupSelector,i=e.left,r=e.top,o=n(i),a=n(r);if(t.fillStyle=this.selectionColor,t.fillRect(e.ex-(i>0?0:-i),e.ey-(r>0?0:-r),o,a),t.lineWidth=this.selectionLineWidth,t.strokeStyle=this.selectionBorderColor,this.selectionDashArray.length>1){var h=e.ex+s-(i>0?0:o),c=e.ey+s-(r>0?0:a);t.beginPath(),fabric.util.drawDashedLine(t,h,c,h+o,c,this.selectionDashArray),fabric.util.drawDashedLine(t,h,c+a-1,h+o,c+a-1,this.selectionDashArray),fabric.util.drawDashedLine(t,h,c,h,c+a,this.selectionDashArray),fabric.util.drawDashedLine(t,h+o-1,c,h+o-1,c+a,this.selectionDashArray),t.closePath(),t.stroke()}else t.strokeRect(e.ex+s-(i>0?0:o),e.ey+s-(r>0?0:a),o,a)},findTarget:function(t,e){if(!this.skipTargetFind){var i=!0,r=this.getPointer(t,i),n=this.getActiveGroup(),s=this.getActiveObject();if(n&&!e&&this._checkTarget(r,n))return n;if(s&&this._checkTarget(r,s))return s;this.targets=[];var o=this._searchPossibleTargets(this._objects,r);return this._fireOverOutEvents(o,t),o}},_fireOverOutEvents:function(t,e){t?this._hoveredTarget!==t&&(this._hoveredTarget&&(this.fire("mouse:out",{target:this._hoveredTarget,e:e}),this._hoveredTarget.fire("mouseout")),this.fire("mouse:over",{target:t,e:e}),t.fire("mouseover"),this._hoveredTarget=t):this._hoveredTarget&&(this.fire("mouse:out",{target:this._hoveredTarget,e:e}),this._hoveredTarget.fire("mouseout"),this._hoveredTarget=null)},_checkTarget:function(t,e){if(e&&e.visible&&e.evented&&this.containsPoint(null,e,t)){if(!this.perPixelTargetFind&&!e.perPixelTargetFind||e.isEditing)return!0;var i=this.isTargetTransparent(e,t.x,t.y);if(!i)return!0}},_searchPossibleTargets:function(t,e){for(var i,r,n,s=t.length;s--;)if(this._checkTarget(e,t[s])){i=t[s],"group"===i.type&&i.subTargetCheck&&(r=this._normalizePointer(i,e),n=this._searchPossibleTargets(i._objects,r),n&&this.targets.push(n));break}return i},restorePointerVpt:function(t){return fabric.util.transformPoint(t,fabric.util.invertTransform(this.viewportTransform))},getPointer:function(e,i,r){r||(r=this.upperCanvasEl);var n,s=t(e),o=r.getBoundingClientRect(),a=o.width||0,h=o.height||0;return a&&h||("top"in o&&"bottom"in o&&(h=Math.abs(o.top-o.bottom)),"right"in o&&"left"in o&&(a=Math.abs(o.right-o.left))),this.calcOffset(),s.x=s.x-this._offset.left,s.y=s.y-this._offset.top,i||(s=this.restorePointerVpt(s)),n=0===a||0===h?{width:1,height:1}:{width:r.width/a,height:r.height/h},{x:s.x*n.width,y:s.y*n.height}},_createUpperCanvas:function(){var t=this.lowerCanvasEl.className.replace(/\s*lower-canvas\s*/,"");this.upperCanvasEl=this._createCanvasElement(),fabric.util.addClass(this.upperCanvasEl,"upper-canvas "+t),this.wrapperEl.appendChild(this.upperCanvasEl),this._copyCanvasStyle(this.lowerCanvasEl,this.upperCanvasEl),this._applyCanvasStyle(this.upperCanvasEl),this.contextTop=this.upperCanvasEl.getContext("2d")},_createCacheCanvas:function(){this.cacheCanvasEl=this._createCanvasElement(),this.cacheCanvasEl.setAttribute("width",this.width),this.cacheCanvasEl.setAttribute("height",this.height),this.contextCache=this.cacheCanvasEl.getContext("2d")},_initWrapperElement:function(){this.wrapperEl=fabric.util.wrapElement(this.lowerCanvasEl,"div",{class:this.containerClass}),fabric.util.setStyle(this.wrapperEl,{width:this.getWidth()+"px",height:this.getHeight()+"px",position:"relative"}),fabric.util.makeElementUnselectable(this.wrapperEl)},_applyCanvasStyle:function(t){var e=this.getWidth()||t.width,i=this.getHeight()||t.height;fabric.util.setStyle(t,{position:"absolute",width:e+"px",height:i+"px",left:0,top:0}),t.width=e,t.height=i,fabric.util.makeElementUnselectable(t)},_copyCanvasStyle:function(t,e){e.style.cssText=t.style.cssText},getSelectionContext:function(){return this.contextTop},getSelectionElement:function(){return this.upperCanvasEl},_setActiveObject:function(t){this._activeObject&&this._activeObject.set("active",!1),this._activeObject=t,t.set("active",!0)},setActiveObject:function(t,e){return this._setActiveObject(t),this.renderAll(),this.fire("object:selected",{target:t,e:e}),t.fire("selected",{e:e}),this},getActiveObject:function(){return this._activeObject},_onObjectRemoved:function(t){this.getActiveObject()===t&&(this.fire("before:selection:cleared",{target:t}),this._discardActiveObject(),this.fire("selection:cleared",{target:t}),t.fire("deselected")),this.callSuper("_onObjectRemoved",t)},_discardActiveObject:function(){this._activeObject&&this._activeObject.set("active",!1),this._activeObject=null},discardActiveObject:function(t){var e=this._activeObject;return this.fire("before:selection:cleared",{target:e,e:t}),this._discardActiveObject(),this.fire("selection:cleared",{e:t}),e&&e.fire("deselected",{e:t}),this},_setActiveGroup:function(t){this._activeGroup=t,t&&t.set("active",!0)},setActiveGroup:function(t,e){return this._setActiveGroup(t),t&&(this.fire("object:selected",{target:t,e:e}),t.fire("selected",{e:e})),this},getActiveGroup:function(){return this._activeGroup},_discardActiveGroup:function(){var t=this.getActiveGroup();t&&t.destroy(),this.setActiveGroup(null)},discardActiveGroup:function(t){var e=this.getActiveGroup();return this.fire("before:selection:cleared",{e:t,target:e}),this._discardActiveGroup(),this.fire("selection:cleared",{e:t}),this},deactivateAll:function(){for(var t=this.getObjects(),e=0,i=t.length;e1)){var r=this._groupSelector;r?(i=this.getPointer(t,!0),r.left=i.x-r.ex,r.top=i.y-r.ey,this.renderTop()):this._currentTransform?this._transformObject(t):(e=this.findTarget(t),this._setCursorFromEvent(t,e)),this._handleEvent(t,"move",e?e:null)}},__onMouseWheel:function(t){this.fire("mouse:wheel",{e:t})},_transformObject:function(t){var e=this.getPointer(t),i=this._currentTransform;i.reset=!1,i.target.isMoving=!0,this._beforeScaleTransform(t,i),this._performTransformAction(t,i,e),i.actionPerformed&&this.renderAll()},_performTransformAction:function(t,e,i){var r=i.x,n=i.y,s=e.target,o=e.action,a=!1;"rotate"===o?(a=this._rotateObject(r,n))&&this._fire("rotating",s,t):"scale"===o?(a=this._onScale(t,e,r,n))&&this._fire("scaling",s,t):"scaleX"===o?(a=this._scaleObject(r,n,"x"))&&this._fire("scaling",s,t):"scaleY"===o?(a=this._scaleObject(r,n,"y"))&&this._fire("scaling",s,t):"skewX"===o?(a=this._skewObject(r,n,"x"))&&this._fire("skewing",s,t):"skewY"===o?(a=this._skewObject(r,n,"y"))&&this._fire("skewing",s,t):(a=this._translateObject(r,n),a&&(this._fire("moving",s,t),this.setCursor(s.moveCursor||this.moveCursor))),e.actionPerformed=a},_fire:function(t,e,i){this.fire("object:"+t,{target:e,e:i}),e.fire(t,{e:i})},_beforeScaleTransform:function(t,e){if("scale"===e.action||"scaleX"===e.action||"scaleY"===e.action){var i=this._shouldCenterTransform(e.target);(i&&("center"!==e.originX||"center"!==e.originY)||!i&&"center"===e.originX&&"center"===e.originY)&&(this._resetCurrentTransform(),e.reset=!0)}},_onScale:function(t,e,i,r){return!t[this.uniScaleKey]&&!this.uniScaleTransform||e.target.get("lockUniScaling")?(e.reset||"scale"!==e.currentAction||this._resetCurrentTransform(),e.currentAction="scaleEqually",this._scaleObject(i,r,"equally")):(e.currentAction="scale",this._scaleObject(i,r))},_setCursorFromEvent:function(t,e){if(!e)return this.setCursor(this.defaultCursor),!1;var i=e.hoverCursor||this.hoverCursor;if(e.selectable){var r=this.getActiveGroup(),n=e._findTargetCorner&&(!r||!r.contains(e))&&e._findTargetCorner(this.getPointer(t,!0));n?this._setCornerCursor(n,e,t):this.setCursor(i)}else this.setCursor(i);return!0},_setCornerCursor:function(e,i,r){if(e in t)this.setCursor(this._getRotatedCornerCursor(e,i,r));else{if("mtr"!==e||!i.hasRotatingPoint)return this.setCursor(this.defaultCursor),!1;this.setCursor(this.rotationCursor)}},_getRotatedCornerCursor:function(e,i,r){var n=Math.round(i.getAngle()%360/45);return n<0&&(n+=8),n+=t[e],r[this.altActionKey]&&t[e]%2===0&&(n+=2),n%=8,this.cursorMap[n]}})}(),function(){var t=Math.min,e=Math.max;fabric.util.object.extend(fabric.Canvas.prototype,{_shouldGroup:function(t,e){var i=this.getActiveObject();return t[this.selectionKey]&&e&&e.selectable&&(this.getActiveGroup()||i&&i!==e)&&this.selection},_handleGrouping:function(t,e){var i=this.getActiveGroup();(e!==i||(e=this.findTarget(t,!0)))&&(i?this._updateActiveGroup(e,t):this._createActiveGroup(e,t),this._activeGroup&&this._activeGroup.saveCoords())},_updateActiveGroup:function(t,e){var i=this.getActiveGroup();if(i.contains(t)){if(i.removeWithUpdate(t),t.set("active",!1),1===i.size())return this.discardActiveGroup(e),void this.setActiveObject(i.item(0))}else i.addWithUpdate(t);this.fire("selection:created",{target:i,e:e}),i.set("active",!0)},_createActiveGroup:function(t,e){if(this._activeObject&&t!==this._activeObject){var i=this._createGroup(t);i.addWithUpdate(),this.setActiveGroup(i),this._activeObject=null,this.fire("selection:created",{target:i,e:e})}t.set("active",!0)},_createGroup:function(t){var e=this.getObjects(),i=e.indexOf(this._activeObject)1&&(e=new fabric.Group(e.reverse(),{canvas:this}),e.addWithUpdate(),this.setActiveGroup(e,t),e.saveCoords(),this.fire("selection:created",{target:e}),this.renderAll())},_collectObjects:function(){for(var i,r=[],n=this._groupSelector.ex,s=this._groupSelector.ey,o=n+this._groupSelector.left,a=s+this._groupSelector.top,h=new fabric.Point(t(n,o),t(s,a)),c=new fabric.Point(e(n,o),e(s,a)),l=n===o&&s===a,u=this._objects.length;u--&&(i=this._objects[u],!(i&&i.selectable&&i.visible&&(i.intersectsWithRect(h,c)||i.isContainedWithinRect(h,c)||i.containsPoint(h)||i.containsPoint(c))&&(i.set("active",!0),r.push(i),l))););return r},_maybeGroupObjects:function(t){this.selection&&this._groupSelector&&this._groupSelectedObjects(t);var e=this.getActiveGroup();e&&(e.setObjectsCoords().setCoords(),e.isMoving=!1,this.setCursor(this.defaultCursor)),this._groupSelector=null,this._currentTransform=null}})}(),fabric.util.object.extend(fabric.StaticCanvas.prototype,{toDataURL:function(t){t||(t={});var e=t.format||"png",i=t.quality||1,r=t.multiplier||1,n={left:t.left,top:t.top,width:t.width,height:t.height};return this._isRetinaScaling()&&(r*=fabric.devicePixelRatio),1!==r?this.__toDataURLWithMultiplier(e,i,n,r):this.__toDataURL(e,i,n)},__toDataURL:function(t,e,i){this.renderAll();var r=this.contextContainer.canvas,n=this.__getCroppedCanvas(r,i);"jpg"===t&&(t="jpeg");var s=fabric.StaticCanvas.supports("toDataURLWithQuality")?(n||r).toDataURL("image/"+t,e):(n||r).toDataURL("image/"+t);return n&&(n=null),s},__getCroppedCanvas:function(t,e){var i,r,n="left"in e||"top"in e||"width"in e||"height"in e;return n&&(i=fabric.util.createCanvasElement(),r=i.getContext("2d"),i.width=e.width||this.width,i.height=e.height||this.height,r.drawImage(t,-e.left||0,-e.top||0)),i},__toDataURLWithMultiplier:function(t,e,i,r){var n=this.getWidth(),s=this.getHeight(),o=n*r,a=s*r,h=this.getActiveObject(),c=this.getActiveGroup(),l=this.getZoom(),u=l*r/fabric.devicePixelRatio;r>1&&this.setDimensions({width:o,height:a}),this.setZoom(u),i.left&&(i.left*=r),i.top&&(i.top*=r),i.width?i.width*=r:r<1&&(i.width=o),i.height?i.height*=r:r<1&&(i.height=a),c?this._tempRemoveBordersControlsFromGroup(c):h&&this.deactivateAll&&this.deactivateAll();var f=this.__toDataURL(t,e,i);return c?this._restoreBordersControlsOnGroup(c):h&&this.setActiveObject&&this.setActiveObject(h),this.setZoom(l),this.setDimensions({width:n,height:s}),f},toDataURLWithMultiplier:function(t,e,i){return this.toDataURL({format:t,multiplier:e,quality:i})},_tempRemoveBordersControlsFromGroup:function(t){t.origHasControls=t.hasControls,t.origBorderColor=t.borderColor,t.hasControls=!0,t.borderColor="rgba(0,0,0,0)",t.forEachObject(function(t){t.origBorderColor=t.borderColor,t.borderColor="rgba(0,0,0,0)"})},_restoreBordersControlsOnGroup:function(t){t.hideControls=t.origHideControls,t.borderColor=t.origBorderColor,t.forEachObject(function(t){t.borderColor=t.origBorderColor,delete t.origBorderColor})}}),fabric.util.object.extend(fabric.StaticCanvas.prototype,{loadFromDatalessJSON:function(t,e,i){return this.loadFromJSON(t,e,i)},loadFromJSON:function(t,e,i){if(t){var r="string"==typeof t?JSON.parse(t):fabric.util.object.clone(t);this.clear();var n=this;return this._enlivenObjects(r.objects,function(){n._setBgOverlay(r,function(){delete r.objects,delete r.backgroundImage,delete r.overlayImage,delete r.background,delete r.overlay;for(var t in r)n[t]=r[t];e&&e()})},i),this}},_setBgOverlay:function(t,e){var i=this,r={backgroundColor:!1,overlayColor:!1,backgroundImage:!1,overlayImage:!1};if(!(t.backgroundImage||t.overlayImage||t.background||t.overlay))return void(e&&e());var n=function(){r.backgroundImage&&r.overlayImage&&r.backgroundColor&&r.overlayColor&&(i.renderAll(),e&&e())};this.__setBgOverlay("backgroundImage",t.backgroundImage,r,n),this.__setBgOverlay("overlayImage",t.overlayImage,r,n),this.__setBgOverlay("backgroundColor",t.background,r,n),this.__setBgOverlay("overlayColor",t.overlay,r,n),n()},__setBgOverlay:function(t,e,i,r){var n=this;return e?void("backgroundImage"===t||"overlayImage"===t?fabric.Image.fromObject(e,function(e){n[t]=e,i[t]=!0,r&&r()}):this["set"+fabric.util.string.capitalize(t,!0)](e,function(){i[t]=!0,r&&r()})):void(i[t]=!0)},_enlivenObjects:function(t,e,i){var r=this;if(!t||0===t.length)return void(e&&e());var n=this.renderOnAddRemove;this.renderOnAddRemove=!1,fabric.util.enlivenObjects(t,function(t){t.forEach(function(t,e){r.insertAt(t,e)}),r.renderOnAddRemove=n,e&&e()},null,i)},_toDataURL:function(t,e){this.clone(function(i){e(i.toDataURL(t))})},_toDataURLWithMultiplier:function(t,e,i){this.clone(function(r){i(r.toDataURLWithMultiplier(t,e))})},clone:function(t,e){var i=JSON.stringify(this.toJSON(e));this.cloneWithoutData(function(e){e.loadFromJSON(i,function(){t&&t(e)})})},cloneWithoutData:function(t){var e=fabric.document.createElement("canvas");e.width=this.getWidth(),e.height=this.getHeight();var i=new fabric.Canvas(e);i.clipTo=this.clipTo,this.backgroundImage?(i.setBackgroundImage(this.backgroundImage.src,function(){i.renderAll(),t&&t(i)}),i.backgroundImageOpacity=this.backgroundImageOpacity,i.backgroundImageStretch=this.backgroundImageStretch):t&&t(i)}}),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=e.util.object.extend,r=e.util.toFixed,n=e.util.string.capitalize,s=e.util.degreesToRadians,o=e.StaticCanvas.supports("setLineDash");e.Object||(e.Object=e.util.createClass({type:"object",originX:"left",originY:"top",top:0,left:0,width:0,height:0,scaleX:1,scaleY:1,flipX:!1,flipY:!1,opacity:1,angle:0,skewX:0,skewY:0,cornerSize:13,transparentCorners:!0,hoverCursor:null,moveCursor:null,padding:0,borderColor:"rgba(102,153,255,0.75)",borderDashArray:null,cornerColor:"rgba(102,153,255,0.5)",cornerStrokeColor:null,cornerStyle:"rect",cornerDashArray:null,centeredScaling:!1,centeredRotation:!0,fill:"rgb(0,0,0)",fillRule:"nonzero",globalCompositeOperation:"source-over",backgroundColor:"",selectionBackgroundColor:"",stroke:null,strokeWidth:1,strokeDashArray:null,strokeLineCap:"butt",strokeLineJoin:"miter",strokeMiterLimit:10,shadow:null,borderOpacityWhenMoving:.4,borderScaleFactor:1,transformMatrix:null,minScaleLimit:.01,selectable:!0,evented:!0,visible:!0,hasControls:!0,hasBorders:!0,hasRotatingPoint:!0,rotatingPointOffset:40,perPixelTargetFind:!1,includeDefaultValues:!0,clipTo:null,lockMovementX:!1,lockMovementY:!1,lockRotation:!1,lockScalingX:!1,lockScalingY:!1,lockUniScaling:!1,lockSkewingX:!1,lockSkewingY:!1,lockScalingFlip:!1,excludeFromExport:!1,stateProperties:"top left width height scaleX scaleY flipX flipY originX originY transformMatrix stroke strokeWidth strokeDashArray strokeLineCap strokeLineJoin strokeMiterLimit angle opacity fill fillRule globalCompositeOperation shadow clipTo visible backgroundColor alignX alignY meetOrSlice skewX skewY".split(" "),initialize:function(t){t&&this.setOptions(t)},_initGradient:function(t){!t.fill||!t.fill.colorStops||t.fill instanceof e.Gradient||this.set("fill",new e.Gradient(t.fill)),!t.stroke||!t.stroke.colorStops||t.stroke instanceof e.Gradient||this.set("stroke",new e.Gradient(t.stroke))},_initPattern:function(t){!t.fill||!t.fill.source||t.fill instanceof e.Pattern||this.set("fill",new e.Pattern(t.fill)),!t.stroke||!t.stroke.source||t.stroke instanceof e.Pattern||this.set("stroke",new e.Pattern(t.stroke))},_initClipping:function(t){if(t.clipTo&&"string"==typeof t.clipTo){var i=e.util.getFunctionBody(t.clipTo);"undefined"!=typeof i&&(this.clipTo=new Function("ctx",i))}},setOptions:function(t){for(var e in t)this.set(e,t[e]);this._initGradient(t),this._initPattern(t),this._initClipping(t)},transform:function(t,e){this.group&&!this.group._transformDone&&this.group===this.canvas._activeGroup&&this.group.transform(t);var i=e?this._getLeftTopCoords():this.getCenterPoint();t.translate(i.x,i.y),t.rotate(s(this.angle)),t.scale(this.scaleX*(this.flipX?-1:1),this.scaleY*(this.flipY?-1:1)),t.transform(1,0,Math.tan(s(this.skewX)),1,0,0),t.transform(1,Math.tan(s(this.skewY)),0,1,0,0)},toObject:function(t){var i=e.Object.NUM_FRACTION_DIGITS,n={type:this.type,originX:this.originX,originY:this.originY,left:r(this.left,i),top:r(this.top,i),width:r(this.width,i),height:r(this.height,i),fill:this.fill&&this.fill.toObject?this.fill.toObject():this.fill,stroke:this.stroke&&this.stroke.toObject?this.stroke.toObject():this.stroke,strokeWidth:r(this.strokeWidth,i),strokeDashArray:this.strokeDashArray?this.strokeDashArray.concat():this.strokeDashArray,strokeLineCap:this.strokeLineCap,strokeLineJoin:this.strokeLineJoin,strokeMiterLimit:r(this.strokeMiterLimit,i),scaleX:r(this.scaleX,i),scaleY:r(this.scaleY,i),angle:r(this.getAngle(),i),flipX:this.flipX,flipY:this.flipY,opacity:r(this.opacity,i),shadow:this.shadow&&this.shadow.toObject?this.shadow.toObject():this.shadow,visible:this.visible,clipTo:this.clipTo&&String(this.clipTo),backgroundColor:this.backgroundColor,fillRule:this.fillRule,globalCompositeOperation:this.globalCompositeOperation,transformMatrix:this.transformMatrix?this.transformMatrix.concat():this.transformMatrix,skewX:r(this.skewX,i),skewY:r(this.skewY,i)};return this.includeDefaultValues||(n=this._removeDefaultValues(n)),e.util.populateWithProperties(this,n,t),n},toDatalessObject:function(t){return this.toObject(t)},_removeDefaultValues:function(t){var i=e.util.getKlass(t.type).prototype,r=i.stateProperties;return r.forEach(function(e){t[e]===i[e]&&delete t[e];var r="[object Array]"===Object.prototype.toString.call(t[e])&&"[object Array]"===Object.prototype.toString.call(i[e]);r&&0===t[e].length&&0===i[e].length&&delete t[e]}),t},toString:function(){return"#"},get:function(t){return this[t]},getObjectScaling:function(){var t=this.scaleX,e=this.scaleY;if(this.group){var i=this.group.getObjectScaling();t*=i.scaleX,e*=i.scaleY}return{scaleX:t,scaleY:e}},_setObject:function(t){for(var e in t)this._set(e,t[e])},set:function(t,e){return"object"==typeof t?this._setObject(t):"function"==typeof e&&"clipTo"!==t?this._set(t,e(this.get(t))):this._set(t,e),this},_set:function(t,i){var r="scaleX"===t||"scaleY"===t;return r&&(i=this._constrainScale(i)),"scaleX"===t&&i<0?(this.flipX=!this.flipX,i*=-1):"scaleY"===t&&i<0?(this.flipY=!this.flipY,i*=-1):"shadow"!==t||!i||i instanceof e.Shadow||(i=new e.Shadow(i)),this[t]=i,"width"!==t&&"height"!==t||(this.minScaleLimit=Math.min(.1,1/Math.max(this.width,this.height))),this},setOnGroup:function(){},toggle:function(t){var e=this.get(t);return"boolean"==typeof e&&this.set(t,!e),this},setSourcePath:function(t){return this.sourcePath=t,this},getViewportTransform:function(){return this.canvas&&this.canvas.viewportTransform?this.canvas.viewportTransform:[1,0,0,1,0,0]},render:function(t,i){0===this.width&&0===this.height||!this.visible||(t.save(),this._setupCompositeOperation(t),this.drawSelectionBackground(t),i||this.transform(t),this._setStrokeStyles(t),this._setFillStyles(t),this.transformMatrix&&t.transform.apply(t,this.transformMatrix),this._setOpacity(t),this._setShadow(t),this.clipTo&&e.util.clipContext(this,t),this._render(t,i),this.clipTo&&t.restore(),t.restore())},_setOpacity:function(t){this.group&&this.group._setOpacity(t),t.globalAlpha*=this.opacity},_setStrokeStyles:function(t){this.stroke&&(t.lineWidth=this.strokeWidth,t.lineCap=this.strokeLineCap,t.lineJoin=this.strokeLineJoin,t.miterLimit=this.strokeMiterLimit,t.strokeStyle=this.stroke.toLive?this.stroke.toLive(t,this):this.stroke)},_setFillStyles:function(t){this.fill&&(t.fillStyle=this.fill.toLive?this.fill.toLive(t,this):this.fill)},_setLineDash:function(t,e,i){e&&(1&e.length&&e.push.apply(e,e),o?t.setLineDash(e):i&&i(t))},_renderControls:function(t,i){if(!(!this.active||i||this.group&&this.group!==this.canvas.getActiveGroup())){var r,n=this.getViewportTransform(),o=this.calcTransformMatrix();o=e.util.multiplyTransformMatrices(n,o),r=e.util.qrDecompose(o),t.save(),t.translate(r.translateX,r.translateY),t.lineWidth=1*this.borderScaleFactor,t.globalAlpha=this.isMoving?this.borderOpacityWhenMoving:1,this.group&&this.group===this.canvas.getActiveGroup()?(t.rotate(s(r.angle)),this.drawBordersInGroup(t,r)):(t.rotate(s(this.angle)),this.drawBorders(t)),this.drawControls(t),t.restore()}},_setShadow:function(t){if(this.shadow){var i=this.canvas&&this.canvas.viewportTransform[0]||1,r=this.canvas&&this.canvas.viewportTransform[3]||1,n=this.getObjectScaling();this.canvas&&this.canvas._isRetinaScaling()&&(i*=e.devicePixelRatio,r*=e.devicePixelRatio),t.shadowColor=this.shadow.color,t.shadowBlur=this.shadow.blur*(i+r)*(n.scaleX+n.scaleY)/4,t.shadowOffsetX=this.shadow.offsetX*i*n.scaleX,t.shadowOffsetY=this.shadow.offsetY*r*n.scaleY}},_removeShadow:function(t){this.shadow&&(t.shadowColor="",t.shadowBlur=t.shadowOffsetX=t.shadowOffsetY=0)},_renderFill:function(t){if(this.fill){if(t.save(),this.fill.gradientTransform){var e=this.fill.gradientTransform;t.transform.apply(t,e)}this.fill.toLive&&t.translate(-this.width/2+this.fill.offsetX||0,-this.height/2+this.fill.offsetY||0),"evenodd"===this.fillRule?t.fill("evenodd"):t.fill(),t.restore()}},_renderStroke:function(t){if(this.stroke&&0!==this.strokeWidth){if(this.shadow&&!this.shadow.affectStroke&&this._removeShadow(t),t.save(),this._setLineDash(t,this.strokeDashArray,this._renderDashedStroke),this.stroke.gradientTransform){var e=this.stroke.gradientTransform;t.transform.apply(t,e)}this.stroke.toLive&&t.translate(-this.width/2+this.stroke.offsetX||0,-this.height/2+this.stroke.offsetY||0),t.stroke(),t.restore()}},clone:function(t,i){return this.constructor.fromObject?this.constructor.fromObject(this.toObject(i),t):new e.Object(this.toObject(i))},cloneAsImage:function(t,i){var r=this.toDataURL(i);return e.util.loadImage(r,function(i){t&&t(new e.Image(i))}),this},toDataURL:function(t){t||(t={});var i=e.util.createCanvasElement(),r=this.getBoundingRect();i.width=r.width,i.height=r.height,e.util.wrapElement(i,"div");var n=new e.StaticCanvas(i,{enableRetinaScaling:t.enableRetinaScaling});"jpg"===t.format&&(t.format="jpeg"),"jpeg"===t.format&&(n.backgroundColor="#fff");var s={active:this.get("active"),left:this.getLeft(),top:this.getTop()};this.set("active",!1),this.setPositionByOrigin(new e.Point(n.getWidth()/2,n.getHeight()/2),"center","center");var o=this.canvas;n.add(this);var a=n.toDataURL(t);return this.set(s).setCoords(),this.canvas=o,n.dispose(),n=null,a},isType:function(t){return this.type===t},complexity:function(){return 0},toJSON:function(t){return this.toObject(t)},setGradient:function(t,i){i||(i={});var r={colorStops:[]};r.type=i.type||(i.r1||i.r2?"radial":"linear"),r.coords={x1:i.x1,y1:i.y1,x2:i.x2,y2:i.y2},(i.r1||i.r2)&&(r.coords.r1=i.r1,r.coords.r2=i.r2),i.gradientTransform&&(r.gradientTransform=i.gradientTransform);for(var n in i.colorStops){var s=new e.Color(i.colorStops[n]);r.colorStops.push({offset:n,color:s.toRgb(),opacity:s.getAlpha()})}return this.set(t,e.Gradient.forObject(this,r))},setPatternFill:function(t){return this.set("fill",new e.Pattern(t))},setShadow:function(t){return this.set("shadow",t?new e.Shadow(t):null)},setColor:function(t){return this.set("fill",t),this},setAngle:function(t){var e=("center"!==this.originX||"center"!==this.originY)&&this.centeredRotation;return e&&this._setOriginToCenter(),this.set("angle",t),e&&this._resetOrigin(),this},centerH:function(){return this.canvas&&this.canvas.centerObjectH(this),this},viewportCenterH:function(){return this.canvas&&this.canvas.viewportCenterObjectH(this),this},centerV:function(){return this.canvas&&this.canvas.centerObjectV(this),this},viewportCenterV:function(){return this.canvas&&this.canvas.viewportCenterObjectV(this),this},center:function(){return this.canvas&&this.canvas.centerObject(this),this},viewportCenter:function(){return this.canvas&&this.canvas.viewportCenterObject(this),this},remove:function(){return this.canvas&&this.canvas.remove(this),this},getLocalPointer:function(t,i){i=i||this.canvas.getPointer(t);var r=new e.Point(i.x,i.y),n=this._getLeftTopCoords();return this.angle&&(r=e.util.rotatePoint(r,n,e.util.degreesToRadians(-this.angle))),{x:r.x-n.x,y:r.y-n.y}},_setupCompositeOperation:function(t){this.globalCompositeOperation&&(t.globalCompositeOperation=this.globalCompositeOperation)}}),e.util.createAccessors(e.Object),e.Object.prototype.rotate=e.Object.prototype.setAngle,i(e.Object.prototype,e.Observable),e.Object.NUM_FRACTION_DIGITS=2,e.Object.__uid=0)}("undefined"!=typeof exports?exports:this),function(){var t=fabric.util.degreesToRadians,e={left:-.5,center:0,right:.5},i={top:-.5,center:0,bottom:.5};fabric.util.object.extend(fabric.Object.prototype,{translateToGivenOrigin:function(t,r,n,s,o){var a,h,c,l=t.x,u=t.y;return"string"==typeof r?r=e[r]:r-=.5,"string"==typeof s?s=e[s]:s-=.5,a=s-r,"string"==typeof n?n=i[n]:n-=.5,"string"==typeof o?o=i[o]:o-=.5,h=o-n,(a||h)&&(c=this._getTransformedDimensions(),l=t.x+a*c.x,u=t.y+h*c.y),new fabric.Point(l,u)},translateToCenterPoint:function(e,i,r){var n=this.translateToGivenOrigin(e,i,r,"center","center");return this.angle?fabric.util.rotatePoint(n,e,t(this.angle)):n},translateToOriginPoint:function(e,i,r){var n=this.translateToGivenOrigin(e,"center","center",i,r);return this.angle?fabric.util.rotatePoint(n,e,t(this.angle)):n},getCenterPoint:function(){var t=new fabric.Point(this.left,this.top);return this.translateToCenterPoint(t,this.originX,this.originY)},getPointByOrigin:function(t,e){var i=this.getCenterPoint();return this.translateToOriginPoint(i,t,e)},toLocalPoint:function(e,i,r){var n,s,o=this.getCenterPoint();return n="undefined"!=typeof i&&"undefined"!=typeof r?this.translateToGivenOrigin(o,"center","center",i,r):new fabric.Point(this.left,this.top),s=new fabric.Point(e.x,e.y),this.angle&&(s=fabric.util.rotatePoint(s,o,-t(this.angle))),s.subtractEquals(n)},setPositionByOrigin:function(t,e,i){var r=this.translateToCenterPoint(t,e,i),n=this.translateToOriginPoint(r,this.originX,this.originY);this.set("left",n.x),this.set("top",n.y)},adjustPosition:function(i){var r,n,s=t(this.angle),o=this.getWidth(),a=Math.cos(s)*o,h=Math.sin(s)*o;r="string"==typeof this.originX?e[this.originX]:this.originX-.5,n="string"==typeof i?e[i]:i-.5,this.left+=a*(n-r),this.top+=h*(n-r),this.setCoords(),this.originX=i},_setOriginToCenter:function(){this._originalOriginX=this.originX,this._originalOriginY=this.originY;var t=this.getCenterPoint();this.originX="center",this.originY="center",this.left=t.x,this.top=t.y},_resetOrigin:function(){var t=this.translateToOriginPoint(this.getCenterPoint(),this._originalOriginX,this._originalOriginY);this.originX=this._originalOriginX,this.originY=this._originalOriginY,this.left=t.x,this.top=t.y,this._originalOriginX=null,this._originalOriginY=null},_getLeftTopCoords:function(){return this.translateToOriginPoint(this.getCenterPoint(),"left","top")}})}(),function(){function t(t){return[new fabric.Point(t.tl.x,t.tl.y),new fabric.Point(t.tr.x,t.tr.y),new fabric.Point(t.br.x,t.br.y),new fabric.Point(t.bl.x,t.bl.y)]}var e=fabric.util.degreesToRadians,i=fabric.util.multiplyTransformMatrices;fabric.util.object.extend(fabric.Object.prototype,{oCoords:null,intersectsWithRect:function(e,i){var r=t(this.oCoords),n=fabric.Intersection.intersectPolygonRectangle(r,e,i);return"Intersection"===n.status},intersectsWithObject:function(e){var i=fabric.Intersection.intersectPolygonPolygon(t(this.oCoords),t(e.oCoords));return"Intersection"===i.status},isContainedWithinObject:function(t){var e=t.getBoundingRect(),i=new fabric.Point(e.left,e.top),r=new fabric.Point(e.left+e.width,e.top+e.height);return this.isContainedWithinRect(i,r)},isContainedWithinRect:function(t,e){var i=this.getBoundingRect();return i.left>=t.x&&i.left+i.width<=e.x&&i.top>=t.y&&i.top+i.height<=e.y},containsPoint:function(t){this.oCoords||this.setCoords();var e=this._getImageLines(this.oCoords),i=this._findCrossPoints(t,e);return 0!==i&&i%2===1},_getImageLines:function(t){return{topline:{o:t.tl,d:t.tr},rightline:{o:t.tr,d:t.br},bottomline:{o:t.br,d:t.bl},leftline:{o:t.bl,d:t.tl}}},_findCrossPoints:function(t,e){var i,r,n,s,o,a,h,c=0;for(var l in e)if(h=e[l],!(h.o.y=t.y&&h.d.y>=t.y||(h.o.x===h.d.x&&h.o.x>=t.x?(o=h.o.x,a=t.y):(i=0,r=(h.d.y-h.o.y)/(h.d.x-h.o.x),n=t.y-i*t.x,s=h.o.y-r*h.o.x,o=-(n-s)/(i-r),a=n+i*o),o>=t.x&&(c+=1),2!==c)))break;return c},getBoundingRectWidth:function(){return this.getBoundingRect().width},getBoundingRectHeight:function(){return this.getBoundingRect().height},getBoundingRect:function(){return this.oCoords||this.setCoords(),fabric.util.makeBoundingBoxFromPoints([this.oCoords.tl,this.oCoords.tr,this.oCoords.br,this.oCoords.bl])},getWidth:function(){return this._getTransformedDimensions().x},getHeight:function(){return this._getTransformedDimensions().y},_constrainScale:function(t){return Math.abs(t)0?Math.atan(s/n):0,c=n/Math.cos(h)/2,l=Math.cos(h+t)*c,u=Math.sin(h+t)*c,f=fabric.util.transformPoint(this.getCenterPoint(),i),d=new fabric.Point(f.x-l,f.y-u),g=new fabric.Point(d.x+n*a,d.y+n*o),p=new fabric.Point(d.x-s*o,d.y+s*a),v=new fabric.Point(f.x+l,f.y+u),b=new fabric.Point((d.x+p.x)/2,(d.y+p.y)/2),m=new fabric.Point((g.x+d.x)/2,(g.y+d.y)/2),y=new fabric.Point((v.x+g.x)/2,(v.y+g.y)/2),_=new fabric.Point((v.x+p.x)/2,(v.y+p.y)/2),x=new fabric.Point(m.x+o*this.rotatingPointOffset,m.y-a*this.rotatingPointOffset);return this.oCoords={tl:d,tr:g,br:v,bl:p,ml:b,mt:m,mr:y,mb:_,mtr:x},this._setCornerCoords&&this._setCornerCoords(),this},_calcRotateMatrix:function(){if(this.angle){var t=e(this.angle),i=Math.cos(t),r=Math.sin(t);return[i,r,-r,i,0,0]}return[1,0,0,1,0,0]},calcTransformMatrix:function(){var t=this.getCenterPoint(),e=[1,0,0,1,t.x,t.y],r=this._calcRotateMatrix(),n=this._calcDimensionsTransformMatrix(this.skewX,this.skewY,!0),s=this.group?this.group.calcTransformMatrix():[1,0,0,1,0,0];return s=i(s,e),s=i(s,r),s=i(s,n)},_calcDimensionsTransformMatrix:function(t,r,n){var s=[1,0,Math.tan(e(t)),1],o=[1,Math.tan(e(r)),0,1],a=this.scaleX*(n&&this.flipX?-1:1),h=this.scaleY*(n&&this.flipY?-1:1),c=[a,0,0,h],l=i(c,s,!0);return i(l,o,!0)}})}(),fabric.util.object.extend(fabric.Object.prototype,{sendToBack:function(){return this.group?fabric.StaticCanvas.prototype.sendToBack.call(this.group,this):this.canvas.sendToBack(this),this},bringToFront:function(){return this.group?fabric.StaticCanvas.prototype.bringToFront.call(this.group,this):this.canvas.bringToFront(this), -this},sendBackwards:function(t){return this.group?fabric.StaticCanvas.prototype.sendBackwards.call(this.group,this,t):this.canvas.sendBackwards(this,t),this},bringForward:function(t){return this.group?fabric.StaticCanvas.prototype.bringForward.call(this.group,this,t):this.canvas.bringForward(this,t),this},moveTo:function(t){return this.group?fabric.StaticCanvas.prototype.moveTo.call(this.group,this,t):this.canvas.moveTo(this,t),this}}),function(){function t(t,e){if(e){if(e.toLive)return t+": url(#SVGID_"+e.id+"); ";var i=new fabric.Color(e),r=t+": "+i.toRgb()+"; ",n=i.getAlpha();return 1!==n&&(r+=t+"-opacity: "+n.toString()+"; "),r}return t+": none; "}fabric.util.object.extend(fabric.Object.prototype,{getSvgStyles:function(e){var i=this.fillRule,r=this.strokeWidth?this.strokeWidth:"0",n=this.strokeDashArray?this.strokeDashArray.join(" "):"none",s=this.strokeLineCap?this.strokeLineCap:"butt",o=this.strokeLineJoin?this.strokeLineJoin:"miter",a=this.strokeMiterLimit?this.strokeMiterLimit:"4",h="undefined"!=typeof this.opacity?this.opacity:"1",c=this.visible?"":" visibility: hidden;",l=e?"":this.getSvgFilter(),u=t("fill",this.fill),f=t("stroke",this.stroke);return[f,"stroke-width: ",r,"; ","stroke-dasharray: ",n,"; ","stroke-linecap: ",s,"; ","stroke-linejoin: ",o,"; ","stroke-miterlimit: ",a,"; ",u,"fill-rule: ",i,"; ","opacity: ",h,";",l,c].join("")},getSvgFilter:function(){return this.shadow?"filter: url(#SVGID_"+this.shadow.id+");":""},getSvgId:function(){return this.id?'id="'+this.id+'" ':""},getSvgTransform:function(){if(this.group&&"path-group"===this.group.type)return"";var t=fabric.util.toFixed,e=this.getAngle(),i=this.getSkewX()%360,r=this.getSkewY()%360,n=this.getCenterPoint(),s=fabric.Object.NUM_FRACTION_DIGITS,o="path-group"===this.type?"":"translate("+t(n.x,s)+" "+t(n.y,s)+")",a=0!==e?" rotate("+t(e,s)+")":"",h=1===this.scaleX&&1===this.scaleY?"":" scale("+t(this.scaleX,s)+" "+t(this.scaleY,s)+")",c=0!==i?" skewX("+t(i,s)+")":"",l=0!==r?" skewY("+t(r,s)+")":"",u="path-group"===this.type?this.width:0,f=this.flipX?" matrix(-1 0 0 1 "+u+" 0) ":"",d="path-group"===this.type?this.height:0,g=this.flipY?" matrix(1 0 0 -1 0 "+d+")":"";return[o,a,h,f,g,c,l].join("")},getSvgTransformMatrix:function(){return this.transformMatrix?" matrix("+this.transformMatrix.join(" ")+") ":""},_createBaseSVGMarkup:function(){var t=[];return this.fill&&this.fill.toLive&&t.push(this.fill.toSVG(this,!1)),this.stroke&&this.stroke.toLive&&t.push(this.stroke.toSVG(this,!1)),this.shadow&&t.push(this.shadow.toSVG(this)),t}})}(),fabric.util.object.extend(fabric.Object.prototype,{hasStateChanged:function(){return this.stateProperties.some(function(t){return this.get(t)!==this.originalState[t]},this)},saveState:function(t){return this.stateProperties.forEach(function(t){this.originalState[t]=this.get(t)},this),t&&t.stateProperties&&t.stateProperties.forEach(function(t){this.originalState[t]=this.get(t)},this),this},setupState:function(){return this.originalState={},this.saveState(),this}}),function(){var t=fabric.util.degreesToRadians,e=function(){return"undefined"!=typeof G_vmlCanvasManager};fabric.util.object.extend(fabric.Object.prototype,{_controlsVisibility:null,_findTargetCorner:function(t){if(!this.hasControls||!this.active)return!1;var e,i,r=t.x,n=t.y;this.__corner=0;for(var s in this.oCoords)if(this.isControlVisible(s)&&("mtr"!==s||this.hasRotatingPoint)&&(!this.get("lockUniScaling")||"mt"!==s&&"mr"!==s&&"mb"!==s&&"ml"!==s)&&(i=this._getImageLines(this.oCoords[s].corner),e=this._findCrossPoints({x:r,y:n},i),0!==e&&e%2===1))return this.__corner=s,s;return!1},_setCornerCoords:function(){var e,i,r=this.oCoords,n=t(45-this.angle),s=.707106*this.cornerSize,o=s*Math.cos(n),a=s*Math.sin(n);for(var h in r)e=r[h].x,i=r[h].y,r[h].corner={tl:{x:e-a,y:i-o},tr:{x:e+o,y:i-a},bl:{x:e-o,y:i+a},br:{x:e+a,y:i+o}}},_getNonTransformedDimensions:function(){var t=this.strokeWidth,e=this.width,i=this.height,r=!0,n=!0;return"line"===this.type&&"butt"===this.strokeLineCap&&(n=e,r=i),n&&(i+=i<0?-t:t),r&&(e+=e<0?-t:t),{x:e,y:i}},_getTransformedDimensions:function(t,e){"undefined"==typeof t&&(t=this.skewX),"undefined"==typeof e&&(e=this.skewY);var i,r,n=this._getNonTransformedDimensions(),s=n.x/2,o=n.y/2,a=[{x:-s,y:-o},{x:s,y:-o},{x:-s,y:o},{x:s,y:o}],h=this._calcDimensionsTransformMatrix(t,e,!1);for(i=0;i\n'),t?t(e.join("")):e.join("")},complexity:function(){return 1}}),i.Line.ATTRIBUTE_NAMES=i.SHARED_ATTRIBUTES.concat("x1 y1 x2 y2".split(" ")),i.Line.fromElement=function(t,e){var n=i.parseAttributes(t,i.Line.ATTRIBUTE_NAMES),s=[n.x1||0,n.y1||0,n.x2||0,n.y2||0];return new i.Line(s,r(n,e))},void(i.Line.fromObject=function(t){var e=[t.x1,t.y1,t.x2,t.y2];return new i.Line(e,t)}))}("undefined"!=typeof exports?exports:this),function(t){"use strict";function e(t){return"radius"in t&&t.radius>=0}var i=t.fabric||(t.fabric={}),r=Math.PI,n=i.util.object.extend;return i.Circle?void i.warn("fabric.Circle is already defined."):(i.Circle=i.util.createClass(i.Object,{type:"circle",radius:0,startAngle:0,endAngle:2*r,initialize:function(t){t=t||{},this.callSuper("initialize",t),this.set("radius",t.radius||0),this.startAngle=t.startAngle||this.startAngle,this.endAngle=t.endAngle||this.endAngle},_set:function(t,e){return this.callSuper("_set",t,e),"radius"===t&&this.setRadius(e),this},toObject:function(t){return n(this.callSuper("toObject",t),{radius:this.get("radius"),startAngle:this.startAngle,endAngle:this.endAngle})},toSVG:function(t){var e=this._createBaseSVGMarkup(),i=0,n=0,s=(this.endAngle-this.startAngle)%(2*r);if(0===s)this.group&&"path-group"===this.group.type&&(i=this.left+this.radius,n=this.top+this.radius),e.push("\n');else{var o=Math.cos(this.startAngle)*this.radius,a=Math.sin(this.startAngle)*this.radius,h=Math.cos(this.endAngle)*this.radius,c=Math.sin(this.endAngle)*this.radius,l=s>r?"1":"0";e.push('\n')}return t?t(e.join("")):e.join("")},_render:function(t,e){t.beginPath(),t.arc(e?this.left+this.radius:0,e?this.top+this.radius:0,this.radius,this.startAngle,this.endAngle,!1),this._renderFill(t),this._renderStroke(t)},getRadiusX:function(){return this.get("radius")*this.get("scaleX")},getRadiusY:function(){return this.get("radius")*this.get("scaleY")},setRadius:function(t){return this.radius=t,this.set("width",2*t).set("height",2*t)},complexity:function(){return 1}}),i.Circle.ATTRIBUTE_NAMES=i.SHARED_ATTRIBUTES.concat("cx cy r".split(" ")),i.Circle.fromElement=function(t,r){r||(r={});var s=i.parseAttributes(t,i.Circle.ATTRIBUTE_NAMES);if(!e(s))throw new Error("value of `r` attribute is required and can not be negative");s.left=s.left||0,s.top=s.top||0;var o=new i.Circle(n(s,r));return o.left-=o.radius,o.top-=o.radius,o},void(i.Circle.fromObject=function(t){return new i.Circle(t)}))}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={});return e.Triangle?void e.warn("fabric.Triangle is already defined"):(e.Triangle=e.util.createClass(e.Object,{type:"triangle",initialize:function(t){t=t||{},this.callSuper("initialize",t),this.set("width",t.width||100).set("height",t.height||100)},_render:function(t){var e=this.width/2,i=this.height/2;t.beginPath(),t.moveTo(-e,i),t.lineTo(0,-i),t.lineTo(e,i),t.closePath(),this._renderFill(t),this._renderStroke(t)},_renderDashedStroke:function(t){var i=this.width/2,r=this.height/2;t.beginPath(),e.util.drawDashedLine(t,-i,r,0,-r,this.strokeDashArray),e.util.drawDashedLine(t,0,-r,i,r,this.strokeDashArray),e.util.drawDashedLine(t,i,r,-i,r,this.strokeDashArray),t.closePath()},toSVG:function(t){var e=this._createBaseSVGMarkup(),i=this.width/2,r=this.height/2,n=[-i+" "+r,"0 "+-r,i+" "+r].join(",");return e.push("'),t?t(e.join("")):e.join("")},complexity:function(){return 1}}),void(e.Triangle.fromObject=function(t){return new e.Triangle(t)}))}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=2*Math.PI,r=e.util.object.extend;return e.Ellipse?void e.warn("fabric.Ellipse is already defined."):(e.Ellipse=e.util.createClass(e.Object,{type:"ellipse",rx:0,ry:0,initialize:function(t){t=t||{},this.callSuper("initialize",t),this.set("rx",t.rx||0),this.set("ry",t.ry||0)},_set:function(t,e){switch(this.callSuper("_set",t,e),t){case"rx":this.rx=e,this.set("width",2*e);break;case"ry":this.ry=e,this.set("height",2*e)}return this},getRx:function(){return this.get("rx")*this.get("scaleX")},getRy:function(){return this.get("ry")*this.get("scaleY")},toObject:function(t){return r(this.callSuper("toObject",t),{rx:this.get("rx"),ry:this.get("ry")})},toSVG:function(t){var e=this._createBaseSVGMarkup(),i=0,r=0;return this.group&&"path-group"===this.group.type&&(i=this.left+this.rx,r=this.top+this.ry),e.push("\n'),t?t(e.join("")):e.join("")},_render:function(t,e){t.beginPath(),t.save(),t.transform(1,0,0,this.ry/this.rx,0,0),t.arc(e?this.left+this.rx:0,e?(this.top+this.ry)*this.rx/this.ry:0,this.rx,0,i,!1),t.restore(),this._renderFill(t),this._renderStroke(t)},complexity:function(){return 1}}),e.Ellipse.ATTRIBUTE_NAMES=e.SHARED_ATTRIBUTES.concat("cx cy rx ry".split(" ")),e.Ellipse.fromElement=function(t,i){i||(i={});var n=e.parseAttributes(t,e.Ellipse.ATTRIBUTE_NAMES);n.left=n.left||0,n.top=n.top||0;var s=new e.Ellipse(r(n,i));return s.top-=s.ry,s.left-=s.rx,s},void(e.Ellipse.fromObject=function(t){return new e.Ellipse(t)}))}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=e.util.object.extend;if(e.Rect)return void e.warn("fabric.Rect is already defined");var r=e.Object.prototype.stateProperties.concat();r.push("rx","ry","x","y"),e.Rect=e.util.createClass(e.Object,{stateProperties:r,type:"rect",rx:0,ry:0,strokeDashArray:null,initialize:function(t){t=t||{},this.callSuper("initialize",t),this._initRxRy()},_initRxRy:function(){this.rx&&!this.ry?this.ry=this.rx:this.ry&&!this.rx&&(this.rx=this.ry)},_render:function(t,e){if(1===this.width&&1===this.height)return void t.fillRect(-.5,-.5,1,1);var i=this.rx?Math.min(this.rx,this.width/2):0,r=this.ry?Math.min(this.ry,this.height/2):0,n=this.width,s=this.height,o=e?this.left:-this.width/2,a=e?this.top:-this.height/2,h=0!==i||0!==r,c=.4477152502;t.beginPath(),t.moveTo(o+i,a),t.lineTo(o+n-i,a),h&&t.bezierCurveTo(o+n-c*i,a,o+n,a+c*r,o+n,a+r),t.lineTo(o+n,a+s-r),h&&t.bezierCurveTo(o+n,a+s-c*r,o+n-c*i,a+s,o+n-i,a+s),t.lineTo(o+i,a+s),h&&t.bezierCurveTo(o+c*i,a+s,o,a+s-c*r,o,a+s-r),t.lineTo(o,a+r),h&&t.bezierCurveTo(o,a+c*r,o+c*i,a,o+i,a),t.closePath(),this._renderFill(t),this._renderStroke(t)},_renderDashedStroke:function(t){var i=-this.width/2,r=-this.height/2,n=this.width,s=this.height;t.beginPath(),e.util.drawDashedLine(t,i,r,i+n,r,this.strokeDashArray),e.util.drawDashedLine(t,i+n,r,i+n,r+s,this.strokeDashArray),e.util.drawDashedLine(t,i+n,r+s,i,r+s,this.strokeDashArray),e.util.drawDashedLine(t,i,r+s,i,r,this.strokeDashArray),t.closePath()},toObject:function(t){var e=i(this.callSuper("toObject",t),{rx:this.get("rx")||0,ry:this.get("ry")||0});return this.includeDefaultValues||this._removeDefaultValues(e),e},toSVG:function(t){var e=this._createBaseSVGMarkup(),i=this.left,r=this.top;return this.group&&"path-group"===this.group.type||(i=-this.width/2,r=-this.height/2),e.push("\n'),t?t(e.join("")):e.join("")},complexity:function(){return 1}}),e.Rect.ATTRIBUTE_NAMES=e.SHARED_ATTRIBUTES.concat("x y rx ry width height".split(" ")),e.Rect.fromElement=function(t,r){if(!t)return null;r=r||{};var n=e.parseAttributes(t,e.Rect.ATTRIBUTE_NAMES);n.left=n.left||0,n.top=n.top||0;var s=new e.Rect(i(r?e.util.object.clone(r):{},n));return s.visible=s.visible&&s.width>0&&s.height>0,s},e.Rect.fromObject=function(t){return new e.Rect(t)}}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={});return e.Polyline?void e.warn("fabric.Polyline is already defined"):(e.Polyline=e.util.createClass(e.Object,{type:"polyline",points:null,minX:0,minY:0,initialize:function(t,i){return e.Polygon.prototype.initialize.call(this,t,i)},_calcDimensions:function(){return e.Polygon.prototype._calcDimensions.call(this)},toObject:function(t){return e.Polygon.prototype.toObject.call(this,t)},toSVG:function(t){return e.Polygon.prototype.toSVG.call(this,t)},_render:function(t,i){e.Polygon.prototype.commonRender.call(this,t,i)&&(this._renderFill(t),this._renderStroke(t))},_renderDashedStroke:function(t){var i,r;t.beginPath();for(var n=0,s=this.points.length;n\n'),t?t(r.join("")):r.join("")},_render:function(t,e){this.commonRender(t,e)&&(this._renderFill(t),(this.stroke||this.strokeDashArray)&&(t.closePath(),this._renderStroke(t)))},commonRender:function(t,e){var i,r=this.points.length;if(!r||isNaN(this.points[r-1].y))return!1;e||t.translate(-this.pathOffset.x,-this.pathOffset.y),t.beginPath(),t.moveTo(this.points[0].x,this.points[0].y);for(var n=0;n"},toObject:function(t){var e=n(this.callSuper("toObject",t),{path:this.path.map(function(t){return t.slice()}),pathOffset:this.pathOffset});return this.sourcePath&&(e.sourcePath=this.sourcePath),this.transformMatrix&&(e.transformMatrix=this.transformMatrix),e},toDatalessObject:function(t){var e=this.toObject(t);return this.sourcePath&&(e.path=this.sourcePath),delete e.sourcePath,e},toSVG:function(t){for(var e=[],i=this._createBaseSVGMarkup(),r="",n=0,s=this.path.length;n\n"),t?t(i.join("")):i.join("")},complexity:function(){return this.path.length},_parsePath:function(){for(var t,e,i,r,n,s=[],o=[],c=/([-+]?((\d+\.\d+)|((\d+)|(\.\d+)))(?:e[-+]?\d+)?)/gi,l=0,u=this.path.length;lp)for(var b=1,m=n.length;b\n");for(var s=0,o=e.length;s\n"),t?t(n.join("")):n.join("")},toString:function(){return"#"},isSameColor:function(){var t=this.getObjects()[0].get("fill")||"";return"string"==typeof t&&(t=t.toLowerCase(),this.getObjects().every(function(e){var i=e.get("fill")||"";return"string"==typeof i&&i.toLowerCase()===t}))},complexity:function(){return this.paths.reduce(function(t,e){return t+(e&&e.complexity?e.complexity():0)},0)},getObjects:function(){return this.paths}}),e.PathGroup.fromObject=function(t,i){"string"==typeof t.paths?e.loadSVGFromURL(t.paths,function(r){var n=t.paths;delete t.paths;var s=e.util.groupSVGElements(r,t,n);i(s)}):e.util.enlivenObjects(t.paths,function(r){delete t.paths,i(new e.PathGroup(r,t))})},void(e.PathGroup.async=!0))}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=e.util.object.extend,r=e.util.array.min,n=e.util.array.max,s=e.util.array.invoke;if(!e.Group){var o={lockMovementX:!0,lockMovementY:!0,lockRotation:!0,lockScalingX:!0,lockScalingY:!0,lockUniScaling:!0};e.Group=e.util.createClass(e.Object,e.Collection,{type:"group",strokeWidth:0,subTargetCheck:!1,initialize:function(t,e,i){e=e||{},this._objects=[],i&&this.callSuper("initialize",e),this._objects=t||[];for(var r=this._objects.length;r--;)this._objects[r].group=this;this.originalState={},e.originX&&(this.originX=e.originX),e.originY&&(this.originY=e.originY),i?this._updateObjectsCoords(!0):(this._calcBounds(),this._updateObjectsCoords(),this.callSuper("initialize",e)),this.setCoords(),this.saveCoords()},_updateObjectsCoords:function(t){for(var e=this._objects.length;e--;)this._updateObjectCoords(this._objects[e],t)},_updateObjectCoords:function(t,e){if(t.__origHasControls=t.hasControls,t.hasControls=!1,!e){var i=t.getLeft(),r=t.getTop(),n=this.getCenterPoint();t.set({originalLeft:i,originalTop:r,left:i-n.x,top:r-n.y}),t.setCoords()}},toString:function(){return"#"},addWithUpdate:function(t){return this._restoreObjectsState(),e.util.resetObjectTransform(this),t&&(this._objects.push(t),t.group=this,t._set("canvas",this.canvas)),this.forEachObject(this._setObjectActive,this),this._calcBounds(),this._updateObjectsCoords(),this},_setObjectActive:function(t){t.set("active",!0),t.group=this},removeWithUpdate:function(t){return this._restoreObjectsState(),e.util.resetObjectTransform(this),this.forEachObject(this._setObjectActive,this),this.remove(t),this._calcBounds(),this._updateObjectsCoords(),this},_onObjectAdded:function(t){t.group=this,t._set("canvas",this.canvas)},_onObjectRemoved:function(t){delete t.group,t.set("active",!1)},delegatedProperties:{fill:!0,stroke:!0,strokeWidth:!0,fontFamily:!0,fontWeight:!0,fontSize:!0,fontStyle:!0,lineHeight:!0,textDecoration:!0,textAlign:!0,backgroundColor:!0},_set:function(t,e){var i=this._objects.length;if(this.delegatedProperties[t]||"canvas"===t)for(;i--;)this._objects[i].set(t,e);else for(;i--;)this._objects[i].setOnGroup(t,e);this.callSuper("_set",t,e)},toObject:function(t){return i(this.callSuper("toObject",t),{objects:s(this._objects,"toObject",t)})},render:function(t){if(this.visible){t.save(),this.transformMatrix&&t.transform.apply(t,this.transformMatrix),this.transform(t),this._setShadow(t),this.clipTo&&e.util.clipContext(this,t),this._transformDone=!0;for(var i=0,r=this._objects.length;i\n');for(var i=0,r=this._objects.length;i\n"),t?t(e.join("")):e.join("")},get:function(t){if(t in o){if(this[t])return this[t];for(var e=0,i=this._objects.length;e\n',"\n"),this.stroke||this.strokeDashArray){var s=this.fill;this.fill=null,e.push("\n'),this.fill=s}return e.push("\n"),t?t(e.join("")):e.join("")},getSrc:function(){var t=this._originalElement;return t?fabric.isLikelyNode?t._src:t.src:this.src||""},setSrc:function(t,e,i){fabric.util.loadImage(t,function(t){return this.setElement(t,e,i)},this,i&&i.crossOrigin)},toString:function(){return'#'},clone:function(t,e){this.constructor.fromObject(this.toObject(e),t)},applyFilters:function(t,e,i,r){if(e=e||this.filters,i=i||this._originalElement){var n,s,o=fabric.util.createImage(),a=this.canvas?this.canvas.getRetinaScaling():fabric.devicePixelRatio,h=this.minimumScaleTrigger/a,c=this;if(0===e.length)return this._element=i,t&&t(this),i;var l=fabric.util.createCanvasElement();return l.width=i.width,l.height=i.height,l.getContext("2d").drawImage(i,0,0,i.width,i.height),e.forEach(function(t){t&&(r?(n=c.scaleX0?90*Math.round((t-1)/90):90*Math.round(t/90)},straighten:function(){return this.setAngle(this._getAngleValueForStraighten()),this},fxStraighten:function(t){t=t||{};var e=function(){},i=t.onComplete||e,r=t.onChange||e,n=this;return fabric.util.animate({startValue:this.get("angle"),endValue:this._getAngleValueForStraighten(),duration:this.FX_DURATION,onChange:function(t){n.setAngle(t),r()},onComplete:function(){n.setCoords(),i()},onStart:function(){n.set("active",!1)}}),this}}),fabric.util.object.extend(fabric.StaticCanvas.prototype,{straightenObject:function(t){return t.straighten(),this.renderAll(),this},fxStraightenObject:function(t){return t.fxStraighten({onChange:this.renderAll.bind(this)}),this}}),fabric.Image.filters=fabric.Image.filters||{},fabric.Image.filters.BaseFilter=fabric.util.createClass({type:"BaseFilter",initialize:function(t){t&&this.setOptions(t)},setOptions:function(t){for(var e in t)this[e]=t[e]},toObject:function(){return{type:this.type}},toJSON:function(){return this.toObject()}}),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=e.util.object.extend;e.Image.filters.Brightness=e.util.createClass(e.Image.filters.BaseFilter,{type:"Brightness",initialize:function(t){t=t||{},this.brightness=t.brightness||0},applyTo:function(t){for(var e=t.getContext("2d"),i=e.getImageData(0,0,t.width,t.height),r=i.data,n=this.brightness,s=0,o=r.length;sb||o<0||o>v||(h=4*(a*v+o),c=l[C*d+w],e+=p[h]*c,i+=p[h+1]*c,r+=p[h+2]*c,n+=p[h+3]*c);y[s]=e,y[s+1]=i,y[s+2]=r,y[s+3]=n+_*(255-n)}u.putImageData(m,0,0)},toObject:function(){return i(this.callSuper("toObject"),{opaque:this.opaque,matrix:this.matrix})}}),e.Image.filters.Convolute.fromObject=function(t){return new e.Image.filters.Convolute(t)}}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=e.util.object.extend;e.Image.filters.GradientTransparency=e.util.createClass(e.Image.filters.BaseFilter,{type:"GradientTransparency",initialize:function(t){t=t||{},this.threshold=t.threshold||100},applyTo:function(t){for(var e=t.getContext("2d"),i=e.getImageData(0,0,t.width,t.height),r=i.data,n=this.threshold,s=r.length,o=0,a=r.length;o-1?t.channel:0},applyTo:function(t){if(this.mask){var i,r=t.getContext("2d"),n=r.getImageData(0,0,t.width,t.height),s=n.data,o=this.mask.getElement(),a=e.util.createCanvasElement(),h=this.channel,c=n.width*n.height*4;a.width=t.width,a.height=t.height,a.getContext("2d").drawImage(o,0,0,t.width,t.height);var l=a.getContext("2d").getImageData(0,0,t.width,t.height),u=l.data;for(i=0;ic&&i>c&&r>c&&l(e-i)i&&(l=2,f=-1),a>n&&(u=2,d=-1),h=c.getImageData(0,0,i,n),t.width=o(s,i),t.height=o(a,n),c.putImageData(h,0,0);!g||!p;)i=v,n=b,s*ft)return 0;if(e*=Math.PI,s(e)<1e-16)return 1;var i=e/t;return h(e)*h(i)/e/i}}function f(t){var h,c,u,d,g,j,A,M,P,I,L;for(T.x=(t+.5)*y,k.x=r(T.x),h=0;h=e)){I=r(1e3*s(c-T.x)),O[I]||(O[I]={});for(var E=k.y-w;E<=k.y+w;E++)E<0||E>=o||(L=r(1e3*s(E-T.y)),O[I][L]||(O[I][L]=m(n(i(I*x,2)+i(L*S,2))/1e3)),u=O[I][L],u>0&&(d=4*(E*e+c),g+=u,j+=u*v[d],A+=u*v[d+1],M+=u*v[d+2],P+=u*v[d+3]))}d=4*(h*a+t),b[d]=j/g,b[d+1]=A/g,b[d+2]=M/g,b[d+3]=P/g}return++t1&&D<-1||(x=2*D*D*D-3*D*D+1,x>0&&(E=4*(L+A*e),k+=x*p[E+3],C+=x,p[E+3]<255&&(x=x*p[E+3]/250),w+=x*p[E],O+=x*p[E+1],T+=x*p[E+2],S+=x))}b[_]=w/S,b[_+1]=O/S,b[_+2]=T/S,b[_+3]=k/C}return v},toObject:function(){return{type:this.type,scaleX:this.scaleX,scaleY:this.scaleY,resizeType:this.resizeType,lanczosLobes:this.lanczosLobes}}}),e.Image.filters.Resize.fromObject=function(t){return new e.Image.filters.Resize(t)}}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=e.util.object.extend;e.Image.filters.ColorMatrix=e.util.createClass(e.Image.filters.BaseFilter,{type:"ColorMatrix",initialize:function(t){t||(t={}),this.matrix=t.matrix||[1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0]},applyTo:function(t){var e,i,r,n,s,o=t.getContext("2d"),a=o.getImageData(0,0,t.width,t.height),h=a.data,c=h.length,l=this.matrix;for(e=0;e'},_render:function(t){this.clipTo&&e.util.clipContext(this,t),this._setOpacity(t),this._setShadow(t),this._setupCompositeOperation(t),this._renderTextBackground(t),this._setStrokeStyles(t),this._setFillStyles(t),this._renderText(t),this._renderTextDecoration(t),this.clipTo&&t.restore()},_renderText:function(t){this._renderTextFill(t),this._renderTextStroke(t)},_setTextStyles:function(t){t.textBaseline="alphabetic",t.font=this._getFontDeclaration()},_getTextHeight:function(){return this._getHeightOfSingleLine()+(this._textLines.length-1)*this._getHeightOfLine()},_getTextWidth:function(t){for(var e=this._getLineWidth(t,0),i=1,r=this._textLines.length;ie&&(e=n)}return e},_getNonTransformedDimensions:function(){ -return{x:this.width,y:this.height}},_renderChars:function(t,e,i,r,n){var s,o,a=t.slice(0,-4);if(this[a].toLive){var h=-this.width/2+this[a].offsetX||0,c=-this.height/2+this[a].offsetY||0;e.save(),e.translate(h,c),r-=h,n-=c}if(0!==this.charSpacing){var l=this._getWidthOfCharSpacing();i=i.split("");for(var u=0,f=i.length;u0?o:0}else e[t](i,r,n);this[a].toLive&&e.restore()},_renderTextLine:function(t,e,i,r,n,s){n-=this.fontSize*this._fontSizeFraction;var o=this._getLineWidth(e,s);if("justify"!==this.textAlign||this.width0?u/f:0,g=0,p=0,v=h.length;p0?n:0},_getLeftOffset:function(){return-this.width/2},_getTopOffset:function(){return-this.height/2},isEmptyStyles:function(){return!0},_renderTextCommon:function(t,e){for(var i=0,r=this._getLeftOffset(),n=this._getTopOffset(),s=0,o=this._textLines.length;s0&&(r=this._getLineLeftOffset(i),t.fillRect(this._getLeftOffset()+r,this._getTopOffset()+n,i,e/this.lineHeight)),n+=e;this._removeShadow(t)}},_getLineLeftOffset:function(t){return"center"===this.textAlign?(this.width-t)/2:"right"===this.textAlign?this.width-t:0},_clearCache:function(){this.__lineWidths=[],this.__lineHeights=[]},_shouldClearCache:function(){var t=!1;if(this._forceClearCache)return this._forceClearCache=!1,!0;for(var e in this._dimensionAffectingProps)this["__"+e]!==this[e]&&(this["__"+e]=this[e],t=!0);return t},_getLineWidth:function(t,e){if(this.__lineWidths[e])return this.__lineWidths[e]===-1?this.width:this.__lineWidths[e];var i,r,n=this._textLines[e];return i=""===n?0:this._measureLine(t,e),this.__lineWidths[e]=i,i&&"justify"===this.textAlign&&(r=n.split(/\s+/),r.length>1&&(this.__lineWidths[e]=-1)),i},_getWidthOfCharSpacing:function(){return 0!==this.charSpacing?this.fontSize*this.charSpacing/1e3:0},_measureLine:function(t,e){var i,r,n=this._textLines[e],s=t.measureText(n).width,o=0;return 0!==this.charSpacing&&(i=n.split("").length,o=(i-1)*this._getWidthOfCharSpacing()),r=s+o,r>0?r:0},_renderTextDecoration:function(t){function e(e){var n,s,o,a,h,c,l,u=0;for(n=0,s=r._textLines.length;n-1&&n.push(.85),this.textDecoration.indexOf("line-through")>-1&&n.push(.43),this.textDecoration.indexOf("overline")>-1&&n.push(-.12),n.length>0&&e(n)}},_getFontDeclaration:function(){return[e.isLikelyNode?this.fontWeight:this.fontStyle,e.isLikelyNode?this.fontStyle:this.fontWeight,this.fontSize+"px",'"'+this.fontFamily+'"'].join(" ")},render:function(t,e){this.visible&&(t.save(),this._setTextStyles(t),this._shouldClearCache()&&this._initDimensions(t),this.drawSelectionBackground(t),e||this.transform(t),this.transformMatrix&&t.transform.apply(t,this.transformMatrix),this.group&&"path-group"===this.group.type&&t.translate(this.left,this.top),this._render(t),t.restore())},_splitTextIntoLines:function(){return this.text.split(this._reNewline)},toObject:function(t){var e=i(this.callSuper("toObject",t),{text:this.text,fontSize:this.fontSize,fontWeight:this.fontWeight,fontFamily:this.fontFamily,fontStyle:this.fontStyle,lineHeight:this.lineHeight,textDecoration:this.textDecoration,textAlign:this.textAlign,textBackgroundColor:this.textBackgroundColor,charSpacing:this.charSpacing});return this.includeDefaultValues||this._removeDefaultValues(e),e},toSVG:function(t){this.ctx||(this.ctx=e.util.createCanvasElement().getContext("2d"));var i=this._createBaseSVGMarkup(),r=this._getSVGLeftTopOffsets(this.ctx),n=this._getSVGTextAndBg(r.textTop,r.textLeft);return this._wrapSVGTextAndBg(i,n),t?t(i.join("")):i.join("")},_getSVGLeftTopOffsets:function(t){var e=this._getHeightOfLine(t,0),i=-this.width/2,r=0;return{textLeft:i+(this.group&&"path-group"===this.group.type?this.left:0),textTop:r+(this.group&&"path-group"===this.group.type?-this.top:0),lineTop:e}},_wrapSVGTextAndBg:function(t,e){var i=!0,r=this.getSvgFilter(),n=""===r?"":' style="'+r+'"';t.push("\t\n",e.textBgRects.join(""),"\t\t\n',e.textSpans.join(""),"\t\t\n","\t\n")},_getSVGTextAndBg:function(t,e){var i=[],r=[],n=0;this._setSVGBg(r);for(var s=0,o=this._textLines.length;s",e.util.string.escapeXml(this._textLines[t]),"\n")},_setSVGTextLineJustifed:function(t,i,r,o){var a=e.util.createCanvasElement().getContext("2d");this._setTextStyles(a);var h,c,l=this._textLines[t],u=l.split(/\s+/),f=this._getWidthOfWords(a,u.join("")),d=this.width-f,g=u.length-1,p=g>0?d/g:0,v=this._getFillAttributes(this.fill);for(o+=this._getLineLeftOffset(this._getLineWidth(a,t)),t=0,c=u.length;t",e.util.string.escapeXml(h),"\n"),o+=this._getWidthOfWords(a,h)+p},_setSVGTextLineBg:function(t,e,i,r,o){t.push("\t\t\n')},_setSVGBg:function(t){this.backgroundColor&&t.push("\t\t\n')},_getFillAttributes:function(t){var i=t&&"string"==typeof t?new e.Color(t):"";return i&&i.getSource()&&1!==i.getAlpha()?'opacity="'+i.getAlpha()+'" fill="'+i.setAlpha(1).toRgb()+'"':'fill="'+t+'"'},_set:function(t,e){this.callSuper("_set",t,e),t in this._dimensionAffectingProps&&(this._initDimensions(),this.setCoords())},complexity:function(){return 1}}),e.Text.ATTRIBUTE_NAMES=e.SHARED_ATTRIBUTES.concat("x y dx dy font-family font-style font-weight font-size text-decoration text-anchor".split(" ")),e.Text.DEFAULT_SVG_FONT_SIZE=16,e.Text.fromElement=function(t,i){if(!t)return null;var r=e.parseAttributes(t,e.Text.ATTRIBUTE_NAMES);i=e.util.object.extend(i?e.util.object.clone(i):{},r),i.top=i.top||0,i.left=i.left||0,"dx"in r&&(i.left+=r.dx),"dy"in r&&(i.top+=r.dy),"fontSize"in i||(i.fontSize=e.Text.DEFAULT_SVG_FONT_SIZE),i.originX||(i.originX="left");var n="";"textContent"in t?n=t.textContent:"firstChild"in t&&null!==t.firstChild&&"data"in t.firstChild&&null!==t.firstChild.data&&(n=t.firstChild.data),n=n.replace(/^\s+|\s+$|\n+/g,"").replace(/\s+/g," ");var s=new e.Text(n,i),o=s.getHeight()/s.height,a=(s.height+s.strokeWidth)*s.lineHeight-s.height,h=a*o,c=s.getHeight()+h,l=0;return"left"===s.originX&&(l=s.getWidth()/2),"right"===s.originX&&(l=-s.getWidth()/2),s.set({left:s.getLeft()+l,top:s.getTop()-c/2+s.fontSize*(.18+s._fontSizeFraction)/s.lineHeight}),s},e.Text.fromObject=function(t){return new e.Text(t.text,r(t))},e.util.createAccessors(e.Text)}("undefined"!=typeof exports?exports:this),function(){var t=fabric.util.object.clone;fabric.IText=fabric.util.createClass(fabric.Text,fabric.Observable,{type:"i-text",selectionStart:0,selectionEnd:0,selectionColor:"rgba(17,119,255,0.3)",isEditing:!1,editable:!0,editingBorderColor:"rgba(102,153,255,0.25)",cursorWidth:2,cursorColor:"#333",cursorDelay:1e3,cursorDuration:600,styles:null,caching:!0,_reSpace:/\s|\n/,_currentCursorOpacity:0,_selectionDirection:null,_abortCursorAnimation:!1,__widthOfSpace:[],initialize:function(t,e){this.styles=e?e.styles||{}:{},this.callSuper("initialize",t,e),this.initBehavior()},_clearCache:function(){this.callSuper("_clearCache"),this.__widthOfSpace=[]},isEmptyStyles:function(){if(!this.styles)return!0;var t=this.styles;for(var e in t)for(var i in t[e])for(var r in t[e][i])return!1;return!0},setSelectionStart:function(t){t=Math.max(t,0),this._updateAndFire("selectionStart",t)},setSelectionEnd:function(t){t=Math.min(t,this.text.length),this._updateAndFire("selectionEnd",t)},_updateAndFire:function(t,e){this[t]!==e&&(this._fireSelectionChanged(),this[t]=e),this._updateTextarea()},_fireSelectionChanged:function(){this.fire("selection:changed"),this.canvas&&this.canvas.fire("text:selection:changed",{target:this})},getSelectionStyles:function(t,e){if(2===arguments.length){for(var i=[],r=t;r0?a:0,lineLeft:r},this.cursorOffsetCache=i,this.cursorOffsetCache},renderCursor:function(t,e){var i=this.get2DCursorLocation(),r=i.lineIndex,n=i.charIndex,s=this.getCurrentCharFontSize(r,n),o=0===r&&0===n?this._getLineLeftOffset(this._getLineWidth(e,r)):t.leftOffset,a=this.scaleX*this.canvas.getZoom(),h=this.cursorWidth/a;e.fillStyle=this.getCurrentCharColor(r,n),e.globalAlpha=this.__isMousedown?1:this._currentCursorOpacity,e.fillRect(t.left+o-h/2,t.top+t.topOffset,h,s)},renderSelection:function(t,e,i){i.fillStyle=this.selectionColor;for(var r=this.get2DCursorLocation(this.selectionStart),n=this.get2DCursorLocation(this.selectionEnd),s=r.lineIndex,o=n.lineIndex,a=s;a<=o;a++){var h=this._getLineLeftOffset(this._getLineWidth(i,a))||0,c=this._getHeightOfLine(this.ctx,a),l=0,u=0,f=this._textLines[a];if(a===s){for(var d=0,g=f.length;d=r.charIndex&&(a!==o||ds&&a1)&&(c/=this.lineHeight),i.fillRect(e.left+h,e.top+e.topOffset,u>0?u:0,c),e.topOffset+=l}},_renderChars:function(t,e,i,r,n,s,o){if(this.isEmptyStyles())return this._renderCharsFast(t,e,i,r,n);o=o||0;var a,h,c=this._getHeightOfLine(e,s),l="";e.save(),n-=c/this.lineHeight*this._fontSizeFraction;for(var u=o,f=i.length+o;u<=f;u++)a=a||this.getCurrentCharStyle(s,u),h=this.getCurrentCharStyle(s,u+1),(this._hasStyleChanged(a,h)||u===f)&&(this._renderChar(t,e,s,u-1,l,r,n,c),l="",a=h),l+=i[u-o];e.restore()},_renderCharsFast:function(t,e,i,r,n){"fillText"===t&&this.fill&&this.callSuper("_renderChars",t,e,i,r,n),"strokeText"===t&&(this.stroke&&this.strokeWidth>0||this.skipFillStrokeCheck)&&this.callSuper("_renderChars",t,e,i,r,n)},_renderChar:function(t,e,i,r,n,s,o,a){var h,c,l,u,f,d,g,p,v,b=this._getStyleDeclaration(i,r);if(b?(c=this._getHeightOfChar(e,n,i,r),u=b.stroke,l=b.fill,d=b.textDecoration):c=this.fontSize,u=(u||this.stroke)&&"strokeText"===t,l=(l||this.fill)&&"fillText"===t,b&&e.save(),h=this._applyCharStylesGetWidth(e,n,i,r,b||null),d=d||this.textDecoration,b&&b.textBackgroundColor&&this._removeShadow(e),0!==this.charSpacing){p=this._getWidthOfCharSpacing(),g=n.split(""),h=0;for(var m,y=0,_=g.length;y<_;y++)m=g[y],l&&e.fillText(m,s+h,o),u&&e.strokeText(m,s+h,o),v=e.measureText(m).width+p,h+=v>0?v:0}else l&&e.fillText(n,s,o),u&&e.strokeText(n,s,o);(d||""!==d)&&(f=this._fontSizeFraction*a/this.lineHeight,this._renderCharDecoration(e,d,s,o,f,h,c)),b&&e.restore(),e.translate(h,0)},_hasStyleChanged:function(t,e){return t.fill!==e.fill||t.fontSize!==e.fontSize||t.textBackgroundColor!==e.textBackgroundColor||t.textDecoration!==e.textDecoration||t.fontFamily!==e.fontFamily||t.fontWeight!==e.fontWeight||t.fontStyle!==e.fontStyle||t.stroke!==e.stroke||t.strokeWidth!==e.strokeWidth},_renderCharDecoration:function(t,e,i,r,n,s,o){if(e){var a,h,c=o/15,l={underline:r+o/10,"line-through":r-o*(this._fontSizeFraction+this._fontSizeMult-1)+c,overline:r-(this._fontSizeMult-this._fontSizeFraction)*o},u=["underline","line-through","overline"];for(a=0;a-1&&t.fillRect(i,l[h],s,c)}},_renderTextLine:function(t,e,i,r,n,s){this.isEmptyStyles()||(n+=this.fontSize*(this._fontSizeFraction+.03)),this.callSuper("_renderTextLine",t,e,i,r,n,s)},_renderTextDecoration:function(t){if(this.isEmptyStyles())return this.callSuper("_renderTextDecoration",t)},_renderTextLinesBackground:function(t){this.callSuper("_renderTextLinesBackground",t);for(var e,i,r,n,s,o,a=0,h=this._getLeftOffset(),c=this._getTopOffset(),l=0,u=this._textLines.length;l0?n:0},_getHeightOfChar:function(t,e,i){var r=this._getStyleDeclaration(e,i);return r&&r.fontSize?r.fontSize:this.fontSize},_getWidthOfCharsAt:function(t,e,i){var r,n,s=0;for(r=0;r0?i:0},_getWidthOfSpace:function(t,e){if(this.__widthOfSpace[e])return this.__widthOfSpace[e];var i=this._textLines[e],r=this._getWidthOfWords(t,i,e,0),n=this.width-r,s=i.length-i.replace(this._reSpacesAndTabs,"").length,o=Math.max(n/s,t.measureText(" ").width);return this.__widthOfSpace[e]=o,o},_getWidthOfWords:function(t,e,i,r){for(var n=0,s=0;sr&&(r=o)}return this.__lineHeights[e]=r*this.lineHeight*this._fontSizeMult,this.__lineHeights[e]},_getTextHeight:function(t){for(var e,i=0,r=0,n=this._textLines.length;r-1;)e++,i--;return t-e},findWordBoundaryRight:function(t){var e=0,i=t;if(this._reSpace.test(this.text.charAt(i)))for(;this._reSpace.test(this.text.charAt(i));)e++,i++;for(;/\S/.test(this.text.charAt(i))&&i-1;)e++,i--;return t-e},findLineBoundaryRight:function(t){for(var e=0,i=t;!/\n/.test(this.text.charAt(i))&&i0&&ithis.__selectionStartOnMouseDown?(this.selectionStart=this.__selectionStartOnMouseDown,this.selectionEnd=e):(this.selectionStart=e,this.selectionEnd=this.__selectionStartOnMouseDown),this.selectionStart===i&&this.selectionEnd===r||(this._fireSelectionChanged(),this._updateTextarea(),this.renderCursorOrSelection()))}},_setEditingProps:function(){this.hoverCursor="text",this.canvas&&(this.canvas.defaultCursor=this.canvas.moveCursor="text"),this.borderColor=this.editingBorderColor,this.hasControls=this.selectable=!1,this.lockMovementX=this.lockMovementY=!0},_updateTextarea:function(){if(this.hiddenTextarea&&!this.inCompositionMode&&(this.cursorOffsetCache={},this.hiddenTextarea.value=this.text,this.hiddenTextarea.selectionStart=this.selectionStart,this.hiddenTextarea.selectionEnd=this.selectionEnd,this.selectionStart===this.selectionEnd)){var t=this._calcTextareaPosition();this.hiddenTextarea.style.left=t.left,this.hiddenTextarea.style.top=t.top,this.hiddenTextarea.style.fontSize=t.fontSize}},_calcTextareaPosition:function(){if(!this.canvas)return{x:1,y:1};var t=this.text.split(""),e=this._getCursorBoundaries(t,"cursor"),i=this.get2DCursorLocation(),r=i.lineIndex,n=i.charIndex,s=this.getCurrentCharFontSize(r,n),o=0===r&&0===n?this._getLineLeftOffset(this._getLineWidth(this.ctx,r)):e.leftOffset,a=this.calcTransformMatrix(),h={x:e.left+o,y:e.top+e.topOffset+s},c=this.canvas.upperCanvasEl,l=c.width-s,u=c.height-s;return h=fabric.util.transformPoint(h,a),h=fabric.util.transformPoint(h,this.canvas.viewportTransform),h.x<0&&(h.x=0),h.x>l&&(h.x=l),h.y<0&&(h.y=0),h.y>u&&(h.y=u),{left:h.x+"px",top:h.y+"px",fontSize:s}},_saveEditingProps:function(){this._savedProps={hasControls:this.hasControls,borderColor:this.borderColor,lockMovementX:this.lockMovementX,lockMovementY:this.lockMovementY,hoverCursor:this.hoverCursor,defaultCursor:this.canvas&&this.canvas.defaultCursor,moveCursor:this.canvas&&this.canvas.moveCursor}},_restoreEditingProps:function(){this._savedProps&&(this.hoverCursor=this._savedProps.overCursor,this.hasControls=this._savedProps.hasControls,this.borderColor=this._savedProps.borderColor,this.lockMovementX=this._savedProps.lockMovementX,this.lockMovementY=this._savedProps.lockMovementY,this.canvas&&(this.canvas.defaultCursor=this._savedProps.defaultCursor,this.canvas.moveCursor=this._savedProps.moveCursor))},exitEditing:function(){var t=this._textBeforeEdit!==this.text;return this.selected=!1,this.isEditing=!1,this.selectable=!0,this.selectionEnd=this.selectionStart,this.hiddenTextarea&&this.canvas&&this.hiddenTextarea.parentNode.removeChild(this.hiddenTextarea),this.hiddenTextarea=null,this.abortCursorAnimation(),this._restoreEditingProps(),this._currentCursorOpacity=0,this.fire("editing:exited"),t&&this.fire("modified"),this.canvas&&(this.canvas.off("mouse:move",this.mouseMoveHandler),this.canvas.fire("text:editing:exited",{target:this}),t&&this.canvas.fire("object:modified",{target:this})),this},_removeExtraneousStyles:function(){for(var t in this.styles)this._textLines[t]||delete this.styles[t]},_removeCharsFromTo:function(t,e){for(;e!==t;)this._removeSingleCharAndStyle(t+1),e--;this.selectionStart=t,this.selectionEnd=t},_removeSingleCharAndStyle:function(t){var e="\n"===this.text[t-1],i=e?t:t-1;this.removeStyleObject(e,i),this.text=this.text.slice(0,t-1)+this.text.slice(t),this._textLines=this._splitTextIntoLines()},insertChars:function(t,e){var i;if(this.selectionEnd-this.selectionStart>1&&this._removeCharsFromTo(this.selectionStart,this.selectionEnd),!e&&this.isEmptyStyles())return void this.insertChar(t,!1);for(var r=0,n=t.length;r=i&&(s[parseInt(o,10)-i]=this.styles[e][o],delete this.styles[e][o]);this.styles[e+1]=s}this._forceClearCache=!0},insertCharStyleObject:function(e,i,r){var n=this.styles[e],s=t(n);0!==i||r||(i=1);for(var o in s){var a=parseInt(o,10);a>=i&&(n[a+1]=s[a],s[a-1]||delete n[a])}this.styles[e][i]=r||t(n[i-1]),this._forceClearCache=!0},insertStyleObjects:function(t,e,i){var r=this.get2DCursorLocation(),n=r.lineIndex,s=r.charIndex;this._getLineStyle(n)||this._setLineStyle(n,{}),"\n"===t?this.insertNewlineStyleObject(n,s,e):this.insertCharStyleObject(n,s,i)},shiftLineStyles:function(e,i){ -var r=t(this.styles);for(var n in this.styles){var s=parseInt(n,10);s>e&&(this.styles[s+i]=r[s],r[s-i]||delete this.styles[s])}},removeStyleObject:function(t,e){var i=this.get2DCursorLocation(e),r=i.lineIndex,n=i.charIndex;this._removeStyleObject(t,i,r,n)},_getTextOnPreviousLine:function(t){return this._textLines[t-1]},_removeStyleObject:function(e,i,r,n){if(e){var s=this._getTextOnPreviousLine(i.lineIndex),o=s?s.length:0;this.styles[r-1]||(this.styles[r-1]={});for(n in this.styles[r])this.styles[r-1][parseInt(n,10)+o]=this.styles[r][n];this.shiftLineStyles(i.lineIndex,-1)}else{var a=this.styles[r];a&&delete a[n];var h=t(a);for(var c in h){var l=parseInt(c,10);l>=n&&0!==l&&(a[l-1]=h[l],delete a[l])}}},insertNewline:function(){this.insertChars("\n")}})}(),fabric.util.object.extend(fabric.IText.prototype,{initDoubleClickSimulation:function(){this.__lastClickTime=+new Date,this.__lastLastClickTime=+new Date,this.__lastPointer={},this.on("mousedown",this.onMouseDown.bind(this))},onMouseDown:function(t){this.__newClickTime=+new Date;var e=this.canvas.getPointer(t.e);this.isTripleClick(e)?(this.fire("tripleclick",t),this._stopEvent(t.e)):this.isDoubleClick(e)&&(this.fire("dblclick",t),this._stopEvent(t.e)),this.__lastLastClickTime=this.__lastClickTime,this.__lastClickTime=this.__newClickTime,this.__lastPointer=e,this.__lastIsEditing=this.isEditing,this.__lastSelected=this.selected},isDoubleClick:function(t){return this.__newClickTime-this.__lastClickTime<500&&this.__lastPointer.x===t.x&&this.__lastPointer.y===t.y&&this.__lastIsEditing},isTripleClick:function(t){return this.__newClickTime-this.__lastClickTime<500&&this.__lastClickTime-this.__lastLastClickTime<500&&this.__lastPointer.x===t.x&&this.__lastPointer.y===t.y},_stopEvent:function(t){t.preventDefault&&t.preventDefault(),t.stopPropagation&&t.stopPropagation()},initCursorSelectionHandlers:function(){this.initSelectedHandler(),this.initMousedownHandler(),this.initMouseupHandler(),this.initClicks()},initClicks:function(){this.on("dblclick",function(t){this.selectWord(this.getSelectionStartFromPointer(t.e))}),this.on("tripleclick",function(t){this.selectLine(this.getSelectionStartFromPointer(t.e))})},initMousedownHandler:function(){this.on("mousedown",function(t){if(this.editable){var e=this.canvas.getPointer(t.e);this.__mousedownX=e.x,this.__mousedownY=e.y,this.__isMousedown=!0,this.selected&&this.setCursorByClick(t.e),this.isEditing&&(this.__selectionStartOnMouseDown=this.selectionStart,this.selectionStart===this.selectionEnd&&this.abortCursorAnimation(),this.renderCursorOrSelection())}})},_isObjectMoved:function(t){var e=this.canvas.getPointer(t);return this.__mousedownX!==e.x||this.__mousedownY!==e.y},initMouseupHandler:function(){this.on("mouseup",function(t){this.__isMousedown=!1,this.editable&&!this._isObjectMoved(t.e)&&(this.__lastSelected&&!this.__corner&&(this.enterEditing(t.e),this.selectionStart===this.selectionEnd?this.initDelayedCursor(!0):this.renderCursorOrSelection()),this.selected=!0)})},setCursorByClick:function(t){var e=this.getSelectionStartFromPointer(t);t.shiftKey?es?0:1,h=r+a;return this.flipX&&(h=n-h),h>this.text.length&&(h=this.text.length),h}}),fabric.util.object.extend(fabric.IText.prototype,{initHiddenTextarea:function(){this.hiddenTextarea=fabric.document.createElement("textarea"),this.hiddenTextarea.setAttribute("autocapitalize","off");var t=this._calcTextareaPosition();this.hiddenTextarea.style.cssText="position: absolute; top: "+t.top+"; left: "+t.left+"; opacity: 0; width: 0px; height: 0px; z-index: -999;",fabric.document.body.appendChild(this.hiddenTextarea),fabric.util.addListener(this.hiddenTextarea,"keydown",this.onKeyDown.bind(this)),fabric.util.addListener(this.hiddenTextarea,"keyup",this.onKeyUp.bind(this)),fabric.util.addListener(this.hiddenTextarea,"input",this.onInput.bind(this)),fabric.util.addListener(this.hiddenTextarea,"copy",this.copy.bind(this)),fabric.util.addListener(this.hiddenTextarea,"cut",this.cut.bind(this)),fabric.util.addListener(this.hiddenTextarea,"paste",this.paste.bind(this)),fabric.util.addListener(this.hiddenTextarea,"compositionstart",this.onCompositionStart.bind(this)),fabric.util.addListener(this.hiddenTextarea,"compositionupdate",this.onCompositionUpdate.bind(this)),fabric.util.addListener(this.hiddenTextarea,"compositionend",this.onCompositionEnd.bind(this)),!this._clickHandlerInitialized&&this.canvas&&(fabric.util.addListener(this.canvas.upperCanvasEl,"click",this.onClick.bind(this)),this._clickHandlerInitialized=!0)},_keysMap:{8:"removeChars",9:"exitEditing",27:"exitEditing",13:"insertNewline",33:"moveCursorUp",34:"moveCursorDown",35:"moveCursorRight",36:"moveCursorLeft",37:"moveCursorLeft",38:"moveCursorUp",39:"moveCursorRight",40:"moveCursorDown",46:"forwardDelete"},_ctrlKeysMapUp:{67:"copy",88:"cut"},_ctrlKeysMapDown:{65:"selectAll"},onClick:function(){this.hiddenTextarea&&this.hiddenTextarea.focus()},onKeyDown:function(t){if(this.isEditing){if(t.keyCode in this._keysMap)this[this._keysMap[t.keyCode]](t);else{if(!(t.keyCode in this._ctrlKeysMapDown&&(t.ctrlKey||t.metaKey)))return;this[this._ctrlKeysMapDown[t.keyCode]](t)}t.stopImmediatePropagation(),t.preventDefault(),this.canvas&&this.canvas.renderAll()}},onKeyUp:function(t){return!this.isEditing||this._copyDone?void(this._copyDone=!1):void(t.keyCode in this._ctrlKeysMapUp&&(t.ctrlKey||t.metaKey)&&(this[this._ctrlKeysMapUp[t.keyCode]](t),t.stopImmediatePropagation(),t.preventDefault(),this.canvas&&this.canvas.renderAll()))},onInput:function(t){if(this.isEditing&&!this.inCompositionMode){var e,i,r,n=this.selectionStart||0,s=this.selectionEnd||0,o=this.text.length,a=this.hiddenTextarea.value.length;a>o?(r="left"===this._selectionDirection?s:n,e=a-o,i=this.hiddenTextarea.value.slice(r,r+e)):(e=a-o+s-n,i=this.hiddenTextarea.value.slice(n,n+e)),this.insertChars(i),t.stopPropagation()}},onCompositionStart:function(){this.inCompositionMode=!0,this.prevCompositionLength=0,this.compositionStart=this.selectionStart},onCompositionEnd:function(){this.inCompositionMode=!1},onCompositionUpdate:function(t){var e=t.data;this.selectionStart=this.compositionStart,this.selectionEnd=this.selectionEnd===this.selectionStart?this.compositionStart+this.prevCompositionLength:this.selectionEnd,this.insertChars(e,!1),this.prevCompositionLength=e.length},forwardDelete:function(t){if(this.selectionStart===this.selectionEnd){if(this.selectionStart===this.text.length)return;this.moveCursorRight(t)}this.removeChars(t)},copy:function(t){if(this.selectionStart!==this.selectionEnd){var e=this.getSelectedText(),i=this._getClipboardData(t);i&&i.setData("text",e),fabric.copiedText=e,fabric.copiedTextStyle=this.getSelectionStyles(this.selectionStart,this.selectionEnd),t.stopImmediatePropagation(),t.preventDefault(),this._copyDone=!0}},paste:function(t){var e=null,i=this._getClipboardData(t),r=!0;i?(e=i.getData("text").replace(/\r/g,""),fabric.copiedTextStyle&&fabric.copiedText===e||(r=!1)):e=fabric.copiedText,e&&this.insertChars(e,r),t.stopImmediatePropagation(),t.preventDefault()},cut:function(t){this.selectionStart!==this.selectionEnd&&(this.copy(t),this.removeChars(t))},_getClipboardData:function(t){return t&&t.clipboardData||fabric.window.clipboardData},getDownCursorOffset:function(t,e){var i,r,n=e?this.selectionEnd:this.selectionStart,s=this.get2DCursorLocation(n),o=s.lineIndex,a=this._textLines[o].slice(0,s.charIndex),h=this._textLines[o].slice(s.charIndex),c=this._textLines[o+1]||"";if(o===this._textLines.length-1||t.metaKey||34===t.keyCode)return this.text.length-n;var l=this._getLineWidth(this.ctx,o);r=this._getLineLeftOffset(l);for(var u=r,f=0,d=a.length;fi){r=!0;var d=a-f,g=a,p=Math.abs(d-i),v=Math.abs(g-i);h=v=this.text.length&&this.selectionEnd>=this.text.length||this._moveCursorUpOrDown("Down",t)},moveCursorDownWithoutShift:function(t){return this._selectionDirection="right",this.selectionEnd=this.selectionEnd+t,this.selectionStart=this.selectionEnd,0!==t},swapSelectionPoints:function(){var t=this.selectionEnd;this.selectionEnd=this.selectionStart,this.selectionStart=t},moveCursorDownWithShift:function(t){return this.selectionEnd===this.selectionStart&&(this._selectionDirection="right"),"right"===this._selectionDirection?this.selectionEnd+=t:this.selectionStart+=t,this.selectionEndthis.text.length&&(this.selectionEnd=this.text.length),0!==t},getUpCursorOffset:function(t,e){var i=e?this.selectionEnd:this.selectionStart,r=this.get2DCursorLocation(i),n=r.lineIndex;if(0===n||t.metaKey||33===t.keyCode)return i;for(var s,o=this._textLines[n].slice(0,r.charIndex),a=this._textLines[n-1]||"",h=this._getLineWidth(this.ctx,r.lineIndex),c=this._getLineLeftOffset(h),l=c,u=0,f=o.length;ui){r=!0;var d=a-f,g=a,p=Math.abs(d-i),v=Math.abs(g-i);h=v=this.text.length&&this.selectionEnd>=this.text.length||this._moveCursorLeftOrRight("Right",t)},_moveCursorLeftOrRight:function(t,e){var i="moveCursor"+t+"With";this._currentCursorOpacity=1,i+=e.shiftKey?"Shift":"outShift",this[i](e)&&(this.abortCursorAnimation(),this.initDelayedCursor(),this._fireSelectionChanged(),this._updateTextarea())},moveCursorRightWithShift:function(t){return"left"===this._selectionDirection&&this.selectionStart!==this.selectionEnd?this._moveRight(t,"selectionStart"):this.selectionEnd!==this.text.length?(this._selectionDirection="right",this._moveRight(t,"selectionEnd")):void 0},moveCursorRightWithoutShift:function(t){var e=!0;return this._selectionDirection="right",this.selectionStart===this.selectionEnd?(e=this._moveRight(t,"selectionStart"),this.selectionEnd=this.selectionStart):this.selectionStart=this.selectionEnd,e},removeChars:function(t){this.selectionStart===this.selectionEnd?this._removeCharsNearCursor(t):this._removeCharsFromTo(this.selectionStart,this.selectionEnd),this.setSelectionEnd(this.selectionStart),this._removeExtraneousStyles(),this.canvas&&this.canvas.renderAll(),this.setCoords(),this.fire("changed"),this.canvas&&this.canvas.fire("text:changed",{target:this})},_removeCharsNearCursor:function(t){if(0!==this.selectionStart)if(t.metaKey){var e=this.findLineBoundaryLeft(this.selectionStart);this._removeCharsFromTo(e,this.selectionStart),this.setSelectionStart(e)}else if(t.altKey){var i=this.findWordBoundaryLeft(this.selectionStart);this._removeCharsFromTo(i,this.selectionStart),this.setSelectionStart(i)}else this._removeSingleCharAndStyle(this.selectionStart),this.setSelectionStart(this.selectionStart-1)}}),function(){var t=fabric.util.toFixed,e=fabric.Object.NUM_FRACTION_DIGITS;fabric.util.object.extend(fabric.IText.prototype,{_setSVGTextLineText:function(t,e,i,r,n,s){this._getLineStyle(t)?this._setSVGTextLineChars(t,e,i,r,s):fabric.Text.prototype._setSVGTextLineText.call(this,t,e,i,r,n)},_setSVGTextLineChars:function(t,e,i,r,n){for(var s=this._textLines[t],o=0,a=this._getLineLeftOffset(this._getLineWidth(this.ctx,t))-this.width/2,h=this._getSVGLineTopOffset(t),c=this._getHeightOfLine(this.ctx,t),l=0,u=s.length;l\n'].join("")},_createTextCharSpan:function(i,r,n,s,o){var a=this.getSvgStyles.call(fabric.util.object.extend({visible:!0,fill:this.fill,stroke:this.stroke,type:"text",getSvgFilter:fabric.Object.prototype.getSvgFilter},r));return['\t\t\t',fabric.util.string.escapeXml(i),"\n"].join("")}})}(),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=e.util.object.clone;e.Textbox=e.util.createClass(e.IText,e.Observable,{type:"textbox",minWidth:20,dynamicMinWidth:0,__cachedLines:null,lockScalingY:!0,lockScalingFlip:!0,initialize:function(t,i){this.ctx=e.util.createCanvasElement().getContext("2d"),this.callSuper("initialize",t,i),this.setControlsVisibility(e.Textbox.getTextboxControlVisibility()),this._dimensionAffectingProps.width=!0},_initDimensions:function(t){this.__skipDimension||(t||(t=e.util.createCanvasElement().getContext("2d"),this._setTextStyles(t)),this.dynamicMinWidth=0,this._textLines=this._splitTextIntoLines(),this.dynamicMinWidth>this.width&&this._set("width",this.dynamicMinWidth),this._clearCache(),this.height=this._getTextHeight(t))},_generateStyleMap:function(){for(var t=0,e=0,i=0,r={},n=0;n=this.width&&!d?(n.push(s),s="",r=l,d=!0):r+=g,d||(s+=c),s+=a,u=this._measureText(t,c,i,h),h++,d=!1,l>f&&(f=l);return p&&n.push(s),f>this.dynamicMinWidth&&(this.dynamicMinWidth=f-g),n},_splitTextIntoLines:function(){var t=this.textAlign;this.ctx.save(),this._setTextStyles(this.ctx),this.textAlign="left";var e=this._wrapText(this.ctx,this.text);return this.textAlign=t,this.ctx.restore(),this._textLines=e,this._styleMap=this._generateStyleMap(),e},setOnGroup:function(t,e){"scaleX"===t&&(this.set("scaleX",Math.abs(1/e)),this.set("width",this.get("width")*e/("undefined"==typeof this.__oldScaleX?1:this.__oldScaleX)),this.__oldScaleX=e)},get2DCursorLocation:function(t){"undefined"==typeof t&&(t=this.selectionStart);for(var e=this._textLines.length,i=0,r=0;r=h.getMinWidth()?(h.set("width",c),!0):void 0},fabric.Group.prototype._refreshControlsVisibility=function(){if("undefined"!=typeof fabric.Textbox)for(var t=this._objects.length;t--;)if(this._objects[t]instanceof fabric.Textbox)return void this.setControlsVisibility(fabric.Textbox.getTextboxControlVisibility())};var e=fabric.util.object.clone;fabric.util.object.extend(fabric.Textbox.prototype,{_removeExtraneousStyles:function(){for(var t in this._styleMap)this._textLines[t]||delete this.styles[this._styleMap[t].line]},insertCharStyleObject:function(t,e,i){var r=this._styleMap[t];t=r.line,e=r.offset+e,fabric.IText.prototype.insertCharStyleObject.apply(this,[t,e,i])},insertNewlineStyleObject:function(t,e,i){var r=this._styleMap[t];t=r.line,e=r.offset+e,fabric.IText.prototype.insertNewlineStyleObject.apply(this,[t,e,i])},shiftLineStyles:function(t,i){var r=e(this.styles),n=this._styleMap[t];t=n.line;for(var s in this.styles){var o=parseInt(s,10);o>t&&(this.styles[o+i]=r[o],r[o-i]||delete this.styles[o])}},_getTextOnPreviousLine:function(t){for(var e=this._textLines[t-1];this._styleMap[t-2]&&this._styleMap[t-2].line===this._styleMap[t-1].line;)e=this._textLines[t-2]+e,t--;return e},removeStyleObject:function(t,e){var i=this.get2DCursorLocation(e),r=this._styleMap[i.lineIndex],n=r.line,s=r.offset+i.charIndex;this._removeStyleObject(t,i,n,s)}})}(),function(){var t=fabric.IText.prototype._getNewSelectionStartFromOffset;fabric.IText.prototype._getNewSelectionStartFromOffset=function(e,i,r,n,s){n=t.call(this,e,i,r,n,s);for(var o=0,a=0,h=0;h=n));h++)"\n"!==this.text[o+a]&&" "!==this.text[o+a]||a++;return n-h+a}}(),function(){function request(t,e,i){var r=URL.parse(t);r.port||(r.port=0===r.protocol.indexOf("https:")?443:80);var n=0===r.protocol.indexOf("https:")?HTTPS:HTTP,s=n.request({hostname:r.hostname,port:r.port,path:r.path,method:"GET"},function(t){var r="";e&&t.setEncoding(e),t.on("end",function(){i(r)}),t.on("data",function(e){200===t.statusCode&&(r+=e)})});s.on("error",function(t){t.errno===process.ECONNREFUSED?fabric.log("ECONNREFUSED: connection refused to "+r.hostname+":"+r.port):fabric.log(t.message),i(null)}),s.end()}function requestFs(t,e){var i=require("fs");i.readFile(t,function(t,i){if(t)throw fabric.log(t),t;e(i)})}if("undefined"==typeof document||"undefined"==typeof window){var DOMParser=require("xmldom").DOMParser,URL=require("url"),HTTP=require("http"),HTTPS=require("https"),Canvas=require("canvas"),Image=require("canvas").Image;fabric.util.loadImage=function(t,e,i){function r(r){r?(n.src=new Buffer(r,"binary"),n._src=t,e&&e.call(i,n)):(n=null,e&&e.call(i,null,!0))}var n=new Image;t&&(t instanceof Buffer||0===t.indexOf("data"))?(n.src=n._src=t,e&&e.call(i,n)):t&&0!==t.indexOf("http")?requestFs(t,r):t?request(t,"binary",r):e&&e.call(i,t)},fabric.loadSVGFromURL=function(t,e,i){t=t.replace(/^\n\s*/,"").replace(/\?.*$/,"").trim(),0!==t.indexOf("http")?requestFs(t,function(t){fabric.loadSVGFromString(t.toString(),e,i)}):request(t,"",function(t){fabric.loadSVGFromString(t,e,i)})},fabric.loadSVGFromString=function(t,e,i){var r=(new DOMParser).parseFromString(t);fabric.parseSVGDocument(r.documentElement,function(t,i){e&&e(t,i)},i)},fabric.util.getScript=function(url,callback){request(url,"",function(body){eval(body),callback&&callback()})},fabric.createCanvasForNode=function(t,e,i,r){r=r||i;var n=fabric.document.createElement("canvas"),s=new Canvas(t||600,e||600,r),o=new Canvas(t||600,e||600,r);n.style={},n.width=s.width,n.height=s.height;var a=fabric.Canvas||fabric.StaticCanvas,h=new a(n,i);return h.contextContainer=s.getContext("2d"),h.nodeCanvas=s,h.contextCache=o.getContext("2d"),h.nodeCacheCanvas=o,h.Font=Canvas.Font,h},fabric.StaticCanvas.prototype.createPNGStream=function(){return this.nodeCanvas.createPNGStream()},fabric.StaticCanvas.prototype.createJPEGStream=function(t){return this.nodeCanvas.createJPEGStream(t)};var origSetWidth=fabric.StaticCanvas.prototype.setWidth;fabric.StaticCanvas.prototype.setWidth=function(t,e){return origSetWidth.call(this,t,e),this.nodeCanvas.width=t,this},fabric.Canvas&&(fabric.Canvas.prototype.setWidth=fabric.StaticCanvas.prototype.setWidth);var origSetHeight=fabric.StaticCanvas.prototype.setHeight;fabric.StaticCanvas.prototype.setHeight=function(t,e){return origSetHeight.call(this,t,e),this.nodeCanvas.height=t,this},fabric.Canvas&&(fabric.Canvas.prototype.setHeight=fabric.StaticCanvas.prototype.setHeight)}}(); \ No newline at end of file +var fabric=fabric||{version:"1.6.5"};"undefined"!=typeof exports&&(exports.fabric=fabric),"undefined"!=typeof document&&"undefined"!=typeof window?(fabric.document=document,fabric.window=window,window.fabric=fabric):(fabric.document=require("jsdom").jsdom(""),fabric.document.createWindow?fabric.window=fabric.document.createWindow():fabric.window=fabric.document.parentWindow),fabric.isTouchSupported="ontouchstart"in fabric.document.documentElement,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"],fabric.DPI=96,fabric.reNum="(?:[-+]?(?:\\d+|\\d*\\.\\d+)(?:e[-+]?\\d+)?)",fabric.fontPaths={},fabric.charWidthsCache={},fabric.devicePixelRatio=fabric.window.devicePixelRatio||fabric.window.webkitDevicePixelRatio||fabric.window.mozDevicePixelRatio||1,function(){function t(t,e){if(this.__eventListeners[t]){var i=this.__eventListeners[t];e?i[i.indexOf(e)]=!1:fabric.util.array.fill(i,!1)}}function e(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 i(e,i){if(this.__eventListeners){if(0===arguments.length)for(e in this.__eventListeners)t.call(this,e);else if(1===arguments.length&&"object"==typeof arguments[0])for(var r in e)t.call(this,r,e[r]);else t.call(this,e,i);return this}}function r(t,e){if(this.__eventListeners){var i=this.__eventListeners[t];if(i){for(var r=0,n=i.length;r-1},complexity:function(){return this.getObjects().reduce(function(t,e){return t+=e.complexity?e.complexity():0},0)}},function(t){var e=Math.sqrt,i=Math.atan2,r=Math.pow,n=Math.abs,s=Math.PI/180;fabric.util={removeFromArray:function(t,e){var i=t.indexOf(e);return i!==-1&&t.splice(i,1),t},getRandomInt:function(t,e){return Math.floor(Math.random()*(e-t+1))+t},degreesToRadians:function(t){return t*s},radiansToDegrees:function(t){return t/s},rotatePoint:function(t,e,i){t.subtractEquals(e);var r=fabric.util.rotateVector(t,i);return new fabric.Point(r.x,r.y).addEquals(e)},rotateVector:function(t,e){var i=Math.sin(e),r=Math.cos(e),n=t.x*r-t.y*i,s=t.x*i+t.y*r;return{x:n,y:s}},transformPoint:function(t,e,i){return i?new fabric.Point(e[0]*t.x+e[2]*t.y,e[1]*t.x+e[3]*t.y):new fabric.Point(e[0]*t.x+e[2]*t.y+e[4],e[1]*t.x+e[3]*t.y+e[5])},makeBoundingBoxFromPoints:function(t){var e=[t[0].x,t[1].x,t[2].x,t[3].x],i=fabric.util.array.min(e),r=fabric.util.array.max(e),n=Math.abs(i-r),s=[t[0].y,t[1].y,t[2].y,t[3].y],o=fabric.util.array.min(s),a=fabric.util.array.max(s),h=Math.abs(o-a);return{left:i,top:o,width:n,height:h}},invertTransform:function(t){var e=1/(t[0]*t[3]-t[1]*t[2]),i=[e*t[3],-e*t[1],-e*t[2],e*t[0]],r=fabric.util.transformPoint({x:t[4],y:t[5]},i,!0);return i[4]=-r.x,i[5]=-r.y,i},toFixed:function(t,e){return parseFloat(Number(t).toFixed(e))},parseUnit:function(t,e){var i=/\D{0,2}$/.exec(t),r=parseFloat(t);switch(e||(e=fabric.Text.DEFAULT_SVG_FONT_SIZE),i[0]){case"mm":return r*fabric.DPI/25.4;case"cm":return r*fabric.DPI/2.54;case"in":return r*fabric.DPI;case"pt":return r*fabric.DPI/72;case"pc":return r*fabric.DPI/72*12;case"em":return r*e;default:return r}},falseFunction:function(){return!1},getKlass:function(t,e){return t=fabric.util.string.camelize(t.charAt(0).toUpperCase()+t.slice(1)),fabric.util.resolveNamespace(e)[t]},resolveNamespace:function(e){if(!e)return fabric;var i,r=e.split("."),n=r.length,s=t||fabric.window;for(i=0;ir;)r+=a[d++%f],r>l&&(r=l),t[g?"lineTo":"moveTo"](r,0),g=!g;t.restore()},createCanvasElement:function(t){return t||(t=fabric.document.createElement("canvas")),t.getContext||"undefined"==typeof G_vmlCanvasManager||G_vmlCanvasManager.initElement(t),t},createImage:function(){return fabric.isLikelyNode?new(require("canvas").Image):fabric.document.createElement("img")},createAccessors:function(t){var e,i,r,n,s,o=t.prototype;for(e=o.stateProperties.length;e--;)i=o.stateProperties[e],r=i.charAt(0).toUpperCase()+i.slice(1),n="set"+r,s="get"+r,o[s]||(o[s]=function(t){return new Function('return this.get("'+t+'")')}(i)),o[n]||(o[n]=function(t){return new Function("value",'return this.set("'+t+'", value)')}(i))},clipContext:function(t,e){e.save(),e.beginPath(),t.clipTo(e),e.clip()},multiplyTransformMatrices:function(t,e,i){return[t[0]*e[0]+t[2]*e[1],t[1]*e[0]+t[3]*e[1],t[0]*e[2]+t[2]*e[3],t[1]*e[2]+t[3]*e[3],i?0:t[0]*e[4]+t[2]*e[5]+t[4],i?0:t[1]*e[4]+t[3]*e[5]+t[5]]},qrDecompose:function(t){var n=i(t[1],t[0]),o=r(t[0],2)+r(t[1],2),a=e(o),h=(t[0]*t[3]-t[2]*t[1])/a,c=i(t[0]*t[2]+t[1]*t[3],o);return{angle:n/s,scaleX:a,scaleY:h,skewX:c/s,skewY:0,translateX:t[4],translateY:t[5]}},customTransformMatrix:function(t,e,i){var r=[1,0,n(Math.tan(i*s)),1],o=[n(t),0,0,n(e)];return fabric.util.multiplyTransformMatrices(o,r,!0)},resetObjectTransform:function(t){t.scaleX=1,t.scaleY=1,t.skewX=0,t.skewY=0,t.flipX=!1,t.flipY=!1,t.setAngle(0)},getFunctionBody:function(t){return(String(t).match(/function[^{]*\{([\s\S]*)\}/)||{})[1]},isTransparent:function(t,e,i,r){r>0&&(e>r?e-=r:e=0,i>r?i-=r:i=0);var n,s,o=!0,a=t.getImageData(e,i,2*r||1,2*r||1),h=a.data.length;for(n=3;n0?D-=2*f:1===c&&D<0&&(D+=2*f);for(var E=Math.ceil(Math.abs(D/f*2)),L=[],I=D/E,R=8/3*Math.sin(I/4)*Math.sin(I/4)/Math.sin(I/2),F=P+I,B=0;B=n?s-n:2*Math.PI-(n-s)}function r(t,e,i,r,n,s,h,c){var l=a.call(arguments);if(o[l])return o[l];var u,f,d,g,p,v,b,m,y=Math.sqrt,_=Math.min,x=Math.max,S=Math.abs,C=[],w=[[],[]];f=6*t-12*i+6*n,u=-3*t+9*i-9*n+3*h,d=3*i-3*t;for(var O=0;O<2;++O)if(O>0&&(f=6*e-12*r+6*s,u=-3*e+9*r-9*s+3*c,d=3*r-3*e),S(u)<1e-12){if(S(f)<1e-12)continue;g=-d/f,0=e})}function i(t,e){return n(t,e,function(t,e){return t>>0;if(0===i)return-1;var r=0;if(arguments.length>0&&(r=Number(arguments[1]),r!==r?r=0:0!==r&&r!==Number.POSITIVE_INFINITY&&r!==Number.NEGATIVE_INFINITY&&(r=(r>0||-1)*Math.floor(Math.abs(r)))),r>=i)return-1;for(var n=r>=0?r:Math.max(i-Math.abs(r),0);n>>0;i>>0;r>>0;i>>0;i>>0;n>>0,r=0;if(arguments.length>1)e=arguments[1];else for(;;){if(r in this){e=this[r++];break}if(++r>=i)throw new TypeError}for(;r/g,">")}String.prototype.trim||(String.prototype.trim=function(){return this.replace(/^[\s\xA0]+/,"").replace(/[\s\xA0]+$/,"")}),fabric.util.string={camelize:t,capitalize:e,escapeXml:i}}(),function(){var t=Array.prototype.slice,e=Function.prototype.apply,i=function(){};Function.prototype.bind||(Function.prototype.bind=function(r){var n,s=this,o=t.call(arguments,1);return n=o.length?function(){return e.call(s,this instanceof i?this:r,o.concat(t.call(arguments)))}:function(){return e.call(s,this instanceof i?this:r,arguments)},i.prototype=this.prototype,n.prototype=new i,n})}(),function(){function t(){}function e(t){var e=this.constructor.superclass.prototype[t];return arguments.length>1?e.apply(this,r.call(arguments,1)):e.call(this)}function i(){function i(){this.initialize.apply(this,arguments)}var s=null,a=r.call(arguments,0);"function"==typeof a[0]&&(s=a.shift()),i.superclass=s,i.subclasses=[],s&&(t.prototype=s.prototype,i.prototype=new t,s.subclasses.push(i));for(var h=0,c=a.length;h-1?t.prototype[r]=function(t){return function(){var r=this.constructor.superclass;this.constructor.superclass=i;var n=e[t].apply(this,arguments);if(this.constructor.superclass=r,"initialize"!==t)return n}}(r):t.prototype[r]=e[r],s&&(e.toString!==Object.prototype.toString&&(t.prototype.toString=e.toString),e.valueOf!==Object.prototype.valueOf&&(t.prototype.valueOf=e.valueOf))};fabric.util.createClass=i}(),function(){function t(t){var e,i,r=Array.prototype.slice.call(arguments,1),n=r.length;for(i=0;i-1?s(t,e.match(/opacity:\s*(\d?\.?\d*)/)[1]):t;for(var r in e)if("opacity"===r)s(t,e[r]);else{var n="float"===r||"cssFloat"===r?"undefined"==typeof i.styleFloat?"cssFloat":"styleFloat":r;i[n]=e[r]}return t}var e=fabric.document.createElement("div"),i="string"==typeof e.style.opacity,r="string"==typeof e.style.filter,n=/alpha\s*\(\s*opacity\s*=\s*([^\)]+)\)/,s=function(t){return t};i?s=function(t,e){return t.style.opacity=e,t}:r&&(s=function(t,e){var i=t.style;return t.currentStyle&&!t.currentStyle.hasLayout&&(i.zoom=1),n.test(i.filter)?(e=e>=.9999?"":"alpha(opacity="+100*e+")",i.filter=i.filter.replace(n,e)):i.filter+=" alpha(opacity="+100*e+")",t}),fabric.util.setStyle=t}(),function(){function t(t){return"string"==typeof t?fabric.document.getElementById(t):t}function e(t,e){var i=fabric.document.createElement(t);for(var r in e)"class"===r?i.className=e[r]:"for"===r?i.htmlFor=e[r]:i.setAttribute(r,e[r]);return i}function i(t,e){t&&(" "+t.className+" ").indexOf(" "+e+" ")===-1&&(t.className+=(t.className?" ":"")+e)}function r(t,i,r){return"string"==typeof i&&(i=e(i,r)),t.parentNode&&t.parentNode.replaceChild(i,t),i.appendChild(t),i}function n(t){for(var e=0,i=0,r=fabric.document.documentElement,n=fabric.document.body||{scrollLeft:0,scrollTop:0};t&&(t.parentNode||t.host)&&(t=t.parentNode||t.host,t===fabric.document?(e=n.scrollLeft||r.scrollLeft||0,i=n.scrollTop||r.scrollTop||0):(e+=t.scrollLeft||0,i+=t.scrollTop||0),1!==t.nodeType||"fixed"!==fabric.util.getElementStyle(t,"position")););return{left:e,top:i}}function s(t){var e,i,r=t&&t.ownerDocument,s={left:0,top:0},o={left:0,top:0},a={borderLeftWidth:"left",borderTopWidth:"top",paddingLeft:"left",paddingTop:"top"};if(!r)return o;for(var h in a)o[a[h]]+=parseInt(c(t,h),10)||0;return e=r.documentElement,"undefined"!=typeof t.getBoundingClientRect&&(s=t.getBoundingClientRect()),i=n(t),{left:s.left+i.left-(e.clientLeft||0)+o.left,top:s.top+i.top-(e.clientTop||0)+o.top}}var o,a=Array.prototype.slice,h=function(t){return a.call(t,0)};try{o=h(fabric.document.childNodes)instanceof Array}catch(t){}o||(h=function(t){for(var e=new Array(t.length),i=t.length;i--;)e[i]=t[i];return e});var c;c=fabric.document.defaultView&&fabric.document.defaultView.getComputedStyle?function(t,e){var i=fabric.document.defaultView.getComputedStyle(t,null);return i?i[e]:void 0}:function(t,e){var i=t.style[e];return!i&&t.currentStyle&&(i=t.currentStyle[e]),i},function(){function t(t){return"undefined"!=typeof t.onselectstart&&(t.onselectstart=fabric.util.falseFunction),r?t.style[r]="none":"string"==typeof t.unselectable&&(t.unselectable="on"),t}function e(t){return"undefined"!=typeof t.onselectstart&&(t.onselectstart=null),r?t.style[r]="":"string"==typeof t.unselectable&&(t.unselectable=""),t}var i=fabric.document.documentElement.style,r="userSelect"in i?"userSelect":"MozUserSelect"in i?"MozUserSelect":"WebkitUserSelect"in i?"WebkitUserSelect":"KhtmlUserSelect"in i?"KhtmlUserSelect":"";fabric.util.makeElementUnselectable=t,fabric.util.makeElementSelectable=e}(),function(){function t(t,e){var i=fabric.document.getElementsByTagName("head")[0],r=fabric.document.createElement("script"),n=!0;r.onload=r.onreadystatechange=function(t){if(n){if("string"==typeof this.readyState&&"loaded"!==this.readyState&&"complete"!==this.readyState)return;n=!1,e(t||fabric.window.event),r=r.onload=r.onreadystatechange=null}},r.src=t,i.appendChild(r)}fabric.util.getScript=t}(),fabric.util.getById=t,fabric.util.toArray=h,fabric.util.makeElement=e,fabric.util.addClass=i,fabric.util.wrapElement=r,fabric.util.getScrollLeftTop=n,fabric.util.getElementOffset=s,fabric.util.getElementStyle=c}(),function(){function t(t,e){return t+(/\?/.test(t)?"&":"?")+e}function e(){}function i(i,n){n||(n={});var s=n.method?n.method.toUpperCase():"GET",o=n.onComplete||function(){},a=r(),h=n.body||n.parameters;return a.onreadystatechange=function(){4===a.readyState&&(o(a),a.onreadystatechange=e)},"GET"===s&&(h=null,"string"==typeof n.parameters&&(i=t(i,n.parameters))),a.open(s,i,!0),"POST"!==s&&"PUT"!==s||a.setRequestHeader("Content-Type","application/x-www-form-urlencoded"),a.send(h),a}var r=function(){for(var t=[function(){return new ActiveXObject("Microsoft.XMLHTTP")},function(){return new ActiveXObject("Msxml2.XMLHTTP")},function(){return new ActiveXObject("Msxml2.XMLHTTP.3.0")},function(){return new XMLHttpRequest}],e=t.length;e--;)try{var i=t[e]();if(i)return t[e]}catch(t){}}();fabric.util.request=i}(),fabric.log=function(){},fabric.warn=function(){},"undefined"!=typeof console&&["log","warn"].forEach(function(t){"undefined"!=typeof console[t]&&"function"==typeof console[t].apply&&(fabric[t]=function(){return console[t].apply(console,arguments)})}),function(){function t(t){e(function(i){t||(t={});var r,n=i||+new Date,s=t.duration||500,o=n+s,a=t.onChange||function(){},h=t.abort||function(){return!1},c=t.easing||function(t,e,i,r){return-i*Math.cos(t/r*(Math.PI/2))+i+e},l="startValue"in t?t.startValue:0,u="endValue"in t?t.endValue:100,f=t.byValue||u-l;t.onStart&&t.onStart(),function i(u){r=u||+new Date;var d=r>o?s:r-n;return h()?void(t.onComplete&&t.onComplete()):(a(c(d,l,f,s)),r>o?void(t.onComplete&&t.onComplete()):void e(i))}(n)})}function e(){return i.apply(fabric.window,arguments)}var i=fabric.window.requestAnimationFrame||fabric.window.webkitRequestAnimationFrame||fabric.window.mozRequestAnimationFrame||fabric.window.oRequestAnimationFrame||fabric.window.msRequestAnimationFrame||function(t){fabric.window.setTimeout(t,1e3/60)};fabric.util.animate=t,fabric.util.requestAnimFrame=e}(),function(){function t(t,e,i,r){return ta?a:o),1===o&&1===a&&0===h&&0===c&&0===f&&0===d)return y;if((f||d)&&(_=" translate("+x(f)+" "+x(d)+") "),r=_+" matrix("+o+" 0 0 "+a+" "+h*o+" "+c*a+") ","svg"===t.nodeName){for(n=t.ownerDocument.createElement("g");t.firstChild;)n.appendChild(t.firstChild);t.appendChild(n)}else n=t,r=n.getAttribute("transform")+r;return n.setAttribute("transform",r),y}function g(t){var e=t.objects,i=t.options;return e=e.map(function(t){return v[m(t.type)].fromObject(t)}),{objects:e,options:i}}function p(t,e,i){e[i]&&e[i].toSVG&&t.push('\t\n','\t\t\n\t\n')}var v=t.fabric||(t.fabric={}),b=v.util.object.extend,m=v.util.string.capitalize,y=v.util.object.clone,_=v.util.toFixed,x=v.util.parseUnit,S=v.util.multiplyTransformMatrices,C=/^(path|circle|polygon|polyline|ellipse|rect|line|image|text)$/i,w=/^(symbol|image|marker|pattern|view|svg)$/i,O=/^(?:pattern|defs|symbol|metadata)$/i,T=/^(symbol|g|a|svg)$/i,k={cx:"left",x:"left",r:"radius",cy:"top",y:"top",display:"visible",visibility:"visible",transform:"transformMatrix","fill-opacity":"fillOpacity","fill-rule":"fillRule","font-family":"fontFamily","font-size":"fontSize","font-style":"fontStyle","font-weight":"fontWeight","stroke-dasharray":"strokeDashArray","stroke-linecap":"strokeLineCap","stroke-linejoin":"strokeLineJoin","stroke-miterlimit":"strokeMiterLimit","stroke-opacity":"strokeOpacity","stroke-width":"strokeWidth","text-decoration":"textDecoration","text-anchor":"originX"},j={stroke:"strokeOpacity",fill:"fillOpacity"};v.cssRules={},v.gradientDefs={},v.parseTransformAttribute=function(){function t(t,e){var i=e[0],r=3===e.length?e[1]:0,n=3===e.length?e[2]:0;t[0]=Math.cos(i),t[1]=Math.sin(i),t[2]=-Math.sin(i),t[3]=Math.cos(i),t[4]=r-(t[0]*r+t[2]*n),t[5]=n-(t[1]*r+t[3]*n)}function e(t,e){var i=e[0],r=2===e.length?e[1]:e[0];t[0]=i,t[3]=r}function i(t,e){t[2]=Math.tan(v.util.degreesToRadians(e[0])); +}function r(t,e){t[1]=Math.tan(v.util.degreesToRadians(e[0]))}function n(t,e){t[4]=e[0],2===e.length&&(t[5]=e[1])}var s=[1,0,0,1,0,0],o=v.reNum,a="(?:\\s+,?\\s*|,\\s*)",h="(?:(skewX)\\s*\\(\\s*("+o+")\\s*\\))",c="(?:(skewY)\\s*\\(\\s*("+o+")\\s*\\))",l="(?:(rotate)\\s*\\(\\s*("+o+")(?:"+a+"("+o+")"+a+"("+o+"))?\\s*\\))",u="(?:(scale)\\s*\\(\\s*("+o+")(?:"+a+"("+o+"))?\\s*\\))",f="(?:(translate)\\s*\\(\\s*("+o+")(?:"+a+"("+o+"))?\\s*\\))",d="(?:(matrix)\\s*\\(\\s*("+o+")"+a+"("+o+")"+a+"("+o+")"+a+"("+o+")"+a+"("+o+")"+a+"("+o+")\\s*\\))",g="(?:"+d+"|"+f+"|"+u+"|"+l+"|"+h+"|"+c+")",p="(?:"+g+"(?:"+a+"*"+g+")*)",b="^\\s*(?:"+p+"?)\\s*$",m=new RegExp(b),y=new RegExp(g,"g");return function(o){var a=s.concat(),h=[];if(!o||o&&!m.test(o))return a;o.replace(y,function(o){var c=new RegExp(g).exec(o).filter(function(t){return!!t}),l=c[1],u=c.slice(2).map(parseFloat);switch(l){case"translate":n(a,u);break;case"rotate":u[0]=v.util.degreesToRadians(u[0]),t(a,u);break;case"scale":e(a,u);break;case"skewX":i(a,u);break;case"skewY":r(a,u);break;case"matrix":a=u}h.push(a.concat()),a=s.concat()});for(var c=h[0];h.length>1;)h.shift(),c=v.util.multiplyTransformMatrices(c,h[0]);return c}}();var A=new RegExp("^\\s*("+v.reNum+"+)\\s*,?\\s*("+v.reNum+"+)\\s*,?\\s*("+v.reNum+"+)\\s*,?\\s*("+v.reNum+"+)\\s*$");v.parseSVGDocument=function(){function t(t,e){for(;t&&(t=t.parentNode);)if(t.nodeName&&e.test(t.nodeName.replace("svg:",""))&&!t.getAttribute("instantiated_by_use"))return!0;return!1}return function(e,i,r){if(e){f(e);var n=new Date,s=v.Object.__uid++,o=d(e),a=v.util.toArray(e.getElementsByTagName("*"));if(o.svgUid=s,0===a.length&&v.isLikelyNode){a=e.selectNodes('//*[name(.)!="svg"]');for(var h=[],c=0,l=a.length;c/i,""))),n&&n.documentElement||e&&e(null),v.parseSVGDocument(n.documentElement,function(i,r){M.set(t,{objects:v.util.array.invoke(i,"toObject"),options:r}),e&&e(i,r)},i)}t=t.replace(/^\n\s*/,"").trim(),M.has(t,function(i){i?M.get(t,function(t){var i=g(t);e(i.objects,i.options)}):new v.util.request(t,{method:"get",onComplete:r})})},loadSVGFromString:function(t,e,i){t=t.trim();var r;if("undefined"!=typeof DOMParser){var n=new DOMParser;n&&n.parseFromString&&(r=n.parseFromString(t,"text/xml"))}else v.window.ActiveXObject&&(r=new ActiveXObject("Microsoft.XMLDOM"),r.async="false",r.loadXML(t.replace(//i,"")));v.parseSVGDocument(r.documentElement,function(t,i){e(t,i)},i)},createSVGFontFacesMarkup:function(t){for(var e,i,r,n,s,o,a,h="",c={},l=v.fontPaths,u=0,f=t.length;u',"","\n"].join("")),h},createSVGRefElementsMarkup:function(t){var e=[];return p(e,t,"backgroundColor"),p(e,t,"overlayColor"),e.join("")}})}("undefined"!=typeof exports?exports:this),fabric.ElementsParser=function(t,e,i,r){this.elements=t,this.callback=e,this.options=i,this.reviver=r,this.svgUid=i&&i.svgUid||0},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,i){return"undefined"==typeof i&&(i=.5),i=Math.max(Math.min(1,i),0),new e(this.x+(t.x-this.x)*i,this.y+(t.y-this.y)*i)},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 e(Math.min(this.x,t.x),Math.min(this.y,t.y))},max:function(t){return new e(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 e(this.x,this.y)}}))}("undefined"!=typeof exports?exports:this),function(t){"use strict";function e(t){this.status=t,this.points=[]}var i=t.fabric||(t.fabric={});return i.Intersection?void i.warn("fabric.Intersection is already defined"):(i.Intersection=e,i.Intersection.prototype={constructor:e,appendPoint:function(t){return this.points.push(t),this},appendPoints:function(t){return this.points=this.points.concat(t),this}},i.Intersection.intersectLineLine=function(t,r,n,s){var o,a=(s.x-n.x)*(t.y-n.y)-(s.y-n.y)*(t.x-n.x),h=(r.x-t.x)*(t.y-n.y)-(r.y-t.y)*(t.x-n.x),c=(s.y-n.y)*(r.x-t.x)-(s.x-n.x)*(r.y-t.y);if(0!==c){var l=a/c,u=h/c;0<=l&&l<=1&&0<=u&&u<=1?(o=new e("Intersection"),o.appendPoint(new i.Point(t.x+l*(r.x-t.x),t.y+l*(r.y-t.y)))):o=new e}else o=new e(0===a||0===h?"Coincident":"Parallel");return o},i.Intersection.intersectLinePolygon=function(t,i,r){for(var n,s,o,a=new e,h=r.length,c=0;c0&&(a.status="Intersection"),a},i.Intersection.intersectPolygonPolygon=function(t,i){for(var r=new e,n=t.length,s=0;s0&&(r.status="Intersection"),r},void(i.Intersection.intersectPolygonRectangle=function(t,r,n){var s=r.min(n),o=r.max(n),a=new i.Point(o.x,s.y),h=new i.Point(s.x,o.y),c=e.intersectLinePolygon(s,a,t),l=e.intersectLinePolygon(a,o,t),u=e.intersectLinePolygon(o,h,t),f=e.intersectLinePolygon(h,s,t),d=new e;return d.appendPoints(c.points),d.appendPoints(l.points),d.appendPoints(u.points),d.appendPoints(f.points),d.points.length>0&&(d.status="Intersection"),d}))}("undefined"!=typeof exports?exports:this),function(t){"use strict";function e(t){t?this._tryParsingColor(t):this.setSource([0,0,0,1])}function i(t,e,i){return i<0&&(i+=1),i>1&&(i-=1),i<1/6?t+6*(e-t)*i:i<.5?e:i<2/3?t+(e-t)*(2/3-i)*6:t}var r=t.fabric||(t.fabric={});return r.Color?void r.warn("fabric.Color is already defined."):(r.Color=e,r.Color.prototype={_tryParsingColor:function(t){var i;t in e.colorNameMap&&(t=e.colorNameMap[t]),"transparent"===t&&(i=[255,255,255,0]),i||(i=e.sourceFromHex(t)),i||(i=e.sourceFromRgb(t)),i||(i=e.sourceFromHsl(t)),i||(i=[0,0,0,1]),i&&this.setSource(i)},_rgbToHsl:function(t,e,i){t/=255,e/=255,i/=255;var n,s,o,a=r.util.array.max([t,e,i]),h=r.util.array.min([t,e,i]);if(o=(a+h)/2,a===h)n=s=0;else{var c=a-h;switch(s=o>.5?c/(2-a-h):c/(a+h),a){case t:n=(e-i)/c+(e1?1:s,n){var o=n.split(/\s*;\s*/);""===o[o.length-1]&&o.pop();for(var a=o.length;a--;){var h=o[a].split(/\s*:\s*/),c=h[0].trim(),l=h[1].trim();"stop-color"===c?e=l:"stop-opacity"===c&&(r=l)}}return e||(e=t.getAttribute("stop-color")||"rgb(0,0,0)"),r||(r=t.getAttribute("stop-opacity")),e=new fabric.Color(e),i=e.getAlpha(),r=isNaN(parseFloat(r))?1:parseFloat(r),r*=i,{offset:s,color:e.toRgb(),opacity:r}}function e(t){return{x1:t.getAttribute("x1")||0,y1:t.getAttribute("y1")||0,x2:t.getAttribute("x2")||"100%",y2:t.getAttribute("y2")||0}}function i(t){return{x1:t.getAttribute("fx")||t.getAttribute("cx")||"50%",y1:t.getAttribute("fy")||t.getAttribute("cy")||"50%",r1:0,x2:t.getAttribute("cx")||"50%",y2:t.getAttribute("cy")||"50%",r2:t.getAttribute("r")||"50%"}}function r(t,e,i){var r,n=0,s=1,o="";for(var a in e)"Infinity"===e[a]?e[a]=1:"-Infinity"===e[a]&&(e[a]=0),r=parseFloat(e[a],10),s="string"==typeof e[a]&&/^\d+%$/.test(e[a])?.01:1,"x1"===a||"x2"===a||"r2"===a?(s*="objectBoundingBox"===i?t.width:1,n="objectBoundingBox"===i?t.left||0:0):"y1"!==a&&"y2"!==a||(s*="objectBoundingBox"===i?t.height:1,n="objectBoundingBox"===i?t.top||0:0),e[a]=r*s+n;if("ellipse"===t.type&&null!==e.r2&&"objectBoundingBox"===i&&t.rx!==t.ry){var h=t.ry/t.rx;o=" scale(1, "+h+")",e.y1&&(e.y1/=h),e.y2&&(e.y2/=h)}return o}fabric.Gradient=fabric.util.createClass({offsetX:0,offsetY:0,initialize:function(t){t||(t={});var e={};this.id=fabric.Object.__uid++,this.type=t.type||"linear",e={x1:t.coords.x1||0,y1:t.coords.y1||0,x2:t.coords.x2||0,y2:t.coords.y2||0},"radial"===this.type&&(e.r1=t.coords.r1||0,e.r2=t.coords.r2||0),this.coords=e,this.colorStops=t.colorStops.slice(),t.gradientTransform&&(this.gradientTransform=t.gradientTransform),this.offsetX=t.offsetX||this.offsetX,this.offsetY=t.offsetY||this.offsetY},addColorStop:function(t){for(var e in t){var i=new fabric.Color(t[e]);this.colorStops.push({offset:e,color:i.toRgb(),opacity:i.getAlpha()})}return this},toObject:function(){return{type:this.type,coords:this.coords,colorStops:this.colorStops,offsetX:this.offsetX,offsetY:this.offsetY,gradientTransform:this.gradientTransform?this.gradientTransform.concat():this.gradientTransform}},toSVG:function(t){var e,i,r=fabric.util.object.clone(this.coords);if(this.colorStops.sort(function(t,e){return t.offset-e.offset}),!t.group||"path-group"!==t.group.type)for(var n in r)"x1"===n||"x2"===n||"r2"===n?r[n]+=this.offsetX-t.width/2:"y1"!==n&&"y2"!==n||(r[n]+=this.offsetY-t.height/2);i='id="SVGID_'+this.id+'" gradientUnits="userSpaceOnUse"',this.gradientTransform&&(i+=' gradientTransform="matrix('+this.gradientTransform.join(" ")+')" '),"linear"===this.type?e=["\n']:"radial"===this.type&&(e=["\n']);for(var s=0;s\n');return e.push("linear"===this.type?"\n":"\n"),e.join("")},toLive:function(t,e){var i,r,n=fabric.util.object.clone(this.coords);if(this.type){if(e.group&&"path-group"===e.group.type)for(r in n)"x1"===r||"x2"===r?n[r]+=-this.offsetX+e.width/2:"y1"!==r&&"y2"!==r||(n[r]+=-this.offsetY+e.height/2);"linear"===this.type?i=t.createLinearGradient(n.x1,n.y1,n.x2,n.y2):"radial"===this.type&&(i=t.createRadialGradient(n.x1,n.y1,n.r1,n.x2,n.y2,n.r2));for(var s=0,o=this.colorStops.length;s\n\n\n'},toLive:function(t){var e="function"==typeof this.source?this.source():this.source;if(!e)return"";if("undefined"!=typeof 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 e=t.fabric||(t.fabric={}),i=e.util.toFixed;return e.Shadow?void e.warn("fabric.Shadow is already defined."):(e.Shadow=e.util.createClass({color:"rgb(0,0,0)",blur:0,offsetX:0,offsetY:0,affectStroke:!1,includeDefaultValues:!0,initialize:function(t){"string"==typeof t&&(t=this._parseShadow(t));for(var i in t)this[i]=t[i];this.id=e.Object.__uid++},_parseShadow:function(t){var i=t.trim(),r=e.Shadow.reOffsetsAndBlur.exec(i)||[],n=i.replace(e.Shadow.reOffsetsAndBlur,"")||"rgb(0,0,0)";return{color:n.trim(),offsetX:parseInt(r[1],10)||0,offsetY:parseInt(r[2],10)||0,blur:parseInt(r[3],10)||0}},toString:function(){return[this.offsetX,this.offsetY,this.blur,this.color].join("px ")},toSVG:function(t){var r=40,n=40,s=e.Object.NUM_FRACTION_DIGITS,o=e.util.rotateVector({x:this.offsetX,y:this.offsetY},e.util.degreesToRadians(-t.angle)),a=20;return t.width&&t.height&&(r=100*i((Math.abs(o.x)+this.blur)/t.width,s)+a,n=100*i((Math.abs(o.y)+this.blur)/t.height,s)+a),t.flipX&&(o.x*=-1),t.flipY&&(o.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 t={},i=e.Shadow.prototype;return["color","blur","offsetX","offsetY","affectStroke"].forEach(function(e){this[e]!==i[e]&&(t[e]=this[e])},this),t}}),void(e.Shadow.reOffsetsAndBlur=/(?:\s|^)(-?\d+(?:px)?(?:\s?|$))?(-?\d+(?:px)?(?:\s?|$))?(\d+(?:px)?)?(?:\s?|$)(?:$|\s)/))}("undefined"!=typeof exports?exports:this),function(){"use strict";if(fabric.StaticCanvas)return void fabric.warn("fabric.StaticCanvas is already defined.");var t=fabric.util.object.extend,e=fabric.util.getElementOffset,i=fabric.util.removeFromArray,r=fabric.util.toFixed,n=new Error("Could not initialize `canvas` element");fabric.StaticCanvas=fabric.util.createClass({initialize:function(t,e){e||(e={}),this._initStatic(t,e)},backgroundColor:"",backgroundImage:null,overlayColor:"",overlayImage:null,includeDefaultValues:!0,stateful:!0,renderOnAddRemove:!0,clipTo:null,controlsAboveOverlay:!1,allowTouchScrolling:!1,imageSmoothingEnabled:!0,viewportTransform:[1,0,0,1,0,0],backgroundVpt:!0,overlayVpt:!0,onBeforeScaleRotate:function(){},enableRetinaScaling:!0,_initStatic:function(t,e){var i=fabric.StaticCanvas.prototype.renderAll.bind(this);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=e(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(t,e,i,r){return"string"==typeof e?fabric.util.loadImage(e,function(e){e&&(this[t]=new fabric.Image(e,r)),i&&i(e)},this,r&&r.crossOrigin):(r&&e.setOptions(r),this[t]=e,i&&i(e)),this},__setBgOverlayColor:function(t,e,i){if(e&&e.source){var r=this;fabric.util.loadImage(e.source,function(n){r[t]=new fabric.Pattern({source:n,repeat:e.repeat,offsetX:e.offsetX,offsetY:e.offsetY}),i&&i()})}else this[t]=e,i&&i();return this},_createCanvasElement:function(t){var e=fabric.util.createCanvasElement(t);if(e.style||(e.style={}),!e)throw n;if("undefined"==typeof e.getContext)throw n;return e},_initOptions:function(t){for(var e in t)this[e]=t[e];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){this.lowerCanvasEl=fabric.util.getById(t)||this._createCanvasElement(t),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;e=e||{};for(var r in t)i=t[r],e.cssOnly||(this._setBackstoreDimension(r,t[r]),i+="px"),e.backstoreOnly||this._setCssDimension(r,i);return this._initRetinaScaling(),this._setImageSmoothing(),this.calcOffset(),e.cssOnly||this.renderAll(),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 Math.sqrt(this.viewportTransform[0]*this.viewportTransform[3])},setViewportTransform:function(t){var e,i=this._activeGroup;this.viewportTransform=t;for(var r=0,n=this._objects.length;r"),i.join("")},_setSVGPreamble:function(t,e){e.suppressPreamble||t.push('\n','\n')},_setSVGHeader:function(t,e){var i,n=e.width||this.width,s=e.height||this.height,o='viewBox="0 0 '+this.width+" "+this.height+'" ',a=fabric.Object.NUM_FRACTION_DIGITS;e.viewBox?o='viewBox="'+e.viewBox.x+" "+e.viewBox.y+" "+e.viewBox.width+" "+e.viewBox.height+'" ':this.svgViewportTransformation&&(i=this.viewportTransform,o='viewBox="'+r(-i[4]/i[0],a)+" "+r(-i[5]/i[3],a)+" "+r(this.width/i[0],a)+" "+r(this.height/i[3],a)+'" '),t.push("\n',"Created with Fabric.js ",fabric.version,"\n","",fabric.createSVGFontFacesMarkup(this.getObjects()),fabric.createSVGRefElementsMarkup(this),"\n")},_setSVGObjects:function(t,e){for(var i,r=0,n=this.getObjects(),s=n.length;r\n"):this[e]&&"overlayColor"===e&&t.push('\n")},sendToBack:function(t){if(!t)return this;var e,r,n,s=this._activeGroup;if(t===s)for(n=s._objects,e=n.length;e--;)r=n[e],i(this._objects,r),this._objects.unshift(r);else i(this._objects,t),this._objects.unshift(t);return this.renderAll&&this.renderAll()},bringToFront:function(t){if(!t)return this;var e,r,n,s=this._activeGroup;if(t===s)for(n=s._objects,e=0;e=0;--n){var s=t.intersectsWithObject(this._objects[n])||t.isContainedWithinObject(this._objects[n])||this._objects[n].isContainedWithinObject(t);if(s){r=n;break}}}else r=e-1;return r},bringForward:function(t,e){if(!t)return this;var r,n,s,o,a,h=this._activeGroup;if(t===h)for(a=h._objects,r=a.length;r--;)n=a[r],s=this._objects.indexOf(n),s!==this._objects.length-1&&(o=s+1,i(this._objects,n),this._objects.splice(o,0,n));else s=this._objects.indexOf(t),s!==this._objects.length-1&&(o=this._findNewUpperIndex(t,s,e),i(this._objects,t),this._objects.splice(o,0,t));return this.renderAll&&this.renderAll(),this},_findNewUpperIndex:function(t,e,i){var r;if(i){r=e;for(var n=e+1;n"}}),t(fabric.StaticCanvas.prototype,fabric.Observable),t(fabric.StaticCanvas.prototype,fabric.Collection),t(fabric.StaticCanvas.prototype,fabric.DataURLExporter),t(fabric.StaticCanvas,{EMPTY_JSON:'{"objects": [], "background": "white"}',supports:function(t){var e=fabric.util.createCanvasElement();if(!e||!e.getContext)return null;var i=e.getContext("2d");if(!i)return null;switch(t){case"getImageData":return"undefined"!=typeof i.getImageData;case"setLineDash":return"undefined"!=typeof i.setLineDash;case"toDataURL":return"undefined"!=typeof e.toDataURL;case"toDataURLWithQuality":try{return e.toDataURL("image/jpeg",0),!0}catch(t){}return!1;default:return null}}}),fabric.StaticCanvas.prototype.toJSON=fabric.StaticCanvas.prototype.toObject}(),fabric.BaseBrush=fabric.util.createClass({color:"rgb(0, 0, 0)",width:1,shadow:null,strokeLineCap:"round",strokeLineJoin:"round",strokeDashArray:null,setShadow:function(t){return this.shadow=new fabric.Shadow(t),this},_setBrushStyles:function(){var t=this.canvas.contextTop;t.strokeStyle=this.color,t.lineWidth=this.width,t.lineCap=this.strokeLineCap,t.lineJoin=this.strokeLineJoin,this.strokeDashArray&&fabric.StaticCanvas.supports("setLineDash")&&t.setLineDash(this.strokeDashArray)},_setShadow:function(){if(this.shadow){var t=this.canvas.contextTop;t.shadowColor=this.shadow.color,t.shadowBlur=this.shadow.blur,t.shadowOffsetX=this.shadow.offsetX,t.shadowOffsetY=this.shadow.offsetY}},_resetShadow:function(){var t=this.canvas.contextTop;t.shadowColor="",t.shadowBlur=t.shadowOffsetX=t.shadowOffsetY=0}}),function(){fabric.PencilBrush=fabric.util.createClass(fabric.BaseBrush,{initialize:function(t){this.canvas=t,this._points=[]},onMouseDown:function(t){this._prepareForDrawing(t),this._captureDrawingPath(t),this._render()},onMouseMove:function(t){this._captureDrawingPath(t),this.canvas.clearContext(this.canvas.contextTop),this._render()},onMouseUp:function(){this._finalizeAndAddPath()},_prepareForDrawing:function(t){var e=new fabric.Point(t.x,t.y);this._reset(),this._addPoint(e),this.canvas.contextTop.moveTo(e.x,e.y)},_addPoint:function(t){this._points.push(t)},_reset:function(){this._points.length=0,this._setBrushStyles(),this._setShadow()},_captureDrawingPath:function(t){var e=new fabric.Point(t.x,t.y);this._addPoint(e)},_render:function(){var t=this.canvas.contextTop,e=this.canvas.viewportTransform,i=this._points[0],r=this._points[1];t.save(),t.transform(e[0],e[1],e[2],e[3],e[4],e[5]),t.beginPath(),2===this._points.length&&i.x===r.x&&i.y===r.y&&(i.x-=.5,r.x+=.5),t.moveTo(i.x,i.y);for(var n=1,s=this._points.length;n0?1:-1,"y"===i&&(s=e.target.skewY,o="top",a="bottom",r="originY"),n[-1]=o,n[1]=a,e.target.flipX&&(c*=-1),e.target.flipY&&(c*=-1),0===s?(e.skewSign=-h*t*c,e[r]=n[-t]):(s=s>0?1:-1,e.skewSign=s,e[r]=n[s*h*c])},_skewObject:function(t,e,i){var r=this._currentTransform,n=r.target,s=!1,o=n.get("lockSkewingX"),a=n.get("lockSkewingY");if(o&&"x"===i||a&&"y"===i)return!1;var h,c,l=n.getCenterPoint(),u=n.toLocalPoint(new fabric.Point(t,e),"center","center")[i],f=n.toLocalPoint(new fabric.Point(r.lastX,r.lastY),"center","center")[i],d=n._getTransformedDimensions();return this._changeSkewTransformOrigin(u-f,r,i),h=n.toLocalPoint(new fabric.Point(t,e),r.originX,r.originY)[i],c=n.translateToOriginPoint(l,r.originX,r.originY),s=this._setObjectSkew(h,r,i,d),r.lastX=t,r.lastY=e,n.setPositionByOrigin(c,r.originX,r.originY),s},_setObjectSkew:function(t,e,i,r){var n,s,o,a,h,c,l,u,f,d=e.target,g=!1,p=e.skewSign;return"x"===i?(a="y",h="Y",c="X",u=0,f=d.skewY):(a="x",h="X",c="Y",u=d.skewX,f=0),o=d._getTransformedDimensions(u,f),l=2*Math.abs(t)-o[i],l<=2?n=0:(n=p*Math.atan(l/d["scale"+c]/(o[a]/d["scale"+h])),n=fabric.util.radiansToDegrees(n)),g=d["skew"+c]!==n,d.set("skew"+c,n),0!==d["skew"+h]&&(s=d._getTransformedDimensions(),n=r[a]/s[a]*d["scale"+h],d.set("scale"+h,n)),g},_scaleObject:function(t,e,i){var r=this._currentTransform,n=r.target,s=n.get("lockScalingX"),o=n.get("lockScalingY"),a=n.get("lockScalingFlip");if(s&&o)return!1;var h=n.translateToOriginPoint(n.getCenterPoint(),r.originX,r.originY),c=n.toLocalPoint(new fabric.Point(t,e),r.originX,r.originY),l=n._getTransformedDimensions(),u=!1;return this._setLocalMouse(c,r),u=this._setObjectScale(c,r,s,o,i,a,l),n.setPositionByOrigin(h,r.originX,r.originY),u},_setObjectScale:function(t,e,i,r,n,s,o){var a,h,c,l,u=e.target,f=!1,d=!1,g=!1;return c=t.x*u.scaleX/o.x,l=t.y*u.scaleY/o.y,a=u.scaleX!==c,h=u.scaleY!==l,s&&c<=0&&ci.padding?t.x<0?t.x+=i.padding:t.x-=i.padding:t.x=0,n(t.y)>i.padding?t.y<0?t.y+=i.padding:t.y-=i.padding:t.y=0},_rotateObject:function(t,e){var n=this._currentTransform;if(n.target.get("lockRotation"))return!1;var s=r(n.ey-n.top,n.ex-n.left),o=r(e-n.top,t-n.left),a=i(o-s+n.theta);return a<0&&(a=360+a),n.target.angle=a%360,!0},setCursor:function(t){this.upperCanvasEl.style.cursor=t},_resetObjectTransform:function(t){t.scaleX=1,t.scaleY=1,t.skewX=0,t.skewY=0,t.setAngle(0)},_drawSelection:function(t){var e=this._groupSelector,i=e.left,r=e.top,a=n(i),h=n(r);if(this.selectionColor&&(t.fillStyle=this.selectionColor,t.fillRect(e.ex-(i>0?0:-i),e.ey-(r>0?0:-r),a,h)),this.selectionLineWidth&&this.selectionBorderColor)if(t.lineWidth=this.selectionLineWidth,t.strokeStyle=this.selectionBorderColor,this.selectionDashArray.length>1&&!s){var c=e.ex+o-(i>0?0:a),l=e.ey+o-(r>0?0:h);t.beginPath(),fabric.util.drawDashedLine(t,c,l,c+a,l,this.selectionDashArray),fabric.util.drawDashedLine(t,c,l+h-1,c+a,l+h-1,this.selectionDashArray),fabric.util.drawDashedLine(t,c,l,c,l+h,this.selectionDashArray),fabric.util.drawDashedLine(t,c+a-1,l,c+a-1,l+h,this.selectionDashArray),t.closePath(),t.stroke()}else fabric.Object.prototype._setLineDash.call(this,t,this.selectionDashArray),t.strokeRect(e.ex+o-(i>0?0:a),e.ey+o-(r>0?0:h),a,h)},findTarget:function(t,e){if(!this.skipTargetFind){var i,r=!0,n=this.getPointer(t,r),s=this.getActiveGroup(),o=this.getActiveObject();if(s&&!e&&this._checkTarget(n,s))return this._fireOverOutEvents(s,t),s;if(o&&o._findTargetCorner(n))return this._fireOverOutEvents(o,t),o;if(o&&this._checkTarget(n,o)){if(!this.preserveObjectStacking)return this._fireOverOutEvents(o,t),o;i=o}this.targets=[];var a=this._searchPossibleTargets(this._objects,n);return t[this.altSelectionKey]&&a&&i&&a!==i&&(a=i),this._fireOverOutEvents(a,t),a}},_fireOverOutEvents:function(t,e){t?this._hoveredTarget!==t&&(this._hoveredTarget&&(this.fire("mouse:out",{target:this._hoveredTarget,e:e}),this._hoveredTarget.fire("mouseout")),this.fire("mouse:over",{target:t,e:e}),t.fire("mouseover"),this._hoveredTarget=t):this._hoveredTarget&&(this.fire("mouse:out",{target:this._hoveredTarget,e:e}),this._hoveredTarget.fire("mouseout"),this._hoveredTarget=null)},_checkTarget:function(t,e){if(e&&e.visible&&e.evented&&this.containsPoint(null,e,t)){if(!this.perPixelTargetFind&&!e.perPixelTargetFind||e.isEditing)return!0;var i=this.isTargetTransparent(e,t.x,t.y);if(!i)return!0}},_searchPossibleTargets:function(t,e){for(var i,r,n,s=t.length;s--;)if(this._checkTarget(e,t[s])){i=t[s],"group"===i.type&&i.subTargetCheck&&(r=this._normalizePointer(i,e),n=this._searchPossibleTargets(i._objects,r),n&&this.targets.push(n));break}return i},restorePointerVpt:function(t){return fabric.util.transformPoint(t,fabric.util.invertTransform(this.viewportTransform))},getPointer:function(e,i,r){r||(r=this.upperCanvasEl);var n,s=t(e),o=r.getBoundingClientRect(),a=o.width||0,h=o.height||0;return a&&h||("top"in o&&"bottom"in o&&(h=Math.abs(o.top-o.bottom)),"right"in o&&"left"in o&&(a=Math.abs(o.right-o.left))),this.calcOffset(),s.x=s.x-this._offset.left,s.y=s.y-this._offset.top,i||(s=this.restorePointerVpt(s)),n=0===a||0===h?{width:1,height:1}:{width:r.width/a,height:r.height/h},{x:s.x*n.width,y:s.y*n.height}},_createUpperCanvas:function(){var t=this.lowerCanvasEl.className.replace(/\s*lower-canvas\s*/,"");this.upperCanvasEl=this._createCanvasElement(),fabric.util.addClass(this.upperCanvasEl,"upper-canvas "+t),this.wrapperEl.appendChild(this.upperCanvasEl),this._copyCanvasStyle(this.lowerCanvasEl,this.upperCanvasEl),this._applyCanvasStyle(this.upperCanvasEl),this.contextTop=this.upperCanvasEl.getContext("2d")},_createCacheCanvas:function(){this.cacheCanvasEl=this._createCanvasElement(),this.cacheCanvasEl.setAttribute("width",this.width),this.cacheCanvasEl.setAttribute("height",this.height),this.contextCache=this.cacheCanvasEl.getContext("2d")},_initWrapperElement:function(){this.wrapperEl=fabric.util.wrapElement(this.lowerCanvasEl,"div",{class:this.containerClass}),fabric.util.setStyle(this.wrapperEl,{width:this.getWidth()+"px",height:this.getHeight()+"px",position:"relative"}),fabric.util.makeElementUnselectable(this.wrapperEl)},_applyCanvasStyle:function(t){var e=this.getWidth()||t.width,i=this.getHeight()||t.height;fabric.util.setStyle(t,{position:"absolute",width:e+"px",height:i+"px",left:0,top:0}),t.width=e,t.height=i,fabric.util.makeElementUnselectable(t)},_copyCanvasStyle:function(t,e){e.style.cssText=t.style.cssText},getSelectionContext:function(){return this.contextTop},getSelectionElement:function(){return this.upperCanvasEl},_setActiveObject:function(t){this._activeObject&&this._activeObject.set("active",!1),this._activeObject=t,t.set("active",!0)},setActiveObject:function(t,e){return this._setActiveObject(t),this.renderAll(),this.fire("object:selected",{target:t,e:e}),t.fire("selected",{e:e}),this},getActiveObject:function(){return this._activeObject},_onObjectRemoved:function(t){this.getActiveObject()===t&&(this.fire("before:selection:cleared",{target:t}),this._discardActiveObject(),this.fire("selection:cleared",{target:t}),t.fire("deselected")),this.callSuper("_onObjectRemoved",t)},_discardActiveObject:function(){this._activeObject&&this._activeObject.set("active",!1),this._activeObject=null},discardActiveObject:function(t){var e=this._activeObject;return this.fire("before:selection:cleared",{target:e,e:t}),this._discardActiveObject(),this.fire("selection:cleared",{e:t}),e&&e.fire("deselected",{e:t}),this},_setActiveGroup:function(t){this._activeGroup=t,t&&t.set("active",!0)},setActiveGroup:function(t,e){return this._setActiveGroup(t),t&&(this.fire("object:selected",{target:t,e:e}),t.fire("selected",{e:e})),this},getActiveGroup:function(){return this._activeGroup},_discardActiveGroup:function(){var t=this.getActiveGroup();t&&t.destroy(),this.setActiveGroup(null)},discardActiveGroup:function(t){var e=this.getActiveGroup();return this.fire("before:selection:cleared",{e:t,target:e}),this._discardActiveGroup(),this.fire("selection:cleared",{e:t}),this},deactivateAll:function(){for(var t=this.getObjects(),e=0,i=t.length;e1)){var r=this._groupSelector;r?(i=this.getPointer(t,!0),r.left=i.x-r.ex,r.top=i.y-r.ey,this.renderTop()):this._currentTransform?this._transformObject(t):(e=this.findTarget(t),this._setCursorFromEvent(t,e)),this._handleEvent(t,"move",e?e:null)}},__onMouseWheel:function(t){this.fire("mouse:wheel",{e:t})},_transformObject:function(t){var e=this.getPointer(t),i=this._currentTransform;i.reset=!1,i.target.isMoving=!0,this._beforeScaleTransform(t,i),this._performTransformAction(t,i,e),i.actionPerformed&&this.renderAll()},_performTransformAction:function(t,e,i){var r=i.x,n=i.y,s=e.target,o=e.action,a=!1;"rotate"===o?(a=this._rotateObject(r,n))&&this._fire("rotating",s,t):"scale"===o?(a=this._onScale(t,e,r,n))&&this._fire("scaling",s,t):"scaleX"===o?(a=this._scaleObject(r,n,"x"))&&this._fire("scaling",s,t):"scaleY"===o?(a=this._scaleObject(r,n,"y"))&&this._fire("scaling",s,t):"skewX"===o?(a=this._skewObject(r,n,"x"))&&this._fire("skewing",s,t):"skewY"===o?(a=this._skewObject(r,n,"y"))&&this._fire("skewing",s,t):(a=this._translateObject(r,n),a&&(this._fire("moving",s,t),this.setCursor(s.moveCursor||this.moveCursor))),e.actionPerformed=a},_fire:function(t,e,i){this.fire("object:"+t,{target:e,e:i}),e.fire(t,{e:i})},_beforeScaleTransform:function(t,e){if("scale"===e.action||"scaleX"===e.action||"scaleY"===e.action){var i=this._shouldCenterTransform(e.target);(i&&("center"!==e.originX||"center"!==e.originY)||!i&&"center"===e.originX&&"center"===e.originY)&&(this._resetCurrentTransform(),e.reset=!0)}},_onScale:function(t,e,i,r){return!t[this.uniScaleKey]&&!this.uniScaleTransform||e.target.get("lockUniScaling")?(e.reset||"scale"!==e.currentAction||this._resetCurrentTransform(),e.currentAction="scaleEqually",this._scaleObject(i,r,"equally")):(e.currentAction="scale",this._scaleObject(i,r))},_setCursorFromEvent:function(t,e){if(!e)return this.setCursor(this.defaultCursor),!1;var i=e.hoverCursor||this.hoverCursor;if(e.selectable){var r=this.getActiveGroup(),n=e._findTargetCorner&&(!r||!r.contains(e))&&e._findTargetCorner(this.getPointer(t,!0));n?this._setCornerCursor(n,e,t):this.setCursor(i)}else this.setCursor(i);return!0},_setCornerCursor:function(e,i,r){if(e in t)this.setCursor(this._getRotatedCornerCursor(e,i,r));else{if("mtr"!==e||!i.hasRotatingPoint)return this.setCursor(this.defaultCursor),!1;this.setCursor(this.rotationCursor)}},_getRotatedCornerCursor:function(e,i,r){var n=Math.round(i.getAngle()%360/45);return n<0&&(n+=8),n+=t[e],r[this.altActionKey]&&t[e]%2===0&&(n+=2),n%=8,this.cursorMap[n]}})}(),function(){var t=Math.min,e=Math.max;fabric.util.object.extend(fabric.Canvas.prototype,{_shouldGroup:function(t,e){var i=this.getActiveObject();return t[this.selectionKey]&&e&&e.selectable&&(this.getActiveGroup()||i&&i!==e)&&this.selection},_handleGrouping:function(t,e){var i=this.getActiveGroup();(e!==i||(e=this.findTarget(t,!0)))&&(i?this._updateActiveGroup(e,t):this._createActiveGroup(e,t),this._activeGroup&&this._activeGroup.saveCoords())},_updateActiveGroup:function(t,e){var i=this.getActiveGroup();if(i.contains(t)){if(i.removeWithUpdate(t),t.set("active",!1),1===i.size())return this.discardActiveGroup(e),void this.setActiveObject(i.item(0))}else i.addWithUpdate(t);this.fire("selection:created",{target:i,e:e}),i.set("active",!0)},_createActiveGroup:function(t,e){if(this._activeObject&&t!==this._activeObject){var i=this._createGroup(t);i.addWithUpdate(),this.setActiveGroup(i),this._activeObject=null,this.fire("selection:created",{target:i,e:e})}t.set("active",!0)},_createGroup:function(t){var e=this.getObjects(),i=e.indexOf(this._activeObject)1&&(e=new fabric.Group(e.reverse(),{canvas:this}),e.addWithUpdate(),this.setActiveGroup(e,t),e.saveCoords(),this.fire("selection:created",{target:e}),this.renderAll())},_collectObjects:function(){for(var i,r=[],n=this._groupSelector.ex,s=this._groupSelector.ey,o=n+this._groupSelector.left,a=s+this._groupSelector.top,h=new fabric.Point(t(n,o),t(s,a)),c=new fabric.Point(e(n,o),e(s,a)),l=n===o&&s===a,u=this._objects.length;u--&&(i=this._objects[u],!(i&&i.selectable&&i.visible&&(i.intersectsWithRect(h,c)||i.isContainedWithinRect(h,c)||i.containsPoint(h)||i.containsPoint(c))&&(i.set("active",!0),r.push(i),l))););return r},_maybeGroupObjects:function(t){this.selection&&this._groupSelector&&this._groupSelectedObjects(t);var e=this.getActiveGroup();e&&(e.setObjectsCoords().setCoords(),e.isMoving=!1,this.setCursor(this.defaultCursor)),this._groupSelector=null,this._currentTransform=null}})}(),function(){var t=fabric.StaticCanvas.supports("toDataURLWithQuality");fabric.util.object.extend(fabric.StaticCanvas.prototype,{toDataURL:function(t){t||(t={});var e=t.format||"png",i=t.quality||1,r=t.multiplier||1,n={left:t.left||0,top:t.top||0,width:t.width||0,height:t.height||0};return this.__toDataURLWithMultiplier(e,i,n,r)},__toDataURLWithMultiplier:function(t,e,i,r){var n=this.getWidth(),s=this.getHeight(),o=(i.width||this.getWidth())*r,a=(i.width||this.getHeight())*r,h=this.getZoom(),c=h*r,l=this.viewportTransform,u=(l[4]-i.left)*r,f=(l[5]-i.top)*r,d=[c,0,0,c,u,f],g=this.interactive;this.viewportTransform=d,this.interactive&&(this.interactive=!1),n!==o||s!==a?this.setDimensions({width:o,height:a}):this.renderAll();var p=this.__toDataURL(t,e,i);return g&&(this.interactive=g),this.viewportTransform=l,this.setDimensions({width:n,height:s}),p},__toDataURL:function(e,i){var r=this.contextContainer.canvas;"jpg"===e&&(e="jpeg");var n=t?r.toDataURL("image/"+e,i):r.toDataURL("image/"+e);return n},toDataURLWithMultiplier:function(t,e,i){return this.toDataURL({format:t,multiplier:e,quality:i})}})}(),fabric.util.object.extend(fabric.StaticCanvas.prototype,{loadFromDatalessJSON:function(t,e,i){return this.loadFromJSON(t,e,i)},loadFromJSON:function(t,e,i){if(t){var r="string"==typeof t?JSON.parse(t):fabric.util.object.clone(t);this.clear();var n=this;return this._enlivenObjects(r.objects,function(){n._setBgOverlay(r,function(){delete r.objects,delete r.backgroundImage,delete r.overlayImage,delete r.background,delete r.overlay;for(var t in r)n[t]=r[t];e&&e()})},i),this}},_setBgOverlay:function(t,e){var i=this,r={backgroundColor:!1,overlayColor:!1,backgroundImage:!1,overlayImage:!1};if(!(t.backgroundImage||t.overlayImage||t.background||t.overlay))return void(e&&e());var n=function(){r.backgroundImage&&r.overlayImage&&r.backgroundColor&&r.overlayColor&&(i.renderAll(),e&&e())};this.__setBgOverlay("backgroundImage",t.backgroundImage,r,n),this.__setBgOverlay("overlayImage",t.overlayImage,r,n),this.__setBgOverlay("backgroundColor",t.background,r,n),this.__setBgOverlay("overlayColor",t.overlay,r,n),n()},__setBgOverlay:function(t,e,i,r){var n=this;return e?void("backgroundImage"===t||"overlayImage"===t?fabric.Image.fromObject(e,function(e){n[t]=e,i[t]=!0,r&&r()}):this["set"+fabric.util.string.capitalize(t,!0)](e,function(){i[t]=!0,r&&r()})):void(i[t]=!0)},_enlivenObjects:function(t,e,i){var r=this;if(!t||0===t.length)return void(e&&e());var n=this.renderOnAddRemove;this.renderOnAddRemove=!1,fabric.util.enlivenObjects(t,function(t){t.forEach(function(t,e){r.insertAt(t,e)}),r.renderOnAddRemove=n,e&&e()},null,i)},_toDataURL:function(t,e){this.clone(function(i){e(i.toDataURL(t))})},_toDataURLWithMultiplier:function(t,e,i){this.clone(function(r){i(r.toDataURLWithMultiplier(t,e))})},clone:function(t,e){var i=JSON.stringify(this.toJSON(e));this.cloneWithoutData(function(e){e.loadFromJSON(i,function(){t&&t(e)})})},cloneWithoutData:function(t){var e=fabric.document.createElement("canvas");e.width=this.getWidth(),e.height=this.getHeight();var i=new fabric.Canvas(e);i.clipTo=this.clipTo,this.backgroundImage?(i.setBackgroundImage(this.backgroundImage.src,function(){i.renderAll(),t&&t(i)}),i.backgroundImageOpacity=this.backgroundImageOpacity,i.backgroundImageStretch=this.backgroundImageStretch):t&&t(i)}}),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=e.util.object.extend,r=e.util.toFixed,n=e.util.string.capitalize,s=e.util.degreesToRadians,o=e.StaticCanvas.supports("setLineDash");e.Object||(e.Object=e.util.createClass({type:"object",originX:"left",originY:"top",top:0,left:0,width:0,height:0,scaleX:1,scaleY:1,flipX:!1,flipY:!1,opacity:1,angle:0,skewX:0,skewY:0,cornerSize:13,transparentCorners:!0,hoverCursor:null,moveCursor:null,padding:0,borderColor:"rgba(102,153,255,0.75)",borderDashArray:null,cornerColor:"rgba(102,153,255,0.5)",cornerStrokeColor:null,cornerStyle:"rect",cornerDashArray:null,centeredScaling:!1,centeredRotation:!0,fill:"rgb(0,0,0)",fillRule:"nonzero",globalCompositeOperation:"source-over",backgroundColor:"",selectionBackgroundColor:"",stroke:null,strokeWidth:1,strokeDashArray:null,strokeLineCap:"butt",strokeLineJoin:"miter",strokeMiterLimit:10,shadow:null,borderOpacityWhenMoving:.4,borderScaleFactor:1,transformMatrix:null,minScaleLimit:.01,selectable:!0,evented:!0,visible:!0,hasControls:!0,hasBorders:!0,hasRotatingPoint:!0,rotatingPointOffset:40,perPixelTargetFind:!1,includeDefaultValues:!0,clipTo:null,lockMovementX:!1,lockMovementY:!1,lockRotation:!1,lockScalingX:!1,lockScalingY:!1,lockUniScaling:!1,lockSkewingX:!1,lockSkewingY:!1,lockScalingFlip:!1,excludeFromExport:!1,stateProperties:"top left width height scaleX scaleY flipX flipY originX originY transformMatrix stroke strokeWidth strokeDashArray strokeLineCap strokeLineJoin strokeMiterLimit angle opacity fill fillRule globalCompositeOperation shadow clipTo visible backgroundColor skewX skewY".split(" "),initialize:function(t){t&&this.setOptions(t)},_initGradient:function(t){!t.fill||!t.fill.colorStops||t.fill instanceof e.Gradient||this.set("fill",new e.Gradient(t.fill)),!t.stroke||!t.stroke.colorStops||t.stroke instanceof e.Gradient||this.set("stroke",new e.Gradient(t.stroke))},_initPattern:function(t){!t.fill||!t.fill.source||t.fill instanceof e.Pattern||this.set("fill",new e.Pattern(t.fill)),!t.stroke||!t.stroke.source||t.stroke instanceof e.Pattern||this.set("stroke",new e.Pattern(t.stroke))},_initClipping:function(t){if(t.clipTo&&"string"==typeof t.clipTo){var i=e.util.getFunctionBody(t.clipTo);"undefined"!=typeof i&&(this.clipTo=new Function("ctx",i))}},setOptions:function(t){for(var e in t)this.set(e,t[e]);this._initGradient(t),this._initPattern(t),this._initClipping(t)},transform:function(t,e){this.group&&!this.group._transformDone&&this.group===this.canvas._activeGroup&&this.group.transform(t);var i=e?this._getLeftTopCoords():this.getCenterPoint();t.translate(i.x,i.y),t.rotate(s(this.angle)),t.scale(this.scaleX*(this.flipX?-1:1),this.scaleY*(this.flipY?-1:1)),t.transform(1,0,Math.tan(s(this.skewX)),1,0,0),t.transform(1,Math.tan(s(this.skewY)),0,1,0,0)},toObject:function(t){var i=e.Object.NUM_FRACTION_DIGITS,n={type:this.type,originX:this.originX,originY:this.originY,left:r(this.left,i),top:r(this.top,i),width:r(this.width,i),height:r(this.height,i),fill:this.fill&&this.fill.toObject?this.fill.toObject():this.fill,stroke:this.stroke&&this.stroke.toObject?this.stroke.toObject():this.stroke,strokeWidth:r(this.strokeWidth,i),strokeDashArray:this.strokeDashArray?this.strokeDashArray.concat():this.strokeDashArray,strokeLineCap:this.strokeLineCap,strokeLineJoin:this.strokeLineJoin,strokeMiterLimit:r(this.strokeMiterLimit,i),scaleX:r(this.scaleX,i),scaleY:r(this.scaleY,i),angle:r(this.getAngle(),i),flipX:this.flipX,flipY:this.flipY,opacity:r(this.opacity,i),shadow:this.shadow&&this.shadow.toObject?this.shadow.toObject():this.shadow,visible:this.visible,clipTo:this.clipTo&&String(this.clipTo),backgroundColor:this.backgroundColor,fillRule:this.fillRule,globalCompositeOperation:this.globalCompositeOperation,transformMatrix:this.transformMatrix?this.transformMatrix.concat():this.transformMatrix,skewX:r(this.skewX,i),skewY:r(this.skewY,i)};return this.includeDefaultValues||(n=this._removeDefaultValues(n)),e.util.populateWithProperties(this,n,t),n},toDatalessObject:function(t){return this.toObject(t)},_removeDefaultValues:function(t){var i=e.util.getKlass(t.type).prototype,r=i.stateProperties;return r.forEach(function(e){t[e]===i[e]&&delete t[e];var r="[object Array]"===Object.prototype.toString.call(t[e])&&"[object Array]"===Object.prototype.toString.call(i[e]);r&&0===t[e].length&&0===i[e].length&&delete t[e]}),t},toString:function(){return"#"},get:function(t){return this[t]},getObjectScaling:function(){var t=this.scaleX,e=this.scaleY;if(this.group){var i=this.group.getObjectScaling();t*=i.scaleX,e*=i.scaleY}return{scaleX:t,scaleY:e}},_setObject:function(t){for(var e in t)this._set(e,t[e])},set:function(t,e){return"object"==typeof t?this._setObject(t):"function"==typeof e&&"clipTo"!==t?this._set(t,e(this.get(t))):this._set(t,e),this},_set:function(t,i){var r="scaleX"===t||"scaleY"===t;return r&&(i=this._constrainScale(i)),"scaleX"===t&&i<0?(this.flipX=!this.flipX,i*=-1):"scaleY"===t&&i<0?(this.flipY=!this.flipY,i*=-1):"shadow"!==t||!i||i instanceof e.Shadow||(i=new e.Shadow(i)),this[t]=i,"width"!==t&&"height"!==t||(this.minScaleLimit=Math.min(.1,1/Math.max(this.width,this.height))),this},setOnGroup:function(){},toggle:function(t){var e=this.get(t);return"boolean"==typeof e&&this.set(t,!e),this},setSourcePath:function(t){return this.sourcePath=t,this},getViewportTransform:function(){return this.canvas&&this.canvas.viewportTransform?this.canvas.viewportTransform:[1,0,0,1,0,0]},render:function(t,i){0===this.width&&0===this.height||!this.visible||(t.save(),this._setupCompositeOperation(t),this.drawSelectionBackground(t),i||this.transform(t),this._setOpacity(t),this._setShadow(t),this._renderBackground(t),this._setStrokeStyles(t),this._setFillStyles(t),this.transformMatrix&&t.transform.apply(t,this.transformMatrix),this.clipTo&&e.util.clipContext(this,t),this._render(t,i),this.clipTo&&t.restore(),t.restore())},_renderBackground:function(t){this.backgroundColor&&(t.fillStyle=this.backgroundColor,t.fillRect(-this.width/2,-this.height/2,this.width,this.height),this._removeShadow(t))},_setOpacity:function(t){this.group&&this.group._setOpacity(t),t.globalAlpha*=this.opacity},_setStrokeStyles:function(t){this.stroke&&(t.lineWidth=this.strokeWidth,t.lineCap=this.strokeLineCap,t.lineJoin=this.strokeLineJoin,t.miterLimit=this.strokeMiterLimit,t.strokeStyle=this.stroke.toLive?this.stroke.toLive(t,this):this.stroke)},_setFillStyles:function(t){this.fill&&(t.fillStyle=this.fill.toLive?this.fill.toLive(t,this):this.fill)},_setLineDash:function(t,e,i){e&&(1&e.length&&e.push.apply(e,e),o?t.setLineDash(e):i&&i(t))},_renderControls:function(t,i){if(!(!this.active||i||this.group&&this.group!==this.canvas.getActiveGroup())){var r,n=this.getViewportTransform(),o=this.calcTransformMatrix();o=e.util.multiplyTransformMatrices(n,o),r=e.util.qrDecompose(o),t.save(),t.translate(r.translateX,r.translateY),t.lineWidth=1*this.borderScaleFactor,t.globalAlpha=this.isMoving?this.borderOpacityWhenMoving:1,this.group&&this.group===this.canvas.getActiveGroup()?(t.rotate(s(r.angle)),this.drawBordersInGroup(t,r)):(t.rotate(s(this.angle)),this.drawBorders(t)),this.drawControls(t),t.restore()}},_setShadow:function(t){if(this.shadow){var i=this.canvas&&this.canvas.viewportTransform[0]||1,r=this.canvas&&this.canvas.viewportTransform[3]||1,n=this.getObjectScaling();this.canvas&&this.canvas._isRetinaScaling()&&(i*=e.devicePixelRatio,r*=e.devicePixelRatio),t.shadowColor=this.shadow.color,t.shadowBlur=this.shadow.blur*(i+r)*(n.scaleX+n.scaleY)/4,t.shadowOffsetX=this.shadow.offsetX*i*n.scaleX,t.shadowOffsetY=this.shadow.offsetY*r*n.scaleY}},_removeShadow:function(t){this.shadow&&(t.shadowColor="",t.shadowBlur=t.shadowOffsetX=t.shadowOffsetY=0)},_renderFill:function(t){if(this.fill){if(t.save(),this.fill.gradientTransform){var e=this.fill.gradientTransform;t.transform.apply(t,e)}this.fill.toLive&&t.translate(-this.width/2+this.fill.offsetX||0,-this.height/2+this.fill.offsetY||0),"evenodd"===this.fillRule?t.fill("evenodd"):t.fill(),t.restore()}},_renderStroke:function(t){if(this.stroke&&0!==this.strokeWidth){if(this.shadow&&!this.shadow.affectStroke&&this._removeShadow(t),t.save(),this._setLineDash(t,this.strokeDashArray,this._renderDashedStroke),this.stroke.gradientTransform){var e=this.stroke.gradientTransform;t.transform.apply(t,e)}this.stroke.toLive&&t.translate(-this.width/2+this.stroke.offsetX||0,-this.height/2+this.stroke.offsetY||0),t.stroke(),t.restore()}},clone:function(t,i){return this.constructor.fromObject?this.constructor.fromObject(this.toObject(i),t):new e.Object(this.toObject(i))},cloneAsImage:function(t,i){var r=this.toDataURL(i);return e.util.loadImage(r,function(i){t&&t(new e.Image(i))}),this},toDataURL:function(t){t||(t={});var i=e.util.createCanvasElement(),r=this.getBoundingRect();i.width=r.width,i.height=r.height,e.util.wrapElement(i,"div");var n=new e.StaticCanvas(i,{enableRetinaScaling:t.enableRetinaScaling});"jpg"===t.format&&(t.format="jpeg"),"jpeg"===t.format&&(n.backgroundColor="#fff");var s={active:this.get("active"),left:this.getLeft(),top:this.getTop()};this.set("active",!1),this.setPositionByOrigin(new e.Point(n.getWidth()/2,n.getHeight()/2),"center","center");var o=this.canvas;n.add(this);var a=n.toDataURL(t);return this.set(s).setCoords(),this.canvas=o,n.dispose(),n=null,a},isType:function(t){return this.type===t},complexity:function(){return 0},toJSON:function(t){return this.toObject(t)},setGradient:function(t,i){i||(i={});var r={colorStops:[]};r.type=i.type||(i.r1||i.r2?"radial":"linear"),r.coords={x1:i.x1,y1:i.y1,x2:i.x2,y2:i.y2},(i.r1||i.r2)&&(r.coords.r1=i.r1,r.coords.r2=i.r2),i.gradientTransform&&(r.gradientTransform=i.gradientTransform);for(var n in i.colorStops){var s=new e.Color(i.colorStops[n]);r.colorStops.push({offset:n,color:s.toRgb(),opacity:s.getAlpha()})}return this.set(t,e.Gradient.forObject(this,r))},setPatternFill:function(t){return this.set("fill",new e.Pattern(t))},setShadow:function(t){return this.set("shadow",t?new e.Shadow(t):null)},setColor:function(t){return this.set("fill",t),this},setAngle:function(t){var e=("center"!==this.originX||"center"!==this.originY)&&this.centeredRotation;return e&&this._setOriginToCenter(),this.set("angle",t),e&&this._resetOrigin(),this},centerH:function(){return this.canvas&&this.canvas.centerObjectH(this),this},viewportCenterH:function(){return this.canvas&&this.canvas.viewportCenterObjectH(this),this},centerV:function(){return this.canvas&&this.canvas.centerObjectV(this),this},viewportCenterV:function(){return this.canvas&&this.canvas.viewportCenterObjectV(this),this},center:function(){return this.canvas&&this.canvas.centerObject(this),this},viewportCenter:function(){return this.canvas&&this.canvas.viewportCenterObject(this),this},remove:function(){return this.canvas&&this.canvas.remove(this),this},getLocalPointer:function(t,i){i=i||this.canvas.getPointer(t);var r=new e.Point(i.x,i.y),n=this._getLeftTopCoords();return this.angle&&(r=e.util.rotatePoint(r,n,e.util.degreesToRadians(-this.angle))),{x:r.x-n.x,y:r.y-n.y}},_setupCompositeOperation:function(t){this.globalCompositeOperation&&(t.globalCompositeOperation=this.globalCompositeOperation)}}),e.util.createAccessors(e.Object),e.Object.prototype.rotate=e.Object.prototype.setAngle,i(e.Object.prototype,e.Observable),e.Object.NUM_FRACTION_DIGITS=2,e.Object.__uid=0)}("undefined"!=typeof exports?exports:this),function(){var t=fabric.util.degreesToRadians,e={left:-.5,center:0,right:.5},i={top:-.5,center:0,bottom:.5};fabric.util.object.extend(fabric.Object.prototype,{translateToGivenOrigin:function(t,r,n,s,o){var a,h,c,l=t.x,u=t.y;return"string"==typeof r?r=e[r]:r-=.5,"string"==typeof s?s=e[s]:s-=.5,a=s-r,"string"==typeof n?n=i[n]:n-=.5,"string"==typeof o?o=i[o]:o-=.5,h=o-n,(a||h)&&(c=this._getTransformedDimensions(),l=t.x+a*c.x,u=t.y+h*c.y),new fabric.Point(l,u)},translateToCenterPoint:function(e,i,r){var n=this.translateToGivenOrigin(e,i,r,"center","center");return this.angle?fabric.util.rotatePoint(n,e,t(this.angle)):n},translateToOriginPoint:function(e,i,r){var n=this.translateToGivenOrigin(e,"center","center",i,r);return this.angle?fabric.util.rotatePoint(n,e,t(this.angle)):n},getCenterPoint:function(){var t=new fabric.Point(this.left,this.top);return this.translateToCenterPoint(t,this.originX,this.originY)},getPointByOrigin:function(t,e){var i=this.getCenterPoint();return this.translateToOriginPoint(i,t,e)},toLocalPoint:function(e,i,r){var n,s,o=this.getCenterPoint();return n="undefined"!=typeof i&&"undefined"!=typeof r?this.translateToGivenOrigin(o,"center","center",i,r):new fabric.Point(this.left,this.top),s=new fabric.Point(e.x,e.y),this.angle&&(s=fabric.util.rotatePoint(s,o,-t(this.angle))),s.subtractEquals(n)},setPositionByOrigin:function(t,e,i){var r=this.translateToCenterPoint(t,e,i),n=this.translateToOriginPoint(r,this.originX,this.originY);this.set("left",n.x),this.set("top",n.y)},adjustPosition:function(i){var r,n,s=t(this.angle),o=this.getWidth(),a=Math.cos(s)*o,h=Math.sin(s)*o;r="string"==typeof this.originX?e[this.originX]:this.originX-.5,n="string"==typeof i?e[i]:i-.5,this.left+=a*(n-r),this.top+=h*(n-r),this.setCoords(),this.originX=i},_setOriginToCenter:function(){this._originalOriginX=this.originX,this._originalOriginY=this.originY;var t=this.getCenterPoint();this.originX="center",this.originY="center",this.left=t.x,this.top=t.y},_resetOrigin:function(){var t=this.translateToOriginPoint(this.getCenterPoint(),this._originalOriginX,this._originalOriginY);this.originX=this._originalOriginX,this.originY=this._originalOriginY,this.left=t.x,this.top=t.y,this._originalOriginX=null,this._originalOriginY=null},_getLeftTopCoords:function(){return this.translateToOriginPoint(this.getCenterPoint(),"left","top")}})}(),function(){function t(t){return[new fabric.Point(t.tl.x,t.tl.y),new fabric.Point(t.tr.x,t.tr.y),new fabric.Point(t.br.x,t.br.y),new fabric.Point(t.bl.x,t.bl.y)]}var e=fabric.util.degreesToRadians,i=fabric.util.multiplyTransformMatrices;fabric.util.object.extend(fabric.Object.prototype,{oCoords:null,intersectsWithRect:function(e,i){var r=t(this.oCoords),n=fabric.Intersection.intersectPolygonRectangle(r,e,i);return"Intersection"===n.status},intersectsWithObject:function(e){var i=fabric.Intersection.intersectPolygonPolygon(t(this.oCoords),t(e.oCoords));return"Intersection"===i.status||e.isContainedWithinObject(this)||this.isContainedWithinObject(e)},isContainedWithinObject:function(e){for(var i=t(this.oCoords),r=0;r<4;r++)if(!e.containsPoint(i[r]))return!1;return!0},isContainedWithinRect:function(t,e){var i=this.getBoundingRect();return i.left>=t.x&&i.left+i.width<=e.x&&i.top>=t.y&&i.top+i.height<=e.y},containsPoint:function(t){this.oCoords||this.setCoords();var e=this._getImageLines(this.oCoords),i=this._findCrossPoints(t,e);return 0!==i&&i%2===1},_getImageLines:function(t){return{topline:{o:t.tl,d:t.tr},rightline:{o:t.tr,d:t.br},bottomline:{o:t.br,d:t.bl},leftline:{o:t.bl,d:t.tl}}},_findCrossPoints:function(t,e){var i,r,n,s,o,a,h=0;for(var c in e)if(a=e[c],!(a.o.y=t.y&&a.d.y>=t.y||(a.o.x===a.d.x&&a.o.x>=t.x?o=a.o.x:(i=0,r=(a.d.y-a.o.y)/(a.d.x-a.o.x),n=t.y-i*t.x,s=a.o.y-r*a.o.x,o=-(n-s)/(i-r)),o>=t.x&&(h+=1),2!==h)))break;return h},getBoundingRectWidth:function(){return this.getBoundingRect().width},getBoundingRectHeight:function(){return this.getBoundingRect().height},getBoundingRect:function(){return this.oCoords||this.setCoords(),fabric.util.makeBoundingBoxFromPoints([this.oCoords.tl,this.oCoords.tr,this.oCoords.br,this.oCoords.bl])},getWidth:function(){return this._getTransformedDimensions().x},getHeight:function(){return this._getTransformedDimensions().y},_constrainScale:function(t){return Math.abs(t)0?Math.atan(s/n):0,c=n/Math.cos(h)/2,l=Math.cos(h+t)*c,u=Math.sin(h+t)*c,f=fabric.util.transformPoint(this.getCenterPoint(),i),d=new fabric.Point(f.x-l,f.y-u),g=new fabric.Point(d.x+n*a,d.y+n*o),p=new fabric.Point(d.x-s*o,d.y+s*a),v=new fabric.Point(f.x+l,f.y+u),b=new fabric.Point((d.x+p.x)/2,(d.y+p.y)/2),m=new fabric.Point((g.x+d.x)/2,(g.y+d.y)/2),y=new fabric.Point((v.x+g.x)/2,(v.y+g.y)/2),_=new fabric.Point((v.x+p.x)/2,(v.y+p.y)/2),x=new fabric.Point(m.x+o*this.rotatingPointOffset,m.y-a*this.rotatingPointOffset);return this.oCoords={tl:d,tr:g,br:v,bl:p,ml:b,mt:m,mr:y,mb:_,mtr:x},this._setCornerCoords&&this._setCornerCoords(),this},_calcRotateMatrix:function(){if(this.angle){var t=e(this.angle),i=Math.cos(t),r=Math.sin(t);return[i,r,-r,i,0,0]}return[1,0,0,1,0,0]},calcTransformMatrix:function(){var t=this.getCenterPoint(),e=[1,0,0,1,t.x,t.y],r=this._calcRotateMatrix(),n=this._calcDimensionsTransformMatrix(this.skewX,this.skewY,!0),s=this.group?this.group.calcTransformMatrix():[1,0,0,1,0,0]; +return s=i(s,e),s=i(s,r),s=i(s,n)},_calcDimensionsTransformMatrix:function(t,r,n){var s=[1,0,Math.tan(e(t)),1],o=[1,Math.tan(e(r)),0,1],a=this.scaleX*(n&&this.flipX?-1:1),h=this.scaleY*(n&&this.flipY?-1:1),c=[a,0,0,h],l=i(c,s,!0);return i(l,o,!0)}})}(),fabric.util.object.extend(fabric.Object.prototype,{sendToBack:function(){return this.group?fabric.StaticCanvas.prototype.sendToBack.call(this.group,this):this.canvas.sendToBack(this),this},bringToFront:function(){return this.group?fabric.StaticCanvas.prototype.bringToFront.call(this.group,this):this.canvas.bringToFront(this),this},sendBackwards:function(t){return this.group?fabric.StaticCanvas.prototype.sendBackwards.call(this.group,this,t):this.canvas.sendBackwards(this,t),this},bringForward:function(t){return this.group?fabric.StaticCanvas.prototype.bringForward.call(this.group,this,t):this.canvas.bringForward(this,t),this},moveTo:function(t){return this.group?fabric.StaticCanvas.prototype.moveTo.call(this.group,this,t):this.canvas.moveTo(this,t),this}}),function(){function t(t,e){if(e){if(e.toLive)return t+": url(#SVGID_"+e.id+"); ";var i=new fabric.Color(e),r=t+": "+i.toRgb()+"; ",n=i.getAlpha();return 1!==n&&(r+=t+"-opacity: "+n.toString()+"; "),r}return t+": none; "}fabric.util.object.extend(fabric.Object.prototype,{getSvgStyles:function(e){var i=this.fillRule,r=this.strokeWidth?this.strokeWidth:"0",n=this.strokeDashArray?this.strokeDashArray.join(" "):"none",s=this.strokeLineCap?this.strokeLineCap:"butt",o=this.strokeLineJoin?this.strokeLineJoin:"miter",a=this.strokeMiterLimit?this.strokeMiterLimit:"4",h="undefined"!=typeof this.opacity?this.opacity:"1",c=this.visible?"":" visibility: hidden;",l=e?"":this.getSvgFilter(),u=t("fill",this.fill),f=t("stroke",this.stroke);return[f,"stroke-width: ",r,"; ","stroke-dasharray: ",n,"; ","stroke-linecap: ",s,"; ","stroke-linejoin: ",o,"; ","stroke-miterlimit: ",a,"; ",u,"fill-rule: ",i,"; ","opacity: ",h,";",l,c].join("")},getSvgFilter:function(){return this.shadow?"filter: url(#SVGID_"+this.shadow.id+");":""},getSvgId:function(){return this.id?'id="'+this.id+'" ':""},getSvgTransform:function(){if(this.group&&"path-group"===this.group.type)return"";var t=fabric.util.toFixed,e=this.getAngle(),i=this.getSkewX()%360,r=this.getSkewY()%360,n=this.getCenterPoint(),s=fabric.Object.NUM_FRACTION_DIGITS,o="path-group"===this.type?"":"translate("+t(n.x,s)+" "+t(n.y,s)+")",a=0!==e?" rotate("+t(e,s)+")":"",h=1===this.scaleX&&1===this.scaleY?"":" scale("+t(this.scaleX,s)+" "+t(this.scaleY,s)+")",c=0!==i?" skewX("+t(i,s)+")":"",l=0!==r?" skewY("+t(r,s)+")":"",u="path-group"===this.type?this.width:0,f=this.flipX?" matrix(-1 0 0 1 "+u+" 0) ":"",d="path-group"===this.type?this.height:0,g=this.flipY?" matrix(1 0 0 -1 0 "+d+")":"";return[o,a,h,f,g,c,l].join("")},getSvgTransformMatrix:function(){return this.transformMatrix?" matrix("+this.transformMatrix.join(" ")+") ":""},_createBaseSVGMarkup:function(){var t=[];return this.fill&&this.fill.toLive&&t.push(this.fill.toSVG(this,!1)),this.stroke&&this.stroke.toLive&&t.push(this.stroke.toSVG(this,!1)),this.shadow&&t.push(this.shadow.toSVG(this)),t}})}(),function(){function t(t,e,r){var n={},s=!0;r.forEach(function(e){n[e]=t[e]}),i(t[e],n,s)}function e(t,i){if(t instanceof Array){if(t.length!==i.length)return!1;var r=i.concat().sort(),n=t.concat().sort();return!n.some(function(t,i){return!e(r[i],t)})}if(t instanceof Object){for(var s in t)if(!e(t[s],i[s]))return!1;return!0}return t===i}var i=fabric.util.object.extend;fabric.util.object.extend(fabric.Object.prototype,{hasStateChanged:function(){return!e(this.originalState,this)},saveState:function(e){return t(this,"originalState",this.stateProperties),e&&e.stateProperties&&t(this,"originalState",e.stateProperties),this},setupState:function(t){return this.originalState={},this.saveState(t),this}})}(),function(){var t=fabric.util.degreesToRadians,e=function(){return"undefined"!=typeof G_vmlCanvasManager};fabric.util.object.extend(fabric.Object.prototype,{_controlsVisibility:null,_findTargetCorner:function(t){if(!this.hasControls||!this.active)return!1;var e,i,r=t.x,n=t.y;this.__corner=0;for(var s in this.oCoords)if(this.isControlVisible(s)&&("mtr"!==s||this.hasRotatingPoint)&&(!this.get("lockUniScaling")||"mt"!==s&&"mr"!==s&&"mb"!==s&&"ml"!==s)&&(i=this._getImageLines(this.oCoords[s].corner),e=this._findCrossPoints({x:r,y:n},i),0!==e&&e%2===1))return this.__corner=s,s;return!1},_setCornerCoords:function(){var e,i,r=this.oCoords,n=t(45-this.angle),s=.707106*this.cornerSize,o=s*Math.cos(n),a=s*Math.sin(n);for(var h in r)e=r[h].x,i=r[h].y,r[h].corner={tl:{x:e-a,y:i-o},tr:{x:e+o,y:i-a},bl:{x:e-o,y:i+a},br:{x:e+a,y:i+o}}},_getNonTransformedDimensions:function(){var t=this.strokeWidth,e=this.width,i=this.height,r=!0,n=!0;return"line"===this.type&&"butt"===this.strokeLineCap&&(n=e,r=i),n&&(i+=i<0?-t:t),r&&(e+=e<0?-t:t),{x:e,y:i}},_getTransformedDimensions:function(t,e){"undefined"==typeof t&&(t=this.skewX),"undefined"==typeof e&&(e=this.skewY);var i,r,n=this._getNonTransformedDimensions(),s=n.x/2,o=n.y/2,a=[{x:-s,y:-o},{x:s,y:-o},{x:-s,y:o},{x:s,y:o}],h=this._calcDimensionsTransformMatrix(t,e,!1);for(i=0;i\n'),t?t(e.join("")):e.join("")},complexity:function(){return 1}}),i.Line.ATTRIBUTE_NAMES=i.SHARED_ATTRIBUTES.concat("x1 y1 x2 y2".split(" ")),i.Line.fromElement=function(t,e){var n=i.parseAttributes(t,i.Line.ATTRIBUTE_NAMES),s=[n.x1||0,n.y1||0,n.x2||0,n.y2||0];return new i.Line(s,r(n,e))},void(i.Line.fromObject=function(t,e){var r=[t.x1,t.y1,t.x2,t.y2],n=new i.Line(r,t);return e&&e(n),n}))}("undefined"!=typeof exports?exports:this),function(t){"use strict";function e(t){return"radius"in t&&t.radius>=0}var i=t.fabric||(t.fabric={}),r=Math.PI,n=i.util.object.extend;return i.Circle?void i.warn("fabric.Circle is already defined."):(i.Circle=i.util.createClass(i.Object,{type:"circle",radius:0,startAngle:0,endAngle:2*r,initialize:function(t){t=t||{},this.callSuper("initialize",t),this.set("radius",t.radius||0),this.startAngle=t.startAngle||this.startAngle,this.endAngle=t.endAngle||this.endAngle},_set:function(t,e){return this.callSuper("_set",t,e),"radius"===t&&this.setRadius(e),this},toObject:function(t){return n(this.callSuper("toObject",t),{radius:this.get("radius"),startAngle:this.startAngle,endAngle:this.endAngle})},toSVG:function(t){var e=this._createBaseSVGMarkup(),i=0,n=0,s=(this.endAngle-this.startAngle)%(2*r);if(0===s)this.group&&"path-group"===this.group.type&&(i=this.left+this.radius,n=this.top+this.radius),e.push("\n');else{var o=Math.cos(this.startAngle)*this.radius,a=Math.sin(this.startAngle)*this.radius,h=Math.cos(this.endAngle)*this.radius,c=Math.sin(this.endAngle)*this.radius,l=s>r?"1":"0";e.push('\n')}return t?t(e.join("")):e.join("")},_render:function(t,e){t.beginPath(),t.arc(e?this.left+this.radius:0,e?this.top+this.radius:0,this.radius,this.startAngle,this.endAngle,!1),this._renderFill(t),this._renderStroke(t)},getRadiusX:function(){return this.get("radius")*this.get("scaleX")},getRadiusY:function(){return this.get("radius")*this.get("scaleY")},setRadius:function(t){return this.radius=t,this.set("width",2*t).set("height",2*t)},complexity:function(){return 1}}),i.Circle.ATTRIBUTE_NAMES=i.SHARED_ATTRIBUTES.concat("cx cy r".split(" ")),i.Circle.fromElement=function(t,r){r||(r={});var s=i.parseAttributes(t,i.Circle.ATTRIBUTE_NAMES);if(!e(s))throw new Error("value of `r` attribute is required and can not be negative");s.left=s.left||0,s.top=s.top||0;var o=new i.Circle(n(s,r));return o.left-=o.radius,o.top-=o.radius,o},void(i.Circle.fromObject=function(t,e){var r=new i.Circle(t);return e&&e(r),r}))}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={});return e.Triangle?void e.warn("fabric.Triangle is already defined"):(e.Triangle=e.util.createClass(e.Object,{type:"triangle",initialize:function(t){t=t||{},this.callSuper("initialize",t),this.set("width",t.width||100).set("height",t.height||100)},_render:function(t){var e=this.width/2,i=this.height/2;t.beginPath(),t.moveTo(-e,i),t.lineTo(0,-i),t.lineTo(e,i),t.closePath(),this._renderFill(t),this._renderStroke(t)},_renderDashedStroke:function(t){var i=this.width/2,r=this.height/2;t.beginPath(),e.util.drawDashedLine(t,-i,r,0,-r,this.strokeDashArray),e.util.drawDashedLine(t,0,-r,i,r,this.strokeDashArray),e.util.drawDashedLine(t,i,r,-i,r,this.strokeDashArray),t.closePath()},toSVG:function(t){var e=this._createBaseSVGMarkup(),i=this.width/2,r=this.height/2,n=[-i+" "+r,"0 "+-r,i+" "+r].join(",");return e.push("'),t?t(e.join("")):e.join("")},complexity:function(){return 1}}),void(e.Triangle.fromObject=function(t,i){var r=new e.Triangle(t);return i&&i(r),r}))}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=2*Math.PI,r=e.util.object.extend;return e.Ellipse?void e.warn("fabric.Ellipse is already defined."):(e.Ellipse=e.util.createClass(e.Object,{type:"ellipse",rx:0,ry:0,initialize:function(t){t=t||{},this.callSuper("initialize",t),this.set("rx",t.rx||0),this.set("ry",t.ry||0)},_set:function(t,e){switch(this.callSuper("_set",t,e),t){case"rx":this.rx=e,this.set("width",2*e);break;case"ry":this.ry=e,this.set("height",2*e)}return this},getRx:function(){return this.get("rx")*this.get("scaleX")},getRy:function(){return this.get("ry")*this.get("scaleY")},toObject:function(t){return r(this.callSuper("toObject",t),{rx:this.get("rx"),ry:this.get("ry")})},toSVG:function(t){var e=this._createBaseSVGMarkup(),i=0,r=0;return this.group&&"path-group"===this.group.type&&(i=this.left+this.rx,r=this.top+this.ry),e.push("\n'),t?t(e.join("")):e.join("")},_render:function(t,e){t.beginPath(),t.save(),t.transform(1,0,0,this.ry/this.rx,0,0),t.arc(e?this.left+this.rx:0,e?(this.top+this.ry)*this.rx/this.ry:0,this.rx,0,i,!1),t.restore(),this._renderFill(t),this._renderStroke(t)},complexity:function(){return 1}}),e.Ellipse.ATTRIBUTE_NAMES=e.SHARED_ATTRIBUTES.concat("cx cy rx ry".split(" ")),e.Ellipse.fromElement=function(t,i){i||(i={});var n=e.parseAttributes(t,e.Ellipse.ATTRIBUTE_NAMES);n.left=n.left||0,n.top=n.top||0;var s=new e.Ellipse(r(n,i));return s.top-=s.ry,s.left-=s.rx,s},void(e.Ellipse.fromObject=function(t,i){var r=new e.Ellipse(t);return i&&i(r),r}))}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=e.util.object.extend;if(e.Rect)return void e.warn("fabric.Rect is already defined");var r=e.Object.prototype.stateProperties.concat();r.push("rx","ry","x","y"),e.Rect=e.util.createClass(e.Object,{stateProperties:r,type:"rect",rx:0,ry:0,strokeDashArray:null,initialize:function(t){t=t||{},this.callSuper("initialize",t),this._initRxRy()},_initRxRy:function(){this.rx&&!this.ry?this.ry=this.rx:this.ry&&!this.rx&&(this.rx=this.ry)},_render:function(t,e){if(1===this.width&&1===this.height)return void t.fillRect(-.5,-.5,1,1);var i=this.rx?Math.min(this.rx,this.width/2):0,r=this.ry?Math.min(this.ry,this.height/2):0,n=this.width,s=this.height,o=e?this.left:-this.width/2,a=e?this.top:-this.height/2,h=0!==i||0!==r,c=.4477152502;t.beginPath(),t.moveTo(o+i,a),t.lineTo(o+n-i,a),h&&t.bezierCurveTo(o+n-c*i,a,o+n,a+c*r,o+n,a+r),t.lineTo(o+n,a+s-r),h&&t.bezierCurveTo(o+n,a+s-c*r,o+n-c*i,a+s,o+n-i,a+s),t.lineTo(o+i,a+s),h&&t.bezierCurveTo(o+c*i,a+s,o,a+s-c*r,o,a+s-r),t.lineTo(o,a+r),h&&t.bezierCurveTo(o,a+c*r,o+c*i,a,o+i,a),t.closePath(),this._renderFill(t),this._renderStroke(t)},_renderDashedStroke:function(t){var i=-this.width/2,r=-this.height/2,n=this.width,s=this.height;t.beginPath(),e.util.drawDashedLine(t,i,r,i+n,r,this.strokeDashArray),e.util.drawDashedLine(t,i+n,r,i+n,r+s,this.strokeDashArray),e.util.drawDashedLine(t,i+n,r+s,i,r+s,this.strokeDashArray),e.util.drawDashedLine(t,i,r+s,i,r,this.strokeDashArray),t.closePath()},toObject:function(t){var e=i(this.callSuper("toObject",t),{rx:this.get("rx")||0,ry:this.get("ry")||0});return this.includeDefaultValues||this._removeDefaultValues(e),e},toSVG:function(t){var e=this._createBaseSVGMarkup(),i=this.left,r=this.top;return this.group&&"path-group"===this.group.type||(i=-this.width/2,r=-this.height/2),e.push("\n'),t?t(e.join("")):e.join("")},complexity:function(){return 1}}),e.Rect.ATTRIBUTE_NAMES=e.SHARED_ATTRIBUTES.concat("x y rx ry width height".split(" ")),e.Rect.fromElement=function(t,r){if(!t)return null;r=r||{};var n=e.parseAttributes(t,e.Rect.ATTRIBUTE_NAMES);n.left=n.left||0,n.top=n.top||0;var s=new e.Rect(i(r?e.util.object.clone(r):{},n));return s.visible=s.visible&&s.width>0&&s.height>0,s},e.Rect.fromObject=function(t,i){var r=new e.Rect(t);return i&&i(r),r}}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={});return e.Polyline?void e.warn("fabric.Polyline is already defined"):(e.Polyline=e.util.createClass(e.Object,{type:"polyline",points:null,minX:0,minY:0,initialize:function(t,i){return e.Polygon.prototype.initialize.call(this,t,i)},_calcDimensions:function(){return e.Polygon.prototype._calcDimensions.call(this)},toObject:function(t){return e.Polygon.prototype.toObject.call(this,t)},toSVG:function(t){return e.Polygon.prototype.toSVG.call(this,t)},_render:function(t,i){e.Polygon.prototype.commonRender.call(this,t,i)&&(this._renderFill(t),this._renderStroke(t))},_renderDashedStroke:function(t){var i,r;t.beginPath();for(var n=0,s=this.points.length;n\n'),t?t(r.join("")):r.join("")},_render:function(t,e){this.commonRender(t,e)&&(this._renderFill(t),(this.stroke||this.strokeDashArray)&&(t.closePath(),this._renderStroke(t)))},commonRender:function(t,e){var i,r=this.points.length;if(!r||isNaN(this.points[r-1].y))return!1;e||t.translate(-this.pathOffset.x,-this.pathOffset.y),t.beginPath(),t.moveTo(this.points[0].x,this.points[0].y);for(var n=0;n"},toObject:function(t){var e=n(this.callSuper("toObject",t),{path:this.path.map(function(t){return t.slice()}),pathOffset:this.pathOffset});return this.sourcePath&&(e.sourcePath=this.sourcePath),this.transformMatrix&&(e.transformMatrix=this.transformMatrix),e},toDatalessObject:function(t){var e=this.toObject(t);return this.sourcePath&&(e.path=this.sourcePath),delete e.sourcePath,e},toSVG:function(t){for(var e=[],i=this._createBaseSVGMarkup(),r="",n=0,s=this.path.length;n\n"),t?t(i.join("")):i.join("")},complexity:function(){return this.path.length},_parsePath:function(){for(var t,e,i,r,n,s=[],o=[],c=/([-+]?((\d+\.\d+)|((\d+)|(\.\d+)))(?:e[-+]?\d+)?)/gi,l=0,u=this.path.length;lp)for(var b=1,m=n.length;b\n");for(var s=0,o=e.length;s\n"),t?t(n.join("")):n.join("")},toString:function(){return"#"},isSameColor:function(){var t=this.getObjects()[0].get("fill")||"";return"string"==typeof t&&(t=t.toLowerCase(),this.getObjects().every(function(e){var i=e.get("fill")||"";return"string"==typeof i&&i.toLowerCase()===t}))},complexity:function(){return this.paths.reduce(function(t,e){return t+(e&&e.complexity?e.complexity():0)},0)},getObjects:function(){return this.paths}}),e.PathGroup.fromObject=function(t,i){"string"==typeof t.paths?e.loadSVGFromURL(t.paths,function(r){var n=t.paths;delete t.paths;var s=e.util.groupSVGElements(r,t,n);i(s)}):e.util.enlivenObjects(t.paths,function(r){delete t.paths,i(new e.PathGroup(r,t))})},void(e.PathGroup.async=!0))}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=e.util.object.extend,r=e.util.array.min,n=e.util.array.max,s=e.util.array.invoke;if(!e.Group){var o={lockMovementX:!0,lockMovementY:!0,lockRotation:!0,lockScalingX:!0,lockScalingY:!0,lockUniScaling:!0};e.Group=e.util.createClass(e.Object,e.Collection,{type:"group",strokeWidth:0,subTargetCheck:!1,initialize:function(t,e,i){e=e||{},this._objects=[],i&&this.callSuper("initialize",e),this._objects=t||[];for(var r=this._objects.length;r--;)this._objects[r].group=this;this.originalState={},e.originX&&(this.originX=e.originX),e.originY&&(this.originY=e.originY),i?this._updateObjectsCoords(!0):(this._calcBounds(),this._updateObjectsCoords(),this.callSuper("initialize",e)),this.setCoords(),this.saveCoords()},_updateObjectsCoords:function(t){for(var e=this._objects.length;e--;)this._updateObjectCoords(this._objects[e],t)},_updateObjectCoords:function(t,e){if(t.__origHasControls=t.hasControls,t.hasControls=!1,!e){var i=t.getLeft(),r=t.getTop(),n=this.getCenterPoint();t.set({originalLeft:i,originalTop:r,left:i-n.x,top:r-n.y}),t.setCoords()}},toString:function(){return"#"},addWithUpdate:function(t){return this._restoreObjectsState(),e.util.resetObjectTransform(this),t&&(this._objects.push(t),t.group=this,t._set("canvas",this.canvas)),this.forEachObject(this._setObjectActive,this),this._calcBounds(),this._updateObjectsCoords(),this},_setObjectActive:function(t){t.set("active",!0),t.group=this},removeWithUpdate:function(t){return this._restoreObjectsState(),e.util.resetObjectTransform(this),this.forEachObject(this._setObjectActive,this),this.remove(t),this._calcBounds(),this._updateObjectsCoords(),this},_onObjectAdded:function(t){t.group=this,t._set("canvas",this.canvas)},_onObjectRemoved:function(t){delete t.group,t.set("active",!1)},delegatedProperties:{fill:!0,stroke:!0,strokeWidth:!0,fontFamily:!0,fontWeight:!0,fontSize:!0,fontStyle:!0,lineHeight:!0,textDecoration:!0,textAlign:!0,backgroundColor:!0},_set:function(t,e){var i=this._objects.length;if(this.delegatedProperties[t]||"canvas"===t)for(;i--;)this._objects[i].set(t,e);else for(;i--;)this._objects[i].setOnGroup(t,e);this.callSuper("_set",t,e)},toObject:function(t){return i(this.callSuper("toObject",t),{objects:s(this._objects,"toObject",t)})},render:function(t){if(this.visible){t.save(),this.transformMatrix&&t.transform.apply(t,this.transformMatrix),this.transform(t),this._setShadow(t),this.clipTo&&e.util.clipContext(this,t),this._transformDone=!0;for(var i=0,r=this._objects.length;i\n');for(var i=0,r=this._objects.length;i\n"),t?t(e.join("")):e.join("")},get:function(t){if(t in o){if(this[t])return this[t];for(var e=0,i=this._objects.length;e\n',"\n"),this.stroke||this.strokeDashArray){var o=this.fill;this.fill=null,e.push("\n'),this.fill=o}return e.push("\n"),t?t(e.join("")):e.join("")},getSrc:function(t){var e=t?this._element:this._originalElement;return e?fabric.isLikelyNode?e._src:e.src:this.src||""},setSrc:function(t,e,i){fabric.util.loadImage(t,function(t){return this.setElement(t,e,i)},this,i&&i.crossOrigin)},toString:function(){return'#'},applyFilters:function(t,e,i,r){if(e=e||this.filters,i=i||this._originalElement){var n,s,o=fabric.util.createImage(),a=this.canvas?this.canvas.getRetinaScaling():fabric.devicePixelRatio,h=this.minimumScaleTrigger/a,c=this;if(0===e.length)return this._element=i,t&&t(this),i;var l=fabric.util.createCanvasElement();return l.width=i.width,l.height=i.height,l.getContext("2d").drawImage(i,0,0,i.width,i.height),e.forEach(function(t){t&&(r?(n=c.scaleX0?90*Math.round((t-1)/90):90*Math.round(t/90)},straighten:function(){return this.setAngle(this._getAngleValueForStraighten()),this},fxStraighten:function(t){t=t||{};var e=function(){},i=t.onComplete||e,r=t.onChange||e,n=this;return fabric.util.animate({startValue:this.get("angle"),endValue:this._getAngleValueForStraighten(),duration:this.FX_DURATION,onChange:function(t){n.setAngle(t),r()},onComplete:function(){n.setCoords(),i()},onStart:function(){n.set("active",!1)}}),this}}),fabric.util.object.extend(fabric.StaticCanvas.prototype,{straightenObject:function(t){return t.straighten(),this.renderAll(),this},fxStraightenObject:function(t){return t.fxStraighten({onChange:this.renderAll.bind(this)}),this}}),fabric.Image.filters=fabric.Image.filters||{},fabric.Image.filters.BaseFilter=fabric.util.createClass({type:"BaseFilter",initialize:function(t){t&&this.setOptions(t)},setOptions:function(t){for(var e in t)this[e]=t[e]},toObject:function(){return{type:this.type}},toJSON:function(){return this.toObject()}}),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=e.util.object.extend,r=e.Image.filters,n=e.util.createClass;r.Brightness=n(r.BaseFilter,{type:"Brightness",initialize:function(t){t=t||{},this.brightness=t.brightness||0},applyTo:function(t){for(var e=t.getContext("2d"),i=e.getImageData(0,0,t.width,t.height),r=i.data,n=this.brightness,s=0,o=r.length;sb||o<0||o>v||(h=4*(a*v+o),c=l[C*d+w],e+=p[h]*c,i+=p[h+1]*c,r+=p[h+2]*c,n+=p[h+3]*c);y[s]=e,y[s+1]=i,y[s+2]=r,y[s+3]=n+_*(255-n)}u.putImageData(m,0,0)},toObject:function(){return i(this.callSuper("toObject"),{opaque:this.opaque,matrix:this.matrix})}}),e.Image.filters.Convolute.fromObject=function(t){return new e.Image.filters.Convolute(t)}}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=e.util.object.extend,r=e.Image.filters,n=e.util.createClass;r.GradientTransparency=n(r.BaseFilter,{type:"GradientTransparency",initialize:function(t){t=t||{},this.threshold=t.threshold||100},applyTo:function(t){for(var e=t.getContext("2d"),i=e.getImageData(0,0,t.width,t.height),r=i.data,n=this.threshold,s=r.length,o=0,a=r.length;o-1?t.channel:0},applyTo:function(t){if(this.mask){var i,r=t.getContext("2d"),n=r.getImageData(0,0,t.width,t.height),s=n.data,o=this.mask.getElement(),a=e.util.createCanvasElement(),h=this.channel,c=n.width*n.height*4;a.width=t.width,a.height=t.height,a.getContext("2d").drawImage(o,0,0,t.width,t.height);var l=a.getContext("2d").getImageData(0,0,t.width,t.height),u=l.data;for(i=0;ic&&i>c&&r>c&&l(e-i)i&&(l=2,f=-1),a>n&&(u=2,d=-1),h=c.getImageData(0,0,i,n),t.width=o(s,i),t.height=o(a,n),c.putImageData(h,0,0);!g||!p;)i=v,n=b,s*ft)return 0;if(e*=Math.PI,s(e)<1e-16)return 1;var i=e/t;return h(e)*h(i)/e/i}}function f(t){var h,c,u,d,g,j,A,M,P,D,E;for(T.x=(t+.5)*y,k.x=r(T.x),h=0;h=e)){D=r(1e3*s(c-T.x)),O[D]||(O[D]={});for(var L=k.y-w;L<=k.y+w;L++)L<0||L>=o||(E=r(1e3*s(L-T.y)),O[D][E]||(O[D][E]=m(n(i(D*x,2)+i(E*S,2))/1e3)),u=O[D][E],u>0&&(d=4*(L*e+c),g+=u,j+=u*v[d],A+=u*v[d+1],M+=u*v[d+2],P+=u*v[d+3]))}d=4*(h*a+t),b[d]=j/g,b[d+1]=A/g,b[d+2]=M/g,b[d+3]=P/g}return++t1&&I<-1||(x=2*I*I*I-3*I*I+1,x>0&&(L=4*(E+A*e),k+=x*p[L+3],C+=x,p[L+3]<255&&(x=x*p[L+3]/250),w+=x*p[L],O+=x*p[L+1],T+=x*p[L+2],S+=x))}b[_]=w/S,b[_+1]=O/S,b[_+2]=T/S,b[_+3]=k/C}return v},toObject:function(){return{type:this.type,scaleX:this.scaleX,scaleY:this.scaleY,resizeType:this.resizeType,lanczosLobes:this.lanczosLobes}}}),e.Image.filters.Resize.fromObject=function(t){return new e.Image.filters.Resize(t)}}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=e.util.object.extend,r=e.Image.filters,n=e.util.createClass;r.ColorMatrix=n(r.BaseFilter,{type:"ColorMatrix",initialize:function(t){t||(t={}),this.matrix=t.matrix||[1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0]},applyTo:function(t){var e,i,r,n,s,o=t.getContext("2d"),a=o.getImageData(0,0,t.width,t.height),h=a.data,c=h.length,l=this.matrix;for(e=0;e'},_render:function(t){this.clipTo&&e.util.clipContext(this,t),this._setOpacity(t),this._setShadow(t),this._setupCompositeOperation(t),this._renderTextBackground(t),this._setStrokeStyles(t),this._setFillStyles(t),this._renderText(t),this._renderTextDecoration(t),this.clipTo&&t.restore()},_renderText:function(t){this._renderTextFill(t),this._renderTextStroke(t)},_setTextStyles:function(t){t.textBaseline="alphabetic",t.font=this._getFontDeclaration()},_getTextHeight:function(){return this._getHeightOfSingleLine()+(this._textLines.length-1)*this._getHeightOfLine()},_getTextWidth:function(t){for(var e=this._getLineWidth(t,0),i=1,r=this._textLines.length;ie&&(e=n)}return e},_getNonTransformedDimensions:function(){return{x:this.width,y:this.height}},_renderChars:function(t,e,i,r,n){var s,o,a=t.slice(0,-4);if(this[a].toLive){var h=-this.width/2+this[a].offsetX||0,c=-this.height/2+this[a].offsetY||0;e.save(),e.translate(h,c),r-=h,n-=c}if(0!==this.charSpacing){var l=this._getWidthOfCharSpacing();i=i.split("");for(var u=0,f=i.length;u0?o:0}else e[t](i,r,n);this[a].toLive&&e.restore()},_renderTextLine:function(t,e,i,r,n,s){n-=this.fontSize*this._fontSizeFraction;var o=this._getLineWidth(e,s);if("justify"!==this.textAlign||this.width0?u/f:0,g=0,p=0,v=h.length;p0?n:0},_getLeftOffset:function(){return-this.width/2},_getTopOffset:function(){return-this.height/2},isEmptyStyles:function(){return!0},_renderTextCommon:function(t,e){for(var i=0,r=this._getLeftOffset(),n=this._getTopOffset(),s=0,o=this._textLines.length;s0&&(r=this._getLineLeftOffset(i),t.fillRect(this._getLeftOffset()+r,this._getTopOffset()+n,i,e/this.lineHeight)),n+=e;this._removeShadow(t)}},_getLineLeftOffset:function(t){return"center"===this.textAlign?(this.width-t)/2:"right"===this.textAlign?this.width-t:0},_clearCache:function(){this.__lineWidths=[],this.__lineHeights=[]},_shouldClearCache:function(){var t=!1;if(this._forceClearCache)return this._forceClearCache=!1,!0;for(var e in this._dimensionAffectingProps)this["__"+e]!==this[e]&&(this["__"+e]=this[e],t=!0);return t},_getLineWidth:function(t,e){if(this.__lineWidths[e])return this.__lineWidths[e]===-1?this.width:this.__lineWidths[e];var i,r,n=this._textLines[e];return i=""===n?0:this._measureLine(t,e),this.__lineWidths[e]=i,i&&"justify"===this.textAlign&&(r=n.split(/\s+/),r.length>1&&(this.__lineWidths[e]=-1)),i},_getWidthOfCharSpacing:function(){return 0!==this.charSpacing?this.fontSize*this.charSpacing/1e3:0},_measureLine:function(t,e){var i,r,n=this._textLines[e],s=t.measureText(n).width,o=0;return 0!==this.charSpacing&&(i=n.split("").length,o=(i-1)*this._getWidthOfCharSpacing()),r=s+o,r>0?r:0},_renderTextDecoration:function(t){function e(e){var n,s,o,a,h,c,l,u=0;for(n=0,s=r._textLines.length;n-1&&n.push(.85),this.textDecoration.indexOf("line-through")>-1&&n.push(.43),this.textDecoration.indexOf("overline")>-1&&n.push(-.12),n.length>0&&e(n)}},_getFontDeclaration:function(){return[e.isLikelyNode?this.fontWeight:this.fontStyle,e.isLikelyNode?this.fontStyle:this.fontWeight,this.fontSize+"px",e.isLikelyNode?'"'+this.fontFamily+'"':this.fontFamily].join(" ")},render:function(t,e){this.visible&&(t.save(),this._setTextStyles(t),this._shouldClearCache()&&this._initDimensions(t),this.drawSelectionBackground(t),e||this.transform(t),this.transformMatrix&&t.transform.apply(t,this.transformMatrix),this.group&&"path-group"===this.group.type&&t.translate(this.left,this.top),this._render(t),t.restore())},_splitTextIntoLines:function(){return this.text.split(this._reNewline)},toObject:function(t){var e=i(this.callSuper("toObject",t),{text:this.text,fontSize:this.fontSize,fontWeight:this.fontWeight,fontFamily:this.fontFamily,fontStyle:this.fontStyle,lineHeight:this.lineHeight,textDecoration:this.textDecoration,textAlign:this.textAlign,textBackgroundColor:this.textBackgroundColor,charSpacing:this.charSpacing});return this.includeDefaultValues||this._removeDefaultValues(e),e},toSVG:function(t){this.ctx||(this.ctx=e.util.createCanvasElement().getContext("2d"));var i=this._createBaseSVGMarkup(),r=this._getSVGLeftTopOffsets(this.ctx),n=this._getSVGTextAndBg(r.textTop,r.textLeft);return this._wrapSVGTextAndBg(i,n),t?t(i.join("")):i.join("")},_getSVGLeftTopOffsets:function(t){var e=this._getHeightOfLine(t,0),i=-this.width/2,r=0;return{textLeft:i+(this.group&&"path-group"===this.group.type?this.left:0),textTop:r+(this.group&&"path-group"===this.group.type?-this.top:0),lineTop:e}},_wrapSVGTextAndBg:function(t,e){var i=!0,r=this.getSvgFilter(),n=""===r?"":' style="'+r+'"';t.push("\t\n",e.textBgRects.join(""),"\t\t\n',e.textSpans.join(""),"\t\t\n","\t\n")},_getSVGTextAndBg:function(t,e){var i=[],r=[],n=0;this._setSVGBg(r);for(var s=0,o=this._textLines.length;s",e.util.string.escapeXml(this._textLines[t]),"\n")},_setSVGTextLineJustifed:function(t,i,r,o){var a=e.util.createCanvasElement().getContext("2d");this._setTextStyles(a);var h,c,l=this._textLines[t],u=l.split(/\s+/),f=this._getWidthOfWords(a,u.join("")),d=this.width-f,g=u.length-1,p=g>0?d/g:0,v=this._getFillAttributes(this.fill);for(o+=this._getLineLeftOffset(this._getLineWidth(a,t)),t=0,c=u.length;t",e.util.string.escapeXml(h),"\n"),o+=this._getWidthOfWords(a,h)+p},_setSVGTextLineBg:function(t,e,i,r,o){t.push("\t\t\n')},_setSVGBg:function(t){this.backgroundColor&&t.push("\t\t\n')},_getFillAttributes:function(t){var i=t&&"string"==typeof t?new e.Color(t):"";return i&&i.getSource()&&1!==i.getAlpha()?'opacity="'+i.getAlpha()+'" fill="'+i.setAlpha(1).toRgb()+'"':'fill="'+t+'"'},_set:function(t,e){this.callSuper("_set",t,e),t in this._dimensionAffectingProps&&(this._initDimensions(),this.setCoords())},complexity:function(){return 1}}),e.Text.ATTRIBUTE_NAMES=e.SHARED_ATTRIBUTES.concat("x y dx dy font-family font-style font-weight font-size text-decoration text-anchor".split(" ")),e.Text.DEFAULT_SVG_FONT_SIZE=16,e.Text.fromElement=function(t,i){if(!t)return null;var r=e.parseAttributes(t,e.Text.ATTRIBUTE_NAMES);i=e.util.object.extend(i?e.util.object.clone(i):{},r),i.top=i.top||0,i.left=i.left||0,"dx"in r&&(i.left+=r.dx),"dy"in r&&(i.top+=r.dy),"fontSize"in i||(i.fontSize=e.Text.DEFAULT_SVG_FONT_SIZE),i.originX||(i.originX="left");var n="";"textContent"in t?n=t.textContent:"firstChild"in t&&null!==t.firstChild&&"data"in t.firstChild&&null!==t.firstChild.data&&(n=t.firstChild.data),n=n.replace(/^\s+|\s+$|\n+/g,"").replace(/\s+/g," ");var s=new e.Text(n,i),o=s.getHeight()/s.height,a=(s.height+s.strokeWidth)*s.lineHeight-s.height,h=a*o,c=s.getHeight()+h,l=0;return"left"===s.originX&&(l=s.getWidth()/2),"right"===s.originX&&(l=-s.getWidth()/2),s.set({left:s.getLeft()+l,top:s.getTop()-c/2+s.fontSize*(.18+s._fontSizeFraction)/s.lineHeight}),s},e.Text.fromObject=function(t,i){var n=new e.Text(t.text,r(t));return i&&i(n),n},e.util.createAccessors(e.Text)}("undefined"!=typeof exports?exports:this),function(){var t=fabric.util.object.clone;fabric.IText=fabric.util.createClass(fabric.Text,fabric.Observable,{type:"i-text",selectionStart:0,selectionEnd:0,selectionColor:"rgba(17,119,255,0.3)",isEditing:!1,editable:!0,editingBorderColor:"rgba(102,153,255,0.25)",cursorWidth:2,cursorColor:"#333",cursorDelay:1e3,cursorDuration:600,styles:null,caching:!0,_reSpace:/\s|\n/,_currentCursorOpacity:0,_selectionDirection:null,_abortCursorAnimation:!1,__widthOfSpace:[],initialize:function(t,e){this.styles=e?e.styles||{}:{},this.callSuper("initialize",t,e),this.initBehavior()},_clearCache:function(){this.callSuper("_clearCache"),this.__widthOfSpace=[]},isEmptyStyles:function(){if(!this.styles)return!0;var t=this.styles;for(var e in t)for(var i in t[e])for(var r in t[e][i])return!1;return!0},setSelectionStart:function(t){t=Math.max(t,0),this._updateAndFire("selectionStart",t)},setSelectionEnd:function(t){t=Math.min(t,this.text.length),this._updateAndFire("selectionEnd",t)},_updateAndFire:function(t,e){this[t]!==e&&(this._fireSelectionChanged(),this[t]=e),this._updateTextarea()},_fireSelectionChanged:function(){this.fire("selection:changed"),this.canvas&&this.canvas.fire("text:selection:changed",{target:this})},getSelectionStyles:function(t,e){if(2===arguments.length){for(var i=[],r=t;r0?a:0,lineLeft:r},this.cursorOffsetCache=i,this.cursorOffsetCache},renderCursor:function(t,e){var i=this.get2DCursorLocation(),r=i.lineIndex,n=i.charIndex,s=this.getCurrentCharFontSize(r,n),o=0===r&&0===n?this._getLineLeftOffset(this._getLineWidth(e,r)):t.leftOffset,a=this.scaleX*this.canvas.getZoom(),h=this.cursorWidth/a;e.fillStyle=this.getCurrentCharColor(r,n),e.globalAlpha=this.__isMousedown?1:this._currentCursorOpacity,e.fillRect(t.left+o-h/2,t.top+t.topOffset,h,s)},renderSelection:function(t,e,i){i.fillStyle=this.selectionColor;for(var r=this.get2DCursorLocation(this.selectionStart),n=this.get2DCursorLocation(this.selectionEnd),s=r.lineIndex,o=n.lineIndex,a=s;a<=o;a++){var h=this._getLineLeftOffset(this._getLineWidth(i,a))||0,c=this._getHeightOfLine(this.ctx,a),l=0,u=0,f=this._textLines[a];if(a===s){for(var d=0,g=f.length;d=r.charIndex&&(a!==o||ds&&a1)&&(c/=this.lineHeight),i.fillRect(e.left+h,e.top+e.topOffset,u>0?u:0,c),e.topOffset+=l}},_renderChars:function(t,e,i,r,n,s,o){if(this.isEmptyStyles())return this._renderCharsFast(t,e,i,r,n);o=o||0;var a,h,c=this._getHeightOfLine(e,s),l="";e.save(),n-=c/this.lineHeight*this._fontSizeFraction;for(var u=o,f=i.length+o;u<=f;u++)a=a||this.getCurrentCharStyle(s,u),h=this.getCurrentCharStyle(s,u+1),(this._hasStyleChanged(a,h)||u===f)&&(this._renderChar(t,e,s,u-1,l,r,n,c),l="",a=h),l+=i[u-o];e.restore()},_renderCharsFast:function(t,e,i,r,n){"fillText"===t&&this.fill&&this.callSuper("_renderChars",t,e,i,r,n),"strokeText"===t&&(this.stroke&&this.strokeWidth>0||this.skipFillStrokeCheck)&&this.callSuper("_renderChars",t,e,i,r,n)},_renderChar:function(t,e,i,r,n,s,o,a){var h,c,l,u,f,d,g,p,v,b=this._getStyleDeclaration(i,r);if(b?(c=this._getHeightOfChar(e,n,i,r),u=b.stroke,l=b.fill,d=b.textDecoration):c=this.fontSize,u=(u||this.stroke)&&"strokeText"===t,l=(l||this.fill)&&"fillText"===t,b&&e.save(),h=this._applyCharStylesGetWidth(e,n,i,r,b||null),d=d||this.textDecoration,b&&b.textBackgroundColor&&this._removeShadow(e),0!==this.charSpacing){p=this._getWidthOfCharSpacing(),g=n.split(""),h=0;for(var m,y=0,_=g.length;y<_;y++)m=g[y],l&&e.fillText(m,s+h,o),u&&e.strokeText(m,s+h,o),v=e.measureText(m).width+p,h+=v>0?v:0}else l&&e.fillText(n,s,o),u&&e.strokeText(n,s,o);(d||""!==d)&&(f=this._fontSizeFraction*a/this.lineHeight,this._renderCharDecoration(e,d,s,o,f,h,c)),b&&e.restore(),e.translate(h,0)},_hasStyleChanged:function(t,e){return t.fill!==e.fill||t.fontSize!==e.fontSize||t.textBackgroundColor!==e.textBackgroundColor||t.textDecoration!==e.textDecoration||t.fontFamily!==e.fontFamily||t.fontWeight!==e.fontWeight||t.fontStyle!==e.fontStyle||t.stroke!==e.stroke||t.strokeWidth!==e.strokeWidth},_renderCharDecoration:function(t,e,i,r,n,s,o){if(e){var a,h,c=o/15,l={underline:r+o/10,"line-through":r-o*(this._fontSizeFraction+this._fontSizeMult-1)+c,overline:r-(this._fontSizeMult-this._fontSizeFraction)*o},u=["underline","line-through","overline"];for(a=0;a-1&&t.fillRect(i,l[h],s,c)}},_renderTextLine:function(t,e,i,r,n,s){this.isEmptyStyles()||(n+=this.fontSize*(this._fontSizeFraction+.03)),this.callSuper("_renderTextLine",t,e,i,r,n,s)},_renderTextDecoration:function(t){if(this.isEmptyStyles())return this.callSuper("_renderTextDecoration",t)},_renderTextLinesBackground:function(t){this.callSuper("_renderTextLinesBackground",t);for(var e,i,r,n,s,o,a=0,h=this._getLeftOffset(),c=this._getTopOffset(),l=0,u=this._textLines.length;l0?n:0},_getHeightOfChar:function(t,e,i){var r=this._getStyleDeclaration(e,i);return r&&r.fontSize?r.fontSize:this.fontSize},_getWidthOfCharsAt:function(t,e,i){var r,n,s=0;for(r=0;r0?i:0},_getWidthOfSpace:function(t,e){if(this.__widthOfSpace[e])return this.__widthOfSpace[e];var i=this._textLines[e],r=this._getWidthOfWords(t,i,e,0),n=this.width-r,s=i.length-i.replace(this._reSpacesAndTabs,"").length,o=Math.max(n/s,t.measureText(" ").width);return this.__widthOfSpace[e]=o,o},_getWidthOfWords:function(t,e,i,r){for(var n=0,s=0;sr&&(r=o)}return this.__lineHeights[e]=r*this.lineHeight*this._fontSizeMult,this.__lineHeights[e]},_getTextHeight:function(t){for(var e,i=0,r=0,n=this._textLines.length;r-1;)e++,i--;return t-e},findWordBoundaryRight:function(t){var e=0,i=t;if(this._reSpace.test(this.text.charAt(i)))for(;this._reSpace.test(this.text.charAt(i));)e++,i++;for(;/\S/.test(this.text.charAt(i))&&i-1;)e++,i--;return t-e},findLineBoundaryRight:function(t){for(var e=0,i=t;!/\n/.test(this.text.charAt(i))&&i0&&ithis.__selectionStartOnMouseDown?(this.selectionStart=this.__selectionStartOnMouseDown,this.selectionEnd=e):(this.selectionStart=e,this.selectionEnd=this.__selectionStartOnMouseDown),this.selectionStart===i&&this.selectionEnd===r||(this._fireSelectionChanged(),this._updateTextarea(),this.renderCursorOrSelection()))}},_setEditingProps:function(){this.hoverCursor="text",this.canvas&&(this.canvas.defaultCursor=this.canvas.moveCursor="text"),this.borderColor=this.editingBorderColor,this.hasControls=this.selectable=!1,this.lockMovementX=this.lockMovementY=!0},_updateTextarea:function(){if(this.hiddenTextarea&&!this.inCompositionMode&&(this.cursorOffsetCache={},this.hiddenTextarea.value=this.text,this.hiddenTextarea.selectionStart=this.selectionStart,this.hiddenTextarea.selectionEnd=this.selectionEnd,this.selectionStart===this.selectionEnd)){var t=this._calcTextareaPosition();this.hiddenTextarea.style.left=t.left,this.hiddenTextarea.style.top=t.top,this.hiddenTextarea.style.fontSize=t.fontSize}},_calcTextareaPosition:function(){if(!this.canvas)return{x:1,y:1};var t=this.text.split(""),e=this._getCursorBoundaries(t,"cursor"),i=this.get2DCursorLocation(),r=i.lineIndex,n=i.charIndex,s=this.getCurrentCharFontSize(r,n),o=0===r&&0===n?this._getLineLeftOffset(this._getLineWidth(this.ctx,r)):e.leftOffset,a=this.calcTransformMatrix(),h={x:e.left+o,y:e.top+e.topOffset+s},c=this.canvas.upperCanvasEl,l=c.width-s,u=c.height-s;return h=fabric.util.transformPoint(h,a),h=fabric.util.transformPoint(h,this.canvas.viewportTransform),h.x<0&&(h.x=0),h.x>l&&(h.x=l),h.y<0&&(h.y=0),h.y>u&&(h.y=u),h.x+=this.canvas._offset.left,h.y+=this.canvas._offset.top,{left:h.x+"px",top:h.y+"px",fontSize:s}},_saveEditingProps:function(){this._savedProps={hasControls:this.hasControls,borderColor:this.borderColor,lockMovementX:this.lockMovementX,lockMovementY:this.lockMovementY,hoverCursor:this.hoverCursor,defaultCursor:this.canvas&&this.canvas.defaultCursor,moveCursor:this.canvas&&this.canvas.moveCursor}},_restoreEditingProps:function(){this._savedProps&&(this.hoverCursor=this._savedProps.overCursor,this.hasControls=this._savedProps.hasControls,this.borderColor=this._savedProps.borderColor,this.lockMovementX=this._savedProps.lockMovementX,this.lockMovementY=this._savedProps.lockMovementY,this.canvas&&(this.canvas.defaultCursor=this._savedProps.defaultCursor,this.canvas.moveCursor=this._savedProps.moveCursor))},exitEditing:function(){var t=this._textBeforeEdit!==this.text;return this.selected=!1,this.isEditing=!1,this.selectable=!0,this.selectionEnd=this.selectionStart,this.hiddenTextarea&&this.canvas&&this.hiddenTextarea.parentNode.removeChild(this.hiddenTextarea),this.hiddenTextarea=null,this.abortCursorAnimation(),this._restoreEditingProps(),this._currentCursorOpacity=0,this.fire("editing:exited"),t&&this.fire("modified"),this.canvas&&(this.canvas.off("mouse:move",this.mouseMoveHandler),this.canvas.fire("text:editing:exited",{target:this}),t&&this.canvas.fire("object:modified",{target:this})),this},_removeExtraneousStyles:function(){for(var t in this.styles)this._textLines[t]||delete this.styles[t]},_removeCharsFromTo:function(t,e){for(;e!==t;)this._removeSingleCharAndStyle(t+1),e--;this.selectionStart=t,this.selectionEnd=t},_removeSingleCharAndStyle:function(t){var e="\n"===this.text[t-1],i=e?t:t-1;this.removeStyleObject(e,i),this.text=this.text.slice(0,t-1)+this.text.slice(t),this._textLines=this._splitTextIntoLines()},insertChars:function(t,e){var i;if(this.selectionEnd-this.selectionStart>1&&this._removeCharsFromTo(this.selectionStart,this.selectionEnd),!e&&this.isEmptyStyles())return void this.insertChar(t,!1);for(var r=0,n=t.length;r=i&&(s[parseInt(o,10)-i]=this.styles[e][o],delete this.styles[e][o]);this.styles[e+1]=s}this._forceClearCache=!0},insertCharStyleObject:function(e,i,r){var n=this.styles[e],s=t(n);0!==i||r||(i=1);for(var o in s){var a=parseInt(o,10);a>=i&&(n[a+1]=s[a],s[a-1]||delete n[a])}this.styles[e][i]=r||t(n[i-1]),this._forceClearCache=!0},insertStyleObjects:function(t,e,i){var r=this.get2DCursorLocation(),n=r.lineIndex,s=r.charIndex;this._getLineStyle(n)||this._setLineStyle(n,{}),"\n"===t?this.insertNewlineStyleObject(n,s,e):this.insertCharStyleObject(n,s,i)},shiftLineStyles:function(e,i){var r=t(this.styles);for(var n in this.styles){var s=parseInt(n,10);s>e&&(this.styles[s+i]=r[s],r[s-i]||delete this.styles[s])}},removeStyleObject:function(t,e){var i=this.get2DCursorLocation(e),r=i.lineIndex,n=i.charIndex;this._removeStyleObject(t,i,r,n)},_getTextOnPreviousLine:function(t){return this._textLines[t-1]},_removeStyleObject:function(e,i,r,n){if(e){var s=this._getTextOnPreviousLine(i.lineIndex),o=s?s.length:0;this.styles[r-1]||(this.styles[r-1]={});for(n in this.styles[r])this.styles[r-1][parseInt(n,10)+o]=this.styles[r][n];this.shiftLineStyles(i.lineIndex,-1)}else{var a=this.styles[r];a&&delete a[n];var h=t(a);for(var c in h){var l=parseInt(c,10);l>=n&&0!==l&&(a[l-1]=h[l],delete a[l])}}},insertNewline:function(){this.insertChars("\n")},setSelectionStartEndWithShift:function(t,e,i){i<=t?(e===t?this._selectionDirection="left":"right"===this._selectionDirection&&(this._selectionDirection="left",this.selectionEnd=t),this.selectionStart=i):i>t&&it?this.selectionStart=t:this.selectionStart<0&&(this.selectionStart=0),this.selectionEnd>t?this.selectionEnd=t:this.selectionEnd<0&&(this.selectionEnd=0)}})}(),fabric.util.object.extend(fabric.IText.prototype,{initDoubleClickSimulation:function(){this.__lastClickTime=+new Date,this.__lastLastClickTime=+new Date,this.__lastPointer={},this.on("mousedown",this.onMouseDown.bind(this))},onMouseDown:function(t){this.__newClickTime=+new Date;var e=this.canvas.getPointer(t.e);this.isTripleClick(e)?(this.fire("tripleclick",t),this._stopEvent(t.e)):this.isDoubleClick(e)&&(this.fire("dblclick",t),this._stopEvent(t.e)),this.__lastLastClickTime=this.__lastClickTime,this.__lastClickTime=this.__newClickTime,this.__lastPointer=e,this.__lastIsEditing=this.isEditing,this.__lastSelected=this.selected},isDoubleClick:function(t){return this.__newClickTime-this.__lastClickTime<500&&this.__lastPointer.x===t.x&&this.__lastPointer.y===t.y&&this.__lastIsEditing},isTripleClick:function(t){return this.__newClickTime-this.__lastClickTime<500&&this.__lastClickTime-this.__lastLastClickTime<500&&this.__lastPointer.x===t.x&&this.__lastPointer.y===t.y},_stopEvent:function(t){t.preventDefault&&t.preventDefault(),t.stopPropagation&&t.stopPropagation()},initCursorSelectionHandlers:function(){this.initSelectedHandler(),this.initMousedownHandler(),this.initMouseupHandler(),this.initClicks()},initClicks:function(){this.on("dblclick",function(t){this.selectWord(this.getSelectionStartFromPointer(t.e))}),this.on("tripleclick",function(t){this.selectLine(this.getSelectionStartFromPointer(t.e))})},initMousedownHandler:function(){this.on("mousedown",function(t){if(this.editable){var e=this.canvas.getPointer(t.e);this.__mousedownX=e.x,this.__mousedownY=e.y,this.__isMousedown=!0,this.selected&&this.setCursorByClick(t.e),this.isEditing&&(this.__selectionStartOnMouseDown=this.selectionStart,this.selectionStart===this.selectionEnd&&this.abortCursorAnimation(),this.renderCursorOrSelection())}})},_isObjectMoved:function(t){var e=this.canvas.getPointer(t);return this.__mousedownX!==e.x||this.__mousedownY!==e.y},initMouseupHandler:function(){this.on("mouseup",function(t){this.__isMousedown=!1,this.editable&&!this._isObjectMoved(t.e)&&(this.__lastSelected&&!this.__corner&&(this.enterEditing(t.e),this.selectionStart===this.selectionEnd?this.initDelayedCursor(!0):this.renderCursorOrSelection()),this.selected=!0)})},setCursorByClick:function(t){var e=this.getSelectionStartFromPointer(t),i=this.selectionStart,r=this.selectionEnd;t.shiftKey?this.setSelectionStartEndWithShift(i,r,e):(this.selectionStart=e,this.selectionEnd=e),this._fireSelectionChanged(),this._updateTextarea()},getSelectionStartFromPointer:function(t){for(var e,i,r=this.getLocalPointer(t),n=0,s=0,o=0,a=0,h=0,c=this._textLines.length;hs?0:1,h=r+a;return this.flipX&&(h=n-h),h>this.text.length&&(h=this.text.length),h}}),fabric.util.object.extend(fabric.IText.prototype,{initHiddenTextarea:function(){this.hiddenTextarea=fabric.document.createElement("textarea"),this.hiddenTextarea.setAttribute("autocapitalize","off");var t=this._calcTextareaPosition();this.hiddenTextarea.style.cssText="position: absolute; top: "+t.top+"; left: "+t.left+"; opacity: 0; width: 0px; height: 0px; z-index: -999;",fabric.document.body.appendChild(this.hiddenTextarea),fabric.util.addListener(this.hiddenTextarea,"keydown",this.onKeyDown.bind(this)),fabric.util.addListener(this.hiddenTextarea,"keyup",this.onKeyUp.bind(this)),fabric.util.addListener(this.hiddenTextarea,"input",this.onInput.bind(this)),fabric.util.addListener(this.hiddenTextarea,"copy",this.copy.bind(this)),fabric.util.addListener(this.hiddenTextarea,"cut",this.cut.bind(this)),fabric.util.addListener(this.hiddenTextarea,"paste",this.paste.bind(this)),fabric.util.addListener(this.hiddenTextarea,"compositionstart",this.onCompositionStart.bind(this)),fabric.util.addListener(this.hiddenTextarea,"compositionupdate",this.onCompositionUpdate.bind(this)),fabric.util.addListener(this.hiddenTextarea,"compositionend",this.onCompositionEnd.bind(this)),!this._clickHandlerInitialized&&this.canvas&&(fabric.util.addListener(this.canvas.upperCanvasEl,"click",this.onClick.bind(this)),this._clickHandlerInitialized=!0)},_keysMap:{8:"removeChars",9:"exitEditing",27:"exitEditing",13:"insertNewline",33:"moveCursorUp",34:"moveCursorDown",35:"moveCursorRight",36:"moveCursorLeft",37:"moveCursorLeft",38:"moveCursorUp",39:"moveCursorRight",40:"moveCursorDown",46:"forwardDelete"},_ctrlKeysMapUp:{67:"copy",88:"cut"},_ctrlKeysMapDown:{65:"selectAll"},onClick:function(){this.hiddenTextarea&&this.hiddenTextarea.focus()},onKeyDown:function(t){if(this.isEditing){if(t.keyCode in this._keysMap)this[this._keysMap[t.keyCode]](t);else{if(!(t.keyCode in this._ctrlKeysMapDown&&(t.ctrlKey||t.metaKey)))return;this[this._ctrlKeysMapDown[t.keyCode]](t)}t.stopImmediatePropagation(),t.preventDefault(),this.canvas&&this.canvas.renderAll()}},onKeyUp:function(t){return!this.isEditing||this._copyDone?void(this._copyDone=!1):void(t.keyCode in this._ctrlKeysMapUp&&(t.ctrlKey||t.metaKey)&&(this[this._ctrlKeysMapUp[t.keyCode]](t),t.stopImmediatePropagation(),t.preventDefault(),this.canvas&&this.canvas.renderAll()))},onInput:function(t){if(this.isEditing&&!this.inCompositionMode){var e,i,r,n=this.selectionStart||0,s=this.selectionEnd||0,o=this.text.length,a=this.hiddenTextarea.value.length;a>o?(r="left"===this._selectionDirection?s:n,e=a-o,i=this.hiddenTextarea.value.slice(r,r+e)):(e=a-o+s-n,i=this.hiddenTextarea.value.slice(n,n+e)),this.insertChars(i),t.stopPropagation()}},onCompositionStart:function(){this.inCompositionMode=!0,this.prevCompositionLength=0,this.compositionStart=this.selectionStart},onCompositionEnd:function(){this.inCompositionMode=!1},onCompositionUpdate:function(t){var e=t.data;this.selectionStart=this.compositionStart,this.selectionEnd=this.selectionEnd===this.selectionStart?this.compositionStart+this.prevCompositionLength:this.selectionEnd,this.insertChars(e,!1),this.prevCompositionLength=e.length},forwardDelete:function(t){if(this.selectionStart===this.selectionEnd){if(this.selectionStart===this.text.length)return;this.moveCursorRight(t)}this.removeChars(t)},copy:function(t){if(this.selectionStart!==this.selectionEnd){var e=this.getSelectedText(),i=this._getClipboardData(t);i&&i.setData("text",e),fabric.copiedText=e,fabric.copiedTextStyle=this.getSelectionStyles(this.selectionStart,this.selectionEnd),t.stopImmediatePropagation(),t.preventDefault(),this._copyDone=!0}},paste:function(t){var e=null,i=this._getClipboardData(t),r=!0;i?(e=i.getData("text").replace(/\r/g,""),fabric.copiedTextStyle&&fabric.copiedText===e||(r=!1)):e=fabric.copiedText,e&&this.insertChars(e,r),t.stopImmediatePropagation(),t.preventDefault()},cut:function(t){this.selectionStart!==this.selectionEnd&&(this.copy(t),this.removeChars(t))},_getClipboardData:function(t){return t&&t.clipboardData||fabric.window.clipboardData},_getWidthBeforeCursor:function(t,e){for(var i,r=this._textLines[t].slice(0,e),n=this._getLineWidth(this.ctx,t),s=this._getLineLeftOffset(n),o=0,a=r.length;oe){i=!0;var f=o-u,d=o,g=Math.abs(f-e),p=Math.abs(d-e);a=p=this.text.length&&this.selectionEnd>=this.text.length||this._moveCursorUpOrDown("Down",t)},moveCursorUp:function(t){0===this.selectionStart&&0===this.selectionEnd||this._moveCursorUpOrDown("Up",t)},_moveCursorUpOrDown:function(t,e){var i="get"+t+"CursorOffset",r=this[i](e,"right"===this._selectionDirection);e.shiftKey?this.moveCursorWithShift(r):this.moveCursorWithoutShift(r),0!==r&&(this.setSelectionInBoundaries(),this.abortCursorAnimation(),this._currentCursorOpacity=1,this.initDelayedCursor(),this._fireSelectionChanged(),this._updateTextarea())},moveCursorWithShift:function(t){var e="left"===this._selectionDirection?this.selectionStart+t:this.selectionEnd+t;return this.setSelectionStartEndWithShift(this.selectionStart,this.selectionEnd,e),0!==t},moveCursorWithoutShift:function(t){return t<0?(this.selectionStart+=t,this.selectionEnd=this.selectionStart):(this.selectionEnd+=t,this.selectionStart=this.selectionEnd),0!==t},moveCursorLeft:function(t){0===this.selectionStart&&0===this.selectionEnd||this._moveCursorLeftOrRight("Left",t)},_move:function(t,e,i){var r;if(t.altKey)r=this["findWordBoundary"+i](this[e]);else{if(!t.metaKey&&35!==t.keyCode&&36!==t.keyCode)return this[e]+="Left"===i?-1:1,!0;r=this["findLineBoundary"+i](this[e])}if(void 0!==typeof r&&this[e]!==r)return this[e]=r,!0},_moveLeft:function(t,e){return this._move(t,e,"Left")},_moveRight:function(t,e){return this._move(t,e,"Right")},moveCursorLeftWithoutShift:function(t){var e=!0;return this._selectionDirection="left",this.selectionEnd===this.selectionStart&&0!==this.selectionStart&&(e=this._moveLeft(t,"selectionStart")),this.selectionEnd=this.selectionStart,e},moveCursorLeftWithShift:function(t){return"right"===this._selectionDirection&&this.selectionStart!==this.selectionEnd?this._moveLeft(t,"selectionEnd"):0!==this.selectionStart?(this._selectionDirection="left",this._moveLeft(t,"selectionStart")):void 0},moveCursorRight:function(t){this.selectionStart>=this.text.length&&this.selectionEnd>=this.text.length||this._moveCursorLeftOrRight("Right",t)},_moveCursorLeftOrRight:function(t,e){var i="moveCursor"+t+"With";this._currentCursorOpacity=1,i+=e.shiftKey?"Shift":"outShift",this[i](e)&&(this.abortCursorAnimation(),this.initDelayedCursor(),this._fireSelectionChanged(),this._updateTextarea())},moveCursorRightWithShift:function(t){return"left"===this._selectionDirection&&this.selectionStart!==this.selectionEnd?this._moveRight(t,"selectionStart"):this.selectionEnd!==this.text.length?(this._selectionDirection="right",this._moveRight(t,"selectionEnd")):void 0},moveCursorRightWithoutShift:function(t){var e=!0;return this._selectionDirection="right",this.selectionStart===this.selectionEnd?(e=this._moveRight(t,"selectionStart"),this.selectionEnd=this.selectionStart):this.selectionStart=this.selectionEnd,e},removeChars:function(t){this.selectionStart===this.selectionEnd?this._removeCharsNearCursor(t):this._removeCharsFromTo(this.selectionStart,this.selectionEnd),this.setSelectionEnd(this.selectionStart),this._removeExtraneousStyles(),this.canvas&&this.canvas.renderAll(),this.setCoords(),this.fire("changed"),this.canvas&&this.canvas.fire("text:changed",{target:this})},_removeCharsNearCursor:function(t){if(0!==this.selectionStart)if(t.metaKey){var e=this.findLineBoundaryLeft(this.selectionStart);this._removeCharsFromTo(e,this.selectionStart),this.setSelectionStart(e)}else if(t.altKey){var i=this.findWordBoundaryLeft(this.selectionStart);this._removeCharsFromTo(i,this.selectionStart),this.setSelectionStart(i)}else this._removeSingleCharAndStyle(this.selectionStart),this.setSelectionStart(this.selectionStart-1)}}),function(){var t=fabric.util.toFixed,e=fabric.Object.NUM_FRACTION_DIGITS;fabric.util.object.extend(fabric.IText.prototype,{_setSVGTextLineText:function(t,e,i,r,n,s){this._getLineStyle(t)?this._setSVGTextLineChars(t,e,i,r,s):fabric.Text.prototype._setSVGTextLineText.call(this,t,e,i,r,n)},_setSVGTextLineChars:function(t,e,i,r,n){for(var s=this._textLines[t],o=0,a=this._getLineLeftOffset(this._getLineWidth(this.ctx,t))-this.width/2,h=this._getSVGLineTopOffset(t),c=this._getHeightOfLine(this.ctx,t),l=0,u=s.length;l\n'].join("")},_createTextCharSpan:function(i,r,n,s,o){var a=this.getSvgStyles.call(fabric.util.object.extend({visible:!0,fill:this.fill,stroke:this.stroke,type:"text",getSvgFilter:fabric.Object.prototype.getSvgFilter},r));return['\t\t\t',fabric.util.string.escapeXml(i),"\n"].join("")}})}(),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=e.util.object.clone;e.Textbox=e.util.createClass(e.IText,e.Observable,{type:"textbox",minWidth:20,dynamicMinWidth:2,__cachedLines:null,lockScalingY:!0,lockScalingFlip:!0,initialize:function(t,i){this.ctx=e.util.createCanvasElement().getContext("2d"),this.callSuper("initialize",t,i),this.setControlsVisibility(e.Textbox.getTextboxControlVisibility()),this._dimensionAffectingProps.width=!0},_initDimensions:function(t){this.__skipDimension||(t||(t=e.util.createCanvasElement().getContext("2d"),this._setTextStyles(t)),this.dynamicMinWidth=0,this._textLines=this._splitTextIntoLines(),this.dynamicMinWidth>this.width&&this._set("width",this.dynamicMinWidth),this._clearCache(),this.height=this._getTextHeight(t))},_generateStyleMap:function(){for(var t=0,e=0,i=0,r={},n=0;n0?(e=0,i++,t++):" "===this.text[i]&&n>0&&(e++,i++),r[n]={line:t,offset:e},i+=this._textLines[n].length,e+=this._textLines[n].length;return r},_getStyleDeclaration:function(t,e,i){if(this._styleMap){var r=this._styleMap[t];if(!r)return i?{}:null;t=r.line,e=r.offset+e}return this.callSuper("_getStyleDeclaration",t,e,i)},_setStyleDeclaration:function(t,e,i){var r=this._styleMap[t];t=r.line,e=r.offset+e,this.styles[t][e]=i},_deleteStyleDeclaration:function(t,e){var i=this._styleMap[t];t=i.line,e=i.offset+e,delete this.styles[t][e]},_getLineStyle:function(t){var e=this._styleMap[t];return this.styles[e.line]},_setLineStyle:function(t,e){var i=this._styleMap[t];this.styles[i.line]=e},_deleteLineStyle:function(t){var e=this._styleMap[t];delete this.styles[e.line]},_wrapText:function(t,e){var i,r=e.split(this._reNewline),n=[];for(i=0;i=this.width&&!d?(n.push(s),s="",r=l,d=!0):r+=g,d||(s+=c),s+=a,u=this._measureText(t,c,i,h),h++,d=!1,l>f&&(f=l);return p&&n.push(s),f>this.dynamicMinWidth&&(this.dynamicMinWidth=f-g),n},_splitTextIntoLines:function(){var t=this.textAlign;this.ctx.save(),this._setTextStyles(this.ctx),this.textAlign="left";var e=this._wrapText(this.ctx,this.text);return this.textAlign=t,this.ctx.restore(),this._textLines=e,this._styleMap=this._generateStyleMap(),e},setOnGroup:function(t,e){"scaleX"===t&&(this.set("scaleX",Math.abs(1/e)),this.set("width",this.get("width")*e/("undefined"==typeof this.__oldScaleX?1:this.__oldScaleX)),this.__oldScaleX=e)},get2DCursorLocation:function(t){"undefined"==typeof t&&(t=this.selectionStart);for(var e=this._textLines.length,i=0,r=0;r=h.getMinWidth()?(h.set("width",c),!0):void 0},fabric.Group.prototype._refreshControlsVisibility=function(){if("undefined"!=typeof fabric.Textbox)for(var t=this._objects.length;t--;)if(this._objects[t]instanceof fabric.Textbox)return void this.setControlsVisibility(fabric.Textbox.getTextboxControlVisibility())};var e=fabric.util.object.clone;fabric.util.object.extend(fabric.Textbox.prototype,{_removeExtraneousStyles:function(){for(var t in this._styleMap)this._textLines[t]||delete this.styles[this._styleMap[t].line]},insertCharStyleObject:function(t,e,i){var r=this._styleMap[t];t=r.line,e=r.offset+e,fabric.IText.prototype.insertCharStyleObject.apply(this,[t,e,i])},insertNewlineStyleObject:function(t,e,i){var r=this._styleMap[t];t=r.line,e=r.offset+e,fabric.IText.prototype.insertNewlineStyleObject.apply(this,[t,e,i])},shiftLineStyles:function(t,i){var r=e(this.styles),n=this._styleMap[t];t=n.line;for(var s in this.styles){var o=parseInt(s,10);o>t&&(this.styles[o+i]=r[o],r[o-i]||delete this.styles[o])}},_getTextOnPreviousLine:function(t){for(var e=this._textLines[t-1];this._styleMap[t-2]&&this._styleMap[t-2].line===this._styleMap[t-1].line;)e=this._textLines[t-2]+e,t--;return e},removeStyleObject:function(t,e){var i=this.get2DCursorLocation(e),r=this._styleMap[i.lineIndex],n=r.line,s=r.offset+i.charIndex;this._removeStyleObject(t,i,n,s)}})}(),function(){var t=fabric.IText.prototype._getNewSelectionStartFromOffset;fabric.IText.prototype._getNewSelectionStartFromOffset=function(e,i,r,n,s){n=t.call(this,e,i,r,n,s);for(var o=0,a=0,h=0;h=n));h++)"\n"!==this.text[o+a]&&" "!==this.text[o+a]||a++;return n-h+a}}(),function(){function request(t,e,i){var r=URL.parse(t);r.port||(r.port=0===r.protocol.indexOf("https:")?443:80);var n=0===r.protocol.indexOf("https:")?HTTPS:HTTP,s=n.request({hostname:r.hostname,port:r.port,path:r.path,method:"GET"},function(t){var r="";e&&t.setEncoding(e),t.on("end",function(){i(r)}),t.on("data",function(e){200===t.statusCode&&(r+=e)})});s.on("error",function(t){t.errno===process.ECONNREFUSED?fabric.log("ECONNREFUSED: connection refused to "+r.hostname+":"+r.port):fabric.log(t.message),i(null)}),s.end()}function requestFs(t,e){var i=require("fs");i.readFile(t,function(t,i){if(t)throw fabric.log(t),t;e(i)})}if("undefined"==typeof document||"undefined"==typeof window){var DOMParser=require("xmldom").DOMParser,URL=require("url"),HTTP=require("http"),HTTPS=require("https"),Canvas=require("canvas"),Image=require("canvas").Image;fabric.util.loadImage=function(t,e,i){function r(r){r?(n.src=new Buffer(r,"binary"),n._src=t,e&&e.call(i,n)):(n=null,e&&e.call(i,null,!0))}var n=new Image;t&&(t instanceof Buffer||0===t.indexOf("data"))?(n.src=n._src=t,e&&e.call(i,n)):t&&0!==t.indexOf("http")?requestFs(t,r):t?request(t,"binary",r):e&&e.call(i,t)},fabric.loadSVGFromURL=function(t,e,i){t=t.replace(/^\n\s*/,"").replace(/\?.*$/,"").trim(),0!==t.indexOf("http")?requestFs(t,function(t){fabric.loadSVGFromString(t.toString(),e,i)}):request(t,"",function(t){fabric.loadSVGFromString(t,e,i)})},fabric.loadSVGFromString=function(t,e,i){var r=(new DOMParser).parseFromString(t);fabric.parseSVGDocument(r.documentElement,function(t,i){e&&e(t,i)},i)},fabric.util.getScript=function(url,callback){request(url,"",function(body){eval(body),callback&&callback()})},fabric.createCanvasForNode=function(t,e,i,r){r=r||i;var n=fabric.document.createElement("canvas"),s=new Canvas(t||600,e||600,r),o=new Canvas(t||600,e||600,r);n.style={},n.width=s.width,n.height=s.height,i=i||{},i.nodeCanvas=s,i.nodeCacheCanvas=o;var a=fabric.Canvas||fabric.StaticCanvas,h=new a(n,i);return h.nodeCanvas=s,h.nodeCacheCanvas=o,h.contextContainer=s.getContext("2d"),h.contextCache=o.getContext("2d"),h.Font=Canvas.Font,h};var originaInitStatic=fabric.StaticCanvas.prototype._initStatic;fabric.StaticCanvas.prototype._initStatic=function(t,e){t=t||fabric.document.createElement("canvas"),this.nodeCanvas=new Canvas(t.width,t.height),this.nodeCacheCanvas=new Canvas(t.width,t.height),originaInitStatic.call(this,t,e),this.contextContainer=this.nodeCanvas.getContext("2d"),this.contextCache=this.nodeCacheCanvas.getContext("2d"),this.Font=Canvas.Font},fabric.StaticCanvas.prototype.createPNGStream=function(){return this.nodeCanvas.createPNGStream()},fabric.StaticCanvas.prototype.createJPEGStream=function(t){return this.nodeCanvas.createJPEGStream(t)},fabric.StaticCanvas.prototype._initRetinaScaling=function(){if(this._isRetinaScaling())return this.lowerCanvasEl.setAttribute("width",this.width*fabric.devicePixelRatio),this.lowerCanvasEl.setAttribute("height",this.height*fabric.devicePixelRatio),this.nodeCanvas.width=this.width*fabric.devicePixelRatio,this.nodeCanvas.height=this.height*fabric.devicePixelRatio,this.contextContainer.scale(fabric.devicePixelRatio,fabric.devicePixelRatio),this},fabric.Canvas&&(fabric.Canvas.prototype._initRetinaScaling=fabric.StaticCanvas.prototype._initRetinaScaling);var origSetBackstoreDimension=fabric.StaticCanvas.prototype._setBackstoreDimension;fabric.StaticCanvas.prototype._setBackstoreDimension=function(t,e){return origSetBackstoreDimension.call(this,t,e),this.nodeCanvas[t]=e,this},fabric.Canvas&&(fabric.Canvas.prototype._setBackstoreDimension=fabric.StaticCanvas.prototype._setBackstoreDimension)}}(); \ No newline at end of file diff --git a/dist/fabric.min.js.gz b/dist/fabric.min.js.gz index 1b8630ff105e432c5618f444fd92ff2594cb141d..af922952fb674601cabdef5a0c2f9fadb2e70efa 100644 GIT binary patch delta 66593 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 Lj_|@n!CK# delta 66352 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 0) { @@ -2569,7 +2590,9 @@ fabric.ElementsParser.prototype.checkIfDone = function() { } }, _rgbToHsl: function(r, g, b) { - r /= 255, g /= 255, b /= 255; + r /= 255; + g /= 255; + b /= 255; var h, s, l, max = fabric.util.array.max([ r, g, b ]), min = fabric.util.array.min([ r, g, b ]); l = (max + min) / 2; if (max === min) { @@ -2872,7 +2895,7 @@ fabric.ElementsParser.prototype.checkIfDone = function() { markup = [ "\n' ]; } for (var i = 0; i < this.colorStops.length; i++) { - markup.push("\n'); + markup.push("\n'); } markup.push(this.type === "linear" ? "\n" : "\n"); return markup.join(""); @@ -3249,22 +3272,18 @@ fabric.Pattern = fabric.util.createClass({ } return this; }, - _createCanvasElement: function() { - var element = fabric.document.createElement("canvas"); + _createCanvasElement: function(canvasEl) { + var element = fabric.util.createCanvasElement(canvasEl); if (!element.style) { element.style = {}; } if (!element) { throw CANVAS_INIT_ERROR; } - this._initCanvasElement(element); - return element; - }, - _initCanvasElement: function(element) { - fabric.util.createCanvasElement(element); if (typeof element.getContext === "undefined") { throw CANVAS_INIT_ERROR; } + return element; }, _initOptions: function(options) { for (var prop in options) { @@ -3282,8 +3301,7 @@ fabric.Pattern = fabric.util.createClass({ this.viewportTransform = this.viewportTransform.slice(); }, _createLowerCanvas: function(canvasEl) { - this.lowerCanvasEl = fabric.util.getById(canvasEl) || this._createCanvasElement(); - this._initCanvasElement(this.lowerCanvasEl); + this.lowerCanvasEl = fabric.util.getById(canvasEl) || this._createCanvasElement(canvasEl); fabric.util.addClass(this.lowerCanvasEl, "lower-canvas"); if (this.interactive) { this._applyCanvasStyle(this.lowerCanvasEl); @@ -3352,10 +3370,11 @@ fabric.Pattern = fabric.util.createClass({ return Math.sqrt(this.viewportTransform[0] * this.viewportTransform[3]); }, setViewportTransform: function(vpt) { - var activeGroup = this.getActiveGroup(); + var activeGroup = this._activeGroup, object; this.viewportTransform = vpt; for (var i = 0, len = this._objects.length; i < len; i++) { - this._objects[i].setCoords(); + object = this._objects[i]; + object.group || object.setCoords(); } if (activeGroup) { activeGroup.setCoords(); @@ -3389,12 +3408,6 @@ fabric.Pattern = fabric.util.createClass({ getElement: function() { return this.lowerCanvasEl; }, - getActiveObject: function() { - return null; - }, - getActiveGroup: function() { - return null; - }, _onObjectAdded: function(obj) { this.stateful && obj.setupState(); obj._set("canvas", this); @@ -3409,6 +3422,7 @@ fabric.Pattern = fabric.util.createClass({ target: obj }); obj.fire("removed"); + delete obj.canvas; }, clearContext: function(ctx) { ctx.clearRect(0, 0, this.width, this.height); @@ -3419,6 +3433,10 @@ fabric.Pattern = fabric.util.createClass({ }, clear: function() { this._objects.length = 0; + this.backgroundImage = null; + this.overlayImage = null; + this.backgroundColor = ""; + this.overlayColor = ""; this.clearContext(this.contextContainer); this.fire("canvas:cleared"); this.renderAll(); @@ -3452,7 +3470,6 @@ fabric.Pattern = fabric.util.createClass({ } this.fire("after:render"); }, - drawControls: function() {}, _renderObjects: function(ctx, objects) { for (var i = 0, length = objects.length; i < length; ++i) { objects[i] && objects[i].render(ctx); @@ -3534,7 +3551,7 @@ fabric.Pattern = fabric.util.createClass({ var data = { objects: this._toObjects(methodName, propertiesToInclude) }; - extend(data, this.__serializeBgOverlay()); + extend(data, this.__serializeBgOverlay(propertiesToInclude)); fabric.util.populateWithProperties(this, data, propertiesToInclude); return data; }, @@ -3551,43 +3568,24 @@ fabric.Pattern = fabric.util.createClass({ originalValue = instance.includeDefaultValues; instance.includeDefaultValues = false; } - var originalProperties = this._realizeGroupTransformOnObject(instance), object = instance[methodName](propertiesToInclude); + var object = instance[methodName](propertiesToInclude); if (!this.includeDefaultValues) { instance.includeDefaultValues = originalValue; } - this._unwindGroupTransformOnObject(instance, originalProperties); return object; }, - _realizeGroupTransformOnObject: function(instance) { - var layoutProps = [ "angle", "flipX", "flipY", "height", "left", "scaleX", "scaleY", "top", "width" ]; - if (instance.group && instance.group === this.getActiveGroup()) { - var originalValues = {}; - layoutProps.forEach(function(prop) { - originalValues[prop] = instance[prop]; - }); - this.getActiveGroup().realizeTransform(instance); - return originalValues; - } else { - return null; - } - }, - _unwindGroupTransformOnObject: function(instance, originalValues) { - if (originalValues) { - instance.set(originalValues); - } - }, - __serializeBgOverlay: function() { + __serializeBgOverlay: function(propertiesToInclude) { var data = { - background: this.backgroundColor && this.backgroundColor.toObject ? this.backgroundColor.toObject() : this.backgroundColor + background: this.backgroundColor && this.backgroundColor.toObject ? this.backgroundColor.toObject(propertiesToInclude) : this.backgroundColor }; if (this.overlayColor) { - data.overlay = this.overlayColor.toObject ? this.overlayColor.toObject() : this.overlayColor; + data.overlay = this.overlayColor.toObject ? this.overlayColor.toObject(propertiesToInclude) : this.overlayColor; } if (this.backgroundImage) { - data.backgroundImage = this.backgroundImage.toObject(); + data.backgroundImage = this.backgroundImage.toObject(propertiesToInclude); } if (this.overlayImage) { - data.overlayImage = this.overlayImage.toObject(); + data.overlayImage = this.overlayImage.toObject(propertiesToInclude); } return data; }, @@ -3624,17 +3622,18 @@ fabric.Pattern = fabric.util.createClass({ markup.push("\n', "Created with Fabric.js ", fabric.version, "\n", "", fabric.createSVGFontFacesMarkup(this.getObjects()), fabric.createSVGRefElementsMarkup(this), "\n"); }, _setSVGObjects: function(markup, reviver) { - var instance, originalProperties; + var instance; for (var i = 0, objects = this.getObjects(), len = objects.length; i < len; i++) { instance = objects[i]; if (instance.excludeFromExport) { continue; } - originalProperties = this._realizeGroupTransformOnObject(instance); - markup.push(instance.toSVG(reviver)); - this._unwindGroupTransformOnObject(instance, originalProperties); + this._setSVGObject(markup, instance, reviver); } }, + _setSVGObject: function(markup, instance, reviver) { + markup.push(instance.toSVG(reviver)); + }, _setSVGBgOverlayImage: function(markup, property, reviver) { if (this[property] && this[property].toSVG) { markup.push(this[property].toSVG(reviver)); @@ -3651,7 +3650,7 @@ fabric.Pattern = fabric.util.createClass({ if (!object) { return this; } - var activeGroup = this.getActiveGroup ? this.getActiveGroup() : null, i, obj, objs; + var activeGroup = this._activeGroup, i, obj, objs; if (object === activeGroup) { objs = activeGroup._objects; for (i = objs.length; i--; ) { @@ -3669,7 +3668,7 @@ fabric.Pattern = fabric.util.createClass({ if (!object) { return this; } - var activeGroup = this.getActiveGroup ? this.getActiveGroup() : null, i, obj, objs; + var activeGroup = this._activeGroup, i, obj, objs; if (object === activeGroup) { objs = activeGroup._objects; for (i = 0; i < objs.length; i++) { @@ -3687,7 +3686,7 @@ fabric.Pattern = fabric.util.createClass({ if (!object) { return this; } - var activeGroup = this.getActiveGroup ? this.getActiveGroup() : null, i, obj, idx, newIdx, objs; + var activeGroup = this._activeGroup, i, obj, idx, newIdx, objs; if (object === activeGroup) { objs = activeGroup._objects; for (i = 0; i < objs.length; i++) { @@ -3730,7 +3729,7 @@ fabric.Pattern = fabric.util.createClass({ if (!object) { return this; } - var activeGroup = this.getActiveGroup ? this.getActiveGroup() : null, i, obj, idx, newIdx, objs; + var activeGroup = this._activeGroup, i, obj, idx, newIdx, objs; if (object === activeGroup) { objs = activeGroup._objects; for (i = objs.length; i--; ) { @@ -4176,7 +4175,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, { }); (function() { - var getPointer = fabric.util.getPointer, degreesToRadians = fabric.util.degreesToRadians, radiansToDegrees = fabric.util.radiansToDegrees, atan2 = Math.atan2, abs = Math.abs, STROKE_OFFSET = .5; + var getPointer = fabric.util.getPointer, degreesToRadians = fabric.util.degreesToRadians, radiansToDegrees = fabric.util.radiansToDegrees, atan2 = Math.atan2, abs = Math.abs, supportLineDash = fabric.StaticCanvas.supports("setLineDash"), STROKE_OFFSET = .5; fabric.Canvas = fabric.util.createClass(fabric.StaticCanvas, { initialize: function(el, options) { options || (options = {}); @@ -4193,6 +4192,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, { interactive: true, selection: true, selectionKey: "shiftKey", + altSelectionKey: null, selectionColor: "rgba(100, 100, 255, 0.3)", selectionDashArray: [], selectionBorderColor: "rgba(255, 255, 255, 0.3)", @@ -4208,6 +4208,8 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, { skipTargetFind: false, isDrawingMode: false, preserveObjectStacking: false, + stopContextMenu: false, + fireRightClick: false, _initInteractive: function() { this._currentTransform = null; this._groupSelector = null; @@ -4456,7 +4458,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, { } var center = target.getCenterPoint(), actualMouseByCenter = target.toLocalPoint(new fabric.Point(x, y), "center", "center")[by], lastMouseByCenter = target.toLocalPoint(new fabric.Point(t.lastX, t.lastY), "center", "center")[by], actualMouseByOrigin, constraintPosition, dim = target._getTransformedDimensions(); this._changeSkewTransformOrigin(actualMouseByCenter - lastMouseByCenter, t, by); - actualMouseByOrigin = target.toLocalPoint(new fabric.Point(x, y), t.originX, t.originY)[by], + actualMouseByOrigin = target.toLocalPoint(new fabric.Point(x, y), t.originX, t.originY)[by]; constraintPosition = target.translateToOriginPoint(center, t.originX, t.originY); skewed = this._setObjectSkew(actualMouseByOrigin, t, by, dim); t.lastX = x; @@ -4620,11 +4622,16 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, { }, _drawSelection: function(ctx) { var groupSelector = this._groupSelector, left = groupSelector.left, top = groupSelector.top, aleft = abs(left), atop = abs(top); - ctx.fillStyle = this.selectionColor; - ctx.fillRect(groupSelector.ex - (left > 0 ? 0 : -left), groupSelector.ey - (top > 0 ? 0 : -top), aleft, atop); + if (this.selectionColor) { + ctx.fillStyle = this.selectionColor; + ctx.fillRect(groupSelector.ex - (left > 0 ? 0 : -left), groupSelector.ey - (top > 0 ? 0 : -top), aleft, atop); + } + if (!this.selectionLineWidth || !this.selectionBorderColor) { + return; + } ctx.lineWidth = this.selectionLineWidth; ctx.strokeStyle = this.selectionBorderColor; - if (this.selectionDashArray.length > 1) { + if (this.selectionDashArray.length > 1 && !supportLineDash) { var px = groupSelector.ex + STROKE_OFFSET - (left > 0 ? 0 : aleft), py = groupSelector.ey + STROKE_OFFSET - (top > 0 ? 0 : atop); ctx.beginPath(); fabric.util.drawDashedLine(ctx, px, py, px + aleft, py, this.selectionDashArray); @@ -4634,6 +4641,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, { ctx.closePath(); ctx.stroke(); } else { + fabric.Object.prototype._setLineDash.call(this, ctx, this.selectionDashArray); ctx.strokeRect(groupSelector.ex + STROKE_OFFSET - (left > 0 ? 0 : aleft), groupSelector.ey + STROKE_OFFSET - (top > 0 ? 0 : atop), aleft, atop); } }, @@ -4641,15 +4649,28 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, { if (this.skipTargetFind) { return; } - var ignoreZoom = true, pointer = this.getPointer(e, ignoreZoom), activeGroup = this.getActiveGroup(), activeObject = this.getActiveObject(); + var ignoreZoom = true, pointer = this.getPointer(e, ignoreZoom), activeGroup = this.getActiveGroup(), activeObject = this.getActiveObject(), activeTarget; if (activeGroup && !skipGroup && this._checkTarget(pointer, activeGroup)) { + this._fireOverOutEvents(activeGroup, e); return activeGroup; } - if (activeObject && this._checkTarget(pointer, activeObject)) { + if (activeObject && activeObject._findTargetCorner(pointer)) { + this._fireOverOutEvents(activeObject, e); return activeObject; } + if (activeObject && this._checkTarget(pointer, activeObject)) { + if (!this.preserveObjectStacking) { + this._fireOverOutEvents(activeObject, e); + return activeObject; + } else { + activeTarget = activeObject; + } + } this.targets = []; var target = this._searchPossibleTargets(this._objects, pointer); + if (e[this.altSelectionKey] && target && activeTarget && target !== activeTarget) { + target = activeTarget; + } this._fireOverOutEvents(target, e); return target; }, @@ -4950,6 +4971,35 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, { } this._objects[i]._renderControls(ctx); } + }, + _toObject: function(instance, methodName, propertiesToInclude) { + var originalProperties = this._realizeGroupTransformOnObject(instance), object = this.callSuper("_toObject", instance, methodName, propertiesToInclude); + this._unwindGroupTransformOnObject(instance, originalProperties); + return object; + }, + _realizeGroupTransformOnObject: function(instance) { + var layoutProps = [ "angle", "flipX", "flipY", "height", "left", "scaleX", "scaleY", "top", "width" ]; + if (instance.group && instance.group === this.getActiveGroup()) { + var originalValues = {}; + layoutProps.forEach(function(prop) { + originalValues[prop] = instance[prop]; + }); + this.getActiveGroup().realizeTransform(instance); + return originalValues; + } else { + return null; + } + }, + _unwindGroupTransformOnObject: function(instance, originalValues) { + if (originalValues) { + instance.set(originalValues); + } + }, + _setSVGObject: function(markup, instance, reviver) { + var originalProperties; + originalProperties = this._realizeGroupTransformOnObject(instance); + this.callSuper("_setSVGObject", markup, instance, reviver); + this._unwindGroupTransformOnObject(instance, originalProperties); } }); for (var prop in fabric.StaticCanvas) { @@ -4983,6 +5033,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, { addListener(this.upperCanvasEl, "mousemove", this._onMouseMove); addListener(this.upperCanvasEl, "mouseout", this._onMouseOut); addListener(this.upperCanvasEl, "wheel", this._onMouseWheel); + addListener(this.upperCanvasEl, "contextmenu", this._onContextMenu); addListener(this.upperCanvasEl, "touchstart", this._onMouseDown); addListener(this.upperCanvasEl, "touchmove", this._onMouseMove); if (typeof eventjs !== "undefined" && "add" in eventjs) { @@ -5005,6 +5056,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, { this._onOrientationChange = this._onOrientationChange.bind(this); this._onMouseWheel = this._onMouseWheel.bind(this); this._onMouseOut = this._onMouseOut.bind(this); + this._onContextMenu = this._onContextMenu.bind(this); }, removeListeners: function() { removeListener(fabric.window, "resize", this._onResize); @@ -5012,6 +5064,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, { removeListener(this.upperCanvasEl, "mousemove", this._onMouseMove); removeListener(this.upperCanvasEl, "mouseout", this._onMouseOut); removeListener(this.upperCanvasEl, "wheel", this._onMouseWheel); + removeListener(this.upperCanvasEl, "contextmenu", this._onContextMenu); removeListener(this.upperCanvasEl, "touchstart", this._onMouseDown); removeListener(this.upperCanvasEl, "touchmove", this._onMouseMove); if (typeof eventjs !== "undefined" && "remove" in eventjs) { @@ -5051,6 +5104,13 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, { _onLongPress: function(e, self) { this.__onLongPress && this.__onLongPress(e, self); }, + _onContextMenu: function(e) { + if (this.stopContextMenu) { + e.stopPropagation(); + e.preventDefault(); + } + return false; + }, _onMouseDown: function(e) { this.__onMouseDown(e); addListener(fabric.document, "touchend", this._onMouseUp); @@ -5183,8 +5243,11 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, { this._handleEvent(e, "up"); }, __onMouseDown: function(e) { - var isLeftClick = "which" in e ? e.which === 1 : e.button === 0; - if (!isLeftClick && !fabric.isTouchSupported) { + var isRightClick = "which" in e ? e.which === 3 : e.button === 2; + if (isRightClick) { + if (this.fireRightClick) { + this._handleEvent(e, "down", target ? target : null); + } return; } if (this.isDrawingMode) { @@ -5285,7 +5348,8 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, { }, _transformObject: function(e) { var pointer = this.getPointer(e), transform = this._currentTransform; - transform.reset = false, transform.target.isMoving = true; + transform.reset = false; + transform.target.isMoving = true; this._beforeScaleTransform(e, transform); this._performTransformAction(e, transform, pointer); transform.actionPerformed && this.renderAll(); @@ -5499,116 +5563,57 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, { }); })(); -fabric.util.object.extend(fabric.StaticCanvas.prototype, { - toDataURL: function(options) { - options || (options = {}); - var format = options.format || "png", quality = options.quality || 1, multiplier = options.multiplier || 1, cropping = { - left: options.left, - top: options.top, - width: options.width, - height: options.height - }; - if (this._isRetinaScaling()) { - multiplier *= fabric.devicePixelRatio; - } - if (multiplier !== 1) { +(function() { + var supportQuality = fabric.StaticCanvas.supports("toDataURLWithQuality"); + fabric.util.object.extend(fabric.StaticCanvas.prototype, { + toDataURL: function(options) { + options || (options = {}); + var format = options.format || "png", quality = options.quality || 1, multiplier = options.multiplier || 1, cropping = { + left: options.left || 0, + top: options.top || 0, + width: options.width || 0, + height: options.height || 0 + }; return this.__toDataURLWithMultiplier(format, quality, cropping, multiplier); - } else { - return this.__toDataURL(format, quality, cropping); - } - }, - __toDataURL: function(format, quality, cropping) { - this.renderAll(); - var canvasEl = this.contextContainer.canvas, croppedCanvasEl = this.__getCroppedCanvas(canvasEl, cropping); - if (format === "jpg") { - format = "jpeg"; - } - var data = fabric.StaticCanvas.supports("toDataURLWithQuality") ? (croppedCanvasEl || canvasEl).toDataURL("image/" + format, quality) : (croppedCanvasEl || canvasEl).toDataURL("image/" + format); - if (croppedCanvasEl) { - croppedCanvasEl = null; - } - return data; - }, - __getCroppedCanvas: function(canvasEl, cropping) { - var croppedCanvasEl, croppedCtx, shouldCrop = "left" in cropping || "top" in cropping || "width" in cropping || "height" in cropping; - if (shouldCrop) { - croppedCanvasEl = fabric.util.createCanvasElement(); - croppedCtx = croppedCanvasEl.getContext("2d"); - croppedCanvasEl.width = cropping.width || this.width; - croppedCanvasEl.height = cropping.height || this.height; - croppedCtx.drawImage(canvasEl, -cropping.left || 0, -cropping.top || 0); - } - return croppedCanvasEl; - }, - __toDataURLWithMultiplier: function(format, quality, cropping, multiplier) { - var origWidth = this.getWidth(), origHeight = this.getHeight(), scaledWidth = origWidth * multiplier, scaledHeight = origHeight * multiplier, activeObject = this.getActiveObject(), activeGroup = this.getActiveGroup(), zoom = this.getZoom(), newZoom = zoom * multiplier / fabric.devicePixelRatio; - if (multiplier > 1) { + }, + __toDataURLWithMultiplier: function(format, quality, cropping, multiplier) { + var origWidth = this.getWidth(), origHeight = this.getHeight(), scaledWidth = (cropping.width || this.getWidth()) * multiplier, scaledHeight = (cropping.width || this.getHeight()) * multiplier, zoom = this.getZoom(), newZoom = zoom * multiplier, vp = this.viewportTransform, translateX = (vp[4] - cropping.left) * multiplier, translateY = (vp[5] - cropping.top) * multiplier, newVp = [ newZoom, 0, 0, newZoom, translateX, translateY ], originalInteractive = this.interactive; + this.viewportTransform = newVp; + this.interactive && (this.interactive = false); + if (origWidth !== scaledWidth || origHeight !== scaledHeight) { + this.setDimensions({ + width: scaledWidth, + height: scaledHeight + }); + } else { + this.renderAll(); + } + var data = this.__toDataURL(format, quality, cropping); + originalInteractive && (this.interactive = originalInteractive); + this.viewportTransform = vp; this.setDimensions({ - width: scaledWidth, - height: scaledHeight + width: origWidth, + height: origHeight + }); + return data; + }, + __toDataURL: function(format, quality) { + var canvasEl = this.contextContainer.canvas; + if (format === "jpg") { + format = "jpeg"; + } + var data = supportQuality ? canvasEl.toDataURL("image/" + format, quality) : canvasEl.toDataURL("image/" + format); + return data; + }, + toDataURLWithMultiplier: function(format, multiplier, quality) { + return this.toDataURL({ + format: format, + multiplier: multiplier, + quality: quality }); } - this.setZoom(newZoom); - if (cropping.left) { - cropping.left *= multiplier; - } - if (cropping.top) { - cropping.top *= multiplier; - } - if (cropping.width) { - cropping.width *= multiplier; - } else if (multiplier < 1) { - cropping.width = scaledWidth; - } - if (cropping.height) { - cropping.height *= multiplier; - } else if (multiplier < 1) { - cropping.height = scaledHeight; - } - if (activeGroup) { - this._tempRemoveBordersControlsFromGroup(activeGroup); - } else if (activeObject && this.deactivateAll) { - this.deactivateAll(); - } - var data = this.__toDataURL(format, quality, cropping); - if (activeGroup) { - this._restoreBordersControlsOnGroup(activeGroup); - } else if (activeObject && this.setActiveObject) { - this.setActiveObject(activeObject); - } - this.setZoom(zoom); - this.setDimensions({ - width: origWidth, - height: origHeight - }); - return data; - }, - toDataURLWithMultiplier: function(format, multiplier, quality) { - return this.toDataURL({ - format: format, - multiplier: multiplier, - quality: quality - }); - }, - _tempRemoveBordersControlsFromGroup: function(group) { - group.origHasControls = group.hasControls; - group.origBorderColor = group.borderColor; - group.hasControls = true; - group.borderColor = "rgba(0,0,0,0)"; - group.forEachObject(function(o) { - o.origBorderColor = o.borderColor; - o.borderColor = "rgba(0,0,0,0)"; - }); - }, - _restoreBordersControlsOnGroup: function(group) { - group.hideControls = group.origHideControls; - group.borderColor = group.origBorderColor; - group.forEachObject(function(o) { - o.borderColor = o.origBorderColor; - delete o.origBorderColor; - }); - } -}); + }); +})(); fabric.util.object.extend(fabric.StaticCanvas.prototype, { loadFromDatalessJSON: function(json, callback, reviver) { @@ -5802,7 +5807,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { lockSkewingY: false, lockScalingFlip: false, excludeFromExport: false, - stateProperties: ("top left width height scaleX scaleY flipX flipY originX originY transformMatrix " + "stroke strokeWidth strokeDashArray strokeLineCap strokeLineJoin strokeMiterLimit " + "angle opacity fill fillRule globalCompositeOperation shadow clipTo visible backgroundColor " + "alignX alignY meetOrSlice skewX skewY").split(" "), + stateProperties: ("top left width height scaleX scaleY flipX flipY originX originY transformMatrix " + "stroke strokeWidth strokeDashArray strokeLineCap strokeLineJoin strokeMiterLimit " + "angle opacity fill fillRule globalCompositeOperation shadow clipTo visible backgroundColor " + "skewX skewY").split(" "), initialize: function(options) { if (options) { this.setOptions(options); @@ -5989,18 +5994,27 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { if (!noTransform) { this.transform(ctx); } + this._setOpacity(ctx); + this._setShadow(ctx); + this._renderBackground(ctx); this._setStrokeStyles(ctx); this._setFillStyles(ctx); if (this.transformMatrix) { ctx.transform.apply(ctx, this.transformMatrix); } - this._setOpacity(ctx); - this._setShadow(ctx); this.clipTo && fabric.util.clipContext(this, ctx); this._render(ctx, noTransform); this.clipTo && ctx.restore(); ctx.restore(); }, + _renderBackground: function(ctx) { + if (!this.backgroundColor) { + return; + } + ctx.fillStyle = this.backgroundColor; + ctx.fillRect(-this.width / 2, -this.height / 2, this.width, this.height); + this._removeShadow(ctx); + }, _setOpacity: function(ctx) { if (this.group) { this.group._setOpacity(ctx); @@ -6405,11 +6419,16 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { }, intersectsWithObject: function(other) { var intersection = fabric.Intersection.intersectPolygonPolygon(getCoords(this.oCoords), getCoords(other.oCoords)); - return intersection.status === "Intersection"; + return intersection.status === "Intersection" || other.isContainedWithinObject(this) || this.isContainedWithinObject(other); }, isContainedWithinObject: function(other) { - var boundingRect = other.getBoundingRect(), point1 = new fabric.Point(boundingRect.left, boundingRect.top), point2 = new fabric.Point(boundingRect.left + boundingRect.width, boundingRect.top + boundingRect.height); - return this.isContainedWithinRect(point1, point2); + var points = getCoords(this.oCoords), i = 0; + for (;i < 4; i++) { + if (!other.containsPoint(points[i])) { + return false; + } + } + return true; }, isContainedWithinRect: function(pointTL, pointBR) { var boundingRect = this.getBoundingRect(); @@ -6443,7 +6462,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { }; }, _findCrossPoints: function(point, oCoords) { - var b1, b2, a1, a2, xi, yi, xcount = 0, iLine; + var b1, b2, a1, a2, xi, xcount = 0, iLine; for (var lineKey in oCoords) { iLine = oCoords[lineKey]; if (iLine.o.y < point.y && iLine.d.y < point.y) { @@ -6454,14 +6473,12 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { } if (iLine.o.x === iLine.d.x && iLine.o.x >= point.x) { xi = iLine.o.x; - yi = point.y; } else { b1 = 0; b2 = (iLine.d.y - iLine.o.y) / (iLine.d.x - iLine.o.x); a1 = point.y - b1 * point.x; a2 = iLine.o.y - b2 * iLine.o.x; xi = -(a1 - a2) / (b1 - b2); - yi = a1 + b1 * xi; } if (xi >= point.x) { xcount += 1; @@ -6653,29 +6670,53 @@ fabric.util.object.extend(fabric.Object.prototype, { }); })(); -fabric.util.object.extend(fabric.Object.prototype, { - hasStateChanged: function() { - return this.stateProperties.some(function(prop) { - return this.get(prop) !== this.originalState[prop]; - }, this); - }, - saveState: function(options) { - this.stateProperties.forEach(function(prop) { - this.originalState[prop] = this.get(prop); - }, this); - if (options && options.stateProperties) { - options.stateProperties.forEach(function(prop) { - this.originalState[prop] = this.get(prop); - }, this); - } - return this; - }, - setupState: function() { - this.originalState = {}; - this.saveState(); - return this; +(function() { + var extend = fabric.util.object.extend; + function saveProps(origin, destination, props) { + var tmpObj = {}, deep = true; + props.forEach(function(prop) { + tmpObj[prop] = origin[prop]; + }); + extend(origin[destination], tmpObj, deep); } -}); + function _isEqual(origValue, currentValue) { + if (origValue instanceof Array) { + if (origValue.length !== currentValue.length) { + return false; + } + var _currentValue = currentValue.concat().sort(), _origValue = origValue.concat().sort(); + return !_origValue.some(function(v, i) { + return !_isEqual(_currentValue[i], v); + }); + } else if (origValue instanceof Object) { + for (var key in origValue) { + if (!_isEqual(origValue[key], currentValue[key])) { + return false; + } + } + return true; + } else { + return origValue === currentValue; + } + } + fabric.util.object.extend(fabric.Object.prototype, { + hasStateChanged: function() { + return !_isEqual(this.originalState, this); + }, + saveState: function(options) { + saveProps(this, "originalState", this.stateProperties); + if (options && options.stateProperties) { + saveProps(this, "originalState", options.stateProperties); + } + return this; + }, + setupState: function(options) { + this.originalState = {}; + this.saveState(options); + return this; + } + }); +})(); (function() { var degreesToRadians = fabric.util.degreesToRadians, isVML = function() { @@ -6787,7 +6828,7 @@ fabric.util.object.extend(fabric.Object.prototype, { return p.scalarAdd(2 * this.padding); }, drawSelectionBackground: function(ctx) { - if (!this.selectionBackgroundColor || this.group || this !== this.canvas.getActiveObject()) { + if (!this.selectionBackgroundColor || this.group || !this.active) { return this; } ctx.save(); @@ -7168,9 +7209,10 @@ fabric.util.object.extend(fabric.Object.prototype, { var parsedAttributes = fabric.parseAttributes(element, fabric.Line.ATTRIBUTE_NAMES), points = [ parsedAttributes.x1 || 0, parsedAttributes.y1 || 0, parsedAttributes.x2 || 0, parsedAttributes.y2 || 0 ]; return new fabric.Line(points, extend(parsedAttributes, options)); }; - fabric.Line.fromObject = function(object) { - var points = [ object.x1, object.y1, object.x2, object.y2 ]; - return new fabric.Line(points, object); + fabric.Line.fromObject = function(object, callback) { + var points = [ object.x1, object.y1, object.x2, object.y2 ], line = new fabric.Line(points, object); + callback && callback(line); + return line; }; function makeEdgeToOriginGetter(propertyNames, originValues) { var origin = propertyNames.origin, axis1 = propertyNames.axis1, axis2 = propertyNames.axis2, dimension = propertyNames.dimension, nearest = originValues.nearest, center = originValues.center, farthest = originValues.farthest; @@ -7273,8 +7315,10 @@ fabric.util.object.extend(fabric.Object.prototype, { function isValidRadius(attributes) { return "radius" in attributes && attributes.radius >= 0; } - fabric.Circle.fromObject = function(object) { - return new fabric.Circle(object); + fabric.Circle.fromObject = function(object, callback) { + var circle = new fabric.Circle(object); + callback && callback(circle); + return circle; }; })(typeof exports !== "undefined" ? exports : this); @@ -7319,8 +7363,10 @@ fabric.util.object.extend(fabric.Object.prototype, { return 1; } }); - fabric.Triangle.fromObject = function(object) { - return new fabric.Triangle(object); + fabric.Triangle.fromObject = function(object, callback) { + var triangle = new fabric.Triangle(object); + callback && callback(triangle); + return triangle; }; })(typeof exports !== "undefined" ? exports : this); @@ -7401,8 +7447,10 @@ fabric.util.object.extend(fabric.Object.prototype, { ellipse.left -= ellipse.rx; return ellipse; }; - fabric.Ellipse.fromObject = function(object) { - return new fabric.Ellipse(object); + fabric.Ellipse.fromObject = function(object, callback) { + var ellipse = new fabric.Ellipse(object); + callback && callback(ellipse); + return ellipse; }; })(typeof exports !== "undefined" ? exports : this); @@ -7498,8 +7546,10 @@ fabric.util.object.extend(fabric.Object.prototype, { rect.visible = rect.visible && rect.width > 0 && rect.height > 0; return rect; }; - fabric.Rect.fromObject = function(object) { - return new fabric.Rect(object); + fabric.Rect.fromObject = function(object, callback) { + var rect = new fabric.Rect(object); + callback && callback(rect); + return rect; }; })(typeof exports !== "undefined" ? exports : this); @@ -7556,9 +7606,10 @@ fabric.util.object.extend(fabric.Object.prototype, { var points = fabric.parsePointsAttribute(element.getAttribute("points")), parsedAttributes = fabric.parseAttributes(element, fabric.Polyline.ATTRIBUTE_NAMES); return new fabric.Polyline(points, fabric.util.object.extend(parsedAttributes, options)); }; - fabric.Polyline.fromObject = function(object) { - var points = object.points; - return new fabric.Polyline(points, object, true); + fabric.Polyline.fromObject = function(object, callback) { + var polyline = new fabric.Polyline(object.points, object); + callback && callback(polyline); + return polyline; }; })(typeof exports !== "undefined" ? exports : this); @@ -7594,7 +7645,8 @@ fabric.util.object.extend(fabric.Object.prototype, { var points = this.points, minX = min(points, "x"), minY = min(points, "y"), maxX = max(points, "x"), maxY = max(points, "y"); this.width = maxX - minX || 0; this.height = maxY - minY || 0; - this.minX = minX || 0, this.minY = minY || 0; + this.minX = minX || 0; + this.minY = minY || 0; }, toObject: function(propertiesToInclude) { return extend(this.callSuper("toObject", propertiesToInclude), { @@ -7653,8 +7705,10 @@ fabric.util.object.extend(fabric.Object.prototype, { var points = fabric.parsePointsAttribute(element.getAttribute("points")), parsedAttributes = fabric.parseAttributes(element, fabric.Polygon.ATTRIBUTE_NAMES); return new fabric.Polygon(points, extend(parsedAttributes, options)); }; - fabric.Polygon.fromObject = function(object) { - return new fabric.Polygon(object.points, object, true); + fabric.Polygon.fromObject = function(object, callback) { + var polygon = new fabric.Polygon(object.points, object); + callback && callback(polygon); + return polygon; }; })(typeof exports !== "undefined" ? exports : this); @@ -8164,16 +8218,20 @@ fabric.util.object.extend(fabric.Object.prototype, { } }); fabric.Path.fromObject = function(object, callback) { + var path; if (typeof object.path === "string") { fabric.loadSVGFromURL(object.path, function(elements) { - var path = elements[0], pathUrl = object.path; + var pathUrl = object.path; + path = elements[0]; delete object.path; fabric.util.object.extend(path, object); path.setSourcePath(pathUrl); - callback(path); + callback && callback(path); }); } else { - callback(new fabric.Path(object.path, object)); + path = new fabric.Path(object.path, object); + callback && callback(path); + return path; } }; fabric.Path.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat([ "d" ]); @@ -8626,6 +8684,8 @@ fabric.util.object.extend(fabric.Object.prototype, { fabric.warn("fabric.Image is already defined."); return; } + var stateProperties = fabric.Object.prototype.stateProperties.concat(); + stateProperties.push("alignX", "alignY", "meetOrSlice"); fabric.Image = fabric.util.createClass(fabric.Object, { type: "image", crossOrigin: "", @@ -8636,6 +8696,7 @@ fabric.util.object.extend(fabric.Object.prototype, { _lastScaleX: 1, _lastScaleY: 1, minimumScaleTrigger: .5, + stateProperties: stateProperties, initialize: function(element, options, callback) { options || (options = {}); this.filters = []; @@ -8734,7 +8795,7 @@ fabric.util.object.extend(fabric.Object.prototype, { return object; }, toSVG: function(reviver) { - var markup = this._createBaseSVGMarkup(), x = -this.width / 2, y = -this.height / 2, preserveAspectRatio = "none"; + var markup = this._createBaseSVGMarkup(), x = -this.width / 2, y = -this.height / 2, preserveAspectRatio = "none", filtered = true; if (this.group && this.group.type === "path-group") { x = this.left; y = this.top; @@ -8742,7 +8803,7 @@ fabric.util.object.extend(fabric.Object.prototype, { if (this.alignX !== "none" && this.alignY !== "none") { preserveAspectRatio = "x" + this.alignX + "Y" + this.alignY + " " + this.meetOrSlice; } - markup.push('\n', "\n"); + markup.push('\n', "\n"); if (this.stroke || this.strokeDashArray) { var origFill = this.fill; this.fill = null; @@ -8752,8 +8813,8 @@ fabric.util.object.extend(fabric.Object.prototype, { markup.push("\n"); return reviver ? reviver(markup.join("")) : markup.join(""); }, - getSrc: function() { - var element = this._originalElement; + getSrc: function(filtered) { + var element = filtered ? this._element : this._originalElement; if (element) { return fabric.isLikelyNode ? element._src : element.src; } else { @@ -8768,9 +8829,6 @@ fabric.util.object.extend(fabric.Object.prototype, { toString: function() { return '#'; }, - clone: function(callback, propertiesToInclude) { - this.constructor.fromObject(this.toObject(propertiesToInclude), callback); - }, applyFilters: function(callback, filters, imgElement, forResizing) { filters = filters || this.filters; imgElement = imgElement || this._originalElement; @@ -9018,8 +9076,8 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass({ (function(global) { "use strict"; - var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend; - fabric.Image.filters.Brightness = fabric.util.createClass(fabric.Image.filters.BaseFilter, { + var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend, filters = fabric.Image.filters, createClass = fabric.util.createClass; + filters.Brightness = createClass(filters.BaseFilter, { type: "Brightness", initialize: function(options) { options = options || {}; @@ -9047,8 +9105,8 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass({ (function(global) { "use strict"; - var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend; - fabric.Image.filters.Convolute = fabric.util.createClass(fabric.Image.filters.BaseFilter, { + var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend, filters = fabric.Image.filters, createClass = fabric.util.createClass; + filters.Convolute = createClass(filters.BaseFilter, { type: "Convolute", initialize: function(options) { options = options || {}; @@ -9101,8 +9159,8 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass({ (function(global) { "use strict"; - var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend; - fabric.Image.filters.GradientTransparency = fabric.util.createClass(fabric.Image.filters.BaseFilter, { + var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend, filters = fabric.Image.filters, createClass = fabric.util.createClass; + filters.GradientTransparency = createClass(filters.BaseFilter, { type: "GradientTransparency", initialize: function(options) { options = options || {}; @@ -9128,8 +9186,8 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass({ (function(global) { "use strict"; - var fabric = global.fabric || (global.fabric = {}); - fabric.Image.filters.Grayscale = fabric.util.createClass(fabric.Image.filters.BaseFilter, { + var fabric = global.fabric || (global.fabric = {}), filters = fabric.Image.filters, createClass = fabric.util.createClass; + filters.Grayscale = createClass(filters.BaseFilter, { type: "Grayscale", applyTo: function(canvasEl) { var context = canvasEl.getContext("2d"), imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height), data = imageData.data, len = imageData.width * imageData.height * 4, index = 0, average; @@ -9150,8 +9208,8 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass({ (function(global) { "use strict"; - var fabric = global.fabric || (global.fabric = {}); - fabric.Image.filters.Invert = fabric.util.createClass(fabric.Image.filters.BaseFilter, { + var fabric = global.fabric || (global.fabric = {}), filters = fabric.Image.filters, createClass = fabric.util.createClass; + filters.Invert = createClass(filters.BaseFilter, { type: "Invert", applyTo: function(canvasEl) { var context = canvasEl.getContext("2d"), imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height), data = imageData.data, iLen = data.length, i; @@ -9170,8 +9228,8 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass({ (function(global) { "use strict"; - var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend; - fabric.Image.filters.Mask = fabric.util.createClass(fabric.Image.filters.BaseFilter, { + var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend, filters = fabric.Image.filters, createClass = fabric.util.createClass; + filters.Mask = createClass(filters.BaseFilter, { type: "Mask", initialize: function(options) { options = options || {}; @@ -9210,8 +9268,8 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass({ (function(global) { "use strict"; - var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend; - fabric.Image.filters.Noise = fabric.util.createClass(fabric.Image.filters.BaseFilter, { + var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend, filters = fabric.Image.filters, createClass = fabric.util.createClass; + filters.Noise = createClass(filters.BaseFilter, { type: "Noise", initialize: function(options) { options = options || {}; @@ -9240,8 +9298,8 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass({ (function(global) { "use strict"; - var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend; - fabric.Image.filters.Pixelate = fabric.util.createClass(fabric.Image.filters.BaseFilter, { + var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend, filters = fabric.Image.filters, createClass = fabric.util.createClass; + filters.Pixelate = createClass(filters.BaseFilter, { type: "Pixelate", initialize: function(options) { options = options || {}; @@ -9282,8 +9340,8 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass({ (function(global) { "use strict"; - var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend; - fabric.Image.filters.RemoveWhite = fabric.util.createClass(fabric.Image.filters.BaseFilter, { + var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend, filters = fabric.Image.filters, createClass = fabric.util.createClass; + filters.RemoveWhite = createClass(filters.BaseFilter, { type: "RemoveWhite", initialize: function(options) { options = options || {}; @@ -9316,8 +9374,8 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass({ (function(global) { "use strict"; - var fabric = global.fabric || (global.fabric = {}); - fabric.Image.filters.Sepia = fabric.util.createClass(fabric.Image.filters.BaseFilter, { + var fabric = global.fabric || (global.fabric = {}), filters = fabric.Image.filters, createClass = fabric.util.createClass; + filters.Sepia = createClass(filters.BaseFilter, { type: "Sepia", applyTo: function(canvasEl) { var context = canvasEl.getContext("2d"), imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height), data = imageData.data, iLen = data.length, i, avg; @@ -9337,8 +9395,8 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass({ (function(global) { "use strict"; - var fabric = global.fabric || (global.fabric = {}); - fabric.Image.filters.Sepia2 = fabric.util.createClass(fabric.Image.filters.BaseFilter, { + var fabric = global.fabric || (global.fabric = {}), filters = fabric.Image.filters, createClass = fabric.util.createClass; + filters.Sepia2 = createClass(filters.BaseFilter, { type: "Sepia2", applyTo: function(canvasEl) { var context = canvasEl.getContext("2d"), imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height), data = imageData.data, iLen = data.length, i, r, g, b; @@ -9360,8 +9418,8 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass({ (function(global) { "use strict"; - var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend; - fabric.Image.filters.Tint = fabric.util.createClass(fabric.Image.filters.BaseFilter, { + var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend, filters = fabric.Image.filters, createClass = fabric.util.createClass; + filters.Tint = createClass(filters.BaseFilter, { type: "Tint", initialize: function(options) { options = options || {}; @@ -9399,8 +9457,8 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass({ (function(global) { "use strict"; - var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend; - fabric.Image.filters.Multiply = fabric.util.createClass(fabric.Image.filters.BaseFilter, { + var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend, filters = fabric.Image.filters, createClass = fabric.util.createClass; + filters.Multiply = createClass(filters.BaseFilter, { type: "Multiply", initialize: function(options) { options = options || {}; @@ -9429,8 +9487,8 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass({ (function(global) { "use strict"; - var fabric = global.fabric; - fabric.Image.filters.Blend = fabric.util.createClass(fabric.Image.filters.BaseFilter, { + var fabric = global.fabric, filters = fabric.Image.filters, createClass = fabric.util.createClass; + filters.Blend = createClass(filters.BaseFilter, { type: "Blend", initialize: function(options) { options = options || {}; @@ -9531,8 +9589,8 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass({ (function(global) { "use strict"; - var fabric = global.fabric || (global.fabric = {}), pow = Math.pow, floor = Math.floor, sqrt = Math.sqrt, abs = Math.abs, max = Math.max, round = Math.round, sin = Math.sin, ceil = Math.ceil; - fabric.Image.filters.Resize = fabric.util.createClass(fabric.Image.filters.BaseFilter, { + var fabric = global.fabric || (global.fabric = {}), pow = Math.pow, floor = Math.floor, sqrt = Math.sqrt, abs = Math.abs, max = Math.max, round = Math.round, sin = Math.sin, ceil = Math.ceil, filters = fabric.Image.filters, createClass = fabric.util.createClass; + filters.Resize = createClass(filters.BaseFilter, { type: "Resize", resizeType: "hermite", scaleX: 0, @@ -9622,7 +9680,11 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass({ for (v = 0; v < dH; v++) { center.y = (v + .5) * ratioY; icenter.y = floor(center.y); - a = 0, red = 0, green = 0, blue = 0, alpha = 0; + a = 0; + red = 0; + green = 0; + blue = 0; + alpha = 0; for (i = icenter.x - range2X; i <= icenter.x + range2X; i++) { if (i < 0 || i >= oW) { continue; @@ -9738,8 +9800,8 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass({ (function(global) { "use strict"; - var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend; - fabric.Image.filters.ColorMatrix = fabric.util.createClass(fabric.Image.filters.BaseFilter, { + var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend, filters = fabric.Image.filters, createClass = fabric.util.createClass; + filters.ColorMatrix = createClass(filters.BaseFilter, { type: "ColorMatrix", initialize: function(options) { options || (options = {}); @@ -9773,7 +9835,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass({ (function(global) { "use strict"; - var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend, clone = fabric.util.object.clone, toFixed = fabric.util.toFixed, NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS; + var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend, clone = fabric.util.object.clone, toFixed = fabric.util.toFixed, NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS, MIN_TEXT_WIDTH = 2; if (fabric.Text) { fabric.warn("fabric.Text is already defined"); return; @@ -9790,7 +9852,6 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass({ text: true, charSpacing: true, textAlign: true, - stroke: false, strokeWidth: false }, _reNewline: /\r?\n/, @@ -9828,7 +9889,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass({ } this._textLines = this._splitTextIntoLines(); this._clearCache(); - this.width = this._getTextWidth(ctx); + this.width = this._getTextWidth(ctx) || this.cursorWidth || MIN_TEXT_WIDTH; this.height = this._getTextHeight(ctx); }, toString: function() { @@ -9967,17 +10028,9 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass({ return this.fontSize * this._fontSizeMult; }, _renderTextBackground: function(ctx) { - this._renderTextBoxBackground(ctx); + this._renderBackground(ctx); this._renderTextLinesBackground(ctx); }, - _renderTextBoxBackground: function(ctx) { - if (!this.backgroundColor) { - return; - } - ctx.fillStyle = this.backgroundColor; - ctx.fillRect(this._getLeftOffset(), this._getTopOffset(), this.width, this.height); - this._removeShadow(ctx); - }, _renderTextLinesBackground: function(ctx) { if (!this.textBackgroundColor) { return; @@ -10064,7 +10117,8 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass({ function renderLinesAtOffset(offsets) { var i, lineHeight = 0, len, j, oLen, lineWidth, lineLeftOffset, heightOfLine; for (i = 0, len = _this._textLines.length; i < len; i++) { - lineWidth = _this._getLineWidth(ctx, i), lineLeftOffset = _this._getLineLeftOffset(lineWidth), + lineWidth = _this._getLineWidth(ctx, i); + lineLeftOffset = _this._getLineLeftOffset(lineWidth); heightOfLine = _this._getHeightOfLine(ctx, i); for (j = 0, oLen = offsets.length; j < oLen; j++) { ctx.fillRect(_this._getLeftOffset() + lineLeftOffset, lineHeight + (_this._fontSizeMult - 1 + offsets[j]) * _this.fontSize - halfOfVerticalBox, lineWidth, _this.fontSize / 15); @@ -10086,7 +10140,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass({ } }, _getFontDeclaration: function() { - return [ fabric.isLikelyNode ? this.fontWeight : this.fontStyle, fabric.isLikelyNode ? this.fontStyle : this.fontWeight, this.fontSize + "px", '"' + this.fontFamily + '"' ].join(" "); + return [ fabric.isLikelyNode ? this.fontWeight : this.fontStyle, fabric.isLikelyNode ? this.fontStyle : this.fontWeight, this.fontSize + "px", fabric.isLikelyNode ? '"' + this.fontFamily + '"' : this.fontFamily ].join(" "); }, render: function(ctx, noTransform) { if (!this.visible) { @@ -10257,8 +10311,10 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass({ }); return text; }; - fabric.Text.fromObject = function(object) { - return new fabric.Text(object.text, clone(object)); + fabric.Text.fromObject = function(object, callback) { + var text = new fabric.Text(object.text, clone(object)); + callback && callback(text); + return text; }; fabric.util.createAccessors(fabric.Text); })(typeof exports !== "undefined" ? exports : this); @@ -10672,6 +10728,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass({ styleDeclaration.scaleX = this.scaleX; styleDeclaration.scaleY = this.scaleY; styleDeclaration.canvas = this.canvas; + styleDeclaration.getObjectScaling = this.getObjectScaling; this._setShadow.call(styleDeclaration, ctx); } if (!this.caching || !charWidthsCache[cacheProp]) { @@ -10803,8 +10860,10 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass({ }); } }); - fabric.IText.fromObject = function(object) { - return new fabric.IText(object.text, clone(object)); + fabric.IText.fromObject = function(object, callback) { + var iText = new fabric.IText(object.text, clone(object)); + callback && callback(iText); + return iText; }; })(); @@ -11119,6 +11178,8 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass({ if (p.y > maxHeight) { p.y = maxHeight; } + p.x += this.canvas._offset.left; + p.y += this.canvas._offset.top; return { left: p.x + "px", top: p.y + "px", @@ -11327,6 +11388,44 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass({ }, insertNewline: function() { this.insertChars("\n"); + }, + setSelectionStartEndWithShift: function(start, end, newSelection) { + if (newSelection <= start) { + if (end === start) { + this._selectionDirection = "left"; + } else if (this._selectionDirection === "right") { + this._selectionDirection = "left"; + this.selectionEnd = start; + } + this.selectionStart = newSelection; + } else if (newSelection > start && newSelection < end) { + if (this._selectionDirection === "right") { + this.selectionEnd = newSelection; + } else { + this.selectionStart = newSelection; + } + } else { + if (end === start) { + this._selectionDirection = "right"; + } else if (this._selectionDirection === "left") { + this._selectionDirection = "right"; + this.selectionStart = end; + } + this.selectionEnd = newSelection; + } + }, + setSelectionInBoundaries: function() { + var length = this.text.length; + if (this.selectionStart > length) { + this.selectionStart = length; + } else if (this.selectionStart < 0) { + this.selectionStart = 0; + } + if (this.selectionEnd > length) { + this.selectionEnd = length; + } else if (this.selectionEnd < 0) { + this.selectionEnd = 0; + } } }); })(); @@ -11421,17 +11520,12 @@ fabric.util.object.extend(fabric.IText.prototype, { }); }, setCursorByClick: function(e) { - var newSelectionStart = this.getSelectionStartFromPointer(e); + var newSelection = this.getSelectionStartFromPointer(e), start = this.selectionStart, end = this.selectionEnd; if (e.shiftKey) { - if (newSelectionStart < this.selectionStart) { - this.selectionEnd = this.selectionStart; - this.selectionStart = newSelectionStart; - } else { - this.selectionEnd = newSelectionStart; - } + this.setSelectionStartEndWithShift(start, end, newSelection); } else { - this.selectionStart = newSelectionStart; - this.selectionEnd = newSelectionStart; + this.selectionStart = newSelection; + this.selectionEnd = newSelection; } this._fireSelectionChanged(); this._updateTextarea(); @@ -11627,37 +11721,53 @@ fabric.util.object.extend(fabric.IText.prototype, { _getClipboardData: function(e) { return e && e.clipboardData || fabric.window.clipboardData; }, + _getWidthBeforeCursor: function(lineIndex, charIndex) { + var textBeforeCursor = this._textLines[lineIndex].slice(0, charIndex), widthOfLine = this._getLineWidth(this.ctx, lineIndex), widthBeforeCursor = this._getLineLeftOffset(widthOfLine), _char; + for (var i = 0, len = textBeforeCursor.length; i < len; i++) { + _char = textBeforeCursor[i]; + widthBeforeCursor += this._getWidthOfChar(this.ctx, _char, lineIndex, i); + } + return widthBeforeCursor; + }, getDownCursorOffset: function(e, isRight) { - var selectionProp = isRight ? this.selectionEnd : this.selectionStart, cursorLocation = this.get2DCursorLocation(selectionProp), _char, lineLeftOffset, lineIndex = cursorLocation.lineIndex, textOnSameLineBeforeCursor = this._textLines[lineIndex].slice(0, cursorLocation.charIndex), textOnSameLineAfterCursor = this._textLines[lineIndex].slice(cursorLocation.charIndex), textOnNextLine = this._textLines[lineIndex + 1] || ""; + var selectionProp = this._getSelectionForOffset(e, isRight), cursorLocation = this.get2DCursorLocation(selectionProp), lineIndex = cursorLocation.lineIndex; if (lineIndex === this._textLines.length - 1 || e.metaKey || e.keyCode === 34) { return this.text.length - selectionProp; } - var widthOfSameLineBeforeCursor = this._getLineWidth(this.ctx, lineIndex); - lineLeftOffset = this._getLineLeftOffset(widthOfSameLineBeforeCursor); - var widthOfCharsOnSameLineBeforeCursor = lineLeftOffset; - for (var i = 0, len = textOnSameLineBeforeCursor.length; i < len; i++) { - _char = textOnSameLineBeforeCursor[i]; - widthOfCharsOnSameLineBeforeCursor += this._getWidthOfChar(this.ctx, _char, lineIndex, i); - } - var indexOnNextLine = this._getIndexOnNextLine(cursorLocation, textOnNextLine, widthOfCharsOnSameLineBeforeCursor); - return textOnSameLineAfterCursor.length + 1 + indexOnNextLine; + var charIndex = cursorLocation.charIndex, widthBeforeCursor = this._getWidthBeforeCursor(lineIndex, charIndex), indexOnOtherLine = this._getIndexOnLine(lineIndex + 1, widthBeforeCursor), textAfterCursor = this._textLines[lineIndex].slice(charIndex); + return textAfterCursor.length + indexOnOtherLine + 2; }, - _getIndexOnNextLine: function(cursorLocation, textOnNextLine, widthOfCharsOnSameLineBeforeCursor) { - var lineIndex = cursorLocation.lineIndex + 1, widthOfNextLine = this._getLineWidth(this.ctx, lineIndex), lineLeftOffset = this._getLineLeftOffset(widthOfNextLine), widthOfCharsOnNextLine = lineLeftOffset, indexOnNextLine = 0, foundMatch; - for (var j = 0, jlen = textOnNextLine.length; j < jlen; j++) { - var _char = textOnNextLine[j], widthOfChar = this._getWidthOfChar(this.ctx, _char, lineIndex, j); - widthOfCharsOnNextLine += widthOfChar; - if (widthOfCharsOnNextLine > widthOfCharsOnSameLineBeforeCursor) { + _getSelectionForOffset: function(e, isRight) { + if (e.shiftKey && this.selectionStart !== this.selectionEnd && isRight) { + return this.selectionEnd; + } else { + return this.selectionStart; + } + }, + getUpCursorOffset: function(e, isRight) { + var selectionProp = this._getSelectionForOffset(e, isRight), cursorLocation = this.get2DCursorLocation(selectionProp), lineIndex = cursorLocation.lineIndex; + if (lineIndex === 0 || e.metaKey || e.keyCode === 33) { + return -selectionProp; + } + var charIndex = cursorLocation.charIndex, widthBeforeCursor = this._getWidthBeforeCursor(lineIndex, charIndex), indexOnOtherLine = this._getIndexOnLine(lineIndex - 1, widthBeforeCursor), textBeforeCursor = this._textLines[lineIndex].slice(0, charIndex); + return -this._textLines[lineIndex - 1].length + indexOnOtherLine - textBeforeCursor.length; + }, + _getIndexOnLine: function(lineIndex, width) { + var widthOfLine = this._getLineWidth(this.ctx, lineIndex), textOnLine = this._textLines[lineIndex], lineLeftOffset = this._getLineLeftOffset(widthOfLine), widthOfCharsOnLine = lineLeftOffset, indexOnLine = 0, foundMatch; + for (var j = 0, jlen = textOnLine.length; j < jlen; j++) { + var _char = textOnLine[j], widthOfChar = this._getWidthOfChar(this.ctx, _char, lineIndex, j); + widthOfCharsOnLine += widthOfChar; + if (widthOfCharsOnLine > width) { foundMatch = true; - var leftEdge = widthOfCharsOnNextLine - widthOfChar, rightEdge = widthOfCharsOnNextLine, offsetFromLeftEdge = Math.abs(leftEdge - widthOfCharsOnSameLineBeforeCursor), offsetFromRightEdge = Math.abs(rightEdge - widthOfCharsOnSameLineBeforeCursor); - indexOnNextLine = offsetFromRightEdge < offsetFromLeftEdge ? j + 1 : j; + var leftEdge = widthOfCharsOnLine - widthOfChar, rightEdge = widthOfCharsOnLine, offsetFromLeftEdge = Math.abs(leftEdge - width), offsetFromRightEdge = Math.abs(rightEdge - width); + indexOnLine = offsetFromRightEdge < offsetFromLeftEdge ? j : j - 1; break; } } if (!foundMatch) { - indexOnNextLine = textOnNextLine.length; + indexOnLine = textOnLine.length - 1; } - return indexOnNextLine; + return indexOnLine; }, moveCursorDown: function(e) { if (this.selectionStart >= this.text.length && this.selectionEnd >= this.text.length) { @@ -11665,65 +11775,6 @@ fabric.util.object.extend(fabric.IText.prototype, { } this._moveCursorUpOrDown("Down", e); }, - moveCursorDownWithoutShift: function(offset) { - this._selectionDirection = "right"; - this.selectionEnd = this.selectionEnd + offset; - this.selectionStart = this.selectionEnd; - return offset !== 0; - }, - swapSelectionPoints: function() { - var swapSel = this.selectionEnd; - this.selectionEnd = this.selectionStart; - this.selectionStart = swapSel; - }, - moveCursorDownWithShift: function(offset) { - if (this.selectionEnd === this.selectionStart) { - this._selectionDirection = "right"; - } - if (this._selectionDirection === "right") { - this.selectionEnd += offset; - } else { - this.selectionStart += offset; - } - if (this.selectionEnd < this.selectionStart && this._selectionDirection === "left") { - this.swapSelectionPoints(); - this._selectionDirection = "right"; - } - if (this.selectionEnd > this.text.length) { - this.selectionEnd = this.text.length; - } - return offset !== 0; - }, - getUpCursorOffset: function(e, isRight) { - var selectionProp = isRight ? this.selectionEnd : this.selectionStart, cursorLocation = this.get2DCursorLocation(selectionProp), lineIndex = cursorLocation.lineIndex; - if (lineIndex === 0 || e.metaKey || e.keyCode === 33) { - return selectionProp; - } - var textOnSameLineBeforeCursor = this._textLines[lineIndex].slice(0, cursorLocation.charIndex), textOnPreviousLine = this._textLines[lineIndex - 1] || "", _char, widthOfSameLineBeforeCursor = this._getLineWidth(this.ctx, cursorLocation.lineIndex), lineLeftOffset = this._getLineLeftOffset(widthOfSameLineBeforeCursor), widthOfCharsOnSameLineBeforeCursor = lineLeftOffset; - for (var i = 0, len = textOnSameLineBeforeCursor.length; i < len; i++) { - _char = textOnSameLineBeforeCursor[i]; - widthOfCharsOnSameLineBeforeCursor += this._getWidthOfChar(this.ctx, _char, lineIndex, i); - } - var indexOnPrevLine = this._getIndexOnPrevLine(cursorLocation, textOnPreviousLine, widthOfCharsOnSameLineBeforeCursor); - return textOnPreviousLine.length - indexOnPrevLine + textOnSameLineBeforeCursor.length; - }, - _getIndexOnPrevLine: function(cursorLocation, textOnPreviousLine, widthOfCharsOnSameLineBeforeCursor) { - var lineIndex = cursorLocation.lineIndex - 1, widthOfPreviousLine = this._getLineWidth(this.ctx, lineIndex), lineLeftOffset = this._getLineLeftOffset(widthOfPreviousLine), widthOfCharsOnPreviousLine = lineLeftOffset, indexOnPrevLine = 0, foundMatch; - for (var j = 0, jlen = textOnPreviousLine.length; j < jlen; j++) { - var _char = textOnPreviousLine[j], widthOfChar = this._getWidthOfChar(this.ctx, _char, lineIndex, j); - widthOfCharsOnPreviousLine += widthOfChar; - if (widthOfCharsOnPreviousLine > widthOfCharsOnSameLineBeforeCursor) { - foundMatch = true; - var leftEdge = widthOfCharsOnPreviousLine - widthOfChar, rightEdge = widthOfCharsOnPreviousLine, offsetFromLeftEdge = Math.abs(leftEdge - widthOfCharsOnSameLineBeforeCursor), offsetFromRightEdge = Math.abs(rightEdge - widthOfCharsOnSameLineBeforeCursor); - indexOnPrevLine = offsetFromRightEdge < offsetFromLeftEdge ? j : j - 1; - break; - } - } - if (!foundMatch) { - indexOnPrevLine = textOnPreviousLine.length - 1; - } - return indexOnPrevLine; - }, moveCursorUp: function(e) { if (this.selectionStart === 0 && this.selectionEnd === 0) { return; @@ -11731,13 +11782,14 @@ fabric.util.object.extend(fabric.IText.prototype, { this._moveCursorUpOrDown("Up", e); }, _moveCursorUpOrDown: function(direction, e) { - var action = "get" + direction + "CursorOffset", moveAction = "moveCursor" + direction, offset = this[action](e, this._selectionDirection === "right"); + var action = "get" + direction + "CursorOffset", offset = this[action](e, this._selectionDirection === "right"); if (e.shiftKey) { - moveAction += "WithShift"; + this.moveCursorWithShift(offset); } else { - moveAction += "WithoutShift"; + this.moveCursorWithoutShift(offset); } - if (this[moveAction](offset)) { + if (offset !== 0) { + this.setSelectionInBoundaries(); this.abortCursorAnimation(); this._currentCursorOpacity = 1; this.initDelayedCursor(); @@ -11745,25 +11797,19 @@ fabric.util.object.extend(fabric.IText.prototype, { this._updateTextarea(); } }, - moveCursorUpWithShift: function(offset) { - if (this.selectionEnd === this.selectionStart) { - this._selectionDirection = "left"; - } - if (this._selectionDirection === "right") { - this.selectionEnd -= offset; - } else { - this.selectionStart -= offset; - } - if (this.selectionEnd < this.selectionStart && this._selectionDirection === "right") { - this.swapSelectionPoints(); - this._selectionDirection = "left"; - } + moveCursorWithShift: function(offset) { + var newSelection = this._selectionDirection === "left" ? this.selectionStart + offset : this.selectionEnd + offset; + this.setSelectionStartEndWithShift(this.selectionStart, this.selectionEnd, newSelection); return offset !== 0; }, - moveCursorUpWithoutShift: function(offset) { - this._selectionDirection = "left"; - this.selectionStart -= offset; - this.selectionEnd = this.selectionStart; + moveCursorWithoutShift: function(offset) { + if (offset < 0) { + this.selectionStart += offset; + this.selectionEnd = this.selectionStart; + } else { + this.selectionEnd += offset; + this.selectionStart = this.selectionEnd; + } return offset !== 0; }, moveCursorLeft: function(e) { @@ -11939,7 +11985,7 @@ fabric.util.object.extend(fabric.IText.prototype, { fabric.Textbox = fabric.util.createClass(fabric.IText, fabric.Observable, { type: "textbox", minWidth: 20, - dynamicMinWidth: 0, + dynamicMinWidth: 2, __cachedLines: null, lockScalingY: true, lockScalingFlip: true, @@ -11968,11 +12014,11 @@ fabric.util.object.extend(fabric.IText.prototype, { _generateStyleMap: function() { var realLineCount = 0, realLineCharCount = 0, charCount = 0, map = {}; for (var i = 0; i < this._textLines.length; i++) { - if (this.text[charCount] === "\n") { + if (this.text[charCount] === "\n" && i > 0) { realLineCharCount = 0; charCount++; realLineCount++; - } else if (this.text[charCount] === " ") { + } else if (this.text[charCount] === " " && i > 0) { realLineCharCount++; charCount++; } @@ -12135,8 +12181,10 @@ fabric.util.object.extend(fabric.IText.prototype, { }); } }); - fabric.Textbox.fromObject = function(object) { - return new fabric.Textbox(object.text, clone(object)); + fabric.Textbox.fromObject = function(object, callback) { + var textbox = new fabric.Textbox(object.text, clone(object)); + callback && callback(textbox); + return textbox; }; fabric.Textbox.getTextboxControlVisibility = function() { return { @@ -12348,37 +12396,55 @@ fabric.util.object.extend(fabric.IText.prototype, { canvasEl.style = {}; canvasEl.width = nodeCanvas.width; canvasEl.height = nodeCanvas.height; + options = options || {}; + options.nodeCanvas = nodeCanvas; + options.nodeCacheCanvas = nodeCacheCanvas; var FabricCanvas = fabric.Canvas || fabric.StaticCanvas, fabricCanvas = new FabricCanvas(canvasEl, options); - fabricCanvas.contextContainer = nodeCanvas.getContext("2d"); fabricCanvas.nodeCanvas = nodeCanvas; - fabricCanvas.contextCache = nodeCacheCanvas.getContext("2d"); fabricCanvas.nodeCacheCanvas = nodeCacheCanvas; + fabricCanvas.contextContainer = nodeCanvas.getContext("2d"); + fabricCanvas.contextCache = nodeCacheCanvas.getContext("2d"); fabricCanvas.Font = Canvas.Font; return fabricCanvas; }; + var originaInitStatic = fabric.StaticCanvas.prototype._initStatic; + fabric.StaticCanvas.prototype._initStatic = function(el, options) { + el = el || fabric.document.createElement("canvas"); + this.nodeCanvas = new Canvas(el.width, el.height); + this.nodeCacheCanvas = new Canvas(el.width, el.height); + originaInitStatic.call(this, el, options); + this.contextContainer = this.nodeCanvas.getContext("2d"); + this.contextCache = this.nodeCacheCanvas.getContext("2d"); + this.Font = Canvas.Font; + }; fabric.StaticCanvas.prototype.createPNGStream = function() { return this.nodeCanvas.createPNGStream(); }; fabric.StaticCanvas.prototype.createJPEGStream = function(opts) { return this.nodeCanvas.createJPEGStream(opts); }; - var origSetWidth = fabric.StaticCanvas.prototype.setWidth; - fabric.StaticCanvas.prototype.setWidth = function(width, options) { - origSetWidth.call(this, width, options); - this.nodeCanvas.width = width; + fabric.StaticCanvas.prototype._initRetinaScaling = function() { + if (!this._isRetinaScaling()) { + return; + } + this.lowerCanvasEl.setAttribute("width", this.width * fabric.devicePixelRatio); + this.lowerCanvasEl.setAttribute("height", this.height * fabric.devicePixelRatio); + this.nodeCanvas.width = this.width * fabric.devicePixelRatio; + this.nodeCanvas.height = this.height * fabric.devicePixelRatio; + this.contextContainer.scale(fabric.devicePixelRatio, fabric.devicePixelRatio); return this; }; if (fabric.Canvas) { - fabric.Canvas.prototype.setWidth = fabric.StaticCanvas.prototype.setWidth; + fabric.Canvas.prototype._initRetinaScaling = fabric.StaticCanvas.prototype._initRetinaScaling; } - var origSetHeight = fabric.StaticCanvas.prototype.setHeight; - fabric.StaticCanvas.prototype.setHeight = function(height, options) { - origSetHeight.call(this, height, options); - this.nodeCanvas.height = height; + var origSetBackstoreDimension = fabric.StaticCanvas.prototype._setBackstoreDimension; + fabric.StaticCanvas.prototype._setBackstoreDimension = function(prop, value) { + origSetBackstoreDimension.call(this, prop, value); + this.nodeCanvas[prop] = value; return this; }; if (fabric.Canvas) { - fabric.Canvas.prototype.setHeight = fabric.StaticCanvas.prototype.setHeight; + fabric.Canvas.prototype._setBackstoreDimension = fabric.StaticCanvas.prototype._setBackstoreDimension; } })(); diff --git a/package.json b/package.json index e2ca924a..cae5715c 100644 --- a/package.json +++ b/package.json @@ -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": "1.6.4", + "version": "1.6.5", "author": "Juriy Zaytsev ", "contributors": [ { diff --git a/src/mixins/collection.mixin.js b/src/mixins/collection.mixin.js index 34cef890..fbd7ae11 100644 --- a/src/mixins/collection.mixin.js +++ b/src/mixins/collection.mixin.js @@ -6,7 +6,9 @@ fabric.Collection = { _objects: [], /** - * Adds objects to collection, then renders canvas (if `renderOnAddRemove` is not `false`) + * Adds objects to collection, Canvas or Group, then renders canvas + * (if `renderOnAddRemove` is not `false`). + * in case of Group no changes to bounding box are made. * Objects should be instances of (or inherit from) fabric.Object * @param {...fabric.Object} object Zero or more fabric instances * @return {Self} thisArg diff --git a/src/shapes/itext.class.js b/src/shapes/itext.class.js index 9f711873..f8ea01ba 100644 --- a/src/shapes/itext.class.js +++ b/src/shapes/itext.class.js @@ -888,6 +888,7 @@ styleDeclaration.scaleX = this.scaleX; styleDeclaration.scaleY = this.scaleY; styleDeclaration.canvas = this.canvas; + styleDeclaration.getObjectScaling = this.getObjectScaling; this._setShadow.call(styleDeclaration, ctx); }