28cd9b1fc703cb8b2a3d470dd76aa3e3.json
2.66 MB
{"ast":null,"code":"/* build: `node build.js modules=ALL exclude=gestures,accessors requirejs minifier=uglifyjs` */\n\n/*! Fabric.js Copyright 2008-2015, Printio (Juriy Zaytsev, Maxim Chernyak) */\nvar fabric = fabric || {\n version: '4.2.0'\n};\n\nif (typeof exports !== 'undefined') {\n exports.fabric = fabric;\n}\n/* _AMD_START_ */\nelse if (typeof define === 'function' && define.amd) {\n define([], function () {\n return fabric;\n });\n }\n/* _AMD_END_ */\n\n\nif (typeof document !== 'undefined' && typeof window !== 'undefined') {\n if (document instanceof (typeof HTMLDocument !== 'undefined' ? HTMLDocument : Document)) {\n fabric.document = document;\n } else {\n fabric.document = document.implementation.createHTMLDocument('');\n }\n\n fabric.window = window;\n} else {\n // assume we're running under node.js when document/window are not present\n var jsdom = require('jsdom');\n\n var virtualWindow = new jsdom.JSDOM(decodeURIComponent('%3C!DOCTYPE%20html%3E%3Chtml%3E%3Chead%3E%3C%2Fhead%3E%3Cbody%3E%3C%2Fbody%3E%3C%2Fhtml%3E'), {\n features: {\n FetchExternalResources: ['img']\n },\n resources: 'usable'\n }).window;\n fabric.document = virtualWindow.document;\n fabric.jsdomImplForWrapper = require('jsdom/lib/jsdom/living/generated/utils').implForWrapper;\n fabric.nodeCanvas = require('jsdom/lib/jsdom/utils').Canvas;\n fabric.window = virtualWindow;\n DOMParser = fabric.window.DOMParser;\n}\n/**\n * True when in environment that supports touch events\n * @type boolean\n */\n\n\nfabric.isTouchSupported = 'ontouchstart' in fabric.window || 'ontouchstart' in fabric.document || fabric.window && fabric.window.navigator && fabric.window.navigator.maxTouchPoints > 0;\n/**\n * True when in environment that's probably Node.js\n * @type boolean\n */\n\nfabric.isLikelyNode = typeof Buffer !== 'undefined' && typeof window === 'undefined';\n/* _FROM_SVG_START_ */\n\n/**\n * Attributes parsed from all SVG elements\n * @type array\n */\n\nfabric.SHARED_ATTRIBUTES = ['display', 'transform', 'fill', 'fill-opacity', 'fill-rule', 'opacity', 'stroke', 'stroke-dasharray', 'stroke-linecap', 'stroke-dashoffset', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'id', 'paint-order', 'vector-effect', 'instantiated_by_use', 'clip-path'];\n/* _FROM_SVG_END_ */\n\n/**\n * Pixel per Inch as a default value set to 96. Can be changed for more realistic conversion.\n */\n\nfabric.DPI = 96;\nfabric.reNum = '(?:[-+]?(?:\\\\d+|\\\\d*\\\\.\\\\d+)(?:[eE][-+]?\\\\d+)?)';\nfabric.commaWsp = '(?:\\\\s+,?\\\\s*|,\\\\s*)';\nfabric.rePathCommand = /([-+]?((\\d+\\.\\d+)|((\\d+)|(\\.\\d+)))(?:[eE][-+]?\\d+)?)/ig;\nfabric.reNonWord = /[ \\n\\.,;!\\?\\-]/;\nfabric.fontPaths = {};\nfabric.iMatrix = [1, 0, 0, 1, 0, 0];\nfabric.svgNS = 'http://www.w3.org/2000/svg';\n/**\n * Pixel limit for cache canvases. 1Mpx , 4Mpx should be fine.\n * @since 1.7.14\n * @type Number\n * @default\n */\n\nfabric.perfLimitSizeTotal = 2097152;\n/**\n * Pixel limit for cache canvases width or height. IE fixes the maximum at 5000\n * @since 1.7.14\n * @type Number\n * @default\n */\n\nfabric.maxCacheSideLimit = 4096;\n/**\n * Lowest pixel limit for cache canvases, set at 256PX\n * @since 1.7.14\n * @type Number\n * @default\n */\n\nfabric.minCacheSideLimit = 256;\n/**\n * Cache Object for widths of chars in text rendering.\n */\n\nfabric.charWidthsCache = {};\n/**\n * if webgl is enabled and available, textureSize will determine the size\n * of the canvas backend\n * @since 2.0.0\n * @type Number\n * @default\n */\n\nfabric.textureSize = 2048;\n/**\n * When 'true', style information is not retained when copy/pasting text, making\n * pasted text use destination style.\n * Defaults to 'false'.\n * @type Boolean\n * @default\n */\n\nfabric.disableStyleCopyPaste = false;\n/**\n * Enable webgl for filtering picture is available\n * A filtering backend will be initialized, this will both take memory and\n * time since a default 2048x2048 canvas will be created for the gl context\n * @since 2.0.0\n * @type Boolean\n * @default\n */\n\nfabric.enableGLFiltering = true;\n/**\n * Device Pixel Ratio\n * @see https://developer.apple.com/library/safari/documentation/AudioVideo/Conceptual/HTML-canvas-guide/SettingUptheCanvas/SettingUptheCanvas.html\n */\n\nfabric.devicePixelRatio = fabric.window.devicePixelRatio || fabric.window.webkitDevicePixelRatio || fabric.window.mozDevicePixelRatio || 1;\n/**\n * Browser-specific constant to adjust CanvasRenderingContext2D.shadowBlur value,\n * which is unitless and not rendered equally across browsers.\n *\n * Values that work quite well (as of October 2017) are:\n * - Chrome: 1.5\n * - Edge: 1.75\n * - Firefox: 0.9\n * - Safari: 0.95\n *\n * @since 2.0.0\n * @type Number\n * @default 1\n */\n\nfabric.browserShadowBlurConstant = 1;\n/**\n * This object contains the result of arc to beizer conversion for faster retrieving if the same arc needs to be converted again.\n * It was an internal variable, is accessible since version 2.3.4\n */\n\nfabric.arcToSegmentsCache = {};\n/**\n * This object keeps the results of the boundsOfCurve calculation mapped by the joined arguments necessary to calculate it.\n * It does speed up calculation, if you parse and add always the same paths, but in case of heavy usage of freedrawing\n * you do not get any speed benefit and you get a big object in memory.\n * The object was a private variable before, while now is appended to the lib so that you have access to it and you\n * can eventually clear it.\n * It was an internal variable, is accessible since version 2.3.4\n */\n\nfabric.boundsOfCurveCache = {};\n/**\n * If disabled boundsOfCurveCache is not used. For apps that make heavy usage of pencil drawing probably disabling it is better\n * @default true\n */\n\nfabric.cachesBoundsOfCurve = true;\n/**\n * Skip performance testing of setupGLContext and force the use of putImageData that seems to be the one that works best on\n * Chrome + old hardware. if your users are experiencing empty images after filtering you may try to force this to true\n * this has to be set before instantiating the filtering backend ( before filtering the first image )\n * @type Boolean\n * @default false\n */\n\nfabric.forceGLPutImageData = false;\n\nfabric.initFilterBackend = function () {\n if (fabric.enableGLFiltering && fabric.isWebglSupported && fabric.isWebglSupported(fabric.textureSize)) {\n console.log('max texture size: ' + fabric.maxTextureSize);\n return new fabric.WebglFilterBackend({\n tileSize: fabric.textureSize\n });\n } else if (fabric.Canvas2dFilterBackend) {\n return new fabric.Canvas2dFilterBackend();\n }\n};\n\nif (typeof document !== 'undefined' && typeof window !== 'undefined') {\n // ensure globality even if entire library were function wrapped (as in Meteor.js packaging system)\n window.fabric = fabric;\n}\n\n(function () {\n /**\n * @private\n * @param {String} eventName\n * @param {Function} handler\n */\n function _removeEventListener(eventName, handler) {\n if (!this.__eventListeners[eventName]) {\n return;\n }\n\n var eventListener = this.__eventListeners[eventName];\n\n if (handler) {\n eventListener[eventListener.indexOf(handler)] = false;\n } else {\n fabric.util.array.fill(eventListener, false);\n }\n }\n /**\n * Observes specified event\n * @memberOf fabric.Observable\n * @alias on\n * @param {String|Object} eventName Event name (eg. 'after:render') or object with key/value pairs (eg. {'after:render': handler, 'selection:cleared': handler})\n * @param {Function} handler Function that receives a notification when an event of the specified type occurs\n * @return {Self} thisArg\n * @chainable\n */\n\n\n function on(eventName, handler) {\n if (!this.__eventListeners) {\n this.__eventListeners = {};\n } // one object with key/value pairs was passed\n\n\n if (arguments.length === 1) {\n for (var prop in eventName) {\n this.on(prop, eventName[prop]);\n }\n } else {\n if (!this.__eventListeners[eventName]) {\n this.__eventListeners[eventName] = [];\n }\n\n this.__eventListeners[eventName].push(handler);\n }\n\n return this;\n }\n /**\n * Stops event observing for a particular event handler. Calling this method\n * without arguments removes all handlers for all events\n * @memberOf fabric.Observable\n * @alias off\n * @param {String|Object} eventName Event name (eg. 'after:render') or object with key/value pairs (eg. {'after:render': handler, 'selection:cleared': handler})\n * @param {Function} handler Function to be deleted from EventListeners\n * @return {Self} thisArg\n * @chainable\n */\n\n\n function off(eventName, handler) {\n if (!this.__eventListeners) {\n return this;\n } // remove all key/value pairs (event name -> event handler)\n\n\n if (arguments.length === 0) {\n for (eventName in this.__eventListeners) {\n _removeEventListener.call(this, eventName);\n }\n } // one object with key/value pairs was passed\n else if (arguments.length === 1 && typeof arguments[0] === 'object') {\n for (var prop in eventName) {\n _removeEventListener.call(this, prop, eventName[prop]);\n }\n } else {\n _removeEventListener.call(this, eventName, handler);\n }\n\n return this;\n }\n /**\n * Fires event with an optional options object\n * @memberOf fabric.Observable\n * @param {String} eventName Event name to fire\n * @param {Object} [options] Options object\n * @return {Self} thisArg\n * @chainable\n */\n\n\n function fire(eventName, options) {\n if (!this.__eventListeners) {\n return this;\n }\n\n var listenersForEvent = this.__eventListeners[eventName];\n\n if (!listenersForEvent) {\n return this;\n }\n\n for (var i = 0, len = listenersForEvent.length; i < len; i++) {\n listenersForEvent[i] && listenersForEvent[i].call(this, options || {});\n }\n\n this.__eventListeners[eventName] = listenersForEvent.filter(function (value) {\n return value !== false;\n });\n return this;\n }\n /**\n * @namespace fabric.Observable\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#events}\n * @see {@link http://fabricjs.com/events|Events demo}\n */\n\n\n fabric.Observable = {\n fire: fire,\n on: on,\n off: off\n };\n})();\n/**\n * @namespace fabric.Collection\n */\n\n\nfabric.Collection = {\n _objects: [],\n\n /**\n * Adds objects to collection, Canvas or Group, then renders canvas\n * (if `renderOnAddRemove` is not `false`).\n * in case of Group no changes to bounding box are made.\n * Objects should be instances of (or inherit from) fabric.Object\n * Use of this function is highly discouraged for groups.\n * you can add a bunch of objects with the add method but then you NEED\n * to run a addWithUpdate call for the Group class or position/bbox will be wrong.\n * @param {...fabric.Object} object Zero or more fabric instances\n * @return {Self} thisArg\n * @chainable\n */\n add: function () {\n this._objects.push.apply(this._objects, arguments);\n\n if (this._onObjectAdded) {\n for (var i = 0, length = arguments.length; i < length; i++) {\n this._onObjectAdded(arguments[i]);\n }\n }\n\n this.renderOnAddRemove && this.requestRenderAll();\n return this;\n },\n\n /**\n * Inserts an object into collection at specified index, then renders canvas (if `renderOnAddRemove` is not `false`)\n * An object should be an instance of (or inherit from) fabric.Object\n * Use of this function is highly discouraged for groups.\n * you can add a bunch of objects with the insertAt method but then you NEED\n * to run a addWithUpdate call for the Group class or position/bbox will be wrong.\n * @param {Object} object Object to insert\n * @param {Number} index Index to insert object at\n * @param {Boolean} nonSplicing When `true`, no splicing (shifting) of objects occurs\n * @return {Self} thisArg\n * @chainable\n */\n insertAt: function (object, index, nonSplicing) {\n var objects = this._objects;\n\n if (nonSplicing) {\n objects[index] = object;\n } else {\n objects.splice(index, 0, object);\n }\n\n this._onObjectAdded && this._onObjectAdded(object);\n this.renderOnAddRemove && this.requestRenderAll();\n return this;\n },\n\n /**\n * Removes objects from a collection, then renders canvas (if `renderOnAddRemove` is not `false`)\n * @param {...fabric.Object} object Zero or more fabric instances\n * @return {Self} thisArg\n * @chainable\n */\n remove: function () {\n var objects = this._objects,\n index,\n somethingRemoved = false;\n\n for (var i = 0, length = arguments.length; i < length; i++) {\n index = objects.indexOf(arguments[i]); // only call onObjectRemoved if an object was actually removed\n\n if (index !== -1) {\n somethingRemoved = true;\n objects.splice(index, 1);\n this._onObjectRemoved && this._onObjectRemoved(arguments[i]);\n }\n }\n\n this.renderOnAddRemove && somethingRemoved && this.requestRenderAll();\n return this;\n },\n\n /**\n * Executes given function for each object in this group\n * @param {Function} callback\n * Callback invoked with current object as first argument,\n * index - as second and an array of all objects - as third.\n * Callback is invoked in a context of Global Object (e.g. `window`)\n * when no `context` argument is given\n *\n * @param {Object} context Context (aka thisObject)\n * @return {Self} thisArg\n * @chainable\n */\n forEachObject: function (callback, context) {\n var objects = this.getObjects();\n\n for (var i = 0, len = objects.length; i < len; i++) {\n callback.call(context, objects[i], i, objects);\n }\n\n return this;\n },\n\n /**\n * Returns an array of children objects of this instance\n * Type parameter introduced in 1.3.10\n * since 2.3.5 this method return always a COPY of the array;\n * @param {String} [type] When specified, only objects of this type are returned\n * @return {Array}\n */\n getObjects: function (type) {\n if (typeof type === 'undefined') {\n return this._objects.concat();\n }\n\n return this._objects.filter(function (o) {\n return o.type === type;\n });\n },\n\n /**\n * Returns object at specified index\n * @param {Number} index\n * @return {Self} thisArg\n */\n item: function (index) {\n return this._objects[index];\n },\n\n /**\n * Returns true if collection contains no objects\n * @return {Boolean} true if collection is empty\n */\n isEmpty: function () {\n return this._objects.length === 0;\n },\n\n /**\n * Returns a size of a collection (i.e: length of an array containing its objects)\n * @return {Number} Collection size\n */\n size: function () {\n return this._objects.length;\n },\n\n /**\n * Returns true if collection contains an object\n * @param {Object} object Object to check against\n * @return {Boolean} `true` if collection contains an object\n */\n contains: function (object) {\n return this._objects.indexOf(object) > -1;\n },\n\n /**\n * Returns number representation of a collection complexity\n * @return {Number} complexity\n */\n complexity: function () {\n return this._objects.reduce(function (memo, current) {\n memo += current.complexity ? current.complexity() : 0;\n return memo;\n }, 0);\n }\n};\n/**\n * @namespace fabric.CommonMethods\n */\n\nfabric.CommonMethods = {\n /**\n * Sets object's properties from options\n * @param {Object} [options] Options object\n */\n _setOptions: function (options) {\n for (var prop in options) {\n this.set(prop, options[prop]);\n }\n },\n\n /**\n * @private\n * @param {Object} [filler] Options object\n * @param {String} [property] property to set the Gradient to\n */\n _initGradient: function (filler, property) {\n if (filler && filler.colorStops && !(filler instanceof fabric.Gradient)) {\n this.set(property, new fabric.Gradient(filler));\n }\n },\n\n /**\n * @private\n * @param {Object} [filler] Options object\n * @param {String} [property] property to set the Pattern to\n * @param {Function} [callback] callback to invoke after pattern load\n */\n _initPattern: function (filler, property, callback) {\n if (filler && filler.source && !(filler instanceof fabric.Pattern)) {\n this.set(property, new fabric.Pattern(filler, callback));\n } else {\n callback && callback();\n }\n },\n\n /**\n * @private\n */\n _setObject: function (obj) {\n for (var prop in obj) {\n this._set(prop, obj[prop]);\n }\n },\n\n /**\n * Sets property to a given value. When changing position/dimension -related properties (left, top, scale, angle, etc.) `set` does not update position of object's borders/controls. If you need to update those, call `setCoords()`.\n * @param {String|Object} key Property name or object (if object, iterate over the object properties)\n * @param {Object|Function} value Property value (if function, the value is passed into it and its return value is used as a new one)\n * @return {fabric.Object} thisArg\n * @chainable\n */\n set: function (key, value) {\n if (typeof key === 'object') {\n this._setObject(key);\n } else {\n this._set(key, value);\n }\n\n return this;\n },\n _set: function (key, value) {\n this[key] = value;\n },\n\n /**\n * Toggles specified property from `true` to `false` or from `false` to `true`\n * @param {String} property Property to toggle\n * @return {fabric.Object} thisArg\n * @chainable\n */\n toggle: function (property) {\n var value = this.get(property);\n\n if (typeof value === 'boolean') {\n this.set(property, !value);\n }\n\n return this;\n },\n\n /**\n * Basic getter\n * @param {String} property Property name\n * @return {*} value of a property\n */\n get: function (property) {\n return this[property];\n }\n};\n\n(function (global) {\n var sqrt = Math.sqrt,\n atan2 = Math.atan2,\n pow = Math.pow,\n PiBy180 = Math.PI / 180,\n PiBy2 = Math.PI / 2;\n /**\n * @namespace fabric.util\n */\n\n fabric.util = {\n /**\n * Calculate the cos of an angle, avoiding returning floats for known results\n * @static\n * @memberOf fabric.util\n * @param {Number} angle the angle in radians or in degree\n * @return {Number}\n */\n cos: function (angle) {\n if (angle === 0) {\n return 1;\n }\n\n if (angle < 0) {\n // cos(a) = cos(-a)\n angle = -angle;\n }\n\n var angleSlice = angle / PiBy2;\n\n switch (angleSlice) {\n case 1:\n case 3:\n return 0;\n\n case 2:\n return -1;\n }\n\n return Math.cos(angle);\n },\n\n /**\n * Calculate the sin of an angle, avoiding returning floats for known results\n * @static\n * @memberOf fabric.util\n * @param {Number} angle the angle in radians or in degree\n * @return {Number}\n */\n sin: function (angle) {\n if (angle === 0) {\n return 0;\n }\n\n var angleSlice = angle / PiBy2,\n sign = 1;\n\n if (angle < 0) {\n // sin(-a) = -sin(a)\n sign = -1;\n }\n\n switch (angleSlice) {\n case 1:\n return sign;\n\n case 2:\n return 0;\n\n case 3:\n return -sign;\n }\n\n return Math.sin(angle);\n },\n\n /**\n * Removes value from an array.\n * Presence of value (and its position in an array) is determined via `Array.prototype.indexOf`\n * @static\n * @memberOf fabric.util\n * @param {Array} array\n * @param {*} value\n * @return {Array} original array\n */\n removeFromArray: function (array, value) {\n var idx = array.indexOf(value);\n\n if (idx !== -1) {\n array.splice(idx, 1);\n }\n\n return array;\n },\n\n /**\n * Returns random number between 2 specified ones.\n * @static\n * @memberOf fabric.util\n * @param {Number} min lower limit\n * @param {Number} max upper limit\n * @return {Number} random value (between min and max)\n */\n getRandomInt: function (min, max) {\n return Math.floor(Math.random() * (max - min + 1)) + min;\n },\n\n /**\n * Transforms degrees to radians.\n * @static\n * @memberOf fabric.util\n * @param {Number} degrees value in degrees\n * @return {Number} value in radians\n */\n degreesToRadians: function (degrees) {\n return degrees * PiBy180;\n },\n\n /**\n * Transforms radians to degrees.\n * @static\n * @memberOf fabric.util\n * @param {Number} radians value in radians\n * @return {Number} value in degrees\n */\n radiansToDegrees: function (radians) {\n return radians / PiBy180;\n },\n\n /**\n * Rotates `point` around `origin` with `radians`\n * @static\n * @memberOf fabric.util\n * @param {fabric.Point} point The point to rotate\n * @param {fabric.Point} origin The origin of the rotation\n * @param {Number} radians The radians of the angle for the rotation\n * @return {fabric.Point} The new rotated point\n */\n rotatePoint: function (point, origin, radians) {\n point.subtractEquals(origin);\n var v = fabric.util.rotateVector(point, radians);\n return new fabric.Point(v.x, v.y).addEquals(origin);\n },\n\n /**\n * Rotates `vector` with `radians`\n * @static\n * @memberOf fabric.util\n * @param {Object} vector The vector to rotate (x and y)\n * @param {Number} radians The radians of the angle for the rotation\n * @return {Object} The new rotated point\n */\n rotateVector: function (vector, radians) {\n var sin = fabric.util.sin(radians),\n cos = fabric.util.cos(radians),\n rx = vector.x * cos - vector.y * sin,\n ry = vector.x * sin + vector.y * cos;\n return {\n x: rx,\n y: ry\n };\n },\n\n /**\n * Apply transform t to point p\n * @static\n * @memberOf fabric.util\n * @param {fabric.Point} p The point to transform\n * @param {Array} t The transform\n * @param {Boolean} [ignoreOffset] Indicates that the offset should not be applied\n * @return {fabric.Point} The transformed point\n */\n transformPoint: function (p, t, ignoreOffset) {\n if (ignoreOffset) {\n return new fabric.Point(t[0] * p.x + t[2] * p.y, t[1] * p.x + t[3] * p.y);\n }\n\n return new fabric.Point(t[0] * p.x + t[2] * p.y + t[4], t[1] * p.x + t[3] * p.y + t[5]);\n },\n\n /**\n * Returns coordinates of points's bounding rectangle (left, top, width, height)\n * @param {Array} points 4 points array\n * @param {Array} [transform] an array of 6 numbers representing a 2x3 transform matrix\n * @return {Object} Object with left, top, width, height properties\n */\n makeBoundingBoxFromPoints: function (points, transform) {\n if (transform) {\n for (var i = 0; i < points.length; i++) {\n points[i] = fabric.util.transformPoint(points[i], transform);\n }\n }\n\n var xPoints = [points[0].x, points[1].x, points[2].x, points[3].x],\n minX = fabric.util.array.min(xPoints),\n maxX = fabric.util.array.max(xPoints),\n width = maxX - minX,\n yPoints = [points[0].y, points[1].y, points[2].y, points[3].y],\n minY = fabric.util.array.min(yPoints),\n maxY = fabric.util.array.max(yPoints),\n height = maxY - minY;\n return {\n left: minX,\n top: minY,\n width: width,\n height: height\n };\n },\n\n /**\n * Invert transformation t\n * @static\n * @memberOf fabric.util\n * @param {Array} t The transform\n * @return {Array} The inverted transform\n */\n invertTransform: function (t) {\n var a = 1 / (t[0] * t[3] - t[1] * t[2]),\n r = [a * t[3], -a * t[1], -a * t[2], a * t[0]],\n o = fabric.util.transformPoint({\n x: t[4],\n y: t[5]\n }, r, true);\n r[4] = -o.x;\n r[5] = -o.y;\n return r;\n },\n\n /**\n * A wrapper around Number#toFixed, which contrary to native method returns number, not string.\n * @static\n * @memberOf fabric.util\n * @param {Number|String} number number to operate on\n * @param {Number} fractionDigits number of fraction digits to \"leave\"\n * @return {Number}\n */\n toFixed: function (number, fractionDigits) {\n return parseFloat(Number(number).toFixed(fractionDigits));\n },\n\n /**\n * Converts from attribute value to pixel value if applicable.\n * Returns converted pixels or original value not converted.\n * @param {Number|String} value number to operate on\n * @param {Number} fontSize\n * @return {Number|String}\n */\n parseUnit: function (value, fontSize) {\n var unit = /\\D{0,2}$/.exec(value),\n number = parseFloat(value);\n\n if (!fontSize) {\n fontSize = fabric.Text.DEFAULT_SVG_FONT_SIZE;\n }\n\n switch (unit[0]) {\n case 'mm':\n return number * fabric.DPI / 25.4;\n\n case 'cm':\n return number * fabric.DPI / 2.54;\n\n case 'in':\n return number * fabric.DPI;\n\n case 'pt':\n return number * fabric.DPI / 72;\n // or * 4 / 3\n\n case 'pc':\n return number * fabric.DPI / 72 * 12;\n // or * 16\n\n case 'em':\n return number * fontSize;\n\n default:\n return number;\n }\n },\n\n /**\n * Function which always returns `false`.\n * @static\n * @memberOf fabric.util\n * @return {Boolean}\n */\n falseFunction: function () {\n return false;\n },\n\n /**\n * Returns klass \"Class\" object of given namespace\n * @memberOf fabric.util\n * @param {String} type Type of object (eg. 'circle')\n * @param {String} namespace Namespace to get klass \"Class\" object from\n * @return {Object} klass \"Class\"\n */\n getKlass: function (type, namespace) {\n // capitalize first letter only\n type = fabric.util.string.camelize(type.charAt(0).toUpperCase() + type.slice(1));\n return fabric.util.resolveNamespace(namespace)[type];\n },\n\n /**\n * Returns array of attributes for given svg that fabric parses\n * @memberOf fabric.util\n * @param {String} type Type of svg element (eg. 'circle')\n * @return {Array} string names of supported attributes\n */\n getSvgAttributes: function (type) {\n var attributes = ['instantiated_by_use', 'style', 'id', 'class'];\n\n switch (type) {\n case 'linearGradient':\n attributes = attributes.concat(['x1', 'y1', 'x2', 'y2', 'gradientUnits', 'gradientTransform']);\n break;\n\n case 'radialGradient':\n attributes = attributes.concat(['gradientUnits', 'gradientTransform', 'cx', 'cy', 'r', 'fx', 'fy', 'fr']);\n break;\n\n case 'stop':\n attributes = attributes.concat(['offset', 'stop-color', 'stop-opacity']);\n break;\n }\n\n return attributes;\n },\n\n /**\n * Returns object of given namespace\n * @memberOf fabric.util\n * @param {String} namespace Namespace string e.g. 'fabric.Image.filter' or 'fabric'\n * @return {Object} Object for given namespace (default fabric)\n */\n resolveNamespace: function (namespace) {\n if (!namespace) {\n return fabric;\n }\n\n var parts = namespace.split('.'),\n len = parts.length,\n i,\n obj = global || fabric.window;\n\n for (i = 0; i < len; ++i) {\n obj = obj[parts[i]];\n }\n\n return obj;\n },\n\n /**\n * Loads image element from given url and passes it to a callback\n * @memberOf fabric.util\n * @param {String} url URL representing an image\n * @param {Function} callback Callback; invoked with loaded image\n * @param {*} [context] Context to invoke callback in\n * @param {Object} [crossOrigin] crossOrigin value to set image element to\n */\n loadImage: function (url, callback, context, crossOrigin) {\n if (!url) {\n callback && callback.call(context, url);\n return;\n }\n\n var img = fabric.util.createImage();\n /** @ignore */\n\n var onLoadCallback = function () {\n callback && callback.call(context, img, false);\n img = img.onload = img.onerror = null;\n };\n\n img.onload = onLoadCallback;\n /** @ignore */\n\n img.onerror = function () {\n fabric.log('Error loading ' + img.src);\n callback && callback.call(context, null, true);\n img = img.onload = img.onerror = null;\n }; // data-urls appear to be buggy with crossOrigin\n // https://github.com/kangax/fabric.js/commit/d0abb90f1cd5c5ef9d2a94d3fb21a22330da3e0a#commitcomment-4513767\n // see https://code.google.com/p/chromium/issues/detail?id=315152\n // https://bugzilla.mozilla.org/show_bug.cgi?id=935069\n // crossOrigin null is the same as not set.\n\n\n if (url.indexOf('data') !== 0 && crossOrigin !== undefined && crossOrigin !== null) {\n img.crossOrigin = crossOrigin;\n } // IE10 / IE11-Fix: SVG contents from data: URI\n // will only be available if the IMG is present\n // in the DOM (and visible)\n\n\n if (url.substring(0, 14) === 'data:image/svg') {\n img.onload = null;\n fabric.util.loadImageInDom(img, onLoadCallback);\n }\n\n img.src = url;\n },\n\n /**\n * Attaches SVG image with data: URL to the dom\n * @memberOf fabric.util\n * @param {Object} img Image object with data:image/svg src\n * @param {Function} callback Callback; invoked with loaded image\n * @return {Object} DOM element (div containing the SVG image)\n */\n loadImageInDom: function (img, onLoadCallback) {\n var div = fabric.document.createElement('div');\n div.style.width = div.style.height = '1px';\n div.style.left = div.style.top = '-100%';\n div.style.position = 'absolute';\n div.appendChild(img);\n fabric.document.querySelector('body').appendChild(div);\n /**\n * Wrap in function to:\n * 1. Call existing callback\n * 2. Cleanup DOM\n */\n\n img.onload = function () {\n onLoadCallback();\n div.parentNode.removeChild(div);\n div = null;\n };\n },\n\n /**\n * Creates corresponding fabric instances from their object representations\n * @static\n * @memberOf fabric.util\n * @param {Array} objects Objects to enliven\n * @param {Function} callback Callback to invoke when all objects are created\n * @param {String} namespace Namespace to get klass \"Class\" object from\n * @param {Function} reviver Method for further parsing of object elements,\n * called after each fabric object created.\n */\n enlivenObjects: function (objects, callback, namespace, reviver) {\n objects = objects || [];\n var enlivenedObjects = [],\n numLoadedObjects = 0,\n numTotalObjects = objects.length;\n\n function onLoaded() {\n if (++numLoadedObjects === numTotalObjects) {\n callback && callback(enlivenedObjects.filter(function (obj) {\n // filter out undefined objects (objects that gave error)\n return obj;\n }));\n }\n }\n\n if (!numTotalObjects) {\n callback && callback(enlivenedObjects);\n return;\n }\n\n objects.forEach(function (o, index) {\n // if sparse array\n if (!o || !o.type) {\n onLoaded();\n return;\n }\n\n var klass = fabric.util.getKlass(o.type, namespace);\n klass.fromObject(o, function (obj, error) {\n error || (enlivenedObjects[index] = obj);\n reviver && reviver(o, obj, error);\n onLoaded();\n });\n });\n },\n\n /**\n * Create and wait for loading of patterns\n * @static\n * @memberOf fabric.util\n * @param {Array} patterns Objects to enliven\n * @param {Function} callback Callback to invoke when all objects are created\n * called after each fabric object created.\n */\n enlivenPatterns: function (patterns, callback) {\n patterns = patterns || [];\n\n function onLoaded() {\n if (++numLoadedPatterns === numPatterns) {\n callback && callback(enlivenedPatterns);\n }\n }\n\n var enlivenedPatterns = [],\n numLoadedPatterns = 0,\n numPatterns = patterns.length;\n\n if (!numPatterns) {\n callback && callback(enlivenedPatterns);\n return;\n }\n\n patterns.forEach(function (p, index) {\n if (p && p.source) {\n new fabric.Pattern(p, function (pattern) {\n enlivenedPatterns[index] = pattern;\n onLoaded();\n });\n } else {\n enlivenedPatterns[index] = p;\n onLoaded();\n }\n });\n },\n\n /**\n * Groups SVG elements (usually those retrieved from SVG document)\n * @static\n * @memberOf fabric.util\n * @param {Array} elements SVG elements to group\n * @param {Object} [options] Options object\n * @param {String} path Value to set sourcePath to\n * @return {fabric.Object|fabric.Group}\n */\n groupSVGElements: function (elements, options, path) {\n var object;\n\n if (elements && elements.length === 1) {\n return elements[0];\n }\n\n if (options) {\n if (options.width && options.height) {\n options.centerPoint = {\n x: options.width / 2,\n y: options.height / 2\n };\n } else {\n delete options.width;\n delete options.height;\n }\n }\n\n object = new fabric.Group(elements, options);\n\n if (typeof path !== 'undefined') {\n object.sourcePath = path;\n }\n\n return object;\n },\n\n /**\n * Populates an object with properties of another object\n * @static\n * @memberOf fabric.util\n * @param {Object} source Source object\n * @param {Object} destination Destination object\n * @return {Array} properties Properties names to include\n */\n populateWithProperties: function (source, destination, properties) {\n if (properties && Object.prototype.toString.call(properties) === '[object Array]') {\n for (var i = 0, len = properties.length; i < len; i++) {\n if (properties[i] in source) {\n destination[properties[i]] = source[properties[i]];\n }\n }\n }\n },\n\n /**\n * Draws a dashed line between two points\n *\n * This method is used to draw dashed line around selection area.\n * See <a href=\"http://stackoverflow.com/questions/4576724/dotted-stroke-in-canvas\">dotted stroke in canvas</a>\n *\n * @param {CanvasRenderingContext2D} ctx context\n * @param {Number} x start x coordinate\n * @param {Number} y start y coordinate\n * @param {Number} x2 end x coordinate\n * @param {Number} y2 end y coordinate\n * @param {Array} da dash array pattern\n */\n drawDashedLine: function (ctx, x, y, x2, y2, da) {\n var dx = x2 - x,\n dy = y2 - y,\n len = sqrt(dx * dx + dy * dy),\n rot = atan2(dy, dx),\n dc = da.length,\n di = 0,\n draw = true;\n ctx.save();\n ctx.translate(x, y);\n ctx.moveTo(0, 0);\n ctx.rotate(rot);\n x = 0;\n\n while (len > x) {\n x += da[di++ % dc];\n\n if (x > len) {\n x = len;\n }\n\n ctx[draw ? 'lineTo' : 'moveTo'](x, 0);\n draw = !draw;\n }\n\n ctx.restore();\n },\n\n /**\n * Creates canvas element\n * @static\n * @memberOf fabric.util\n * @return {CanvasElement} initialized canvas element\n */\n createCanvasElement: function () {\n return fabric.document.createElement('canvas');\n },\n\n /**\n * Creates a canvas element that is a copy of another and is also painted\n * @param {CanvasElement} canvas to copy size and content of\n * @static\n * @memberOf fabric.util\n * @return {CanvasElement} initialized canvas element\n */\n copyCanvasElement: function (canvas) {\n var newCanvas = fabric.util.createCanvasElement();\n newCanvas.width = canvas.width;\n newCanvas.height = canvas.height;\n newCanvas.getContext('2d').drawImage(canvas, 0, 0);\n return newCanvas;\n },\n\n /**\n * since 2.6.0 moved from canvas instance to utility.\n * @param {CanvasElement} canvasEl to copy size and content of\n * @param {String} format 'jpeg' or 'png', in some browsers 'webp' is ok too\n * @param {Number} quality <= 1 and > 0\n * @static\n * @memberOf fabric.util\n * @return {String} data url\n */\n toDataURL: function (canvasEl, format, quality) {\n return canvasEl.toDataURL('image/' + format, quality);\n },\n\n /**\n * Creates image element (works on client and node)\n * @static\n * @memberOf fabric.util\n * @return {HTMLImageElement} HTML image element\n */\n createImage: function () {\n return fabric.document.createElement('img');\n },\n\n /**\n * Multiply matrix A by matrix B to nest transformations\n * @static\n * @memberOf fabric.util\n * @param {Array} a First transformMatrix\n * @param {Array} b Second transformMatrix\n * @param {Boolean} is2x2 flag to multiply matrices as 2x2 matrices\n * @return {Array} The product of the two transform matrices\n */\n multiplyTransformMatrices: function (a, b, is2x2) {\n // Matrix multiply a * b\n return [a[0] * b[0] + a[2] * b[1], a[1] * b[0] + a[3] * b[1], a[0] * b[2] + a[2] * b[3], a[1] * b[2] + a[3] * b[3], is2x2 ? 0 : a[0] * b[4] + a[2] * b[5] + a[4], is2x2 ? 0 : a[1] * b[4] + a[3] * b[5] + a[5]];\n },\n\n /**\n * Decomposes standard 2x3 matrix into transform components\n * @static\n * @memberOf fabric.util\n * @param {Array} a transformMatrix\n * @return {Object} Components of transform\n */\n qrDecompose: function (a) {\n var angle = atan2(a[1], a[0]),\n denom = pow(a[0], 2) + pow(a[1], 2),\n scaleX = sqrt(denom),\n scaleY = (a[0] * a[3] - a[2] * a[1]) / scaleX,\n skewX = atan2(a[0] * a[2] + a[1] * a[3], denom);\n return {\n angle: angle / PiBy180,\n scaleX: scaleX,\n scaleY: scaleY,\n skewX: skewX / PiBy180,\n skewY: 0,\n translateX: a[4],\n translateY: a[5]\n };\n },\n\n /**\n * Returns a transform matrix starting from an object of the same kind of\n * the one returned from qrDecompose, useful also if you want to calculate some\n * transformations from an object that is not enlived yet\n * @static\n * @memberOf fabric.util\n * @param {Object} options\n * @param {Number} [options.angle] angle in degrees\n * @return {Number[]} transform matrix\n */\n calcRotateMatrix: function (options) {\n if (!options.angle) {\n return fabric.iMatrix.concat();\n }\n\n var theta = fabric.util.degreesToRadians(options.angle),\n cos = fabric.util.cos(theta),\n sin = fabric.util.sin(theta);\n return [cos, sin, -sin, cos, 0, 0];\n },\n\n /**\n * Returns a transform matrix starting from an object of the same kind of\n * the one returned from qrDecompose, useful also if you want to calculate some\n * transformations from an object that is not enlived yet.\n * is called DimensionsTransformMatrix because those properties are the one that influence\n * the size of the resulting box of the object.\n * @static\n * @memberOf fabric.util\n * @param {Object} options\n * @param {Number} [options.scaleX]\n * @param {Number} [options.scaleY]\n * @param {Boolean} [options.flipX]\n * @param {Boolean} [options.flipY]\n * @param {Number} [options.skewX]\n * @param {Number} [options.skewX]\n * @return {Number[]} transform matrix\n */\n calcDimensionsMatrix: function (options) {\n var scaleX = typeof options.scaleX === 'undefined' ? 1 : options.scaleX,\n scaleY = typeof options.scaleY === 'undefined' ? 1 : options.scaleY,\n scaleMatrix = [options.flipX ? -scaleX : scaleX, 0, 0, options.flipY ? -scaleY : scaleY, 0, 0],\n multiply = fabric.util.multiplyTransformMatrices,\n degreesToRadians = fabric.util.degreesToRadians;\n\n if (options.skewX) {\n scaleMatrix = multiply(scaleMatrix, [1, 0, Math.tan(degreesToRadians(options.skewX)), 1], true);\n }\n\n if (options.skewY) {\n scaleMatrix = multiply(scaleMatrix, [1, Math.tan(degreesToRadians(options.skewY)), 0, 1], true);\n }\n\n return scaleMatrix;\n },\n\n /**\n * Returns a transform matrix starting from an object of the same kind of\n * the one returned from qrDecompose, useful also if you want to calculate some\n * transformations from an object that is not enlived yet\n * @static\n * @memberOf fabric.util\n * @param {Object} options\n * @param {Number} [options.angle]\n * @param {Number} [options.scaleX]\n * @param {Number} [options.scaleY]\n * @param {Boolean} [options.flipX]\n * @param {Boolean} [options.flipY]\n * @param {Number} [options.skewX]\n * @param {Number} [options.skewX]\n * @param {Number} [options.translateX]\n * @param {Number} [options.translateY]\n * @return {Number[]} transform matrix\n */\n composeMatrix: function (options) {\n var matrix = [1, 0, 0, 1, options.translateX || 0, options.translateY || 0],\n multiply = fabric.util.multiplyTransformMatrices;\n\n if (options.angle) {\n matrix = multiply(matrix, fabric.util.calcRotateMatrix(options));\n }\n\n if (options.scaleX !== 1 || options.scaleY !== 1 || options.skewX || options.skewY || options.flipX || options.flipY) {\n matrix = multiply(matrix, fabric.util.calcDimensionsMatrix(options));\n }\n\n return matrix;\n },\n\n /**\n * reset an object transform state to neutral. Top and left are not accounted for\n * @static\n * @memberOf fabric.util\n * @param {fabric.Object} target object to transform\n */\n resetObjectTransform: function (target) {\n target.scaleX = 1;\n target.scaleY = 1;\n target.skewX = 0;\n target.skewY = 0;\n target.flipX = false;\n target.flipY = false;\n target.rotate(0);\n },\n\n /**\n * Extract Object transform values\n * @static\n * @memberOf fabric.util\n * @param {fabric.Object} target object to read from\n * @return {Object} Components of transform\n */\n saveObjectTransform: function (target) {\n return {\n scaleX: target.scaleX,\n scaleY: target.scaleY,\n skewX: target.skewX,\n skewY: target.skewY,\n angle: target.angle,\n left: target.left,\n flipX: target.flipX,\n flipY: target.flipY,\n top: target.top\n };\n },\n\n /**\n * Returns true if context has transparent pixel\n * at specified location (taking tolerance into account)\n * @param {CanvasRenderingContext2D} ctx context\n * @param {Number} x x coordinate\n * @param {Number} y y coordinate\n * @param {Number} tolerance Tolerance\n */\n isTransparent: function (ctx, x, y, tolerance) {\n // If tolerance is > 0 adjust start coords to take into account.\n // If moves off Canvas fix to 0\n if (tolerance > 0) {\n if (x > tolerance) {\n x -= tolerance;\n } else {\n x = 0;\n }\n\n if (y > tolerance) {\n y -= tolerance;\n } else {\n y = 0;\n }\n }\n\n var _isTransparent = true,\n i,\n temp,\n imageData = ctx.getImageData(x, y, tolerance * 2 || 1, tolerance * 2 || 1),\n l = imageData.data.length; // Split image data - for tolerance > 1, pixelDataSize = 4;\n\n for (i = 3; i < l; i += 4) {\n temp = imageData.data[i];\n _isTransparent = temp <= 0;\n\n if (_isTransparent === false) {\n break; // Stop if colour found\n }\n }\n\n imageData = null;\n return _isTransparent;\n },\n\n /**\n * Parse preserveAspectRatio attribute from element\n * @param {string} attribute to be parsed\n * @return {Object} an object containing align and meetOrSlice attribute\n */\n parsePreserveAspectRatioAttribute: function (attribute) {\n var meetOrSlice = 'meet',\n alignX = 'Mid',\n alignY = 'Mid',\n aspectRatioAttrs = attribute.split(' '),\n align;\n\n if (aspectRatioAttrs && aspectRatioAttrs.length) {\n meetOrSlice = aspectRatioAttrs.pop();\n\n if (meetOrSlice !== 'meet' && meetOrSlice !== 'slice') {\n align = meetOrSlice;\n meetOrSlice = 'meet';\n } else if (aspectRatioAttrs.length) {\n align = aspectRatioAttrs.pop();\n }\n } //divide align in alignX and alignY\n\n\n alignX = align !== 'none' ? align.slice(1, 4) : 'none';\n alignY = align !== 'none' ? align.slice(5, 8) : 'none';\n return {\n meetOrSlice: meetOrSlice,\n alignX: alignX,\n alignY: alignY\n };\n },\n\n /**\n * Clear char widths cache for the given font family or all the cache if no\n * fontFamily is specified.\n * Use it if you know you are loading fonts in a lazy way and you are not waiting\n * for custom fonts to load properly when adding text objects to the canvas.\n * If a text object is added when its own font is not loaded yet, you will get wrong\n * measurement and so wrong bounding boxes.\n * After the font cache is cleared, either change the textObject text content or call\n * initDimensions() to trigger a recalculation\n * @memberOf fabric.util\n * @param {String} [fontFamily] font family to clear\n */\n clearFabricFontCache: function (fontFamily) {\n fontFamily = (fontFamily || '').toLowerCase();\n\n if (!fontFamily) {\n fabric.charWidthsCache = {};\n } else if (fabric.charWidthsCache[fontFamily]) {\n delete fabric.charWidthsCache[fontFamily];\n }\n },\n\n /**\n * Given current aspect ratio, determines the max width and height that can\n * respect the total allowed area for the cache.\n * @memberOf fabric.util\n * @param {Number} ar aspect ratio\n * @param {Number} maximumArea Maximum area you want to achieve\n * @return {Object.x} Limited dimensions by X\n * @return {Object.y} Limited dimensions by Y\n */\n limitDimsByArea: function (ar, maximumArea) {\n var roughWidth = Math.sqrt(maximumArea * ar),\n perfLimitSizeY = Math.floor(maximumArea / roughWidth);\n return {\n x: Math.floor(roughWidth),\n y: perfLimitSizeY\n };\n },\n capValue: function (min, value, max) {\n return Math.max(min, Math.min(value, max));\n },\n\n /**\n * Finds the scale for the object source to fit inside the object destination,\n * keeping aspect ratio intact.\n * respect the total allowed area for the cache.\n * @memberOf fabric.util\n * @param {Object | fabric.Object} source\n * @param {Number} source.height natural unscaled height of the object\n * @param {Number} source.width natural unscaled width of the object\n * @param {Object | fabric.Object} destination\n * @param {Number} destination.height natural unscaled height of the object\n * @param {Number} destination.width natural unscaled width of the object\n * @return {Number} scale factor to apply to source to fit into destination\n */\n findScaleToFit: function (source, destination) {\n return Math.min(destination.width / source.width, destination.height / source.height);\n },\n\n /**\n * Finds the scale for the object source to cover entirely the object destination,\n * keeping aspect ratio intact.\n * respect the total allowed area for the cache.\n * @memberOf fabric.util\n * @param {Object | fabric.Object} source\n * @param {Number} source.height natural unscaled height of the object\n * @param {Number} source.width natural unscaled width of the object\n * @param {Object | fabric.Object} destination\n * @param {Number} destination.height natural unscaled height of the object\n * @param {Number} destination.width natural unscaled width of the object\n * @return {Number} scale factor to apply to source to cover destination\n */\n findScaleToCover: function (source, destination) {\n return Math.max(destination.width / source.width, destination.height / source.height);\n },\n\n /**\n * given an array of 6 number returns something like `\"matrix(...numbers)\"`\n * @memberOf fabric.util\n * @param {Array} trasnform an array with 6 numbers\n * @return {String} transform matrix for svg\n * @return {Object.y} Limited dimensions by Y\n */\n matrixToSVG: function (transform) {\n return 'matrix(' + transform.map(function (value) {\n return fabric.util.toFixed(value, fabric.Object.NUM_FRACTION_DIGITS);\n }).join(' ') + ')';\n },\n\n /**\n * given a width and height, return the size of the bounding box\n * that can contains the box with width/height with applied transform\n * described in options.\n * Use to calculate the boxes around objects for controls.\n * @memberOf fabric.util\n * @param {Number} width\n * @param {Number} height\n * @param {Object} options\n * @param {Number} options.scaleX\n * @param {Number} options.scaleY\n * @param {Number} options.skewX\n * @param {Number} options.skewY\n * @return {Object.x} width of containing\n * @return {Object.y} height of containing\n */\n sizeAfterTransform: function (width, height, options) {\n var dimX = width / 2,\n dimY = height / 2,\n points = [{\n x: -dimX,\n y: -dimY\n }, {\n x: dimX,\n y: -dimY\n }, {\n x: -dimX,\n y: dimY\n }, {\n x: dimX,\n y: dimY\n }],\n transformMatrix = fabric.util.calcDimensionsMatrix(options),\n bbox = fabric.util.makeBoundingBoxFromPoints(points, transformMatrix);\n return {\n x: bbox.width,\n y: bbox.height\n };\n }\n };\n})(typeof exports !== 'undefined' ? exports : this);\n\n(function () {\n var _join = Array.prototype.join,\n commandLengths = {\n m: 2,\n l: 2,\n h: 1,\n v: 1,\n c: 6,\n s: 4,\n q: 4,\n t: 2,\n a: 7\n },\n repeatedCommands = {\n m: 'l',\n M: 'L'\n };\n\n function segmentToBezier(th2, th3, cosTh, sinTh, rx, ry, cx1, cy1, mT, fromX, fromY) {\n var costh2 = fabric.util.cos(th2),\n sinth2 = fabric.util.sin(th2),\n costh3 = fabric.util.cos(th3),\n sinth3 = fabric.util.sin(th3),\n toX = cosTh * rx * costh3 - sinTh * ry * sinth3 + cx1,\n toY = sinTh * rx * costh3 + cosTh * ry * sinth3 + cy1,\n cp1X = fromX + mT * (-cosTh * rx * sinth2 - sinTh * ry * costh2),\n cp1Y = fromY + mT * (-sinTh * rx * sinth2 + cosTh * ry * costh2),\n cp2X = toX + mT * (cosTh * rx * sinth3 + sinTh * ry * costh3),\n cp2Y = toY + mT * (sinTh * rx * sinth3 - cosTh * ry * costh3);\n return ['C', cp1X, cp1Y, cp2X, cp2Y, toX, toY];\n }\n /* Adapted from http://dxr.mozilla.org/mozilla-central/source/content/svg/content/src/nsSVGPathDataParser.cpp\n * by Andrea Bogazzi code is under MPL. if you don't have a copy of the license you can take it here\n * http://mozilla.org/MPL/2.0/\n */\n\n\n function arcToSegments(toX, toY, rx, ry, large, sweep, rotateX) {\n var PI = Math.PI,\n th = rotateX * PI / 180,\n sinTh = fabric.util.sin(th),\n cosTh = fabric.util.cos(th),\n fromX = 0,\n fromY = 0;\n rx = Math.abs(rx);\n ry = Math.abs(ry);\n var px = -cosTh * toX * 0.5 - sinTh * toY * 0.5,\n py = -cosTh * toY * 0.5 + sinTh * toX * 0.5,\n rx2 = rx * rx,\n ry2 = ry * ry,\n py2 = py * py,\n px2 = px * px,\n pl = rx2 * ry2 - rx2 * py2 - ry2 * px2,\n root = 0;\n\n if (pl < 0) {\n var s = Math.sqrt(1 - pl / (rx2 * ry2));\n rx *= s;\n ry *= s;\n } else {\n root = (large === sweep ? -1.0 : 1.0) * Math.sqrt(pl / (rx2 * py2 + ry2 * px2));\n }\n\n var cx = root * rx * py / ry,\n cy = -root * ry * px / rx,\n cx1 = cosTh * cx - sinTh * cy + toX * 0.5,\n cy1 = sinTh * cx + cosTh * cy + toY * 0.5,\n mTheta = calcVectorAngle(1, 0, (px - cx) / rx, (py - cy) / ry),\n dtheta = calcVectorAngle((px - cx) / rx, (py - cy) / ry, (-px - cx) / rx, (-py - cy) / ry);\n\n if (sweep === 0 && dtheta > 0) {\n dtheta -= 2 * PI;\n } else if (sweep === 1 && dtheta < 0) {\n dtheta += 2 * PI;\n } // Convert into cubic bezier segments <= 90deg\n\n\n var segments = Math.ceil(Math.abs(dtheta / PI * 2)),\n result = [],\n mDelta = dtheta / segments,\n mT = 8 / 3 * Math.sin(mDelta / 4) * Math.sin(mDelta / 4) / Math.sin(mDelta / 2),\n th3 = mTheta + mDelta;\n\n for (var i = 0; i < segments; i++) {\n result[i] = segmentToBezier(mTheta, th3, cosTh, sinTh, rx, ry, cx1, cy1, mT, fromX, fromY);\n fromX = result[i][5];\n fromY = result[i][6];\n mTheta = th3;\n th3 += mDelta;\n }\n\n return result;\n }\n /*\n * Private\n */\n\n\n function calcVectorAngle(ux, uy, vx, vy) {\n var ta = Math.atan2(uy, ux),\n tb = Math.atan2(vy, vx);\n\n if (tb >= ta) {\n return tb - ta;\n } else {\n return 2 * Math.PI - (ta - tb);\n }\n }\n /**\n * Calculate bounding box of a beziercurve\n * @param {Number} x0 starting point\n * @param {Number} y0\n * @param {Number} x1 first control point\n * @param {Number} y1\n * @param {Number} x2 secondo control point\n * @param {Number} y2\n * @param {Number} x3 end of beizer\n * @param {Number} y3\n */\n // taken from http://jsbin.com/ivomiq/56/edit no credits available for that.\n // TODO: can we normalize this with the starting points set at 0 and then translated the bbox?\n\n\n function getBoundsOfCurve(x0, y0, x1, y1, x2, y2, x3, y3) {\n var argsString;\n\n if (fabric.cachesBoundsOfCurve) {\n argsString = _join.call(arguments);\n\n if (fabric.boundsOfCurveCache[argsString]) {\n return fabric.boundsOfCurveCache[argsString];\n }\n }\n\n var sqrt = Math.sqrt,\n min = Math.min,\n max = Math.max,\n abs = Math.abs,\n tvalues = [],\n bounds = [[], []],\n a,\n b,\n c,\n t,\n t1,\n t2,\n b2ac,\n sqrtb2ac;\n b = 6 * x0 - 12 * x1 + 6 * x2;\n a = -3 * x0 + 9 * x1 - 9 * x2 + 3 * x3;\n c = 3 * x1 - 3 * x0;\n\n for (var i = 0; i < 2; ++i) {\n if (i > 0) {\n b = 6 * y0 - 12 * y1 + 6 * y2;\n a = -3 * y0 + 9 * y1 - 9 * y2 + 3 * y3;\n c = 3 * y1 - 3 * y0;\n }\n\n if (abs(a) < 1e-12) {\n if (abs(b) < 1e-12) {\n continue;\n }\n\n t = -c / b;\n\n if (0 < t && t < 1) {\n tvalues.push(t);\n }\n\n continue;\n }\n\n b2ac = b * b - 4 * c * a;\n\n if (b2ac < 0) {\n continue;\n }\n\n sqrtb2ac = sqrt(b2ac);\n t1 = (-b + sqrtb2ac) / (2 * a);\n\n if (0 < t1 && t1 < 1) {\n tvalues.push(t1);\n }\n\n t2 = (-b - sqrtb2ac) / (2 * a);\n\n if (0 < t2 && t2 < 1) {\n tvalues.push(t2);\n }\n }\n\n var x,\n y,\n j = tvalues.length,\n jlen = j,\n mt;\n\n while (j--) {\n t = tvalues[j];\n mt = 1 - t;\n x = mt * mt * mt * x0 + 3 * mt * mt * t * x1 + 3 * mt * t * t * x2 + t * t * t * x3;\n bounds[0][j] = x;\n y = mt * mt * mt * y0 + 3 * mt * mt * t * y1 + 3 * mt * t * t * y2 + t * t * t * y3;\n bounds[1][j] = y;\n }\n\n bounds[0][jlen] = x0;\n bounds[1][jlen] = y0;\n bounds[0][jlen + 1] = x3;\n bounds[1][jlen + 1] = y3;\n var result = [{\n x: min.apply(null, bounds[0]),\n y: min.apply(null, bounds[1])\n }, {\n x: max.apply(null, bounds[0]),\n y: max.apply(null, bounds[1])\n }];\n\n if (fabric.cachesBoundsOfCurve) {\n fabric.boundsOfCurveCache[argsString] = result;\n }\n\n return result;\n }\n /**\n * Converts arc to a bunch of beizer curves\n * @param {Number} fx starting point x\n * @param {Number} fy starting point y\n * @param {Array} coords Arc command\n */\n\n\n function fromArcToBeizers(fx, fy, coords) {\n var rx = coords[1],\n ry = coords[2],\n rot = coords[3],\n large = coords[4],\n sweep = coords[5],\n tx = coords[6],\n ty = coords[7],\n segsNorm = arcToSegments(tx - fx, ty - fy, rx, ry, large, sweep, rot);\n\n for (var i = 0, len = segsNorm.length; i < len; i++) {\n segsNorm[i][1] += fx;\n segsNorm[i][2] += fy;\n segsNorm[i][3] += fx;\n segsNorm[i][4] += fy;\n segsNorm[i][5] += fx;\n segsNorm[i][6] += fy;\n }\n\n return segsNorm;\n }\n\n ;\n\n function makePathSimpler(path) {\n // x and y represent the last point of the path. the previous command point.\n // we add them to each relative command to make it an absolute comment.\n // we also swap the v V h H with L, because are easier to transform.\n var x = 0,\n y = 0,\n len = path.length,\n // x1 and y1 represent the last point of the subpath. the subpath is started with\n // m or M command. When a z or Z command is drawn, x and y need to be resetted to\n // the last x1 and y1.\n x1 = 0,\n y1 = 0,\n current,\n i,\n converted,\n // previous will host the letter of the previous command, to handle S and T.\n // controlX and controlY will host the previous reflected control point\n destinationPath = [],\n previous,\n controlX,\n controlY;\n\n for (i = 0; i < len; ++i) {\n converted = false;\n current = path[i].slice(0);\n\n switch (current[0]) {\n // first letter\n case 'l':\n // lineto, relative\n current[0] = 'L';\n current[1] += x;\n current[2] += y;\n // falls through\n\n case 'L':\n x = current[1];\n y = current[2];\n break;\n\n case 'h':\n // horizontal lineto, relative\n current[1] += x;\n // falls through\n\n case 'H':\n current[0] = 'L';\n current[2] = y;\n x = current[1];\n break;\n\n case 'v':\n // vertical lineto, relative\n current[1] += y;\n // falls through\n\n case 'V':\n current[0] = 'L';\n y = current[1];\n current[1] = x;\n current[2] = y;\n break;\n\n case 'm':\n // moveTo, relative\n current[0] = 'M';\n current[1] += x;\n current[2] += y;\n // falls through\n\n case 'M':\n x = current[1];\n y = current[2];\n x1 = current[1];\n y1 = current[2];\n break;\n\n case 'c':\n // bezierCurveTo, relative\n current[0] = 'C';\n current[1] += x;\n current[2] += y;\n current[3] += x;\n current[4] += y;\n current[5] += x;\n current[6] += y;\n // falls through\n\n case 'C':\n controlX = current[3];\n controlY = current[4];\n x = current[5];\n y = current[6];\n break;\n\n case 's':\n // shorthand cubic bezierCurveTo, relative\n current[0] = 'S';\n current[1] += x;\n current[2] += y;\n current[3] += x;\n current[4] += y;\n // falls through\n\n case 'S':\n // would be sScC but since we are swapping sSc for C, we check just that.\n if (previous === 'C') {\n // calculate reflection of previous control points\n controlX = 2 * x - controlX;\n controlY = 2 * y - controlY;\n } else {\n // If there is no previous command or if the previous command was not a C, c, S, or s,\n // the control point is coincident with the current point\n controlX = x;\n controlY = y;\n }\n\n x = current[3];\n y = current[4];\n current[0] = 'C';\n current[5] = current[3];\n current[6] = current[4];\n current[3] = current[1];\n current[4] = current[2];\n current[1] = controlX;\n current[2] = controlY; // current[3] and current[4] are NOW the second control point.\n // we keep it for the next reflection.\n\n controlX = current[3];\n controlY = current[4];\n break;\n\n case 'q':\n // quadraticCurveTo, relative\n current[0] = 'Q';\n current[1] += x;\n current[2] += y;\n current[3] += x;\n current[4] += y;\n // falls through\n\n case 'Q':\n controlX = current[1];\n controlY = current[2];\n x = current[3];\n y = current[4];\n break;\n\n case 't':\n // shorthand quadraticCurveTo, relative\n current[0] = 'T';\n current[1] += x;\n current[2] += y;\n // falls through\n\n case 'T':\n if (previous === 'Q') {\n // calculate reflection of previous control point\n controlX = 2 * x - controlX;\n controlY = 2 * y - controlY;\n } else {\n // If there is no previous command or if the previous command was not a Q, q, T or t,\n // assume the control point is coincident with the current point\n controlX = x;\n controlY = y;\n }\n\n current[0] = 'Q';\n x = current[1];\n y = current[2];\n current[1] = controlX;\n current[2] = controlY;\n current[3] = x;\n current[4] = y;\n break;\n\n case 'a':\n current[0] = 'A';\n current[6] += x;\n current[7] += y;\n // falls through\n\n case 'A':\n converted = true;\n destinationPath = destinationPath.concat(fromArcToBeizers(x, y, current));\n x = current[6];\n y = current[7];\n break;\n\n case 'z':\n case 'Z':\n x = x1;\n y = y1;\n break;\n\n default:\n }\n\n if (!converted) {\n destinationPath.push(current);\n }\n\n previous = current[0];\n }\n\n return destinationPath;\n }\n\n ;\n /**\n * Calc length from point x1,y1 to x2,y2\n * @param {Number} x1 starting point x\n * @param {Number} y1 starting point y\n * @param {Number} x2 starting point x\n * @param {Number} y2 starting point y\n * @return {Number} length of segment\n */\n\n function calcLineLength(x1, y1, x2, y2) {\n return Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));\n } // functions for the Cubic beizer\n // taken from: https://github.com/konvajs/konva/blob/7.0.5/src/shapes/Path.ts#L350\n\n\n function CB1(t) {\n return t * t * t;\n }\n\n function CB2(t) {\n return 3 * t * t * (1 - t);\n }\n\n function CB3(t) {\n return 3 * t * (1 - t) * (1 - t);\n }\n\n function CB4(t) {\n return (1 - t) * (1 - t) * (1 - t);\n }\n\n function getPointOnCubicBezierIterator(p1x, p1y, p2x, p2y, p3x, p3y, p4x, p4y) {\n return function (pct) {\n var c1 = CB1(pct),\n c2 = CB2(pct),\n c3 = CB3(pct),\n c4 = CB4(pct);\n return {\n x: p4x * c1 + p3x * c2 + p2x * c3 + p1x * c4,\n y: p4y * c1 + p3y * c2 + p2y * c3 + p1y * c4\n };\n };\n }\n\n function QB1(t) {\n return t * t;\n }\n\n function QB2(t) {\n return 2 * t * (1 - t);\n }\n\n function QB3(t) {\n return (1 - t) * (1 - t);\n }\n\n function getPointOnQuadraticBezierIterator(p1x, p1y, p2x, p2y, p3x, p3y) {\n return function (pct) {\n var c1 = QB1(pct),\n c2 = QB2(pct),\n c3 = QB3(pct);\n return {\n x: p3x * c1 + p2x * c2 + p1x * c3,\n y: p3y * c1 + p2y * c2 + p1y * c3\n };\n };\n }\n\n function pathIterator(iterator, x1, y1) {\n var tempP = {\n x: x1,\n y: y1\n },\n p,\n tmpLen = 0,\n perc;\n\n for (perc = 0.01; perc <= 1; perc += 0.01) {\n p = iterator(perc);\n tmpLen += calcLineLength(tempP.x, tempP.y, p.x, p.y);\n tempP = p;\n }\n\n return tmpLen;\n } //measures the length of a pre-simplified path\n\n\n function getPathSegmentsInfo(path) {\n var totalLength = 0,\n len = path.length,\n current,\n //x2 and y2 are the coords of segment start\n //x1 and y1 are the coords of the current point\n x1 = 0,\n y1 = 0,\n x2 = 0,\n y2 = 0,\n info = [],\n iterator,\n tempInfo;\n\n for (var i = 0; i < len; i++) {\n current = path[i];\n tempInfo = {\n x: x1,\n y: y1,\n command: current[0]\n };\n\n switch (current[0]) {\n //first letter\n case 'M':\n tempInfo.length = 0;\n x2 = x1 = current[1];\n y2 = y1 = current[2];\n break;\n\n case 'L':\n tempInfo.length = calcLineLength(x1, y1, current[1], current[2]);\n x1 = current[1];\n y1 = current[2];\n break;\n\n case 'C':\n iterator = getPointOnCubicBezierIterator(x1, y1, current[1], current[2], current[3], current[4], current[5], current[6]);\n tempInfo.length = pathIterator(iterator, x1, y1);\n x1 = current[5];\n y1 = current[6];\n break;\n\n case 'Q':\n iterator = getPointOnQuadraticBezierIterator(x1, y1, current[1], current[2], current[3], current[4]);\n tempInfo.length = pathIterator(iterator, x1, y1);\n x1 = current[3];\n y1 = current[4];\n break;\n\n case 'Z':\n case 'z':\n // we add those in order to ease calculations later\n tempInfo.destX = x2;\n tempInfo.destY = y2;\n tempInfo.length = calcLineLength(x1, y1, x2, y2);\n x1 = x2;\n y1 = y2;\n break;\n }\n\n totalLength += tempInfo.length;\n info.push(tempInfo);\n }\n\n info.push({\n length: totalLength,\n x: x1,\n y: y1\n });\n return info;\n }\n\n function getPointOnPath(path, perc, infos) {\n if (!infos) {\n infos = getPathSegmentsInfo(path);\n }\n\n var distance = infos[infos.length - 1] * perc,\n i = 0;\n\n while (distance - infos[i] > 0 && i < infos.length) {\n distance -= infos[i];\n i++;\n }\n\n var segInfo = infos[i],\n segPercent = distance / segInfo.length,\n command = segInfo.length,\n segment = path[i];\n\n switch (command) {\n case 'Z':\n case 'z':\n return new fabric.Point(segInfo.x, segInfo.y).lerp(new fabric.Point(segInfo.destX, segInfo.destY), segPercent);\n break;\n\n case 'L':\n return new fabric.Point(segInfo.x, segInfo.y).lerp(new fabric.Point(segment[1], segment[2]), segPercent);\n break;\n\n case 'C':\n return getPointOnCubicBezierIterator(segInfo.x, segInfo.y, segment[1], segment[2], segment[3], segment[4], segment[5], segment[6])(segPercent);\n break;\n\n case 'Q':\n return getPointOnQuadraticBezierIterator(segInfo.x, segInfo.y, segment[1], segment[2], segment[3], segment[4])(segPercent);\n break;\n }\n }\n\n function parsePath(pathString) {\n var result = [],\n coords = [],\n currentPath,\n parsed,\n re = fabric.rePathCommand,\n rNumber = '[-+]?(?:\\\\d*\\\\.\\\\d+|\\\\d+\\\\.?)(?:[eE][-+]?\\\\d+)?\\\\s*',\n rNumberCommaWsp = '(' + rNumber + ')' + fabric.commaWsp,\n rFlagCommaWsp = '([01])' + fabric.commaWsp + '?',\n rArcSeq = rNumberCommaWsp + '?' + rNumberCommaWsp + '?' + rNumberCommaWsp + rFlagCommaWsp + rFlagCommaWsp + rNumberCommaWsp + '?(' + rNumber + ')',\n regArcArgumentSequence = new RegExp(rArcSeq, 'g'),\n match,\n coordsStr,\n // one of commands (m,M,l,L,q,Q,c,C,etc.) followed by non-command characters (i.e. command values)\n path;\n\n if (!pathString || !pathString.match) {\n return result;\n }\n\n path = pathString.match(/[mzlhvcsqta][^mzlhvcsqta]*/gi);\n\n for (var i = 0, coordsParsed, len = path.length; i < len; i++) {\n currentPath = path[i];\n coordsStr = currentPath.slice(1).trim();\n coords.length = 0;\n var command = currentPath.charAt(0);\n coordsParsed = [command];\n\n if (command.toLowerCase() === 'a') {\n // arcs have special flags that apparently don't require spaces so handle special\n for (var args; args = regArcArgumentSequence.exec(coordsStr);) {\n for (var j = 1; j < args.length; j++) {\n coords.push(args[j]);\n }\n }\n } else {\n while (match = re.exec(coordsStr)) {\n coords.push(match[0]);\n }\n }\n\n for (var j = 0, jlen = coords.length; j < jlen; j++) {\n parsed = parseFloat(coords[j]);\n\n if (!isNaN(parsed)) {\n coordsParsed.push(parsed);\n }\n }\n\n var commandLength = commandLengths[command.toLowerCase()],\n repeatedCommand = repeatedCommands[command] || command;\n\n if (coordsParsed.length - 1 > commandLength) {\n for (var k = 1, klen = coordsParsed.length; k < klen; k += commandLength) {\n result.push([command].concat(coordsParsed.slice(k, k + commandLength)));\n command = repeatedCommand;\n }\n } else {\n result.push(coordsParsed);\n }\n }\n\n return result;\n }\n\n ;\n /**\n * Calculate bounding box of a elliptic-arc\n * @deprecated\n * @param {Number} fx start point of arc\n * @param {Number} fy\n * @param {Number} rx horizontal radius\n * @param {Number} ry vertical radius\n * @param {Number} rot angle of horizontal axis\n * @param {Number} large 1 or 0, whatever the arc is the big or the small on the 2 points\n * @param {Number} sweep 1 or 0, 1 clockwise or counterclockwise direction\n * @param {Number} tx end point of arc\n * @param {Number} ty\n */\n\n function getBoundsOfArc(fx, fy, rx, ry, rot, large, sweep, tx, ty) {\n var fromX = 0,\n fromY = 0,\n bound,\n bounds = [],\n segs = arcToSegments(tx - fx, ty - fy, rx, ry, large, sweep, rot);\n\n for (var i = 0, len = segs.length; i < len; i++) {\n bound = getBoundsOfCurve(fromX, fromY, segs[i][1], segs[i][2], segs[i][3], segs[i][4], segs[i][5], segs[i][6]);\n bounds.push({\n x: bound[0].x + fx,\n y: bound[0].y + fy\n });\n bounds.push({\n x: bound[1].x + fx,\n y: bound[1].y + fy\n });\n fromX = segs[i][5];\n fromY = segs[i][6];\n }\n\n return bounds;\n }\n\n ;\n /**\n * Draws arc\n * @param {CanvasRenderingContext2D} ctx\n * @param {Number} fx\n * @param {Number} fy\n * @param {Array} coords coords of the arc, without the front 'A/a'\n */\n\n function drawArc(ctx, fx, fy, coords) {\n coords = coords.slice(0).unshift('X'); // command A or a does not matter\n\n var beizers = fromArcToBeizers(fx, fy, coords);\n beizers.forEach(function (beizer) {\n ctx.bezierCurveTo.apply(ctx, beizer.slice(1));\n });\n }\n\n ;\n fabric.util.parsePath = parsePath;\n fabric.util.makePathSimpler = makePathSimpler;\n fabric.util.getPathSegmentsInfo = getPathSegmentsInfo;\n fabric.util.fromArcToBeizers = fromArcToBeizers;\n fabric.util.getBoundsOfCurve = getBoundsOfCurve;\n fabric.util.getPointOnPath = getPointOnPath; // kept because we do not want to make breaking changes.\n // but useless and deprecated.\n\n fabric.util.getBoundsOfArc = getBoundsOfArc;\n fabric.util.drawArc = drawArc;\n})();\n\n(function () {\n var slice = Array.prototype.slice;\n /**\n * Invokes method on all items in a given array\n * @memberOf fabric.util.array\n * @param {Array} array Array to iterate over\n * @param {String} method Name of a method to invoke\n * @return {Array}\n */\n\n function invoke(array, method) {\n var args = slice.call(arguments, 2),\n result = [];\n\n for (var i = 0, len = array.length; i < len; i++) {\n result[i] = args.length ? array[i][method].apply(array[i], args) : array[i][method].call(array[i]);\n }\n\n return result;\n }\n /**\n * Finds maximum value in array (not necessarily \"first\" one)\n * @memberOf fabric.util.array\n * @param {Array} array Array to iterate over\n * @param {String} byProperty\n * @return {*}\n */\n\n\n function max(array, byProperty) {\n return find(array, byProperty, function (value1, value2) {\n return value1 >= value2;\n });\n }\n /**\n * Finds minimum value in array (not necessarily \"first\" one)\n * @memberOf fabric.util.array\n * @param {Array} array Array to iterate over\n * @param {String} byProperty\n * @return {*}\n */\n\n\n function min(array, byProperty) {\n return find(array, byProperty, function (value1, value2) {\n return value1 < value2;\n });\n }\n /**\n * @private\n */\n\n\n function fill(array, value) {\n var k = array.length;\n\n while (k--) {\n array[k] = value;\n }\n\n return array;\n }\n /**\n * @private\n */\n\n\n function find(array, byProperty, condition) {\n if (!array || array.length === 0) {\n return;\n }\n\n var i = array.length - 1,\n result = byProperty ? array[i][byProperty] : array[i];\n\n if (byProperty) {\n while (i--) {\n if (condition(array[i][byProperty], result)) {\n result = array[i][byProperty];\n }\n }\n } else {\n while (i--) {\n if (condition(array[i], result)) {\n result = array[i];\n }\n }\n }\n\n return result;\n }\n /**\n * @namespace fabric.util.array\n */\n\n\n fabric.util.array = {\n fill: fill,\n invoke: invoke,\n min: min,\n max: max\n };\n})();\n\n(function () {\n /**\n * Copies all enumerable properties of one js object to another\n * this does not and cannot compete with generic utils.\n * Does not clone or extend fabric.Object subclasses.\n * This is mostly for internal use and has extra handling for fabricJS objects\n * it skips the canvas and group properties in deep cloning.\n * @memberOf fabric.util.object\n * @param {Object} destination Where to copy to\n * @param {Object} source Where to copy from\n * @return {Object}\n */\n function extend(destination, source, deep) {\n // JScript DontEnum bug is not taken care of\n // the deep clone is for internal use, is not meant to avoid\n // javascript traps or cloning html element or self referenced objects.\n if (deep) {\n if (!fabric.isLikelyNode && source instanceof Element) {\n // avoid cloning deep images, canvases,\n destination = source;\n } else if (source instanceof Array) {\n destination = [];\n\n for (var i = 0, len = source.length; i < len; i++) {\n destination[i] = extend({}, source[i], deep);\n }\n } else if (source && typeof source === 'object') {\n for (var property in source) {\n if (property === 'canvas' || property === 'group') {\n // we do not want to clone this props at all.\n // we want to keep the keys in the copy\n destination[property] = null;\n } else if (source.hasOwnProperty(property)) {\n destination[property] = extend({}, source[property], deep);\n }\n }\n } else {\n // this sounds odd for an extend but is ok for recursive use\n destination = source;\n }\n } else {\n for (var property in source) {\n destination[property] = source[property];\n }\n }\n\n return destination;\n }\n /**\n * Creates an empty object and copies all enumerable properties of another object to it\n * @memberOf fabric.util.object\n * TODO: this function return an empty object if you try to clone null\n * @param {Object} object Object to clone\n * @return {Object}\n */\n\n\n function clone(object, deep) {\n return extend({}, object, deep);\n }\n /** @namespace fabric.util.object */\n\n\n fabric.util.object = {\n extend: extend,\n clone: clone\n };\n fabric.util.object.extend(fabric.util, fabric.Observable);\n})();\n\n(function () {\n /**\n * Camelizes a string\n * @memberOf fabric.util.string\n * @param {String} string String to camelize\n * @return {String} Camelized version of a string\n */\n function camelize(string) {\n return string.replace(/-+(.)?/g, function (match, character) {\n return character ? character.toUpperCase() : '';\n });\n }\n /**\n * Capitalizes a string\n * @memberOf fabric.util.string\n * @param {String} string String to capitalize\n * @param {Boolean} [firstLetterOnly] If true only first letter is capitalized\n * and other letters stay untouched, if false first letter is capitalized\n * and other letters are converted to lowercase.\n * @return {String} Capitalized version of a string\n */\n\n\n function capitalize(string, firstLetterOnly) {\n return string.charAt(0).toUpperCase() + (firstLetterOnly ? string.slice(1) : string.slice(1).toLowerCase());\n }\n /**\n * Escapes XML in a string\n * @memberOf fabric.util.string\n * @param {String} string String to escape\n * @return {String} Escaped version of a string\n */\n\n\n function escapeXml(string) {\n return string.replace(/&/g, '&').replace(/\"/g, '"').replace(/'/g, ''').replace(/</g, '<').replace(/>/g, '>');\n }\n /**\n * Divide a string in the user perceived single units\n * @memberOf fabric.util.string\n * @param {String} textstring String to escape\n * @return {Array} array containing the graphemes\n */\n\n\n function graphemeSplit(textstring) {\n var i = 0,\n chr,\n graphemes = [];\n\n for (i = 0, chr; i < textstring.length; i++) {\n if ((chr = getWholeChar(textstring, i)) === false) {\n continue;\n }\n\n graphemes.push(chr);\n }\n\n return graphemes;\n } // taken from mdn in the charAt doc page.\n\n\n function getWholeChar(str, i) {\n var code = str.charCodeAt(i);\n\n if (isNaN(code)) {\n return ''; // Position not found\n }\n\n if (code < 0xD800 || code > 0xDFFF) {\n return str.charAt(i);\n } // High surrogate (could change last hex to 0xDB7F to treat high private\n // surrogates as single characters)\n\n\n if (0xD800 <= code && code <= 0xDBFF) {\n if (str.length <= i + 1) {\n throw 'High surrogate without following low surrogate';\n }\n\n var next = str.charCodeAt(i + 1);\n\n if (0xDC00 > next || next > 0xDFFF) {\n throw 'High surrogate without following low surrogate';\n }\n\n return str.charAt(i) + str.charAt(i + 1);\n } // Low surrogate (0xDC00 <= code && code <= 0xDFFF)\n\n\n if (i === 0) {\n throw 'Low surrogate without preceding high surrogate';\n }\n\n var prev = str.charCodeAt(i - 1); // (could change last hex to 0xDB7F to treat high private\n // surrogates as single characters)\n\n if (0xD800 > prev || prev > 0xDBFF) {\n throw 'Low surrogate without preceding high surrogate';\n } // We can pass over low surrogates now as the second component\n // in a pair which we have already processed\n\n\n return false;\n }\n /**\n * String utilities\n * @namespace fabric.util.string\n */\n\n\n fabric.util.string = {\n camelize: camelize,\n capitalize: capitalize,\n escapeXml: escapeXml,\n graphemeSplit: graphemeSplit\n };\n})();\n\n(function () {\n var slice = Array.prototype.slice,\n emptyFunction = function () {},\n IS_DONTENUM_BUGGY = function () {\n for (var p in {\n toString: 1\n }) {\n if (p === 'toString') {\n return false;\n }\n }\n\n return true;\n }(),\n\n /** @ignore */\n addMethods = function (klass, source, parent) {\n for (var property in source) {\n if (property in klass.prototype && typeof klass.prototype[property] === 'function' && (source[property] + '').indexOf('callSuper') > -1) {\n klass.prototype[property] = function (property) {\n return function () {\n var superclass = this.constructor.superclass;\n this.constructor.superclass = parent;\n var returnValue = source[property].apply(this, arguments);\n this.constructor.superclass = superclass;\n\n if (property !== 'initialize') {\n return returnValue;\n }\n };\n }(property);\n } else {\n klass.prototype[property] = source[property];\n }\n\n if (IS_DONTENUM_BUGGY) {\n if (source.toString !== Object.prototype.toString) {\n klass.prototype.toString = source.toString;\n }\n\n if (source.valueOf !== Object.prototype.valueOf) {\n klass.prototype.valueOf = source.valueOf;\n }\n }\n }\n };\n\n function Subclass() {}\n\n function callSuper(methodName) {\n var parentMethod = null,\n _this = this; // climb prototype chain to find method not equal to callee's method\n\n\n while (_this.constructor.superclass) {\n var superClassMethod = _this.constructor.superclass.prototype[methodName];\n\n if (_this[methodName] !== superClassMethod) {\n parentMethod = superClassMethod;\n break;\n } // eslint-disable-next-line\n\n\n _this = _this.constructor.superclass.prototype;\n }\n\n if (!parentMethod) {\n return console.log('tried to callSuper ' + methodName + ', method not found in prototype chain', this);\n }\n\n return arguments.length > 1 ? parentMethod.apply(this, slice.call(arguments, 1)) : parentMethod.call(this);\n }\n /**\n * Helper for creation of \"classes\".\n * @memberOf fabric.util\n * @param {Function} [parent] optional \"Class\" to inherit from\n * @param {Object} [properties] Properties shared by all instances of this class\n * (be careful modifying objects defined here as this would affect all instances)\n */\n\n\n function createClass() {\n var parent = null,\n properties = slice.call(arguments, 0);\n\n if (typeof properties[0] === 'function') {\n parent = properties.shift();\n }\n\n function klass() {\n this.initialize.apply(this, arguments);\n }\n\n klass.superclass = parent;\n klass.subclasses = [];\n\n if (parent) {\n Subclass.prototype = parent.prototype;\n klass.prototype = new Subclass();\n parent.subclasses.push(klass);\n }\n\n for (var i = 0, length = properties.length; i < length; i++) {\n addMethods(klass, properties[i], parent);\n }\n\n if (!klass.prototype.initialize) {\n klass.prototype.initialize = emptyFunction;\n }\n\n klass.prototype.constructor = klass;\n klass.prototype.callSuper = callSuper;\n return klass;\n }\n\n fabric.util.createClass = createClass;\n})();\n\n(function () {\n // since ie11 can use addEventListener but they do not support options, i need to check\n var couldUseAttachEvent = !!fabric.document.createElement('div').attachEvent,\n touchEvents = ['touchstart', 'touchmove', 'touchend'];\n /**\n * Adds an event listener to an element\n * @function\n * @memberOf fabric.util\n * @param {HTMLElement} element\n * @param {String} eventName\n * @param {Function} handler\n */\n\n fabric.util.addListener = function (element, eventName, handler, options) {\n element && element.addEventListener(eventName, handler, couldUseAttachEvent ? false : options);\n };\n /**\n * Removes an event listener from an element\n * @function\n * @memberOf fabric.util\n * @param {HTMLElement} element\n * @param {String} eventName\n * @param {Function} handler\n */\n\n\n fabric.util.removeListener = function (element, eventName, handler, options) {\n element && element.removeEventListener(eventName, handler, couldUseAttachEvent ? false : options);\n };\n\n function getTouchInfo(event) {\n var touchProp = event.changedTouches;\n\n if (touchProp && touchProp[0]) {\n return touchProp[0];\n }\n\n return event;\n }\n\n fabric.util.getPointer = function (event) {\n var element = event.target,\n scroll = fabric.util.getScrollLeftTop(element),\n _evt = getTouchInfo(event);\n\n return {\n x: _evt.clientX + scroll.left,\n y: _evt.clientY + scroll.top\n };\n };\n\n fabric.util.isTouchEvent = function (event) {\n return touchEvents.indexOf(event.type) > -1 || event.pointerType === 'touch';\n };\n})();\n\n(function () {\n /**\n * Cross-browser wrapper for setting element's style\n * @memberOf fabric.util\n * @param {HTMLElement} element\n * @param {Object} styles\n * @return {HTMLElement} Element that was passed as a first argument\n */\n function setStyle(element, styles) {\n var elementStyle = element.style;\n\n if (!elementStyle) {\n return element;\n }\n\n if (typeof styles === 'string') {\n element.style.cssText += ';' + styles;\n return styles.indexOf('opacity') > -1 ? setOpacity(element, styles.match(/opacity:\\s*(\\d?\\.?\\d*)/)[1]) : element;\n }\n\n for (var property in styles) {\n if (property === 'opacity') {\n setOpacity(element, styles[property]);\n } else {\n var normalizedProperty = property === 'float' || property === 'cssFloat' ? typeof elementStyle.styleFloat === 'undefined' ? 'cssFloat' : 'styleFloat' : property;\n elementStyle[normalizedProperty] = styles[property];\n }\n }\n\n return element;\n }\n\n var parseEl = fabric.document.createElement('div'),\n supportsOpacity = typeof parseEl.style.opacity === 'string',\n supportsFilters = typeof parseEl.style.filter === 'string',\n reOpacity = /alpha\\s*\\(\\s*opacity\\s*=\\s*([^\\)]+)\\)/,\n\n /** @ignore */\n setOpacity = function (element) {\n return element;\n };\n\n if (supportsOpacity) {\n /** @ignore */\n setOpacity = function (element, value) {\n element.style.opacity = value;\n return element;\n };\n } else if (supportsFilters) {\n /** @ignore */\n setOpacity = function (element, value) {\n var es = element.style;\n\n if (element.currentStyle && !element.currentStyle.hasLayout) {\n es.zoom = 1;\n }\n\n if (reOpacity.test(es.filter)) {\n value = value >= 0.9999 ? '' : 'alpha(opacity=' + value * 100 + ')';\n es.filter = es.filter.replace(reOpacity, value);\n } else {\n es.filter += ' alpha(opacity=' + value * 100 + ')';\n }\n\n return element;\n };\n }\n\n fabric.util.setStyle = setStyle;\n})();\n\n(function () {\n var _slice = Array.prototype.slice;\n /**\n * Takes id and returns an element with that id (if one exists in a document)\n * @memberOf fabric.util\n * @param {String|HTMLElement} id\n * @return {HTMLElement|null}\n */\n\n function getById(id) {\n return typeof id === 'string' ? fabric.document.getElementById(id) : id;\n }\n\n var sliceCanConvertNodelists,\n\n /**\n * Converts an array-like object (e.g. arguments or NodeList) to an array\n * @memberOf fabric.util\n * @param {Object} arrayLike\n * @return {Array}\n */\n toArray = function (arrayLike) {\n return _slice.call(arrayLike, 0);\n };\n\n try {\n sliceCanConvertNodelists = toArray(fabric.document.childNodes) instanceof Array;\n } catch (err) {}\n\n if (!sliceCanConvertNodelists) {\n toArray = function (arrayLike) {\n var arr = new Array(arrayLike.length),\n i = arrayLike.length;\n\n while (i--) {\n arr[i] = arrayLike[i];\n }\n\n return arr;\n };\n }\n /**\n * Creates specified element with specified attributes\n * @memberOf fabric.util\n * @param {String} tagName Type of an element to create\n * @param {Object} [attributes] Attributes to set on an element\n * @return {HTMLElement} Newly created element\n */\n\n\n function makeElement(tagName, attributes) {\n var el = fabric.document.createElement(tagName);\n\n for (var prop in attributes) {\n if (prop === 'class') {\n el.className = attributes[prop];\n } else if (prop === 'for') {\n el.htmlFor = attributes[prop];\n } else {\n el.setAttribute(prop, attributes[prop]);\n }\n }\n\n return el;\n }\n /**\n * Adds class to an element\n * @memberOf fabric.util\n * @param {HTMLElement} element Element to add class to\n * @param {String} className Class to add to an element\n */\n\n\n function addClass(element, className) {\n if (element && (' ' + element.className + ' ').indexOf(' ' + className + ' ') === -1) {\n element.className += (element.className ? ' ' : '') + className;\n }\n }\n /**\n * Wraps element with another element\n * @memberOf fabric.util\n * @param {HTMLElement} element Element to wrap\n * @param {HTMLElement|String} wrapper Element to wrap with\n * @param {Object} [attributes] Attributes to set on a wrapper\n * @return {HTMLElement} wrapper\n */\n\n\n function wrapElement(element, wrapper, attributes) {\n if (typeof wrapper === 'string') {\n wrapper = makeElement(wrapper, attributes);\n }\n\n if (element.parentNode) {\n element.parentNode.replaceChild(wrapper, element);\n }\n\n wrapper.appendChild(element);\n return wrapper;\n }\n /**\n * Returns element scroll offsets\n * @memberOf fabric.util\n * @param {HTMLElement} element Element to operate on\n * @return {Object} Object with left/top values\n */\n\n\n function getScrollLeftTop(element) {\n var left = 0,\n top = 0,\n docElement = fabric.document.documentElement,\n body = fabric.document.body || {\n scrollLeft: 0,\n scrollTop: 0\n }; // While loop checks (and then sets element to) .parentNode OR .host\n // to account for ShadowDOM. We still want to traverse up out of ShadowDOM,\n // but the .parentNode of a root ShadowDOM node will always be null, instead\n // it should be accessed through .host. See http://stackoverflow.com/a/24765528/4383938\n\n while (element && (element.parentNode || element.host)) {\n // Set element to element parent, or 'host' in case of ShadowDOM\n element = element.parentNode || element.host;\n\n if (element === fabric.document) {\n left = body.scrollLeft || docElement.scrollLeft || 0;\n top = body.scrollTop || docElement.scrollTop || 0;\n } else {\n left += element.scrollLeft || 0;\n top += element.scrollTop || 0;\n }\n\n if (element.nodeType === 1 && element.style.position === 'fixed') {\n break;\n }\n }\n\n return {\n left: left,\n top: top\n };\n }\n /**\n * Returns offset for a given element\n * @function\n * @memberOf fabric.util\n * @param {HTMLElement} element Element to get offset for\n * @return {Object} Object with \"left\" and \"top\" properties\n */\n\n\n function getElementOffset(element) {\n var docElem,\n doc = element && element.ownerDocument,\n box = {\n left: 0,\n top: 0\n },\n offset = {\n left: 0,\n top: 0\n },\n scrollLeftTop,\n offsetAttributes = {\n borderLeftWidth: 'left',\n borderTopWidth: 'top',\n paddingLeft: 'left',\n paddingTop: 'top'\n };\n\n if (!doc) {\n return offset;\n }\n\n for (var attr in offsetAttributes) {\n offset[offsetAttributes[attr]] += parseInt(getElementStyle(element, attr), 10) || 0;\n }\n\n docElem = doc.documentElement;\n\n if (typeof element.getBoundingClientRect !== 'undefined') {\n box = element.getBoundingClientRect();\n }\n\n scrollLeftTop = getScrollLeftTop(element);\n return {\n left: box.left + scrollLeftTop.left - (docElem.clientLeft || 0) + offset.left,\n top: box.top + scrollLeftTop.top - (docElem.clientTop || 0) + offset.top\n };\n }\n /**\n * Returns style attribute value of a given element\n * @memberOf fabric.util\n * @param {HTMLElement} element Element to get style attribute for\n * @param {String} attr Style attribute to get for element\n * @return {String} Style attribute value of the given element.\n */\n\n\n var getElementStyle;\n\n if (fabric.document.defaultView && fabric.document.defaultView.getComputedStyle) {\n getElementStyle = function (element, attr) {\n var style = fabric.document.defaultView.getComputedStyle(element, null);\n return style ? style[attr] : undefined;\n };\n } else {\n getElementStyle = function (element, attr) {\n var value = element.style[attr];\n\n if (!value && element.currentStyle) {\n value = element.currentStyle[attr];\n }\n\n return value;\n };\n }\n\n (function () {\n var style = fabric.document.documentElement.style,\n selectProp = 'userSelect' in style ? 'userSelect' : 'MozUserSelect' in style ? 'MozUserSelect' : 'WebkitUserSelect' in style ? 'WebkitUserSelect' : 'KhtmlUserSelect' in style ? 'KhtmlUserSelect' : '';\n /**\n * Makes element unselectable\n * @memberOf fabric.util\n * @param {HTMLElement} element Element to make unselectable\n * @return {HTMLElement} Element that was passed in\n */\n\n function makeElementUnselectable(element) {\n if (typeof element.onselectstart !== 'undefined') {\n element.onselectstart = fabric.util.falseFunction;\n }\n\n if (selectProp) {\n element.style[selectProp] = 'none';\n } else if (typeof element.unselectable === 'string') {\n element.unselectable = 'on';\n }\n\n return element;\n }\n /**\n * Makes element selectable\n * @memberOf fabric.util\n * @param {HTMLElement} element Element to make selectable\n * @return {HTMLElement} Element that was passed in\n */\n\n\n function makeElementSelectable(element) {\n if (typeof element.onselectstart !== 'undefined') {\n element.onselectstart = null;\n }\n\n if (selectProp) {\n element.style[selectProp] = '';\n } else if (typeof element.unselectable === 'string') {\n element.unselectable = '';\n }\n\n return element;\n }\n\n fabric.util.makeElementUnselectable = makeElementUnselectable;\n fabric.util.makeElementSelectable = makeElementSelectable;\n })();\n\n function getNodeCanvas(element) {\n var impl = fabric.jsdomImplForWrapper(element);\n return impl._canvas || impl._image;\n }\n\n ;\n\n function cleanUpJsdomNode(element) {\n if (!fabric.isLikelyNode) {\n return;\n }\n\n var impl = fabric.jsdomImplForWrapper(element);\n\n if (impl) {\n impl._image = null;\n impl._canvas = null; // unsure if necessary\n\n impl._currentSrc = null;\n impl._attributes = null;\n impl._classList = null;\n }\n }\n\n function setImageSmoothing(ctx, value) {\n ctx.imageSmoothingEnabled = ctx.imageSmoothingEnabled || ctx.webkitImageSmoothingEnabled || ctx.mozImageSmoothingEnabled || ctx.msImageSmoothingEnabled || ctx.oImageSmoothingEnabled;\n ctx.imageSmoothingEnabled = value;\n }\n /**\n * setImageSmoothing sets the context imageSmoothingEnabled property.\n * Used by canvas and by ImageObject.\n * @memberOf fabric.util\n * @since 4.0.0\n * @param {HTMLRenderingContext2D} ctx to set on\n * @param {Boolean} value true or false\n */\n\n\n fabric.util.setImageSmoothing = setImageSmoothing;\n fabric.util.getById = getById;\n fabric.util.toArray = toArray;\n fabric.util.addClass = addClass;\n fabric.util.makeElement = makeElement;\n fabric.util.wrapElement = wrapElement;\n fabric.util.getScrollLeftTop = getScrollLeftTop;\n fabric.util.getElementOffset = getElementOffset;\n fabric.util.getNodeCanvas = getNodeCanvas;\n fabric.util.cleanUpJsdomNode = cleanUpJsdomNode;\n})();\n\n(function () {\n function addParamToUrl(url, param) {\n return url + (/\\?/.test(url) ? '&' : '?') + param;\n }\n\n function emptyFn() {}\n /**\n * Cross-browser abstraction for sending XMLHttpRequest\n * @memberOf fabric.util\n * @param {String} url URL to send XMLHttpRequest to\n * @param {Object} [options] Options object\n * @param {String} [options.method=\"GET\"]\n * @param {String} [options.parameters] parameters to append to url in GET or in body\n * @param {String} [options.body] body to send with POST or PUT request\n * @param {Function} options.onComplete Callback to invoke when request is completed\n * @return {XMLHttpRequest} request\n */\n\n\n function request(url, options) {\n options || (options = {});\n\n var method = options.method ? options.method.toUpperCase() : 'GET',\n onComplete = options.onComplete || function () {},\n xhr = new fabric.window.XMLHttpRequest(),\n body = options.body || options.parameters;\n /** @ignore */\n\n\n xhr.onreadystatechange = function () {\n if (xhr.readyState === 4) {\n onComplete(xhr);\n xhr.onreadystatechange = emptyFn;\n }\n };\n\n if (method === 'GET') {\n body = null;\n\n if (typeof options.parameters === 'string') {\n url = addParamToUrl(url, options.parameters);\n }\n }\n\n xhr.open(method, url, true);\n\n if (method === 'POST' || method === 'PUT') {\n xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');\n }\n\n xhr.send(body);\n return xhr;\n }\n\n fabric.util.request = request;\n})();\n/**\n * Wrapper around `console.log` (when available)\n * @param {*} [values] Values to log\n */\n\n\nfabric.log = console.log;\n/**\n * Wrapper around `console.warn` (when available)\n * @param {*} [values] Values to log as a warning\n */\n\nfabric.warn = console.warn;\n\n(function () {\n function noop() {\n return false;\n }\n\n function defaultEasing(t, b, c, d) {\n return -c * Math.cos(t / d * (Math.PI / 2)) + c + b;\n }\n /**\n * Changes value from one to another within certain period of time, invoking callbacks as value is being changed.\n * @memberOf fabric.util\n * @param {Object} [options] Animation options\n * @param {Function} [options.onChange] Callback; invoked on every value change\n * @param {Function} [options.onComplete] Callback; invoked when value change is completed\n * @param {Number} [options.startValue=0] Starting value\n * @param {Number} [options.endValue=100] Ending value\n * @param {Number} [options.byValue=100] Value to modify the property by\n * @param {Function} [options.easing] Easing function\n * @param {Number} [options.duration=500] Duration of change (in ms)\n * @param {Function} [options.abort] Additional function with logic. If returns true, onComplete is called.\n */\n\n\n function animate(options) {\n requestAnimFrame(function (timestamp) {\n options || (options = {});\n var start = timestamp || +new Date(),\n duration = options.duration || 500,\n finish = start + duration,\n time,\n onChange = options.onChange || noop,\n abort = options.abort || noop,\n onComplete = options.onComplete || noop,\n easing = options.easing || defaultEasing,\n startValue = 'startValue' in options ? options.startValue : 0,\n endValue = 'endValue' in options ? options.endValue : 100,\n byValue = options.byValue || endValue - startValue;\n options.onStart && options.onStart();\n\n (function tick(ticktime) {\n // TODO: move abort call after calculation\n // and pass (current,valuePerc, timePerc) as arguments\n time = ticktime || +new Date();\n var currentTime = time > finish ? duration : time - start,\n timePerc = currentTime / duration,\n current = easing(currentTime, startValue, byValue, duration),\n valuePerc = Math.abs((current - startValue) / byValue);\n\n if (abort()) {\n onComplete(endValue, 1, 1);\n return;\n }\n\n if (time > finish) {\n onChange(endValue, 1, 1);\n onComplete(endValue, 1, 1);\n return;\n } else {\n onChange(current, valuePerc, timePerc);\n requestAnimFrame(tick);\n }\n })(start);\n });\n }\n\n var _requestAnimFrame = fabric.window.requestAnimationFrame || fabric.window.webkitRequestAnimationFrame || fabric.window.mozRequestAnimationFrame || fabric.window.oRequestAnimationFrame || fabric.window.msRequestAnimationFrame || function (callback) {\n return fabric.window.setTimeout(callback, 1000 / 60);\n };\n\n var _cancelAnimFrame = fabric.window.cancelAnimationFrame || fabric.window.clearTimeout;\n /**\n * requestAnimationFrame polyfill based on http://paulirish.com/2011/requestanimationframe-for-smart-animating/\n * In order to get a precise start time, `requestAnimFrame` should be called as an entry into the method\n * @memberOf fabric.util\n * @param {Function} callback Callback to invoke\n * @param {DOMElement} element optional Element to associate with animation\n */\n\n\n function requestAnimFrame() {\n return _requestAnimFrame.apply(fabric.window, arguments);\n }\n\n function cancelAnimFrame() {\n return _cancelAnimFrame.apply(fabric.window, arguments);\n }\n\n fabric.util.animate = animate;\n fabric.util.requestAnimFrame = requestAnimFrame;\n fabric.util.cancelAnimFrame = cancelAnimFrame;\n})();\n\n(function () {\n // Calculate an in-between color. Returns a \"rgba()\" string.\n // Credit: Edwin Martin <edwin@bitstorm.org>\n // http://www.bitstorm.org/jquery/color-animation/jquery.animate-colors.js\n function calculateColor(begin, end, pos) {\n var color = 'rgba(' + parseInt(begin[0] + pos * (end[0] - begin[0]), 10) + ',' + parseInt(begin[1] + pos * (end[1] - begin[1]), 10) + ',' + parseInt(begin[2] + pos * (end[2] - begin[2]), 10);\n color += ',' + (begin && end ? parseFloat(begin[3] + pos * (end[3] - begin[3])) : 1);\n color += ')';\n return color;\n }\n /**\n * Changes the color from one to another within certain period of time, invoking callbacks as value is being changed.\n * @memberOf fabric.util\n * @param {String} fromColor The starting color in hex or rgb(a) format.\n * @param {String} toColor The starting color in hex or rgb(a) format.\n * @param {Number} [duration] Duration of change (in ms).\n * @param {Object} [options] Animation options\n * @param {Function} [options.onChange] Callback; invoked on every value change\n * @param {Function} [options.onComplete] Callback; invoked when value change is completed\n * @param {Function} [options.colorEasing] Easing function. Note that this function only take two arguments (currentTime, duration). Thus the regular animation easing functions cannot be used.\n * @param {Function} [options.abort] Additional function with logic. If returns true, onComplete is called.\n */\n\n\n function animateColor(fromColor, toColor, duration, options) {\n var startColor = new fabric.Color(fromColor).getSource(),\n endColor = new fabric.Color(toColor).getSource(),\n originalOnComplete = options.onComplete,\n originalOnChange = options.onChange;\n options = options || {};\n fabric.util.animate(fabric.util.object.extend(options, {\n duration: duration || 500,\n startValue: startColor,\n endValue: endColor,\n byValue: endColor,\n easing: function (currentTime, startValue, byValue, duration) {\n var posValue = options.colorEasing ? options.colorEasing(currentTime, duration) : 1 - Math.cos(currentTime / duration * (Math.PI / 2));\n return calculateColor(startValue, byValue, posValue);\n },\n // has to take in account for color restoring;\n onComplete: function (current, valuePerc, timePerc) {\n if (originalOnComplete) {\n return originalOnComplete(calculateColor(endColor, endColor, 0), valuePerc, timePerc);\n }\n },\n onChange: function (current, valuePerc, timePerc) {\n if (originalOnChange) {\n if (Array.isArray(current)) {\n return originalOnChange(calculateColor(current, current, 0), valuePerc, timePerc);\n }\n\n originalOnChange(current, valuePerc, timePerc);\n }\n }\n }));\n }\n\n fabric.util.animateColor = animateColor;\n})();\n\n(function () {\n function normalize(a, c, p, s) {\n if (a < Math.abs(c)) {\n a = c;\n s = p / 4;\n } else {\n //handle the 0/0 case:\n if (c === 0 && a === 0) {\n s = p / (2 * Math.PI) * Math.asin(1);\n } else {\n s = p / (2 * Math.PI) * Math.asin(c / a);\n }\n }\n\n return {\n a: a,\n c: c,\n p: p,\n s: s\n };\n }\n\n function elastic(opts, t, d) {\n return opts.a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - opts.s) * (2 * Math.PI) / opts.p);\n }\n /**\n * Cubic easing out\n * @memberOf fabric.util.ease\n */\n\n\n function easeOutCubic(t, b, c, d) {\n return c * ((t = t / d - 1) * t * t + 1) + b;\n }\n /**\n * Cubic easing in and out\n * @memberOf fabric.util.ease\n */\n\n\n function easeInOutCubic(t, b, c, d) {\n t /= d / 2;\n\n if (t < 1) {\n return c / 2 * t * t * t + b;\n }\n\n return c / 2 * ((t -= 2) * t * t + 2) + b;\n }\n /**\n * Quartic easing in\n * @memberOf fabric.util.ease\n */\n\n\n function easeInQuart(t, b, c, d) {\n return c * (t /= d) * t * t * t + b;\n }\n /**\n * Quartic easing out\n * @memberOf fabric.util.ease\n */\n\n\n function easeOutQuart(t, b, c, d) {\n return -c * ((t = t / d - 1) * t * t * t - 1) + b;\n }\n /**\n * Quartic easing in and out\n * @memberOf fabric.util.ease\n */\n\n\n function easeInOutQuart(t, b, c, d) {\n t /= d / 2;\n\n if (t < 1) {\n return c / 2 * t * t * t * t + b;\n }\n\n return -c / 2 * ((t -= 2) * t * t * t - 2) + b;\n }\n /**\n * Quintic easing in\n * @memberOf fabric.util.ease\n */\n\n\n function easeInQuint(t, b, c, d) {\n return c * (t /= d) * t * t * t * t + b;\n }\n /**\n * Quintic easing out\n * @memberOf fabric.util.ease\n */\n\n\n function easeOutQuint(t, b, c, d) {\n return c * ((t = t / d - 1) * t * t * t * t + 1) + b;\n }\n /**\n * Quintic easing in and out\n * @memberOf fabric.util.ease\n */\n\n\n function easeInOutQuint(t, b, c, d) {\n t /= d / 2;\n\n if (t < 1) {\n return c / 2 * t * t * t * t * t + b;\n }\n\n return c / 2 * ((t -= 2) * t * t * t * t + 2) + b;\n }\n /**\n * Sinusoidal easing in\n * @memberOf fabric.util.ease\n */\n\n\n function easeInSine(t, b, c, d) {\n return -c * Math.cos(t / d * (Math.PI / 2)) + c + b;\n }\n /**\n * Sinusoidal easing out\n * @memberOf fabric.util.ease\n */\n\n\n function easeOutSine(t, b, c, d) {\n return c * Math.sin(t / d * (Math.PI / 2)) + b;\n }\n /**\n * Sinusoidal easing in and out\n * @memberOf fabric.util.ease\n */\n\n\n function easeInOutSine(t, b, c, d) {\n return -c / 2 * (Math.cos(Math.PI * t / d) - 1) + b;\n }\n /**\n * Exponential easing in\n * @memberOf fabric.util.ease\n */\n\n\n function easeInExpo(t, b, c, d) {\n return t === 0 ? b : c * Math.pow(2, 10 * (t / d - 1)) + b;\n }\n /**\n * Exponential easing out\n * @memberOf fabric.util.ease\n */\n\n\n function easeOutExpo(t, b, c, d) {\n return t === d ? b + c : c * (-Math.pow(2, -10 * t / d) + 1) + b;\n }\n /**\n * Exponential easing in and out\n * @memberOf fabric.util.ease\n */\n\n\n function easeInOutExpo(t, b, c, d) {\n if (t === 0) {\n return b;\n }\n\n if (t === d) {\n return b + c;\n }\n\n t /= d / 2;\n\n if (t < 1) {\n return c / 2 * Math.pow(2, 10 * (t - 1)) + b;\n }\n\n return c / 2 * (-Math.pow(2, -10 * --t) + 2) + b;\n }\n /**\n * Circular easing in\n * @memberOf fabric.util.ease\n */\n\n\n function easeInCirc(t, b, c, d) {\n return -c * (Math.sqrt(1 - (t /= d) * t) - 1) + b;\n }\n /**\n * Circular easing out\n * @memberOf fabric.util.ease\n */\n\n\n function easeOutCirc(t, b, c, d) {\n return c * Math.sqrt(1 - (t = t / d - 1) * t) + b;\n }\n /**\n * Circular easing in and out\n * @memberOf fabric.util.ease\n */\n\n\n function easeInOutCirc(t, b, c, d) {\n t /= d / 2;\n\n if (t < 1) {\n return -c / 2 * (Math.sqrt(1 - t * t) - 1) + b;\n }\n\n return c / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1) + b;\n }\n /**\n * Elastic easing in\n * @memberOf fabric.util.ease\n */\n\n\n function easeInElastic(t, b, c, d) {\n var s = 1.70158,\n p = 0,\n a = c;\n\n if (t === 0) {\n return b;\n }\n\n t /= d;\n\n if (t === 1) {\n return b + c;\n }\n\n if (!p) {\n p = d * 0.3;\n }\n\n var opts = normalize(a, c, p, s);\n return -elastic(opts, t, d) + b;\n }\n /**\n * Elastic easing out\n * @memberOf fabric.util.ease\n */\n\n\n function easeOutElastic(t, b, c, d) {\n var s = 1.70158,\n p = 0,\n a = c;\n\n if (t === 0) {\n return b;\n }\n\n t /= d;\n\n if (t === 1) {\n return b + c;\n }\n\n if (!p) {\n p = d * 0.3;\n }\n\n var opts = normalize(a, c, p, s);\n return opts.a * Math.pow(2, -10 * t) * Math.sin((t * d - opts.s) * (2 * Math.PI) / opts.p) + opts.c + b;\n }\n /**\n * Elastic easing in and out\n * @memberOf fabric.util.ease\n */\n\n\n function easeInOutElastic(t, b, c, d) {\n var s = 1.70158,\n p = 0,\n a = c;\n\n if (t === 0) {\n return b;\n }\n\n t /= d / 2;\n\n if (t === 2) {\n return b + c;\n }\n\n if (!p) {\n p = d * (0.3 * 1.5);\n }\n\n var opts = normalize(a, c, p, s);\n\n if (t < 1) {\n return -0.5 * elastic(opts, t, d) + b;\n }\n\n return opts.a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * d - opts.s) * (2 * Math.PI) / opts.p) * 0.5 + opts.c + b;\n }\n /**\n * Backwards easing in\n * @memberOf fabric.util.ease\n */\n\n\n function easeInBack(t, b, c, d, s) {\n if (s === undefined) {\n s = 1.70158;\n }\n\n return c * (t /= d) * t * ((s + 1) * t - s) + b;\n }\n /**\n * Backwards easing out\n * @memberOf fabric.util.ease\n */\n\n\n function easeOutBack(t, b, c, d, s) {\n if (s === undefined) {\n s = 1.70158;\n }\n\n return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b;\n }\n /**\n * Backwards easing in and out\n * @memberOf fabric.util.ease\n */\n\n\n function easeInOutBack(t, b, c, d, s) {\n if (s === undefined) {\n s = 1.70158;\n }\n\n t /= d / 2;\n\n if (t < 1) {\n return c / 2 * (t * t * (((s *= 1.525) + 1) * t - s)) + b;\n }\n\n return c / 2 * ((t -= 2) * t * (((s *= 1.525) + 1) * t + s) + 2) + b;\n }\n /**\n * Bouncing easing in\n * @memberOf fabric.util.ease\n */\n\n\n function easeInBounce(t, b, c, d) {\n return c - easeOutBounce(d - t, 0, c, d) + b;\n }\n /**\n * Bouncing easing out\n * @memberOf fabric.util.ease\n */\n\n\n function easeOutBounce(t, b, c, d) {\n if ((t /= d) < 1 / 2.75) {\n return c * (7.5625 * t * t) + b;\n } else if (t < 2 / 2.75) {\n return c * (7.5625 * (t -= 1.5 / 2.75) * t + 0.75) + b;\n } else if (t < 2.5 / 2.75) {\n return c * (7.5625 * (t -= 2.25 / 2.75) * t + 0.9375) + b;\n } else {\n return c * (7.5625 * (t -= 2.625 / 2.75) * t + 0.984375) + b;\n }\n }\n /**\n * Bouncing easing in and out\n * @memberOf fabric.util.ease\n */\n\n\n function easeInOutBounce(t, b, c, d) {\n if (t < d / 2) {\n return easeInBounce(t * 2, 0, c, d) * 0.5 + b;\n }\n\n return easeOutBounce(t * 2 - d, 0, c, d) * 0.5 + c * 0.5 + b;\n }\n /**\n * Easing functions\n * See <a href=\"http://gizma.com/easing/\">Easing Equations by Robert Penner</a>\n * @namespace fabric.util.ease\n */\n\n\n fabric.util.ease = {\n /**\n * Quadratic easing in\n * @memberOf fabric.util.ease\n */\n easeInQuad: function (t, b, c, d) {\n return c * (t /= d) * t + b;\n },\n\n /**\n * Quadratic easing out\n * @memberOf fabric.util.ease\n */\n easeOutQuad: function (t, b, c, d) {\n return -c * (t /= d) * (t - 2) + b;\n },\n\n /**\n * Quadratic easing in and out\n * @memberOf fabric.util.ease\n */\n easeInOutQuad: function (t, b, c, d) {\n t /= d / 2;\n\n if (t < 1) {\n return c / 2 * t * t + b;\n }\n\n return -c / 2 * (--t * (t - 2) - 1) + b;\n },\n\n /**\n * Cubic easing in\n * @memberOf fabric.util.ease\n */\n easeInCubic: function (t, b, c, d) {\n return c * (t /= d) * t * t + b;\n },\n easeOutCubic: easeOutCubic,\n easeInOutCubic: easeInOutCubic,\n easeInQuart: easeInQuart,\n easeOutQuart: easeOutQuart,\n easeInOutQuart: easeInOutQuart,\n easeInQuint: easeInQuint,\n easeOutQuint: easeOutQuint,\n easeInOutQuint: easeInOutQuint,\n easeInSine: easeInSine,\n easeOutSine: easeOutSine,\n easeInOutSine: easeInOutSine,\n easeInExpo: easeInExpo,\n easeOutExpo: easeOutExpo,\n easeInOutExpo: easeInOutExpo,\n easeInCirc: easeInCirc,\n easeOutCirc: easeOutCirc,\n easeInOutCirc: easeInOutCirc,\n easeInElastic: easeInElastic,\n easeOutElastic: easeOutElastic,\n easeInOutElastic: easeInOutElastic,\n easeInBack: easeInBack,\n easeOutBack: easeOutBack,\n easeInOutBack: easeInOutBack,\n easeInBounce: easeInBounce,\n easeOutBounce: easeOutBounce,\n easeInOutBounce: easeInOutBounce\n };\n})();\n\n(function (global) {\n 'use strict';\n /**\n * @name fabric\n * @namespace\n */\n\n var fabric = global.fabric || (global.fabric = {}),\n extend = fabric.util.object.extend,\n clone = fabric.util.object.clone,\n toFixed = fabric.util.toFixed,\n parseUnit = fabric.util.parseUnit,\n multiplyTransformMatrices = fabric.util.multiplyTransformMatrices,\n svgValidTagNames = ['path', 'circle', 'polygon', 'polyline', 'ellipse', 'rect', 'line', 'image', 'text'],\n svgViewBoxElements = ['symbol', 'image', 'marker', 'pattern', 'view', 'svg'],\n svgInvalidAncestors = ['pattern', 'defs', 'symbol', 'metadata', 'clipPath', 'mask', 'desc'],\n svgValidParents = ['symbol', 'g', 'a', 'svg', 'clipPath', 'defs'],\n attributesMap = {\n cx: 'left',\n x: 'left',\n r: 'radius',\n cy: 'top',\n y: 'top',\n display: 'visible',\n visibility: 'visible',\n transform: 'transformMatrix',\n 'fill-opacity': 'fillOpacity',\n 'fill-rule': 'fillRule',\n 'font-family': 'fontFamily',\n 'font-size': 'fontSize',\n 'font-style': 'fontStyle',\n 'font-weight': 'fontWeight',\n 'letter-spacing': 'charSpacing',\n 'paint-order': 'paintFirst',\n 'stroke-dasharray': 'strokeDashArray',\n 'stroke-dashoffset': 'strokeDashOffset',\n 'stroke-linecap': 'strokeLineCap',\n 'stroke-linejoin': 'strokeLineJoin',\n 'stroke-miterlimit': 'strokeMiterLimit',\n 'stroke-opacity': 'strokeOpacity',\n 'stroke-width': 'strokeWidth',\n 'text-decoration': 'textDecoration',\n 'text-anchor': 'textAnchor',\n opacity: 'opacity',\n 'clip-path': 'clipPath',\n 'clip-rule': 'clipRule',\n 'vector-effect': 'strokeUniform',\n 'image-rendering': 'imageSmoothing'\n },\n colorAttributes = {\n stroke: 'strokeOpacity',\n fill: 'fillOpacity'\n },\n fSize = 'font-size',\n cPath = 'clip-path';\n fabric.svgValidTagNamesRegEx = getSvgRegex(svgValidTagNames);\n fabric.svgViewBoxElementsRegEx = getSvgRegex(svgViewBoxElements);\n fabric.svgInvalidAncestorsRegEx = getSvgRegex(svgInvalidAncestors);\n fabric.svgValidParentsRegEx = getSvgRegex(svgValidParents);\n fabric.cssRules = {};\n fabric.gradientDefs = {};\n fabric.clipPaths = {};\n\n function normalizeAttr(attr) {\n // transform attribute names\n if (attr in attributesMap) {\n return attributesMap[attr];\n }\n\n return attr;\n }\n\n function normalizeValue(attr, value, parentAttributes, fontSize) {\n var isArray = Object.prototype.toString.call(value) === '[object Array]',\n parsed;\n\n if ((attr === 'fill' || attr === 'stroke') && value === 'none') {\n value = '';\n } else if (attr === 'strokeUniform') {\n return value === 'non-scaling-stroke';\n } else if (attr === 'strokeDashArray') {\n if (value === 'none') {\n value = null;\n } else {\n value = value.replace(/,/g, ' ').split(/\\s+/).map(parseFloat);\n }\n } else if (attr === 'transformMatrix') {\n if (parentAttributes && parentAttributes.transformMatrix) {\n value = multiplyTransformMatrices(parentAttributes.transformMatrix, fabric.parseTransformAttribute(value));\n } else {\n value = fabric.parseTransformAttribute(value);\n }\n } else if (attr === 'visible') {\n value = value !== 'none' && value !== 'hidden'; // display=none on parent element always takes precedence over child element\n\n if (parentAttributes && parentAttributes.visible === false) {\n value = false;\n }\n } else if (attr === 'opacity') {\n value = parseFloat(value);\n\n if (parentAttributes && typeof parentAttributes.opacity !== 'undefined') {\n value *= parentAttributes.opacity;\n }\n } else if (attr === 'textAnchor'\n /* text-anchor */\n ) {\n value = value === 'start' ? 'left' : value === 'end' ? 'right' : 'center';\n } else if (attr === 'charSpacing') {\n // parseUnit returns px and we convert it to em\n parsed = parseUnit(value, fontSize) / fontSize * 1000;\n } else if (attr === 'paintFirst') {\n var fillIndex = value.indexOf('fill');\n var strokeIndex = value.indexOf('stroke');\n var value = 'fill';\n\n if (fillIndex > -1 && strokeIndex > -1 && strokeIndex < fillIndex) {\n value = 'stroke';\n } else if (fillIndex === -1 && strokeIndex > -1) {\n value = 'stroke';\n }\n } else if (attr === 'href' || attr === 'xlink:href' || attr === 'font') {\n return value;\n } else if (attr === 'imageSmoothing') {\n return value === 'optimizeQuality' ? true : false;\n } else {\n parsed = isArray ? value.map(parseUnit) : parseUnit(value, fontSize);\n }\n\n return !isArray && isNaN(parsed) ? value : parsed;\n }\n /**\n * @private\n */\n\n\n function getSvgRegex(arr) {\n return new RegExp('^(' + arr.join('|') + ')\\\\b', 'i');\n }\n /**\n * @private\n * @param {Object} attributes Array of attributes to parse\n */\n\n\n function _setStrokeFillOpacity(attributes) {\n for (var attr in colorAttributes) {\n if (typeof attributes[colorAttributes[attr]] === 'undefined' || attributes[attr] === '') {\n continue;\n }\n\n if (typeof attributes[attr] === 'undefined') {\n if (!fabric.Object.prototype[attr]) {\n continue;\n }\n\n attributes[attr] = fabric.Object.prototype[attr];\n }\n\n if (attributes[attr].indexOf('url(') === 0) {\n continue;\n }\n\n var color = new fabric.Color(attributes[attr]);\n attributes[attr] = color.setAlpha(toFixed(color.getAlpha() * attributes[colorAttributes[attr]], 2)).toRgba();\n }\n\n return attributes;\n }\n /**\n * @private\n */\n\n\n function _getMultipleNodes(doc, nodeNames) {\n var nodeName,\n nodeArray = [],\n nodeList,\n i,\n len;\n\n for (i = 0, len = nodeNames.length; i < len; i++) {\n nodeName = nodeNames[i];\n nodeList = doc.getElementsByTagName(nodeName);\n nodeArray = nodeArray.concat(Array.prototype.slice.call(nodeList));\n }\n\n return nodeArray;\n }\n /**\n * Parses \"transform\" attribute, returning an array of values\n * @static\n * @function\n * @memberOf fabric\n * @param {String} attributeValue String containing attribute value\n * @return {Array} Array of 6 elements representing transformation matrix\n */\n\n\n fabric.parseTransformAttribute = function () {\n function rotateMatrix(matrix, args) {\n var cos = fabric.util.cos(args[0]),\n sin = fabric.util.sin(args[0]),\n x = 0,\n y = 0;\n\n if (args.length === 3) {\n x = args[1];\n y = args[2];\n }\n\n matrix[0] = cos;\n matrix[1] = sin;\n matrix[2] = -sin;\n matrix[3] = cos;\n matrix[4] = x - (cos * x - sin * y);\n matrix[5] = y - (sin * x + cos * y);\n }\n\n function scaleMatrix(matrix, args) {\n var multiplierX = args[0],\n multiplierY = args.length === 2 ? args[1] : args[0];\n matrix[0] = multiplierX;\n matrix[3] = multiplierY;\n }\n\n function skewMatrix(matrix, args, pos) {\n matrix[pos] = Math.tan(fabric.util.degreesToRadians(args[0]));\n }\n\n function translateMatrix(matrix, args) {\n matrix[4] = args[0];\n\n if (args.length === 2) {\n matrix[5] = args[1];\n }\n } // identity matrix\n\n\n var iMatrix = fabric.iMatrix,\n // == begin transform regexp\n number = fabric.reNum,\n commaWsp = fabric.commaWsp,\n skewX = '(?:(skewX)\\\\s*\\\\(\\\\s*(' + number + ')\\\\s*\\\\))',\n skewY = '(?:(skewY)\\\\s*\\\\(\\\\s*(' + number + ')\\\\s*\\\\))',\n rotate = '(?:(rotate)\\\\s*\\\\(\\\\s*(' + number + ')(?:' + commaWsp + '(' + number + ')' + commaWsp + '(' + number + '))?\\\\s*\\\\))',\n scale = '(?:(scale)\\\\s*\\\\(\\\\s*(' + number + ')(?:' + commaWsp + '(' + number + '))?\\\\s*\\\\))',\n translate = '(?:(translate)\\\\s*\\\\(\\\\s*(' + number + ')(?:' + commaWsp + '(' + number + '))?\\\\s*\\\\))',\n matrix = '(?:(matrix)\\\\s*\\\\(\\\\s*' + '(' + number + ')' + commaWsp + '(' + number + ')' + commaWsp + '(' + number + ')' + commaWsp + '(' + number + ')' + commaWsp + '(' + number + ')' + commaWsp + '(' + number + ')' + '\\\\s*\\\\))',\n transform = '(?:' + matrix + '|' + translate + '|' + scale + '|' + rotate + '|' + skewX + '|' + skewY + ')',\n transforms = '(?:' + transform + '(?:' + commaWsp + '*' + transform + ')*' + ')',\n transformList = '^\\\\s*(?:' + transforms + '?)\\\\s*$',\n // http://www.w3.org/TR/SVG/coords.html#TransformAttribute\n reTransformList = new RegExp(transformList),\n // == end transform regexp\n reTransform = new RegExp(transform, 'g');\n return function (attributeValue) {\n // start with identity matrix\n var matrix = iMatrix.concat(),\n matrices = []; // return if no argument was given or\n // an argument does not match transform attribute regexp\n\n if (!attributeValue || attributeValue && !reTransformList.test(attributeValue)) {\n return matrix;\n }\n\n attributeValue.replace(reTransform, function (match) {\n var m = new RegExp(transform).exec(match).filter(function (match) {\n // match !== '' && match != null\n return !!match;\n }),\n operation = m[1],\n args = m.slice(2).map(parseFloat);\n\n switch (operation) {\n case 'translate':\n translateMatrix(matrix, args);\n break;\n\n case 'rotate':\n args[0] = fabric.util.degreesToRadians(args[0]);\n rotateMatrix(matrix, args);\n break;\n\n case 'scale':\n scaleMatrix(matrix, args);\n break;\n\n case 'skewX':\n skewMatrix(matrix, args, 2);\n break;\n\n case 'skewY':\n skewMatrix(matrix, args, 1);\n break;\n\n case 'matrix':\n matrix = args;\n break;\n } // snapshot current matrix into matrices array\n\n\n matrices.push(matrix.concat()); // reset\n\n matrix = iMatrix.concat();\n });\n var combinedMatrix = matrices[0];\n\n while (matrices.length > 1) {\n matrices.shift();\n combinedMatrix = fabric.util.multiplyTransformMatrices(combinedMatrix, matrices[0]);\n }\n\n return combinedMatrix;\n };\n }();\n /**\n * @private\n */\n\n\n function parseStyleString(style, oStyle) {\n var attr, value;\n style.replace(/;\\s*$/, '').split(';').forEach(function (chunk) {\n var pair = chunk.split(':');\n attr = pair[0].trim().toLowerCase();\n value = pair[1].trim();\n oStyle[attr] = value;\n });\n }\n /**\n * @private\n */\n\n\n function parseStyleObject(style, oStyle) {\n var attr, value;\n\n for (var prop in style) {\n if (typeof style[prop] === 'undefined') {\n continue;\n }\n\n attr = prop.toLowerCase();\n value = style[prop];\n oStyle[attr] = value;\n }\n }\n /**\n * @private\n */\n\n\n function getGlobalStylesForElement(element, svgUid) {\n var styles = {};\n\n for (var rule in fabric.cssRules[svgUid]) {\n if (elementMatchesRule(element, rule.split(' '))) {\n for (var property in fabric.cssRules[svgUid][rule]) {\n styles[property] = fabric.cssRules[svgUid][rule][property];\n }\n }\n }\n\n return styles;\n }\n /**\n * @private\n */\n\n\n function elementMatchesRule(element, selectors) {\n var firstMatching,\n parentMatching = true; //start from rightmost selector.\n\n firstMatching = selectorMatches(element, selectors.pop());\n\n if (firstMatching && selectors.length) {\n parentMatching = doesSomeParentMatch(element, selectors);\n }\n\n return firstMatching && parentMatching && selectors.length === 0;\n }\n\n function doesSomeParentMatch(element, selectors) {\n var selector,\n parentMatching = true;\n\n while (element.parentNode && element.parentNode.nodeType === 1 && selectors.length) {\n if (parentMatching) {\n selector = selectors.pop();\n }\n\n element = element.parentNode;\n parentMatching = selectorMatches(element, selector);\n }\n\n return selectors.length === 0;\n }\n /**\n * @private\n */\n\n\n function selectorMatches(element, selector) {\n var nodeName = element.nodeName,\n classNames = element.getAttribute('class'),\n id = element.getAttribute('id'),\n matcher,\n i; // i check if a selector matches slicing away part from it.\n // if i get empty string i should match\n\n matcher = new RegExp('^' + nodeName, 'i');\n selector = selector.replace(matcher, '');\n\n if (id && selector.length) {\n matcher = new RegExp('#' + id + '(?![a-zA-Z\\\\-]+)', 'i');\n selector = selector.replace(matcher, '');\n }\n\n if (classNames && selector.length) {\n classNames = classNames.split(' ');\n\n for (i = classNames.length; i--;) {\n matcher = new RegExp('\\\\.' + classNames[i] + '(?![a-zA-Z\\\\-]+)', 'i');\n selector = selector.replace(matcher, '');\n }\n }\n\n return selector.length === 0;\n }\n /**\n * @private\n * to support IE8 missing getElementById on SVGdocument and on node xmlDOM\n */\n\n\n function elementById(doc, id) {\n var el;\n doc.getElementById && (el = doc.getElementById(id));\n\n if (el) {\n return el;\n }\n\n var node,\n i,\n len,\n nodelist = doc.getElementsByTagName('*');\n\n for (i = 0, len = nodelist.length; i < len; i++) {\n node = nodelist[i];\n\n if (id === node.getAttribute('id')) {\n return node;\n }\n }\n }\n /**\n * @private\n */\n\n\n function parseUseDirectives(doc) {\n var nodelist = _getMultipleNodes(doc, ['use', 'svg:use']),\n i = 0;\n\n while (nodelist.length && i < nodelist.length) {\n var el = nodelist[i],\n xlink = (el.getAttribute('xlink:href') || el.getAttribute('href')).substr(1),\n x = el.getAttribute('x') || 0,\n y = el.getAttribute('y') || 0,\n el2 = elementById(doc, xlink).cloneNode(true),\n currentTrans = (el2.getAttribute('transform') || '') + ' translate(' + x + ', ' + y + ')',\n parentNode,\n oldLength = nodelist.length,\n attr,\n j,\n attrs,\n len,\n namespace = fabric.svgNS;\n applyViewboxTransform(el2);\n\n if (/^svg$/i.test(el2.nodeName)) {\n var el3 = el2.ownerDocument.createElementNS(namespace, 'g');\n\n for (j = 0, attrs = el2.attributes, len = attrs.length; j < len; j++) {\n attr = attrs.item(j);\n el3.setAttributeNS(namespace, attr.nodeName, attr.nodeValue);\n } // el2.firstChild != null\n\n\n while (el2.firstChild) {\n el3.appendChild(el2.firstChild);\n }\n\n el2 = el3;\n }\n\n for (j = 0, attrs = el.attributes, len = attrs.length; j < len; j++) {\n attr = attrs.item(j);\n\n if (attr.nodeName === 'x' || attr.nodeName === 'y' || attr.nodeName === 'xlink:href' || attr.nodeName === 'href') {\n continue;\n }\n\n if (attr.nodeName === 'transform') {\n currentTrans = attr.nodeValue + ' ' + currentTrans;\n } else {\n el2.setAttribute(attr.nodeName, attr.nodeValue);\n }\n }\n\n el2.setAttribute('transform', currentTrans);\n el2.setAttribute('instantiated_by_use', '1');\n el2.removeAttribute('id');\n parentNode = el.parentNode;\n parentNode.replaceChild(el2, el); // some browsers do not shorten nodelist after replaceChild (IE8)\n\n if (nodelist.length === oldLength) {\n i++;\n }\n }\n } // http://www.w3.org/TR/SVG/coords.html#ViewBoxAttribute\n // matches, e.g.: +14.56e-12, etc.\n\n\n var reViewBoxAttrValue = new RegExp('^' + '\\\\s*(' + fabric.reNum + '+)\\\\s*,?' + '\\\\s*(' + fabric.reNum + '+)\\\\s*,?' + '\\\\s*(' + fabric.reNum + '+)\\\\s*,?' + '\\\\s*(' + fabric.reNum + '+)\\\\s*' + '$');\n /**\n * Add a <g> element that envelop all child elements and makes the viewbox transformMatrix descend on all elements\n */\n\n function applyViewboxTransform(element) {\n if (!fabric.svgViewBoxElementsRegEx.test(element.nodeName)) {\n return;\n }\n\n var viewBoxAttr = element.getAttribute('viewBox'),\n scaleX = 1,\n scaleY = 1,\n minX = 0,\n minY = 0,\n viewBoxWidth,\n viewBoxHeight,\n matrix,\n el,\n widthAttr = element.getAttribute('width'),\n heightAttr = element.getAttribute('height'),\n x = element.getAttribute('x') || 0,\n y = element.getAttribute('y') || 0,\n preserveAspectRatio = element.getAttribute('preserveAspectRatio') || '',\n missingViewBox = !viewBoxAttr || !(viewBoxAttr = viewBoxAttr.match(reViewBoxAttrValue)),\n missingDimAttr = !widthAttr || !heightAttr || widthAttr === '100%' || heightAttr === '100%',\n toBeParsed = missingViewBox && missingDimAttr,\n parsedDim = {},\n translateMatrix = '',\n widthDiff = 0,\n heightDiff = 0;\n parsedDim.width = 0;\n parsedDim.height = 0;\n parsedDim.toBeParsed = toBeParsed;\n\n if (missingViewBox) {\n if ((x || y) && element.parentNode.nodeName !== '#document') {\n translateMatrix = ' translate(' + parseUnit(x) + ' ' + parseUnit(y) + ') ';\n matrix = (element.getAttribute('transform') || '') + translateMatrix;\n element.setAttribute('transform', matrix);\n element.removeAttribute('x');\n element.removeAttribute('y');\n }\n }\n\n if (toBeParsed) {\n return parsedDim;\n }\n\n if (missingViewBox) {\n parsedDim.width = parseUnit(widthAttr);\n parsedDim.height = parseUnit(heightAttr); // set a transform for elements that have x y and are inner(only) SVGs\n\n return parsedDim;\n }\n\n minX = -parseFloat(viewBoxAttr[1]);\n minY = -parseFloat(viewBoxAttr[2]);\n viewBoxWidth = parseFloat(viewBoxAttr[3]);\n viewBoxHeight = parseFloat(viewBoxAttr[4]);\n parsedDim.minX = minX;\n parsedDim.minY = minY;\n parsedDim.viewBoxWidth = viewBoxWidth;\n parsedDim.viewBoxHeight = viewBoxHeight;\n\n if (!missingDimAttr) {\n parsedDim.width = parseUnit(widthAttr);\n parsedDim.height = parseUnit(heightAttr);\n scaleX = parsedDim.width / viewBoxWidth;\n scaleY = parsedDim.height / viewBoxHeight;\n } else {\n parsedDim.width = viewBoxWidth;\n parsedDim.height = viewBoxHeight;\n } // default is to preserve aspect ratio\n\n\n preserveAspectRatio = fabric.util.parsePreserveAspectRatioAttribute(preserveAspectRatio);\n\n if (preserveAspectRatio.alignX !== 'none') {\n //translate all container for the effect of Mid, Min, Max\n if (preserveAspectRatio.meetOrSlice === 'meet') {\n scaleY = scaleX = scaleX > scaleY ? scaleY : scaleX; // calculate additional translation to move the viewbox\n }\n\n if (preserveAspectRatio.meetOrSlice === 'slice') {\n scaleY = scaleX = scaleX > scaleY ? scaleX : scaleY; // calculate additional translation to move the viewbox\n }\n\n widthDiff = parsedDim.width - viewBoxWidth * scaleX;\n heightDiff = parsedDim.height - viewBoxHeight * scaleX;\n\n if (preserveAspectRatio.alignX === 'Mid') {\n widthDiff /= 2;\n }\n\n if (preserveAspectRatio.alignY === 'Mid') {\n heightDiff /= 2;\n }\n\n if (preserveAspectRatio.alignX === 'Min') {\n widthDiff = 0;\n }\n\n if (preserveAspectRatio.alignY === 'Min') {\n heightDiff = 0;\n }\n }\n\n if (scaleX === 1 && scaleY === 1 && minX === 0 && minY === 0 && x === 0 && y === 0) {\n return parsedDim;\n }\n\n if ((x || y) && element.parentNode.nodeName !== '#document') {\n translateMatrix = ' translate(' + parseUnit(x) + ' ' + parseUnit(y) + ') ';\n }\n\n matrix = translateMatrix + ' matrix(' + scaleX + ' 0' + ' 0 ' + scaleY + ' ' + (minX * scaleX + widthDiff) + ' ' + (minY * scaleY + heightDiff) + ') '; // seems unused.\n // parsedDim.viewboxTransform = fabric.parseTransformAttribute(matrix);\n\n if (element.nodeName === 'svg') {\n el = element.ownerDocument.createElementNS(fabric.svgNS, 'g'); // element.firstChild != null\n\n while (element.firstChild) {\n el.appendChild(element.firstChild);\n }\n\n element.appendChild(el);\n } else {\n el = element;\n el.removeAttribute('x');\n el.removeAttribute('y');\n matrix = el.getAttribute('transform') + matrix;\n }\n\n el.setAttribute('transform', matrix);\n return parsedDim;\n }\n\n function hasAncestorWithNodeName(element, nodeName) {\n while (element && (element = element.parentNode)) {\n if (element.nodeName && nodeName.test(element.nodeName.replace('svg:', '')) && !element.getAttribute('instantiated_by_use')) {\n return true;\n }\n }\n\n return false;\n }\n /**\n * Parses an SVG document, converts it to an array of corresponding fabric.* instances and passes them to a callback\n * @static\n * @function\n * @memberOf fabric\n * @param {SVGDocument} doc SVG document to parse\n * @param {Function} callback Callback to call when parsing is finished;\n * It's being passed an array of elements (parsed from a document).\n * @param {Function} [reviver] Method for further parsing of SVG elements, called after each fabric object created.\n * @param {Object} [parsingOptions] options for parsing document\n * @param {String} [parsingOptions.crossOrigin] crossOrigin settings\n */\n\n\n fabric.parseSVGDocument = function (doc, callback, reviver, parsingOptions) {\n if (!doc) {\n return;\n }\n\n parseUseDirectives(doc);\n var svgUid = fabric.Object.__uid++,\n i,\n len,\n options = applyViewboxTransform(doc),\n descendants = fabric.util.toArray(doc.getElementsByTagName('*'));\n options.crossOrigin = parsingOptions && parsingOptions.crossOrigin;\n options.svgUid = svgUid;\n\n if (descendants.length === 0 && fabric.isLikelyNode) {\n // we're likely in node, where \"o3-xml\" library fails to gEBTN(\"*\")\n // https://github.com/ajaxorg/node-o3-xml/issues/21\n descendants = doc.selectNodes('//*[name(.)!=\"svg\"]');\n var arr = [];\n\n for (i = 0, len = descendants.length; i < len; i++) {\n arr[i] = descendants[i];\n }\n\n descendants = arr;\n }\n\n var elements = descendants.filter(function (el) {\n applyViewboxTransform(el);\n return fabric.svgValidTagNamesRegEx.test(el.nodeName.replace('svg:', '')) && !hasAncestorWithNodeName(el, fabric.svgInvalidAncestorsRegEx); // http://www.w3.org/TR/SVG/struct.html#DefsElement\n });\n\n if (!elements || elements && !elements.length) {\n callback && callback([], {});\n return;\n }\n\n var clipPaths = {};\n descendants.filter(function (el) {\n return el.nodeName.replace('svg:', '') === 'clipPath';\n }).forEach(function (el) {\n var id = el.getAttribute('id');\n clipPaths[id] = fabric.util.toArray(el.getElementsByTagName('*')).filter(function (el) {\n return fabric.svgValidTagNamesRegEx.test(el.nodeName.replace('svg:', ''));\n });\n });\n fabric.gradientDefs[svgUid] = fabric.getGradientDefs(doc);\n fabric.cssRules[svgUid] = fabric.getCSSRules(doc);\n fabric.clipPaths[svgUid] = clipPaths; // Precedence of rules: style > class > attribute\n\n fabric.parseElements(elements, function (instances, elements) {\n if (callback) {\n callback(instances, options, elements, descendants);\n delete fabric.gradientDefs[svgUid];\n delete fabric.cssRules[svgUid];\n delete fabric.clipPaths[svgUid];\n }\n }, clone(options), reviver, parsingOptions);\n };\n\n function recursivelyParseGradientsXlink(doc, gradient) {\n var gradientsAttrs = ['gradientTransform', 'x1', 'x2', 'y1', 'y2', 'gradientUnits', 'cx', 'cy', 'r', 'fx', 'fy'],\n xlinkAttr = 'xlink:href',\n xLink = gradient.getAttribute(xlinkAttr).substr(1),\n referencedGradient = elementById(doc, xLink);\n\n if (referencedGradient && referencedGradient.getAttribute(xlinkAttr)) {\n recursivelyParseGradientsXlink(doc, referencedGradient);\n }\n\n gradientsAttrs.forEach(function (attr) {\n if (referencedGradient && !gradient.hasAttribute(attr) && referencedGradient.hasAttribute(attr)) {\n gradient.setAttribute(attr, referencedGradient.getAttribute(attr));\n }\n });\n\n if (!gradient.children.length) {\n var referenceClone = referencedGradient.cloneNode(true);\n\n while (referenceClone.firstChild) {\n gradient.appendChild(referenceClone.firstChild);\n }\n }\n\n gradient.removeAttribute(xlinkAttr);\n }\n\n var reFontDeclaration = new RegExp('(normal|italic)?\\\\s*(normal|small-caps)?\\\\s*' + '(normal|bold|bolder|lighter|100|200|300|400|500|600|700|800|900)?\\\\s*(' + fabric.reNum + '(?:px|cm|mm|em|pt|pc|in)*)(?:\\\\/(normal|' + fabric.reNum + '))?\\\\s+(.*)');\n extend(fabric, {\n /**\n * Parses a short font declaration, building adding its properties to a style object\n * @static\n * @function\n * @memberOf fabric\n * @param {String} value font declaration\n * @param {Object} oStyle definition\n */\n parseFontDeclaration: function (value, oStyle) {\n var match = value.match(reFontDeclaration);\n\n if (!match) {\n return;\n }\n\n var fontStyle = match[1],\n // font variant is not used\n // fontVariant = match[2],\n fontWeight = match[3],\n fontSize = match[4],\n lineHeight = match[5],\n fontFamily = match[6];\n\n if (fontStyle) {\n oStyle.fontStyle = fontStyle;\n }\n\n if (fontWeight) {\n oStyle.fontWeight = isNaN(parseFloat(fontWeight)) ? fontWeight : parseFloat(fontWeight);\n }\n\n if (fontSize) {\n oStyle.fontSize = parseUnit(fontSize);\n }\n\n if (fontFamily) {\n oStyle.fontFamily = fontFamily;\n }\n\n if (lineHeight) {\n oStyle.lineHeight = lineHeight === 'normal' ? 1 : lineHeight;\n }\n },\n\n /**\n * Parses an SVG document, returning all of the gradient declarations found in it\n * @static\n * @function\n * @memberOf fabric\n * @param {SVGDocument} doc SVG document to parse\n * @return {Object} Gradient definitions; key corresponds to element id, value -- to gradient definition element\n */\n getGradientDefs: function (doc) {\n var tagArray = ['linearGradient', 'radialGradient', 'svg:linearGradient', 'svg:radialGradient'],\n elList = _getMultipleNodes(doc, tagArray),\n el,\n j = 0,\n gradientDefs = {};\n\n j = elList.length;\n\n while (j--) {\n el = elList[j];\n\n if (el.getAttribute('xlink:href')) {\n recursivelyParseGradientsXlink(doc, el);\n }\n\n gradientDefs[el.getAttribute('id')] = el;\n }\n\n return gradientDefs;\n },\n\n /**\n * Returns an object of attributes' name/value, given element and an array of attribute names;\n * Parses parent \"g\" nodes recursively upwards.\n * @static\n * @memberOf fabric\n * @param {DOMElement} element Element to parse\n * @param {Array} attributes Array of attributes to parse\n * @return {Object} object containing parsed attributes' names/values\n */\n parseAttributes: function (element, attributes, svgUid) {\n if (!element) {\n return;\n }\n\n var value,\n parentAttributes = {},\n fontSize,\n parentFontSize;\n\n if (typeof svgUid === 'undefined') {\n svgUid = element.getAttribute('svgUid');\n } // if there's a parent container (`g` or `a` or `symbol` node), parse its attributes recursively upwards\n\n\n if (element.parentNode && fabric.svgValidParentsRegEx.test(element.parentNode.nodeName)) {\n parentAttributes = fabric.parseAttributes(element.parentNode, attributes, svgUid);\n }\n\n var ownAttributes = attributes.reduce(function (memo, attr) {\n value = element.getAttribute(attr);\n\n if (value) {\n // eslint-disable-line\n memo[attr] = value;\n }\n\n return memo;\n }, {}); // add values parsed from style, which take precedence over attributes\n // (see: http://www.w3.org/TR/SVG/styling.html#UsingPresentationAttributes)\n\n var cssAttrs = extend(getGlobalStylesForElement(element, svgUid), fabric.parseStyleAttribute(element));\n ownAttributes = extend(ownAttributes, cssAttrs);\n\n if (cssAttrs[cPath]) {\n element.setAttribute(cPath, cssAttrs[cPath]);\n }\n\n fontSize = parentFontSize = parentAttributes.fontSize || fabric.Text.DEFAULT_SVG_FONT_SIZE;\n\n if (ownAttributes[fSize]) {\n // looks like the minimum should be 9px when dealing with ems. this is what looks like in browsers.\n ownAttributes[fSize] = fontSize = parseUnit(ownAttributes[fSize], parentFontSize);\n }\n\n var normalizedAttr,\n normalizedValue,\n normalizedStyle = {};\n\n for (var attr in ownAttributes) {\n normalizedAttr = normalizeAttr(attr);\n normalizedValue = normalizeValue(normalizedAttr, ownAttributes[attr], parentAttributes, fontSize);\n normalizedStyle[normalizedAttr] = normalizedValue;\n }\n\n if (normalizedStyle && normalizedStyle.font) {\n fabric.parseFontDeclaration(normalizedStyle.font, normalizedStyle);\n }\n\n var mergedAttrs = extend(parentAttributes, normalizedStyle);\n return fabric.svgValidParentsRegEx.test(element.nodeName) ? mergedAttrs : _setStrokeFillOpacity(mergedAttrs);\n },\n\n /**\n * Transforms an array of svg elements to corresponding fabric.* instances\n * @static\n * @memberOf fabric\n * @param {Array} elements Array of elements to parse\n * @param {Function} callback Being passed an array of fabric instances (transformed from SVG elements)\n * @param {Object} [options] Options object\n * @param {Function} [reviver] Method for further parsing of SVG elements, called after each fabric object created.\n */\n parseElements: function (elements, callback, options, reviver, parsingOptions) {\n new fabric.ElementsParser(elements, callback, options, reviver, parsingOptions).parse();\n },\n\n /**\n * Parses \"style\" attribute, retuning an object with values\n * @static\n * @memberOf fabric\n * @param {SVGElement} element Element to parse\n * @return {Object} Objects with values parsed from style attribute of an element\n */\n parseStyleAttribute: function (element) {\n var oStyle = {},\n style = element.getAttribute('style');\n\n if (!style) {\n return oStyle;\n }\n\n if (typeof style === 'string') {\n parseStyleString(style, oStyle);\n } else {\n parseStyleObject(style, oStyle);\n }\n\n return oStyle;\n },\n\n /**\n * Parses \"points\" attribute, returning an array of values\n * @static\n * @memberOf fabric\n * @param {String} points points attribute string\n * @return {Array} array of points\n */\n parsePointsAttribute: function (points) {\n // points attribute is required and must not be empty\n if (!points) {\n return null;\n } // replace commas with whitespace and remove bookending whitespace\n\n\n points = points.replace(/,/g, ' ').trim();\n points = points.split(/\\s+/);\n var parsedPoints = [],\n i,\n len;\n\n for (i = 0, len = points.length; i < len; i += 2) {\n parsedPoints.push({\n x: parseFloat(points[i]),\n y: parseFloat(points[i + 1])\n });\n } // odd number of points is an error\n // if (parsedPoints.length % 2 !== 0) {\n // return null;\n // }\n\n\n return parsedPoints;\n },\n\n /**\n * Returns CSS rules for a given SVG document\n * @static\n * @function\n * @memberOf fabric\n * @param {SVGDocument} doc SVG document to parse\n * @return {Object} CSS rules of this document\n */\n getCSSRules: function (doc) {\n var styles = doc.getElementsByTagName('style'),\n i,\n len,\n allRules = {},\n rules; // very crude parsing of style contents\n\n for (i = 0, len = styles.length; i < len; i++) {\n // <style/> could produce `undefined`, covering this case with ''\n var styleContents = styles[i].textContent || ''; // remove comments\n\n styleContents = styleContents.replace(/\\/\\*[\\s\\S]*?\\*\\//g, '');\n\n if (styleContents.trim() === '') {\n continue;\n }\n\n rules = styleContents.match(/[^{]*\\{[\\s\\S]*?\\}/g);\n rules = rules.map(function (rule) {\n return rule.trim();\n }); // eslint-disable-next-line no-loop-func\n\n rules.forEach(function (rule) {\n var match = rule.match(/([\\s\\S]*?)\\s*\\{([^}]*)\\}/),\n ruleObj = {},\n declaration = match[2].trim(),\n propertyValuePairs = declaration.replace(/;$/, '').split(/\\s*;\\s*/);\n\n for (i = 0, len = propertyValuePairs.length; i < len; i++) {\n var pair = propertyValuePairs[i].split(/\\s*:\\s*/),\n property = pair[0],\n value = pair[1];\n ruleObj[property] = value;\n }\n\n rule = match[1];\n rule.split(',').forEach(function (_rule) {\n _rule = _rule.replace(/^svg/i, '').trim();\n\n if (_rule === '') {\n return;\n }\n\n if (allRules[_rule]) {\n fabric.util.object.extend(allRules[_rule], ruleObj);\n } else {\n allRules[_rule] = fabric.util.object.clone(ruleObj);\n }\n });\n });\n }\n\n return allRules;\n },\n\n /**\n * Takes url corresponding to an SVG document, and parses it into a set of fabric objects.\n * Note that SVG is fetched via XMLHttpRequest, so it needs to conform to SOP (Same Origin Policy)\n * @memberOf fabric\n * @param {String} url\n * @param {Function} callback\n * @param {Function} [reviver] Method for further parsing of SVG elements, called after each fabric object created.\n * @param {Object} [options] Object containing options for parsing\n * @param {String} [options.crossOrigin] crossOrigin crossOrigin setting to use for external resources\n */\n loadSVGFromURL: function (url, callback, reviver, options) {\n url = url.replace(/^\\n\\s*/, '').trim();\n new fabric.util.request(url, {\n method: 'get',\n onComplete: onComplete\n });\n\n function onComplete(r) {\n var xml = r.responseXML;\n\n if (!xml || !xml.documentElement) {\n callback && callback(null);\n return false;\n }\n\n fabric.parseSVGDocument(xml.documentElement, function (results, _options, elements, allElements) {\n callback && callback(results, _options, elements, allElements);\n }, reviver, options);\n }\n },\n\n /**\n * Takes string corresponding to an SVG document, and parses it into a set of fabric objects\n * @memberOf fabric\n * @param {String} string\n * @param {Function} callback\n * @param {Function} [reviver] Method for further parsing of SVG elements, called after each fabric object created.\n * @param {Object} [options] Object containing options for parsing\n * @param {String} [options.crossOrigin] crossOrigin crossOrigin setting to use for external resources\n */\n loadSVGFromString: function (string, callback, reviver, options) {\n var parser = new fabric.window.DOMParser(),\n doc = parser.parseFromString(string.trim(), 'text/xml');\n fabric.parseSVGDocument(doc.documentElement, function (results, _options, elements, allElements) {\n callback(results, _options, elements, allElements);\n }, reviver, options);\n }\n });\n})(typeof exports !== 'undefined' ? exports : this);\n\nfabric.ElementsParser = function (elements, callback, options, reviver, parsingOptions, doc) {\n this.elements = elements;\n this.callback = callback;\n this.options = options;\n this.reviver = reviver;\n this.svgUid = options && options.svgUid || 0;\n this.parsingOptions = parsingOptions;\n this.regexUrl = /^url\\(['\"]?#([^'\"]+)['\"]?\\)/g;\n this.doc = doc;\n};\n\n(function (proto) {\n proto.parse = function () {\n this.instances = new Array(this.elements.length);\n this.numElements = this.elements.length;\n this.createObjects();\n };\n\n proto.createObjects = function () {\n var _this = this;\n\n this.elements.forEach(function (element, i) {\n element.setAttribute('svgUid', _this.svgUid);\n\n _this.createObject(element, i);\n });\n };\n\n proto.findTag = function (el) {\n return fabric[fabric.util.string.capitalize(el.tagName.replace('svg:', ''))];\n };\n\n proto.createObject = function (el, index) {\n var klass = this.findTag(el);\n\n if (klass && klass.fromElement) {\n try {\n klass.fromElement(el, this.createCallback(index, el), this.options);\n } catch (err) {\n fabric.log(err);\n }\n } else {\n this.checkIfDone();\n }\n };\n\n proto.createCallback = function (index, el) {\n var _this = this;\n\n return function (obj) {\n var _options;\n\n _this.resolveGradient(obj, el, 'fill');\n\n _this.resolveGradient(obj, el, 'stroke');\n\n if (obj instanceof fabric.Image && obj._originalElement) {\n _options = obj.parsePreserveAspectRatioAttribute(el);\n }\n\n obj._removeTransformMatrix(_options);\n\n _this.resolveClipPath(obj, el);\n\n _this.reviver && _this.reviver(el, obj);\n _this.instances[index] = obj;\n\n _this.checkIfDone();\n };\n };\n\n proto.extractPropertyDefinition = function (obj, property, storage) {\n var value = obj[property],\n regex = this.regexUrl;\n\n if (!regex.test(value)) {\n return;\n }\n\n regex.lastIndex = 0;\n var id = regex.exec(value)[1];\n regex.lastIndex = 0;\n return fabric[storage][this.svgUid][id];\n };\n\n proto.resolveGradient = function (obj, el, property) {\n var gradientDef = this.extractPropertyDefinition(obj, property, 'gradientDefs');\n\n if (gradientDef) {\n var opacityAttr = el.getAttribute(property + '-opacity');\n var gradient = fabric.Gradient.fromElement(gradientDef, obj, opacityAttr, this.options);\n obj.set(property, gradient);\n }\n };\n\n proto.createClipPathCallback = function (obj, container) {\n return function (_newObj) {\n _newObj._removeTransformMatrix();\n\n _newObj.fillRule = _newObj.clipRule;\n container.push(_newObj);\n };\n };\n\n proto.resolveClipPath = function (obj, usingElement) {\n var clipPath = this.extractPropertyDefinition(obj, 'clipPath', 'clipPaths'),\n element,\n klass,\n objTransformInv,\n container,\n gTransform,\n options;\n\n if (clipPath) {\n container = [];\n objTransformInv = fabric.util.invertTransform(obj.calcTransformMatrix()); // move the clipPath tag as sibling to the real element that is using it\n\n var clipPathTag = clipPath[0].parentNode;\n var clipPathOwner = usingElement;\n\n while (clipPathOwner.parentNode && clipPathOwner.getAttribute('clip-path') !== obj.clipPath) {\n clipPathOwner = clipPathOwner.parentNode;\n }\n\n clipPathOwner.parentNode.appendChild(clipPathTag);\n\n for (var i = 0; i < clipPath.length; i++) {\n element = clipPath[i];\n klass = this.findTag(element);\n klass.fromElement(element, this.createClipPathCallback(obj, container), this.options);\n }\n\n if (container.length === 1) {\n clipPath = container[0];\n } else {\n clipPath = new fabric.Group(container);\n }\n\n gTransform = fabric.util.multiplyTransformMatrices(objTransformInv, clipPath.calcTransformMatrix());\n\n if (clipPath.clipPath) {\n this.resolveClipPath(clipPath, clipPathOwner);\n }\n\n var options = fabric.util.qrDecompose(gTransform);\n clipPath.flipX = false;\n clipPath.flipY = false;\n clipPath.set('scaleX', options.scaleX);\n clipPath.set('scaleY', options.scaleY);\n clipPath.angle = options.angle;\n clipPath.skewX = options.skewX;\n clipPath.skewY = 0;\n clipPath.setPositionByOrigin({\n x: options.translateX,\n y: options.translateY\n }, 'center', 'center');\n obj.clipPath = clipPath;\n } else {\n // if clip-path does not resolve to any element, delete the property.\n delete obj.clipPath;\n }\n };\n\n proto.checkIfDone = function () {\n if (--this.numElements === 0) {\n this.instances = this.instances.filter(function (el) {\n // eslint-disable-next-line no-eq-null, eqeqeq\n return el != null;\n });\n this.callback(this.instances, this.elements);\n }\n };\n})(fabric.ElementsParser.prototype);\n\n(function (global) {\n 'use strict';\n /* Adaptation of work of Kevin Lindsey (kevin@kevlindev.com) */\n\n var fabric = global.fabric || (global.fabric = {});\n\n if (fabric.Point) {\n fabric.warn('fabric.Point is already defined');\n return;\n }\n\n fabric.Point = Point;\n /**\n * Point class\n * @class fabric.Point\n * @memberOf fabric\n * @constructor\n * @param {Number} x\n * @param {Number} y\n * @return {fabric.Point} thisArg\n */\n\n function Point(x, y) {\n this.x = x;\n this.y = y;\n }\n\n Point.prototype =\n /** @lends fabric.Point.prototype */\n {\n type: 'point',\n constructor: Point,\n\n /**\n * Adds another point to this one and returns another one\n * @param {fabric.Point} that\n * @return {fabric.Point} new Point instance with added values\n */\n add: function (that) {\n return new Point(this.x + that.x, this.y + that.y);\n },\n\n /**\n * Adds another point to this one\n * @param {fabric.Point} that\n * @return {fabric.Point} thisArg\n * @chainable\n */\n addEquals: function (that) {\n this.x += that.x;\n this.y += that.y;\n return this;\n },\n\n /**\n * Adds value to this point and returns a new one\n * @param {Number} scalar\n * @return {fabric.Point} new Point with added value\n */\n scalarAdd: function (scalar) {\n return new Point(this.x + scalar, this.y + scalar);\n },\n\n /**\n * Adds value to this point\n * @param {Number} scalar\n * @return {fabric.Point} thisArg\n * @chainable\n */\n scalarAddEquals: function (scalar) {\n this.x += scalar;\n this.y += scalar;\n return this;\n },\n\n /**\n * Subtracts another point from this point and returns a new one\n * @param {fabric.Point} that\n * @return {fabric.Point} new Point object with subtracted values\n */\n subtract: function (that) {\n return new Point(this.x - that.x, this.y - that.y);\n },\n\n /**\n * Subtracts another point from this point\n * @param {fabric.Point} that\n * @return {fabric.Point} thisArg\n * @chainable\n */\n subtractEquals: function (that) {\n this.x -= that.x;\n this.y -= that.y;\n return this;\n },\n\n /**\n * Subtracts value from this point and returns a new one\n * @param {Number} scalar\n * @return {fabric.Point}\n */\n scalarSubtract: function (scalar) {\n return new Point(this.x - scalar, this.y - scalar);\n },\n\n /**\n * Subtracts value from this point\n * @param {Number} scalar\n * @return {fabric.Point} thisArg\n * @chainable\n */\n scalarSubtractEquals: function (scalar) {\n this.x -= scalar;\n this.y -= scalar;\n return this;\n },\n\n /**\n * Multiplies this point by a value and returns a new one\n * TODO: rename in scalarMultiply in 2.0\n * @param {Number} scalar\n * @return {fabric.Point}\n */\n multiply: function (scalar) {\n return new Point(this.x * scalar, this.y * scalar);\n },\n\n /**\n * Multiplies this point by a value\n * TODO: rename in scalarMultiplyEquals in 2.0\n * @param {Number} scalar\n * @return {fabric.Point} thisArg\n * @chainable\n */\n multiplyEquals: function (scalar) {\n this.x *= scalar;\n this.y *= scalar;\n return this;\n },\n\n /**\n * Divides this point by a value and returns a new one\n * TODO: rename in scalarDivide in 2.0\n * @param {Number} scalar\n * @return {fabric.Point}\n */\n divide: function (scalar) {\n return new Point(this.x / scalar, this.y / scalar);\n },\n\n /**\n * Divides this point by a value\n * TODO: rename in scalarDivideEquals in 2.0\n * @param {Number} scalar\n * @return {fabric.Point} thisArg\n * @chainable\n */\n divideEquals: function (scalar) {\n this.x /= scalar;\n this.y /= scalar;\n return this;\n },\n\n /**\n * Returns true if this point is equal to another one\n * @param {fabric.Point} that\n * @return {Boolean}\n */\n eq: function (that) {\n return this.x === that.x && this.y === that.y;\n },\n\n /**\n * Returns true if this point is less than another one\n * @param {fabric.Point} that\n * @return {Boolean}\n */\n lt: function (that) {\n return this.x < that.x && this.y < that.y;\n },\n\n /**\n * Returns true if this point is less than or equal to another one\n * @param {fabric.Point} that\n * @return {Boolean}\n */\n lte: function (that) {\n return this.x <= that.x && this.y <= that.y;\n },\n\n /**\n * Returns true if this point is greater another one\n * @param {fabric.Point} that\n * @return {Boolean}\n */\n gt: function (that) {\n return this.x > that.x && this.y > that.y;\n },\n\n /**\n * Returns true if this point is greater than or equal to another one\n * @param {fabric.Point} that\n * @return {Boolean}\n */\n gte: function (that) {\n return this.x >= that.x && this.y >= that.y;\n },\n\n /**\n * Returns new point which is the result of linear interpolation with this one and another one\n * @param {fabric.Point} that\n * @param {Number} t , position of interpolation, between 0 and 1 default 0.5\n * @return {fabric.Point}\n */\n lerp: function (that, t) {\n if (typeof t === 'undefined') {\n t = 0.5;\n }\n\n t = Math.max(Math.min(1, t), 0);\n return new Point(this.x + (that.x - this.x) * t, this.y + (that.y - this.y) * t);\n },\n\n /**\n * Returns distance from this point and another one\n * @param {fabric.Point} that\n * @return {Number}\n */\n distanceFrom: function (that) {\n var dx = this.x - that.x,\n dy = this.y - that.y;\n return Math.sqrt(dx * dx + dy * dy);\n },\n\n /**\n * Returns the point between this point and another one\n * @param {fabric.Point} that\n * @return {fabric.Point}\n */\n midPointFrom: function (that) {\n return this.lerp(that);\n },\n\n /**\n * Returns a new point which is the min of this and another one\n * @param {fabric.Point} that\n * @return {fabric.Point}\n */\n min: function (that) {\n return new Point(Math.min(this.x, that.x), Math.min(this.y, that.y));\n },\n\n /**\n * Returns a new point which is the max of this and another one\n * @param {fabric.Point} that\n * @return {fabric.Point}\n */\n max: function (that) {\n return new Point(Math.max(this.x, that.x), Math.max(this.y, that.y));\n },\n\n /**\n * Returns string representation of this point\n * @return {String}\n */\n toString: function () {\n return this.x + ',' + this.y;\n },\n\n /**\n * Sets x/y of this point\n * @param {Number} x\n * @param {Number} y\n * @chainable\n */\n setXY: function (x, y) {\n this.x = x;\n this.y = y;\n return this;\n },\n\n /**\n * Sets x of this point\n * @param {Number} x\n * @chainable\n */\n setX: function (x) {\n this.x = x;\n return this;\n },\n\n /**\n * Sets y of this point\n * @param {Number} y\n * @chainable\n */\n setY: function (y) {\n this.y = y;\n return this;\n },\n\n /**\n * Sets x/y of this point from another point\n * @param {fabric.Point} that\n * @chainable\n */\n setFromPoint: function (that) {\n this.x = that.x;\n this.y = that.y;\n return this;\n },\n\n /**\n * Swaps x/y of this point and another point\n * @param {fabric.Point} that\n */\n swap: function (that) {\n var x = this.x,\n y = this.y;\n this.x = that.x;\n this.y = that.y;\n that.x = x;\n that.y = y;\n },\n\n /**\n * return a cloned instance of the point\n * @return {fabric.Point}\n */\n clone: function () {\n return new Point(this.x, this.y);\n }\n };\n})(typeof exports !== 'undefined' ? exports : this);\n\n(function (global) {\n 'use strict';\n /* Adaptation of work of Kevin Lindsey (kevin@kevlindev.com) */\n\n var fabric = global.fabric || (global.fabric = {});\n\n if (fabric.Intersection) {\n fabric.warn('fabric.Intersection is already defined');\n return;\n }\n /**\n * Intersection class\n * @class fabric.Intersection\n * @memberOf fabric\n * @constructor\n */\n\n\n function Intersection(status) {\n this.status = status;\n this.points = [];\n }\n\n fabric.Intersection = Intersection;\n fabric.Intersection.prototype =\n /** @lends fabric.Intersection.prototype */\n {\n constructor: Intersection,\n\n /**\n * Appends a point to intersection\n * @param {fabric.Point} point\n * @return {fabric.Intersection} thisArg\n * @chainable\n */\n appendPoint: function (point) {\n this.points.push(point);\n return this;\n },\n\n /**\n * Appends points to intersection\n * @param {Array} points\n * @return {fabric.Intersection} thisArg\n * @chainable\n */\n appendPoints: function (points) {\n this.points = this.points.concat(points);\n return this;\n }\n };\n /**\n * Checks if one line intersects another\n * TODO: rename in intersectSegmentSegment\n * @static\n * @param {fabric.Point} a1\n * @param {fabric.Point} a2\n * @param {fabric.Point} b1\n * @param {fabric.Point} b2\n * @return {fabric.Intersection}\n */\n\n fabric.Intersection.intersectLineLine = function (a1, a2, b1, b2) {\n var result,\n uaT = (b2.x - b1.x) * (a1.y - b1.y) - (b2.y - b1.y) * (a1.x - b1.x),\n ubT = (a2.x - a1.x) * (a1.y - b1.y) - (a2.y - a1.y) * (a1.x - b1.x),\n uB = (b2.y - b1.y) * (a2.x - a1.x) - (b2.x - b1.x) * (a2.y - a1.y);\n\n if (uB !== 0) {\n var ua = uaT / uB,\n ub = ubT / uB;\n\n if (0 <= ua && ua <= 1 && 0 <= ub && ub <= 1) {\n result = new Intersection('Intersection');\n result.appendPoint(new fabric.Point(a1.x + ua * (a2.x - a1.x), a1.y + ua * (a2.y - a1.y)));\n } else {\n result = new Intersection();\n }\n } else {\n if (uaT === 0 || ubT === 0) {\n result = new Intersection('Coincident');\n } else {\n result = new Intersection('Parallel');\n }\n }\n\n return result;\n };\n /**\n * Checks if line intersects polygon\n * TODO: rename in intersectSegmentPolygon\n * fix detection of coincident\n * @static\n * @param {fabric.Point} a1\n * @param {fabric.Point} a2\n * @param {Array} points\n * @return {fabric.Intersection}\n */\n\n\n fabric.Intersection.intersectLinePolygon = function (a1, a2, points) {\n var result = new Intersection(),\n length = points.length,\n b1,\n b2,\n inter,\n i;\n\n for (i = 0; i < length; i++) {\n b1 = points[i];\n b2 = points[(i + 1) % length];\n inter = Intersection.intersectLineLine(a1, a2, b1, b2);\n result.appendPoints(inter.points);\n }\n\n if (result.points.length > 0) {\n result.status = 'Intersection';\n }\n\n return result;\n };\n /**\n * Checks if polygon intersects another polygon\n * @static\n * @param {Array} points1\n * @param {Array} points2\n * @return {fabric.Intersection}\n */\n\n\n fabric.Intersection.intersectPolygonPolygon = function (points1, points2) {\n var result = new Intersection(),\n length = points1.length,\n i;\n\n for (i = 0; i < length; i++) {\n var a1 = points1[i],\n a2 = points1[(i + 1) % length],\n inter = Intersection.intersectLinePolygon(a1, a2, points2);\n result.appendPoints(inter.points);\n }\n\n if (result.points.length > 0) {\n result.status = 'Intersection';\n }\n\n return result;\n };\n /**\n * Checks if polygon intersects rectangle\n * @static\n * @param {Array} points\n * @param {fabric.Point} r1\n * @param {fabric.Point} r2\n * @return {fabric.Intersection}\n */\n\n\n fabric.Intersection.intersectPolygonRectangle = function (points, r1, r2) {\n var min = r1.min(r2),\n max = r1.max(r2),\n topRight = new fabric.Point(max.x, min.y),\n bottomLeft = new fabric.Point(min.x, max.y),\n inter1 = Intersection.intersectLinePolygon(min, topRight, points),\n inter2 = Intersection.intersectLinePolygon(topRight, max, points),\n inter3 = Intersection.intersectLinePolygon(max, bottomLeft, points),\n inter4 = Intersection.intersectLinePolygon(bottomLeft, min, points),\n result = new Intersection();\n result.appendPoints(inter1.points);\n result.appendPoints(inter2.points);\n result.appendPoints(inter3.points);\n result.appendPoints(inter4.points);\n\n if (result.points.length > 0) {\n result.status = 'Intersection';\n }\n\n return result;\n };\n})(typeof exports !== 'undefined' ? exports : this);\n\n(function (global) {\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = {});\n\n if (fabric.Color) {\n fabric.warn('fabric.Color is already defined.');\n return;\n }\n /**\n * Color class\n * The purpose of {@link fabric.Color} is to abstract and encapsulate common color operations;\n * {@link fabric.Color} is a constructor and creates instances of {@link fabric.Color} objects.\n *\n * @class fabric.Color\n * @param {String} color optional in hex or rgb(a) or hsl format or from known color list\n * @return {fabric.Color} thisArg\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-2/#colors}\n */\n\n\n function Color(color) {\n if (!color) {\n this.setSource([0, 0, 0, 1]);\n } else {\n this._tryParsingColor(color);\n }\n }\n\n fabric.Color = Color;\n fabric.Color.prototype =\n /** @lends fabric.Color.prototype */\n {\n /**\n * @private\n * @param {String|Array} color Color value to parse\n */\n _tryParsingColor: function (color) {\n var source;\n\n if (color in Color.colorNameMap) {\n color = Color.colorNameMap[color];\n }\n\n if (color === 'transparent') {\n source = [255, 255, 255, 0];\n }\n\n if (!source) {\n source = Color.sourceFromHex(color);\n }\n\n if (!source) {\n source = Color.sourceFromRgb(color);\n }\n\n if (!source) {\n source = Color.sourceFromHsl(color);\n }\n\n if (!source) {\n //if color is not recognize let's make black as canvas does\n source = [0, 0, 0, 1];\n }\n\n if (source) {\n this.setSource(source);\n }\n },\n\n /**\n * Adapted from <a href=\"https://rawgithub.com/mjijackson/mjijackson.github.com/master/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript.html\">https://github.com/mjijackson</a>\n * @private\n * @param {Number} r Red color value\n * @param {Number} g Green color value\n * @param {Number} b Blue color value\n * @return {Array} Hsl color\n */\n _rgbToHsl: function (r, g, b) {\n r /= 255;\n g /= 255;\n b /= 255;\n var h,\n s,\n l,\n max = fabric.util.array.max([r, g, b]),\n min = fabric.util.array.min([r, g, b]);\n l = (max + min) / 2;\n\n if (max === min) {\n h = s = 0; // achromatic\n } else {\n var d = max - min;\n s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n\n switch (max) {\n case r:\n h = (g - b) / d + (g < b ? 6 : 0);\n break;\n\n case g:\n h = (b - r) / d + 2;\n break;\n\n case b:\n h = (r - g) / d + 4;\n break;\n }\n\n h /= 6;\n }\n\n return [Math.round(h * 360), Math.round(s * 100), Math.round(l * 100)];\n },\n\n /**\n * Returns source of this color (where source is an array representation; ex: [200, 200, 100, 1])\n * @return {Array}\n */\n getSource: function () {\n return this._source;\n },\n\n /**\n * Sets source of this color (where source is an array representation; ex: [200, 200, 100, 1])\n * @param {Array} source\n */\n setSource: function (source) {\n this._source = source;\n },\n\n /**\n * Returns color representation in RGB format\n * @return {String} ex: rgb(0-255,0-255,0-255)\n */\n toRgb: function () {\n var source = this.getSource();\n return 'rgb(' + source[0] + ',' + source[1] + ',' + source[2] + ')';\n },\n\n /**\n * Returns color representation in RGBA format\n * @return {String} ex: rgba(0-255,0-255,0-255,0-1)\n */\n toRgba: function () {\n var source = this.getSource();\n return 'rgba(' + source[0] + ',' + source[1] + ',' + source[2] + ',' + source[3] + ')';\n },\n\n /**\n * Returns color representation in HSL format\n * @return {String} ex: hsl(0-360,0%-100%,0%-100%)\n */\n toHsl: function () {\n var source = this.getSource(),\n hsl = this._rgbToHsl(source[0], source[1], source[2]);\n\n return 'hsl(' + hsl[0] + ',' + hsl[1] + '%,' + hsl[2] + '%)';\n },\n\n /**\n * Returns color representation in HSLA format\n * @return {String} ex: hsla(0-360,0%-100%,0%-100%,0-1)\n */\n toHsla: function () {\n var source = this.getSource(),\n hsl = this._rgbToHsl(source[0], source[1], source[2]);\n\n return 'hsla(' + hsl[0] + ',' + hsl[1] + '%,' + hsl[2] + '%,' + source[3] + ')';\n },\n\n /**\n * Returns color representation in HEX format\n * @return {String} ex: FF5555\n */\n toHex: function () {\n var source = this.getSource(),\n r,\n g,\n b;\n r = source[0].toString(16);\n r = r.length === 1 ? '0' + r : r;\n g = source[1].toString(16);\n g = g.length === 1 ? '0' + g : g;\n b = source[2].toString(16);\n b = b.length === 1 ? '0' + b : b;\n return r.toUpperCase() + g.toUpperCase() + b.toUpperCase();\n },\n\n /**\n * Returns color representation in HEXA format\n * @return {String} ex: FF5555CC\n */\n toHexa: function () {\n var source = this.getSource(),\n a;\n a = Math.round(source[3] * 255);\n a = a.toString(16);\n a = a.length === 1 ? '0' + a : a;\n return this.toHex() + a.toUpperCase();\n },\n\n /**\n * Gets value of alpha channel for this color\n * @return {Number} 0-1\n */\n getAlpha: function () {\n return this.getSource()[3];\n },\n\n /**\n * Sets value of alpha channel for this color\n * @param {Number} alpha Alpha value 0-1\n * @return {fabric.Color} thisArg\n */\n setAlpha: function (alpha) {\n var source = this.getSource();\n source[3] = alpha;\n this.setSource(source);\n return this;\n },\n\n /**\n * Transforms color to its grayscale representation\n * @return {fabric.Color} thisArg\n */\n toGrayscale: function () {\n var source = this.getSource(),\n average = parseInt((source[0] * 0.3 + source[1] * 0.59 + source[2] * 0.11).toFixed(0), 10),\n currentAlpha = source[3];\n this.setSource([average, average, average, currentAlpha]);\n return this;\n },\n\n /**\n * Transforms color to its black and white representation\n * @param {Number} threshold\n * @return {fabric.Color} thisArg\n */\n toBlackWhite: function (threshold) {\n var source = this.getSource(),\n average = (source[0] * 0.3 + source[1] * 0.59 + source[2] * 0.11).toFixed(0),\n currentAlpha = source[3];\n threshold = threshold || 127;\n average = Number(average) < Number(threshold) ? 0 : 255;\n this.setSource([average, average, average, currentAlpha]);\n return this;\n },\n\n /**\n * Overlays color with another color\n * @param {String|fabric.Color} otherColor\n * @return {fabric.Color} thisArg\n */\n overlayWith: function (otherColor) {\n if (!(otherColor instanceof Color)) {\n otherColor = new Color(otherColor);\n }\n\n var result = [],\n alpha = this.getAlpha(),\n otherAlpha = 0.5,\n source = this.getSource(),\n otherSource = otherColor.getSource(),\n i;\n\n for (i = 0; i < 3; i++) {\n result.push(Math.round(source[i] * (1 - otherAlpha) + otherSource[i] * otherAlpha));\n }\n\n result[3] = alpha;\n this.setSource(result);\n return this;\n }\n };\n /**\n * Regex matching color in RGB or RGBA formats (ex: rgb(0, 0, 0), rgba(255, 100, 10, 0.5), rgba( 255 , 100 , 10 , 0.5 ), rgb(1,1,1), rgba(100%, 60%, 10%, 0.5))\n * @static\n * @field\n * @memberOf fabric.Color\n */\n // eslint-disable-next-line max-len\n\n 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*)?\\)$/i;\n /**\n * Regex matching color in HSL or HSLA formats (ex: hsl(200, 80%, 10%), hsla(300, 50%, 80%, 0.5), hsla( 300 , 50% , 80% , 0.5 ))\n * @static\n * @field\n * @memberOf fabric.Color\n */\n\n fabric.Color.reHSLa = /^hsla?\\(\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3}\\%)\\s*,\\s*(\\d{1,3}\\%)\\s*(?:\\s*,\\s*(\\d+(?:\\.\\d+)?)\\s*)?\\)$/i;\n /**\n * Regex matching color in HEX format (ex: #FF5544CC, #FF5555, 010155, aff)\n * @static\n * @field\n * @memberOf fabric.Color\n */\n\n fabric.Color.reHex = /^#?([0-9a-f]{8}|[0-9a-f]{6}|[0-9a-f]{4}|[0-9a-f]{3})$/i;\n /**\n * Map of the 148 color names with HEX code\n * @static\n * @field\n * @memberOf fabric.Color\n * @see: https://www.w3.org/TR/css3-color/#svg-color\n */\n\n fabric.Color.colorNameMap = {\n aliceblue: '#F0F8FF',\n antiquewhite: '#FAEBD7',\n aqua: '#00FFFF',\n aquamarine: '#7FFFD4',\n azure: '#F0FFFF',\n beige: '#F5F5DC',\n bisque: '#FFE4C4',\n black: '#000000',\n blanchedalmond: '#FFEBCD',\n blue: '#0000FF',\n blueviolet: '#8A2BE2',\n brown: '#A52A2A',\n burlywood: '#DEB887',\n cadetblue: '#5F9EA0',\n chartreuse: '#7FFF00',\n chocolate: '#D2691E',\n coral: '#FF7F50',\n cornflowerblue: '#6495ED',\n cornsilk: '#FFF8DC',\n crimson: '#DC143C',\n cyan: '#00FFFF',\n darkblue: '#00008B',\n darkcyan: '#008B8B',\n darkgoldenrod: '#B8860B',\n darkgray: '#A9A9A9',\n darkgrey: '#A9A9A9',\n darkgreen: '#006400',\n darkkhaki: '#BDB76B',\n darkmagenta: '#8B008B',\n darkolivegreen: '#556B2F',\n darkorange: '#FF8C00',\n darkorchid: '#9932CC',\n darkred: '#8B0000',\n darksalmon: '#E9967A',\n darkseagreen: '#8FBC8F',\n darkslateblue: '#483D8B',\n darkslategray: '#2F4F4F',\n darkslategrey: '#2F4F4F',\n darkturquoise: '#00CED1',\n darkviolet: '#9400D3',\n deeppink: '#FF1493',\n deepskyblue: '#00BFFF',\n dimgray: '#696969',\n dimgrey: '#696969',\n dodgerblue: '#1E90FF',\n firebrick: '#B22222',\n floralwhite: '#FFFAF0',\n forestgreen: '#228B22',\n fuchsia: '#FF00FF',\n gainsboro: '#DCDCDC',\n ghostwhite: '#F8F8FF',\n gold: '#FFD700',\n goldenrod: '#DAA520',\n gray: '#808080',\n grey: '#808080',\n green: '#008000',\n greenyellow: '#ADFF2F',\n honeydew: '#F0FFF0',\n hotpink: '#FF69B4',\n indianred: '#CD5C5C',\n indigo: '#4B0082',\n ivory: '#FFFFF0',\n khaki: '#F0E68C',\n lavender: '#E6E6FA',\n lavenderblush: '#FFF0F5',\n lawngreen: '#7CFC00',\n lemonchiffon: '#FFFACD',\n lightblue: '#ADD8E6',\n lightcoral: '#F08080',\n lightcyan: '#E0FFFF',\n lightgoldenrodyellow: '#FAFAD2',\n lightgray: '#D3D3D3',\n lightgrey: '#D3D3D3',\n lightgreen: '#90EE90',\n lightpink: '#FFB6C1',\n lightsalmon: '#FFA07A',\n lightseagreen: '#20B2AA',\n lightskyblue: '#87CEFA',\n lightslategray: '#778899',\n lightslategrey: '#778899',\n lightsteelblue: '#B0C4DE',\n lightyellow: '#FFFFE0',\n lime: '#00FF00',\n limegreen: '#32CD32',\n linen: '#FAF0E6',\n magenta: '#FF00FF',\n maroon: '#800000',\n mediumaquamarine: '#66CDAA',\n mediumblue: '#0000CD',\n mediumorchid: '#BA55D3',\n mediumpurple: '#9370DB',\n mediumseagreen: '#3CB371',\n mediumslateblue: '#7B68EE',\n mediumspringgreen: '#00FA9A',\n mediumturquoise: '#48D1CC',\n mediumvioletred: '#C71585',\n midnightblue: '#191970',\n mintcream: '#F5FFFA',\n mistyrose: '#FFE4E1',\n moccasin: '#FFE4B5',\n navajowhite: '#FFDEAD',\n navy: '#000080',\n oldlace: '#FDF5E6',\n olive: '#808000',\n olivedrab: '#6B8E23',\n orange: '#FFA500',\n orangered: '#FF4500',\n orchid: '#DA70D6',\n palegoldenrod: '#EEE8AA',\n palegreen: '#98FB98',\n paleturquoise: '#AFEEEE',\n palevioletred: '#DB7093',\n papayawhip: '#FFEFD5',\n peachpuff: '#FFDAB9',\n peru: '#CD853F',\n pink: '#FFC0CB',\n plum: '#DDA0DD',\n powderblue: '#B0E0E6',\n purple: '#800080',\n rebeccapurple: '#663399',\n red: '#FF0000',\n rosybrown: '#BC8F8F',\n royalblue: '#4169E1',\n saddlebrown: '#8B4513',\n salmon: '#FA8072',\n sandybrown: '#F4A460',\n seagreen: '#2E8B57',\n seashell: '#FFF5EE',\n sienna: '#A0522D',\n silver: '#C0C0C0',\n skyblue: '#87CEEB',\n slateblue: '#6A5ACD',\n slategray: '#708090',\n slategrey: '#708090',\n snow: '#FFFAFA',\n springgreen: '#00FF7F',\n steelblue: '#4682B4',\n tan: '#D2B48C',\n teal: '#008080',\n thistle: '#D8BFD8',\n tomato: '#FF6347',\n turquoise: '#40E0D0',\n violet: '#EE82EE',\n wheat: '#F5DEB3',\n white: '#FFFFFF',\n whitesmoke: '#F5F5F5',\n yellow: '#FFFF00',\n yellowgreen: '#9ACD32'\n };\n /**\n * @private\n * @param {Number} p\n * @param {Number} q\n * @param {Number} t\n * @return {Number}\n */\n\n function hue2rgb(p, q, t) {\n if (t < 0) {\n t += 1;\n }\n\n if (t > 1) {\n t -= 1;\n }\n\n if (t < 1 / 6) {\n return p + (q - p) * 6 * t;\n }\n\n if (t < 1 / 2) {\n return q;\n }\n\n if (t < 2 / 3) {\n return p + (q - p) * (2 / 3 - t) * 6;\n }\n\n return p;\n }\n /**\n * Returns new color object, when given a color in RGB format\n * @memberOf fabric.Color\n * @param {String} color Color value ex: rgb(0-255,0-255,0-255)\n * @return {fabric.Color}\n */\n\n\n fabric.Color.fromRgb = function (color) {\n return Color.fromSource(Color.sourceFromRgb(color));\n };\n /**\n * Returns array representation (ex: [100, 100, 200, 1]) of a color that's in RGB or RGBA format\n * @memberOf fabric.Color\n * @param {String} color Color value ex: rgb(0-255,0-255,0-255), rgb(0%-100%,0%-100%,0%-100%)\n * @return {Array} source\n */\n\n\n fabric.Color.sourceFromRgb = function (color) {\n var match = color.match(Color.reRGBa);\n\n if (match) {\n var r = parseInt(match[1], 10) / (/%$/.test(match[1]) ? 100 : 1) * (/%$/.test(match[1]) ? 255 : 1),\n g = parseInt(match[2], 10) / (/%$/.test(match[2]) ? 100 : 1) * (/%$/.test(match[2]) ? 255 : 1),\n b = parseInt(match[3], 10) / (/%$/.test(match[3]) ? 100 : 1) * (/%$/.test(match[3]) ? 255 : 1);\n return [parseInt(r, 10), parseInt(g, 10), parseInt(b, 10), match[4] ? parseFloat(match[4]) : 1];\n }\n };\n /**\n * Returns new color object, when given a color in RGBA format\n * @static\n * @function\n * @memberOf fabric.Color\n * @param {String} color\n * @return {fabric.Color}\n */\n\n\n fabric.Color.fromRgba = Color.fromRgb;\n /**\n * Returns new color object, when given a color in HSL format\n * @param {String} color Color value ex: hsl(0-260,0%-100%,0%-100%)\n * @memberOf fabric.Color\n * @return {fabric.Color}\n */\n\n fabric.Color.fromHsl = function (color) {\n return Color.fromSource(Color.sourceFromHsl(color));\n };\n /**\n * Returns array representation (ex: [100, 100, 200, 1]) of a color that's in HSL or HSLA format.\n * Adapted from <a href=\"https://rawgithub.com/mjijackson/mjijackson.github.com/master/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript.html\">https://github.com/mjijackson</a>\n * @memberOf fabric.Color\n * @param {String} color Color value ex: hsl(0-360,0%-100%,0%-100%) or hsla(0-360,0%-100%,0%-100%, 0-1)\n * @return {Array} source\n * @see http://http://www.w3.org/TR/css3-color/#hsl-color\n */\n\n\n fabric.Color.sourceFromHsl = function (color) {\n var match = color.match(Color.reHSLa);\n\n if (!match) {\n return;\n }\n\n var h = (parseFloat(match[1]) % 360 + 360) % 360 / 360,\n s = parseFloat(match[2]) / (/%$/.test(match[2]) ? 100 : 1),\n l = parseFloat(match[3]) / (/%$/.test(match[3]) ? 100 : 1),\n r,\n g,\n b;\n\n if (s === 0) {\n r = g = b = l;\n } else {\n var q = l <= 0.5 ? l * (s + 1) : l + s - l * s,\n p = l * 2 - q;\n r = hue2rgb(p, q, h + 1 / 3);\n g = hue2rgb(p, q, h);\n b = hue2rgb(p, q, h - 1 / 3);\n }\n\n return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255), match[4] ? parseFloat(match[4]) : 1];\n };\n /**\n * Returns new color object, when given a color in HSLA format\n * @static\n * @function\n * @memberOf fabric.Color\n * @param {String} color\n * @return {fabric.Color}\n */\n\n\n fabric.Color.fromHsla = Color.fromHsl;\n /**\n * Returns new color object, when given a color in HEX format\n * @static\n * @memberOf fabric.Color\n * @param {String} color Color value ex: FF5555\n * @return {fabric.Color}\n */\n\n fabric.Color.fromHex = function (color) {\n return Color.fromSource(Color.sourceFromHex(color));\n };\n /**\n * Returns array representation (ex: [100, 100, 200, 1]) of a color that's in HEX format\n * @static\n * @memberOf fabric.Color\n * @param {String} color ex: FF5555 or FF5544CC (RGBa)\n * @return {Array} source\n */\n\n\n fabric.Color.sourceFromHex = function (color) {\n if (color.match(Color.reHex)) {\n var value = color.slice(color.indexOf('#') + 1),\n isShortNotation = value.length === 3 || value.length === 4,\n isRGBa = value.length === 8 || value.length === 4,\n r = isShortNotation ? value.charAt(0) + value.charAt(0) : value.substring(0, 2),\n g = isShortNotation ? value.charAt(1) + value.charAt(1) : value.substring(2, 4),\n b = isShortNotation ? value.charAt(2) + value.charAt(2) : value.substring(4, 6),\n a = isRGBa ? isShortNotation ? value.charAt(3) + value.charAt(3) : value.substring(6, 8) : 'FF';\n return [parseInt(r, 16), parseInt(g, 16), parseInt(b, 16), parseFloat((parseInt(a, 16) / 255).toFixed(2))];\n }\n };\n /**\n * Returns new color object, when given color in array representation (ex: [200, 100, 100, 0.5])\n * @static\n * @memberOf fabric.Color\n * @param {Array} source\n * @return {fabric.Color}\n */\n\n\n fabric.Color.fromSource = function (source) {\n var oColor = new Color();\n oColor.setSource(source);\n return oColor;\n };\n})(typeof exports !== 'undefined' ? exports : this);\n\n(function (global) {\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = {}),\n scaleMap = ['e', 'se', 's', 'sw', 'w', 'nw', 'n', 'ne', 'e'],\n skewMap = ['ns', 'nesw', 'ew', 'nwse'],\n controls = {},\n LEFT = 'left',\n TOP = 'top',\n RIGHT = 'right',\n BOTTOM = 'bottom',\n CENTER = 'center',\n opposite = {\n top: BOTTOM,\n bottom: TOP,\n left: RIGHT,\n right: LEFT,\n center: CENTER\n },\n radiansToDegrees = fabric.util.radiansToDegrees,\n sign = Math.sign || function (x) {\n return (x > 0) - (x < 0) || +x;\n };\n /**\n * Combine control position and object angle to find the control direction compared\n * to the object center.\n * @param {fabric.Object} fabricObject the fabric object for which we are rendering controls\n * @param {fabric.Control} control the control class\n * @return {Number} 0 - 7 a quadrant number\n */\n\n\n function findCornerQuadrant(fabricObject, control) {\n var cornerAngle = fabricObject.angle + radiansToDegrees(Math.atan2(control.y, control.x)) + 360;\n return Math.round(cornerAngle % 360 / 45);\n }\n\n function fireEvent(eventName, options) {\n var target = options.transform.target,\n canvas = target.canvas,\n canvasOptions = fabric.util.object.clone(options);\n canvasOptions.target = target;\n canvas && canvas.fire('object:' + eventName, canvasOptions);\n target.fire(eventName, options);\n }\n /**\n * Inspect event and fabricObject properties to understand if the scaling action\n * @param {Event} eventData from the user action\n * @param {fabric.Object} fabricObject the fabric object about to scale\n * @return {Boolean} true if scale is proportional\n */\n\n\n function scaleIsProportional(eventData, fabricObject) {\n var canvas = fabricObject.canvas,\n uniScaleKey = canvas.uniScaleKey,\n uniformIsToggled = eventData[uniScaleKey];\n return canvas.uniformScaling && !uniformIsToggled || !canvas.uniformScaling && uniformIsToggled;\n }\n /**\n * Checks if transform is centered\n * @param {Object} transform transform data\n * @return {Boolean} true if transform is centered\n */\n\n\n function isTransformCentered(transform) {\n return transform.originX === CENTER && transform.originY === CENTER;\n }\n /**\n * Inspect fabricObject to understand if the current scaling action is allowed\n * @param {fabric.Object} fabricObject the fabric object about to scale\n * @param {String} by 'x' or 'y' or ''\n * @param {Boolean} scaleProportionally true if we are trying to scale proportionally\n * @return {Boolean} true if scaling is not allowed at current conditions\n */\n\n\n function scalingIsForbidden(fabricObject, by, scaleProportionally) {\n var lockX = fabricObject.lockScalingX,\n lockY = fabricObject.lockScalingY;\n\n if (lockX && lockY) {\n return true;\n }\n\n if (!by && (lockX || lockY) && scaleProportionally) {\n return true;\n }\n\n if (lockX && by === 'x') {\n return true;\n }\n\n if (lockY && by === 'y') {\n return true;\n }\n\n return false;\n }\n /**\n * return the correct cursor style for the scale action\n * @param {Event} eventData the javascript event that is causing the scale\n * @param {fabric.Control} control the control that is interested in the action\n * @param {fabric.Object} fabricObject the fabric object that is interested in the action\n * @return {String} a valid css string for the cursor\n */\n\n\n function scaleCursorStyleHandler(eventData, control, fabricObject) {\n var notAllowed = 'not-allowed',\n scaleProportionally = scaleIsProportional(eventData, fabricObject),\n by = '';\n\n if (control.x !== 0 && control.y === 0) {\n by = 'x';\n } else if (control.x === 0 && control.y !== 0) {\n by = 'y';\n }\n\n if (scalingIsForbidden(fabricObject, by, scaleProportionally)) {\n return notAllowed;\n }\n\n var n = findCornerQuadrant(fabricObject, control);\n return scaleMap[n] + '-resize';\n }\n /**\n * return the correct cursor style for the skew action\n * @param {Event} eventData the javascript event that is causing the scale\n * @param {fabric.Control} control the control that is interested in the action\n * @param {fabric.Object} fabricObject the fabric object that is interested in the action\n * @return {String} a valid css string for the cursor\n */\n\n\n function skewCursorStyleHandler(eventData, control, fabricObject) {\n var notAllowed = 'not-allowed';\n\n if (control.x !== 0 && fabricObject.lockSkewingY) {\n return notAllowed;\n }\n\n if (control.y !== 0 && fabricObject.lockSkewingX) {\n return notAllowed;\n }\n\n var n = findCornerQuadrant(fabricObject, control) % 4;\n return skewMap[n] + '-resize';\n }\n /**\n * Combine skew and scale style handlers to cover fabric standard use case\n * @param {Event} eventData the javascript event that is causing the scale\n * @param {fabric.Control} control the control that is interested in the action\n * @param {fabric.Object} fabricObject the fabric object that is interested in the action\n * @return {String} a valid css string for the cursor\n */\n\n\n function scaleSkewCursorStyleHandler(eventData, control, fabricObject) {\n if (eventData[fabricObject.canvas.altActionKey]) {\n return controls.skewCursorStyleHandler(eventData, control, fabricObject);\n }\n\n return controls.scaleCursorStyleHandler(eventData, control, fabricObject);\n }\n /**\n * Inspect event, control and fabricObject to return the correct action name\n * @param {Event} eventData the javascript event that is causing the scale\n * @param {fabric.Control} control the control that is interested in the action\n * @param {fabric.Object} fabricObject the fabric object that is interested in the action\n * @return {String} an action name\n */\n\n\n function scaleOrSkewActionName(eventData, control, fabricObject) {\n var isAlternative = eventData[fabricObject.canvas.altActionKey];\n\n if (control.x === 0) {\n // then is scaleY or skewX\n return isAlternative ? 'skewX' : 'scaleY';\n }\n\n if (control.y === 0) {\n // then is scaleY or skewX\n return isAlternative ? 'skewY' : 'scaleX';\n }\n }\n /**\n * Find the correct style for the control that is used for rotation.\n * this function is very simple and it just take care of not-allowed or standard cursor\n * @param {Event} eventData the javascript event that is causing the scale\n * @param {fabric.Control} control the control that is interested in the action\n * @param {fabric.Object} fabricObject the fabric object that is interested in the action\n * @return {String} a valid css string for the cursor\n */\n\n\n function rotationStyleHandler(eventData, control, fabricObject) {\n if (fabricObject.lockRotation) {\n return 'not-allowed';\n }\n\n return control.cursorStyle;\n }\n\n function commonEventInfo(eventData, transform, x, y) {\n return {\n e: eventData,\n transform: transform,\n pointer: {\n x: x,\n y: y\n }\n };\n }\n /**\n * Wrap an action handler with saving/restoring object position on the transform.\n * this is the code that permits to objects to keep their position while transforming.\n * @param {Function} actionHandler the function to wrap\n * @return {Function} a function with an action handler signature\n */\n\n\n function wrapWithFixedAnchor(actionHandler) {\n return function (eventData, transform, x, y) {\n var target = transform.target,\n centerPoint = target.getCenterPoint(),\n constraint = target.translateToOriginPoint(centerPoint, transform.originX, transform.originY),\n actionPerformed = actionHandler(eventData, transform, x, y);\n target.setPositionByOrigin(constraint, transform.originX, transform.originY);\n return actionPerformed;\n };\n }\n /**\n * Transforms a point described by x and y in a distance from the top left corner of the object\n * bounding box.\n * @param {Object} transform\n * @param {String} originX\n * @param {String} originY\n * @param {number} x\n * @param {number} y\n * @return {Fabric.Point} the normalized point\n */\n\n\n function getLocalPoint(transform, originX, originY, x, y) {\n var target = transform.target,\n control = target.controls[transform.corner],\n zoom = target.canvas.getZoom(),\n padding = target.padding / zoom,\n localPoint = target.toLocalPoint(new fabric.Point(x, y), originX, originY);\n\n if (localPoint.x >= padding) {\n localPoint.x -= padding;\n }\n\n if (localPoint.x <= -padding) {\n localPoint.x += padding;\n }\n\n if (localPoint.y >= padding) {\n localPoint.y -= padding;\n }\n\n if (localPoint.y <= padding) {\n localPoint.y += padding;\n }\n\n localPoint.x -= control.offsetX;\n localPoint.y -= control.offsetY;\n return localPoint;\n }\n /**\n * Detect if the fabric object is flipped on one side.\n * @param {fabric.Object} target\n * @return {Boolean} true if one flip, but not two.\n */\n\n\n function targetHasOneFlip(target) {\n return target.flipX && !target.flipY || !target.flipX && target.flipY;\n }\n /**\n * Utility function to compensate the scale factor when skew is applied on both axes\n * @private\n */\n\n\n function compensateScaleForSkew(target, oppositeSkew, scaleToCompensate, axis, reference) {\n if (target[oppositeSkew] !== 0) {\n var newDim = target._getTransformedDimensions()[axis];\n\n var newValue = reference / newDim * target[scaleToCompensate];\n target.set(scaleToCompensate, newValue);\n }\n }\n /**\n * Action handler for skewing on the X axis\n * @private\n */\n\n\n function skewObjectX(eventData, transform, x, y) {\n var target = transform.target,\n // find how big the object would be, if there was no skewX. takes in account scaling\n dimNoSkew = target._getTransformedDimensions(0, target.skewY),\n localPoint = getLocalPoint(transform, transform.originX, transform.originY, x, y),\n // the mouse is in the center of the object, and we want it to stay there.\n // so the object will grow twice as much as the mouse.\n // this makes the skew growth to localPoint * 2 - dimNoSkew.\n totalSkewSize = Math.abs(localPoint.x * 2) - dimNoSkew.x,\n currentSkew = target.skewX,\n newSkew;\n\n if (totalSkewSize < 2) {\n // let's make it easy to go back to position 0.\n newSkew = 0;\n } else {\n newSkew = radiansToDegrees(Math.atan2(totalSkewSize / target.scaleX, dimNoSkew.y / target.scaleY)); // now we have to find the sign of the skew.\n // it mostly depend on the origin of transformation.\n\n if (transform.originX === LEFT && transform.originY === BOTTOM) {\n newSkew = -newSkew;\n }\n\n if (transform.originX === RIGHT && transform.originY === TOP) {\n newSkew = -newSkew;\n }\n\n if (targetHasOneFlip(target)) {\n newSkew = -newSkew;\n }\n }\n\n var hasSkewed = currentSkew !== newSkew;\n\n if (hasSkewed) {\n var dimBeforeSkewing = target._getTransformedDimensions().y;\n\n target.set('skewX', newSkew);\n compensateScaleForSkew(target, 'skewY', 'scaleY', 'y', dimBeforeSkewing);\n fireEvent('skewing', commonEventInfo(eventData, transform, x, y));\n }\n\n return hasSkewed;\n }\n /**\n * Action handler for skewing on the Y axis\n * @private\n */\n\n\n function skewObjectY(eventData, transform, x, y) {\n var target = transform.target,\n // find how big the object would be, if there was no skewX. takes in account scaling\n dimNoSkew = target._getTransformedDimensions(target.skewX, 0),\n localPoint = getLocalPoint(transform, transform.originX, transform.originY, x, y),\n // the mouse is in the center of the object, and we want it to stay there.\n // so the object will grow twice as much as the mouse.\n // this makes the skew growth to localPoint * 2 - dimNoSkew.\n totalSkewSize = Math.abs(localPoint.y * 2) - dimNoSkew.y,\n currentSkew = target.skewY,\n newSkew;\n\n if (totalSkewSize < 2) {\n // let's make it easy to go back to position 0.\n newSkew = 0;\n } else {\n newSkew = radiansToDegrees(Math.atan2(totalSkewSize / target.scaleY, dimNoSkew.x / target.scaleX)); // now we have to find the sign of the skew.\n // it mostly depend on the origin of transformation.\n\n if (transform.originX === LEFT && transform.originY === BOTTOM) {\n newSkew = -newSkew;\n }\n\n if (transform.originX === RIGHT && transform.originY === TOP) {\n newSkew = -newSkew;\n }\n\n if (targetHasOneFlip(target)) {\n newSkew = -newSkew;\n }\n }\n\n var hasSkewed = currentSkew !== newSkew;\n\n if (hasSkewed) {\n var dimBeforeSkewing = target._getTransformedDimensions().x;\n\n target.set('skewY', newSkew);\n compensateScaleForSkew(target, 'skewX', 'scaleX', 'x', dimBeforeSkewing);\n fireEvent('skewing', commonEventInfo(eventData, transform, x, y));\n }\n\n return hasSkewed;\n }\n /**\n * Wrapped Action handler for skewing on the Y axis, takes care of the\n * skew direction and determine the correct transform origin for the anchor point\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @return {Boolean} true if some change happened\n */\n\n\n function skewHandlerX(eventData, transform, x, y) {\n // step1 figure out and change transform origin.\n // if skewX > 0 and originY bottom we anchor on right\n // if skewX > 0 and originY top we anchor on left\n // if skewX < 0 and originY bottom we anchor on left\n // if skewX < 0 and originY top we anchor on right\n // if skewX is 0, we look for mouse position to understand where are we going.\n var target = transform.target,\n currentSkew = target.skewX,\n originX,\n originY = transform.originY;\n\n if (target.lockSkewingX) {\n return false;\n }\n\n if (currentSkew === 0) {\n var localPointFromCenter = getLocalPoint(transform, CENTER, CENTER, x, y);\n\n if (localPointFromCenter.x > 0) {\n // we are pulling right, anchor left;\n originX = LEFT;\n } else {\n // we are pulling right, anchor right\n originX = RIGHT;\n }\n } else {\n if (currentSkew > 0) {\n originX = originY === TOP ? LEFT : RIGHT;\n }\n\n if (currentSkew < 0) {\n originX = originY === TOP ? RIGHT : LEFT;\n } // is the object flipped on one side only? swap the origin.\n\n\n if (targetHasOneFlip(target)) {\n originX = originX === LEFT ? RIGHT : LEFT;\n }\n } // once we have the origin, we find the anchor point\n\n\n transform.originX = originX;\n var finalHandler = wrapWithFixedAnchor(skewObjectX);\n return finalHandler(eventData, transform, x, y);\n }\n /**\n * Wrapped Action handler for skewing on the Y axis, takes care of the\n * skew direction and determine the correct transform origin for the anchor point\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @return {Boolean} true if some change happened\n */\n\n\n function skewHandlerY(eventData, transform, x, y) {\n // step1 figure out and change transform origin.\n // if skewY > 0 and originX left we anchor on top\n // if skewY > 0 and originX right we anchor on bottom\n // if skewY < 0 and originX left we anchor on bottom\n // if skewY < 0 and originX right we anchor on top\n // if skewY is 0, we look for mouse position to understand where are we going.\n var target = transform.target,\n currentSkew = target.skewY,\n originY,\n originX = transform.originX;\n\n if (target.lockSkewingY) {\n return false;\n }\n\n if (currentSkew === 0) {\n var localPointFromCenter = getLocalPoint(transform, CENTER, CENTER, x, y);\n\n if (localPointFromCenter.y > 0) {\n // we are pulling down, anchor up;\n originY = TOP;\n } else {\n // we are pulling up, anchor down\n originY = BOTTOM;\n }\n } else {\n if (currentSkew > 0) {\n originY = originX === LEFT ? TOP : BOTTOM;\n }\n\n if (currentSkew < 0) {\n originY = originX === LEFT ? BOTTOM : TOP;\n } // is the object flipped on one side only? swap the origin.\n\n\n if (targetHasOneFlip(target)) {\n originY = originY === TOP ? BOTTOM : TOP;\n }\n } // once we have the origin, we find the anchor point\n\n\n transform.originY = originY;\n var finalHandler = wrapWithFixedAnchor(skewObjectY);\n return finalHandler(eventData, transform, x, y);\n }\n /**\n * Action handler for rotation and snapping, without anchor point.\n * Needs to be wrapped with `wrapWithFixedAnchor` to be effective\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @return {Boolean} true if some change happened\n * @private\n */\n\n\n function rotationWithSnapping(eventData, transform, x, y) {\n var t = transform,\n target = t.target,\n pivotPoint = target.translateToOriginPoint(target.getCenterPoint(), t.originX, t.originY);\n\n if (target.lockRotation) {\n return false;\n }\n\n var lastAngle = Math.atan2(t.ey - pivotPoint.y, t.ex - pivotPoint.x),\n curAngle = Math.atan2(y - pivotPoint.y, x - pivotPoint.x),\n angle = radiansToDegrees(curAngle - lastAngle + t.theta),\n hasRotated = true;\n\n if (target.snapAngle > 0) {\n var snapAngle = target.snapAngle,\n snapThreshold = target.snapThreshold || snapAngle,\n rightAngleLocked = Math.ceil(angle / snapAngle) * snapAngle,\n leftAngleLocked = Math.floor(angle / snapAngle) * snapAngle;\n\n if (Math.abs(angle - leftAngleLocked) < snapThreshold) {\n angle = leftAngleLocked;\n } else if (Math.abs(angle - rightAngleLocked) < snapThreshold) {\n angle = rightAngleLocked;\n }\n } // normalize angle to positive value\n\n\n if (angle < 0) {\n angle = 360 + angle;\n }\n\n angle %= 360;\n hasRotated = target.angle !== angle;\n target.angle = angle;\n\n if (hasRotated) {\n fireEvent('rotating', commonEventInfo(eventData, transform, x, y));\n }\n\n return hasRotated;\n }\n /**\n * Basic scaling logic, reused with different constrain for scaling X,Y, freely or equally.\n * Needs to be wrapped with `wrapWithFixedAnchor` to be effective\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @param {Object} options additional information for scaling\n * @param {String} options.by 'x', 'y', 'equally' or '' to indicate type of scaling\n * @return {Boolean} true if some change happened\n * @private\n */\n\n\n function scaleObject(eventData, transform, x, y, options) {\n options = options || {};\n var target = transform.target,\n lockScalingX = target.lockScalingX,\n lockScalingY = target.lockScalingY,\n by = options.by,\n newPoint,\n scaleX,\n scaleY,\n dim,\n scaleProportionally = scaleIsProportional(eventData, target),\n forbidScaling = scalingIsForbidden(target, by, scaleProportionally),\n signX,\n signY,\n gestureScale = transform.gestureScale;\n\n if (forbidScaling) {\n return false;\n }\n\n if (gestureScale) {\n scaleX = transform.scaleX * gestureScale;\n scaleY = transform.scaleY * gestureScale;\n } else {\n newPoint = getLocalPoint(transform, transform.originX, transform.originY, x, y); // use of sign: We use sign to detect change of direction of an action. sign usually change when\n // we cross the origin point with the mouse. So a scale flip for example. There is an issue when scaling\n // by center and scaling using one middle control ( default: mr, mt, ml, mb), the mouse movement can easily\n // cross many time the origin point and flip the object. so we need a way to filter out the noise.\n // This ternary here should be ok to filter out X scaling when we want Y only and vice versa.\n\n signX = by !== 'y' ? sign(newPoint.x) : 1;\n signY = by !== 'x' ? sign(newPoint.y) : 1;\n\n if (!transform.signX) {\n transform.signX = signX;\n }\n\n if (!transform.signY) {\n transform.signY = signY;\n }\n\n if (target.lockScalingFlip && (transform.signX !== signX || transform.signY !== signY)) {\n return false;\n }\n\n dim = target._getTransformedDimensions(); // missing detection of flip and logic to switch the origin\n\n if (scaleProportionally && !by) {\n // uniform scaling\n var distance = Math.abs(newPoint.x) + Math.abs(newPoint.y),\n original = transform.original,\n originalDistance = Math.abs(dim.x * original.scaleX / target.scaleX) + Math.abs(dim.y * original.scaleY / target.scaleY),\n scale = distance / originalDistance,\n hasScaled;\n scaleX = original.scaleX * scale;\n scaleY = original.scaleY * scale;\n } else {\n scaleX = Math.abs(newPoint.x * target.scaleX / dim.x);\n scaleY = Math.abs(newPoint.y * target.scaleY / dim.y);\n } // if we are scaling by center, we need to double the scale\n\n\n if (isTransformCentered(transform)) {\n scaleX *= 2;\n scaleY *= 2;\n }\n\n if (transform.signX !== signX && by !== 'y') {\n transform.originX = opposite[transform.originX];\n scaleX *= -1;\n transform.signX = signX;\n }\n\n if (transform.signY !== signY && by !== 'x') {\n transform.originY = opposite[transform.originY];\n scaleY *= -1;\n transform.signY = signY;\n }\n } // minScale is taken are in the setter.\n\n\n var oldScaleX = target.scaleX,\n oldScaleY = target.scaleY;\n\n if (!by) {\n !lockScalingX && target.set('scaleX', scaleX);\n !lockScalingY && target.set('scaleY', scaleY);\n } else {\n // forbidden cases already handled on top here.\n by === 'x' && target.set('scaleX', scaleX);\n by === 'y' && target.set('scaleY', scaleY);\n }\n\n hasScaled = oldScaleX !== target.scaleX || oldScaleY !== target.scaleY;\n\n if (hasScaled) {\n fireEvent('scaling', commonEventInfo(eventData, transform, x, y));\n }\n\n return hasScaled;\n }\n /**\n * Generic scaling logic, to scale from corners either equally or freely.\n * Needs to be wrapped with `wrapWithFixedAnchor` to be effective\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @return {Boolean} true if some change happened\n */\n\n\n function scaleObjectFromCorner(eventData, transform, x, y) {\n return scaleObject(eventData, transform, x, y);\n }\n /**\n * Scaling logic for the X axis.\n * Needs to be wrapped with `wrapWithFixedAnchor` to be effective\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @return {Boolean} true if some change happened\n */\n\n\n function scaleObjectX(eventData, transform, x, y) {\n return scaleObject(eventData, transform, x, y, {\n by: 'x'\n });\n }\n /**\n * Scaling logic for the Y axis.\n * Needs to be wrapped with `wrapWithFixedAnchor` to be effective\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @return {Boolean} true if some change happened\n */\n\n\n function scaleObjectY(eventData, transform, x, y) {\n return scaleObject(eventData, transform, x, y, {\n by: 'y'\n });\n }\n /**\n * Composed action handler to either scale Y or skew X\n * Needs to be wrapped with `wrapWithFixedAnchor` to be effective\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @return {Boolean} true if some change happened\n */\n\n\n function scalingYOrSkewingX(eventData, transform, x, y) {\n // ok some safety needed here.\n if (eventData[transform.target.canvas.altActionKey]) {\n return controls.skewHandlerX(eventData, transform, x, y);\n }\n\n return controls.scalingY(eventData, transform, x, y);\n }\n /**\n * Composed action handler to either scale X or skew Y\n * Needs to be wrapped with `wrapWithFixedAnchor` to be effective\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @return {Boolean} true if some change happened\n */\n\n\n function scalingXOrSkewingY(eventData, transform, x, y) {\n // ok some safety needed here.\n if (eventData[transform.target.canvas.altActionKey]) {\n return controls.skewHandlerY(eventData, transform, x, y);\n }\n\n return controls.scalingX(eventData, transform, x, y);\n }\n /**\n * Action handler to change textbox width\n * Needs to be wrapped with `wrapWithFixedAnchor` to be effective\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @return {Boolean} true if some change happened\n */\n\n\n function changeWidth(eventData, transform, x, y) {\n var target = transform.target,\n localPoint = getLocalPoint(transform, transform.originX, transform.originY, x, y),\n strokePadding = target.strokeWidth / (target.strokeUniform ? target.scaleX : 1),\n multiplier = isTransformCentered(transform) ? 2 : 1,\n oldWidth = target.width,\n hasResized,\n newWidth = Math.abs(localPoint.x * multiplier / target.scaleX) - strokePadding;\n target.set('width', Math.max(newWidth, 0));\n hasResized = oldWidth !== newWidth;\n\n if (hasResized) {\n fireEvent('resizing', commonEventInfo(eventData, transform, x, y));\n }\n\n return hasResized;\n }\n /**\n * Action handler\n * @private\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @return {Boolean} true if the translation occurred\n */\n\n\n function dragHandler(eventData, transform, x, y) {\n var target = transform.target,\n newLeft = x - transform.offsetX,\n newTop = y - transform.offsetY,\n moveX = !target.get('lockMovementX') && target.left !== newLeft,\n moveY = !target.get('lockMovementY') && target.top !== newTop;\n moveX && target.set('left', newLeft);\n moveY && target.set('top', newTop);\n\n if (moveX || moveY) {\n fireEvent('moving', commonEventInfo(eventData, transform, x, y));\n }\n\n return moveX || moveY;\n }\n\n controls.scaleCursorStyleHandler = scaleCursorStyleHandler;\n controls.skewCursorStyleHandler = skewCursorStyleHandler;\n controls.scaleSkewCursorStyleHandler = scaleSkewCursorStyleHandler;\n controls.rotationWithSnapping = wrapWithFixedAnchor(rotationWithSnapping);\n controls.scalingEqually = wrapWithFixedAnchor(scaleObjectFromCorner);\n controls.scalingX = wrapWithFixedAnchor(scaleObjectX);\n controls.scalingY = wrapWithFixedAnchor(scaleObjectY);\n controls.scalingYOrSkewingX = scalingYOrSkewingX;\n controls.scalingXOrSkewingY = scalingXOrSkewingY;\n controls.changeWidth = wrapWithFixedAnchor(changeWidth);\n controls.skewHandlerX = skewHandlerX;\n controls.skewHandlerY = skewHandlerY;\n controls.dragHandler = dragHandler;\n controls.scaleOrSkewActionName = scaleOrSkewActionName;\n controls.rotationStyleHandler = rotationStyleHandler;\n controls.fireEvent = fireEvent;\n controls.wrapWithFixedAnchor = wrapWithFixedAnchor;\n controls.getLocalPoint = getLocalPoint;\n fabric.controlsUtils = controls;\n})(typeof exports !== 'undefined' ? exports : this);\n\n(function (global) {\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = {}),\n degreesToRadians = fabric.util.degreesToRadians,\n controls = fabric.controlsUtils;\n /**\n * Render a round control, as per fabric features.\n * This function is written to respect object properties like transparentCorners, cornerSize\n * cornerColor, cornerStrokeColor\n * plus the addition of offsetY and offsetX.\n * @param {CanvasRenderingContext2D} ctx context to render on\n * @param {Number} left x coordinate where the control center should be\n * @param {Number} top y coordinate where the control center should be\n * @param {Object} styleOverride override for fabric.Object controls style\n * @param {fabric.Object} fabricObject the fabric object for which we are rendering controls\n */\n\n function renderCircleControl(ctx, left, top, styleOverride, fabricObject) {\n styleOverride = styleOverride || {};\n var size = styleOverride.cornerSize || fabricObject.cornerSize,\n transparentCorners = typeof styleOverride.transparentCorners !== 'undefined' ? styleOverride.transparentCorners : this.transparentCorners,\n methodName = transparentCorners ? 'stroke' : 'fill',\n stroke = !transparentCorners && (styleOverride.cornerStrokeColor || fabricObject.cornerStrokeColor);\n ctx.save();\n ctx.fillStyle = styleOverride.cornerColor || fabricObject.cornerColor;\n ctx.strokeStyle = styleOverride.cornerStrokeColor || fabricObject.cornerStrokeColor; // this is still wrong\n\n ctx.lineWidth = 1;\n ctx.beginPath();\n ctx.arc(left, top, size / 2, 0, 2 * Math.PI, false);\n ctx[methodName]();\n\n if (stroke) {\n ctx.stroke();\n }\n\n ctx.restore();\n }\n /**\n * Render a square control, as per fabric features.\n * This function is written to respect object properties like transparentCorners, cornerSize\n * cornerColor, cornerStrokeColor\n * plus the addition of offsetY and offsetX.\n * @param {CanvasRenderingContext2D} ctx context to render on\n * @param {Number} left x coordinate where the control center should be\n * @param {Number} top y coordinate where the control center should be\n * @param {Object} styleOverride override for fabric.Object controls style\n * @param {fabric.Object} fabricObject the fabric object for which we are rendering controls\n */\n\n\n function renderSquareControl(ctx, left, top, styleOverride, fabricObject) {\n styleOverride = styleOverride || {};\n var size = styleOverride.cornerSize || fabricObject.cornerSize,\n transparentCorners = typeof styleOverride.transparentCorners !== 'undefined' ? styleOverride.transparentCorners : fabricObject.transparentCorners,\n methodName = transparentCorners ? 'stroke' : 'fill',\n stroke = !transparentCorners && (styleOverride.cornerStrokeColor || fabricObject.cornerStrokeColor),\n sizeBy2 = size / 2;\n ctx.save();\n ctx.fillStyle = styleOverride.cornerColor || fabricObject.cornerColor;\n ctx.strokeStyle = styleOverride.strokeCornerColor || fabricObject.strokeCornerColor; // this is still wrong\n\n ctx.lineWidth = 1;\n ctx.translate(left, top);\n ctx.rotate(degreesToRadians(fabricObject.angle)); // this does not work, and fixed with ( && ) does not make sense.\n // to have real transparent corners we need the controls on upperCanvas\n // transparentCorners || ctx.clearRect(-sizeBy2, -sizeBy2, size, size);\n\n ctx[methodName + 'Rect'](-sizeBy2, -sizeBy2, size, size);\n\n if (stroke) {\n ctx.strokeRect(-sizeBy2, -sizeBy2, size, size);\n }\n\n ctx.restore();\n }\n\n controls.renderCircleControl = renderCircleControl;\n controls.renderSquareControl = renderSquareControl;\n})(typeof exports !== 'undefined' ? exports : this);\n\n(function (global) {\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = {});\n\n function Control(options) {\n for (var i in options) {\n this[i] = options[i];\n }\n }\n\n fabric.Control = Control;\n fabric.Control.prototype =\n /** @lends fabric.Control.prototype */\n {\n /**\n * keep track of control visibility.\n * mainly for backward compatibility.\n * if you do not want to see a control, you can remove it\n * from the controlset.\n * @type {Boolean}\n * @default true\n */\n visible: true,\n\n /**\n * Name of the action that the controll will likely execute.\n * This is optional. FabricJS uses to identify what the user is doing for some\n * extra optimizations. If you are writing a custom control and you want to know\n * somewhere else in the code what is going on, you can use this string here.\n * you can also provide a custom getActionName if your control run multiple actions\n * depending on some external state.\n * default to scale since is the most common, used on 4 corners by default\n * @type {String}\n * @default 'scale'\n */\n actionName: 'scale',\n\n /**\n * Drawing angle of the control.\n * NOT used for now, but name marked as needed for internal logic\n * example: to reuse the same drawing function for different rotated controls\n * @type {Number}\n * @default 0\n */\n angle: 0,\n\n /**\n * Relative position of the control. X\n * 0,0 is the center of the Object, while -0.5 (left) or 0.5 (right) are the extremities\n * of the bounding box.\n * @type {Number}\n * @default 0\n */\n x: 0,\n\n /**\n * Relative position of the control. Y\n * 0,0 is the center of the Object, while -0.5 (top) or 0.5 (bottom) are the extremities\n * of the bounding box.\n * @type {Number}\n * @default 0\n */\n y: 0,\n\n /**\n * Horizontal offset of the control from the defined position. In pixels\n * Positive offset moves the control to the right, negative to the left.\n * It used when you want to have position of control that does not scale with\n * the bounding box. Example: rotation control is placed at x:0, y: 0.5 on\n * the boundindbox, with an offset of 30 pixels vertivally. Those 30 pixels will\n * stay 30 pixels no matter how the object is big. Another example is having 2\n * controls in the corner, that stay in the same position when the object scale.\n * of the bounding box.\n * @type {Number}\n * @default 0\n */\n offsetX: 0,\n\n /**\n * Vertical offset of the control from the defined position. In pixels\n * Positive offset moves the control to the bottom, negative to the top.\n * @type {Number}\n * @default 0\n */\n offsetY: 0,\n\n /**\n * Css cursor style to display when the control is hovered.\n * if the method `cursorStyleHandler` is provided, this property is ignored.\n * @type {String}\n * @default 'crosshair'\n */\n cursorStyle: 'crosshair',\n\n /**\n * If controls has an offsetY or offsetX, draw a line that connects\n * the control to the bounding box\n * @type {Boolean}\n * @default false\n */\n withConnection: false,\n\n /**\n * The control actionHandler, provide one to handle action ( control being moved )\n * @param {Event} eventData the native mouse event\n * @param {Object} transformData properties of the current transform\n * @param {fabric.Object} object on which the control is displayed\n * @return {Function}\n */\n actionHandler: function ()\n /* eventData, transformData, fabricObject */\n {},\n\n /**\n * The control handler for mouse down, provide one to handle mouse down on control\n * @param {Event} eventData the native mouse event\n * @param {Object} transformData properties of the current transform\n * @param {fabric.Object} object on which the control is displayed\n * @return {Function}\n */\n mouseDownHandler: function ()\n /* eventData, transformData, fabricObject */\n {},\n\n /**\n * The control mouseUpHandler, provide one to handle an effect on mouse up.\n * @param {Event} eventData the native mouse event\n * @param {Object} transformData properties of the current transform\n * @param {fabric.Object} object on which the control is displayed\n * @return {Function}\n */\n mouseUpHandler: function ()\n /* eventData, transformData, fabricObject */\n {},\n\n /**\n * Returns control actionHandler\n * @param {Event} eventData the native mouse event\n * @param {Object} transformData properties of the current transform\n * @param {fabric.Object} object on which the control is displayed\n * @return {Function}\n */\n getActionHandler: function ()\n /* eventData, transformData, fabricObject */\n {\n return this.actionHandler;\n },\n\n /**\n * Returns control mouseDown handler\n * @param {Event} eventData the native mouse event\n * @param {Object} transformData properties of the current transform\n * @param {fabric.Object} object on which the control is displayed\n * @return {Function}\n */\n getMouseDownHandler: function ()\n /* eventData, fabricObject, control */\n {\n return this.mouseDownHandler;\n },\n\n /**\n * Returns control mouseUp handler\n * @param {Event} eventData the native mouse event\n * @param {Object} transformData properties of the current transform\n * @param {fabric.Object} object on which the control is displayed\n * @return {Function}\n */\n getMouseUpHandler: function ()\n /* eventData, fabricObject, control */\n {\n return this.mouseUpHandler;\n },\n\n /**\n * Returns control cursorStyle for css using cursorStyle. If you need a more elaborate\n * function you can pass one in the constructor\n * the cursorStyle property\n * @param {Event} eventData the native mouse event\n * @param {fabric.Control} control the current control ( likely this)\n * @param {fabric.Object} object on which the control is displayed\n * @return {String}\n */\n cursorStyleHandler: function (eventData, control\n /* fabricObject */\n ) {\n return control.cursorStyle;\n },\n\n /**\n * Returns the action name. The basic implementation just return the actionName property.\n * @param {Event} eventData the native mouse event\n * @param {fabric.Control} control the current control ( likely this)\n * @param {fabric.Object} object on which the control is displayed\n * @return {String}\n */\n getActionName: function (eventData, control\n /* fabricObject */\n ) {\n return control.actionName;\n },\n\n /**\n * Returns controls visibility\n * @param {fabric.Object} object on which the control is displayed\n * @param {String} controlKey key where the control is memorized on the\n * @return {Boolean}\n */\n getVisibility: function (fabricObject, controlKey) {\n var objectVisibility = fabricObject._controlsVisibility;\n\n if (objectVisibility && typeof objectVisibility[controlKey] !== 'undefined') {\n return objectVisibility[controlKey];\n }\n\n return this.visible;\n },\n\n /**\n * Sets controls visibility\n * @param {Boolean} visibility for the object\n * @return {Void}\n */\n setVisibility: function (visibility\n /* name, fabricObject */\n ) {\n this.visible = visibility;\n },\n positionHandler: function (dim, finalMatrix\n /*, fabricObject, currentControl */\n ) {\n var point = fabric.util.transformPoint({\n x: this.x * dim.x + this.offsetX,\n y: this.y * dim.y + this.offsetY\n }, finalMatrix);\n return point;\n },\n\n /**\n * Render function for the control.\n * When this function runs the context is unscaled. unrotate. Just retina scaled.\n * all the functions will have to translate to the point left,top before starting Drawing\n * if they want to draw a control where the position is detected.\n * left and top are the result of the positionHandler function\n * @param {RenderingContext2D} ctx the context where the control will be drawn\n * @param {Number} left position of the canvas where we are about to render the control.\n * @param {Number} top position of the canvas where we are about to render the control.\n * @param {Object} styleOverride\n * @param {fabric.Object} fabricObject the object where the control is about to be rendered\n */\n render: function (ctx, left, top, styleOverride, fabricObject) {\n styleOverride = styleOverride || {};\n\n switch (styleOverride.cornerStyle || fabricObject.cornerStyle) {\n case 'circle':\n fabric.controlsUtils.renderCircleControl.call(this, ctx, left, top, styleOverride, fabricObject);\n break;\n\n default:\n fabric.controlsUtils.renderSquareControl.call(this, ctx, left, top, styleOverride, fabricObject);\n }\n }\n };\n})(typeof exports !== 'undefined' ? exports : this);\n\n(function () {\n /* _FROM_SVG_START_ */\n function getColorStop(el, multiplier) {\n var style = el.getAttribute('style'),\n offset = el.getAttribute('offset') || 0,\n color,\n colorAlpha,\n opacity,\n i; // convert percents to absolute values\n\n offset = parseFloat(offset) / (/%$/.test(offset) ? 100 : 1);\n offset = offset < 0 ? 0 : offset > 1 ? 1 : offset;\n\n if (style) {\n var keyValuePairs = style.split(/\\s*;\\s*/);\n\n if (keyValuePairs[keyValuePairs.length - 1] === '') {\n keyValuePairs.pop();\n }\n\n for (i = keyValuePairs.length; i--;) {\n var split = keyValuePairs[i].split(/\\s*:\\s*/),\n key = split[0].trim(),\n value = split[1].trim();\n\n if (key === 'stop-color') {\n color = value;\n } else if (key === 'stop-opacity') {\n opacity = value;\n }\n }\n }\n\n if (!color) {\n color = el.getAttribute('stop-color') || 'rgb(0,0,0)';\n }\n\n if (!opacity) {\n opacity = el.getAttribute('stop-opacity');\n }\n\n color = new fabric.Color(color);\n colorAlpha = color.getAlpha();\n opacity = isNaN(parseFloat(opacity)) ? 1 : parseFloat(opacity);\n opacity *= colorAlpha * multiplier;\n return {\n offset: offset,\n color: color.toRgb(),\n opacity: opacity\n };\n }\n\n function getLinearCoords(el) {\n return {\n x1: el.getAttribute('x1') || 0,\n y1: el.getAttribute('y1') || 0,\n x2: el.getAttribute('x2') || '100%',\n y2: el.getAttribute('y2') || 0\n };\n }\n\n function getRadialCoords(el) {\n return {\n x1: el.getAttribute('fx') || el.getAttribute('cx') || '50%',\n y1: el.getAttribute('fy') || el.getAttribute('cy') || '50%',\n r1: 0,\n x2: el.getAttribute('cx') || '50%',\n y2: el.getAttribute('cy') || '50%',\n r2: el.getAttribute('r') || '50%'\n };\n }\n /* _FROM_SVG_END_ */\n\n\n var clone = fabric.util.object.clone;\n /**\n * Gradient class\n * @class fabric.Gradient\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#gradients}\n * @see {@link fabric.Gradient#initialize} for constructor definition\n */\n\n fabric.Gradient = fabric.util.createClass(\n /** @lends fabric.Gradient.prototype */\n {\n /**\n * Horizontal offset for aligning gradients coming from SVG when outside pathgroups\n * @type Number\n * @default 0\n */\n offsetX: 0,\n\n /**\n * Vertical offset for aligning gradients coming from SVG when outside pathgroups\n * @type Number\n * @default 0\n */\n offsetY: 0,\n\n /**\n * A transform matrix to apply to the gradient before painting.\n * Imported from svg gradients, is not applied with the current transform in the center.\n * Before this transform is applied, the origin point is at the top left corner of the object\n * plus the addition of offsetY and offsetX.\n * @type Number[]\n * @default null\n */\n gradientTransform: null,\n\n /**\n * coordinates units for coords.\n * If `pixels`, the number of coords are in the same unit of width / height.\n * If set as `percentage` the coords are still a number, but 1 means 100% of width\n * for the X and 100% of the height for the y. It can be bigger than 1 and negative.\n * allowed values pixels or percentage.\n * @type String\n * @default 'pixels'\n */\n gradientUnits: 'pixels',\n\n /**\n * Gradient type linear or radial\n * @type String\n * @default 'pixels'\n */\n type: 'linear',\n\n /**\n * Constructor\n * @param {Object} options Options object with type, coords, gradientUnits and colorStops\n * @param {Object} [options.type] gradient type linear or radial\n * @param {Object} [options.gradientUnits] gradient units\n * @param {Object} [options.offsetX] SVG import compatibility\n * @param {Object} [options.offsetY] SVG import compatibility\n * @param {Object[]} options.colorStops contains the colorstops.\n * @param {Object} options.coords contains the coords of the gradient\n * @param {Number} [options.coords.x1] X coordiante of the first point for linear or of the focal point for radial\n * @param {Number} [options.coords.y1] Y coordiante of the first point for linear or of the focal point for radial\n * @param {Number} [options.coords.x2] X coordiante of the second point for linear or of the center point for radial\n * @param {Number} [options.coords.y2] Y coordiante of the second point for linear or of the center point for radial\n * @param {Number} [options.coords.r1] only for radial gradient, radius of the inner circle\n * @param {Number} [options.coords.r2] only for radial gradient, radius of the external circle\n * @return {fabric.Gradient} thisArg\n */\n initialize: function (options) {\n options || (options = {});\n options.coords || (options.coords = {});\n\n var coords,\n _this = this; // sets everything, then coords and colorstops get sets again\n\n\n Object.keys(options).forEach(function (option) {\n _this[option] = options[option];\n });\n\n if (this.id) {\n this.id += '_' + fabric.Object.__uid++;\n } else {\n this.id = fabric.Object.__uid++;\n }\n\n coords = {\n x1: options.coords.x1 || 0,\n y1: options.coords.y1 || 0,\n x2: options.coords.x2 || 0,\n y2: options.coords.y2 || 0\n };\n\n if (this.type === 'radial') {\n coords.r1 = options.coords.r1 || 0;\n coords.r2 = options.coords.r2 || 0;\n }\n\n this.coords = coords;\n this.colorStops = options.colorStops.slice();\n },\n\n /**\n * Adds another colorStop\n * @param {Object} colorStop Object with offset and color\n * @return {fabric.Gradient} thisArg\n */\n addColorStop: function (colorStops) {\n for (var position in colorStops) {\n var color = new fabric.Color(colorStops[position]);\n this.colorStops.push({\n offset: parseFloat(position),\n color: color.toRgb(),\n opacity: color.getAlpha()\n });\n }\n\n return this;\n },\n\n /**\n * Returns object representation of a gradient\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object}\n */\n toObject: function (propertiesToInclude) {\n var object = {\n type: this.type,\n coords: this.coords,\n colorStops: this.colorStops,\n offsetX: this.offsetX,\n offsetY: this.offsetY,\n gradientUnits: this.gradientUnits,\n gradientTransform: this.gradientTransform ? this.gradientTransform.concat() : this.gradientTransform\n };\n fabric.util.populateWithProperties(this, object, propertiesToInclude);\n return object;\n },\n\n /* _TO_SVG_START_ */\n\n /**\n * Returns SVG representation of an gradient\n * @param {Object} object Object to create a gradient for\n * @return {String} SVG representation of an gradient (linear/radial)\n */\n toSVG: function (object, options) {\n var coords = clone(this.coords, true),\n i,\n len,\n options = options || {},\n markup,\n commonAttributes,\n colorStops = clone(this.colorStops, true),\n needsSwap = coords.r1 > coords.r2,\n transform = this.gradientTransform ? this.gradientTransform.concat() : fabric.iMatrix.concat(),\n offsetX = -this.offsetX,\n offsetY = -this.offsetY,\n withViewport = !!options.additionalTransform,\n gradientUnits = this.gradientUnits === 'pixels' ? 'userSpaceOnUse' : 'objectBoundingBox'; // colorStops must be sorted ascending\n\n colorStops.sort(function (a, b) {\n return a.offset - b.offset;\n });\n\n if (gradientUnits === 'objectBoundingBox') {\n offsetX /= object.width;\n offsetY /= object.height;\n } else {\n offsetX += object.width / 2;\n offsetY += object.height / 2;\n }\n\n if (object.type === 'path') {\n offsetX -= object.pathOffset.x;\n offsetY -= object.pathOffset.y;\n }\n\n transform[4] -= offsetX;\n transform[5] -= offsetY;\n commonAttributes = 'id=\"SVGID_' + this.id + '\" gradientUnits=\"' + gradientUnits + '\"';\n commonAttributes += ' gradientTransform=\"' + (withViewport ? options.additionalTransform + ' ' : '') + fabric.util.matrixToSVG(transform) + '\" ';\n\n if (this.type === 'linear') {\n markup = ['<linearGradient ', commonAttributes, ' x1=\"', coords.x1, '\" y1=\"', coords.y1, '\" x2=\"', coords.x2, '\" y2=\"', coords.y2, '\">\\n'];\n } else if (this.type === 'radial') {\n // svg radial gradient has just 1 radius. the biggest.\n markup = ['<radialGradient ', commonAttributes, ' cx=\"', needsSwap ? coords.x1 : coords.x2, '\" cy=\"', needsSwap ? coords.y1 : coords.y2, '\" r=\"', needsSwap ? coords.r1 : coords.r2, '\" fx=\"', needsSwap ? coords.x2 : coords.x1, '\" fy=\"', needsSwap ? coords.y2 : coords.y1, '\">\\n'];\n }\n\n if (this.type === 'radial') {\n if (needsSwap) {\n // svg goes from internal to external radius. if radius are inverted, swap color stops.\n colorStops = colorStops.concat();\n colorStops.reverse();\n\n for (i = 0, len = colorStops.length; i < len; i++) {\n colorStops[i].offset = 1 - colorStops[i].offset;\n }\n }\n\n var minRadius = Math.min(coords.r1, coords.r2);\n\n if (minRadius > 0) {\n // i have to shift all colorStops and add new one in 0.\n var maxRadius = Math.max(coords.r1, coords.r2),\n percentageShift = minRadius / maxRadius;\n\n for (i = 0, len = colorStops.length; i < len; i++) {\n colorStops[i].offset += percentageShift * (1 - colorStops[i].offset);\n }\n }\n }\n\n for (i = 0, len = colorStops.length; i < len; i++) {\n var colorStop = colorStops[i];\n markup.push('<stop ', 'offset=\"', colorStop.offset * 100 + '%', '\" style=\"stop-color:', colorStop.color, typeof colorStop.opacity !== 'undefined' ? ';stop-opacity: ' + colorStop.opacity : ';', '\"/>\\n');\n }\n\n markup.push(this.type === 'linear' ? '</linearGradient>\\n' : '</radialGradient>\\n');\n return markup.join('');\n },\n\n /* _TO_SVG_END_ */\n\n /**\n * Returns an instance of CanvasGradient\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @return {CanvasGradient}\n */\n toLive: function (ctx) {\n var gradient,\n coords = fabric.util.object.clone(this.coords),\n i,\n len;\n\n if (!this.type) {\n return;\n }\n\n if (this.type === 'linear') {\n gradient = ctx.createLinearGradient(coords.x1, coords.y1, coords.x2, coords.y2);\n } else if (this.type === 'radial') {\n gradient = ctx.createRadialGradient(coords.x1, coords.y1, coords.r1, coords.x2, coords.y2, coords.r2);\n }\n\n for (i = 0, len = this.colorStops.length; i < len; i++) {\n var color = this.colorStops[i].color,\n opacity = this.colorStops[i].opacity,\n offset = this.colorStops[i].offset;\n\n if (typeof opacity !== 'undefined') {\n color = new fabric.Color(color).setAlpha(opacity).toRgba();\n }\n\n gradient.addColorStop(offset, color);\n }\n\n return gradient;\n }\n });\n fabric.util.object.extend(fabric.Gradient, {\n /* _FROM_SVG_START_ */\n\n /**\n * Returns {@link fabric.Gradient} instance from an SVG element\n * @static\n * @memberOf fabric.Gradient\n * @param {SVGGradientElement} el SVG gradient element\n * @param {fabric.Object} instance\n * @param {String} opacityAttr A fill-opacity or stroke-opacity attribute to multiply to each stop's opacity.\n * @param {Object} svgOptions an object containing the size of the SVG in order to parse correctly graidents\n * that uses gradientUnits as 'userSpaceOnUse' and percentages.\n * @param {Object.number} viewBoxWidth width part of the viewBox attribute on svg\n * @param {Object.number} viewBoxHeight height part of the viewBox attribute on svg\n * @param {Object.number} width width part of the svg tag if viewBox is not specified\n * @param {Object.number} height height part of the svg tag if viewBox is not specified\n * @return {fabric.Gradient} Gradient instance\n * @see http://www.w3.org/TR/SVG/pservers.html#LinearGradientElement\n * @see http://www.w3.org/TR/SVG/pservers.html#RadialGradientElement\n */\n fromElement: function (el, instance, opacityAttr, svgOptions) {\n /**\n * @example:\n *\n * <linearGradient id=\"linearGrad1\">\n * <stop offset=\"0%\" stop-color=\"white\"/>\n * <stop offset=\"100%\" stop-color=\"black\"/>\n * </linearGradient>\n *\n * OR\n *\n * <linearGradient id=\"linearGrad2\">\n * <stop offset=\"0\" style=\"stop-color:rgb(255,255,255)\"/>\n * <stop offset=\"1\" style=\"stop-color:rgb(0,0,0)\"/>\n * </linearGradient>\n *\n * OR\n *\n * <radialGradient id=\"radialGrad1\">\n * <stop offset=\"0%\" stop-color=\"white\" stop-opacity=\"1\" />\n * <stop offset=\"50%\" stop-color=\"black\" stop-opacity=\"0.5\" />\n * <stop offset=\"100%\" stop-color=\"white\" stop-opacity=\"1\" />\n * </radialGradient>\n *\n * OR\n *\n * <radialGradient id=\"radialGrad2\">\n * <stop offset=\"0\" stop-color=\"rgb(255,255,255)\" />\n * <stop offset=\"0.5\" stop-color=\"rgb(0,0,0)\" />\n * <stop offset=\"1\" stop-color=\"rgb(255,255,255)\" />\n * </radialGradient>\n *\n */\n var multiplier = parseFloat(opacityAttr) / (/%$/.test(opacityAttr) ? 100 : 1);\n multiplier = multiplier < 0 ? 0 : multiplier > 1 ? 1 : multiplier;\n\n if (isNaN(multiplier)) {\n multiplier = 1;\n }\n\n var colorStopEls = el.getElementsByTagName('stop'),\n type,\n gradientUnits = el.getAttribute('gradientUnits') === 'userSpaceOnUse' ? 'pixels' : 'percentage',\n gradientTransform = el.getAttribute('gradientTransform') || '',\n colorStops = [],\n coords,\n i,\n offsetX = 0,\n offsetY = 0,\n transformMatrix;\n\n if (el.nodeName === 'linearGradient' || el.nodeName === 'LINEARGRADIENT') {\n type = 'linear';\n coords = getLinearCoords(el);\n } else {\n type = 'radial';\n coords = getRadialCoords(el);\n }\n\n for (i = colorStopEls.length; i--;) {\n colorStops.push(getColorStop(colorStopEls[i], multiplier));\n }\n\n transformMatrix = fabric.parseTransformAttribute(gradientTransform);\n\n __convertPercentUnitsToValues(instance, coords, svgOptions, gradientUnits);\n\n if (gradientUnits === 'pixels') {\n offsetX = -instance.left;\n offsetY = -instance.top;\n }\n\n var gradient = new fabric.Gradient({\n id: el.getAttribute('id'),\n type: type,\n coords: coords,\n colorStops: colorStops,\n gradientUnits: gradientUnits,\n gradientTransform: transformMatrix,\n offsetX: offsetX,\n offsetY: offsetY\n });\n return gradient;\n }\n /* _FROM_SVG_END_ */\n\n });\n /**\n * @private\n */\n\n function __convertPercentUnitsToValues(instance, options, svgOptions, gradientUnits) {\n var propValue, finalValue;\n Object.keys(options).forEach(function (prop) {\n propValue = options[prop];\n\n if (propValue === 'Infinity') {\n finalValue = 1;\n } else if (propValue === '-Infinity') {\n finalValue = 0;\n } else {\n finalValue = parseFloat(options[prop], 10);\n\n if (typeof propValue === 'string' && /^(\\d+\\.\\d+)%|(\\d+)%$/.test(propValue)) {\n finalValue *= 0.01;\n\n if (gradientUnits === 'pixels') {\n // then we need to fix those percentages here in svg parsing\n if (prop === 'x1' || prop === 'x2' || prop === 'r2') {\n finalValue *= svgOptions.viewBoxWidth || svgOptions.width;\n }\n\n if (prop === 'y1' || prop === 'y2') {\n finalValue *= svgOptions.viewBoxHeight || svgOptions.height;\n }\n }\n }\n }\n\n options[prop] = finalValue;\n });\n }\n})();\n\n(function () {\n 'use strict';\n\n var toFixed = fabric.util.toFixed;\n /**\n * Pattern class\n * @class fabric.Pattern\n * @see {@link http://fabricjs.com/patterns|Pattern demo}\n * @see {@link http://fabricjs.com/dynamic-patterns|DynamicPattern demo}\n * @see {@link fabric.Pattern#initialize} for constructor definition\n */\n\n fabric.Pattern = fabric.util.createClass(\n /** @lends fabric.Pattern.prototype */\n {\n /**\n * Repeat property of a pattern (one of repeat, repeat-x, repeat-y or no-repeat)\n * @type String\n * @default\n */\n repeat: 'repeat',\n\n /**\n * Pattern horizontal offset from object's left/top corner\n * @type Number\n * @default\n */\n offsetX: 0,\n\n /**\n * Pattern vertical offset from object's left/top corner\n * @type Number\n * @default\n */\n offsetY: 0,\n\n /**\n * crossOrigin value (one of \"\", \"anonymous\", \"use-credentials\")\n * @see https://developer.mozilla.org/en-US/docs/HTML/CORS_settings_attributes\n * @type String\n * @default\n */\n crossOrigin: '',\n\n /**\n * transform matrix to change the pattern, imported from svgs.\n * @type Array\n * @default\n */\n patternTransform: null,\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n * @param {Function} [callback] function to invoke after callback init.\n * @return {fabric.Pattern} thisArg\n */\n initialize: function (options, callback) {\n options || (options = {});\n this.id = fabric.Object.__uid++;\n this.setOptions(options);\n\n if (!options.source || options.source && typeof options.source !== 'string') {\n callback && callback(this);\n return;\n } else {\n // img src string\n var _this = this;\n\n this.source = fabric.util.createImage();\n fabric.util.loadImage(options.source, function (img, isError) {\n _this.source = img;\n callback && callback(_this, isError);\n }, null, this.crossOrigin);\n }\n },\n\n /**\n * Returns object representation of a pattern\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} Object representation of a pattern instance\n */\n toObject: function (propertiesToInclude) {\n var NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS,\n source,\n object; // <img> element\n\n if (typeof this.source.src === 'string') {\n source = this.source.src;\n } // <canvas> element\n else if (typeof this.source === 'object' && this.source.toDataURL) {\n source = this.source.toDataURL();\n }\n\n object = {\n type: 'pattern',\n source: source,\n repeat: this.repeat,\n crossOrigin: this.crossOrigin,\n offsetX: toFixed(this.offsetX, NUM_FRACTION_DIGITS),\n offsetY: toFixed(this.offsetY, NUM_FRACTION_DIGITS),\n patternTransform: this.patternTransform ? this.patternTransform.concat() : null\n };\n fabric.util.populateWithProperties(this, object, propertiesToInclude);\n return object;\n },\n\n /* _TO_SVG_START_ */\n\n /**\n * Returns SVG representation of a pattern\n * @param {fabric.Object} object\n * @return {String} SVG representation of a pattern\n */\n toSVG: function (object) {\n var patternSource = typeof this.source === 'function' ? this.source() : this.source,\n patternWidth = patternSource.width / object.width,\n patternHeight = patternSource.height / object.height,\n patternOffsetX = this.offsetX / object.width,\n patternOffsetY = this.offsetY / object.height,\n patternImgSrc = '';\n\n if (this.repeat === 'repeat-x' || this.repeat === 'no-repeat') {\n patternHeight = 1;\n\n if (patternOffsetY) {\n patternHeight += Math.abs(patternOffsetY);\n }\n }\n\n if (this.repeat === 'repeat-y' || this.repeat === 'no-repeat') {\n patternWidth = 1;\n\n if (patternOffsetX) {\n patternWidth += Math.abs(patternOffsetX);\n }\n }\n\n if (patternSource.src) {\n patternImgSrc = patternSource.src;\n } else if (patternSource.toDataURL) {\n patternImgSrc = patternSource.toDataURL();\n }\n\n return '<pattern id=\"SVGID_' + this.id + '\" x=\"' + patternOffsetX + '\" y=\"' + patternOffsetY + '\" width=\"' + patternWidth + '\" height=\"' + patternHeight + '\">\\n' + '<image x=\"0\" y=\"0\"' + ' width=\"' + patternSource.width + '\" height=\"' + patternSource.height + '\" xlink:href=\"' + patternImgSrc + '\"></image>\\n' + '</pattern>\\n';\n },\n\n /* _TO_SVG_END_ */\n setOptions: function (options) {\n for (var prop in options) {\n this[prop] = options[prop];\n }\n },\n\n /**\n * Returns an instance of CanvasPattern\n * @param {CanvasRenderingContext2D} ctx Context to create pattern\n * @return {CanvasPattern}\n */\n toLive: function (ctx) {\n var source = this.source; // if the image failed to load, return, and allow rest to continue loading\n\n if (!source) {\n return '';\n } // if an image\n\n\n if (typeof source.src !== 'undefined') {\n if (!source.complete) {\n return '';\n }\n\n if (source.naturalWidth === 0 || source.naturalHeight === 0) {\n return '';\n }\n }\n\n return ctx.createPattern(source, this.repeat);\n }\n });\n})();\n\n(function (global) {\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = {}),\n toFixed = fabric.util.toFixed;\n\n if (fabric.Shadow) {\n fabric.warn('fabric.Shadow is already defined.');\n return;\n }\n /**\n * Shadow class\n * @class fabric.Shadow\n * @see {@link http://fabricjs.com/shadows|Shadow demo}\n * @see {@link fabric.Shadow#initialize} for constructor definition\n */\n\n\n fabric.Shadow = fabric.util.createClass(\n /** @lends fabric.Shadow.prototype */\n {\n /**\n * Shadow color\n * @type String\n * @default\n */\n color: 'rgb(0,0,0)',\n\n /**\n * Shadow blur\n * @type Number\n */\n blur: 0,\n\n /**\n * Shadow horizontal offset\n * @type Number\n * @default\n */\n offsetX: 0,\n\n /**\n * Shadow vertical offset\n * @type Number\n * @default\n */\n offsetY: 0,\n\n /**\n * Whether the shadow should affect stroke operations\n * @type Boolean\n * @default\n */\n affectStroke: false,\n\n /**\n * Indicates whether toObject should include default values\n * @type Boolean\n * @default\n */\n includeDefaultValues: true,\n\n /**\n * When `false`, the shadow will scale with the object.\n * When `true`, the shadow's offsetX, offsetY, and blur will not be affected by the object's scale.\n * default to false\n * @type Boolean\n * @default\n */\n nonScaling: false,\n\n /**\n * Constructor\n * @param {Object|String} [options] Options object with any of color, blur, offsetX, offsetY properties or string (e.g. \"rgba(0,0,0,0.2) 2px 2px 10px\")\n * @return {fabric.Shadow} thisArg\n */\n initialize: function (options) {\n if (typeof options === 'string') {\n options = this._parseShadow(options);\n }\n\n for (var prop in options) {\n this[prop] = options[prop];\n }\n\n this.id = fabric.Object.__uid++;\n },\n\n /**\n * @private\n * @param {String} shadow Shadow value to parse\n * @return {Object} Shadow object with color, offsetX, offsetY and blur\n */\n _parseShadow: function (shadow) {\n var shadowStr = shadow.trim(),\n offsetsAndBlur = fabric.Shadow.reOffsetsAndBlur.exec(shadowStr) || [],\n color = shadowStr.replace(fabric.Shadow.reOffsetsAndBlur, '') || 'rgb(0,0,0)';\n return {\n color: color.trim(),\n offsetX: parseInt(offsetsAndBlur[1], 10) || 0,\n offsetY: parseInt(offsetsAndBlur[2], 10) || 0,\n blur: parseInt(offsetsAndBlur[3], 10) || 0\n };\n },\n\n /**\n * Returns a string representation of an instance\n * @see http://www.w3.org/TR/css-text-decor-3/#text-shadow\n * @return {String} Returns CSS3 text-shadow declaration\n */\n toString: function () {\n return [this.offsetX, this.offsetY, this.blur, this.color].join('px ');\n },\n\n /* _TO_SVG_START_ */\n\n /**\n * Returns SVG representation of a shadow\n * @param {fabric.Object} object\n * @return {String} SVG representation of a shadow\n */\n toSVG: function (object) {\n var fBoxX = 40,\n fBoxY = 40,\n NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS,\n offset = fabric.util.rotateVector({\n x: this.offsetX,\n y: this.offsetY\n }, fabric.util.degreesToRadians(-object.angle)),\n BLUR_BOX = 20,\n color = new fabric.Color(this.color);\n\n if (object.width && object.height) {\n //http://www.w3.org/TR/SVG/filters.html#FilterEffectsRegion\n // we add some extra space to filter box to contain the blur ( 20 )\n fBoxX = toFixed((Math.abs(offset.x) + this.blur) / object.width, NUM_FRACTION_DIGITS) * 100 + BLUR_BOX;\n fBoxY = toFixed((Math.abs(offset.y) + this.blur) / object.height, NUM_FRACTION_DIGITS) * 100 + BLUR_BOX;\n }\n\n if (object.flipX) {\n offset.x *= -1;\n }\n\n if (object.flipY) {\n offset.y *= -1;\n }\n\n return '<filter id=\"SVGID_' + this.id + '\" y=\"-' + fBoxY + '%\" height=\"' + (100 + 2 * fBoxY) + '%\" ' + 'x=\"-' + fBoxX + '%\" width=\"' + (100 + 2 * fBoxX) + '%\" ' + '>\\n' + '\\t<feGaussianBlur in=\"SourceAlpha\" stdDeviation=\"' + toFixed(this.blur ? this.blur / 2 : 0, NUM_FRACTION_DIGITS) + '\"></feGaussianBlur>\\n' + '\\t<feOffset dx=\"' + toFixed(offset.x, NUM_FRACTION_DIGITS) + '\" dy=\"' + toFixed(offset.y, NUM_FRACTION_DIGITS) + '\" result=\"oBlur\" ></feOffset>\\n' + '\\t<feFlood flood-color=\"' + color.toRgb() + '\" flood-opacity=\"' + color.getAlpha() + '\"/>\\n' + '\\t<feComposite in2=\"oBlur\" operator=\"in\" />\\n' + '\\t<feMerge>\\n' + '\\t\\t<feMergeNode></feMergeNode>\\n' + '\\t\\t<feMergeNode in=\"SourceGraphic\"></feMergeNode>\\n' + '\\t</feMerge>\\n' + '</filter>\\n';\n },\n\n /* _TO_SVG_END_ */\n\n /**\n * Returns object representation of a shadow\n * @return {Object} Object representation of a shadow instance\n */\n toObject: function () {\n if (this.includeDefaultValues) {\n return {\n color: this.color,\n blur: this.blur,\n offsetX: this.offsetX,\n offsetY: this.offsetY,\n affectStroke: this.affectStroke,\n nonScaling: this.nonScaling\n };\n }\n\n var obj = {},\n proto = fabric.Shadow.prototype;\n ['color', 'blur', 'offsetX', 'offsetY', 'affectStroke', 'nonScaling'].forEach(function (prop) {\n if (this[prop] !== proto[prop]) {\n obj[prop] = this[prop];\n }\n }, this);\n return obj;\n }\n });\n /**\n * Regex matching shadow offsetX, offsetY and blur (ex: \"2px 2px 10px rgba(0,0,0,0.2)\", \"rgb(0,255,0) 2px 2px\")\n * @static\n * @field\n * @memberOf fabric.Shadow\n */\n // eslint-disable-next-line max-len\n\n fabric.Shadow.reOffsetsAndBlur = /(?:\\s|^)(-?\\d+(?:px)?(?:\\s?|$))?(-?\\d+(?:px)?(?:\\s?|$))?(\\d+(?:px)?)?(?:\\s?|$)(?:$|\\s)/;\n})(typeof exports !== 'undefined' ? exports : this);\n\n(function () {\n 'use strict';\n\n if (fabric.StaticCanvas) {\n fabric.warn('fabric.StaticCanvas is already defined.');\n return;\n } // aliases for faster resolution\n\n\n var extend = fabric.util.object.extend,\n getElementOffset = fabric.util.getElementOffset,\n removeFromArray = fabric.util.removeFromArray,\n toFixed = fabric.util.toFixed,\n transformPoint = fabric.util.transformPoint,\n invertTransform = fabric.util.invertTransform,\n getNodeCanvas = fabric.util.getNodeCanvas,\n createCanvasElement = fabric.util.createCanvasElement,\n CANVAS_INIT_ERROR = new Error('Could not initialize `canvas` element');\n /**\n * Static canvas class\n * @class fabric.StaticCanvas\n * @mixes fabric.Collection\n * @mixes fabric.Observable\n * @see {@link http://fabricjs.com/static_canvas|StaticCanvas demo}\n * @see {@link fabric.StaticCanvas#initialize} for constructor definition\n * @fires before:render\n * @fires after:render\n * @fires canvas:cleared\n * @fires object:added\n * @fires object:removed\n */\n\n fabric.StaticCanvas = fabric.util.createClass(fabric.CommonMethods,\n /** @lends fabric.StaticCanvas.prototype */\n {\n /**\n * Constructor\n * @param {HTMLElement | String} el <canvas> element to initialize instance on\n * @param {Object} [options] Options object\n * @return {Object} thisArg\n */\n initialize: function (el, options) {\n options || (options = {});\n this.renderAndResetBound = this.renderAndReset.bind(this);\n this.requestRenderAllBound = this.requestRenderAll.bind(this);\n\n this._initStatic(el, options);\n },\n\n /**\n * Background color of canvas instance.\n * Should be set via {@link fabric.StaticCanvas#setBackgroundColor}.\n * @type {(String|fabric.Pattern)}\n * @default\n */\n backgroundColor: '',\n\n /**\n * Background image of canvas instance.\n * since 2.4.0 image caching is active, please when putting an image as background, add to the\n * canvas property a reference to the canvas it is on. Otherwise the image cannot detect the zoom\n * vale. As an alternative you can disable image objectCaching\n * @type fabric.Image\n * @default\n */\n backgroundImage: null,\n\n /**\n * Overlay color of canvas instance.\n * Should be set via {@link fabric.StaticCanvas#setOverlayColor}\n * @since 1.3.9\n * @type {(String|fabric.Pattern)}\n * @default\n */\n overlayColor: '',\n\n /**\n * Overlay image of canvas instance.\n * since 2.4.0 image caching is active, please when putting an image as overlay, add to the\n * canvas property a reference to the canvas it is on. Otherwise the image cannot detect the zoom\n * vale. As an alternative you can disable image objectCaching\n * @type fabric.Image\n * @default\n */\n overlayImage: null,\n\n /**\n * Indicates whether toObject/toDatalessObject should include default values\n * if set to false, takes precedence over the object value.\n * @type Boolean\n * @default\n */\n includeDefaultValues: true,\n\n /**\n * Indicates whether objects' state should be saved\n * @type Boolean\n * @default\n */\n stateful: false,\n\n /**\n * Indicates whether {@link fabric.Collection.add}, {@link fabric.Collection.insertAt} and {@link fabric.Collection.remove},\n * {@link fabric.StaticCanvas.moveTo}, {@link fabric.StaticCanvas.clear} and many more, should also re-render canvas.\n * Disabling this option will not give a performance boost when adding/removing a lot of objects to/from canvas at once\n * since the renders are quequed and executed one per frame.\n * Disabling is suggested anyway and managing the renders of the app manually is not a big effort ( canvas.requestRenderAll() )\n * Left default to true to do not break documentation and old app, fiddles.\n * @type Boolean\n * @default\n */\n renderOnAddRemove: true,\n\n /**\n * Indicates whether object controls (borders/controls) are rendered above overlay image\n * @type Boolean\n * @default\n */\n controlsAboveOverlay: false,\n\n /**\n * Indicates whether the browser can be scrolled when using a touchscreen and dragging on the canvas\n * @type Boolean\n * @default\n */\n allowTouchScrolling: false,\n\n /**\n * Indicates whether this canvas will use image smoothing, this is on by default in browsers\n * @type Boolean\n * @default\n */\n imageSmoothingEnabled: true,\n\n /**\n * The transformation (in the format of Canvas transform) which focuses the viewport\n * @type Array\n * @default\n */\n viewportTransform: fabric.iMatrix.concat(),\n\n /**\n * if set to false background image is not affected by viewport transform\n * @since 1.6.3\n * @type Boolean\n * @default\n */\n backgroundVpt: true,\n\n /**\n * if set to false overlya image is not affected by viewport transform\n * @since 1.6.3\n * @type Boolean\n * @default\n */\n overlayVpt: true,\n\n /**\n * When true, canvas is scaled by devicePixelRatio for better rendering on retina screens\n * @type Boolean\n * @default\n */\n enableRetinaScaling: true,\n\n /**\n * Describe canvas element extension over design\n * properties are tl,tr,bl,br.\n * if canvas is not zoomed/panned those points are the four corner of canvas\n * if canvas is viewportTransformed you those points indicate the extension\n * of canvas element in plain untrasformed coordinates\n * The coordinates get updated with @method calcViewportBoundaries.\n * @memberOf fabric.StaticCanvas.prototype\n */\n vptCoords: {},\n\n /**\n * Based on vptCoords and object.aCoords, skip rendering of objects that\n * are not included in current viewport.\n * May greatly help in applications with crowded canvas and use of zoom/pan\n * If One of the corner of the bounding box of the object is on the canvas\n * the objects get rendered.\n * @memberOf fabric.StaticCanvas.prototype\n * @type Boolean\n * @default\n */\n skipOffscreen: true,\n\n /**\n * a fabricObject that, without stroke define a clipping area with their shape. filled in black\n * the clipPath object gets used when the canvas has rendered, and the context is placed in the\n * top left corner of the canvas.\n * clipPath will clip away controls, if you do not want this to happen use controlsAboveOverlay = true\n * @type fabric.Object\n */\n clipPath: undefined,\n\n /**\n * @private\n * @param {HTMLElement | String} el <canvas> element to initialize instance on\n * @param {Object} [options] Options object\n */\n _initStatic: function (el, options) {\n var cb = this.requestRenderAllBound;\n this._objects = [];\n\n this._createLowerCanvas(el);\n\n this._initOptions(options); // only initialize retina scaling once\n\n\n if (!this.interactive) {\n this._initRetinaScaling();\n }\n\n if (options.overlayImage) {\n this.setOverlayImage(options.overlayImage, cb);\n }\n\n if (options.backgroundImage) {\n this.setBackgroundImage(options.backgroundImage, cb);\n }\n\n if (options.backgroundColor) {\n this.setBackgroundColor(options.backgroundColor, cb);\n }\n\n if (options.overlayColor) {\n this.setOverlayColor(options.overlayColor, cb);\n }\n\n this.calcOffset();\n },\n\n /**\n * @private\n */\n _isRetinaScaling: function () {\n return fabric.devicePixelRatio !== 1 && this.enableRetinaScaling;\n },\n\n /**\n * @private\n * @return {Number} retinaScaling if applied, otherwise 1;\n */\n getRetinaScaling: function () {\n return this._isRetinaScaling() ? fabric.devicePixelRatio : 1;\n },\n\n /**\n * @private\n */\n _initRetinaScaling: function () {\n if (!this._isRetinaScaling()) {\n return;\n }\n\n var scaleRatio = fabric.devicePixelRatio;\n\n this.__initRetinaScaling(scaleRatio, this.lowerCanvasEl, this.contextContainer);\n\n if (this.upperCanvasEl) {\n this.__initRetinaScaling(scaleRatio, this.upperCanvasEl, this.contextTop);\n }\n },\n __initRetinaScaling: function (scaleRatio, canvas, context) {\n canvas.setAttribute('width', this.width * scaleRatio);\n canvas.setAttribute('height', this.height * scaleRatio);\n context.scale(scaleRatio, scaleRatio);\n },\n\n /**\n * Calculates canvas element offset relative to the document\n * This method is also attached as \"resize\" event handler of window\n * @return {fabric.Canvas} instance\n * @chainable\n */\n calcOffset: function () {\n this._offset = getElementOffset(this.lowerCanvasEl);\n return this;\n },\n\n /**\n * Sets {@link fabric.StaticCanvas#overlayImage|overlay image} for this canvas\n * @param {(fabric.Image|String)} image fabric.Image instance or URL of an image to set overlay to\n * @param {Function} callback callback to invoke when image is loaded and set as an overlay\n * @param {Object} [options] Optional options to set for the {@link fabric.Image|overlay image}.\n * @return {fabric.Canvas} thisArg\n * @chainable\n * @see {@link http://jsfiddle.net/fabricjs/MnzHT/|jsFiddle demo}\n * @example <caption>Normal overlayImage with left/top = 0</caption>\n * canvas.setOverlayImage('http://fabricjs.com/assets/jail_cell_bars.png', canvas.renderAll.bind(canvas), {\n * // Needed to position overlayImage at 0/0\n * originX: 'left',\n * originY: 'top'\n * });\n * @example <caption>overlayImage with different properties</caption>\n * canvas.setOverlayImage('http://fabricjs.com/assets/jail_cell_bars.png', canvas.renderAll.bind(canvas), {\n * opacity: 0.5,\n * angle: 45,\n * left: 400,\n * top: 400,\n * originX: 'left',\n * originY: 'top'\n * });\n * @example <caption>Stretched overlayImage #1 - width/height correspond to canvas width/height</caption>\n * fabric.Image.fromURL('http://fabricjs.com/assets/jail_cell_bars.png', function(img, isError) {\n * img.set({width: canvas.width, height: canvas.height, originX: 'left', originY: 'top'});\n * canvas.setOverlayImage(img, canvas.renderAll.bind(canvas));\n * });\n * @example <caption>Stretched overlayImage #2 - width/height correspond to canvas width/height</caption>\n * canvas.setOverlayImage('http://fabricjs.com/assets/jail_cell_bars.png', canvas.renderAll.bind(canvas), {\n * width: canvas.width,\n * height: canvas.height,\n * // Needed to position overlayImage at 0/0\n * originX: 'left',\n * originY: 'top'\n * });\n * @example <caption>overlayImage loaded from cross-origin</caption>\n * canvas.setOverlayImage('http://fabricjs.com/assets/jail_cell_bars.png', canvas.renderAll.bind(canvas), {\n * opacity: 0.5,\n * angle: 45,\n * left: 400,\n * top: 400,\n * originX: 'left',\n * originY: 'top',\n * crossOrigin: 'anonymous'\n * });\n */\n setOverlayImage: function (image, callback, options) {\n return this.__setBgOverlayImage('overlayImage', image, callback, options);\n },\n\n /**\n * Sets {@link fabric.StaticCanvas#backgroundImage|background image} for this canvas\n * @param {(fabric.Image|String)} image fabric.Image instance or URL of an image to set background to\n * @param {Function} callback Callback to invoke when image is loaded and set as background\n * @param {Object} [options] Optional options to set for the {@link fabric.Image|background image}.\n * @return {fabric.Canvas} thisArg\n * @chainable\n * @see {@link http://jsfiddle.net/djnr8o7a/28/|jsFiddle demo}\n * @example <caption>Normal backgroundImage with left/top = 0</caption>\n * canvas.setBackgroundImage('http://fabricjs.com/assets/honey_im_subtle.png', canvas.renderAll.bind(canvas), {\n * // Needed to position backgroundImage at 0/0\n * originX: 'left',\n * originY: 'top'\n * });\n * @example <caption>backgroundImage with different properties</caption>\n * canvas.setBackgroundImage('http://fabricjs.com/assets/honey_im_subtle.png', canvas.renderAll.bind(canvas), {\n * opacity: 0.5,\n * angle: 45,\n * left: 400,\n * top: 400,\n * originX: 'left',\n * originY: 'top'\n * });\n * @example <caption>Stretched backgroundImage #1 - width/height correspond to canvas width/height</caption>\n * fabric.Image.fromURL('http://fabricjs.com/assets/honey_im_subtle.png', function(img, isError) {\n * img.set({width: canvas.width, height: canvas.height, originX: 'left', originY: 'top'});\n * canvas.setBackgroundImage(img, canvas.renderAll.bind(canvas));\n * });\n * @example <caption>Stretched backgroundImage #2 - width/height correspond to canvas width/height</caption>\n * canvas.setBackgroundImage('http://fabricjs.com/assets/honey_im_subtle.png', canvas.renderAll.bind(canvas), {\n * width: canvas.width,\n * height: canvas.height,\n * // Needed to position backgroundImage at 0/0\n * originX: 'left',\n * originY: 'top'\n * });\n * @example <caption>backgroundImage loaded from cross-origin</caption>\n * canvas.setBackgroundImage('http://fabricjs.com/assets/honey_im_subtle.png', canvas.renderAll.bind(canvas), {\n * opacity: 0.5,\n * angle: 45,\n * left: 400,\n * top: 400,\n * originX: 'left',\n * originY: 'top',\n * crossOrigin: 'anonymous'\n * });\n */\n // TODO: fix stretched examples\n setBackgroundImage: function (image, callback, options) {\n return this.__setBgOverlayImage('backgroundImage', image, callback, options);\n },\n\n /**\n * Sets {@link fabric.StaticCanvas#overlayColor|foreground color} for this canvas\n * @param {(String|fabric.Pattern)} overlayColor Color or pattern to set foreground color to\n * @param {Function} callback Callback to invoke when foreground color is set\n * @return {fabric.Canvas} thisArg\n * @chainable\n * @see {@link http://jsfiddle.net/fabricjs/pB55h/|jsFiddle demo}\n * @example <caption>Normal overlayColor - color value</caption>\n * canvas.setOverlayColor('rgba(255, 73, 64, 0.6)', canvas.renderAll.bind(canvas));\n * @example <caption>fabric.Pattern used as overlayColor</caption>\n * canvas.setOverlayColor({\n * source: 'http://fabricjs.com/assets/escheresque_ste.png'\n * }, canvas.renderAll.bind(canvas));\n * @example <caption>fabric.Pattern used as overlayColor with repeat and offset</caption>\n * canvas.setOverlayColor({\n * source: 'http://fabricjs.com/assets/escheresque_ste.png',\n * repeat: 'repeat',\n * offsetX: 200,\n * offsetY: 100\n * }, canvas.renderAll.bind(canvas));\n */\n setOverlayColor: function (overlayColor, callback) {\n return this.__setBgOverlayColor('overlayColor', overlayColor, callback);\n },\n\n /**\n * Sets {@link fabric.StaticCanvas#backgroundColor|background color} for this canvas\n * @param {(String|fabric.Pattern)} backgroundColor Color or pattern to set background color to\n * @param {Function} callback Callback to invoke when background color is set\n * @return {fabric.Canvas} thisArg\n * @chainable\n * @see {@link http://jsfiddle.net/fabricjs/hXzvk/|jsFiddle demo}\n * @example <caption>Normal backgroundColor - color value</caption>\n * canvas.setBackgroundColor('rgba(255, 73, 64, 0.6)', canvas.renderAll.bind(canvas));\n * @example <caption>fabric.Pattern used as backgroundColor</caption>\n * canvas.setBackgroundColor({\n * source: 'http://fabricjs.com/assets/escheresque_ste.png'\n * }, canvas.renderAll.bind(canvas));\n * @example <caption>fabric.Pattern used as backgroundColor with repeat and offset</caption>\n * canvas.setBackgroundColor({\n * source: 'http://fabricjs.com/assets/escheresque_ste.png',\n * repeat: 'repeat',\n * offsetX: 200,\n * offsetY: 100\n * }, canvas.renderAll.bind(canvas));\n */\n setBackgroundColor: function (backgroundColor, callback) {\n return this.__setBgOverlayColor('backgroundColor', backgroundColor, callback);\n },\n\n /**\n * @private\n * @param {String} property Property to set ({@link fabric.StaticCanvas#backgroundImage|backgroundImage}\n * or {@link fabric.StaticCanvas#overlayImage|overlayImage})\n * @param {(fabric.Image|String|null)} image fabric.Image instance, URL of an image or null to set background or overlay to\n * @param {Function} callback Callback to invoke when image is loaded and set as background or overlay. The first argument is the created image, the second argument is a flag indicating whether an error occured or not.\n * @param {Object} [options] Optional options to set for the {@link fabric.Image|image}.\n */\n __setBgOverlayImage: function (property, image, callback, options) {\n if (typeof image === 'string') {\n fabric.util.loadImage(image, function (img, isError) {\n if (img) {\n var instance = new fabric.Image(img, options);\n this[property] = instance;\n instance.canvas = this;\n }\n\n callback && callback(img, isError);\n }, this, options && options.crossOrigin);\n } else {\n options && image.setOptions(options);\n this[property] = image;\n image && (image.canvas = this);\n callback && callback(image, false);\n }\n\n return this;\n },\n\n /**\n * @private\n * @param {String} property Property to set ({@link fabric.StaticCanvas#backgroundColor|backgroundColor}\n * or {@link fabric.StaticCanvas#overlayColor|overlayColor})\n * @param {(Object|String|null)} color Object with pattern information, color value or null\n * @param {Function} [callback] Callback is invoked when color is set\n */\n __setBgOverlayColor: function (property, color, callback) {\n this[property] = color;\n\n this._initGradient(color, property);\n\n this._initPattern(color, property, callback);\n\n return this;\n },\n\n /**\n * @private\n */\n _createCanvasElement: function () {\n var element = createCanvasElement();\n\n if (!element) {\n throw CANVAS_INIT_ERROR;\n }\n\n if (!element.style) {\n element.style = {};\n }\n\n if (typeof element.getContext === 'undefined') {\n throw CANVAS_INIT_ERROR;\n }\n\n return element;\n },\n\n /**\n * @private\n * @param {Object} [options] Options object\n */\n _initOptions: function (options) {\n var lowerCanvasEl = this.lowerCanvasEl;\n\n this._setOptions(options);\n\n this.width = this.width || parseInt(lowerCanvasEl.width, 10) || 0;\n this.height = this.height || parseInt(lowerCanvasEl.height, 10) || 0;\n\n if (!this.lowerCanvasEl.style) {\n return;\n }\n\n lowerCanvasEl.width = this.width;\n lowerCanvasEl.height = this.height;\n lowerCanvasEl.style.width = this.width + 'px';\n lowerCanvasEl.style.height = this.height + 'px';\n this.viewportTransform = this.viewportTransform.slice();\n },\n\n /**\n * Creates a bottom canvas\n * @private\n * @param {HTMLElement} [canvasEl]\n */\n _createLowerCanvas: function (canvasEl) {\n // canvasEl === 'HTMLCanvasElement' does not work on jsdom/node\n if (canvasEl && canvasEl.getContext) {\n this.lowerCanvasEl = canvasEl;\n } else {\n this.lowerCanvasEl = fabric.util.getById(canvasEl) || this._createCanvasElement();\n }\n\n fabric.util.addClass(this.lowerCanvasEl, 'lower-canvas');\n\n if (this.interactive) {\n this._applyCanvasStyle(this.lowerCanvasEl);\n }\n\n this.contextContainer = this.lowerCanvasEl.getContext('2d');\n },\n\n /**\n * Returns canvas width (in px)\n * @return {Number}\n */\n getWidth: function () {\n return this.width;\n },\n\n /**\n * Returns canvas height (in px)\n * @return {Number}\n */\n getHeight: function () {\n return this.height;\n },\n\n /**\n * Sets width of this canvas instance\n * @param {Number|String} value Value to set width to\n * @param {Object} [options] Options object\n * @param {Boolean} [options.backstoreOnly=false] Set the given dimensions only as canvas backstore dimensions\n * @param {Boolean} [options.cssOnly=false] Set the given dimensions only as css dimensions\n * @return {fabric.Canvas} instance\n * @chainable true\n */\n setWidth: function (value, options) {\n return this.setDimensions({\n width: value\n }, options);\n },\n\n /**\n * Sets height of this canvas instance\n * @param {Number|String} value Value to set height to\n * @param {Object} [options] Options object\n * @param {Boolean} [options.backstoreOnly=false] Set the given dimensions only as canvas backstore dimensions\n * @param {Boolean} [options.cssOnly=false] Set the given dimensions only as css dimensions\n * @return {fabric.Canvas} instance\n * @chainable true\n */\n setHeight: function (value, options) {\n return this.setDimensions({\n height: value\n }, options);\n },\n\n /**\n * Sets dimensions (width, height) of this canvas instance. when options.cssOnly flag active you should also supply the unit of measure (px/%/em)\n * @param {Object} dimensions Object with width/height properties\n * @param {Number|String} [dimensions.width] Width of canvas element\n * @param {Number|String} [dimensions.height] Height of canvas element\n * @param {Object} [options] Options object\n * @param {Boolean} [options.backstoreOnly=false] Set the given dimensions only as canvas backstore dimensions\n * @param {Boolean} [options.cssOnly=false] Set the given dimensions only as css dimensions\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n setDimensions: function (dimensions, options) {\n var cssValue;\n options = options || {};\n\n for (var prop in dimensions) {\n cssValue = dimensions[prop];\n\n if (!options.cssOnly) {\n this._setBackstoreDimension(prop, dimensions[prop]);\n\n cssValue += 'px';\n this.hasLostContext = true;\n }\n\n if (!options.backstoreOnly) {\n this._setCssDimension(prop, cssValue);\n }\n }\n\n if (this._isCurrentlyDrawing) {\n this.freeDrawingBrush && this.freeDrawingBrush._setBrushStyles();\n }\n\n this._initRetinaScaling();\n\n this.calcOffset();\n\n if (!options.cssOnly) {\n this.requestRenderAll();\n }\n\n return this;\n },\n\n /**\n * Helper for setting width/height\n * @private\n * @param {String} prop property (width|height)\n * @param {Number} value value to set property to\n * @return {fabric.Canvas} instance\n * @chainable true\n */\n _setBackstoreDimension: function (prop, value) {\n this.lowerCanvasEl[prop] = value;\n\n if (this.upperCanvasEl) {\n this.upperCanvasEl[prop] = value;\n }\n\n if (this.cacheCanvasEl) {\n this.cacheCanvasEl[prop] = value;\n }\n\n this[prop] = value;\n return this;\n },\n\n /**\n * Helper for setting css width/height\n * @private\n * @param {String} prop property (width|height)\n * @param {String} value value to set property to\n * @return {fabric.Canvas} instance\n * @chainable true\n */\n _setCssDimension: function (prop, value) {\n this.lowerCanvasEl.style[prop] = value;\n\n if (this.upperCanvasEl) {\n this.upperCanvasEl.style[prop] = value;\n }\n\n if (this.wrapperEl) {\n this.wrapperEl.style[prop] = value;\n }\n\n return this;\n },\n\n /**\n * Returns canvas zoom level\n * @return {Number}\n */\n getZoom: function () {\n return this.viewportTransform[0];\n },\n\n /**\n * Sets viewport transform of this canvas instance\n * @param {Array} vpt the transform in the form of context.transform\n * @return {fabric.Canvas} instance\n * @chainable true\n */\n setViewportTransform: function (vpt) {\n var activeObject = this._activeObject,\n object,\n i,\n len;\n this.viewportTransform = vpt;\n\n for (i = 0, len = this._objects.length; i < len; i++) {\n object = this._objects[i];\n object.group || object.setCoords(true);\n }\n\n if (activeObject) {\n activeObject.setCoords();\n }\n\n this.calcViewportBoundaries();\n this.renderOnAddRemove && this.requestRenderAll();\n return this;\n },\n\n /**\n * Sets zoom level of this canvas instance, zoom centered around point\n * @param {fabric.Point} point to zoom with respect to\n * @param {Number} value to set zoom to, less than 1 zooms out\n * @return {fabric.Canvas} instance\n * @chainable true\n */\n zoomToPoint: function (point, value) {\n // TODO: just change the scale, preserve other transformations\n var before = point,\n vpt = this.viewportTransform.slice(0);\n point = transformPoint(point, invertTransform(this.viewportTransform));\n vpt[0] = value;\n vpt[3] = value;\n var after = transformPoint(point, vpt);\n vpt[4] += before.x - after.x;\n vpt[5] += before.y - after.y;\n return this.setViewportTransform(vpt);\n },\n\n /**\n * Sets zoom level of this canvas instance\n * @param {Number} value to set zoom to, less than 1 zooms out\n * @return {fabric.Canvas} instance\n * @chainable true\n */\n setZoom: function (value) {\n this.zoomToPoint(new fabric.Point(0, 0), value);\n return this;\n },\n\n /**\n * Pan viewport so as to place point at top left corner of canvas\n * @param {fabric.Point} point to move to\n * @return {fabric.Canvas} instance\n * @chainable true\n */\n absolutePan: function (point) {\n var vpt = this.viewportTransform.slice(0);\n vpt[4] = -point.x;\n vpt[5] = -point.y;\n return this.setViewportTransform(vpt);\n },\n\n /**\n * Pans viewpoint relatively\n * @param {fabric.Point} point (position vector) to move by\n * @return {fabric.Canvas} instance\n * @chainable true\n */\n relativePan: function (point) {\n return this.absolutePan(new fabric.Point(-point.x - this.viewportTransform[4], -point.y - this.viewportTransform[5]));\n },\n\n /**\n * Returns <canvas> element corresponding to this instance\n * @return {HTMLCanvasElement}\n */\n getElement: function () {\n return this.lowerCanvasEl;\n },\n\n /**\n * @private\n * @param {fabric.Object} obj Object that was added\n */\n _onObjectAdded: function (obj) {\n this.stateful && obj.setupState();\n\n obj._set('canvas', this);\n\n obj.setCoords();\n this.fire('object:added', {\n target: obj\n });\n obj.fire('added');\n },\n\n /**\n * @private\n * @param {fabric.Object} obj Object that was removed\n */\n _onObjectRemoved: function (obj) {\n this.fire('object:removed', {\n target: obj\n });\n obj.fire('removed');\n delete obj.canvas;\n },\n\n /**\n * Clears specified context of canvas element\n * @param {CanvasRenderingContext2D} ctx Context to clear\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n clearContext: function (ctx) {\n ctx.clearRect(0, 0, this.width, this.height);\n return this;\n },\n\n /**\n * Returns context of canvas where objects are drawn\n * @return {CanvasRenderingContext2D}\n */\n getContext: function () {\n return this.contextContainer;\n },\n\n /**\n * Clears all contexts (background, main, top) of an instance\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n clear: function () {\n this._objects.length = 0;\n this.backgroundImage = null;\n this.overlayImage = null;\n this.backgroundColor = '';\n this.overlayColor = '';\n\n if (this._hasITextHandlers) {\n this.off('mouse:up', this._mouseUpITextHandler);\n this._iTextInstances = null;\n this._hasITextHandlers = false;\n }\n\n this.clearContext(this.contextContainer);\n this.fire('canvas:cleared');\n this.renderOnAddRemove && this.requestRenderAll();\n return this;\n },\n\n /**\n * Renders the canvas\n * @return {fabric.Canvas} instance\n * @chainable\n */\n renderAll: function () {\n var canvasToDrawOn = this.contextContainer;\n this.renderCanvas(canvasToDrawOn, this._objects);\n return this;\n },\n\n /**\n * Function created to be instance bound at initialization\n * used in requestAnimationFrame rendering\n * Let the fabricJS call it. If you call it manually you could have more\n * animationFrame stacking on to of each other\n * for an imperative rendering, use canvas.renderAll\n * @private\n * @return {fabric.Canvas} instance\n * @chainable\n */\n renderAndReset: function () {\n this.isRendering = 0;\n this.renderAll();\n },\n\n /**\n * Append a renderAll request to next animation frame.\n * unless one is already in progress, in that case nothing is done\n * a boolean flag will avoid appending more.\n * @return {fabric.Canvas} instance\n * @chainable\n */\n requestRenderAll: function () {\n if (!this.isRendering) {\n this.isRendering = fabric.util.requestAnimFrame(this.renderAndResetBound);\n }\n\n return this;\n },\n\n /**\n * Calculate the position of the 4 corner of canvas with current viewportTransform.\n * helps to determinate when an object is in the current rendering viewport using\n * object absolute coordinates ( aCoords )\n * @return {Object} points.tl\n * @chainable\n */\n calcViewportBoundaries: function () {\n var points = {},\n width = this.width,\n height = this.height,\n iVpt = invertTransform(this.viewportTransform);\n points.tl = transformPoint({\n x: 0,\n y: 0\n }, iVpt);\n points.br = transformPoint({\n x: width,\n y: height\n }, iVpt);\n points.tr = new fabric.Point(points.br.x, points.tl.y);\n points.bl = new fabric.Point(points.tl.x, points.br.y);\n this.vptCoords = points;\n return points;\n },\n cancelRequestedRender: function () {\n if (this.isRendering) {\n fabric.util.cancelAnimFrame(this.isRendering);\n this.isRendering = 0;\n }\n },\n\n /**\n * Renders background, objects, overlay and controls.\n * @param {CanvasRenderingContext2D} ctx\n * @param {Array} objects to render\n * @return {fabric.Canvas} instance\n * @chainable\n */\n renderCanvas: function (ctx, objects) {\n var v = this.viewportTransform,\n path = this.clipPath;\n this.cancelRequestedRender();\n this.calcViewportBoundaries();\n this.clearContext(ctx);\n fabric.util.setImageSmoothing(ctx, this.imageSmoothingEnabled);\n this.fire('before:render', {\n ctx: ctx\n });\n\n this._renderBackground(ctx);\n\n ctx.save(); //apply viewport transform once for all rendering process\n\n ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]);\n\n this._renderObjects(ctx, objects);\n\n ctx.restore();\n\n if (!this.controlsAboveOverlay && this.interactive) {\n this.drawControls(ctx);\n }\n\n if (path) {\n path.canvas = this; // needed to setup a couple of variables\n\n path.shouldCache();\n path._transformDone = true;\n path.renderCache({\n forClipping: true\n });\n this.drawClipPathOnCanvas(ctx);\n }\n\n this._renderOverlay(ctx);\n\n if (this.controlsAboveOverlay && this.interactive) {\n this.drawControls(ctx);\n }\n\n this.fire('after:render', {\n ctx: ctx\n });\n },\n\n /**\n * Paint the cached clipPath on the lowerCanvasEl\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n drawClipPathOnCanvas: function (ctx) {\n var v = this.viewportTransform,\n path = this.clipPath;\n ctx.save();\n ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]); // DEBUG: uncomment this line, comment the following\n // ctx.globalAlpha = 0.4;\n\n ctx.globalCompositeOperation = 'destination-in';\n path.transform(ctx);\n ctx.scale(1 / path.zoomX, 1 / path.zoomY);\n ctx.drawImage(path._cacheCanvas, -path.cacheTranslationX, -path.cacheTranslationY);\n ctx.restore();\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Array} objects to render\n */\n _renderObjects: function (ctx, objects) {\n var i, len;\n\n for (i = 0, len = objects.length; i < len; ++i) {\n objects[i] && objects[i].render(ctx);\n }\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {string} property 'background' or 'overlay'\n */\n _renderBackgroundOrOverlay: function (ctx, property) {\n var fill = this[property + 'Color'],\n object = this[property + 'Image'],\n v = this.viewportTransform,\n needsVpt = this[property + 'Vpt'];\n\n if (!fill && !object) {\n return;\n }\n\n if (fill) {\n ctx.save();\n ctx.beginPath();\n ctx.moveTo(0, 0);\n ctx.lineTo(this.width, 0);\n ctx.lineTo(this.width, this.height);\n ctx.lineTo(0, this.height);\n ctx.closePath();\n ctx.fillStyle = fill.toLive ? fill.toLive(ctx, this) : fill;\n\n if (needsVpt) {\n ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]);\n }\n\n ctx.transform(1, 0, 0, 1, fill.offsetX || 0, fill.offsetY || 0);\n var m = fill.gradientTransform || fill.patternTransform;\n m && ctx.transform(m[0], m[1], m[2], m[3], m[4], m[5]);\n ctx.fill();\n ctx.restore();\n }\n\n if (object) {\n ctx.save();\n\n if (needsVpt) {\n ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]);\n }\n\n object.render(ctx);\n ctx.restore();\n }\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderBackground: function (ctx) {\n this._renderBackgroundOrOverlay(ctx, 'background');\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderOverlay: function (ctx) {\n this._renderBackgroundOrOverlay(ctx, 'overlay');\n },\n\n /**\n * Returns coordinates of a center of canvas.\n * Returned value is an object with top and left properties\n * @return {Object} object with \"top\" and \"left\" number values\n */\n getCenter: function () {\n return {\n top: this.height / 2,\n left: this.width / 2\n };\n },\n\n /**\n * Centers object horizontally in the canvas\n * @param {fabric.Object} object Object to center horizontally\n * @return {fabric.Canvas} thisArg\n */\n centerObjectH: function (object) {\n return this._centerObject(object, new fabric.Point(this.getCenter().left, object.getCenterPoint().y));\n },\n\n /**\n * Centers object vertically in the canvas\n * @param {fabric.Object} object Object to center vertically\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n centerObjectV: function (object) {\n return this._centerObject(object, new fabric.Point(object.getCenterPoint().x, this.getCenter().top));\n },\n\n /**\n * Centers object vertically and horizontally in the canvas\n * @param {fabric.Object} object Object to center vertically and horizontally\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n centerObject: function (object) {\n var center = this.getCenter();\n return this._centerObject(object, new fabric.Point(center.left, center.top));\n },\n\n /**\n * Centers object vertically and horizontally in the viewport\n * @param {fabric.Object} object Object to center vertically and horizontally\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n viewportCenterObject: function (object) {\n var vpCenter = this.getVpCenter();\n return this._centerObject(object, vpCenter);\n },\n\n /**\n * Centers object horizontally in the viewport, object.top is unchanged\n * @param {fabric.Object} object Object to center vertically and horizontally\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n viewportCenterObjectH: function (object) {\n var vpCenter = this.getVpCenter();\n\n this._centerObject(object, new fabric.Point(vpCenter.x, object.getCenterPoint().y));\n\n return this;\n },\n\n /**\n * Centers object Vertically in the viewport, object.top is unchanged\n * @param {fabric.Object} object Object to center vertically and horizontally\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n viewportCenterObjectV: function (object) {\n var vpCenter = this.getVpCenter();\n return this._centerObject(object, new fabric.Point(object.getCenterPoint().x, vpCenter.y));\n },\n\n /**\n * Calculate the point in canvas that correspond to the center of actual viewport.\n * @return {fabric.Point} vpCenter, viewport center\n * @chainable\n */\n getVpCenter: function () {\n var center = this.getCenter(),\n iVpt = invertTransform(this.viewportTransform);\n return transformPoint({\n x: center.left,\n y: center.top\n }, iVpt);\n },\n\n /**\n * @private\n * @param {fabric.Object} object Object to center\n * @param {fabric.Point} center Center point\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n _centerObject: function (object, center) {\n object.setPositionByOrigin(center, 'center', 'center');\n object.setCoords();\n this.renderOnAddRemove && this.requestRenderAll();\n return this;\n },\n\n /**\n * Returs dataless JSON representation of canvas\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {String} json string\n */\n toDatalessJSON: function (propertiesToInclude) {\n return this.toDatalessObject(propertiesToInclude);\n },\n\n /**\n * Returns object representation of canvas\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject: function (propertiesToInclude) {\n return this._toObjectMethod('toObject', propertiesToInclude);\n },\n\n /**\n * Returns dataless object representation of canvas\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toDatalessObject: function (propertiesToInclude) {\n return this._toObjectMethod('toDatalessObject', propertiesToInclude);\n },\n\n /**\n * @private\n */\n _toObjectMethod: function (methodName, propertiesToInclude) {\n var clipPath = this.clipPath,\n data = {\n version: fabric.version,\n objects: this._toObjects(methodName, propertiesToInclude)\n };\n\n if (clipPath) {\n data.clipPath = this._toObject(this.clipPath, methodName, propertiesToInclude);\n }\n\n extend(data, this.__serializeBgOverlay(methodName, propertiesToInclude));\n fabric.util.populateWithProperties(this, data, propertiesToInclude);\n return data;\n },\n\n /**\n * @private\n */\n _toObjects: function (methodName, propertiesToInclude) {\n return this._objects.filter(function (object) {\n return !object.excludeFromExport;\n }).map(function (instance) {\n return this._toObject(instance, methodName, propertiesToInclude);\n }, this);\n },\n\n /**\n * @private\n */\n _toObject: function (instance, methodName, propertiesToInclude) {\n var originalValue;\n\n if (!this.includeDefaultValues) {\n originalValue = instance.includeDefaultValues;\n instance.includeDefaultValues = false;\n }\n\n var object = instance[methodName](propertiesToInclude);\n\n if (!this.includeDefaultValues) {\n instance.includeDefaultValues = originalValue;\n }\n\n return object;\n },\n\n /**\n * @private\n */\n __serializeBgOverlay: function (methodName, propertiesToInclude) {\n var data = {},\n bgImage = this.backgroundImage,\n overlay = this.overlayImage;\n\n if (this.backgroundColor) {\n data.background = this.backgroundColor.toObject ? this.backgroundColor.toObject(propertiesToInclude) : this.backgroundColor;\n }\n\n if (this.overlayColor) {\n data.overlay = this.overlayColor.toObject ? this.overlayColor.toObject(propertiesToInclude) : this.overlayColor;\n }\n\n if (bgImage && !bgImage.excludeFromExport) {\n data.backgroundImage = this._toObject(bgImage, methodName, propertiesToInclude);\n }\n\n if (overlay && !overlay.excludeFromExport) {\n data.overlayImage = this._toObject(overlay, methodName, propertiesToInclude);\n }\n\n return data;\n },\n\n /* _TO_SVG_START_ */\n\n /**\n * When true, getSvgTransform() will apply the StaticCanvas.viewportTransform to the SVG transformation. When true,\n * a zoomed canvas will then produce zoomed SVG output.\n * @type Boolean\n * @default\n */\n svgViewportTransformation: true,\n\n /**\n * Returns SVG representation of canvas\n * @function\n * @param {Object} [options] Options object for SVG output\n * @param {Boolean} [options.suppressPreamble=false] If true xml tag is not included\n * @param {Object} [options.viewBox] SVG viewbox object\n * @param {Number} [options.viewBox.x] x-cooridnate of viewbox\n * @param {Number} [options.viewBox.y] y-coordinate of viewbox\n * @param {Number} [options.viewBox.width] Width of viewbox\n * @param {Number} [options.viewBox.height] Height of viewbox\n * @param {String} [options.encoding=UTF-8] Encoding of SVG output\n * @param {String} [options.width] desired width of svg with or without units\n * @param {String} [options.height] desired height of svg with or without units\n * @param {Function} [reviver] Method for further parsing of svg elements, called after each fabric object converted into svg representation.\n * @return {String} SVG string\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#serialization}\n * @see {@link http://jsfiddle.net/fabricjs/jQ3ZZ/|jsFiddle demo}\n * @example <caption>Normal SVG output</caption>\n * var svg = canvas.toSVG();\n * @example <caption>SVG output without preamble (without <?xml ../>)</caption>\n * var svg = canvas.toSVG({suppressPreamble: true});\n * @example <caption>SVG output with viewBox attribute</caption>\n * var svg = canvas.toSVG({\n * viewBox: {\n * x: 100,\n * y: 100,\n * width: 200,\n * height: 300\n * }\n * });\n * @example <caption>SVG output with different encoding (default: UTF-8)</caption>\n * var svg = canvas.toSVG({encoding: 'ISO-8859-1'});\n * @example <caption>Modify SVG output with reviver function</caption>\n * var svg = canvas.toSVG(null, function(svg) {\n * return svg.replace('stroke-dasharray: ; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; ', '');\n * });\n */\n toSVG: function (options, reviver) {\n options || (options = {});\n options.reviver = reviver;\n var markup = [];\n\n this._setSVGPreamble(markup, options);\n\n this._setSVGHeader(markup, options);\n\n if (this.clipPath) {\n markup.push('<g clip-path=\"url(#' + this.clipPath.clipPathId + ')\" >\\n');\n }\n\n this._setSVGBgOverlayColor(markup, 'background');\n\n this._setSVGBgOverlayImage(markup, 'backgroundImage', reviver);\n\n this._setSVGObjects(markup, reviver);\n\n if (this.clipPath) {\n markup.push('</g>\\n');\n }\n\n this._setSVGBgOverlayColor(markup, 'overlay');\n\n this._setSVGBgOverlayImage(markup, 'overlayImage', reviver);\n\n markup.push('</svg>');\n return markup.join('');\n },\n\n /**\n * @private\n */\n _setSVGPreamble: function (markup, options) {\n if (options.suppressPreamble) {\n return;\n }\n\n markup.push('<?xml version=\"1.0\" encoding=\"', options.encoding || 'UTF-8', '\" standalone=\"no\" ?>\\n', '<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" ', '\"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\\n');\n },\n\n /**\n * @private\n */\n _setSVGHeader: function (markup, options) {\n var width = options.width || this.width,\n height = options.height || this.height,\n vpt,\n viewBox = 'viewBox=\"0 0 ' + this.width + ' ' + this.height + '\" ',\n NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS;\n\n if (options.viewBox) {\n viewBox = 'viewBox=\"' + options.viewBox.x + ' ' + options.viewBox.y + ' ' + options.viewBox.width + ' ' + options.viewBox.height + '\" ';\n } else {\n if (this.svgViewportTransformation) {\n vpt = this.viewportTransform;\n viewBox = 'viewBox=\"' + toFixed(-vpt[4] / vpt[0], NUM_FRACTION_DIGITS) + ' ' + toFixed(-vpt[5] / vpt[3], NUM_FRACTION_DIGITS) + ' ' + toFixed(this.width / vpt[0], NUM_FRACTION_DIGITS) + ' ' + toFixed(this.height / vpt[3], NUM_FRACTION_DIGITS) + '\" ';\n }\n }\n\n markup.push('<svg ', 'xmlns=\"http://www.w3.org/2000/svg\" ', 'xmlns:xlink=\"http://www.w3.org/1999/xlink\" ', 'version=\"1.1\" ', 'width=\"', width, '\" ', 'height=\"', height, '\" ', viewBox, 'xml:space=\"preserve\">\\n', '<desc>Created with Fabric.js ', fabric.version, '</desc>\\n', '<defs>\\n', this.createSVGFontFacesMarkup(), this.createSVGRefElementsMarkup(), this.createSVGClipPathMarkup(options), '</defs>\\n');\n },\n createSVGClipPathMarkup: function (options) {\n var clipPath = this.clipPath;\n\n if (clipPath) {\n clipPath.clipPathId = 'CLIPPATH_' + fabric.Object.__uid++;\n return '<clipPath id=\"' + clipPath.clipPathId + '\" >\\n' + this.clipPath.toClipPathSVG(options.reviver) + '</clipPath>\\n';\n }\n\n return '';\n },\n\n /**\n * Creates markup containing SVG referenced elements like patterns, gradients etc.\n * @return {String}\n */\n createSVGRefElementsMarkup: function () {\n var _this = this,\n markup = ['background', 'overlay'].map(function (prop) {\n var fill = _this[prop + 'Color'];\n\n if (fill && fill.toLive) {\n var shouldTransform = _this[prop + 'Vpt'],\n vpt = _this.viewportTransform,\n object = {\n width: _this.width / (shouldTransform ? vpt[0] : 1),\n height: _this.height / (shouldTransform ? vpt[3] : 1)\n };\n return fill.toSVG(object, {\n additionalTransform: shouldTransform ? fabric.util.matrixToSVG(vpt) : ''\n });\n }\n });\n\n return markup.join('');\n },\n\n /**\n * Creates markup containing SVG font faces,\n * font URLs for font faces must be collected by developers\n * and are not extracted from the DOM by fabricjs\n * @param {Array} objects Array of fabric objects\n * @return {String}\n */\n createSVGFontFacesMarkup: function () {\n var markup = '',\n fontList = {},\n obj,\n fontFamily,\n style,\n row,\n rowIndex,\n _char,\n charIndex,\n i,\n len,\n fontPaths = fabric.fontPaths,\n objects = [];\n\n this._objects.forEach(function add(object) {\n objects.push(object);\n\n if (object._objects) {\n object._objects.forEach(add);\n }\n });\n\n for (i = 0, len = objects.length; i < len; i++) {\n obj = objects[i];\n fontFamily = obj.fontFamily;\n\n if (obj.type.indexOf('text') === -1 || fontList[fontFamily] || !fontPaths[fontFamily]) {\n continue;\n }\n\n fontList[fontFamily] = true;\n\n if (!obj.styles) {\n continue;\n }\n\n style = obj.styles;\n\n for (rowIndex in style) {\n row = style[rowIndex];\n\n for (charIndex in row) {\n _char = row[charIndex];\n fontFamily = _char.fontFamily;\n\n if (!fontList[fontFamily] && fontPaths[fontFamily]) {\n fontList[fontFamily] = true;\n }\n }\n }\n }\n\n for (var j in fontList) {\n markup += ['\\t\\t@font-face {\\n', '\\t\\t\\tfont-family: \\'', j, '\\';\\n', '\\t\\t\\tsrc: url(\\'', fontPaths[j], '\\');\\n', '\\t\\t}\\n'].join('');\n }\n\n if (markup) {\n markup = ['\\t<style type=\"text/css\">', '<![CDATA[\\n', markup, ']]>', '</style>\\n'].join('');\n }\n\n return markup;\n },\n\n /**\n * @private\n */\n _setSVGObjects: function (markup, reviver) {\n var instance,\n i,\n len,\n objects = this._objects;\n\n for (i = 0, len = objects.length; i < len; i++) {\n instance = objects[i];\n\n if (instance.excludeFromExport) {\n continue;\n }\n\n this._setSVGObject(markup, instance, reviver);\n }\n },\n\n /**\n * @private\n */\n _setSVGObject: function (markup, instance, reviver) {\n markup.push(instance.toSVG(reviver));\n },\n\n /**\n * @private\n */\n _setSVGBgOverlayImage: function (markup, property, reviver) {\n if (this[property] && !this[property].excludeFromExport && this[property].toSVG) {\n markup.push(this[property].toSVG(reviver));\n }\n },\n\n /**\n * @private\n */\n _setSVGBgOverlayColor: function (markup, property) {\n var filler = this[property + 'Color'],\n vpt = this.viewportTransform,\n finalWidth = this.width,\n finalHeight = this.height;\n\n if (!filler) {\n return;\n }\n\n if (filler.toLive) {\n var repeat = filler.repeat,\n iVpt = fabric.util.invertTransform(vpt),\n shouldInvert = this[property + 'Vpt'],\n additionalTransform = shouldInvert ? fabric.util.matrixToSVG(iVpt) : '';\n markup.push('<rect transform=\"' + additionalTransform + ' translate(', finalWidth / 2, ',', finalHeight / 2, ')\"', ' x=\"', filler.offsetX - finalWidth / 2, '\" y=\"', filler.offsetY - finalHeight / 2, '\" ', 'width=\"', repeat === 'repeat-y' || repeat === 'no-repeat' ? filler.source.width : finalWidth, '\" height=\"', repeat === 'repeat-x' || repeat === 'no-repeat' ? filler.source.height : finalHeight, '\" fill=\"url(#SVGID_' + filler.id + ')\"', '></rect>\\n');\n } else {\n markup.push('<rect x=\"0\" y=\"0\" width=\"100%\" height=\"100%\" ', 'fill=\"', filler, '\"', '></rect>\\n');\n }\n },\n\n /* _TO_SVG_END_ */\n\n /**\n * Moves an object or the objects of a multiple selection\n * to the bottom of the stack of drawn objects\n * @param {fabric.Object} object Object to send to back\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n sendToBack: function (object) {\n if (!object) {\n return this;\n }\n\n var activeSelection = this._activeObject,\n i,\n obj,\n objs;\n\n if (object === activeSelection && object.type === 'activeSelection') {\n objs = activeSelection._objects;\n\n for (i = objs.length; i--;) {\n obj = objs[i];\n removeFromArray(this._objects, obj);\n\n this._objects.unshift(obj);\n }\n } else {\n removeFromArray(this._objects, object);\n\n this._objects.unshift(object);\n }\n\n this.renderOnAddRemove && this.requestRenderAll();\n return this;\n },\n\n /**\n * Moves an object or the objects of a multiple selection\n * to the top of the stack of drawn objects\n * @param {fabric.Object} object Object to send\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n bringToFront: function (object) {\n if (!object) {\n return this;\n }\n\n var activeSelection = this._activeObject,\n i,\n obj,\n objs;\n\n if (object === activeSelection && object.type === 'activeSelection') {\n objs = activeSelection._objects;\n\n for (i = 0; i < objs.length; i++) {\n obj = objs[i];\n removeFromArray(this._objects, obj);\n\n this._objects.push(obj);\n }\n } else {\n removeFromArray(this._objects, object);\n\n this._objects.push(object);\n }\n\n this.renderOnAddRemove && this.requestRenderAll();\n return this;\n },\n\n /**\n * Moves an object or a selection down in stack of drawn objects\n * An optional paramter, intersecting allowes to move the object in behind\n * the first intersecting object. Where intersection is calculated with\n * bounding box. If no intersection is found, there will not be change in the\n * stack.\n * @param {fabric.Object} object Object to send\n * @param {Boolean} [intersecting] If `true`, send object behind next lower intersecting object\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n sendBackwards: function (object, intersecting) {\n if (!object) {\n return this;\n }\n\n var activeSelection = this._activeObject,\n i,\n obj,\n idx,\n newIdx,\n objs,\n objsMoved = 0;\n\n if (object === activeSelection && object.type === 'activeSelection') {\n objs = activeSelection._objects;\n\n for (i = 0; i < objs.length; i++) {\n obj = objs[i];\n idx = this._objects.indexOf(obj);\n\n if (idx > 0 + objsMoved) {\n newIdx = idx - 1;\n removeFromArray(this._objects, obj);\n\n this._objects.splice(newIdx, 0, obj);\n }\n\n objsMoved++;\n }\n } else {\n idx = this._objects.indexOf(object);\n\n if (idx !== 0) {\n // if object is not on the bottom of stack\n newIdx = this._findNewLowerIndex(object, idx, intersecting);\n removeFromArray(this._objects, object);\n\n this._objects.splice(newIdx, 0, object);\n }\n }\n\n this.renderOnAddRemove && this.requestRenderAll();\n return this;\n },\n\n /**\n * @private\n */\n _findNewLowerIndex: function (object, idx, intersecting) {\n var newIdx, i;\n\n if (intersecting) {\n newIdx = idx; // traverse down the stack looking for the nearest intersecting object\n\n for (i = idx - 1; i >= 0; --i) {\n var isIntersecting = object.intersectsWithObject(this._objects[i]) || object.isContainedWithinObject(this._objects[i]) || this._objects[i].isContainedWithinObject(object);\n\n if (isIntersecting) {\n newIdx = i;\n break;\n }\n }\n } else {\n newIdx = idx - 1;\n }\n\n return newIdx;\n },\n\n /**\n * Moves an object or a selection up in stack of drawn objects\n * An optional paramter, intersecting allowes to move the object in front\n * of the first intersecting object. Where intersection is calculated with\n * bounding box. If no intersection is found, there will not be change in the\n * stack.\n * @param {fabric.Object} object Object to send\n * @param {Boolean} [intersecting] If `true`, send object in front of next upper intersecting object\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n bringForward: function (object, intersecting) {\n if (!object) {\n return this;\n }\n\n var activeSelection = this._activeObject,\n i,\n obj,\n idx,\n newIdx,\n objs,\n objsMoved = 0;\n\n if (object === activeSelection && object.type === 'activeSelection') {\n objs = activeSelection._objects;\n\n for (i = objs.length; i--;) {\n obj = objs[i];\n idx = this._objects.indexOf(obj);\n\n if (idx < this._objects.length - 1 - objsMoved) {\n newIdx = idx + 1;\n removeFromArray(this._objects, obj);\n\n this._objects.splice(newIdx, 0, obj);\n }\n\n objsMoved++;\n }\n } else {\n idx = this._objects.indexOf(object);\n\n if (idx !== this._objects.length - 1) {\n // if object is not on top of stack (last item in an array)\n newIdx = this._findNewUpperIndex(object, idx, intersecting);\n removeFromArray(this._objects, object);\n\n this._objects.splice(newIdx, 0, object);\n }\n }\n\n this.renderOnAddRemove && this.requestRenderAll();\n return this;\n },\n\n /**\n * @private\n */\n _findNewUpperIndex: function (object, idx, intersecting) {\n var newIdx, i, len;\n\n if (intersecting) {\n newIdx = idx; // traverse up the stack looking for the nearest intersecting object\n\n for (i = idx + 1, len = this._objects.length; i < len; ++i) {\n var isIntersecting = object.intersectsWithObject(this._objects[i]) || object.isContainedWithinObject(this._objects[i]) || this._objects[i].isContainedWithinObject(object);\n\n if (isIntersecting) {\n newIdx = i;\n break;\n }\n }\n } else {\n newIdx = idx + 1;\n }\n\n return newIdx;\n },\n\n /**\n * Moves an object to specified level in stack of drawn objects\n * @param {fabric.Object} object Object to send\n * @param {Number} index Position to move to\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n moveTo: function (object, index) {\n removeFromArray(this._objects, object);\n\n this._objects.splice(index, 0, object);\n\n return this.renderOnAddRemove && this.requestRenderAll();\n },\n\n /**\n * Clears a canvas element and dispose objects\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n dispose: function () {\n // cancel eventually ongoing renders\n if (this.isRendering) {\n fabric.util.cancelAnimFrame(this.isRendering);\n this.isRendering = 0;\n }\n\n this.forEachObject(function (object) {\n object.dispose && object.dispose();\n });\n this._objects = [];\n\n if (this.backgroundImage && this.backgroundImage.dispose) {\n this.backgroundImage.dispose();\n }\n\n this.backgroundImage = null;\n\n if (this.overlayImage && this.overlayImage.dispose) {\n this.overlayImage.dispose();\n }\n\n this.overlayImage = null;\n this._iTextInstances = null;\n this.contextContainer = null;\n fabric.util.cleanUpJsdomNode(this.lowerCanvasEl);\n this.lowerCanvasEl = undefined;\n return this;\n },\n\n /**\n * Returns a string representation of an instance\n * @return {String} string representation of an instance\n */\n toString: function () {\n return '#<fabric.Canvas (' + this.complexity() + '): ' + '{ objects: ' + this._objects.length + ' }>';\n }\n });\n extend(fabric.StaticCanvas.prototype, fabric.Observable);\n extend(fabric.StaticCanvas.prototype, fabric.Collection);\n extend(fabric.StaticCanvas.prototype, fabric.DataURLExporter);\n extend(fabric.StaticCanvas,\n /** @lends fabric.StaticCanvas */\n {\n /**\n * @static\n * @type String\n * @default\n */\n EMPTY_JSON: '{\"objects\": [], \"background\": \"white\"}',\n\n /**\n * Provides a way to check support of some of the canvas methods\n * (either those of HTMLCanvasElement itself, or rendering context)\n *\n * @param {String} methodName Method to check support for;\n * Could be one of \"setLineDash\"\n * @return {Boolean | null} `true` if method is supported (or at least exists),\n * `null` if canvas element or context can not be initialized\n */\n supports: function (methodName) {\n var el = createCanvasElement();\n\n if (!el || !el.getContext) {\n return null;\n }\n\n var ctx = el.getContext('2d');\n\n if (!ctx) {\n return null;\n }\n\n switch (methodName) {\n case 'setLineDash':\n return typeof ctx.setLineDash !== 'undefined';\n\n default:\n return null;\n }\n }\n });\n /**\n * Returns JSON representation of canvas\n * @function\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {String} JSON string\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#serialization}\n * @see {@link http://jsfiddle.net/fabricjs/pec86/|jsFiddle demo}\n * @example <caption>JSON without additional properties</caption>\n * var json = canvas.toJSON();\n * @example <caption>JSON with additional properties included</caption>\n * var json = canvas.toJSON(['lockMovementX', 'lockMovementY', 'lockRotation', 'lockScalingX', 'lockScalingY']);\n * @example <caption>JSON without default values</caption>\n * canvas.includeDefaultValues = false;\n * var json = canvas.toJSON();\n */\n\n fabric.StaticCanvas.prototype.toJSON = fabric.StaticCanvas.prototype.toObject;\n\n if (fabric.isLikelyNode) {\n fabric.StaticCanvas.prototype.createPNGStream = function () {\n var impl = getNodeCanvas(this.lowerCanvasEl);\n return impl && impl.createPNGStream();\n };\n\n fabric.StaticCanvas.prototype.createJPEGStream = function (opts) {\n var impl = getNodeCanvas(this.lowerCanvasEl);\n return impl && impl.createJPEGStream(opts);\n };\n }\n})();\n/**\n * BaseBrush class\n * @class fabric.BaseBrush\n * @see {@link http://fabricjs.com/freedrawing|Freedrawing demo}\n */\n\n\nfabric.BaseBrush = fabric.util.createClass(\n/** @lends fabric.BaseBrush.prototype */\n{\n /**\n * Color of a brush\n * @type String\n * @default\n */\n color: 'rgb(0, 0, 0)',\n\n /**\n * Width of a brush, has to be a Number, no string literals\n * @type Number\n * @default\n */\n width: 1,\n\n /**\n * Shadow object representing shadow of this shape.\n * <b>Backwards incompatibility note:</b> This property replaces \"shadowColor\" (String), \"shadowOffsetX\" (Number),\n * \"shadowOffsetY\" (Number) and \"shadowBlur\" (Number) since v1.2.12\n * @type fabric.Shadow\n * @default\n */\n shadow: null,\n\n /**\n * Line endings style of a brush (one of \"butt\", \"round\", \"square\")\n * @type String\n * @default\n */\n strokeLineCap: 'round',\n\n /**\n * Corner style of a brush (one of \"bevel\", \"round\", \"miter\")\n * @type String\n * @default\n */\n strokeLineJoin: 'round',\n\n /**\n * Maximum miter length (used for strokeLineJoin = \"miter\") of a brush's\n * @type Number\n * @default\n */\n strokeMiterLimit: 10,\n\n /**\n * Stroke Dash Array.\n * @type Array\n * @default\n */\n strokeDashArray: null,\n\n /**\n * Sets brush styles\n * @private\n */\n _setBrushStyles: function () {\n var ctx = this.canvas.contextTop;\n ctx.strokeStyle = this.color;\n ctx.lineWidth = this.width;\n ctx.lineCap = this.strokeLineCap;\n ctx.miterLimit = this.strokeMiterLimit;\n ctx.lineJoin = this.strokeLineJoin;\n\n if (fabric.StaticCanvas.supports('setLineDash')) {\n ctx.setLineDash(this.strokeDashArray || []);\n }\n },\n\n /**\n * Sets the transformation on given context\n * @param {RenderingContext2d} ctx context to render on\n * @private\n */\n _saveAndTransform: function (ctx) {\n var v = this.canvas.viewportTransform;\n ctx.save();\n ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]);\n },\n\n /**\n * Sets brush shadow styles\n * @private\n */\n _setShadow: function () {\n if (!this.shadow) {\n return;\n }\n\n var canvas = this.canvas,\n shadow = this.shadow,\n ctx = canvas.contextTop,\n zoom = canvas.getZoom();\n\n if (canvas && canvas._isRetinaScaling()) {\n zoom *= fabric.devicePixelRatio;\n }\n\n ctx.shadowColor = shadow.color;\n ctx.shadowBlur = shadow.blur * zoom;\n ctx.shadowOffsetX = shadow.offsetX * zoom;\n ctx.shadowOffsetY = shadow.offsetY * zoom;\n },\n needsFullRender: function () {\n var color = new fabric.Color(this.color);\n return color.getAlpha() < 1 || !!this.shadow;\n },\n\n /**\n * Removes brush shadow styles\n * @private\n */\n _resetShadow: function () {\n var ctx = this.canvas.contextTop;\n ctx.shadowColor = '';\n ctx.shadowBlur = ctx.shadowOffsetX = ctx.shadowOffsetY = 0;\n }\n});\n\n(function () {\n /**\n * PencilBrush class\n * @class fabric.PencilBrush\n * @extends fabric.BaseBrush\n */\n fabric.PencilBrush = fabric.util.createClass(fabric.BaseBrush,\n /** @lends fabric.PencilBrush.prototype */\n {\n /**\n * Discard points that are less than `decimate` pixel distant from each other\n * @type Number\n * @default 0.4\n */\n decimate: 0.4,\n\n /**\n * Constructor\n * @param {fabric.Canvas} canvas\n * @return {fabric.PencilBrush} Instance of a pencil brush\n */\n initialize: function (canvas) {\n this.canvas = canvas;\n this._points = [];\n },\n\n /**\n * Invoked inside on mouse down and mouse move\n * @param {Object} pointer\n */\n _drawSegment: function (ctx, p1, p2) {\n var midPoint = p1.midPointFrom(p2);\n ctx.quadraticCurveTo(p1.x, p1.y, midPoint.x, midPoint.y);\n return midPoint;\n },\n\n /**\n * Inovoked on mouse down\n * @param {Object} pointer\n */\n onMouseDown: function (pointer, options) {\n if (!this.canvas._isMainEvent(options.e)) {\n return;\n }\n\n this._prepareForDrawing(pointer); // capture coordinates immediately\n // this allows to draw dots (when movement never occurs)\n\n\n this._captureDrawingPath(pointer);\n\n this._render();\n },\n\n /**\n * Inovoked on mouse move\n * @param {Object} pointer\n */\n onMouseMove: function (pointer, options) {\n if (!this.canvas._isMainEvent(options.e)) {\n return;\n }\n\n if (this._captureDrawingPath(pointer) && this._points.length > 1) {\n if (this.needsFullRender()) {\n // redraw curve\n // clear top canvas\n this.canvas.clearContext(this.canvas.contextTop);\n\n this._render();\n } else {\n var points = this._points,\n length = points.length,\n ctx = this.canvas.contextTop; // draw the curve update\n\n this._saveAndTransform(ctx);\n\n if (this.oldEnd) {\n ctx.beginPath();\n ctx.moveTo(this.oldEnd.x, this.oldEnd.y);\n }\n\n this.oldEnd = this._drawSegment(ctx, points[length - 2], points[length - 1], true);\n ctx.stroke();\n ctx.restore();\n }\n }\n },\n\n /**\n * Invoked on mouse up\n */\n onMouseUp: function (options) {\n if (!this.canvas._isMainEvent(options.e)) {\n return true;\n }\n\n this.oldEnd = undefined;\n\n this._finalizeAndAddPath();\n\n return false;\n },\n\n /**\n * @private\n * @param {Object} pointer Actual mouse position related to the canvas.\n */\n _prepareForDrawing: function (pointer) {\n var p = new fabric.Point(pointer.x, pointer.y);\n\n this._reset();\n\n this._addPoint(p);\n\n this.canvas.contextTop.moveTo(p.x, p.y);\n },\n\n /**\n * @private\n * @param {fabric.Point} point Point to be added to points array\n */\n _addPoint: function (point) {\n if (this._points.length > 1 && point.eq(this._points[this._points.length - 1])) {\n return false;\n }\n\n this._points.push(point);\n\n return true;\n },\n\n /**\n * Clear points array and set contextTop canvas style.\n * @private\n */\n _reset: function () {\n this._points = [];\n\n this._setBrushStyles();\n\n this._setShadow();\n },\n\n /**\n * @private\n * @param {Object} pointer Actual mouse position related to the canvas.\n */\n _captureDrawingPath: function (pointer) {\n var pointerPoint = new fabric.Point(pointer.x, pointer.y);\n return this._addPoint(pointerPoint);\n },\n\n /**\n * Draw a smooth path on the topCanvas using quadraticCurveTo\n * @private\n */\n _render: function () {\n var ctx = this.canvas.contextTop,\n i,\n len,\n p1 = this._points[0],\n p2 = this._points[1];\n\n this._saveAndTransform(ctx);\n\n ctx.beginPath(); //if we only have 2 points in the path and they are the same\n //it means that the user only clicked the canvas without moving the mouse\n //then we should be drawing a dot. A path isn't drawn between two identical dots\n //that's why we set them apart a bit\n\n if (this._points.length === 2 && p1.x === p2.x && p1.y === p2.y) {\n var width = this.width / 1000;\n p1 = new fabric.Point(p1.x, p1.y);\n p2 = new fabric.Point(p2.x, p2.y);\n p1.x -= width;\n p2.x += width;\n }\n\n ctx.moveTo(p1.x, p1.y);\n\n for (i = 1, len = this._points.length; i < len; i++) {\n // we pick the point between pi + 1 & pi + 2 as the\n // end point and p1 as our control point.\n this._drawSegment(ctx, p1, p2);\n\n p1 = this._points[i];\n p2 = this._points[i + 1];\n } // Draw last line as a straight line while\n // we wait for the next point to be able to calculate\n // the bezier control point\n\n\n ctx.lineTo(p1.x, p1.y);\n ctx.stroke();\n ctx.restore();\n },\n\n /**\n * Converts points to SVG path\n * @param {Array} points Array of points\n * @return {String} SVG path\n */\n convertPointsToSVGPath: function (points) {\n var path = [],\n i,\n width = this.width / 1000,\n p1 = new fabric.Point(points[0].x, points[0].y),\n p2 = new fabric.Point(points[1].x, points[1].y),\n len = points.length,\n multSignX = 1,\n multSignY = 0,\n manyPoints = len > 2;\n\n if (manyPoints) {\n multSignX = points[2].x < p2.x ? -1 : points[2].x === p2.x ? 0 : 1;\n multSignY = points[2].y < p2.y ? -1 : points[2].y === p2.y ? 0 : 1;\n }\n\n path.push('M ', p1.x - multSignX * width, ' ', p1.y - multSignY * width, ' ');\n\n for (i = 1; i < len; i++) {\n if (!p1.eq(p2)) {\n var midPoint = p1.midPointFrom(p2); // p1 is our bezier control point\n // midpoint is our endpoint\n // start point is p(i-1) value.\n\n path.push('Q ', p1.x, ' ', p1.y, ' ', midPoint.x, ' ', midPoint.y, ' ');\n }\n\n p1 = points[i];\n\n if (i + 1 < points.length) {\n p2 = points[i + 1];\n }\n }\n\n if (manyPoints) {\n multSignX = p1.x > points[i - 2].x ? 1 : p1.x === points[i - 2].x ? 0 : -1;\n multSignY = p1.y > points[i - 2].y ? 1 : p1.y === points[i - 2].y ? 0 : -1;\n }\n\n path.push('L ', p1.x + multSignX * width, ' ', p1.y + multSignY * width);\n return path;\n },\n\n /**\n * Creates fabric.Path object to add on canvas\n * @param {String} pathData Path data\n * @return {fabric.Path} Path to add on canvas\n */\n createPath: function (pathData) {\n var path = new fabric.Path(pathData, {\n fill: null,\n stroke: this.color,\n strokeWidth: this.width,\n strokeLineCap: this.strokeLineCap,\n strokeMiterLimit: this.strokeMiterLimit,\n strokeLineJoin: this.strokeLineJoin,\n strokeDashArray: this.strokeDashArray\n });\n\n if (this.shadow) {\n this.shadow.affectStroke = true;\n path.shadow = new fabric.Shadow(this.shadow);\n }\n\n return path;\n },\n\n /**\n * Decimate poins array with the decimate value\n */\n decimatePoints: function (points, distance) {\n if (points.length <= 2) {\n return points;\n }\n\n var zoom = this.canvas.getZoom(),\n adjustedDistance = Math.pow(distance / zoom, 2),\n i,\n l = points.length - 1,\n lastPoint = points[0],\n newPoints = [lastPoint],\n cDistance;\n\n for (i = 1; i < l; i++) {\n cDistance = Math.pow(lastPoint.x - points[i].x, 2) + Math.pow(lastPoint.y - points[i].y, 2);\n\n if (cDistance >= adjustedDistance) {\n lastPoint = points[i];\n newPoints.push(lastPoint);\n }\n }\n\n if (newPoints.length === 1) {\n newPoints.push(new fabric.Point(newPoints[0].x, newPoints[0].y));\n }\n\n return newPoints;\n },\n\n /**\n * On mouseup after drawing the path on contextTop canvas\n * we use the points captured to create an new fabric path object\n * and add it to the fabric canvas.\n */\n _finalizeAndAddPath: function () {\n var ctx = this.canvas.contextTop;\n ctx.closePath();\n\n if (this.decimate) {\n this._points = this.decimatePoints(this._points, this.decimate);\n }\n\n var pathData = this.convertPointsToSVGPath(this._points).join('');\n\n if (pathData === 'M 0 0 Q 0 0 0 0 L 0 0') {\n // do not create 0 width/height paths, as they are\n // rendered inconsistently across browsers\n // Firefox 4, for example, renders a dot,\n // whereas Chrome 10 renders nothing\n this.canvas.requestRenderAll();\n return;\n }\n\n var path = this.createPath(pathData);\n this.canvas.clearContext(this.canvas.contextTop);\n this.canvas.fire('before:path:created', {\n path: path\n });\n this.canvas.add(path);\n this.canvas.requestRenderAll();\n path.setCoords();\n\n this._resetShadow(); // fire event 'path' created\n\n\n this.canvas.fire('path:created', {\n path: path\n });\n }\n });\n})();\n/**\n * CircleBrush class\n * @class fabric.CircleBrush\n */\n\n\nfabric.CircleBrush = fabric.util.createClass(fabric.BaseBrush,\n/** @lends fabric.CircleBrush.prototype */\n{\n /**\n * Width of a brush\n * @type Number\n * @default\n */\n width: 10,\n\n /**\n * Constructor\n * @param {fabric.Canvas} canvas\n * @return {fabric.CircleBrush} Instance of a circle brush\n */\n initialize: function (canvas) {\n this.canvas = canvas;\n this.points = [];\n },\n\n /**\n * Invoked inside on mouse down and mouse move\n * @param {Object} pointer\n */\n drawDot: function (pointer) {\n var point = this.addPoint(pointer),\n ctx = this.canvas.contextTop;\n\n this._saveAndTransform(ctx);\n\n this.dot(ctx, point);\n ctx.restore();\n },\n dot: function (ctx, point) {\n ctx.fillStyle = point.fill;\n ctx.beginPath();\n ctx.arc(point.x, point.y, point.radius, 0, Math.PI * 2, false);\n ctx.closePath();\n ctx.fill();\n },\n\n /**\n * Invoked on mouse down\n */\n onMouseDown: function (pointer) {\n this.points.length = 0;\n this.canvas.clearContext(this.canvas.contextTop);\n\n this._setShadow();\n\n this.drawDot(pointer);\n },\n\n /**\n * Render the full state of the brush\n * @private\n */\n _render: function () {\n var ctx = this.canvas.contextTop,\n i,\n len,\n points = this.points;\n\n this._saveAndTransform(ctx);\n\n for (i = 0, len = points.length; i < len; i++) {\n this.dot(ctx, points[i]);\n }\n\n ctx.restore();\n },\n\n /**\n * Invoked on mouse move\n * @param {Object} pointer\n */\n onMouseMove: function (pointer) {\n if (this.needsFullRender()) {\n this.canvas.clearContext(this.canvas.contextTop);\n this.addPoint(pointer);\n\n this._render();\n } else {\n this.drawDot(pointer);\n }\n },\n\n /**\n * Invoked on mouse up\n */\n onMouseUp: function () {\n var originalRenderOnAddRemove = this.canvas.renderOnAddRemove,\n i,\n len;\n this.canvas.renderOnAddRemove = false;\n var circles = [];\n\n for (i = 0, len = this.points.length; i < len; i++) {\n var point = this.points[i],\n circle = new fabric.Circle({\n radius: point.radius,\n left: point.x,\n top: point.y,\n originX: 'center',\n originY: 'center',\n fill: point.fill\n });\n this.shadow && (circle.shadow = new fabric.Shadow(this.shadow));\n circles.push(circle);\n }\n\n var group = new fabric.Group(circles);\n group.canvas = this.canvas;\n this.canvas.fire('before:path:created', {\n path: group\n });\n this.canvas.add(group);\n this.canvas.fire('path:created', {\n path: group\n });\n this.canvas.clearContext(this.canvas.contextTop);\n\n this._resetShadow();\n\n this.canvas.renderOnAddRemove = originalRenderOnAddRemove;\n this.canvas.requestRenderAll();\n },\n\n /**\n * @param {Object} pointer\n * @return {fabric.Point} Just added pointer point\n */\n addPoint: function (pointer) {\n var pointerPoint = new fabric.Point(pointer.x, pointer.y),\n circleRadius = fabric.util.getRandomInt(Math.max(0, this.width - 20), this.width + 20) / 2,\n circleColor = new fabric.Color(this.color).setAlpha(fabric.util.getRandomInt(0, 100) / 100).toRgba();\n pointerPoint.radius = circleRadius;\n pointerPoint.fill = circleColor;\n this.points.push(pointerPoint);\n return pointerPoint;\n }\n});\n/**\n * SprayBrush class\n * @class fabric.SprayBrush\n */\n\nfabric.SprayBrush = fabric.util.createClass(fabric.BaseBrush,\n/** @lends fabric.SprayBrush.prototype */\n{\n /**\n * Width of a spray\n * @type Number\n * @default\n */\n width: 10,\n\n /**\n * Density of a spray (number of dots per chunk)\n * @type Number\n * @default\n */\n density: 20,\n\n /**\n * Width of spray dots\n * @type Number\n * @default\n */\n dotWidth: 1,\n\n /**\n * Width variance of spray dots\n * @type Number\n * @default\n */\n dotWidthVariance: 1,\n\n /**\n * Whether opacity of a dot should be random\n * @type Boolean\n * @default\n */\n randomOpacity: false,\n\n /**\n * Whether overlapping dots (rectangles) should be removed (for performance reasons)\n * @type Boolean\n * @default\n */\n optimizeOverlapping: true,\n\n /**\n * Constructor\n * @param {fabric.Canvas} canvas\n * @return {fabric.SprayBrush} Instance of a spray brush\n */\n initialize: function (canvas) {\n this.canvas = canvas;\n this.sprayChunks = [];\n },\n\n /**\n * Invoked on mouse down\n * @param {Object} pointer\n */\n onMouseDown: function (pointer) {\n this.sprayChunks.length = 0;\n this.canvas.clearContext(this.canvas.contextTop);\n\n this._setShadow();\n\n this.addSprayChunk(pointer);\n this.render(this.sprayChunkPoints);\n },\n\n /**\n * Invoked on mouse move\n * @param {Object} pointer\n */\n onMouseMove: function (pointer) {\n this.addSprayChunk(pointer);\n this.render(this.sprayChunkPoints);\n },\n\n /**\n * Invoked on mouse up\n */\n onMouseUp: function () {\n var originalRenderOnAddRemove = this.canvas.renderOnAddRemove;\n this.canvas.renderOnAddRemove = false;\n var rects = [];\n\n for (var i = 0, ilen = this.sprayChunks.length; i < ilen; i++) {\n var sprayChunk = this.sprayChunks[i];\n\n for (var j = 0, jlen = sprayChunk.length; j < jlen; j++) {\n var rect = new fabric.Rect({\n width: sprayChunk[j].width,\n height: sprayChunk[j].width,\n left: sprayChunk[j].x + 1,\n top: sprayChunk[j].y + 1,\n originX: 'center',\n originY: 'center',\n fill: this.color\n });\n rects.push(rect);\n }\n }\n\n if (this.optimizeOverlapping) {\n rects = this._getOptimizedRects(rects);\n }\n\n var group = new fabric.Group(rects);\n this.shadow && group.set('shadow', new fabric.Shadow(this.shadow));\n this.canvas.fire('before:path:created', {\n path: group\n });\n this.canvas.add(group);\n this.canvas.fire('path:created', {\n path: group\n });\n this.canvas.clearContext(this.canvas.contextTop);\n\n this._resetShadow();\n\n this.canvas.renderOnAddRemove = originalRenderOnAddRemove;\n this.canvas.requestRenderAll();\n },\n\n /**\n * @private\n * @param {Array} rects\n */\n _getOptimizedRects: function (rects) {\n // avoid creating duplicate rects at the same coordinates\n var uniqueRects = {},\n key,\n i,\n len;\n\n for (i = 0, len = rects.length; i < len; i++) {\n key = rects[i].left + '' + rects[i].top;\n\n if (!uniqueRects[key]) {\n uniqueRects[key] = rects[i];\n }\n }\n\n var uniqueRectsArray = [];\n\n for (key in uniqueRects) {\n uniqueRectsArray.push(uniqueRects[key]);\n }\n\n return uniqueRectsArray;\n },\n\n /**\n * Render new chunk of spray brush\n */\n render: function (sprayChunk) {\n var ctx = this.canvas.contextTop,\n i,\n len;\n ctx.fillStyle = this.color;\n\n this._saveAndTransform(ctx);\n\n for (i = 0, len = sprayChunk.length; i < len; i++) {\n var point = sprayChunk[i];\n\n if (typeof point.opacity !== 'undefined') {\n ctx.globalAlpha = point.opacity;\n }\n\n ctx.fillRect(point.x, point.y, point.width, point.width);\n }\n\n ctx.restore();\n },\n\n /**\n * Render all spray chunks\n */\n _render: function () {\n var ctx = this.canvas.contextTop,\n i,\n ilen;\n ctx.fillStyle = this.color;\n\n this._saveAndTransform(ctx);\n\n for (i = 0, ilen = this.sprayChunks.length; i < ilen; i++) {\n this.render(this.sprayChunks[i]);\n }\n\n ctx.restore();\n },\n\n /**\n * @param {Object} pointer\n */\n addSprayChunk: function (pointer) {\n this.sprayChunkPoints = [];\n var x,\n y,\n width,\n radius = this.width / 2,\n i;\n\n for (i = 0; i < this.density; i++) {\n x = fabric.util.getRandomInt(pointer.x - radius, pointer.x + radius);\n y = fabric.util.getRandomInt(pointer.y - radius, pointer.y + radius);\n\n if (this.dotWidthVariance) {\n width = fabric.util.getRandomInt( // bottom clamp width to 1\n Math.max(1, this.dotWidth - this.dotWidthVariance), this.dotWidth + this.dotWidthVariance);\n } else {\n width = this.dotWidth;\n }\n\n var point = new fabric.Point(x, y);\n point.width = width;\n\n if (this.randomOpacity) {\n point.opacity = fabric.util.getRandomInt(0, 100) / 100;\n }\n\n this.sprayChunkPoints.push(point);\n }\n\n this.sprayChunks.push(this.sprayChunkPoints);\n }\n});\n/**\n * PatternBrush class\n * @class fabric.PatternBrush\n * @extends fabric.BaseBrush\n */\n\nfabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush,\n/** @lends fabric.PatternBrush.prototype */\n{\n getPatternSrc: function () {\n var dotWidth = 20,\n dotDistance = 5,\n patternCanvas = fabric.util.createCanvasElement(),\n patternCtx = patternCanvas.getContext('2d');\n patternCanvas.width = patternCanvas.height = dotWidth + dotDistance;\n patternCtx.fillStyle = this.color;\n patternCtx.beginPath();\n patternCtx.arc(dotWidth / 2, dotWidth / 2, dotWidth / 2, 0, Math.PI * 2, false);\n patternCtx.closePath();\n patternCtx.fill();\n return patternCanvas;\n },\n getPatternSrcFunction: function () {\n return String(this.getPatternSrc).replace('this.color', '\"' + this.color + '\"');\n },\n\n /**\n * Creates \"pattern\" instance property\n */\n getPattern: function () {\n return this.canvas.contextTop.createPattern(this.source || this.getPatternSrc(), 'repeat');\n },\n\n /**\n * Sets brush styles\n */\n _setBrushStyles: function () {\n this.callSuper('_setBrushStyles');\n this.canvas.contextTop.strokeStyle = this.getPattern();\n },\n\n /**\n * Creates path\n */\n createPath: function (pathData) {\n var path = this.callSuper('createPath', pathData),\n topLeft = path._getLeftTopCoords().scalarAdd(path.strokeWidth / 2);\n\n path.stroke = new fabric.Pattern({\n source: this.source || this.getPatternSrcFunction(),\n offsetX: -topLeft.x,\n offsetY: -topLeft.y\n });\n return path;\n }\n});\n\n(function () {\n var getPointer = fabric.util.getPointer,\n degreesToRadians = fabric.util.degreesToRadians,\n abs = Math.abs,\n supportLineDash = fabric.StaticCanvas.supports('setLineDash'),\n isTouchEvent = fabric.util.isTouchEvent,\n STROKE_OFFSET = 0.5;\n /**\n * Canvas class\n * @class fabric.Canvas\n * @extends fabric.StaticCanvas\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#canvas}\n * @see {@link fabric.Canvas#initialize} for constructor definition\n *\n * @fires object:modified at the end of a transform or any change when statefull is true\n * @fires object:rotating while an object is being rotated from the control\n * @fires object:scaling while an object is being scaled by controls\n * @fires object:moving while an object is being dragged\n * @fires object:skewing while an object is being skewed from the controls\n *\n * @fires before:transform before a transform is is started\n * @fires before:selection:cleared\n * @fires selection:cleared\n * @fires selection:updated\n * @fires selection:created\n *\n * @fires path:created after a drawing operation ends and the path is added\n * @fires mouse:down\n * @fires mouse:move\n * @fires mouse:up\n * @fires mouse:down:before on mouse down, before the inner fabric logic runs\n * @fires mouse:move:before on mouse move, before the inner fabric logic runs\n * @fires mouse:up:before on mouse up, before the inner fabric logic runs\n * @fires mouse:over\n * @fires mouse:out\n * @fires mouse:dblclick whenever a native dbl click event fires on the canvas.\n *\n * @fires dragover\n * @fires dragenter\n * @fires dragleave\n * @fires drop\n * @fires after:render at the end of the render process, receives the context in the callback\n * @fires before:render at start the render process, receives the context in the callback\n *\n * the following events are deprecated:\n * @fires object:rotated at the end of a rotation transform\n * @fires object:scaled at the end of a scale transform\n * @fires object:moved at the end of translation transform\n * @fires object:skewed at the end of a skew transform\n */\n\n fabric.Canvas = fabric.util.createClass(fabric.StaticCanvas,\n /** @lends fabric.Canvas.prototype */\n {\n /**\n * Constructor\n * @param {HTMLElement | String} el <canvas> element to initialize instance on\n * @param {Object} [options] Options object\n * @return {Object} thisArg\n */\n initialize: function (el, options) {\n options || (options = {});\n this.renderAndResetBound = this.renderAndReset.bind(this);\n this.requestRenderAllBound = this.requestRenderAll.bind(this);\n\n this._initStatic(el, options);\n\n this._initInteractive();\n\n this._createCacheCanvas();\n },\n\n /**\n * When true, objects can be transformed by one side (unproportionally)\n * when dragged on the corners that normally would not do that.\n * @type Boolean\n * @default\n * @since fabric 4.0 // changed name and default value\n */\n uniformScaling: true,\n\n /**\n * Indicates which key switches uniform scaling.\n * values: 'altKey', 'shiftKey', 'ctrlKey'.\n * If `null` or 'none' or any other string that is not a modifier key\n * feature is disabled.\n * totally wrong named. this sounds like `uniform scaling`\n * if Canvas.uniformScaling is true, pressing this will set it to false\n * and viceversa.\n * @since 1.6.2\n * @type String\n * @default\n */\n uniScaleKey: 'shiftKey',\n\n /**\n * When true, objects use center point as the origin of scale transformation.\n * <b>Backwards incompatibility note:</b> This property replaces \"centerTransform\" (Boolean).\n * @since 1.3.4\n * @type Boolean\n * @default\n */\n centeredScaling: false,\n\n /**\n * When true, objects use center point as the origin of rotate transformation.\n * <b>Backwards incompatibility note:</b> This property replaces \"centerTransform\" (Boolean).\n * @since 1.3.4\n * @type Boolean\n * @default\n */\n centeredRotation: false,\n\n /**\n * Indicates which key enable centered Transform\n * values: 'altKey', 'shiftKey', 'ctrlKey'.\n * If `null` or 'none' or any other string that is not a modifier key\n * feature is disabled feature disabled.\n * @since 1.6.2\n * @type String\n * @default\n */\n centeredKey: 'altKey',\n\n /**\n * Indicates which key enable alternate action on corner\n * values: 'altKey', 'shiftKey', 'ctrlKey'.\n * If `null` or 'none' or any other string that is not a modifier key\n * feature is disabled feature disabled.\n * @since 1.6.2\n * @type String\n * @default\n */\n altActionKey: 'shiftKey',\n\n /**\n * Indicates that canvas is interactive. This property should not be changed.\n * @type Boolean\n * @default\n */\n interactive: true,\n\n /**\n * Indicates whether group selection should be enabled\n * @type Boolean\n * @default\n */\n selection: true,\n\n /**\n * Indicates which key or keys enable multiple click selection\n * Pass value as a string or array of strings\n * values: 'altKey', 'shiftKey', 'ctrlKey'.\n * If `null` or empty or containing any other string that is not a modifier key\n * feature is disabled.\n * @since 1.6.2\n * @type String|Array\n * @default\n */\n selectionKey: 'shiftKey',\n\n /**\n * Indicates which key enable alternative selection\n * in case of target overlapping with active object\n * values: 'altKey', 'shiftKey', 'ctrlKey'.\n * For a series of reason that come from the general expectations on how\n * things should work, this feature works only for preserveObjectStacking true.\n * If `null` or 'none' or any other string that is not a modifier key\n * feature is disabled.\n * @since 1.6.5\n * @type null|String\n * @default\n */\n altSelectionKey: null,\n\n /**\n * Color of selection\n * @type String\n * @default\n */\n selectionColor: 'rgba(100, 100, 255, 0.3)',\n // blue\n\n /**\n * Default dash array pattern\n * If not empty the selection border is dashed\n * @type Array\n */\n selectionDashArray: [],\n\n /**\n * Color of the border of selection (usually slightly darker than color of selection itself)\n * @type String\n * @default\n */\n selectionBorderColor: 'rgba(255, 255, 255, 0.3)',\n\n /**\n * Width of a line used in object/group selection\n * @type Number\n * @default\n */\n selectionLineWidth: 1,\n\n /**\n * Select only shapes that are fully contained in the dragged selection rectangle.\n * @type Boolean\n * @default\n */\n selectionFullyContained: false,\n\n /**\n * Default cursor value used when hovering over an object on canvas\n * @type String\n * @default\n */\n hoverCursor: 'move',\n\n /**\n * Default cursor value used when moving an object on canvas\n * @type String\n * @default\n */\n moveCursor: 'move',\n\n /**\n * Default cursor value used for the entire canvas\n * @type String\n * @default\n */\n defaultCursor: 'default',\n\n /**\n * Cursor value used during free drawing\n * @type String\n * @default\n */\n freeDrawingCursor: 'crosshair',\n\n /**\n * Cursor value used for rotation point\n * @type String\n * @default\n */\n rotationCursor: 'crosshair',\n\n /**\n * Cursor value used for disabled elements ( corners with disabled action )\n * @type String\n * @since 2.0.0\n * @default\n */\n notAllowedCursor: 'not-allowed',\n\n /**\n * Default element class that's given to wrapper (div) element of canvas\n * @type String\n * @default\n */\n containerClass: 'canvas-container',\n\n /**\n * When true, object detection happens on per-pixel basis rather than on per-bounding-box\n * @type Boolean\n * @default\n */\n perPixelTargetFind: false,\n\n /**\n * Number of pixels around target pixel to tolerate (consider active) during object detection\n * @type Number\n * @default\n */\n targetFindTolerance: 0,\n\n /**\n * When true, target detection is skipped. Target detection will return always undefined.\n * click selection won't work anymore, events will fire with no targets.\n * if something is selected before setting it to true, it will be deselected at the first click.\n * area selection will still work. check the `selection` property too.\n * if you deactivate both, you should look into staticCanvas.\n * @type Boolean\n * @default\n */\n skipTargetFind: false,\n\n /**\n * When true, mouse events on canvas (mousedown/mousemove/mouseup) result in free drawing.\n * After mousedown, mousemove creates a shape,\n * and then mouseup finalizes it and adds an instance of `fabric.Path` onto canvas.\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-4#free_drawing}\n * @type Boolean\n * @default\n */\n isDrawingMode: false,\n\n /**\n * Indicates whether objects should remain in current stack position when selected.\n * When false objects are brought to top and rendered as part of the selection group\n * @type Boolean\n * @default\n */\n preserveObjectStacking: false,\n\n /**\n * Indicates the angle that an object will lock to while rotating.\n * @type Number\n * @since 1.6.7\n * @default\n */\n snapAngle: 0,\n\n /**\n * Indicates the distance from the snapAngle the rotation will lock to the snapAngle.\n * When `null`, the snapThreshold will default to the snapAngle.\n * @type null|Number\n * @since 1.6.7\n * @default\n */\n snapThreshold: null,\n\n /**\n * Indicates if the right click on canvas can output the context menu or not\n * @type Boolean\n * @since 1.6.5\n * @default\n */\n stopContextMenu: false,\n\n /**\n * Indicates if the canvas can fire right click events\n * @type Boolean\n * @since 1.6.5\n * @default\n */\n fireRightClick: false,\n\n /**\n * Indicates if the canvas can fire middle click events\n * @type Boolean\n * @since 1.7.8\n * @default\n */\n fireMiddleClick: false,\n\n /**\n * Keep track of the subTargets for Mouse Events\n * @type fabric.Object[]\n */\n targets: [],\n\n /**\n * Keep track of the hovered target\n * @type fabric.Object\n * @private\n */\n _hoveredTarget: null,\n\n /**\n * hold the list of nested targets hovered\n * @type fabric.Object[]\n * @private\n */\n _hoveredTargets: [],\n\n /**\n * @private\n */\n _initInteractive: function () {\n this._currentTransform = null;\n this._groupSelector = null;\n\n this._initWrapperElement();\n\n this._createUpperCanvas();\n\n this._initEventListeners();\n\n this._initRetinaScaling();\n\n this.freeDrawingBrush = fabric.PencilBrush && new fabric.PencilBrush(this);\n this.calcOffset();\n },\n\n /**\n * Divides objects in two groups, one to render immediately\n * and one to render as activeGroup.\n * @return {Array} objects to render immediately and pushes the other in the activeGroup.\n */\n _chooseObjectsToRender: function () {\n var activeObjects = this.getActiveObjects(),\n object,\n objsToRender,\n activeGroupObjects;\n\n if (activeObjects.length > 0 && !this.preserveObjectStacking) {\n objsToRender = [];\n activeGroupObjects = [];\n\n for (var i = 0, length = this._objects.length; i < length; i++) {\n object = this._objects[i];\n\n if (activeObjects.indexOf(object) === -1) {\n objsToRender.push(object);\n } else {\n activeGroupObjects.push(object);\n }\n }\n\n if (activeObjects.length > 1) {\n this._activeObject._objects = activeGroupObjects;\n }\n\n objsToRender.push.apply(objsToRender, activeGroupObjects);\n } else {\n objsToRender = this._objects;\n }\n\n return objsToRender;\n },\n\n /**\n * Renders both the top canvas and the secondary container canvas.\n * @return {fabric.Canvas} instance\n * @chainable\n */\n renderAll: function () {\n if (this.contextTopDirty && !this._groupSelector && !this.isDrawingMode) {\n this.clearContext(this.contextTop);\n this.contextTopDirty = false;\n }\n\n if (this.hasLostContext) {\n this.renderTopLayer(this.contextTop);\n }\n\n var canvasToDrawOn = this.contextContainer;\n this.renderCanvas(canvasToDrawOn, this._chooseObjectsToRender());\n return this;\n },\n renderTopLayer: function (ctx) {\n ctx.save();\n\n if (this.isDrawingMode && this._isCurrentlyDrawing) {\n this.freeDrawingBrush && this.freeDrawingBrush._render();\n this.contextTopDirty = true;\n } // we render the top context - last object\n\n\n if (this.selection && this._groupSelector) {\n this._drawSelection(ctx);\n\n this.contextTopDirty = true;\n }\n\n ctx.restore();\n },\n\n /**\n * Method to render only the top canvas.\n * Also used to render the group selection box.\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n renderTop: function () {\n var ctx = this.contextTop;\n this.clearContext(ctx);\n this.renderTopLayer(ctx);\n this.fire('after:render');\n return this;\n },\n\n /**\n * @private\n */\n _normalizePointer: function (object, pointer) {\n var m = object.calcTransformMatrix(),\n invertedM = fabric.util.invertTransform(m),\n vptPointer = this.restorePointerVpt(pointer);\n return fabric.util.transformPoint(vptPointer, invertedM);\n },\n\n /**\n * Returns true if object is transparent at a certain location\n * @param {fabric.Object} target Object to check\n * @param {Number} x Left coordinate\n * @param {Number} y Top coordinate\n * @return {Boolean}\n */\n isTargetTransparent: function (target, x, y) {\n // in case the target is the activeObject, we cannot execute this optimization\n // because we need to draw controls too.\n if (target.shouldCache() && target._cacheCanvas && target !== this._activeObject) {\n var normalizedPointer = this._normalizePointer(target, {\n x: x,\n y: y\n }),\n targetRelativeX = Math.max(target.cacheTranslationX + normalizedPointer.x * target.zoomX, 0),\n targetRelativeY = Math.max(target.cacheTranslationY + normalizedPointer.y * target.zoomY, 0);\n\n var isTransparent = fabric.util.isTransparent(target._cacheContext, Math.round(targetRelativeX), Math.round(targetRelativeY), this.targetFindTolerance);\n return isTransparent;\n }\n\n var ctx = this.contextCache,\n originalColor = target.selectionBackgroundColor,\n v = this.viewportTransform;\n target.selectionBackgroundColor = '';\n this.clearContext(ctx);\n ctx.save();\n ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]);\n target.render(ctx);\n ctx.restore();\n target === this._activeObject && target._renderControls(ctx, {\n hasBorders: false,\n transparentCorners: false\n }, {\n hasBorders: false\n });\n target.selectionBackgroundColor = originalColor;\n var isTransparent = fabric.util.isTransparent(ctx, x, y, this.targetFindTolerance);\n return isTransparent;\n },\n\n /**\n * takes an event and determins if selection key has been pressed\n * @private\n * @param {Event} e Event object\n */\n _isSelectionKeyPressed: function (e) {\n var selectionKeyPressed = false;\n\n if (Object.prototype.toString.call(this.selectionKey) === '[object Array]') {\n selectionKeyPressed = !!this.selectionKey.find(function (key) {\n return e[key] === true;\n });\n } else {\n selectionKeyPressed = e[this.selectionKey];\n }\n\n return selectionKeyPressed;\n },\n\n /**\n * @private\n * @param {Event} e Event object\n * @param {fabric.Object} target\n */\n _shouldClearSelection: function (e, target) {\n var activeObjects = this.getActiveObjects(),\n activeObject = this._activeObject;\n return !target || target && activeObject && activeObjects.length > 1 && activeObjects.indexOf(target) === -1 && activeObject !== target && !this._isSelectionKeyPressed(e) || target && !target.evented || target && !target.selectable && activeObject && activeObject !== target;\n },\n\n /**\n * centeredScaling from object can't override centeredScaling from canvas.\n * this should be fixed, since object setting should take precedence over canvas.\n * also this should be something that will be migrated in the control properties.\n * as ability to define the origin of the transformation that the control provide.\n * @private\n * @param {fabric.Object} target\n * @param {String} action\n * @param {Boolean} altKey\n */\n _shouldCenterTransform: function (target, action, altKey) {\n if (!target) {\n return;\n }\n\n var centerTransform;\n\n if (action === 'scale' || action === 'scaleX' || action === 'scaleY' || action === 'resizing') {\n centerTransform = this.centeredScaling || target.centeredScaling;\n } else if (action === 'rotate') {\n centerTransform = this.centeredRotation || target.centeredRotation;\n }\n\n return centerTransform ? !altKey : altKey;\n },\n\n /**\n * should disappear before release 4.0\n * @private\n */\n _getOriginFromCorner: function (target, corner) {\n var origin = {\n x: target.originX,\n y: target.originY\n };\n\n if (corner === 'ml' || corner === 'tl' || corner === 'bl') {\n origin.x = 'right';\n } else if (corner === 'mr' || corner === 'tr' || corner === 'br') {\n origin.x = 'left';\n }\n\n if (corner === 'tl' || corner === 'mt' || corner === 'tr') {\n origin.y = 'bottom';\n } else if (corner === 'bl' || corner === 'mb' || corner === 'br') {\n origin.y = 'top';\n } else if (corner === 'mtr') {\n origin.x = 'center';\n origin.y = 'center';\n }\n\n return origin;\n },\n\n /**\n * @private\n * @param {Boolean} alreadySelected true if target is already selected\n * @param {String} corner a string representing the corner ml, mr, tl ...\n * @param {Event} e Event object\n * @param {fabric.Object} [target] inserted back to help overriding. Unused\n */\n _getActionFromCorner: function (alreadySelected, corner, e, target) {\n if (!corner || !alreadySelected) {\n return 'drag';\n }\n\n var control = target.controls[corner];\n return control.getActionName(e, control, target);\n },\n\n /**\n * @private\n * @param {Event} e Event object\n * @param {fabric.Object} target\n */\n _setupCurrentTransform: function (e, target, alreadySelected) {\n if (!target) {\n return;\n }\n\n var pointer = this.getPointer(e),\n corner = target.__corner,\n actionHandler = alreadySelected && corner ? target.controls[corner].getActionHandler() : fabric.controlsUtils.dragHandler,\n action = this._getActionFromCorner(alreadySelected, corner, e, target),\n origin = this._getOriginFromCorner(target, corner),\n altKey = e[this.centeredKey],\n transform = {\n target: target,\n action: action,\n actionHandler: actionHandler,\n corner: corner,\n scaleX: target.scaleX,\n scaleY: target.scaleY,\n skewX: target.skewX,\n skewY: target.skewY,\n // used by transation\n offsetX: pointer.x - target.left,\n offsetY: pointer.y - target.top,\n originX: origin.x,\n originY: origin.y,\n ex: pointer.x,\n ey: pointer.y,\n lastX: pointer.x,\n lastY: pointer.y,\n // unsure they are useful anymore.\n // left: target.left,\n // top: target.top,\n theta: degreesToRadians(target.angle),\n // end of unsure\n width: target.width * target.scaleX,\n shiftKey: e.shiftKey,\n altKey: altKey,\n original: fabric.util.saveObjectTransform(target)\n };\n\n if (this._shouldCenterTransform(target, action, altKey)) {\n transform.originX = 'center';\n transform.originY = 'center';\n }\n\n transform.original.originX = origin.x;\n transform.original.originY = origin.y;\n this._currentTransform = transform;\n\n this._beforeTransform(e);\n },\n\n /**\n * Set the cursor type of the canvas element\n * @param {String} value Cursor type of the canvas element.\n * @see http://www.w3.org/TR/css3-ui/#cursor\n */\n setCursor: function (value) {\n this.upperCanvasEl.style.cursor = value;\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx to draw the selection on\n */\n _drawSelection: function (ctx) {\n var groupSelector = this._groupSelector,\n left = groupSelector.left,\n top = groupSelector.top,\n aleft = abs(left),\n atop = abs(top);\n\n if (this.selectionColor) {\n ctx.fillStyle = this.selectionColor;\n ctx.fillRect(groupSelector.ex - (left > 0 ? 0 : -left), groupSelector.ey - (top > 0 ? 0 : -top), aleft, atop);\n }\n\n if (!this.selectionLineWidth || !this.selectionBorderColor) {\n return;\n }\n\n ctx.lineWidth = this.selectionLineWidth;\n ctx.strokeStyle = this.selectionBorderColor; // selection border\n\n if (this.selectionDashArray.length > 1 && !supportLineDash) {\n var px = groupSelector.ex + STROKE_OFFSET - (left > 0 ? 0 : aleft),\n py = groupSelector.ey + STROKE_OFFSET - (top > 0 ? 0 : atop);\n ctx.beginPath();\n fabric.util.drawDashedLine(ctx, px, py, px + aleft, py, this.selectionDashArray);\n fabric.util.drawDashedLine(ctx, px, py + atop - 1, px + aleft, py + atop - 1, this.selectionDashArray);\n fabric.util.drawDashedLine(ctx, px, py, px, py + atop, this.selectionDashArray);\n fabric.util.drawDashedLine(ctx, px + aleft - 1, py, px + aleft - 1, py + atop, this.selectionDashArray);\n ctx.closePath();\n ctx.stroke();\n } else {\n fabric.Object.prototype._setLineDash.call(this, ctx, this.selectionDashArray);\n\n ctx.strokeRect(groupSelector.ex + STROKE_OFFSET - (left > 0 ? 0 : aleft), groupSelector.ey + STROKE_OFFSET - (top > 0 ? 0 : atop), aleft, atop);\n }\n },\n\n /**\n * Method that determines what object we are clicking on\n * the skipGroup parameter is for internal use, is needed for shift+click action\n * 11/09/2018 TODO: would be cool if findTarget could discern between being a full target\n * or the outside part of the corner.\n * @param {Event} e mouse event\n * @param {Boolean} skipGroup when true, activeGroup is skipped and only objects are traversed through\n * @return {fabric.Object} the target found\n */\n findTarget: function (e, skipGroup) {\n if (this.skipTargetFind) {\n return;\n }\n\n var ignoreZoom = true,\n pointer = this.getPointer(e, ignoreZoom),\n activeObject = this._activeObject,\n aObjects = this.getActiveObjects(),\n activeTarget,\n activeTargetSubs,\n isTouch = isTouchEvent(e); // first check current group (if one exists)\n // active group does not check sub targets like normal groups.\n // if active group just exits.\n\n this.targets = [];\n\n if (aObjects.length > 1 && !skipGroup && activeObject === this._searchPossibleTargets([activeObject], pointer)) {\n return activeObject;\n } // if we hit the corner of an activeObject, let's return that.\n\n\n if (aObjects.length === 1 && activeObject._findTargetCorner(pointer, isTouch)) {\n return activeObject;\n }\n\n if (aObjects.length === 1 && activeObject === this._searchPossibleTargets([activeObject], pointer)) {\n if (!this.preserveObjectStacking) {\n return activeObject;\n } else {\n activeTarget = activeObject;\n activeTargetSubs = this.targets;\n this.targets = [];\n }\n }\n\n var target = this._searchPossibleTargets(this._objects, pointer);\n\n if (e[this.altSelectionKey] && target && activeTarget && target !== activeTarget) {\n target = activeTarget;\n this.targets = activeTargetSubs;\n }\n\n return target;\n },\n\n /**\n * Checks point is inside the object.\n * @param {Object} [pointer] x,y object of point coordinates we want to check.\n * @param {fabric.Object} obj Object to test against\n * @param {Object} [globalPointer] x,y object of point coordinates relative to canvas used to search per pixel target.\n * @return {Boolean} true if point is contained within an area of given object\n * @private\n */\n _checkTarget: function (pointer, obj, globalPointer) {\n if (obj && obj.visible && obj.evented && ( // http://www.geog.ubc.ca/courses/klink/gis.notes/ncgia/u32.html\n // http://idav.ucdavis.edu/~okreylos/TAship/Spring2000/PointInPolygon.html\n obj.containsPoint(pointer) || !!obj._findTargetCorner(pointer))) {\n if ((this.perPixelTargetFind || obj.perPixelTargetFind) && !obj.isEditing) {\n var isTransparent = this.isTargetTransparent(obj, globalPointer.x, globalPointer.y);\n\n if (!isTransparent) {\n return true;\n }\n } else {\n return true;\n }\n }\n },\n\n /**\n * Function used to search inside objects an object that contains pointer in bounding box or that contains pointerOnCanvas when painted\n * @param {Array} [objects] objects array to look into\n * @param {Object} [pointer] x,y object of point coordinates we want to check.\n * @return {fabric.Object} object that contains pointer\n * @private\n */\n _searchPossibleTargets: function (objects, pointer) {\n // Cache all targets where their bounding box contains point.\n var target,\n i = objects.length,\n subTarget; // Do not check for currently grouped objects, since we check the parent group itself.\n // until we call this function specifically to search inside the activeGroup\n\n while (i--) {\n var objToCheck = objects[i];\n var pointerToUse = objToCheck.group ? this._normalizePointer(objToCheck.group, pointer) : pointer;\n\n if (this._checkTarget(pointerToUse, objToCheck, pointer)) {\n target = objects[i];\n\n if (target.subTargetCheck && target instanceof fabric.Group) {\n subTarget = this._searchPossibleTargets(target._objects, pointer);\n subTarget && this.targets.push(subTarget);\n }\n\n break;\n }\n }\n\n return target;\n },\n\n /**\n * Returns pointer coordinates without the effect of the viewport\n * @param {Object} pointer with \"x\" and \"y\" number values\n * @return {Object} object with \"x\" and \"y\" number values\n */\n restorePointerVpt: function (pointer) {\n return fabric.util.transformPoint(pointer, fabric.util.invertTransform(this.viewportTransform));\n },\n\n /**\n * Returns pointer coordinates relative to canvas.\n * Can return coordinates with or without viewportTransform.\n * ignoreZoom false gives back coordinates that represent\n * the point clicked on canvas element.\n * ignoreZoom true gives back coordinates after being processed\n * by the viewportTransform ( sort of coordinates of what is displayed\n * on the canvas where you are clicking.\n * ignoreZoom true = HTMLElement coordinates relative to top,left\n * ignoreZoom false, default = fabric space coordinates, the same used for shape position\n * To interact with your shapes top and left you want to use ignoreZoom true\n * most of the time, while ignoreZoom false will give you coordinates\n * compatible with the object.oCoords system.\n * of the time.\n * @param {Event} e\n * @param {Boolean} ignoreZoom\n * @return {Object} object with \"x\" and \"y\" number values\n */\n getPointer: function (e, ignoreZoom) {\n // return cached values if we are in the event processing chain\n if (this._absolutePointer && !ignoreZoom) {\n return this._absolutePointer;\n }\n\n if (this._pointer && ignoreZoom) {\n return this._pointer;\n }\n\n var pointer = getPointer(e),\n upperCanvasEl = this.upperCanvasEl,\n bounds = upperCanvasEl.getBoundingClientRect(),\n boundsWidth = bounds.width || 0,\n boundsHeight = bounds.height || 0,\n cssScale;\n\n if (!boundsWidth || !boundsHeight) {\n if ('top' in bounds && 'bottom' in bounds) {\n boundsHeight = Math.abs(bounds.top - bounds.bottom);\n }\n\n if ('right' in bounds && 'left' in bounds) {\n boundsWidth = Math.abs(bounds.right - bounds.left);\n }\n }\n\n this.calcOffset();\n pointer.x = pointer.x - this._offset.left;\n pointer.y = pointer.y - this._offset.top;\n\n if (!ignoreZoom) {\n pointer = this.restorePointerVpt(pointer);\n }\n\n var retinaScaling = this.getRetinaScaling();\n\n if (retinaScaling !== 1) {\n pointer.x /= retinaScaling;\n pointer.y /= retinaScaling;\n }\n\n if (boundsWidth === 0 || boundsHeight === 0) {\n // If bounds are not available (i.e. not visible), do not apply scale.\n cssScale = {\n width: 1,\n height: 1\n };\n } else {\n cssScale = {\n width: upperCanvasEl.width / boundsWidth,\n height: upperCanvasEl.height / boundsHeight\n };\n }\n\n return {\n x: pointer.x * cssScale.width,\n y: pointer.y * cssScale.height\n };\n },\n\n /**\n * @private\n * @throws {CANVAS_INIT_ERROR} If canvas can not be initialized\n */\n _createUpperCanvas: function () {\n var lowerCanvasClass = this.lowerCanvasEl.className.replace(/\\s*lower-canvas\\s*/, ''),\n lowerCanvasEl = this.lowerCanvasEl,\n upperCanvasEl = this.upperCanvasEl; // there is no need to create a new upperCanvas element if we have already one.\n\n if (upperCanvasEl) {\n upperCanvasEl.className = '';\n } else {\n upperCanvasEl = this._createCanvasElement();\n this.upperCanvasEl = upperCanvasEl;\n }\n\n fabric.util.addClass(upperCanvasEl, 'upper-canvas ' + lowerCanvasClass);\n this.wrapperEl.appendChild(upperCanvasEl);\n\n this._copyCanvasStyle(lowerCanvasEl, upperCanvasEl);\n\n this._applyCanvasStyle(upperCanvasEl);\n\n this.contextTop = upperCanvasEl.getContext('2d');\n },\n\n /**\n * @private\n */\n _createCacheCanvas: function () {\n this.cacheCanvasEl = this._createCanvasElement();\n this.cacheCanvasEl.setAttribute('width', this.width);\n this.cacheCanvasEl.setAttribute('height', this.height);\n this.contextCache = this.cacheCanvasEl.getContext('2d');\n },\n\n /**\n * @private\n */\n _initWrapperElement: function () {\n this.wrapperEl = fabric.util.wrapElement(this.lowerCanvasEl, 'div', {\n 'class': this.containerClass\n });\n fabric.util.setStyle(this.wrapperEl, {\n width: this.width + 'px',\n height: this.height + 'px',\n position: 'relative'\n });\n fabric.util.makeElementUnselectable(this.wrapperEl);\n },\n\n /**\n * @private\n * @param {HTMLElement} element canvas element to apply styles on\n */\n _applyCanvasStyle: function (element) {\n var width = this.width || element.width,\n height = this.height || element.height;\n fabric.util.setStyle(element, {\n position: 'absolute',\n width: width + 'px',\n height: height + 'px',\n left: 0,\n top: 0,\n 'touch-action': this.allowTouchScrolling ? 'manipulation' : 'none',\n '-ms-touch-action': this.allowTouchScrolling ? 'manipulation' : 'none'\n });\n element.width = width;\n element.height = height;\n fabric.util.makeElementUnselectable(element);\n },\n\n /**\n * Copy the entire inline style from one element (fromEl) to another (toEl)\n * @private\n * @param {Element} fromEl Element style is copied from\n * @param {Element} toEl Element copied style is applied to\n */\n _copyCanvasStyle: function (fromEl, toEl) {\n toEl.style.cssText = fromEl.style.cssText;\n },\n\n /**\n * Returns context of canvas where object selection is drawn\n * @return {CanvasRenderingContext2D}\n */\n getSelectionContext: function () {\n return this.contextTop;\n },\n\n /**\n * Returns <canvas> element on which object selection is drawn\n * @return {HTMLCanvasElement}\n */\n getSelectionElement: function () {\n return this.upperCanvasEl;\n },\n\n /**\n * Returns currently active object\n * @return {fabric.Object} active object\n */\n getActiveObject: function () {\n return this._activeObject;\n },\n\n /**\n * Returns an array with the current selected objects\n * @return {fabric.Object} active object\n */\n getActiveObjects: function () {\n var active = this._activeObject;\n\n if (active) {\n if (active.type === 'activeSelection' && active._objects) {\n return active._objects.slice(0);\n } else {\n return [active];\n }\n }\n\n return [];\n },\n\n /**\n * @private\n * @param {fabric.Object} obj Object that was removed\n */\n _onObjectRemoved: function (obj) {\n // removing active object should fire \"selection:cleared\" events\n if (obj === this._activeObject) {\n this.fire('before:selection:cleared', {\n target: obj\n });\n\n this._discardActiveObject();\n\n this.fire('selection:cleared', {\n target: obj\n });\n obj.fire('deselected');\n }\n\n if (obj === this._hoveredTarget) {\n this._hoveredTarget = null;\n this._hoveredTargets = [];\n }\n\n this.callSuper('_onObjectRemoved', obj);\n },\n\n /**\n * @private\n * Compares the old activeObject with the current one and fires correct events\n * @param {fabric.Object} obj old activeObject\n */\n _fireSelectionEvents: function (oldObjects, e) {\n var somethingChanged = false,\n objects = this.getActiveObjects(),\n added = [],\n removed = [],\n opt = {\n e: e\n };\n oldObjects.forEach(function (oldObject) {\n if (objects.indexOf(oldObject) === -1) {\n somethingChanged = true;\n oldObject.fire('deselected', opt);\n removed.push(oldObject);\n }\n });\n objects.forEach(function (object) {\n if (oldObjects.indexOf(object) === -1) {\n somethingChanged = true;\n object.fire('selected', opt);\n added.push(object);\n }\n });\n\n if (oldObjects.length > 0 && objects.length > 0) {\n opt.selected = added;\n opt.deselected = removed; // added for backward compatibility\n\n opt.updated = added[0] || removed[0];\n opt.target = this._activeObject;\n somethingChanged && this.fire('selection:updated', opt);\n } else if (objects.length > 0) {\n opt.selected = added; // added for backward compatibility\n\n opt.target = this._activeObject;\n this.fire('selection:created', opt);\n } else if (oldObjects.length > 0) {\n opt.deselected = removed;\n this.fire('selection:cleared', opt);\n }\n },\n\n /**\n * Sets given object as the only active object on canvas\n * @param {fabric.Object} object Object to set as an active one\n * @param {Event} [e] Event (passed along when firing \"object:selected\")\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n setActiveObject: function (object, e) {\n var currentActives = this.getActiveObjects();\n\n this._setActiveObject(object, e);\n\n this._fireSelectionEvents(currentActives, e);\n\n return this;\n },\n\n /**\n * @private\n * @param {Object} object to set as active\n * @param {Event} [e] Event (passed along when firing \"object:selected\")\n * @return {Boolean} true if the selection happened\n */\n _setActiveObject: function (object, e) {\n if (this._activeObject === object) {\n return false;\n }\n\n if (!this._discardActiveObject(e, object)) {\n return false;\n }\n\n if (object.onSelect({\n e: e\n })) {\n return false;\n }\n\n this._activeObject = object;\n return true;\n },\n\n /**\n * @private\n */\n _discardActiveObject: function (e, object) {\n var obj = this._activeObject;\n\n if (obj) {\n // onDeselect return TRUE to cancel selection;\n if (obj.onDeselect({\n e: e,\n object: object\n })) {\n return false;\n }\n\n this._activeObject = null;\n }\n\n return true;\n },\n\n /**\n * Discards currently active object and fire events. If the function is called by fabric\n * as a consequence of a mouse event, the event is passed as a parameter and\n * sent to the fire function for the custom events. When used as a method the\n * e param does not have any application.\n * @param {event} e\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n discardActiveObject: function (e) {\n var currentActives = this.getActiveObjects(),\n activeObject = this.getActiveObject();\n\n if (currentActives.length) {\n this.fire('before:selection:cleared', {\n target: activeObject,\n e: e\n });\n }\n\n this._discardActiveObject(e);\n\n this._fireSelectionEvents(currentActives, e);\n\n return this;\n },\n\n /**\n * Clears a canvas element and removes all event listeners\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n dispose: function () {\n var wrapper = this.wrapperEl;\n this.removeListeners();\n wrapper.removeChild(this.upperCanvasEl);\n wrapper.removeChild(this.lowerCanvasEl);\n this.contextCache = null;\n this.contextTop = null;\n ['upperCanvasEl', 'cacheCanvasEl'].forEach(function (element) {\n fabric.util.cleanUpJsdomNode(this[element]);\n this[element] = undefined;\n }.bind(this));\n\n if (wrapper.parentNode) {\n wrapper.parentNode.replaceChild(this.lowerCanvasEl, this.wrapperEl);\n }\n\n delete this.wrapperEl;\n fabric.StaticCanvas.prototype.dispose.call(this);\n return this;\n },\n\n /**\n * Clears all contexts (background, main, top) of an instance\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n clear: function () {\n // this.discardActiveGroup();\n this.discardActiveObject();\n this.clearContext(this.contextTop);\n return this.callSuper('clear');\n },\n\n /**\n * Draws objects' controls (borders/controls)\n * @param {CanvasRenderingContext2D} ctx Context to render controls on\n */\n drawControls: function (ctx) {\n var activeObject = this._activeObject;\n\n if (activeObject) {\n activeObject._renderControls(ctx);\n }\n },\n\n /**\n * @private\n */\n _toObject: function (instance, methodName, propertiesToInclude) {\n //If the object is part of the current selection group, it should\n //be transformed appropriately\n //i.e. it should be serialised as it would appear if the selection group\n //were to be destroyed.\n var originalProperties = this._realizeGroupTransformOnObject(instance),\n object = this.callSuper('_toObject', instance, methodName, propertiesToInclude); //Undo the damage we did by changing all of its properties\n\n\n this._unwindGroupTransformOnObject(instance, originalProperties);\n\n return object;\n },\n\n /**\n * Realises an object's group transformation on it\n * @private\n * @param {fabric.Object} [instance] the object to transform (gets mutated)\n * @returns the original values of instance which were changed\n */\n _realizeGroupTransformOnObject: function (instance) {\n if (instance.group && instance.group.type === 'activeSelection' && this._activeObject === instance.group) {\n var layoutProps = ['angle', 'flipX', 'flipY', 'left', 'scaleX', 'scaleY', 'skewX', 'skewY', 'top']; //Copy all the positionally relevant properties across now\n\n var originalValues = {};\n layoutProps.forEach(function (prop) {\n originalValues[prop] = instance[prop];\n });\n\n this._activeObject.realizeTransform(instance);\n\n return originalValues;\n } else {\n return null;\n }\n },\n\n /**\n * Restores the changed properties of instance\n * @private\n * @param {fabric.Object} [instance] the object to un-transform (gets mutated)\n * @param {Object} [originalValues] the original values of instance, as returned by _realizeGroupTransformOnObject\n */\n _unwindGroupTransformOnObject: function (instance, originalValues) {\n if (originalValues) {\n instance.set(originalValues);\n }\n },\n\n /**\n * @private\n */\n _setSVGObject: function (markup, instance, reviver) {\n //If the object is in a selection group, simulate what would happen to that\n //object when the group is deselected\n var originalProperties = this._realizeGroupTransformOnObject(instance);\n\n this.callSuper('_setSVGObject', markup, instance, reviver);\n\n this._unwindGroupTransformOnObject(instance, originalProperties);\n },\n setViewportTransform: function (vpt) {\n if (this.renderOnAddRemove && this._activeObject && this._activeObject.isEditing) {\n this._activeObject.clearContextTop();\n }\n\n fabric.StaticCanvas.prototype.setViewportTransform.call(this, vpt);\n }\n }); // copying static properties manually to work around Opera's bug,\n // where \"prototype\" property is enumerable and overrides existing prototype\n\n for (var prop in fabric.StaticCanvas) {\n if (prop !== 'prototype') {\n fabric.Canvas[prop] = fabric.StaticCanvas[prop];\n }\n }\n})();\n\n(function () {\n var addListener = fabric.util.addListener,\n removeListener = fabric.util.removeListener,\n RIGHT_CLICK = 3,\n MIDDLE_CLICK = 2,\n LEFT_CLICK = 1,\n addEventOptions = {\n passive: false\n };\n\n function checkClick(e, value) {\n return e.button && e.button === value - 1;\n }\n\n fabric.util.object.extend(fabric.Canvas.prototype,\n /** @lends fabric.Canvas.prototype */\n {\n /**\n * Contains the id of the touch event that owns the fabric transform\n * @type Number\n * @private\n */\n mainTouchId: null,\n\n /**\n * Adds mouse listeners to canvas\n * @private\n */\n _initEventListeners: function () {\n // in case we initialized the class twice. This should not happen normally\n // but in some kind of applications where the canvas element may be changed\n // this is a workaround to having double listeners.\n this.removeListeners();\n\n this._bindEvents();\n\n this.addOrRemove(addListener, 'add');\n },\n\n /**\n * return an event prefix pointer or mouse.\n * @private\n */\n _getEventPrefix: function () {\n return this.enablePointerEvents ? 'pointer' : 'mouse';\n },\n addOrRemove: function (functor, eventjsFunctor) {\n var canvasElement = this.upperCanvasEl,\n eventTypePrefix = this._getEventPrefix();\n\n functor(fabric.window, 'resize', this._onResize);\n functor(canvasElement, eventTypePrefix + 'down', this._onMouseDown);\n functor(canvasElement, eventTypePrefix + 'move', this._onMouseMove, addEventOptions);\n functor(canvasElement, eventTypePrefix + 'out', this._onMouseOut);\n functor(canvasElement, eventTypePrefix + 'enter', this._onMouseEnter);\n functor(canvasElement, 'wheel', this._onMouseWheel);\n functor(canvasElement, 'contextmenu', this._onContextMenu);\n functor(canvasElement, 'dblclick', this._onDoubleClick);\n functor(canvasElement, 'dragover', this._onDragOver);\n functor(canvasElement, 'dragenter', this._onDragEnter);\n functor(canvasElement, 'dragleave', this._onDragLeave);\n functor(canvasElement, 'drop', this._onDrop);\n\n if (!this.enablePointerEvents) {\n functor(canvasElement, 'touchstart', this._onTouchStart, addEventOptions);\n }\n\n if (typeof eventjs !== 'undefined' && eventjsFunctor in eventjs) {\n eventjs[eventjsFunctor](canvasElement, 'gesture', this._onGesture);\n eventjs[eventjsFunctor](canvasElement, 'drag', this._onDrag);\n eventjs[eventjsFunctor](canvasElement, 'orientation', this._onOrientationChange);\n eventjs[eventjsFunctor](canvasElement, 'shake', this._onShake);\n eventjs[eventjsFunctor](canvasElement, 'longpress', this._onLongPress);\n }\n },\n\n /**\n * Removes all event listeners\n */\n removeListeners: function () {\n this.addOrRemove(removeListener, 'remove'); // if you dispose on a mouseDown, before mouse up, you need to clean document to...\n\n var eventTypePrefix = this._getEventPrefix();\n\n removeListener(fabric.document, eventTypePrefix + 'up', this._onMouseUp);\n removeListener(fabric.document, 'touchend', this._onTouchEnd, addEventOptions);\n removeListener(fabric.document, eventTypePrefix + 'move', this._onMouseMove, addEventOptions);\n removeListener(fabric.document, 'touchmove', this._onMouseMove, addEventOptions);\n },\n\n /**\n * @private\n */\n _bindEvents: function () {\n if (this.eventsBound) {\n // for any reason we pass here twice we do not want to bind events twice.\n return;\n }\n\n this._onMouseDown = this._onMouseDown.bind(this);\n this._onTouchStart = this._onTouchStart.bind(this);\n this._onMouseMove = this._onMouseMove.bind(this);\n this._onMouseUp = this._onMouseUp.bind(this);\n this._onTouchEnd = this._onTouchEnd.bind(this);\n this._onResize = this._onResize.bind(this);\n this._onGesture = this._onGesture.bind(this);\n this._onDrag = this._onDrag.bind(this);\n this._onShake = this._onShake.bind(this);\n this._onLongPress = this._onLongPress.bind(this);\n this._onOrientationChange = this._onOrientationChange.bind(this);\n this._onMouseWheel = this._onMouseWheel.bind(this);\n this._onMouseOut = this._onMouseOut.bind(this);\n this._onMouseEnter = this._onMouseEnter.bind(this);\n this._onContextMenu = this._onContextMenu.bind(this);\n this._onDoubleClick = this._onDoubleClick.bind(this);\n this._onDragOver = this._onDragOver.bind(this);\n this._onDragEnter = this._simpleEventHandler.bind(this, 'dragenter');\n this._onDragLeave = this._simpleEventHandler.bind(this, 'dragleave');\n this._onDrop = this._simpleEventHandler.bind(this, 'drop');\n this.eventsBound = true;\n },\n\n /**\n * @private\n * @param {Event} [e] Event object fired on Event.js gesture\n * @param {Event} [self] Inner Event object\n */\n _onGesture: function (e, self) {\n this.__onTransformGesture && this.__onTransformGesture(e, self);\n },\n\n /**\n * @private\n * @param {Event} [e] Event object fired on Event.js drag\n * @param {Event} [self] Inner Event object\n */\n _onDrag: function (e, self) {\n this.__onDrag && this.__onDrag(e, self);\n },\n\n /**\n * @private\n * @param {Event} [e] Event object fired on wheel event\n */\n _onMouseWheel: function (e) {\n this.__onMouseWheel(e);\n },\n\n /**\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n _onMouseOut: function (e) {\n var target = this._hoveredTarget;\n this.fire('mouse:out', {\n target: target,\n e: e\n });\n this._hoveredTarget = null;\n target && target.fire('mouseout', {\n e: e\n });\n\n var _this = this;\n\n this._hoveredTargets.forEach(function (_target) {\n _this.fire('mouse:out', {\n target: target,\n e: e\n });\n\n _target && target.fire('mouseout', {\n e: e\n });\n });\n\n this._hoveredTargets = [];\n\n if (this._iTextInstances) {\n this._iTextInstances.forEach(function (obj) {\n if (obj.isEditing) {\n obj.hiddenTextarea.focus();\n }\n });\n }\n },\n\n /**\n * @private\n * @param {Event} e Event object fired on mouseenter\n */\n _onMouseEnter: function (e) {\n // This find target and consequent 'mouse:over' is used to\n // clear old instances on hovered target.\n // calling findTarget has the side effect of killing target.__corner.\n // as a short term fix we are not firing this if we are currently transforming.\n // as a long term fix we need to separate the action of finding a target with the\n // side effects we added to it.\n if (!this._currentTransform && !this.findTarget(e)) {\n this.fire('mouse:over', {\n target: null,\n e: e\n });\n this._hoveredTarget = null;\n this._hoveredTargets = [];\n }\n },\n\n /**\n * @private\n * @param {Event} [e] Event object fired on Event.js orientation change\n * @param {Event} [self] Inner Event object\n */\n _onOrientationChange: function (e, self) {\n this.__onOrientationChange && this.__onOrientationChange(e, self);\n },\n\n /**\n * @private\n * @param {Event} [e] Event object fired on Event.js shake\n * @param {Event} [self] Inner Event object\n */\n _onShake: function (e, self) {\n this.__onShake && this.__onShake(e, self);\n },\n\n /**\n * @private\n * @param {Event} [e] Event object fired on Event.js shake\n * @param {Event} [self] Inner Event object\n */\n _onLongPress: function (e, self) {\n this.__onLongPress && this.__onLongPress(e, self);\n },\n\n /**\n * prevent default to allow drop event to be fired\n * @private\n * @param {Event} [e] Event object fired on Event.js shake\n */\n _onDragOver: function (e) {\n e.preventDefault();\n\n var target = this._simpleEventHandler('dragover', e);\n\n this._fireEnterLeaveEvents(target, e);\n },\n\n /**\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n _onContextMenu: function (e) {\n if (this.stopContextMenu) {\n e.stopPropagation();\n e.preventDefault();\n }\n\n return false;\n },\n\n /**\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n _onDoubleClick: function (e) {\n this._cacheTransformEventData(e);\n\n this._handleEvent(e, 'dblclick');\n\n this._resetTransformEventData(e);\n },\n\n /**\n * Return a the id of an event.\n * returns either the pointerId or the identifier or 0 for the mouse event\n * @private\n * @param {Event} evt Event object\n */\n getPointerId: function (evt) {\n var changedTouches = evt.changedTouches;\n\n if (changedTouches) {\n return changedTouches[0] && changedTouches[0].identifier;\n }\n\n if (this.enablePointerEvents) {\n return evt.pointerId;\n }\n\n return -1;\n },\n\n /**\n * Determines if an event has the id of the event that is considered main\n * @private\n * @param {evt} event Event object\n */\n _isMainEvent: function (evt) {\n if (evt.isPrimary === true) {\n return true;\n }\n\n if (evt.isPrimary === false) {\n return false;\n }\n\n if (evt.type === 'touchend' && evt.touches.length === 0) {\n return true;\n }\n\n if (evt.changedTouches) {\n return evt.changedTouches[0].identifier === this.mainTouchId;\n }\n\n return true;\n },\n\n /**\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n _onTouchStart: function (e) {\n e.preventDefault();\n\n if (this.mainTouchId === null) {\n this.mainTouchId = this.getPointerId(e);\n }\n\n this.__onMouseDown(e);\n\n this._resetTransformEventData();\n\n var canvasElement = this.upperCanvasEl,\n eventTypePrefix = this._getEventPrefix();\n\n addListener(fabric.document, 'touchend', this._onTouchEnd, addEventOptions);\n addListener(fabric.document, 'touchmove', this._onMouseMove, addEventOptions); // Unbind mousedown to prevent double triggers from touch devices\n\n removeListener(canvasElement, eventTypePrefix + 'down', this._onMouseDown);\n },\n\n /**\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n _onMouseDown: function (e) {\n this.__onMouseDown(e);\n\n this._resetTransformEventData();\n\n var canvasElement = this.upperCanvasEl,\n eventTypePrefix = this._getEventPrefix();\n\n removeListener(canvasElement, eventTypePrefix + 'move', this._onMouseMove, addEventOptions);\n addListener(fabric.document, eventTypePrefix + 'up', this._onMouseUp);\n addListener(fabric.document, eventTypePrefix + 'move', this._onMouseMove, addEventOptions);\n },\n\n /**\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n _onTouchEnd: function (e) {\n if (e.touches.length > 0) {\n // if there are still touches stop here\n return;\n }\n\n this.__onMouseUp(e);\n\n this._resetTransformEventData();\n\n this.mainTouchId = null;\n\n var eventTypePrefix = this._getEventPrefix();\n\n removeListener(fabric.document, 'touchend', this._onTouchEnd, addEventOptions);\n removeListener(fabric.document, 'touchmove', this._onMouseMove, addEventOptions);\n\n var _this = this;\n\n if (this._willAddMouseDown) {\n clearTimeout(this._willAddMouseDown);\n }\n\n this._willAddMouseDown = setTimeout(function () {\n // Wait 400ms before rebinding mousedown to prevent double triggers\n // from touch devices\n addListener(_this.upperCanvasEl, eventTypePrefix + 'down', _this._onMouseDown);\n _this._willAddMouseDown = 0;\n }, 400);\n },\n\n /**\n * @private\n * @param {Event} e Event object fired on mouseup\n */\n _onMouseUp: function (e) {\n this.__onMouseUp(e);\n\n this._resetTransformEventData();\n\n var canvasElement = this.upperCanvasEl,\n eventTypePrefix = this._getEventPrefix();\n\n if (this._isMainEvent(e)) {\n removeListener(fabric.document, eventTypePrefix + 'up', this._onMouseUp);\n removeListener(fabric.document, eventTypePrefix + 'move', this._onMouseMove, addEventOptions);\n addListener(canvasElement, eventTypePrefix + 'move', this._onMouseMove, addEventOptions);\n }\n },\n\n /**\n * @private\n * @param {Event} e Event object fired on mousemove\n */\n _onMouseMove: function (e) {\n !this.allowTouchScrolling && e.preventDefault && e.preventDefault();\n\n this.__onMouseMove(e);\n },\n\n /**\n * @private\n */\n _onResize: function () {\n this.calcOffset();\n },\n\n /**\n * Decides whether the canvas should be redrawn in mouseup and mousedown events.\n * @private\n * @param {Object} target\n */\n _shouldRender: function (target) {\n var activeObject = this._activeObject;\n\n if (!!activeObject !== !!target || activeObject && target && activeObject !== target) {\n // this covers: switch of target, from target to no target, selection of target\n // multiSelection with key and mouse\n return true;\n } else if (activeObject && activeObject.isEditing) {\n // if we mouse up/down over a editing textbox a cursor change,\n // there is no need to re render\n return false;\n }\n\n return false;\n },\n\n /**\n * Method that defines the actions when mouse is released on canvas.\n * The method resets the currentTransform parameters, store the image corner\n * position in the image object and render the canvas on top.\n * @private\n * @param {Event} e Event object fired on mouseup\n */\n __onMouseUp: function (e) {\n var target,\n transform = this._currentTransform,\n groupSelector = this._groupSelector,\n shouldRender = false,\n isClick = !groupSelector || groupSelector.left === 0 && groupSelector.top === 0;\n\n this._cacheTransformEventData(e);\n\n target = this._target;\n\n this._handleEvent(e, 'up:before'); // if right/middle click just fire events and return\n // target undefined will make the _handleEvent search the target\n\n\n if (checkClick(e, RIGHT_CLICK)) {\n if (this.fireRightClick) {\n this._handleEvent(e, 'up', RIGHT_CLICK, isClick);\n }\n\n return;\n }\n\n if (checkClick(e, MIDDLE_CLICK)) {\n if (this.fireMiddleClick) {\n this._handleEvent(e, 'up', MIDDLE_CLICK, isClick);\n }\n\n this._resetTransformEventData();\n\n return;\n }\n\n if (this.isDrawingMode && this._isCurrentlyDrawing) {\n this._onMouseUpInDrawingMode(e);\n\n return;\n }\n\n if (!this._isMainEvent(e)) {\n return;\n }\n\n if (transform) {\n this._finalizeCurrentTransform(e);\n\n shouldRender = transform.actionPerformed;\n }\n\n if (!isClick) {\n var targetWasActive = target === this._activeObject;\n\n this._maybeGroupObjects(e);\n\n if (!shouldRender) {\n shouldRender = this._shouldRender(target) || !targetWasActive && target === this._activeObject;\n }\n }\n\n if (target) {\n var corner = target._findTargetCorner(this.getPointer(e, true), fabric.util.isTouchEvent(e));\n\n var control = target.controls[corner],\n mouseUpHandler = control && control.getMouseUpHandler(e, target, control);\n\n if (mouseUpHandler) {\n mouseUpHandler(e, target, control);\n }\n\n target.isMoving = false;\n }\n\n this._setCursorFromEvent(e, target);\n\n this._handleEvent(e, 'up', LEFT_CLICK, isClick);\n\n this._groupSelector = null;\n this._currentTransform = null; // reset the target information about which corner is selected\n\n target && (target.__corner = 0);\n\n if (shouldRender) {\n this.requestRenderAll();\n } else if (!isClick) {\n this.renderTop();\n }\n },\n\n /**\n * @private\n * Handle event firing for target and subtargets\n * @param {Event} e event from mouse\n * @param {String} eventType event to fire (up, down or move)\n * @return {Fabric.Object} target return the the target found, for internal reasons.\n */\n _simpleEventHandler: function (eventType, e) {\n var target = this.findTarget(e),\n targets = this.targets,\n options = {\n e: e,\n target: target,\n subTargets: targets\n };\n this.fire(eventType, options);\n target && target.fire(eventType, options);\n\n if (!targets) {\n return target;\n }\n\n for (var i = 0; i < targets.length; i++) {\n targets[i].fire(eventType, options);\n }\n\n return target;\n },\n\n /**\n * @private\n * Handle event firing for target and subtargets\n * @param {Event} e event from mouse\n * @param {String} eventType event to fire (up, down or move)\n * @param {fabric.Object} targetObj receiving event\n * @param {Number} [button] button used in the event 1 = left, 2 = middle, 3 = right\n * @param {Boolean} isClick for left button only, indicates that the mouse up happened without move.\n */\n _handleEvent: function (e, eventType, button, isClick) {\n var target = this._target,\n targets = this.targets || [],\n options = {\n e: e,\n target: target,\n subTargets: targets,\n button: button || LEFT_CLICK,\n isClick: isClick || false,\n pointer: this._pointer,\n absolutePointer: this._absolutePointer,\n transform: this._currentTransform\n };\n\n if (eventType === 'up') {\n options.currentTarget = this.findTarget(e);\n options.currentSubTargets = this.targets;\n }\n\n this.fire('mouse:' + eventType, options);\n target && target.fire('mouse' + eventType, options);\n\n for (var i = 0; i < targets.length; i++) {\n targets[i].fire('mouse' + eventType, options);\n }\n },\n\n /**\n * @private\n * @param {Event} e send the mouse event that generate the finalize down, so it can be used in the event\n */\n _finalizeCurrentTransform: function (e) {\n var transform = this._currentTransform,\n target = transform.target,\n eventName,\n options = {\n e: e,\n target: target,\n transform: transform,\n action: transform.action\n };\n\n if (target._scaling) {\n target._scaling = false;\n }\n\n target.setCoords();\n\n if (transform.actionPerformed || this.stateful && target.hasStateChanged()) {\n if (transform.actionPerformed) {\n // this is not friendly to the new control api.\n // is deprecated.\n eventName = this._addEventOptions(options, transform);\n\n this._fire(eventName, options);\n }\n\n this._fire('modified', options);\n }\n },\n\n /**\n * Mutate option object in order to add by property and give back the event name.\n * @private\n * @deprecated since 4.2.0\n * @param {Object} options to mutate\n * @param {Object} transform to inspect action from\n */\n _addEventOptions: function (options, transform) {\n // we can probably add more details at low cost\n // scale change, rotation changes, translation changes\n var eventName, by;\n\n switch (transform.action) {\n case 'scaleX':\n eventName = 'scaled';\n by = 'x';\n break;\n\n case 'scaleY':\n eventName = 'scaled';\n by = 'y';\n break;\n\n case 'skewX':\n eventName = 'skewed';\n by = 'x';\n break;\n\n case 'skewY':\n eventName = 'skewed';\n by = 'y';\n break;\n\n case 'scale':\n eventName = 'scaled';\n by = 'equally';\n break;\n\n case 'rotate':\n eventName = 'rotated';\n break;\n\n case 'drag':\n eventName = 'moved';\n break;\n }\n\n options.by = by;\n return eventName;\n },\n\n /**\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n _onMouseDownInDrawingMode: function (e) {\n this._isCurrentlyDrawing = true;\n\n if (this.getActiveObject()) {\n this.discardActiveObject(e).requestRenderAll();\n }\n\n var pointer = this.getPointer(e);\n this.freeDrawingBrush.onMouseDown(pointer, {\n e: e,\n pointer: pointer\n });\n\n this._handleEvent(e, 'down');\n },\n\n /**\n * @private\n * @param {Event} e Event object fired on mousemove\n */\n _onMouseMoveInDrawingMode: function (e) {\n if (this._isCurrentlyDrawing) {\n var pointer = this.getPointer(e);\n this.freeDrawingBrush.onMouseMove(pointer, {\n e: e,\n pointer: pointer\n });\n }\n\n this.setCursor(this.freeDrawingCursor);\n\n this._handleEvent(e, 'move');\n },\n\n /**\n * @private\n * @param {Event} e Event object fired on mouseup\n */\n _onMouseUpInDrawingMode: function (e) {\n var pointer = this.getPointer(e);\n this._isCurrentlyDrawing = this.freeDrawingBrush.onMouseUp({\n e: e,\n pointer: pointer\n });\n\n this._handleEvent(e, 'up');\n },\n\n /**\n * Method that defines the actions when mouse is clicked on canvas.\n * The method inits the currentTransform parameters and renders all the\n * canvas so the current image can be placed on the top canvas and the rest\n * in on the container one.\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n __onMouseDown: function (e) {\n this._cacheTransformEventData(e);\n\n this._handleEvent(e, 'down:before');\n\n var target = this._target; // if right click just fire events\n\n if (checkClick(e, RIGHT_CLICK)) {\n if (this.fireRightClick) {\n this._handleEvent(e, 'down', RIGHT_CLICK);\n }\n\n return;\n }\n\n if (checkClick(e, MIDDLE_CLICK)) {\n if (this.fireMiddleClick) {\n this._handleEvent(e, 'down', MIDDLE_CLICK);\n }\n\n return;\n }\n\n if (this.isDrawingMode) {\n this._onMouseDownInDrawingMode(e);\n\n return;\n }\n\n if (!this._isMainEvent(e)) {\n return;\n } // ignore if some object is being transformed at this moment\n\n\n if (this._currentTransform) {\n return;\n }\n\n var pointer = this._pointer; // save pointer for check in __onMouseUp event\n\n this._previousPointer = pointer;\n\n var shouldRender = this._shouldRender(target),\n shouldGroup = this._shouldGroup(e, target);\n\n if (this._shouldClearSelection(e, target)) {\n this.discardActiveObject(e);\n } else if (shouldGroup) {\n this._handleGrouping(e, target);\n\n target = this._activeObject;\n }\n\n if (this.selection && (!target || !target.selectable && !target.isEditing && target !== this._activeObject)) {\n this._groupSelector = {\n ex: pointer.x,\n ey: pointer.y,\n top: 0,\n left: 0\n };\n }\n\n if (target) {\n var alreadySelected = target === this._activeObject;\n\n if (target.selectable) {\n this.setActiveObject(target, e);\n }\n\n var corner = target._findTargetCorner(this.getPointer(e, true), fabric.util.isTouchEvent(e));\n\n target.__corner = corner;\n\n if (target === this._activeObject && (corner || !shouldGroup)) {\n var control = target.controls[corner],\n mouseDownHandler = control && control.getMouseDownHandler(e, target, control);\n\n if (mouseDownHandler) {\n mouseDownHandler(e, target, control);\n }\n\n this._setupCurrentTransform(e, target, alreadySelected);\n }\n }\n\n this._handleEvent(e, 'down'); // we must renderAll so that we update the visuals\n\n\n (shouldRender || shouldGroup) && this.requestRenderAll();\n },\n\n /**\n * reset cache form common information needed during event processing\n * @private\n */\n _resetTransformEventData: function () {\n this._target = null;\n this._pointer = null;\n this._absolutePointer = null;\n },\n\n /**\n * Cache common information needed during event processing\n * @private\n * @param {Event} e Event object fired on event\n */\n _cacheTransformEventData: function (e) {\n // reset in order to avoid stale caching\n this._resetTransformEventData();\n\n this._pointer = this.getPointer(e, true);\n this._absolutePointer = this.restorePointerVpt(this._pointer);\n this._target = this._currentTransform ? this._currentTransform.target : this.findTarget(e) || null;\n },\n\n /**\n * @private\n */\n _beforeTransform: function (e) {\n var t = this._currentTransform;\n this.stateful && t.target.saveState();\n this.fire('before:transform', {\n e: e,\n transform: t\n });\n },\n\n /**\n * Method that defines the actions when mouse is hovering the canvas.\n * The currentTransform parameter will define whether the user is rotating/scaling/translating\n * an image or neither of them (only hovering). A group selection is also possible and would cancel\n * all any other type of action.\n * In case of an image transformation only the top canvas will be rendered.\n * @private\n * @param {Event} e Event object fired on mousemove\n */\n __onMouseMove: function (e) {\n this._handleEvent(e, 'move:before');\n\n this._cacheTransformEventData(e);\n\n var target, pointer;\n\n if (this.isDrawingMode) {\n this._onMouseMoveInDrawingMode(e);\n\n return;\n }\n\n if (!this._isMainEvent(e)) {\n return;\n }\n\n var groupSelector = this._groupSelector; // We initially clicked in an empty area, so we draw a box for multiple selection\n\n if (groupSelector) {\n pointer = this._pointer;\n groupSelector.left = pointer.x - groupSelector.ex;\n groupSelector.top = pointer.y - groupSelector.ey;\n this.renderTop();\n } else if (!this._currentTransform) {\n target = this.findTarget(e) || null;\n\n this._setCursorFromEvent(e, target);\n\n this._fireOverOutEvents(target, e);\n } else {\n this._transformObject(e);\n }\n\n this._handleEvent(e, 'move');\n\n this._resetTransformEventData();\n },\n\n /**\n * Manage the mouseout, mouseover events for the fabric object on the canvas\n * @param {Fabric.Object} target the target where the target from the mousemove event\n * @param {Event} e Event object fired on mousemove\n * @private\n */\n _fireOverOutEvents: function (target, e) {\n var _hoveredTarget = this._hoveredTarget,\n _hoveredTargets = this._hoveredTargets,\n targets = this.targets,\n length = Math.max(_hoveredTargets.length, targets.length);\n this.fireSyntheticInOutEvents(target, e, {\n oldTarget: _hoveredTarget,\n evtOut: 'mouseout',\n canvasEvtOut: 'mouse:out',\n evtIn: 'mouseover',\n canvasEvtIn: 'mouse:over'\n });\n\n for (var i = 0; i < length; i++) {\n this.fireSyntheticInOutEvents(targets[i], e, {\n oldTarget: _hoveredTargets[i],\n evtOut: 'mouseout',\n evtIn: 'mouseover'\n });\n }\n\n this._hoveredTarget = target;\n this._hoveredTargets = this.targets.concat();\n },\n\n /**\n * Manage the dragEnter, dragLeave events for the fabric objects on the canvas\n * @param {Fabric.Object} target the target where the target from the onDrag event\n * @param {Event} e Event object fired on ondrag\n * @private\n */\n _fireEnterLeaveEvents: function (target, e) {\n var _draggedoverTarget = this._draggedoverTarget,\n _hoveredTargets = this._hoveredTargets,\n targets = this.targets,\n length = Math.max(_hoveredTargets.length, targets.length);\n this.fireSyntheticInOutEvents(target, e, {\n oldTarget: _draggedoverTarget,\n evtOut: 'dragleave',\n evtIn: 'dragenter'\n });\n\n for (var i = 0; i < length; i++) {\n this.fireSyntheticInOutEvents(targets[i], e, {\n oldTarget: _hoveredTargets[i],\n evtOut: 'dragleave',\n evtIn: 'dragenter'\n });\n }\n\n this._draggedoverTarget = target;\n },\n\n /**\n * Manage the synthetic in/out events for the fabric objects on the canvas\n * @param {Fabric.Object} target the target where the target from the supported events\n * @param {Event} e Event object fired\n * @param {Object} config configuration for the function to work\n * @param {String} config.targetName property on the canvas where the old target is stored\n * @param {String} [config.canvasEvtOut] name of the event to fire at canvas level for out\n * @param {String} config.evtOut name of the event to fire for out\n * @param {String} [config.canvasEvtIn] name of the event to fire at canvas level for in\n * @param {String} config.evtIn name of the event to fire for in\n * @private\n */\n fireSyntheticInOutEvents: function (target, e, config) {\n var inOpt,\n outOpt,\n oldTarget = config.oldTarget,\n outFires,\n inFires,\n targetChanged = oldTarget !== target,\n canvasEvtIn = config.canvasEvtIn,\n canvasEvtOut = config.canvasEvtOut;\n\n if (targetChanged) {\n inOpt = {\n e: e,\n target: target,\n previousTarget: oldTarget\n };\n outOpt = {\n e: e,\n target: oldTarget,\n nextTarget: target\n };\n }\n\n inFires = target && targetChanged;\n outFires = oldTarget && targetChanged;\n\n if (outFires) {\n canvasEvtOut && this.fire(canvasEvtOut, outOpt);\n oldTarget.fire(config.evtOut, outOpt);\n }\n\n if (inFires) {\n canvasEvtIn && this.fire(canvasEvtIn, inOpt);\n target.fire(config.evtIn, inOpt);\n }\n },\n\n /**\n * Method that defines actions when an Event Mouse Wheel\n * @param {Event} e Event object fired on mouseup\n */\n __onMouseWheel: function (e) {\n this._cacheTransformEventData(e);\n\n this._handleEvent(e, 'wheel');\n\n this._resetTransformEventData();\n },\n\n /**\n * @private\n * @param {Event} e Event fired on mousemove\n */\n _transformObject: function (e) {\n var pointer = this.getPointer(e),\n transform = this._currentTransform;\n transform.reset = false;\n transform.target.isMoving = true;\n transform.shiftKey = e.shiftKey;\n transform.altKey = e[this.centeredKey];\n\n this._performTransformAction(e, transform, pointer);\n\n transform.actionPerformed && this.requestRenderAll();\n },\n\n /**\n * @private\n */\n _performTransformAction: function (e, transform, pointer) {\n var x = pointer.x,\n y = pointer.y,\n action = transform.action,\n actionPerformed = false,\n actionHandler = transform.actionHandler; // this object could be created from the function in the control handlers\n\n if (actionHandler) {\n actionPerformed = actionHandler(e, transform, x, y);\n }\n\n if (action === 'drag' && actionPerformed) {\n this.setCursor(transform.target.moveCursor || this.moveCursor);\n }\n\n transform.actionPerformed = transform.actionPerformed || actionPerformed;\n },\n\n /**\n * @private\n */\n _fire: fabric.controlsUtils.fireEvent,\n\n /**\n * Sets the cursor depending on where the canvas is being hovered.\n * Note: very buggy in Opera\n * @param {Event} e Event object\n * @param {Object} target Object that the mouse is hovering, if so.\n */\n _setCursorFromEvent: function (e, target) {\n if (!target) {\n this.setCursor(this.defaultCursor);\n return false;\n }\n\n var hoverCursor = target.hoverCursor || this.hoverCursor,\n activeSelection = this._activeObject && this._activeObject.type === 'activeSelection' ? this._activeObject : null,\n // only show proper corner when group selection is not active\n corner = (!activeSelection || !activeSelection.contains(target)) && // here we call findTargetCorner always with undefined for the touch parameter.\n // we assume that if you are using a cursor you do not need to interact with\n // the bigger touch area.\n target._findTargetCorner(this.getPointer(e, true));\n\n if (!corner) {\n if (target.subTargetCheck) {\n // hoverCursor should come from top-most subTarget,\n // so we walk the array backwards\n this.targets.concat().reverse().map(function (_target) {\n hoverCursor = _target.hoverCursor || hoverCursor;\n });\n }\n\n this.setCursor(hoverCursor);\n } else {\n this.setCursor(this.getCornerCursor(corner, target, e));\n }\n },\n\n /**\n * @private\n */\n getCornerCursor: function (corner, target, e) {\n var control = target.controls[corner];\n return control.cursorStyleHandler(e, control, target);\n }\n });\n})();\n\n(function () {\n var min = Math.min,\n max = Math.max;\n fabric.util.object.extend(fabric.Canvas.prototype,\n /** @lends fabric.Canvas.prototype */\n {\n /**\n * @private\n * @param {Event} e Event object\n * @param {fabric.Object} target\n * @return {Boolean}\n */\n _shouldGroup: function (e, target) {\n var activeObject = this._activeObject;\n return activeObject && this._isSelectionKeyPressed(e) && target && target.selectable && this.selection && (activeObject !== target || activeObject.type === 'activeSelection') && !target.onSelect({\n e: e\n });\n },\n\n /**\n * @private\n * @param {Event} e Event object\n * @param {fabric.Object} target\n */\n _handleGrouping: function (e, target) {\n var activeObject = this._activeObject; // avoid multi select when shift click on a corner\n\n if (activeObject.__corner) {\n return;\n }\n\n if (target === activeObject) {\n // if it's a group, find target again, using activeGroup objects\n target = this.findTarget(e, true); // if even object is not found or we are on activeObjectCorner, bail out\n\n if (!target || !target.selectable) {\n return;\n }\n }\n\n if (activeObject && activeObject.type === 'activeSelection') {\n this._updateActiveSelection(target, e);\n } else {\n this._createActiveSelection(target, e);\n }\n },\n\n /**\n * @private\n */\n _updateActiveSelection: function (target, e) {\n var activeSelection = this._activeObject,\n currentActiveObjects = activeSelection._objects.slice(0);\n\n if (activeSelection.contains(target)) {\n activeSelection.removeWithUpdate(target);\n this._hoveredTarget = target;\n this._hoveredTargets = this.targets.concat();\n\n if (activeSelection.size() === 1) {\n // activate last remaining object\n this._setActiveObject(activeSelection.item(0), e);\n }\n } else {\n activeSelection.addWithUpdate(target);\n this._hoveredTarget = activeSelection;\n this._hoveredTargets = this.targets.concat();\n }\n\n this._fireSelectionEvents(currentActiveObjects, e);\n },\n\n /**\n * @private\n */\n _createActiveSelection: function (target, e) {\n var currentActives = this.getActiveObjects(),\n group = this._createGroup(target);\n\n this._hoveredTarget = group; // ISSUE 4115: should we consider subTargets here?\n // this._hoveredTargets = [];\n // this._hoveredTargets = this.targets.concat();\n\n this._setActiveObject(group, e);\n\n this._fireSelectionEvents(currentActives, e);\n },\n\n /**\n * @private\n * @param {Object} target\n */\n _createGroup: function (target) {\n var objects = this._objects,\n isActiveLower = objects.indexOf(this._activeObject) < objects.indexOf(target),\n groupObjects = isActiveLower ? [this._activeObject, target] : [target, this._activeObject];\n this._activeObject.isEditing && this._activeObject.exitEditing();\n return new fabric.ActiveSelection(groupObjects, {\n canvas: this\n });\n },\n\n /**\n * @private\n * @param {Event} e mouse event\n */\n _groupSelectedObjects: function (e) {\n var group = this._collectObjects(e),\n aGroup; // do not create group for 1 element only\n\n\n if (group.length === 1) {\n this.setActiveObject(group[0], e);\n } else if (group.length > 1) {\n aGroup = new fabric.ActiveSelection(group.reverse(), {\n canvas: this\n });\n this.setActiveObject(aGroup, e);\n }\n },\n\n /**\n * @private\n */\n _collectObjects: function (e) {\n var group = [],\n currentObject,\n x1 = this._groupSelector.ex,\n y1 = this._groupSelector.ey,\n x2 = x1 + this._groupSelector.left,\n y2 = y1 + this._groupSelector.top,\n selectionX1Y1 = new fabric.Point(min(x1, x2), min(y1, y2)),\n selectionX2Y2 = new fabric.Point(max(x1, x2), max(y1, y2)),\n allowIntersect = !this.selectionFullyContained,\n isClick = x1 === x2 && y1 === y2; // we iterate reverse order to collect top first in case of click.\n\n for (var i = this._objects.length; i--;) {\n currentObject = this._objects[i];\n\n if (!currentObject || !currentObject.selectable || !currentObject.visible) {\n continue;\n }\n\n if (allowIntersect && currentObject.intersectsWithRect(selectionX1Y1, selectionX2Y2) || currentObject.isContainedWithinRect(selectionX1Y1, selectionX2Y2) || allowIntersect && currentObject.containsPoint(selectionX1Y1) || allowIntersect && currentObject.containsPoint(selectionX2Y2)) {\n group.push(currentObject); // only add one object if it's a click\n\n if (isClick) {\n break;\n }\n }\n }\n\n if (group.length > 1) {\n group = group.filter(function (object) {\n return !object.onSelect({\n e: e\n });\n });\n }\n\n return group;\n },\n\n /**\n * @private\n */\n _maybeGroupObjects: function (e) {\n if (this.selection && this._groupSelector) {\n this._groupSelectedObjects(e);\n }\n\n this.setCursor(this.defaultCursor); // clear selection and current transformation\n\n this._groupSelector = null;\n }\n });\n})();\n\n(function () {\n fabric.util.object.extend(fabric.StaticCanvas.prototype,\n /** @lends fabric.StaticCanvas.prototype */\n {\n /**\n * Exports canvas element to a dataurl image. Note that when multiplier is used, cropping is scaled appropriately\n * @param {Object} [options] Options object\n * @param {String} [options.format=png] The format of the output image. Either \"jpeg\" or \"png\"\n * @param {Number} [options.quality=1] Quality level (0..1). Only used for jpeg.\n * @param {Number} [options.multiplier=1] Multiplier to scale by, to have consistent\n * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14\n * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14\n * @param {Number} [options.width] Cropping width. Introduced in v1.2.14\n * @param {Number} [options.height] Cropping height. Introduced in v1.2.14\n * @param {Boolean} [options.enableRetinaScaling] Enable retina scaling for clone image. Introduce in 2.0.0\n * @return {String} Returns a data: URL containing a representation of the object in the format specified by options.format\n * @see {@link http://jsfiddle.net/fabricjs/NfZVb/|jsFiddle demo}\n * @example <caption>Generate jpeg dataURL with lower quality</caption>\n * var dataURL = canvas.toDataURL({\n * format: 'jpeg',\n * quality: 0.8\n * });\n * @example <caption>Generate cropped png dataURL (clipping of canvas)</caption>\n * var dataURL = canvas.toDataURL({\n * format: 'png',\n * left: 100,\n * top: 100,\n * width: 200,\n * height: 200\n * });\n * @example <caption>Generate double scaled png dataURL</caption>\n * var dataURL = canvas.toDataURL({\n * format: 'png',\n * multiplier: 2\n * });\n */\n toDataURL: function (options) {\n options || (options = {});\n var format = options.format || 'png',\n quality = options.quality || 1,\n multiplier = (options.multiplier || 1) * (options.enableRetinaScaling ? this.getRetinaScaling() : 1),\n canvasEl = this.toCanvasElement(multiplier, options);\n return fabric.util.toDataURL(canvasEl, format, quality);\n },\n\n /**\n * Create a new HTMLCanvas element painted with the current canvas content.\n * No need to resize the actual one or repaint it.\n * Will transfer object ownership to a new canvas, paint it, and set everything back.\n * This is an intermediary step used to get to a dataUrl but also it is useful to\n * create quick image copies of a canvas without passing for the dataUrl string\n * @param {Number} [multiplier] a zoom factor.\n * @param {Object} [cropping] Cropping informations\n * @param {Number} [cropping.left] Cropping left offset.\n * @param {Number} [cropping.top] Cropping top offset.\n * @param {Number} [cropping.width] Cropping width.\n * @param {Number} [cropping.height] Cropping height.\n */\n toCanvasElement: function (multiplier, cropping) {\n multiplier = multiplier || 1;\n cropping = cropping || {};\n var scaledWidth = (cropping.width || this.width) * multiplier,\n scaledHeight = (cropping.height || this.height) * multiplier,\n zoom = this.getZoom(),\n originalWidth = this.width,\n originalHeight = this.height,\n newZoom = zoom * multiplier,\n vp = this.viewportTransform,\n translateX = (vp[4] - (cropping.left || 0)) * multiplier,\n translateY = (vp[5] - (cropping.top || 0)) * multiplier,\n originalInteractive = this.interactive,\n newVp = [newZoom, 0, 0, newZoom, translateX, translateY],\n originalRetina = this.enableRetinaScaling,\n canvasEl = fabric.util.createCanvasElement(),\n originalContextTop = this.contextTop;\n canvasEl.width = scaledWidth;\n canvasEl.height = scaledHeight;\n this.contextTop = null;\n this.enableRetinaScaling = false;\n this.interactive = false;\n this.viewportTransform = newVp;\n this.width = scaledWidth;\n this.height = scaledHeight;\n this.calcViewportBoundaries();\n this.renderCanvas(canvasEl.getContext('2d'), this._objects);\n this.viewportTransform = vp;\n this.width = originalWidth;\n this.height = originalHeight;\n this.calcViewportBoundaries();\n this.interactive = originalInteractive;\n this.enableRetinaScaling = originalRetina;\n this.contextTop = originalContextTop;\n return canvasEl;\n }\n });\n})();\n\nfabric.util.object.extend(fabric.StaticCanvas.prototype,\n/** @lends fabric.StaticCanvas.prototype */\n{\n /**\n * Populates canvas with data from the specified JSON.\n * JSON format must conform to the one of {@link fabric.Canvas#toJSON}\n * @param {String|Object} json JSON string or object\n * @param {Function} callback Callback, invoked when json is parsed\n * and corresponding objects (e.g: {@link fabric.Image})\n * are initialized\n * @param {Function} [reviver] Method for further parsing of JSON elements, called after each fabric object created.\n * @return {fabric.Canvas} instance\n * @chainable\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#deserialization}\n * @see {@link http://jsfiddle.net/fabricjs/fmgXt/|jsFiddle demo}\n * @example <caption>loadFromJSON</caption>\n * canvas.loadFromJSON(json, canvas.renderAll.bind(canvas));\n * @example <caption>loadFromJSON with reviver</caption>\n * canvas.loadFromJSON(json, canvas.renderAll.bind(canvas), function(o, object) {\n * // `o` = json object\n * // `object` = fabric.Object instance\n * // ... do some stuff ...\n * });\n */\n loadFromJSON: function (json, callback, reviver) {\n if (!json) {\n return;\n } // serialize if it wasn't already\n\n\n var serialized = typeof json === 'string' ? JSON.parse(json) : fabric.util.object.clone(json);\n\n var _this = this,\n clipPath = serialized.clipPath,\n renderOnAddRemove = this.renderOnAddRemove;\n\n this.renderOnAddRemove = false;\n delete serialized.clipPath;\n\n this._enlivenObjects(serialized.objects, function (enlivenedObjects) {\n _this.clear();\n\n _this._setBgOverlay(serialized, function () {\n if (clipPath) {\n _this._enlivenObjects([clipPath], function (enlivenedCanvasClip) {\n _this.clipPath = enlivenedCanvasClip[0];\n\n _this.__setupCanvas.call(_this, serialized, enlivenedObjects, renderOnAddRemove, callback);\n });\n } else {\n _this.__setupCanvas.call(_this, serialized, enlivenedObjects, renderOnAddRemove, callback);\n }\n });\n }, reviver);\n\n return this;\n },\n\n /**\n * @private\n * @param {Object} serialized Object with background and overlay information\n * @param {Array} restored canvas objects\n * @param {Function} cached renderOnAddRemove callback\n * @param {Function} callback Invoked after all background and overlay images/patterns loaded\n */\n __setupCanvas: function (serialized, enlivenedObjects, renderOnAddRemove, callback) {\n var _this = this;\n\n enlivenedObjects.forEach(function (obj, index) {\n // we splice the array just in case some custom classes restored from JSON\n // will add more object to canvas at canvas init.\n _this.insertAt(obj, index);\n });\n this.renderOnAddRemove = renderOnAddRemove; // remove parts i cannot set as options\n\n delete serialized.objects;\n delete serialized.backgroundImage;\n delete serialized.overlayImage;\n delete serialized.background;\n delete serialized.overlay; // this._initOptions does too many things to just\n // call it. Normally loading an Object from JSON\n // create the Object instance. Here the Canvas is\n // already an instance and we are just loading things over it\n\n this._setOptions(serialized);\n\n this.renderAll();\n callback && callback();\n },\n\n /**\n * @private\n * @param {Object} serialized Object with background and overlay information\n * @param {Function} callback Invoked after all background and overlay images/patterns loaded\n */\n _setBgOverlay: function (serialized, callback) {\n var loaded = {\n backgroundColor: false,\n overlayColor: false,\n backgroundImage: false,\n overlayImage: false\n };\n\n if (!serialized.backgroundImage && !serialized.overlayImage && !serialized.background && !serialized.overlay) {\n callback && callback();\n return;\n }\n\n var cbIfLoaded = function () {\n if (loaded.backgroundImage && loaded.overlayImage && loaded.backgroundColor && loaded.overlayColor) {\n callback && callback();\n }\n };\n\n this.__setBgOverlay('backgroundImage', serialized.backgroundImage, loaded, cbIfLoaded);\n\n this.__setBgOverlay('overlayImage', serialized.overlayImage, loaded, cbIfLoaded);\n\n this.__setBgOverlay('backgroundColor', serialized.background, loaded, cbIfLoaded);\n\n this.__setBgOverlay('overlayColor', serialized.overlay, loaded, cbIfLoaded);\n },\n\n /**\n * @private\n * @param {String} property Property to set (backgroundImage, overlayImage, backgroundColor, overlayColor)\n * @param {(Object|String)} value Value to set\n * @param {Object} loaded Set loaded property to true if property is set\n * @param {Object} callback Callback function to invoke after property is set\n */\n __setBgOverlay: function (property, value, loaded, callback) {\n var _this = this;\n\n if (!value) {\n loaded[property] = true;\n callback && callback();\n return;\n }\n\n if (property === 'backgroundImage' || property === 'overlayImage') {\n fabric.util.enlivenObjects([value], function (enlivedObject) {\n _this[property] = enlivedObject[0];\n loaded[property] = true;\n callback && callback();\n });\n } else {\n this['set' + fabric.util.string.capitalize(property, true)](value, function () {\n loaded[property] = true;\n callback && callback();\n });\n }\n },\n\n /**\n * @private\n * @param {Array} objects\n * @param {Function} callback\n * @param {Function} [reviver]\n */\n _enlivenObjects: function (objects, callback, reviver) {\n if (!objects || objects.length === 0) {\n callback && callback([]);\n return;\n }\n\n fabric.util.enlivenObjects(objects, function (enlivenedObjects) {\n callback && callback(enlivenedObjects);\n }, null, reviver);\n },\n\n /**\n * @private\n * @param {String} format\n * @param {Function} callback\n */\n _toDataURL: function (format, callback) {\n this.clone(function (clone) {\n callback(clone.toDataURL(format));\n });\n },\n\n /**\n * @private\n * @param {String} format\n * @param {Number} multiplier\n * @param {Function} callback\n */\n _toDataURLWithMultiplier: function (format, multiplier, callback) {\n this.clone(function (clone) {\n callback(clone.toDataURLWithMultiplier(format, multiplier));\n });\n },\n\n /**\n * Clones canvas instance\n * @param {Object} [callback] Receives cloned instance as a first argument\n * @param {Array} [properties] Array of properties to include in the cloned canvas and children\n */\n clone: function (callback, properties) {\n var data = JSON.stringify(this.toJSON(properties));\n this.cloneWithoutData(function (clone) {\n clone.loadFromJSON(data, function () {\n callback && callback(clone);\n });\n });\n },\n\n /**\n * Clones canvas instance without cloning existing data.\n * This essentially copies canvas dimensions, clipping properties, etc.\n * but leaves data empty (so that you can populate it with your own)\n * @param {Object} [callback] Receives cloned instance as a first argument\n */\n cloneWithoutData: function (callback) {\n var el = fabric.util.createCanvasElement();\n el.width = this.width;\n el.height = this.height;\n var clone = new fabric.Canvas(el);\n\n if (this.backgroundImage) {\n clone.setBackgroundImage(this.backgroundImage.src, function () {\n clone.renderAll();\n callback && callback(clone);\n });\n clone.backgroundImageOpacity = this.backgroundImageOpacity;\n clone.backgroundImageStretch = this.backgroundImageStretch;\n } else {\n callback && callback(clone);\n }\n }\n});\n\n(function (global) {\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = {}),\n extend = fabric.util.object.extend,\n clone = fabric.util.object.clone,\n toFixed = fabric.util.toFixed,\n capitalize = fabric.util.string.capitalize,\n degreesToRadians = fabric.util.degreesToRadians,\n supportsLineDash = fabric.StaticCanvas.supports('setLineDash'),\n objectCaching = !fabric.isLikelyNode,\n ALIASING_LIMIT = 2;\n\n if (fabric.Object) {\n return;\n }\n /**\n * Root object class from which all 2d shape classes inherit from\n * @class fabric.Object\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#objects}\n * @see {@link fabric.Object#initialize} for constructor definition\n *\n * @fires added\n * @fires removed\n *\n * @fires selected\n * @fires deselected\n * @fires modified\n * @fires modified\n * @fires moved\n * @fires scaled\n * @fires rotated\n * @fires skewed\n *\n * @fires rotating\n * @fires scaling\n * @fires moving\n * @fires skewing\n *\n * @fires mousedown\n * @fires mouseup\n * @fires mouseover\n * @fires mouseout\n * @fires mousewheel\n * @fires mousedblclick\n *\n * @fires dragover\n * @fires dragenter\n * @fires dragleave\n * @fires drop\n */\n\n\n fabric.Object = fabric.util.createClass(fabric.CommonMethods,\n /** @lends fabric.Object.prototype */\n {\n /**\n * Type of an object (rect, circle, path, etc.).\n * Note that this property is meant to be read-only and not meant to be modified.\n * If you modify, certain parts of Fabric (such as JSON loading) won't work correctly.\n * @type String\n * @default\n */\n type: 'object',\n\n /**\n * Horizontal origin of transformation of an object (one of \"left\", \"right\", \"center\")\n * See http://jsfiddle.net/1ow02gea/244/ on how originX/originY affect objects in groups\n * @type String\n * @default\n */\n originX: 'left',\n\n /**\n * Vertical origin of transformation of an object (one of \"top\", \"bottom\", \"center\")\n * See http://jsfiddle.net/1ow02gea/244/ on how originX/originY affect objects in groups\n * @type String\n * @default\n */\n originY: 'top',\n\n /**\n * Top position of an object. Note that by default it's relative to object top. You can change this by setting originY={top/center/bottom}\n * @type Number\n * @default\n */\n top: 0,\n\n /**\n * Left position of an object. Note that by default it's relative to object left. You can change this by setting originX={left/center/right}\n * @type Number\n * @default\n */\n left: 0,\n\n /**\n * Object width\n * @type Number\n * @default\n */\n width: 0,\n\n /**\n * Object height\n * @type Number\n * @default\n */\n height: 0,\n\n /**\n * Object scale factor (horizontal)\n * @type Number\n * @default\n */\n scaleX: 1,\n\n /**\n * Object scale factor (vertical)\n * @type Number\n * @default\n */\n scaleY: 1,\n\n /**\n * When true, an object is rendered as flipped horizontally\n * @type Boolean\n * @default\n */\n flipX: false,\n\n /**\n * When true, an object is rendered as flipped vertically\n * @type Boolean\n * @default\n */\n flipY: false,\n\n /**\n * Opacity of an object\n * @type Number\n * @default\n */\n opacity: 1,\n\n /**\n * Angle of rotation of an object (in degrees)\n * @type Number\n * @default\n */\n angle: 0,\n\n /**\n * Angle of skew on x axes of an object (in degrees)\n * @type Number\n * @default\n */\n skewX: 0,\n\n /**\n * Angle of skew on y axes of an object (in degrees)\n * @type Number\n * @default\n */\n skewY: 0,\n\n /**\n * Size of object's controlling corners (in pixels)\n * @type Number\n * @default\n */\n cornerSize: 13,\n\n /**\n * Size of object's controlling corners when touch interaction is detected\n * @type Number\n * @default\n */\n touchCornerSize: 24,\n\n /**\n * When true, object's controlling corners are rendered as transparent inside (i.e. stroke instead of fill)\n * @type Boolean\n * @default\n */\n transparentCorners: true,\n\n /**\n * Default cursor value used when hovering over this object on canvas\n * @type String\n * @default\n */\n hoverCursor: null,\n\n /**\n * Default cursor value used when moving this object on canvas\n * @type String\n * @default\n */\n moveCursor: null,\n\n /**\n * Padding between object and its controlling borders (in pixels)\n * @type Number\n * @default\n */\n padding: 0,\n\n /**\n * Color of controlling borders of an object (when it's active)\n * @type String\n * @default\n */\n borderColor: 'rgb(178,204,255)',\n\n /**\n * Array specifying dash pattern of an object's borders (hasBorder must be true)\n * @since 1.6.2\n * @type Array\n */\n borderDashArray: null,\n\n /**\n * Color of controlling corners of an object (when it's active)\n * @type String\n * @default\n */\n cornerColor: 'rgb(178,204,255)',\n\n /**\n * Color of controlling corners of an object (when it's active and transparentCorners false)\n * @since 1.6.2\n * @type String\n * @default\n */\n cornerStrokeColor: null,\n\n /**\n * Specify style of control, 'rect' or 'circle'\n * @since 1.6.2\n * @type String\n */\n cornerStyle: 'rect',\n\n /**\n * Array specifying dash pattern of an object's control (hasBorder must be true)\n * @since 1.6.2\n * @type Array\n */\n cornerDashArray: null,\n\n /**\n * When true, this object will use center point as the origin of transformation\n * when being scaled via the controls.\n * <b>Backwards incompatibility note:</b> This property replaces \"centerTransform\" (Boolean).\n * @since 1.3.4\n * @type Boolean\n * @default\n */\n centeredScaling: false,\n\n /**\n * When true, this object will use center point as the origin of transformation\n * when being rotated via the controls.\n * <b>Backwards incompatibility note:</b> This property replaces \"centerTransform\" (Boolean).\n * @since 1.3.4\n * @type Boolean\n * @default\n */\n centeredRotation: true,\n\n /**\n * Color of object's fill\n * takes css colors https://www.w3.org/TR/css-color-3/\n * @type String\n * @default\n */\n fill: 'rgb(0,0,0)',\n\n /**\n * Fill rule used to fill an object\n * accepted values are nonzero, evenodd\n * <b>Backwards incompatibility note:</b> This property was used for setting globalCompositeOperation until v1.4.12 (use `fabric.Object#globalCompositeOperation` instead)\n * @type String\n * @default\n */\n fillRule: 'nonzero',\n\n /**\n * Composite rule used for canvas globalCompositeOperation\n * @type String\n * @default\n */\n globalCompositeOperation: 'source-over',\n\n /**\n * Background color of an object.\n * takes css colors https://www.w3.org/TR/css-color-3/\n * @type String\n * @default\n */\n backgroundColor: '',\n\n /**\n * Selection Background color of an object. colored layer behind the object when it is active.\n * does not mix good with globalCompositeOperation methods.\n * @type String\n * @default\n */\n selectionBackgroundColor: '',\n\n /**\n * When defined, an object is rendered via stroke and this property specifies its color\n * takes css colors https://www.w3.org/TR/css-color-3/\n * @type String\n * @default\n */\n stroke: null,\n\n /**\n * Width of a stroke used to render this object\n * @type Number\n * @default\n */\n strokeWidth: 1,\n\n /**\n * Array specifying dash pattern of an object's stroke (stroke must be defined)\n * @type Array\n */\n strokeDashArray: null,\n\n /**\n * Line offset of an object's stroke\n * @type Number\n * @default\n */\n strokeDashOffset: 0,\n\n /**\n * Line endings style of an object's stroke (one of \"butt\", \"round\", \"square\")\n * @type String\n * @default\n */\n strokeLineCap: 'butt',\n\n /**\n * Corner style of an object's stroke (one of \"bevil\", \"round\", \"miter\")\n * @type String\n * @default\n */\n strokeLineJoin: 'miter',\n\n /**\n * Maximum miter length (used for strokeLineJoin = \"miter\") of an object's stroke\n * @type Number\n * @default\n */\n strokeMiterLimit: 4,\n\n /**\n * Shadow object representing shadow of this shape\n * @type fabric.Shadow\n * @default\n */\n shadow: null,\n\n /**\n * Opacity of object's controlling borders when object is active and moving\n * @type Number\n * @default\n */\n borderOpacityWhenMoving: 0.4,\n\n /**\n * Scale factor of object's controlling borders\n * bigger number will make a thicker border\n * border is 1, so this is basically a border tickness\n * since there is no way to change the border itself.\n * @type Number\n * @default\n */\n borderScaleFactor: 1,\n\n /**\n * Minimum allowed scale value of an object\n * @type Number\n * @default\n */\n minScaleLimit: 0,\n\n /**\n * When set to `false`, an object can not be selected for modification (using either point-click-based or group-based selection).\n * But events still fire on it.\n * @type Boolean\n * @default\n */\n selectable: true,\n\n /**\n * When set to `false`, an object can not be a target of events. All events propagate through it. Introduced in v1.3.4\n * @type Boolean\n * @default\n */\n evented: true,\n\n /**\n * When set to `false`, an object is not rendered on canvas\n * @type Boolean\n * @default\n */\n visible: true,\n\n /**\n * When set to `false`, object's controls are not displayed and can not be used to manipulate object\n * @type Boolean\n * @default\n */\n hasControls: true,\n\n /**\n * When set to `false`, object's controlling borders are not rendered\n * @type Boolean\n * @default\n */\n hasBorders: true,\n\n /**\n * When set to `true`, objects are \"found\" on canvas on per-pixel basis rather than according to bounding box\n * @type Boolean\n * @default\n */\n perPixelTargetFind: false,\n\n /**\n * When `false`, default object's values are not included in its serialization\n * @type Boolean\n * @default\n */\n includeDefaultValues: true,\n\n /**\n * When `true`, object horizontal movement is locked\n * @type Boolean\n * @default\n */\n lockMovementX: false,\n\n /**\n * When `true`, object vertical movement is locked\n * @type Boolean\n * @default\n */\n lockMovementY: false,\n\n /**\n * When `true`, object rotation is locked\n * @type Boolean\n * @default\n */\n lockRotation: false,\n\n /**\n * When `true`, object horizontal scaling is locked\n * @type Boolean\n * @default\n */\n lockScalingX: false,\n\n /**\n * When `true`, object vertical scaling is locked\n * @type Boolean\n * @default\n */\n lockScalingY: false,\n\n /**\n * When `true`, object horizontal skewing is locked\n * @type Boolean\n * @default\n */\n lockSkewingX: false,\n\n /**\n * When `true`, object vertical skewing is locked\n * @type Boolean\n * @default\n */\n lockSkewingY: false,\n\n /**\n * When `true`, object cannot be flipped by scaling into negative values\n * @type Boolean\n * @default\n */\n lockScalingFlip: false,\n\n /**\n * When `true`, object is not exported in OBJECT/JSON\n * @since 1.6.3\n * @type Boolean\n * @default\n */\n excludeFromExport: false,\n\n /**\n * When `true`, object is cached on an additional canvas.\n * When `false`, object is not cached unless necessary ( clipPath )\n * default to true\n * @since 1.7.0\n * @type Boolean\n * @default true\n */\n objectCaching: objectCaching,\n\n /**\n * When `true`, object properties are checked for cache invalidation. In some particular\n * situation you may want this to be disabled ( spray brush, very big, groups)\n * or if your application does not allow you to modify properties for groups child you want\n * to disable it for groups.\n * default to false\n * since 1.7.0\n * @type Boolean\n * @default false\n */\n statefullCache: false,\n\n /**\n * When `true`, cache does not get updated during scaling. The picture will get blocky if scaled\n * too much and will be redrawn with correct details at the end of scaling.\n * this setting is performance and application dependant.\n * default to true\n * since 1.7.0\n * @type Boolean\n * @default true\n */\n noScaleCache: true,\n\n /**\n * When `false`, the stoke width will scale with the object.\n * When `true`, the stroke will always match the exact pixel size entered for stroke width.\n * default to false\n * @since 2.6.0\n * @type Boolean\n * @default false\n * @type Boolean\n * @default false\n */\n strokeUniform: false,\n\n /**\n * When set to `true`, object's cache will be rerendered next render call.\n * since 1.7.0\n * @type Boolean\n * @default true\n */\n dirty: true,\n\n /**\n * keeps the value of the last hovered corner during mouse move.\n * 0 is no corner, or 'mt', 'ml', 'mtr' etc..\n * It should be private, but there is no harm in using it as\n * a read-only property.\n * @type number|string|any\n * @default 0\n */\n __corner: 0,\n\n /**\n * Determines if the fill or the stroke is drawn first (one of \"fill\" or \"stroke\")\n * @type String\n * @default\n */\n paintFirst: 'fill',\n\n /**\n * List of properties to consider when checking if state\n * of an object is changed (fabric.Object#hasStateChanged)\n * as well as for history (undo/redo) purposes\n * @type Array\n */\n stateProperties: ('top left width height scaleX scaleY flipX flipY originX originY transformMatrix ' + 'stroke strokeWidth strokeDashArray strokeLineCap strokeDashOffset strokeLineJoin strokeMiterLimit ' + 'angle opacity fill globalCompositeOperation shadow visible backgroundColor ' + 'skewX skewY fillRule paintFirst clipPath strokeUniform').split(' '),\n\n /**\n * List of properties to consider when checking if cache needs refresh\n * Those properties are checked by statefullCache ON ( or lazy mode if we want ) or from single\n * calls to Object.set(key, value). If the key is in this list, the object is marked as dirty\n * and refreshed at the next render\n * @type Array\n */\n cacheProperties: ('fill stroke strokeWidth strokeDashArray width height paintFirst strokeUniform' + ' strokeLineCap strokeDashOffset strokeLineJoin strokeMiterLimit backgroundColor clipPath').split(' '),\n\n /**\n * List of properties to consider for animating colors.\n * @type Array\n */\n colorProperties: 'fill stroke backgroundColor'.split(' '),\n\n /**\n * a fabricObject that, without stroke define a clipping area with their shape. filled in black\n * the clipPath object gets used when the object has rendered, and the context is placed in the center\n * of the object cacheCanvas.\n * If you want 0,0 of a clipPath to align with an object center, use clipPath.originX/Y to 'center'\n * @type fabric.Object\n */\n clipPath: undefined,\n\n /**\n * Meaningful ONLY when the object is used as clipPath.\n * if true, the clipPath will make the object clip to the outside of the clipPath\n * since 2.4.0\n * @type boolean\n * @default false\n */\n inverted: false,\n\n /**\n * Meaningful ONLY when the object is used as clipPath.\n * if true, the clipPath will have its top and left relative to canvas, and will\n * not be influenced by the object transform. This will make the clipPath relative\n * to the canvas, but clipping just a particular object.\n * WARNING this is beta, this feature may change or be renamed.\n * since 2.4.0\n * @type boolean\n * @default false\n */\n absolutePositioned: false,\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n */\n initialize: function (options) {\n if (options) {\n this.setOptions(options);\n }\n },\n\n /**\n * Create a the canvas used to keep the cached copy of the object\n * @private\n */\n _createCacheCanvas: function () {\n this._cacheProperties = {};\n this._cacheCanvas = fabric.util.createCanvasElement();\n this._cacheContext = this._cacheCanvas.getContext('2d');\n\n this._updateCacheCanvas(); // if canvas gets created, is empty, so dirty.\n\n\n this.dirty = true;\n },\n\n /**\n * Limit the cache dimensions so that X * Y do not cross fabric.perfLimitSizeTotal\n * and each side do not cross fabric.cacheSideLimit\n * those numbers are configurable so that you can get as much detail as you want\n * making bargain with performances.\n * @param {Object} dims\n * @param {Object} dims.width width of canvas\n * @param {Object} dims.height height of canvas\n * @param {Object} dims.zoomX zoomX zoom value to unscale the canvas before drawing cache\n * @param {Object} dims.zoomY zoomY zoom value to unscale the canvas before drawing cache\n * @return {Object}.width width of canvas\n * @return {Object}.height height of canvas\n * @return {Object}.zoomX zoomX zoom value to unscale the canvas before drawing cache\n * @return {Object}.zoomY zoomY zoom value to unscale the canvas before drawing cache\n */\n _limitCacheSize: function (dims) {\n var perfLimitSizeTotal = fabric.perfLimitSizeTotal,\n width = dims.width,\n height = dims.height,\n max = fabric.maxCacheSideLimit,\n min = fabric.minCacheSideLimit;\n\n if (width <= max && height <= max && width * height <= perfLimitSizeTotal) {\n if (width < min) {\n dims.width = min;\n }\n\n if (height < min) {\n dims.height = min;\n }\n\n return dims;\n }\n\n var ar = width / height,\n limitedDims = fabric.util.limitDimsByArea(ar, perfLimitSizeTotal),\n capValue = fabric.util.capValue,\n x = capValue(min, limitedDims.x, max),\n y = capValue(min, limitedDims.y, max);\n\n if (width > x) {\n dims.zoomX /= width / x;\n dims.width = x;\n dims.capped = true;\n }\n\n if (height > y) {\n dims.zoomY /= height / y;\n dims.height = y;\n dims.capped = true;\n }\n\n return dims;\n },\n\n /**\n * Return the dimension and the zoom level needed to create a cache canvas\n * big enough to host the object to be cached.\n * @private\n * @return {Object}.x width of object to be cached\n * @return {Object}.y height of object to be cached\n * @return {Object}.width width of canvas\n * @return {Object}.height height of canvas\n * @return {Object}.zoomX zoomX zoom value to unscale the canvas before drawing cache\n * @return {Object}.zoomY zoomY zoom value to unscale the canvas before drawing cache\n */\n _getCacheCanvasDimensions: function () {\n var objectScale = this.getTotalObjectScaling(),\n // caculate dimensions without skewing\n dim = this._getTransformedDimensions(0, 0),\n neededX = dim.x * objectScale.scaleX / this.scaleX,\n neededY = dim.y * objectScale.scaleY / this.scaleY;\n\n return {\n // for sure this ALIASING_LIMIT is slightly creating problem\n // in situation in which the cache canvas gets an upper limit\n // also objectScale contains already scaleX and scaleY\n width: neededX + ALIASING_LIMIT,\n height: neededY + ALIASING_LIMIT,\n zoomX: objectScale.scaleX,\n zoomY: objectScale.scaleY,\n x: neededX,\n y: neededY\n };\n },\n\n /**\n * Update width and height of the canvas for cache\n * returns true or false if canvas needed resize.\n * @private\n * @return {Boolean} true if the canvas has been resized\n */\n _updateCacheCanvas: function () {\n var targetCanvas = this.canvas;\n\n if (this.noScaleCache && targetCanvas && targetCanvas._currentTransform) {\n var target = targetCanvas._currentTransform.target,\n action = targetCanvas._currentTransform.action;\n\n if (this === target && action.slice && action.slice(0, 5) === 'scale') {\n return false;\n }\n }\n\n var canvas = this._cacheCanvas,\n dims = this._limitCacheSize(this._getCacheCanvasDimensions()),\n minCacheSize = fabric.minCacheSideLimit,\n width = dims.width,\n height = dims.height,\n drawingWidth,\n drawingHeight,\n zoomX = dims.zoomX,\n zoomY = dims.zoomY,\n dimensionsChanged = width !== this.cacheWidth || height !== this.cacheHeight,\n zoomChanged = this.zoomX !== zoomX || this.zoomY !== zoomY,\n shouldRedraw = dimensionsChanged || zoomChanged,\n additionalWidth = 0,\n additionalHeight = 0,\n shouldResizeCanvas = false;\n\n if (dimensionsChanged) {\n var canvasWidth = this._cacheCanvas.width,\n canvasHeight = this._cacheCanvas.height,\n sizeGrowing = width > canvasWidth || height > canvasHeight,\n sizeShrinking = (width < canvasWidth * 0.9 || height < canvasHeight * 0.9) && canvasWidth > minCacheSize && canvasHeight > minCacheSize;\n shouldResizeCanvas = sizeGrowing || sizeShrinking;\n\n if (sizeGrowing && !dims.capped && (width > minCacheSize || height > minCacheSize)) {\n additionalWidth = width * 0.1;\n additionalHeight = height * 0.1;\n }\n }\n\n if (shouldRedraw) {\n if (shouldResizeCanvas) {\n canvas.width = Math.ceil(width + additionalWidth);\n canvas.height = Math.ceil(height + additionalHeight);\n } else {\n this._cacheContext.setTransform(1, 0, 0, 1, 0, 0);\n\n this._cacheContext.clearRect(0, 0, canvas.width, canvas.height);\n }\n\n drawingWidth = dims.x / 2;\n drawingHeight = dims.y / 2;\n this.cacheTranslationX = Math.round(canvas.width / 2 - drawingWidth) + drawingWidth;\n this.cacheTranslationY = Math.round(canvas.height / 2 - drawingHeight) + drawingHeight;\n this.cacheWidth = width;\n this.cacheHeight = height;\n\n this._cacheContext.translate(this.cacheTranslationX, this.cacheTranslationY);\n\n this._cacheContext.scale(zoomX, zoomY);\n\n this.zoomX = zoomX;\n this.zoomY = zoomY;\n return true;\n }\n\n return false;\n },\n\n /**\n * Sets object's properties from options\n * @param {Object} [options] Options object\n */\n setOptions: function (options) {\n this._setOptions(options);\n\n this._initGradient(options.fill, 'fill');\n\n this._initGradient(options.stroke, 'stroke');\n\n this._initPattern(options.fill, 'fill');\n\n this._initPattern(options.stroke, 'stroke');\n },\n\n /**\n * Transforms context when rendering an object\n * @param {CanvasRenderingContext2D} ctx Context\n */\n transform: function (ctx) {\n var needFullTransform = this.group && !this.group._transformDone || this.group && this.canvas && ctx === this.canvas.contextTop;\n var m = this.calcTransformMatrix(!needFullTransform);\n ctx.transform(m[0], m[1], m[2], m[3], m[4], m[5]);\n },\n\n /**\n * Returns an object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} Object representation of an instance\n */\n toObject: function (propertiesToInclude) {\n var NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS,\n object = {\n type: this.type,\n version: fabric.version,\n originX: this.originX,\n originY: this.originY,\n left: toFixed(this.left, NUM_FRACTION_DIGITS),\n top: toFixed(this.top, NUM_FRACTION_DIGITS),\n width: toFixed(this.width, NUM_FRACTION_DIGITS),\n height: toFixed(this.height, NUM_FRACTION_DIGITS),\n fill: this.fill && this.fill.toObject ? this.fill.toObject() : this.fill,\n stroke: this.stroke && this.stroke.toObject ? this.stroke.toObject() : this.stroke,\n strokeWidth: toFixed(this.strokeWidth, NUM_FRACTION_DIGITS),\n strokeDashArray: this.strokeDashArray ? this.strokeDashArray.concat() : this.strokeDashArray,\n strokeLineCap: this.strokeLineCap,\n strokeDashOffset: this.strokeDashOffset,\n strokeLineJoin: this.strokeLineJoin,\n // strokeUniform: this.strokeUniform,\n strokeMiterLimit: toFixed(this.strokeMiterLimit, NUM_FRACTION_DIGITS),\n scaleX: toFixed(this.scaleX, NUM_FRACTION_DIGITS),\n scaleY: toFixed(this.scaleY, NUM_FRACTION_DIGITS),\n angle: toFixed(this.angle, NUM_FRACTION_DIGITS),\n flipX: this.flipX,\n flipY: this.flipY,\n opacity: toFixed(this.opacity, NUM_FRACTION_DIGITS),\n shadow: this.shadow && this.shadow.toObject ? this.shadow.toObject() : this.shadow,\n visible: this.visible,\n backgroundColor: this.backgroundColor,\n fillRule: this.fillRule,\n paintFirst: this.paintFirst,\n globalCompositeOperation: this.globalCompositeOperation,\n skewX: toFixed(this.skewX, NUM_FRACTION_DIGITS),\n skewY: toFixed(this.skewY, NUM_FRACTION_DIGITS)\n };\n\n if (this.clipPath) {\n object.clipPath = this.clipPath.toObject(propertiesToInclude);\n object.clipPath.inverted = this.clipPath.inverted;\n object.clipPath.absolutePositioned = this.clipPath.absolutePositioned;\n }\n\n fabric.util.populateWithProperties(this, object, propertiesToInclude);\n\n if (!this.includeDefaultValues) {\n object = this._removeDefaultValues(object);\n }\n\n return object;\n },\n\n /**\n * Returns (dataless) object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} Object representation of an instance\n */\n toDatalessObject: function (propertiesToInclude) {\n // will be overwritten by subclasses\n return this.toObject(propertiesToInclude);\n },\n\n /**\n * @private\n * @param {Object} object\n */\n _removeDefaultValues: function (object) {\n var prototype = fabric.util.getKlass(object.type).prototype,\n stateProperties = prototype.stateProperties;\n stateProperties.forEach(function (prop) {\n if (prop === 'left' || prop === 'top') {\n return;\n }\n\n if (object[prop] === prototype[prop]) {\n delete object[prop];\n }\n\n var isArray = Object.prototype.toString.call(object[prop]) === '[object Array]' && Object.prototype.toString.call(prototype[prop]) === '[object Array]'; // basically a check for [] === []\n\n if (isArray && object[prop].length === 0 && prototype[prop].length === 0) {\n delete object[prop];\n }\n });\n return object;\n },\n\n /**\n * Returns a string representation of an instance\n * @return {String}\n */\n toString: function () {\n return '#<fabric.' + capitalize(this.type) + '>';\n },\n\n /**\n * Return the object scale factor counting also the group scaling\n * @return {Object} object with scaleX and scaleY properties\n */\n getObjectScaling: function () {\n var options = fabric.util.qrDecompose(this.calcTransformMatrix());\n return {\n scaleX: Math.abs(options.scaleX),\n scaleY: Math.abs(options.scaleY)\n };\n },\n\n /**\n * Return the object scale factor counting also the group scaling, zoom and retina\n * @return {Object} object with scaleX and scaleY properties\n */\n getTotalObjectScaling: function () {\n var scale = this.getObjectScaling(),\n scaleX = scale.scaleX,\n scaleY = scale.scaleY;\n\n if (this.canvas) {\n var zoom = this.canvas.getZoom();\n var retina = this.canvas.getRetinaScaling();\n scaleX *= zoom * retina;\n scaleY *= zoom * retina;\n }\n\n return {\n scaleX: scaleX,\n scaleY: scaleY\n };\n },\n\n /**\n * Return the object opacity counting also the group property\n * @return {Number}\n */\n getObjectOpacity: function () {\n var opacity = this.opacity;\n\n if (this.group) {\n opacity *= this.group.getObjectOpacity();\n }\n\n return opacity;\n },\n\n /**\n * @private\n * @param {String} key\n * @param {*} value\n * @return {fabric.Object} thisArg\n */\n _set: function (key, value) {\n var shouldConstrainValue = key === 'scaleX' || key === 'scaleY',\n isChanged = this[key] !== value,\n groupNeedsUpdate = false;\n\n if (shouldConstrainValue) {\n value = this._constrainScale(value);\n }\n\n if (key === 'scaleX' && value < 0) {\n this.flipX = !this.flipX;\n value *= -1;\n } else if (key === 'scaleY' && value < 0) {\n this.flipY = !this.flipY;\n value *= -1;\n } else if (key === 'shadow' && value && !(value instanceof fabric.Shadow)) {\n value = new fabric.Shadow(value);\n } else if (key === 'dirty' && this.group) {\n this.group.set('dirty', value);\n }\n\n this[key] = value;\n\n if (isChanged) {\n groupNeedsUpdate = this.group && this.group.isOnACache();\n\n if (this.cacheProperties.indexOf(key) > -1) {\n this.dirty = true;\n groupNeedsUpdate && this.group.set('dirty', true);\n } else if (groupNeedsUpdate && this.stateProperties.indexOf(key) > -1) {\n this.group.set('dirty', true);\n }\n }\n\n return this;\n },\n\n /**\n * This callback function is called by the parent group of an object every\n * time a non-delegated property changes on the group. It is passed the key\n * and value as parameters. Not adding in this function's signature to avoid\n * Travis build error about unused variables.\n */\n setOnGroup: function () {// implemented by sub-classes, as needed.\n },\n\n /**\n * Retrieves viewportTransform from Object's canvas if possible\n * @method getViewportTransform\n * @memberOf fabric.Object.prototype\n * @return {Array}\n */\n getViewportTransform: function () {\n if (this.canvas && this.canvas.viewportTransform) {\n return this.canvas.viewportTransform;\n }\n\n return fabric.iMatrix.concat();\n },\n\n /*\n * @private\n * return if the object would be visible in rendering\n * @memberOf fabric.Object.prototype\n * @return {Boolean}\n */\n isNotVisible: function () {\n return this.opacity === 0 || !this.width && !this.height && this.strokeWidth === 0 || !this.visible;\n },\n\n /**\n * Renders an object on a specified context\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n render: function (ctx) {\n // do not render if width/height are zeros or object is not visible\n if (this.isNotVisible()) {\n return;\n }\n\n if (this.canvas && this.canvas.skipOffscreen && !this.group && !this.isOnScreen()) {\n return;\n }\n\n ctx.save();\n\n this._setupCompositeOperation(ctx);\n\n this.drawSelectionBackground(ctx);\n this.transform(ctx);\n\n this._setOpacity(ctx);\n\n this._setShadow(ctx, this);\n\n if (this.shouldCache()) {\n this.renderCache();\n this.drawCacheOnCanvas(ctx);\n } else {\n this._removeCacheCanvas();\n\n this.dirty = false;\n this.drawObject(ctx);\n\n if (this.objectCaching && this.statefullCache) {\n this.saveState({\n propertySet: 'cacheProperties'\n });\n }\n }\n\n ctx.restore();\n },\n renderCache: function (options) {\n options = options || {};\n\n if (!this._cacheCanvas) {\n this._createCacheCanvas();\n }\n\n if (this.isCacheDirty()) {\n this.statefullCache && this.saveState({\n propertySet: 'cacheProperties'\n });\n this.drawObject(this._cacheContext, options.forClipping);\n this.dirty = false;\n }\n },\n\n /**\n * Remove cacheCanvas and its dimensions from the objects\n */\n _removeCacheCanvas: function () {\n this._cacheCanvas = null;\n this.cacheWidth = 0;\n this.cacheHeight = 0;\n },\n\n /**\n * return true if the object will draw a stroke\n * Does not consider text styles. This is just a shortcut used at rendering time\n * We want it to be an aproximation and be fast.\n * wrote to avoid extra caching, it has to return true when stroke happens,\n * can guess when it will not happen at 100% chance, does not matter if it misses\n * some use case where the stroke is invisible.\n * @since 3.0.0\n * @returns Boolean\n */\n hasStroke: function () {\n return this.stroke && this.stroke !== 'transparent' && this.strokeWidth !== 0;\n },\n\n /**\n * return true if the object will draw a fill\n * Does not consider text styles. This is just a shortcut used at rendering time\n * We want it to be an aproximation and be fast.\n * wrote to avoid extra caching, it has to return true when fill happens,\n * can guess when it will not happen at 100% chance, does not matter if it misses\n * some use case where the fill is invisible.\n * @since 3.0.0\n * @returns Boolean\n */\n hasFill: function () {\n return this.fill && this.fill !== 'transparent';\n },\n\n /**\n * When set to `true`, force the object to have its own cache, even if it is inside a group\n * it may be needed when your object behave in a particular way on the cache and always needs\n * its own isolated canvas to render correctly.\n * Created to be overridden\n * since 1.7.12\n * @returns Boolean\n */\n needsItsOwnCache: function () {\n if (this.paintFirst === 'stroke' && this.hasFill() && this.hasStroke() && typeof this.shadow === 'object') {\n return true;\n }\n\n if (this.clipPath) {\n return true;\n }\n\n return false;\n },\n\n /**\n * Decide if the object should cache or not. Create its own cache level\n * objectCaching is a global flag, wins over everything\n * needsItsOwnCache should be used when the object drawing method requires\n * a cache step. None of the fabric classes requires it.\n * Generally you do not cache objects in groups because the group outside is cached.\n * Read as: cache if is needed, or if the feature is enabled but we are not already caching.\n * @return {Boolean}\n */\n shouldCache: function () {\n this.ownCaching = this.needsItsOwnCache() || this.objectCaching && (!this.group || !this.group.isOnACache());\n return this.ownCaching;\n },\n\n /**\n * Check if this object or a child object will cast a shadow\n * used by Group.shouldCache to know if child has a shadow recursively\n * @return {Boolean}\n */\n willDrawShadow: function () {\n return !!this.shadow && (this.shadow.offsetX !== 0 || this.shadow.offsetY !== 0);\n },\n\n /**\n * Execute the drawing operation for an object clipPath\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n drawClipPathOnCache: function (ctx) {\n var path = this.clipPath;\n ctx.save(); // DEBUG: uncomment this line, comment the following\n // ctx.globalAlpha = 0.4\n\n if (path.inverted) {\n ctx.globalCompositeOperation = 'destination-out';\n } else {\n ctx.globalCompositeOperation = 'destination-in';\n } //ctx.scale(1 / 2, 1 / 2);\n\n\n if (path.absolutePositioned) {\n var m = fabric.util.invertTransform(this.calcTransformMatrix());\n ctx.transform(m[0], m[1], m[2], m[3], m[4], m[5]);\n }\n\n path.transform(ctx);\n ctx.scale(1 / path.zoomX, 1 / path.zoomY);\n ctx.drawImage(path._cacheCanvas, -path.cacheTranslationX, -path.cacheTranslationY);\n ctx.restore();\n },\n\n /**\n * Execute the drawing operation for an object on a specified context\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n drawObject: function (ctx, forClipping) {\n var originalFill = this.fill,\n originalStroke = this.stroke;\n\n if (forClipping) {\n this.fill = 'black';\n this.stroke = '';\n\n this._setClippingProperties(ctx);\n } else {\n this._renderBackground(ctx);\n\n this._setStrokeStyles(ctx, this);\n\n this._setFillStyles(ctx, this);\n }\n\n this._render(ctx);\n\n this._drawClipPath(ctx);\n\n this.fill = originalFill;\n this.stroke = originalStroke;\n },\n _drawClipPath: function (ctx) {\n var path = this.clipPath;\n\n if (!path) {\n return;\n } // needed to setup a couple of variables\n // path canvas gets overridden with this one.\n // TODO find a better solution?\n\n\n path.canvas = this.canvas;\n path.shouldCache();\n path._transformDone = true;\n path.renderCache({\n forClipping: true\n });\n this.drawClipPathOnCache(ctx);\n },\n\n /**\n * Paint the cached copy of the object on the target context.\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n drawCacheOnCanvas: function (ctx) {\n ctx.scale(1 / this.zoomX, 1 / this.zoomY);\n ctx.drawImage(this._cacheCanvas, -this.cacheTranslationX, -this.cacheTranslationY);\n },\n\n /**\n * Check if cache is dirty\n * @param {Boolean} skipCanvas skip canvas checks because this object is painted\n * on parent canvas.\n */\n isCacheDirty: function (skipCanvas) {\n if (this.isNotVisible()) {\n return false;\n }\n\n if (this._cacheCanvas && !skipCanvas && this._updateCacheCanvas()) {\n // in this case the context is already cleared.\n return true;\n } else {\n if (this.dirty || this.clipPath && this.clipPath.absolutePositioned || this.statefullCache && this.hasStateChanged('cacheProperties')) {\n if (this._cacheCanvas && !skipCanvas) {\n var width = this.cacheWidth / this.zoomX;\n var height = this.cacheHeight / this.zoomY;\n\n this._cacheContext.clearRect(-width / 2, -height / 2, width, height);\n }\n\n return true;\n }\n }\n\n return false;\n },\n\n /**\n * Draws a background for the object big as its untransformed dimensions\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderBackground: function (ctx) {\n if (!this.backgroundColor) {\n return;\n }\n\n var dim = this._getNonTransformedDimensions();\n\n ctx.fillStyle = this.backgroundColor;\n ctx.fillRect(-dim.x / 2, -dim.y / 2, dim.x, dim.y); // if there is background color no other shadows\n // should be casted\n\n this._removeShadow(ctx);\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _setOpacity: function (ctx) {\n if (this.group && !this.group._transformDone) {\n ctx.globalAlpha = this.getObjectOpacity();\n } else {\n ctx.globalAlpha *= this.opacity;\n }\n },\n _setStrokeStyles: function (ctx, decl) {\n if (decl.stroke) {\n ctx.lineWidth = decl.strokeWidth;\n ctx.lineCap = decl.strokeLineCap;\n ctx.lineDashOffset = decl.strokeDashOffset;\n ctx.lineJoin = decl.strokeLineJoin;\n ctx.miterLimit = decl.strokeMiterLimit;\n ctx.strokeStyle = decl.stroke.toLive ? decl.stroke.toLive(ctx, this) : decl.stroke;\n }\n },\n _setFillStyles: function (ctx, decl) {\n if (decl.fill) {\n ctx.fillStyle = decl.fill.toLive ? decl.fill.toLive(ctx, this) : decl.fill;\n }\n },\n _setClippingProperties: function (ctx) {\n ctx.globalAlpha = 1;\n ctx.strokeStyle = 'transparent';\n ctx.fillStyle = '#000000';\n },\n\n /**\n * @private\n * Sets line dash\n * @param {CanvasRenderingContext2D} ctx Context to set the dash line on\n * @param {Array} dashArray array representing dashes\n * @param {Function} alternative function to call if browser does not support lineDash\n */\n _setLineDash: function (ctx, dashArray, alternative) {\n if (!dashArray || dashArray.length === 0) {\n return;\n } // Spec requires the concatenation of two copies the dash list when the number of elements is odd\n\n\n if (1 & dashArray.length) {\n dashArray.push.apply(dashArray, dashArray);\n }\n\n if (supportsLineDash) {\n ctx.setLineDash(dashArray);\n } else {\n alternative && alternative(ctx);\n }\n },\n\n /**\n * Renders controls and borders for the object\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Object} [styleOverride] properties to override the object style\n */\n _renderControls: function (ctx, styleOverride) {\n var vpt = this.getViewportTransform(),\n matrix = this.calcTransformMatrix(),\n options,\n drawBorders,\n drawControls;\n styleOverride = styleOverride || {};\n drawBorders = typeof styleOverride.hasBorders !== 'undefined' ? styleOverride.hasBorders : this.hasBorders;\n drawControls = typeof styleOverride.hasControls !== 'undefined' ? styleOverride.hasControls : this.hasControls;\n matrix = fabric.util.multiplyTransformMatrices(vpt, matrix);\n options = fabric.util.qrDecompose(matrix);\n ctx.save();\n ctx.translate(options.translateX, options.translateY);\n ctx.lineWidth = 1 * this.borderScaleFactor;\n\n if (!this.group) {\n ctx.globalAlpha = this.isMoving ? this.borderOpacityWhenMoving : 1;\n }\n\n if (styleOverride.forActiveSelection) {\n ctx.rotate(degreesToRadians(options.angle));\n drawBorders && this.drawBordersInGroup(ctx, options, styleOverride);\n } else {\n ctx.rotate(degreesToRadians(this.angle));\n drawBorders && this.drawBorders(ctx, styleOverride);\n }\n\n drawControls && this.drawControls(ctx, styleOverride);\n ctx.restore();\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _setShadow: function (ctx) {\n if (!this.shadow) {\n return;\n }\n\n var shadow = this.shadow,\n canvas = this.canvas,\n scaling,\n multX = canvas && canvas.viewportTransform[0] || 1,\n multY = canvas && canvas.viewportTransform[3] || 1;\n\n if (shadow.nonScaling) {\n scaling = {\n scaleX: 1,\n scaleY: 1\n };\n } else {\n scaling = this.getObjectScaling();\n }\n\n if (canvas && canvas._isRetinaScaling()) {\n multX *= fabric.devicePixelRatio;\n multY *= fabric.devicePixelRatio;\n }\n\n ctx.shadowColor = shadow.color;\n ctx.shadowBlur = shadow.blur * fabric.browserShadowBlurConstant * (multX + multY) * (scaling.scaleX + scaling.scaleY) / 4;\n ctx.shadowOffsetX = shadow.offsetX * multX * scaling.scaleX;\n ctx.shadowOffsetY = shadow.offsetY * multY * scaling.scaleY;\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _removeShadow: function (ctx) {\n if (!this.shadow) {\n return;\n }\n\n ctx.shadowColor = '';\n ctx.shadowBlur = ctx.shadowOffsetX = ctx.shadowOffsetY = 0;\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Object} filler fabric.Pattern or fabric.Gradient\n * @return {Object} offset.offsetX offset for text rendering\n * @return {Object} offset.offsetY offset for text rendering\n */\n _applyPatternGradientTransform: function (ctx, filler) {\n if (!filler || !filler.toLive) {\n return {\n offsetX: 0,\n offsetY: 0\n };\n }\n\n var t = filler.gradientTransform || filler.patternTransform;\n var offsetX = -this.width / 2 + filler.offsetX || 0,\n offsetY = -this.height / 2 + filler.offsetY || 0;\n\n if (filler.gradientUnits === 'percentage') {\n ctx.transform(this.width, 0, 0, this.height, offsetX, offsetY);\n } else {\n ctx.transform(1, 0, 0, 1, offsetX, offsetY);\n }\n\n if (t) {\n ctx.transform(t[0], t[1], t[2], t[3], t[4], t[5]);\n }\n\n return {\n offsetX: offsetX,\n offsetY: offsetY\n };\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderPaintInOrder: function (ctx) {\n if (this.paintFirst === 'stroke') {\n this._renderStroke(ctx);\n\n this._renderFill(ctx);\n } else {\n this._renderFill(ctx);\n\n this._renderStroke(ctx);\n }\n },\n\n /**\n * @private\n * function that actually render something on the context.\n * empty here to allow Obects to work on tests to benchmark fabric functionalites\n * not related to rendering\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _render: function ()\n /* ctx */\n {},\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderFill: function (ctx) {\n if (!this.fill) {\n return;\n }\n\n ctx.save();\n\n this._applyPatternGradientTransform(ctx, this.fill);\n\n if (this.fillRule === 'evenodd') {\n ctx.fill('evenodd');\n } else {\n ctx.fill();\n }\n\n ctx.restore();\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderStroke: function (ctx) {\n if (!this.stroke || this.strokeWidth === 0) {\n return;\n }\n\n if (this.shadow && !this.shadow.affectStroke) {\n this._removeShadow(ctx);\n }\n\n ctx.save();\n\n if (this.strokeUniform && this.group) {\n var scaling = this.getObjectScaling();\n ctx.scale(1 / scaling.scaleX, 1 / scaling.scaleY);\n } else if (this.strokeUniform) {\n ctx.scale(1 / this.scaleX, 1 / this.scaleY);\n }\n\n this._setLineDash(ctx, this.strokeDashArray, this._renderDashedStroke);\n\n if (this.stroke.toLive && this.stroke.gradientUnits === 'percentage') {\n // need to transform gradient in a pattern.\n // this is a slow process. If you are hitting this codepath, and the object\n // is not using caching, you should consider switching it on.\n // we need a canvas as big as the current object caching canvas.\n this._applyPatternForTransformedGradient(ctx, this.stroke);\n } else {\n this._applyPatternGradientTransform(ctx, this.stroke);\n }\n\n ctx.stroke();\n ctx.restore();\n },\n\n /**\n * This function try to patch the missing gradientTransform on canvas gradients.\n * transforming a context to transform the gradient, is going to transform the stroke too.\n * we want to transform the gradient but not the stroke operation, so we create\n * a transformed gradient on a pattern and then we use the pattern instead of the gradient.\n * this method has drwabacks: is slow, is in low resolution, needs a patch for when the size\n * is limited.\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {fabric.Gradient} filler a fabric gradient instance\n */\n _applyPatternForTransformedGradient: function (ctx, filler) {\n var dims = this._limitCacheSize(this._getCacheCanvasDimensions()),\n pCanvas = fabric.util.createCanvasElement(),\n pCtx,\n retinaScaling = this.canvas.getRetinaScaling(),\n width = dims.x / this.scaleX / retinaScaling,\n height = dims.y / this.scaleY / retinaScaling;\n\n pCanvas.width = width;\n pCanvas.height = height;\n pCtx = pCanvas.getContext('2d');\n pCtx.beginPath();\n pCtx.moveTo(0, 0);\n pCtx.lineTo(width, 0);\n pCtx.lineTo(width, height);\n pCtx.lineTo(0, height);\n pCtx.closePath();\n pCtx.translate(width / 2, height / 2);\n pCtx.scale(dims.zoomX / this.scaleX / retinaScaling, dims.zoomY / this.scaleY / retinaScaling);\n\n this._applyPatternGradientTransform(pCtx, filler);\n\n pCtx.fillStyle = filler.toLive(ctx);\n pCtx.fill();\n ctx.translate(-this.width / 2 - this.strokeWidth / 2, -this.height / 2 - this.strokeWidth / 2);\n ctx.scale(retinaScaling * this.scaleX / dims.zoomX, retinaScaling * this.scaleY / dims.zoomY);\n ctx.strokeStyle = pCtx.createPattern(pCanvas, 'no-repeat');\n },\n\n /**\n * This function is an helper for svg import. it returns the center of the object in the svg\n * untransformed coordinates\n * @private\n * @return {Object} center point from element coordinates\n */\n _findCenterFromElement: function () {\n return {\n x: this.left + this.width / 2,\n y: this.top + this.height / 2\n };\n },\n\n /**\n * This function is an helper for svg import. it decompose the transformMatrix\n * and assign properties to object.\n * untransformed coordinates\n * @private\n * @chainable\n */\n _assignTransformMatrixProps: function () {\n if (this.transformMatrix) {\n var options = fabric.util.qrDecompose(this.transformMatrix);\n this.flipX = false;\n this.flipY = false;\n this.set('scaleX', options.scaleX);\n this.set('scaleY', options.scaleY);\n this.angle = options.angle;\n this.skewX = options.skewX;\n this.skewY = 0;\n }\n },\n\n /**\n * This function is an helper for svg import. it removes the transform matrix\n * and set to object properties that fabricjs can handle\n * @private\n * @param {Object} preserveAspectRatioOptions\n * @return {thisArg}\n */\n _removeTransformMatrix: function (preserveAspectRatioOptions) {\n var center = this._findCenterFromElement();\n\n if (this.transformMatrix) {\n this._assignTransformMatrixProps();\n\n center = fabric.util.transformPoint(center, this.transformMatrix);\n }\n\n this.transformMatrix = null;\n\n if (preserveAspectRatioOptions) {\n this.scaleX *= preserveAspectRatioOptions.scaleX;\n this.scaleY *= preserveAspectRatioOptions.scaleY;\n this.cropX = preserveAspectRatioOptions.cropX;\n this.cropY = preserveAspectRatioOptions.cropY;\n center.x += preserveAspectRatioOptions.offsetLeft;\n center.y += preserveAspectRatioOptions.offsetTop;\n this.width = preserveAspectRatioOptions.width;\n this.height = preserveAspectRatioOptions.height;\n }\n\n this.setPositionByOrigin(center, 'center', 'center');\n },\n\n /**\n * Clones an instance, using a callback method will work for every object.\n * @param {Function} callback Callback is invoked with a clone as a first argument\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n */\n clone: function (callback, propertiesToInclude) {\n var objectForm = this.toObject(propertiesToInclude);\n\n if (this.constructor.fromObject) {\n this.constructor.fromObject(objectForm, callback);\n } else {\n fabric.Object._fromObject('Object', objectForm, callback);\n }\n },\n\n /**\n * Creates an instance of fabric.Image out of an object\n * could make use of both toDataUrl or toCanvasElement.\n * @param {Function} callback callback, invoked with an instance as a first argument\n * @param {Object} [options] for clone as image, passed to toDataURL\n * @param {String} [options.format=png] The format of the output image. Either \"jpeg\" or \"png\"\n * @param {Number} [options.quality=1] Quality level (0..1). Only used for jpeg.\n * @param {Number} [options.multiplier=1] Multiplier to scale by\n * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14\n * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14\n * @param {Number} [options.width] Cropping width. Introduced in v1.2.14\n * @param {Number} [options.height] Cropping height. Introduced in v1.2.14\n * @param {Boolean} [options.enableRetinaScaling] Enable retina scaling for clone image. Introduce in 1.6.4\n * @param {Boolean} [options.withoutTransform] Remove current object transform ( no scale , no angle, no flip, no skew ). Introduced in 2.3.4\n * @param {Boolean} [options.withoutShadow] Remove current object shadow. Introduced in 2.4.2\n * @return {fabric.Object} thisArg\n */\n cloneAsImage: function (callback, options) {\n var canvasEl = this.toCanvasElement(options);\n\n if (callback) {\n callback(new fabric.Image(canvasEl));\n }\n\n return this;\n },\n\n /**\n * Converts an object into a HTMLCanvas element\n * @param {Object} options Options object\n * @param {Number} [options.multiplier=1] Multiplier to scale by\n * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14\n * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14\n * @param {Number} [options.width] Cropping width. Introduced in v1.2.14\n * @param {Number} [options.height] Cropping height. Introduced in v1.2.14\n * @param {Boolean} [options.enableRetinaScaling] Enable retina scaling for clone image. Introduce in 1.6.4\n * @param {Boolean} [options.withoutTransform] Remove current object transform ( no scale , no angle, no flip, no skew ). Introduced in 2.3.4\n * @param {Boolean} [options.withoutShadow] Remove current object shadow. Introduced in 2.4.2\n * @return {HTMLCanvasElement} Returns DOM element <canvas> with the fabric.Object\n */\n toCanvasElement: function (options) {\n options || (options = {});\n var utils = fabric.util,\n origParams = utils.saveObjectTransform(this),\n originalGroup = this.group,\n originalShadow = this.shadow,\n abs = Math.abs,\n multiplier = (options.multiplier || 1) * (options.enableRetinaScaling ? fabric.devicePixelRatio : 1);\n delete this.group;\n\n if (options.withoutTransform) {\n utils.resetObjectTransform(this);\n }\n\n if (options.withoutShadow) {\n this.shadow = null;\n }\n\n var el = fabric.util.createCanvasElement(),\n // skip canvas zoom and calculate with setCoords now.\n boundingRect = this.getBoundingRect(true, true),\n shadow = this.shadow,\n scaling,\n shadowOffset = {\n x: 0,\n y: 0\n },\n shadowBlur,\n width,\n height;\n\n if (shadow) {\n shadowBlur = shadow.blur;\n\n if (shadow.nonScaling) {\n scaling = {\n scaleX: 1,\n scaleY: 1\n };\n } else {\n scaling = this.getObjectScaling();\n } // consider non scaling shadow.\n\n\n shadowOffset.x = 2 * Math.round(abs(shadow.offsetX) + shadowBlur) * abs(scaling.scaleX);\n shadowOffset.y = 2 * Math.round(abs(shadow.offsetY) + shadowBlur) * abs(scaling.scaleY);\n }\n\n width = boundingRect.width + shadowOffset.x;\n height = boundingRect.height + shadowOffset.y; // if the current width/height is not an integer\n // we need to make it so.\n\n el.width = Math.ceil(width);\n el.height = Math.ceil(height);\n var canvas = new fabric.StaticCanvas(el, {\n enableRetinaScaling: false,\n renderOnAddRemove: false,\n skipOffscreen: false\n });\n\n if (options.format === 'jpeg') {\n canvas.backgroundColor = '#fff';\n }\n\n this.setPositionByOrigin(new fabric.Point(canvas.width / 2, canvas.height / 2), 'center', 'center');\n var originalCanvas = this.canvas;\n canvas.add(this);\n var canvasEl = canvas.toCanvasElement(multiplier || 1, options);\n this.shadow = originalShadow;\n this.set('canvas', originalCanvas);\n\n if (originalGroup) {\n this.group = originalGroup;\n }\n\n this.set(origParams).setCoords(); // canvas.dispose will call image.dispose that will nullify the elements\n // since this canvas is a simple element for the process, we remove references\n // to objects in this way in order to avoid object trashing.\n\n canvas._objects = [];\n canvas.dispose();\n canvas = null;\n return canvasEl;\n },\n\n /**\n * Converts an object into a data-url-like string\n * @param {Object} options Options object\n * @param {String} [options.format=png] The format of the output image. Either \"jpeg\" or \"png\"\n * @param {Number} [options.quality=1] Quality level (0..1). Only used for jpeg.\n * @param {Number} [options.multiplier=1] Multiplier to scale by\n * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14\n * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14\n * @param {Number} [options.width] Cropping width. Introduced in v1.2.14\n * @param {Number} [options.height] Cropping height. Introduced in v1.2.14\n * @param {Boolean} [options.enableRetinaScaling] Enable retina scaling for clone image. Introduce in 1.6.4\n * @param {Boolean} [options.withoutTransform] Remove current object transform ( no scale , no angle, no flip, no skew ). Introduced in 2.3.4\n * @param {Boolean} [options.withoutShadow] Remove current object shadow. Introduced in 2.4.2\n * @return {String} Returns a data: URL containing a representation of the object in the format specified by options.format\n */\n toDataURL: function (options) {\n options || (options = {});\n return fabric.util.toDataURL(this.toCanvasElement(options), options.format || 'png', options.quality || 1);\n },\n\n /**\n * Returns true if specified type is identical to the type of an instance\n * @param {String} type Type to check against\n * @return {Boolean}\n */\n isType: function (type) {\n return this.type === type;\n },\n\n /**\n * Returns complexity of an instance\n * @return {Number} complexity of this instance (is 1 unless subclassed)\n */\n complexity: function () {\n return 1;\n },\n\n /**\n * Returns a JSON representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} JSON\n */\n toJSON: function (propertiesToInclude) {\n // delegate, not alias\n return this.toObject(propertiesToInclude);\n },\n\n /**\n * Sets \"angle\" of an instance with centered rotation\n * @param {Number} angle Angle value (in degrees)\n * @return {fabric.Object} thisArg\n * @chainable\n */\n rotate: function (angle) {\n var shouldCenterOrigin = (this.originX !== 'center' || this.originY !== 'center') && this.centeredRotation;\n\n if (shouldCenterOrigin) {\n this._setOriginToCenter();\n }\n\n this.set('angle', angle);\n\n if (shouldCenterOrigin) {\n this._resetOrigin();\n }\n\n return this;\n },\n\n /**\n * Centers object horizontally on canvas to which it was added last.\n * You might need to call `setCoords` on an object after centering, to update controls area.\n * @return {fabric.Object} thisArg\n * @chainable\n */\n centerH: function () {\n this.canvas && this.canvas.centerObjectH(this);\n return this;\n },\n\n /**\n * Centers object horizontally on current viewport of canvas to which it was added last.\n * You might need to call `setCoords` on an object after centering, to update controls area.\n * @return {fabric.Object} thisArg\n * @chainable\n */\n viewportCenterH: function () {\n this.canvas && this.canvas.viewportCenterObjectH(this);\n return this;\n },\n\n /**\n * Centers object vertically on canvas to which it was added last.\n * You might need to call `setCoords` on an object after centering, to update controls area.\n * @return {fabric.Object} thisArg\n * @chainable\n */\n centerV: function () {\n this.canvas && this.canvas.centerObjectV(this);\n return this;\n },\n\n /**\n * Centers object vertically on current viewport of canvas to which it was added last.\n * You might need to call `setCoords` on an object after centering, to update controls area.\n * @return {fabric.Object} thisArg\n * @chainable\n */\n viewportCenterV: function () {\n this.canvas && this.canvas.viewportCenterObjectV(this);\n return this;\n },\n\n /**\n * Centers object vertically and horizontally on canvas to which is was added last\n * You might need to call `setCoords` on an object after centering, to update controls area.\n * @return {fabric.Object} thisArg\n * @chainable\n */\n center: function () {\n this.canvas && this.canvas.centerObject(this);\n return this;\n },\n\n /**\n * Centers object on current viewport of canvas to which it was added last.\n * You might need to call `setCoords` on an object after centering, to update controls area.\n * @return {fabric.Object} thisArg\n * @chainable\n */\n viewportCenter: function () {\n this.canvas && this.canvas.viewportCenterObject(this);\n return this;\n },\n\n /**\n * Returns coordinates of a pointer relative to an object\n * @param {Event} e Event to operate upon\n * @param {Object} [pointer] Pointer to operate upon (instead of event)\n * @return {Object} Coordinates of a pointer (x, y)\n */\n getLocalPointer: function (e, pointer) {\n pointer = pointer || this.canvas.getPointer(e);\n\n var pClicked = new fabric.Point(pointer.x, pointer.y),\n objectLeftTop = this._getLeftTopCoords();\n\n if (this.angle) {\n pClicked = fabric.util.rotatePoint(pClicked, objectLeftTop, degreesToRadians(-this.angle));\n }\n\n return {\n x: pClicked.x - objectLeftTop.x,\n y: pClicked.y - objectLeftTop.y\n };\n },\n\n /**\n * Sets canvas globalCompositeOperation for specific object\n * custom composition operation for the particular object can be specified using globalCompositeOperation property\n * @param {CanvasRenderingContext2D} ctx Rendering canvas context\n */\n _setupCompositeOperation: function (ctx) {\n if (this.globalCompositeOperation) {\n ctx.globalCompositeOperation = this.globalCompositeOperation;\n }\n }\n });\n fabric.util.createAccessors && fabric.util.createAccessors(fabric.Object);\n extend(fabric.Object.prototype, fabric.Observable);\n /**\n * Defines the number of fraction digits to use when serializing object values.\n * You can use it to increase/decrease precision of such values like left, top, scaleX, scaleY, etc.\n * @static\n * @memberOf fabric.Object\n * @constant\n * @type Number\n */\n\n fabric.Object.NUM_FRACTION_DIGITS = 2;\n\n fabric.Object._fromObject = function (className, object, callback, extraParam) {\n var klass = fabric[className];\n object = clone(object, true);\n fabric.util.enlivenPatterns([object.fill, object.stroke], function (patterns) {\n if (typeof patterns[0] !== 'undefined') {\n object.fill = patterns[0];\n }\n\n if (typeof patterns[1] !== 'undefined') {\n object.stroke = patterns[1];\n }\n\n fabric.util.enlivenObjects([object.clipPath], function (enlivedProps) {\n object.clipPath = enlivedProps[0];\n var instance = extraParam ? new klass(object[extraParam], object) : new klass(object);\n callback && callback(instance);\n });\n });\n };\n /**\n * Unique id used internally when creating SVG elements\n * @static\n * @memberOf fabric.Object\n * @type Number\n */\n\n\n fabric.Object.__uid = 0;\n})(typeof exports !== 'undefined' ? exports : this);\n\n(function () {\n var degreesToRadians = fabric.util.degreesToRadians,\n originXOffset = {\n left: -0.5,\n center: 0,\n right: 0.5\n },\n originYOffset = {\n top: -0.5,\n center: 0,\n bottom: 0.5\n };\n fabric.util.object.extend(fabric.Object.prototype,\n /** @lends fabric.Object.prototype */\n {\n /**\n * Translates the coordinates from a set of origin to another (based on the object's dimensions)\n * @param {fabric.Point} point The point which corresponds to the originX and originY params\n * @param {String} fromOriginX Horizontal origin: 'left', 'center' or 'right'\n * @param {String} fromOriginY Vertical origin: 'top', 'center' or 'bottom'\n * @param {String} toOriginX Horizontal origin: 'left', 'center' or 'right'\n * @param {String} toOriginY Vertical origin: 'top', 'center' or 'bottom'\n * @return {fabric.Point}\n */\n translateToGivenOrigin: function (point, fromOriginX, fromOriginY, toOriginX, toOriginY) {\n var x = point.x,\n y = point.y,\n offsetX,\n offsetY,\n dim;\n\n if (typeof fromOriginX === 'string') {\n fromOriginX = originXOffset[fromOriginX];\n } else {\n fromOriginX -= 0.5;\n }\n\n if (typeof toOriginX === 'string') {\n toOriginX = originXOffset[toOriginX];\n } else {\n toOriginX -= 0.5;\n }\n\n offsetX = toOriginX - fromOriginX;\n\n if (typeof fromOriginY === 'string') {\n fromOriginY = originYOffset[fromOriginY];\n } else {\n fromOriginY -= 0.5;\n }\n\n if (typeof toOriginY === 'string') {\n toOriginY = originYOffset[toOriginY];\n } else {\n toOriginY -= 0.5;\n }\n\n offsetY = toOriginY - fromOriginY;\n\n if (offsetX || offsetY) {\n dim = this._getTransformedDimensions();\n x = point.x + offsetX * dim.x;\n y = point.y + offsetY * dim.y;\n }\n\n return new fabric.Point(x, y);\n },\n\n /**\n * Translates the coordinates from origin to center coordinates (based on the object's dimensions)\n * @param {fabric.Point} point The point which corresponds to the originX and originY params\n * @param {String} originX Horizontal origin: 'left', 'center' or 'right'\n * @param {String} originY Vertical origin: 'top', 'center' or 'bottom'\n * @return {fabric.Point}\n */\n translateToCenterPoint: function (point, originX, originY) {\n var p = this.translateToGivenOrigin(point, originX, originY, 'center', 'center');\n\n if (this.angle) {\n return fabric.util.rotatePoint(p, point, degreesToRadians(this.angle));\n }\n\n return p;\n },\n\n /**\n * Translates the coordinates from center to origin coordinates (based on the object's dimensions)\n * @param {fabric.Point} center The point which corresponds to center of the object\n * @param {String} originX Horizontal origin: 'left', 'center' or 'right'\n * @param {String} originY Vertical origin: 'top', 'center' or 'bottom'\n * @return {fabric.Point}\n */\n translateToOriginPoint: function (center, originX, originY) {\n var p = this.translateToGivenOrigin(center, 'center', 'center', originX, originY);\n\n if (this.angle) {\n return fabric.util.rotatePoint(p, center, degreesToRadians(this.angle));\n }\n\n return p;\n },\n\n /**\n * Returns the real center coordinates of the object\n * @return {fabric.Point}\n */\n getCenterPoint: function () {\n var leftTop = new fabric.Point(this.left, this.top);\n return this.translateToCenterPoint(leftTop, this.originX, this.originY);\n },\n\n /**\n * Returns the coordinates of the object based on center coordinates\n * @param {fabric.Point} point The point which corresponds to the originX and originY params\n * @return {fabric.Point}\n */\n // getOriginPoint: function(center) {\n // return this.translateToOriginPoint(center, this.originX, this.originY);\n // },\n\n /**\n * Returns the coordinates of the object as if it has a different origin\n * @param {String} originX Horizontal origin: 'left', 'center' or 'right'\n * @param {String} originY Vertical origin: 'top', 'center' or 'bottom'\n * @return {fabric.Point}\n */\n getPointByOrigin: function (originX, originY) {\n var center = this.getCenterPoint();\n return this.translateToOriginPoint(center, originX, originY);\n },\n\n /**\n * Returns the point in local coordinates\n * @param {fabric.Point} point The point relative to the global coordinate system\n * @param {String} originX Horizontal origin: 'left', 'center' or 'right'\n * @param {String} originY Vertical origin: 'top', 'center' or 'bottom'\n * @return {fabric.Point}\n */\n toLocalPoint: function (point, originX, originY) {\n var center = this.getCenterPoint(),\n p,\n p2;\n\n if (typeof originX !== 'undefined' && typeof originY !== 'undefined') {\n p = this.translateToGivenOrigin(center, 'center', 'center', originX, originY);\n } else {\n p = new fabric.Point(this.left, this.top);\n }\n\n p2 = new fabric.Point(point.x, point.y);\n\n if (this.angle) {\n p2 = fabric.util.rotatePoint(p2, center, -degreesToRadians(this.angle));\n }\n\n return p2.subtractEquals(p);\n },\n\n /**\n * Returns the point in global coordinates\n * @param {fabric.Point} The point relative to the local coordinate system\n * @return {fabric.Point}\n */\n // toGlobalPoint: function(point) {\n // return fabric.util.rotatePoint(point, this.getCenterPoint(), degreesToRadians(this.angle)).addEquals(new fabric.Point(this.left, this.top));\n // },\n\n /**\n * Sets the position of the object taking into consideration the object's origin\n * @param {fabric.Point} pos The new position of the object\n * @param {String} originX Horizontal origin: 'left', 'center' or 'right'\n * @param {String} originY Vertical origin: 'top', 'center' or 'bottom'\n * @return {void}\n */\n setPositionByOrigin: function (pos, originX, originY) {\n var center = this.translateToCenterPoint(pos, originX, originY),\n position = this.translateToOriginPoint(center, this.originX, this.originY);\n this.set('left', position.x);\n this.set('top', position.y);\n },\n\n /**\n * @param {String} to One of 'left', 'center', 'right'\n */\n adjustPosition: function (to) {\n var angle = degreesToRadians(this.angle),\n hypotFull = this.getScaledWidth(),\n xFull = fabric.util.cos(angle) * hypotFull,\n yFull = fabric.util.sin(angle) * hypotFull,\n offsetFrom,\n offsetTo; //TODO: this function does not consider mixed situation like top, center.\n\n if (typeof this.originX === 'string') {\n offsetFrom = originXOffset[this.originX];\n } else {\n offsetFrom = this.originX - 0.5;\n }\n\n if (typeof to === 'string') {\n offsetTo = originXOffset[to];\n } else {\n offsetTo = to - 0.5;\n }\n\n this.left += xFull * (offsetTo - offsetFrom);\n this.top += yFull * (offsetTo - offsetFrom);\n this.setCoords();\n this.originX = to;\n },\n\n /**\n * Sets the origin/position of the object to it's center point\n * @private\n * @return {void}\n */\n _setOriginToCenter: function () {\n this._originalOriginX = this.originX;\n this._originalOriginY = this.originY;\n var center = this.getCenterPoint();\n this.originX = 'center';\n this.originY = 'center';\n this.left = center.x;\n this.top = center.y;\n },\n\n /**\n * Resets the origin/position of the object to it's original origin\n * @private\n * @return {void}\n */\n _resetOrigin: function () {\n var originPoint = this.translateToOriginPoint(this.getCenterPoint(), this._originalOriginX, this._originalOriginY);\n this.originX = this._originalOriginX;\n this.originY = this._originalOriginY;\n this.left = originPoint.x;\n this.top = originPoint.y;\n this._originalOriginX = null;\n this._originalOriginY = null;\n },\n\n /**\n * @private\n */\n _getLeftTopCoords: function () {\n return this.translateToOriginPoint(this.getCenterPoint(), 'left', 'top');\n }\n });\n})();\n\n(function () {\n function arrayFromCoords(coords) {\n return [new fabric.Point(coords.tl.x, coords.tl.y), new fabric.Point(coords.tr.x, coords.tr.y), new fabric.Point(coords.br.x, coords.br.y), new fabric.Point(coords.bl.x, coords.bl.y)];\n }\n\n var util = fabric.util,\n degreesToRadians = util.degreesToRadians,\n multiplyMatrices = util.multiplyTransformMatrices,\n transformPoint = util.transformPoint;\n util.object.extend(fabric.Object.prototype,\n /** @lends fabric.Object.prototype */\n {\n /**\n * Describe object's corner position in canvas element coordinates.\n * properties are depending on control keys and padding the main controls.\n * each property is an object with x, y and corner.\n * The `corner` property contains in a similar manner the 4 points of the\n * interactive area of the corner.\n * The coordinates depends from the controls positionHandler and are used\n * to draw and locate controls\n * @memberOf fabric.Object.prototype\n */\n oCoords: null,\n\n /**\n * Describe object's corner position in canvas object absolute coordinates\n * properties are tl,tr,bl,br and describe the four main corner.\n * each property is an object with x, y, instance of Fabric.Point.\n * The coordinates depends from this properties: width, height, scaleX, scaleY\n * skewX, skewY, angle, strokeWidth, top, left.\n * Those coordinates are useful to understand where an object is. They get updated\n * with oCoords but they do not need to be updated when zoom or panning change.\n * The coordinates get updated with @method setCoords.\n * You can calculate them without updating with @method calcACoords();\n * @memberOf fabric.Object.prototype\n */\n aCoords: null,\n\n /**\n * Describe object's corner position in canvas element coordinates.\n * includes padding. Used of object detection.\n * set and refreshed with setCoords and calcCoords.\n * @memberOf fabric.Object.prototype\n */\n lineCoords: null,\n\n /**\n * storage for object transform matrix\n */\n ownMatrixCache: null,\n\n /**\n * storage for object full transform matrix\n */\n matrixCache: null,\n\n /**\n * custom controls interface\n * controls are added by default_controls.js\n */\n controls: {},\n\n /**\n * return correct set of coordinates for intersection\n * this will return either aCoords or lineCoords.\n * @param {Boolean} absolute will return aCoords if true or lineCoords\n * @return {Object} {tl, tr, br, bl} points\n */\n _getCoords: function (absolute, calculate) {\n if (calculate) {\n return absolute ? this.calcACoords() : this.calcLineCoords();\n }\n\n if (!this.aCoords || !this.lineCoords) {\n this.setCoords(true);\n }\n\n return absolute ? this.aCoords : this.lineCoords;\n },\n\n /**\n * return correct set of coordinates for intersection\n * this will return either aCoords or lineCoords.\n * The coords are returned in an array.\n * @return {Array} [tl, tr, br, bl] of points\n */\n getCoords: function (absolute, calculate) {\n return arrayFromCoords(this._getCoords(absolute, calculate));\n },\n\n /**\n * Checks if object intersects with an area formed by 2 points\n * @param {Object} pointTL top-left point of area\n * @param {Object} pointBR bottom-right point of area\n * @param {Boolean} [absolute] use coordinates without viewportTransform\n * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords\n * @return {Boolean} true if object intersects with an area formed by 2 points\n */\n intersectsWithRect: function (pointTL, pointBR, absolute, calculate) {\n var coords = this.getCoords(absolute, calculate),\n intersection = fabric.Intersection.intersectPolygonRectangle(coords, pointTL, pointBR);\n return intersection.status === 'Intersection';\n },\n\n /**\n * Checks if object intersects with another object\n * @param {Object} other Object to test\n * @param {Boolean} [absolute] use coordinates without viewportTransform\n * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords\n * @return {Boolean} true if object intersects with another object\n */\n intersectsWithObject: function (other, absolute, calculate) {\n var intersection = fabric.Intersection.intersectPolygonPolygon(this.getCoords(absolute, calculate), other.getCoords(absolute, calculate));\n return intersection.status === 'Intersection' || other.isContainedWithinObject(this, absolute, calculate) || this.isContainedWithinObject(other, absolute, calculate);\n },\n\n /**\n * Checks if object is fully contained within area of another object\n * @param {Object} other Object to test\n * @param {Boolean} [absolute] use coordinates without viewportTransform\n * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords\n * @return {Boolean} true if object is fully contained within area of another object\n */\n isContainedWithinObject: function (other, absolute, calculate) {\n var points = this.getCoords(absolute, calculate),\n otherCoords = absolute ? other.aCoords : other.lineCoords,\n i = 0,\n lines = other._getImageLines(otherCoords);\n\n for (; i < 4; i++) {\n if (!other.containsPoint(points[i], lines)) {\n return false;\n }\n }\n\n return true;\n },\n\n /**\n * Checks if object is fully contained within area formed by 2 points\n * @param {Object} pointTL top-left point of area\n * @param {Object} pointBR bottom-right point of area\n * @param {Boolean} [absolute] use coordinates without viewportTransform\n * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords\n * @return {Boolean} true if object is fully contained within area formed by 2 points\n */\n isContainedWithinRect: function (pointTL, pointBR, absolute, calculate) {\n var boundingRect = this.getBoundingRect(absolute, calculate);\n return boundingRect.left >= pointTL.x && boundingRect.left + boundingRect.width <= pointBR.x && boundingRect.top >= pointTL.y && boundingRect.top + boundingRect.height <= pointBR.y;\n },\n\n /**\n * Checks if point is inside the object\n * @param {fabric.Point} point Point to check against\n * @param {Object} [lines] object returned from @method _getImageLines\n * @param {Boolean} [absolute] use coordinates without viewportTransform\n * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords\n * @return {Boolean} true if point is inside the object\n */\n containsPoint: function (point, lines, absolute, calculate) {\n var coords = this._getCoords(absolute, calculate),\n lines = lines || this._getImageLines(coords),\n xPoints = this._findCrossPoints(point, lines); // if xPoints is odd then point is inside the object\n\n\n return xPoints !== 0 && xPoints % 2 === 1;\n },\n\n /**\n * Checks if object is contained within the canvas with current viewportTransform\n * the check is done stopping at first point that appears on screen\n * @param {Boolean} [calculate] use coordinates of current position instead of .aCoords\n * @return {Boolean} true if object is fully or partially contained within canvas\n */\n isOnScreen: function (calculate) {\n if (!this.canvas) {\n return false;\n }\n\n var pointTL = this.canvas.vptCoords.tl,\n pointBR = this.canvas.vptCoords.br;\n var points = this.getCoords(true, calculate); // if some point is on screen, the object is on screen.\n\n if (points.some(function (point) {\n return point.x <= pointBR.x && point.x >= pointTL.x && point.y <= pointBR.y && point.y >= pointTL.y;\n })) {\n return true;\n } // no points on screen, check intersection with absolute coordinates\n\n\n if (this.intersectsWithRect(pointTL, pointBR, true, calculate)) {\n return true;\n }\n\n return this._containsCenterOfCanvas(pointTL, pointBR, calculate);\n },\n\n /**\n * Checks if the object contains the midpoint between canvas extremities\n * Does not make sense outside the context of isOnScreen and isPartiallyOnScreen\n * @private\n * @param {Fabric.Point} pointTL Top Left point\n * @param {Fabric.Point} pointBR Top Right point\n * @param {Boolean} calculate use coordinates of current position instead of .oCoords\n * @return {Boolean} true if the object contains the point\n */\n _containsCenterOfCanvas: function (pointTL, pointBR, calculate) {\n // worst case scenario the object is so big that contains the screen\n var centerPoint = {\n x: (pointTL.x + pointBR.x) / 2,\n y: (pointTL.y + pointBR.y) / 2\n };\n\n if (this.containsPoint(centerPoint, null, true, calculate)) {\n return true;\n }\n\n return false;\n },\n\n /**\n * Checks if object is partially contained within the canvas with current viewportTransform\n * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords\n * @return {Boolean} true if object is partially contained within canvas\n */\n isPartiallyOnScreen: function (calculate) {\n if (!this.canvas) {\n return false;\n }\n\n var pointTL = this.canvas.vptCoords.tl,\n pointBR = this.canvas.vptCoords.br;\n\n if (this.intersectsWithRect(pointTL, pointBR, true, calculate)) {\n return true;\n }\n\n var allPointsAreOutside = this.getCoords(true, calculate).every(function (point) {\n return (point.x >= pointBR.x || point.x <= pointTL.x) && (point.y >= pointBR.y || point.y <= pointTL.y);\n });\n return allPointsAreOutside && this._containsCenterOfCanvas(pointTL, pointBR, calculate);\n },\n\n /**\n * Method that returns an object with the object edges in it, given the coordinates of the corners\n * @private\n * @param {Object} oCoords Coordinates of the object corners\n */\n _getImageLines: function (oCoords) {\n var lines = {\n topline: {\n o: oCoords.tl,\n d: oCoords.tr\n },\n rightline: {\n o: oCoords.tr,\n d: oCoords.br\n },\n bottomline: {\n o: oCoords.br,\n d: oCoords.bl\n },\n leftline: {\n o: oCoords.bl,\n d: oCoords.tl\n }\n }; // // debugging\n // if (this.canvas.contextTop) {\n // this.canvas.contextTop.fillRect(lines.bottomline.d.x, lines.bottomline.d.y, 2, 2);\n // this.canvas.contextTop.fillRect(lines.bottomline.o.x, lines.bottomline.o.y, 2, 2);\n //\n // this.canvas.contextTop.fillRect(lines.leftline.d.x, lines.leftline.d.y, 2, 2);\n // this.canvas.contextTop.fillRect(lines.leftline.o.x, lines.leftline.o.y, 2, 2);\n //\n // this.canvas.contextTop.fillRect(lines.topline.d.x, lines.topline.d.y, 2, 2);\n // this.canvas.contextTop.fillRect(lines.topline.o.x, lines.topline.o.y, 2, 2);\n //\n // this.canvas.contextTop.fillRect(lines.rightline.d.x, lines.rightline.d.y, 2, 2);\n // this.canvas.contextTop.fillRect(lines.rightline.o.x, lines.rightline.o.y, 2, 2);\n // }\n\n return lines;\n },\n\n /**\n * Helper method to determine how many cross points are between the 4 object edges\n * and the horizontal line determined by a point on canvas\n * @private\n * @param {fabric.Point} point Point to check\n * @param {Object} lines Coordinates of the object being evaluated\n */\n // remove yi, not used but left code here just in case.\n _findCrossPoints: function (point, lines) {\n var b1,\n b2,\n a1,\n a2,\n xi,\n // yi,\n xcount = 0,\n iLine;\n\n for (var lineKey in lines) {\n iLine = lines[lineKey]; // optimisation 1: line below point. no cross\n\n if (iLine.o.y < point.y && iLine.d.y < point.y) {\n continue;\n } // optimisation 2: line above point. no cross\n\n\n if (iLine.o.y >= point.y && iLine.d.y >= point.y) {\n continue;\n } // optimisation 3: vertical line case\n\n\n if (iLine.o.x === iLine.d.x && iLine.o.x >= point.x) {\n xi = iLine.o.x; // yi = point.y;\n } // calculate the intersection point\n else {\n b1 = 0;\n b2 = (iLine.d.y - iLine.o.y) / (iLine.d.x - iLine.o.x);\n a1 = point.y - b1 * point.x;\n a2 = iLine.o.y - b2 * iLine.o.x;\n xi = -(a1 - a2) / (b1 - b2); // yi = a1 + b1 * xi;\n } // dont count xi < point.x cases\n\n\n if (xi >= point.x) {\n xcount += 1;\n } // optimisation 4: specific for square images\n\n\n if (xcount === 2) {\n break;\n }\n }\n\n return xcount;\n },\n\n /**\n * Returns coordinates of object's bounding rectangle (left, top, width, height)\n * the box is intended as aligned to axis of canvas.\n * @param {Boolean} [absolute] use coordinates without viewportTransform\n * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords / .aCoords\n * @return {Object} Object with left, top, width, height properties\n */\n getBoundingRect: function (absolute, calculate) {\n var coords = this.getCoords(absolute, calculate);\n return util.makeBoundingBoxFromPoints(coords);\n },\n\n /**\n * Returns width of an object's bounding box counting transformations\n * before 2.0 it was named getWidth();\n * @return {Number} width value\n */\n getScaledWidth: function () {\n return this._getTransformedDimensions().x;\n },\n\n /**\n * Returns height of an object bounding box counting transformations\n * before 2.0 it was named getHeight();\n * @return {Number} height value\n */\n getScaledHeight: function () {\n return this._getTransformedDimensions().y;\n },\n\n /**\n * Makes sure the scale is valid and modifies it if necessary\n * @private\n * @param {Number} value\n * @return {Number}\n */\n _constrainScale: function (value) {\n if (Math.abs(value) < this.minScaleLimit) {\n if (value < 0) {\n return -this.minScaleLimit;\n } else {\n return this.minScaleLimit;\n }\n } else if (value === 0) {\n return 0.0001;\n }\n\n return value;\n },\n\n /**\n * Scales an object (equally by x and y)\n * @param {Number} value Scale factor\n * @return {fabric.Object} thisArg\n * @chainable\n */\n scale: function (value) {\n this._set('scaleX', value);\n\n this._set('scaleY', value);\n\n return this.setCoords();\n },\n\n /**\n * Scales an object to a given width, with respect to bounding box (scaling by x/y equally)\n * @param {Number} value New width value\n * @param {Boolean} absolute ignore viewport\n * @return {fabric.Object} thisArg\n * @chainable\n */\n scaleToWidth: function (value, absolute) {\n // adjust to bounding rect factor so that rotated shapes would fit as well\n var boundingRectFactor = this.getBoundingRect(absolute).width / this.getScaledWidth();\n return this.scale(value / this.width / boundingRectFactor);\n },\n\n /**\n * Scales an object to a given height, with respect to bounding box (scaling by x/y equally)\n * @param {Number} value New height value\n * @param {Boolean} absolute ignore viewport\n * @return {fabric.Object} thisArg\n * @chainable\n */\n scaleToHeight: function (value, absolute) {\n // adjust to bounding rect factor so that rotated shapes would fit as well\n var boundingRectFactor = this.getBoundingRect(absolute).height / this.getScaledHeight();\n return this.scale(value / this.height / boundingRectFactor);\n },\n\n /**\n * Calculates and returns the .coords of an object.\n * unused by the library, only for the end dev.\n * @return {Object} Object with tl, tr, br, bl ....\n * @chainable\n * @deprecated\n */\n calcCoords: function (absolute) {\n // this is a compatibility function to avoid removing calcCoords now.\n if (absolute) {\n return this.calcACoords();\n }\n\n return this.calcOCoords();\n },\n calcLineCoords: function () {\n var vpt = this.getViewportTransform(),\n padding = this.padding,\n angle = degreesToRadians(this.angle),\n cos = util.cos(angle),\n sin = util.sin(angle),\n cosP = cos * padding,\n sinP = sin * padding,\n cosPSinP = cosP + sinP,\n cosPMinusSinP = cosP - sinP,\n aCoords = this.calcACoords();\n var lineCoords = {\n tl: transformPoint(aCoords.tl, vpt),\n tr: transformPoint(aCoords.tr, vpt),\n bl: transformPoint(aCoords.bl, vpt),\n br: transformPoint(aCoords.br, vpt)\n };\n\n if (padding) {\n lineCoords.tl.x -= cosPMinusSinP;\n lineCoords.tl.y -= cosPSinP;\n lineCoords.tr.x += cosPSinP;\n lineCoords.tr.y -= cosPMinusSinP;\n lineCoords.bl.x -= cosPSinP;\n lineCoords.bl.y += cosPMinusSinP;\n lineCoords.br.x += cosPMinusSinP;\n lineCoords.br.y += cosPSinP;\n }\n\n return lineCoords;\n },\n calcOCoords: function () {\n var rotateMatrix = this._calcRotateMatrix(),\n translateMatrix = this._calcTranslateMatrix(),\n vpt = this.getViewportTransform(),\n startMatrix = multiplyMatrices(vpt, translateMatrix),\n finalMatrix = multiplyMatrices(startMatrix, rotateMatrix),\n finalMatrix = multiplyMatrices(finalMatrix, [1 / vpt[0], 0, 0, 1 / vpt[3], 0, 0]),\n dim = this._calculateCurrentDimensions(),\n coords = {};\n\n this.forEachControl(function (control, key, fabricObject) {\n coords[key] = control.positionHandler(dim, finalMatrix, fabricObject);\n }); // debug code\n // var canvas = this.canvas;\n // setTimeout(function() {\n // canvas.contextTop.clearRect(0, 0, 700, 700);\n // canvas.contextTop.fillStyle = 'green';\n // Object.keys(coords).forEach(function(key) {\n // var control = coords[key];\n // canvas.contextTop.fillRect(control.x, control.y, 3, 3);\n // });\n // }, 50);\n\n return coords;\n },\n calcACoords: function () {\n var rotateMatrix = this._calcRotateMatrix(),\n translateMatrix = this._calcTranslateMatrix(),\n finalMatrix = multiplyMatrices(translateMatrix, rotateMatrix),\n dim = this._getTransformedDimensions(),\n w = dim.x / 2,\n h = dim.y / 2;\n\n return {\n // corners\n tl: transformPoint({\n x: -w,\n y: -h\n }, finalMatrix),\n tr: transformPoint({\n x: w,\n y: -h\n }, finalMatrix),\n bl: transformPoint({\n x: -w,\n y: h\n }, finalMatrix),\n br: transformPoint({\n x: w,\n y: h\n }, finalMatrix)\n };\n },\n\n /**\n * Sets corner position coordinates based on current angle, width and height.\n * oCoords are used to find the corners\n * aCoords are used to quickly find an object on the canvas\n * lineCoords are used to quickly find object during pointer events.\n * See {@link https://github.com/kangax/fabric.js/wiki/When-to-call-setCoords|When-to-call-setCoords}\n * @param {Boolean} [skipCorners] skip calculation of oCoords.\n * @return {fabric.Object} thisArg\n * @chainable\n */\n setCoords: function (skipCorners) {\n this.aCoords = this.calcACoords(); // in case we are in a group, for how the inner group target check works,\n // lineCoords are exactly aCoords. Since the vpt gets absorbed by the normalized pointer.\n\n this.lineCoords = this.group ? this.aCoords : this.calcLineCoords();\n\n if (skipCorners) {\n return this;\n } // set coordinates of the draggable boxes in the corners used to scale/rotate the image\n\n\n this.oCoords = this.calcOCoords();\n this._setCornerCoords && this._setCornerCoords();\n return this;\n },\n\n /**\n * calculate rotation matrix of an object\n * @return {Array} rotation matrix for the object\n */\n _calcRotateMatrix: function () {\n return util.calcRotateMatrix(this);\n },\n\n /**\n * calculate the translation matrix for an object transform\n * @return {Array} rotation matrix for the object\n */\n _calcTranslateMatrix: function () {\n var center = this.getCenterPoint();\n return [1, 0, 0, 1, center.x, center.y];\n },\n transformMatrixKey: function (skipGroup) {\n var sep = '_',\n prefix = '';\n\n if (!skipGroup && this.group) {\n prefix = this.group.transformMatrixKey(skipGroup) + sep;\n }\n\n ;\n return prefix + this.top + sep + this.left + sep + this.scaleX + sep + this.scaleY + sep + this.skewX + sep + this.skewY + sep + this.angle + sep + this.originX + sep + this.originY + sep + this.width + sep + this.height + sep + this.strokeWidth + this.flipX + this.flipY;\n },\n\n /**\n * calculate transform matrix that represents the current transformations from the\n * object's properties.\n * @param {Boolean} [skipGroup] return transform matrix for object not counting parent transformations\n * There are some situation in which this is useful to avoid the fake rotation.\n * @return {Array} transform matrix for the object\n */\n calcTransformMatrix: function (skipGroup) {\n var matrix = this.calcOwnMatrix();\n\n if (skipGroup || !this.group) {\n return matrix;\n }\n\n var key = this.transformMatrixKey(skipGroup),\n cache = this.matrixCache || (this.matrixCache = {});\n\n if (cache.key === key) {\n return cache.value;\n }\n\n if (this.group) {\n matrix = multiplyMatrices(this.group.calcTransformMatrix(false), matrix);\n }\n\n cache.key = key;\n cache.value = matrix;\n return matrix;\n },\n\n /**\n * calculate transform matrix that represents the current transformations from the\n * object's properties, this matrix does not include the group transformation\n * @return {Array} transform matrix for the object\n */\n calcOwnMatrix: function () {\n var key = this.transformMatrixKey(true),\n cache = this.ownMatrixCache || (this.ownMatrixCache = {});\n\n if (cache.key === key) {\n return cache.value;\n }\n\n var tMatrix = this._calcTranslateMatrix(),\n options = {\n angle: this.angle,\n translateX: tMatrix[4],\n translateY: tMatrix[5],\n scaleX: this.scaleX,\n scaleY: this.scaleY,\n skewX: this.skewX,\n skewY: this.skewY,\n flipX: this.flipX,\n flipY: this.flipY\n };\n\n cache.key = key;\n cache.value = util.composeMatrix(options);\n return cache.value;\n },\n\n /*\n * Calculate object dimensions from its properties\n * @private\n * @deprecated since 3.4.0, please use fabric.util._calcDimensionsTransformMatrix\n * not including or including flipX, flipY to emulate the flipping boolean\n * @return {Object} .x width dimension\n * @return {Object} .y height dimension\n */\n _calcDimensionsTransformMatrix: function (skewX, skewY, flipping) {\n return util.calcDimensionsMatrix({\n skewX: skewX,\n skewY: skewY,\n scaleX: this.scaleX * (flipping && this.flipX ? -1 : 1),\n scaleY: this.scaleY * (flipping && this.flipY ? -1 : 1)\n });\n },\n\n /*\n * Calculate object dimensions from its properties\n * @private\n * @return {Object} .x width dimension\n * @return {Object} .y height dimension\n */\n _getNonTransformedDimensions: function () {\n var strokeWidth = this.strokeWidth,\n w = this.width + strokeWidth,\n h = this.height + strokeWidth;\n return {\n x: w,\n y: h\n };\n },\n\n /*\n * Calculate object bounding box dimensions from its properties scale, skew.\n * @param {Number} skewX, a value to override current skewX\n * @param {Number} skewY, a value to override current skewY\n * @private\n * @return {Object} .x width dimension\n * @return {Object} .y height dimension\n */\n _getTransformedDimensions: function (skewX, skewY) {\n if (typeof skewX === 'undefined') {\n skewX = this.skewX;\n }\n\n if (typeof skewY === 'undefined') {\n skewY = this.skewY;\n }\n\n var dimensions = this._getNonTransformedDimensions(),\n dimX,\n dimY,\n noSkew = skewX === 0 && skewY === 0;\n\n if (this.strokeUniform) {\n dimX = this.width;\n dimY = this.height;\n } else {\n dimX = dimensions.x;\n dimY = dimensions.y;\n }\n\n if (noSkew) {\n return this._finalizeDimensions(dimX * this.scaleX, dimY * this.scaleY);\n }\n\n var bbox = util.sizeAfterTransform(dimX, dimY, {\n scaleX: this.scaleX,\n scaleY: this.scaleY,\n skewX: skewX,\n skewY: skewY\n });\n return this._finalizeDimensions(bbox.x, bbox.y);\n },\n\n /*\n * Calculate object bounding box dimensions from its properties scale, skew.\n * @param Number width width of the bbox\n * @param Number height height of the bbox\n * @private\n * @return {Object} .x finalized width dimension\n * @return {Object} .y finalized height dimension\n */\n _finalizeDimensions: function (width, height) {\n return this.strokeUniform ? {\n x: width + this.strokeWidth,\n y: height + this.strokeWidth\n } : {\n x: width,\n y: height\n };\n },\n\n /*\n * Calculate object dimensions for controls box, including padding and canvas zoom.\n * and active selection\n * private\n */\n _calculateCurrentDimensions: function () {\n var vpt = this.getViewportTransform(),\n dim = this._getTransformedDimensions(),\n p = transformPoint(dim, vpt, true);\n\n return p.scalarAdd(2 * this.padding);\n }\n });\n})();\n\nfabric.util.object.extend(fabric.Object.prototype,\n/** @lends fabric.Object.prototype */\n{\n /**\n * Moves an object to the bottom of the stack of drawn objects\n * @return {fabric.Object} thisArg\n * @chainable\n */\n sendToBack: function () {\n if (this.group) {\n fabric.StaticCanvas.prototype.sendToBack.call(this.group, this);\n } else if (this.canvas) {\n this.canvas.sendToBack(this);\n }\n\n return this;\n },\n\n /**\n * Moves an object to the top of the stack of drawn objects\n * @return {fabric.Object} thisArg\n * @chainable\n */\n bringToFront: function () {\n if (this.group) {\n fabric.StaticCanvas.prototype.bringToFront.call(this.group, this);\n } else if (this.canvas) {\n this.canvas.bringToFront(this);\n }\n\n return this;\n },\n\n /**\n * Moves an object down in stack of drawn objects\n * @param {Boolean} [intersecting] If `true`, send object behind next lower intersecting object\n * @return {fabric.Object} thisArg\n * @chainable\n */\n sendBackwards: function (intersecting) {\n if (this.group) {\n fabric.StaticCanvas.prototype.sendBackwards.call(this.group, this, intersecting);\n } else if (this.canvas) {\n this.canvas.sendBackwards(this, intersecting);\n }\n\n return this;\n },\n\n /**\n * Moves an object up in stack of drawn objects\n * @param {Boolean} [intersecting] If `true`, send object in front of next upper intersecting object\n * @return {fabric.Object} thisArg\n * @chainable\n */\n bringForward: function (intersecting) {\n if (this.group) {\n fabric.StaticCanvas.prototype.bringForward.call(this.group, this, intersecting);\n } else if (this.canvas) {\n this.canvas.bringForward(this, intersecting);\n }\n\n return this;\n },\n\n /**\n * Moves an object to specified level in stack of drawn objects\n * @param {Number} index New position of object\n * @return {fabric.Object} thisArg\n * @chainable\n */\n moveTo: function (index) {\n if (this.group && this.group.type !== 'activeSelection') {\n fabric.StaticCanvas.prototype.moveTo.call(this.group, this, index);\n } else if (this.canvas) {\n this.canvas.moveTo(this, index);\n }\n\n return this;\n }\n});\n/* _TO_SVG_START_ */\n\n(function () {\n function getSvgColorString(prop, value) {\n if (!value) {\n return prop + ': none; ';\n } else if (value.toLive) {\n return prop + ': url(#SVGID_' + value.id + '); ';\n } else {\n var color = new fabric.Color(value),\n str = prop + ': ' + color.toRgb() + '; ',\n opacity = color.getAlpha();\n\n if (opacity !== 1) {\n //change the color in rgb + opacity\n str += prop + '-opacity: ' + opacity.toString() + '; ';\n }\n\n return str;\n }\n }\n\n var toFixed = fabric.util.toFixed;\n fabric.util.object.extend(fabric.Object.prototype,\n /** @lends fabric.Object.prototype */\n {\n /**\n * Returns styles-string for svg-export\n * @param {Boolean} skipShadow a boolean to skip shadow filter output\n * @return {String}\n */\n getSvgStyles: function (skipShadow) {\n var fillRule = this.fillRule ? this.fillRule : 'nonzero',\n strokeWidth = this.strokeWidth ? this.strokeWidth : '0',\n strokeDashArray = this.strokeDashArray ? this.strokeDashArray.join(' ') : 'none',\n strokeDashOffset = this.strokeDashOffset ? this.strokeDashOffset : '0',\n strokeLineCap = this.strokeLineCap ? this.strokeLineCap : 'butt',\n strokeLineJoin = this.strokeLineJoin ? this.strokeLineJoin : 'miter',\n strokeMiterLimit = this.strokeMiterLimit ? this.strokeMiterLimit : '4',\n opacity = typeof this.opacity !== 'undefined' ? this.opacity : '1',\n visibility = this.visible ? '' : ' visibility: hidden;',\n filter = skipShadow ? '' : this.getSvgFilter(),\n fill = getSvgColorString('fill', this.fill),\n stroke = getSvgColorString('stroke', this.stroke);\n return [stroke, 'stroke-width: ', strokeWidth, '; ', 'stroke-dasharray: ', strokeDashArray, '; ', 'stroke-linecap: ', strokeLineCap, '; ', 'stroke-dashoffset: ', strokeDashOffset, '; ', 'stroke-linejoin: ', strokeLineJoin, '; ', 'stroke-miterlimit: ', strokeMiterLimit, '; ', fill, 'fill-rule: ', fillRule, '; ', 'opacity: ', opacity, ';', filter, visibility].join('');\n },\n\n /**\n * Returns styles-string for svg-export\n * @param {Object} style the object from which to retrieve style properties\n * @param {Boolean} useWhiteSpace a boolean to include an additional attribute in the style.\n * @return {String}\n */\n getSvgSpanStyles: function (style, useWhiteSpace) {\n var term = '; ';\n var fontFamily = style.fontFamily ? 'font-family: ' + (style.fontFamily.indexOf('\\'') === -1 && style.fontFamily.indexOf('\"') === -1 ? '\\'' + style.fontFamily + '\\'' : style.fontFamily) + term : '';\n var strokeWidth = style.strokeWidth ? 'stroke-width: ' + style.strokeWidth + term : '',\n fontFamily = fontFamily,\n fontSize = style.fontSize ? 'font-size: ' + style.fontSize + 'px' + term : '',\n fontStyle = style.fontStyle ? 'font-style: ' + style.fontStyle + term : '',\n fontWeight = style.fontWeight ? 'font-weight: ' + style.fontWeight + term : '',\n fill = style.fill ? getSvgColorString('fill', style.fill) : '',\n stroke = style.stroke ? getSvgColorString('stroke', style.stroke) : '',\n textDecoration = this.getSvgTextDecoration(style),\n deltaY = style.deltaY ? 'baseline-shift: ' + -style.deltaY + '; ' : '';\n\n if (textDecoration) {\n textDecoration = 'text-decoration: ' + textDecoration + term;\n }\n\n return [stroke, strokeWidth, fontFamily, fontSize, fontStyle, fontWeight, textDecoration, fill, deltaY, useWhiteSpace ? 'white-space: pre; ' : ''].join('');\n },\n\n /**\n * Returns text-decoration property for svg-export\n * @param {Object} style the object from which to retrieve style properties\n * @return {String}\n */\n getSvgTextDecoration: function (style) {\n return ['overline', 'underline', 'line-through'].filter(function (decoration) {\n return style[decoration.replace('-', '')];\n }).join(' ');\n },\n\n /**\n * Returns filter for svg shadow\n * @return {String}\n */\n getSvgFilter: function () {\n return this.shadow ? 'filter: url(#SVGID_' + this.shadow.id + ');' : '';\n },\n\n /**\n * Returns id attribute for svg output\n * @return {String}\n */\n getSvgCommons: function () {\n return [this.id ? 'id=\"' + this.id + '\" ' : '', this.clipPath ? 'clip-path=\"url(#' + this.clipPath.clipPathId + ')\" ' : ''].join('');\n },\n\n /**\n * Returns transform-string for svg-export\n * @param {Boolean} use the full transform or the single object one.\n * @return {String}\n */\n getSvgTransform: function (full, additionalTransform) {\n var transform = full ? this.calcTransformMatrix() : this.calcOwnMatrix(),\n svgTransform = 'transform=\"' + fabric.util.matrixToSVG(transform);\n return svgTransform + (additionalTransform || '') + '\" ';\n },\n _setSVGBg: function (textBgRects) {\n if (this.backgroundColor) {\n var NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS;\n textBgRects.push('\\t\\t<rect ', this._getFillAttributes(this.backgroundColor), ' x=\"', toFixed(-this.width / 2, NUM_FRACTION_DIGITS), '\" y=\"', toFixed(-this.height / 2, NUM_FRACTION_DIGITS), '\" width=\"', toFixed(this.width, NUM_FRACTION_DIGITS), '\" height=\"', toFixed(this.height, NUM_FRACTION_DIGITS), '\"></rect>\\n');\n }\n },\n\n /**\n * Returns svg representation of an instance\n * @param {Function} [reviver] Method for further parsing of svg representation.\n * @return {String} svg representation of an instance\n */\n toSVG: function (reviver) {\n return this._createBaseSVGMarkup(this._toSVG(reviver), {\n reviver: reviver\n });\n },\n\n /**\n * Returns svg clipPath representation of an instance\n * @param {Function} [reviver] Method for further parsing of svg representation.\n * @return {String} svg representation of an instance\n */\n toClipPathSVG: function (reviver) {\n return '\\t' + this._createBaseClipPathSVGMarkup(this._toSVG(reviver), {\n reviver: reviver\n });\n },\n\n /**\n * @private\n */\n _createBaseClipPathSVGMarkup: function (objectMarkup, options) {\n options = options || {};\n var reviver = options.reviver,\n additionalTransform = options.additionalTransform || '',\n commonPieces = [this.getSvgTransform(true, additionalTransform), this.getSvgCommons()].join(''),\n // insert commons in the markup, style and svgCommons\n index = objectMarkup.indexOf('COMMON_PARTS');\n objectMarkup[index] = commonPieces;\n return reviver ? reviver(objectMarkup.join('')) : objectMarkup.join('');\n },\n\n /**\n * @private\n */\n _createBaseSVGMarkup: function (objectMarkup, options) {\n options = options || {};\n var noStyle = options.noStyle,\n reviver = options.reviver,\n styleInfo = noStyle ? '' : 'style=\"' + this.getSvgStyles() + '\" ',\n shadowInfo = options.withShadow ? 'style=\"' + this.getSvgFilter() + '\" ' : '',\n clipPath = this.clipPath,\n vectorEffect = this.strokeUniform ? 'vector-effect=\"non-scaling-stroke\" ' : '',\n absoluteClipPath = clipPath && clipPath.absolutePositioned,\n stroke = this.stroke,\n fill = this.fill,\n shadow = this.shadow,\n commonPieces,\n markup = [],\n clipPathMarkup,\n // insert commons in the markup, style and svgCommons\n index = objectMarkup.indexOf('COMMON_PARTS'),\n additionalTransform = options.additionalTransform;\n\n if (clipPath) {\n clipPath.clipPathId = 'CLIPPATH_' + fabric.Object.__uid++;\n clipPathMarkup = '<clipPath id=\"' + clipPath.clipPathId + '\" >\\n' + clipPath.toClipPathSVG(reviver) + '</clipPath>\\n';\n }\n\n if (absoluteClipPath) {\n markup.push('<g ', shadowInfo, this.getSvgCommons(), ' >\\n');\n }\n\n markup.push('<g ', this.getSvgTransform(false), !absoluteClipPath ? shadowInfo + this.getSvgCommons() : '', ' >\\n');\n commonPieces = [styleInfo, vectorEffect, noStyle ? '' : this.addPaintOrder(), ' ', additionalTransform ? 'transform=\"' + additionalTransform + '\" ' : ''].join('');\n objectMarkup[index] = commonPieces;\n\n if (fill && fill.toLive) {\n markup.push(fill.toSVG(this));\n }\n\n if (stroke && stroke.toLive) {\n markup.push(stroke.toSVG(this));\n }\n\n if (shadow) {\n markup.push(shadow.toSVG(this));\n }\n\n if (clipPath) {\n markup.push(clipPathMarkup);\n }\n\n markup.push(objectMarkup.join(''));\n markup.push('</g>\\n');\n absoluteClipPath && markup.push('</g>\\n');\n return reviver ? reviver(markup.join('')) : markup.join('');\n },\n addPaintOrder: function () {\n return this.paintFirst !== 'fill' ? ' paint-order=\"' + this.paintFirst + '\" ' : '';\n }\n });\n})();\n/* _TO_SVG_END_ */\n\n\n(function () {\n var extend = fabric.util.object.extend,\n originalSet = 'stateProperties';\n /*\n Depends on `stateProperties`\n */\n\n function saveProps(origin, destination, props) {\n var tmpObj = {},\n deep = true;\n props.forEach(function (prop) {\n tmpObj[prop] = origin[prop];\n });\n extend(origin[destination], tmpObj, deep);\n }\n\n function _isEqual(origValue, currentValue, firstPass) {\n if (origValue === currentValue) {\n // if the objects are identical, return\n return true;\n } else if (Array.isArray(origValue)) {\n if (!Array.isArray(currentValue) || origValue.length !== currentValue.length) {\n return false;\n }\n\n for (var i = 0, len = origValue.length; i < len; i++) {\n if (!_isEqual(origValue[i], currentValue[i])) {\n return false;\n }\n }\n\n return true;\n } else if (origValue && typeof origValue === 'object') {\n var keys = Object.keys(origValue),\n key;\n\n if (!currentValue || typeof currentValue !== 'object' || !firstPass && keys.length !== Object.keys(currentValue).length) {\n return false;\n }\n\n for (var i = 0, len = keys.length; i < len; i++) {\n key = keys[i]; // since clipPath is in the statefull cache list and the clipPath objects\n // would be iterated as an object, this would lead to possible infinite recursion\n // we do not want to compare those.\n\n if (key === 'canvas' || key === 'group') {\n continue;\n }\n\n if (!_isEqual(origValue[key], currentValue[key])) {\n return false;\n }\n }\n\n return true;\n }\n }\n\n fabric.util.object.extend(fabric.Object.prototype,\n /** @lends fabric.Object.prototype */\n {\n /**\n * Returns true if object state (one of its state properties) was changed\n * @param {String} [propertySet] optional name for the set of property we want to save\n * @return {Boolean} true if instance' state has changed since `{@link fabric.Object#saveState}` was called\n */\n hasStateChanged: function (propertySet) {\n propertySet = propertySet || originalSet;\n var dashedPropertySet = '_' + propertySet;\n\n if (Object.keys(this[dashedPropertySet]).length < this[propertySet].length) {\n return true;\n }\n\n return !_isEqual(this[dashedPropertySet], this, true);\n },\n\n /**\n * Saves state of an object\n * @param {Object} [options] Object with additional `stateProperties` array to include when saving state\n * @return {fabric.Object} thisArg\n */\n saveState: function (options) {\n var propertySet = options && options.propertySet || originalSet,\n destination = '_' + propertySet;\n\n if (!this[destination]) {\n return this.setupState(options);\n }\n\n saveProps(this, destination, this[propertySet]);\n\n if (options && options.stateProperties) {\n saveProps(this, destination, options.stateProperties);\n }\n\n return this;\n },\n\n /**\n * Setups state of an object\n * @param {Object} [options] Object with additional `stateProperties` array to include when saving state\n * @return {fabric.Object} thisArg\n */\n setupState: function (options) {\n options = options || {};\n var propertySet = options.propertySet || originalSet;\n options.propertySet = propertySet;\n this['_' + propertySet] = {};\n this.saveState(options);\n return this;\n }\n });\n})();\n\n(function () {\n var degreesToRadians = fabric.util.degreesToRadians;\n fabric.util.object.extend(fabric.Object.prototype,\n /** @lends fabric.Object.prototype */\n {\n /**\n * Determines which corner has been clicked\n * @private\n * @param {Object} pointer The pointer indicating the mouse position\n * @return {String|Boolean} corner code (tl, tr, bl, br, etc.), or false if nothing is found\n */\n _findTargetCorner: function (pointer, forTouch) {\n // objects in group, anykind, are not self modificable,\n // must not return an hovered corner.\n if (!this.hasControls || this.group || !this.canvas || this.canvas._activeObject !== this) {\n return false;\n }\n\n var ex = pointer.x,\n ey = pointer.y,\n xPoints,\n lines,\n keys = Object.keys(this.oCoords),\n j = keys.length - 1,\n i;\n this.__corner = 0; // cycle in reverse order so we pick first the one on top\n\n for (; j >= 0; j--) {\n i = keys[j];\n\n if (!this.isControlVisible(i)) {\n continue;\n }\n\n lines = this._getImageLines(forTouch ? this.oCoords[i].touchCorner : this.oCoords[i].corner); // debugging\n // this.canvas.contextTop.fillRect(lines.bottomline.d.x, lines.bottomline.d.y, 2, 2);\n // this.canvas.contextTop.fillRect(lines.bottomline.o.x, lines.bottomline.o.y, 2, 2);\n //\n // this.canvas.contextTop.fillRect(lines.leftline.d.x, lines.leftline.d.y, 2, 2);\n // this.canvas.contextTop.fillRect(lines.leftline.o.x, lines.leftline.o.y, 2, 2);\n //\n // this.canvas.contextTop.fillRect(lines.topline.d.x, lines.topline.d.y, 2, 2);\n // this.canvas.contextTop.fillRect(lines.topline.o.x, lines.topline.o.y, 2, 2);\n //\n // this.canvas.contextTop.fillRect(lines.rightline.d.x, lines.rightline.d.y, 2, 2);\n // this.canvas.contextTop.fillRect(lines.rightline.o.x, lines.rightline.o.y, 2, 2);\n\n xPoints = this._findCrossPoints({\n x: ex,\n y: ey\n }, lines);\n\n if (xPoints !== 0 && xPoints % 2 === 1) {\n this.__corner = i;\n return i;\n }\n }\n\n return false;\n },\n\n /**\n * Calls a function for each control. The function gets called,\n * with the control, the object that is calling the iterator and the control's key\n * @param {Function} fn function to iterate over the controls over\n */\n forEachControl: function (fn) {\n for (var i in this.controls) {\n fn(this.controls[i], i, this);\n }\n\n ;\n },\n\n /**\n * Sets the coordinates of the draggable boxes in the corners of\n * the image used to scale/rotate it.\n * note: if we would switch to ROUND corner area, all of this would disappear.\n * everything would resolve to a single point and a pythagorean theorem for the distance\n * @private\n */\n _setCornerCoords: function () {\n var coords = this.oCoords,\n newTheta = degreesToRadians(45 - this.angle),\n cosTheta = fabric.util.cos(newTheta),\n sinTheta = fabric.util.sin(newTheta),\n\n /* Math.sqrt(2 * Math.pow(this.cornerSize, 2)) / 2, */\n\n /* 0.707106 stands for sqrt(2)/2 */\n cornerHypotenuse = this.cornerSize * 0.707106,\n touchHypotenuse = this.touchCornerSize * 0.707106,\n cosHalfOffset = cornerHypotenuse * cosTheta,\n sinHalfOffset = cornerHypotenuse * sinTheta,\n touchCosHalfOffset = touchHypotenuse * cosTheta,\n touchSinHalfOffset = touchHypotenuse * sinTheta,\n x,\n y;\n\n for (var control in coords) {\n x = coords[control].x;\n y = coords[control].y;\n coords[control].corner = {\n tl: {\n x: x - sinHalfOffset,\n y: y - cosHalfOffset\n },\n tr: {\n x: x + cosHalfOffset,\n y: y - sinHalfOffset\n },\n bl: {\n x: x - cosHalfOffset,\n y: y + sinHalfOffset\n },\n br: {\n x: x + sinHalfOffset,\n y: y + cosHalfOffset\n }\n };\n coords[control].touchCorner = {\n tl: {\n x: x - touchSinHalfOffset,\n y: y - touchCosHalfOffset\n },\n tr: {\n x: x + touchCosHalfOffset,\n y: y - touchSinHalfOffset\n },\n bl: {\n x: x - touchCosHalfOffset,\n y: y + touchSinHalfOffset\n },\n br: {\n x: x + touchSinHalfOffset,\n y: y + touchCosHalfOffset\n }\n };\n }\n },\n\n /**\n * Draws a colored layer behind the object, inside its selection borders.\n * Requires public options: padding, selectionBackgroundColor\n * this function is called when the context is transformed\n * has checks to be skipped when the object is on a staticCanvas\n * @param {CanvasRenderingContext2D} ctx Context to draw on\n * @return {fabric.Object} thisArg\n * @chainable\n */\n drawSelectionBackground: function (ctx) {\n if (!this.selectionBackgroundColor || this.canvas && !this.canvas.interactive || this.canvas && this.canvas._activeObject !== this) {\n return this;\n }\n\n ctx.save();\n\n var center = this.getCenterPoint(),\n wh = this._calculateCurrentDimensions(),\n vpt = this.canvas.viewportTransform;\n\n ctx.translate(center.x, center.y);\n ctx.scale(1 / vpt[0], 1 / vpt[3]);\n ctx.rotate(degreesToRadians(this.angle));\n ctx.fillStyle = this.selectionBackgroundColor;\n ctx.fillRect(-wh.x / 2, -wh.y / 2, wh.x, wh.y);\n ctx.restore();\n return this;\n },\n\n /**\n * Draws borders of an object's bounding box.\n * Requires public properties: width, height\n * Requires public options: padding, borderColor\n * @param {CanvasRenderingContext2D} ctx Context to draw on\n * @param {Object} styleOverride object to override the object style\n * @return {fabric.Object} thisArg\n * @chainable\n */\n drawBorders: function (ctx, styleOverride) {\n styleOverride = styleOverride || {};\n\n var wh = this._calculateCurrentDimensions(),\n strokeWidth = this.borderScaleFactor,\n width = wh.x + strokeWidth,\n height = wh.y + strokeWidth,\n hasControls = typeof styleOverride.hasControls !== 'undefined' ? styleOverride.hasControls : this.hasControls,\n shouldStroke = false;\n\n ctx.save();\n ctx.strokeStyle = styleOverride.borderColor || this.borderColor;\n\n this._setLineDash(ctx, styleOverride.borderDashArray || this.borderDashArray, null);\n\n ctx.strokeRect(-width / 2, -height / 2, width, height);\n\n if (hasControls) {\n ctx.beginPath();\n this.forEachControl(function (control, key, fabricObject) {\n // in this moment, the ctx is centered on the object.\n // width and height of the above function are the size of the bbox.\n if (control.withConnection && control.getVisibility(fabricObject, key)) {\n // reset movement for each control\n shouldStroke = true;\n ctx.moveTo(control.x * width, control.y * height);\n ctx.lineTo(control.x * width + control.offsetX, control.y * height + control.offsetY);\n }\n });\n\n if (shouldStroke) {\n ctx.stroke();\n }\n }\n\n ctx.restore();\n return this;\n },\n\n /**\n * Draws borders of an object's bounding box when it is inside a group.\n * Requires public properties: width, height\n * Requires public options: padding, borderColor\n * @param {CanvasRenderingContext2D} ctx Context to draw on\n * @param {object} options object representing current object parameters\n * @param {Object} styleOverride object to override the object style\n * @return {fabric.Object} thisArg\n * @chainable\n */\n drawBordersInGroup: function (ctx, options, styleOverride) {\n styleOverride = styleOverride || {};\n var bbox = fabric.util.sizeAfterTransform(this.width, this.height, options),\n strokeWidth = this.strokeWidth,\n strokeUniform = this.strokeUniform,\n borderScaleFactor = this.borderScaleFactor,\n width = bbox.x + strokeWidth * (strokeUniform ? this.canvas.getZoom() : options.scaleX) + borderScaleFactor,\n height = bbox.y + strokeWidth * (strokeUniform ? this.canvas.getZoom() : options.scaleY) + borderScaleFactor;\n ctx.save();\n\n this._setLineDash(ctx, styleOverride.borderDashArray || this.borderDashArray, null);\n\n ctx.strokeStyle = styleOverride.borderColor || this.borderColor;\n ctx.strokeRect(-width / 2, -height / 2, width, height);\n ctx.restore();\n return this;\n },\n\n /**\n * Draws corners of an object's bounding box.\n * Requires public properties: width, height\n * Requires public options: cornerSize, padding\n * @param {CanvasRenderingContext2D} ctx Context to draw on\n * @param {Object} styleOverride object to override the object style\n * @return {fabric.Object} thisArg\n * @chainable\n */\n drawControls: function (ctx, styleOverride) {\n styleOverride = styleOverride || {};\n ctx.save();\n ctx.setTransform(this.canvas.getRetinaScaling(), 0, 0, this.canvas.getRetinaScaling(), 0, 0);\n ctx.strokeStyle = ctx.fillStyle = styleOverride.cornerColor || this.cornerColor;\n\n if (!this.transparentCorners) {\n ctx.strokeStyle = styleOverride.cornerStrokeColor || this.cornerStrokeColor;\n }\n\n this._setLineDash(ctx, styleOverride.cornerDashArray || this.cornerDashArray, null);\n\n this.setCoords();\n this.forEachControl(function (control, key, fabricObject) {\n if (control.getVisibility(fabricObject, key)) {\n control.render(ctx, fabricObject.oCoords[key].x, fabricObject.oCoords[key].y, styleOverride, fabricObject);\n }\n });\n ctx.restore();\n return this;\n },\n\n /**\n * Returns true if the specified control is visible, false otherwise.\n * @param {String} controlKey The key of the control. Possible values are 'tl', 'tr', 'br', 'bl', 'ml', 'mt', 'mr', 'mb', 'mtr'.\n * @returns {Boolean} true if the specified control is visible, false otherwise\n */\n isControlVisible: function (controlKey) {\n return this.controls[controlKey] && this.controls[controlKey].getVisibility(this, controlKey);\n },\n\n /**\n * Sets the visibility of the specified control.\n * @param {String} controlKey The key of the control. Possible values are 'tl', 'tr', 'br', 'bl', 'ml', 'mt', 'mr', 'mb', 'mtr'.\n * @param {Boolean} visible true to set the specified control visible, false otherwise\n * @return {fabric.Object} thisArg\n * @chainable\n */\n setControlVisible: function (controlKey, visible) {\n if (!this._controlsVisibility) {\n this._controlsVisibility = {};\n }\n\n this._controlsVisibility[controlKey] = visible;\n return this;\n },\n\n /**\n * Sets the visibility state of object controls.\n * @param {Object} [options] Options object\n * @param {Boolean} [options.bl] true to enable the bottom-left control, false to disable it\n * @param {Boolean} [options.br] true to enable the bottom-right control, false to disable it\n * @param {Boolean} [options.mb] true to enable the middle-bottom control, false to disable it\n * @param {Boolean} [options.ml] true to enable the middle-left control, false to disable it\n * @param {Boolean} [options.mr] true to enable the middle-right control, false to disable it\n * @param {Boolean} [options.mt] true to enable the middle-top control, false to disable it\n * @param {Boolean} [options.tl] true to enable the top-left control, false to disable it\n * @param {Boolean} [options.tr] true to enable the top-right control, false to disable it\n * @param {Boolean} [options.mtr] true to enable the middle-top-rotate control, false to disable it\n * @return {fabric.Object} thisArg\n * @chainable\n */\n setControlsVisibility: function (options) {\n options || (options = {});\n\n for (var p in options) {\n this.setControlVisible(p, options[p]);\n }\n\n return this;\n },\n\n /**\n * This callback function is called every time _discardActiveObject or _setActiveObject\n * try to to deselect this object. If the function returns true, the process is cancelled\n * @param {Object} [options] options sent from the upper functions\n * @param {Event} [options.e] event if the process is generated by an event\n */\n onDeselect: function () {// implemented by sub-classes, as needed.\n },\n\n /**\n * This callback function is called every time _discardActiveObject or _setActiveObject\n * try to to select this object. If the function returns true, the process is cancelled\n * @param {Object} [options] options sent from the upper functions\n * @param {Event} [options.e] event if the process is generated by an event\n */\n onSelect: function () {// implemented by sub-classes, as needed.\n }\n });\n})();\n\nfabric.util.object.extend(fabric.StaticCanvas.prototype,\n/** @lends fabric.StaticCanvas.prototype */\n{\n /**\n * Animation duration (in ms) for fx* methods\n * @type Number\n * @default\n */\n FX_DURATION: 500,\n\n /**\n * Centers object horizontally with animation.\n * @param {fabric.Object} object Object to center\n * @param {Object} [callbacks] Callbacks object with optional \"onComplete\" and/or \"onChange\" properties\n * @param {Function} [callbacks.onComplete] Invoked on completion\n * @param {Function} [callbacks.onChange] Invoked on every step of animation\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n fxCenterObjectH: function (object, callbacks) {\n callbacks = callbacks || {};\n\n var empty = function () {},\n onComplete = callbacks.onComplete || empty,\n onChange = callbacks.onChange || empty,\n _this = this;\n\n fabric.util.animate({\n startValue: object.left,\n endValue: this.getCenter().left,\n duration: this.FX_DURATION,\n onChange: function (value) {\n object.set('left', value);\n\n _this.requestRenderAll();\n\n onChange();\n },\n onComplete: function () {\n object.setCoords();\n onComplete();\n }\n });\n return this;\n },\n\n /**\n * Centers object vertically with animation.\n * @param {fabric.Object} object Object to center\n * @param {Object} [callbacks] Callbacks object with optional \"onComplete\" and/or \"onChange\" properties\n * @param {Function} [callbacks.onComplete] Invoked on completion\n * @param {Function} [callbacks.onChange] Invoked on every step of animation\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n fxCenterObjectV: function (object, callbacks) {\n callbacks = callbacks || {};\n\n var empty = function () {},\n onComplete = callbacks.onComplete || empty,\n onChange = callbacks.onChange || empty,\n _this = this;\n\n fabric.util.animate({\n startValue: object.top,\n endValue: this.getCenter().top,\n duration: this.FX_DURATION,\n onChange: function (value) {\n object.set('top', value);\n\n _this.requestRenderAll();\n\n onChange();\n },\n onComplete: function () {\n object.setCoords();\n onComplete();\n }\n });\n return this;\n },\n\n /**\n * Same as `fabric.Canvas#remove` but animated\n * @param {fabric.Object} object Object to remove\n * @param {Object} [callbacks] Callbacks object with optional \"onComplete\" and/or \"onChange\" properties\n * @param {Function} [callbacks.onComplete] Invoked on completion\n * @param {Function} [callbacks.onChange] Invoked on every step of animation\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n fxRemove: function (object, callbacks) {\n callbacks = callbacks || {};\n\n var empty = function () {},\n onComplete = callbacks.onComplete || empty,\n onChange = callbacks.onChange || empty,\n _this = this;\n\n fabric.util.animate({\n startValue: object.opacity,\n endValue: 0,\n duration: this.FX_DURATION,\n onChange: function (value) {\n object.set('opacity', value);\n\n _this.requestRenderAll();\n\n onChange();\n },\n onComplete: function () {\n _this.remove(object);\n\n onComplete();\n }\n });\n return this;\n }\n});\nfabric.util.object.extend(fabric.Object.prototype,\n/** @lends fabric.Object.prototype */\n{\n /**\n * Animates object's properties\n * @param {String|Object} property Property to animate (if string) or properties to animate (if object)\n * @param {Number|Object} value Value to animate property to (if string was given first) or options object\n * @return {fabric.Object} thisArg\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#animation}\n * @chainable\n *\n * As object — multiple properties\n *\n * object.animate({ left: ..., top: ... });\n * object.animate({ left: ..., top: ... }, { duration: ... });\n *\n * As string — one property\n *\n * object.animate('left', ...);\n * object.animate('left', { duration: ... });\n *\n */\n animate: function () {\n if (arguments[0] && typeof arguments[0] === 'object') {\n var propsToAnimate = [],\n prop,\n skipCallbacks;\n\n for (prop in arguments[0]) {\n propsToAnimate.push(prop);\n }\n\n for (var i = 0, len = propsToAnimate.length; i < len; i++) {\n prop = propsToAnimate[i];\n skipCallbacks = i !== len - 1;\n\n this._animate(prop, arguments[0][prop], arguments[1], skipCallbacks);\n }\n } else {\n this._animate.apply(this, arguments);\n }\n\n return this;\n },\n\n /**\n * @private\n * @param {String} property Property to animate\n * @param {String} to Value to animate to\n * @param {Object} [options] Options object\n * @param {Boolean} [skipCallbacks] When true, callbacks like onchange and oncomplete are not invoked\n */\n _animate: function (property, to, options, skipCallbacks) {\n var _this = this,\n propPair;\n\n to = to.toString();\n\n if (!options) {\n options = {};\n } else {\n options = fabric.util.object.clone(options);\n }\n\n if (~property.indexOf('.')) {\n propPair = property.split('.');\n }\n\n var propIsColor = _this.colorProperties.indexOf(property) > -1 || propPair && _this.colorProperties.indexOf(propPair[1]) > -1;\n var currentValue = propPair ? this.get(propPair[0])[propPair[1]] : this.get(property);\n\n if (!('from' in options)) {\n options.from = currentValue;\n }\n\n if (!propIsColor) {\n if (~to.indexOf('=')) {\n to = currentValue + parseFloat(to.replace('=', ''));\n } else {\n to = parseFloat(to);\n }\n }\n\n var _options = {\n startValue: options.from,\n endValue: to,\n byValue: options.by,\n easing: options.easing,\n duration: options.duration,\n abort: options.abort && function () {\n return options.abort.call(_this);\n },\n onChange: function (value, valueProgress, timeProgress) {\n if (propPair) {\n _this[propPair[0]][propPair[1]] = value;\n } else {\n _this.set(property, value);\n }\n\n if (skipCallbacks) {\n return;\n }\n\n options.onChange && options.onChange(value, valueProgress, timeProgress);\n },\n onComplete: function (value, valueProgress, timeProgress) {\n if (skipCallbacks) {\n return;\n }\n\n _this.setCoords();\n\n options.onComplete && options.onComplete(value, valueProgress, timeProgress);\n }\n };\n\n if (propIsColor) {\n fabric.util.animateColor(_options.startValue, _options.endValue, _options.duration, _options);\n } else {\n fabric.util.animate(_options);\n }\n }\n});\n\n(function (global) {\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = {}),\n extend = fabric.util.object.extend,\n clone = fabric.util.object.clone,\n coordProps = {\n x1: 1,\n x2: 1,\n y1: 1,\n y2: 1\n },\n supportsLineDash = fabric.StaticCanvas.supports('setLineDash');\n\n if (fabric.Line) {\n fabric.warn('fabric.Line is already defined');\n return;\n }\n /**\n * Line class\n * @class fabric.Line\n * @extends fabric.Object\n * @see {@link fabric.Line#initialize} for constructor definition\n */\n\n\n fabric.Line = fabric.util.createClass(fabric.Object,\n /** @lends fabric.Line.prototype */\n {\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'line',\n\n /**\n * x value or first line edge\n * @type Number\n * @default\n */\n x1: 0,\n\n /**\n * y value or first line edge\n * @type Number\n * @default\n */\n y1: 0,\n\n /**\n * x value or second line edge\n * @type Number\n * @default\n */\n x2: 0,\n\n /**\n * y value or second line edge\n * @type Number\n * @default\n */\n y2: 0,\n cacheProperties: fabric.Object.prototype.cacheProperties.concat('x1', 'x2', 'y1', 'y2'),\n\n /**\n * Constructor\n * @param {Array} [points] Array of points\n * @param {Object} [options] Options object\n * @return {fabric.Line} thisArg\n */\n initialize: function (points, options) {\n if (!points) {\n points = [0, 0, 0, 0];\n }\n\n this.callSuper('initialize', options);\n this.set('x1', points[0]);\n this.set('y1', points[1]);\n this.set('x2', points[2]);\n this.set('y2', points[3]);\n\n this._setWidthHeight(options);\n },\n\n /**\n * @private\n * @param {Object} [options] Options\n */\n _setWidthHeight: function (options) {\n options || (options = {});\n this.width = Math.abs(this.x2 - this.x1);\n this.height = Math.abs(this.y2 - this.y1);\n this.left = 'left' in options ? options.left : this._getLeftToOriginX();\n this.top = 'top' in options ? options.top : this._getTopToOriginY();\n },\n\n /**\n * @private\n * @param {String} key\n * @param {*} value\n */\n _set: function (key, value) {\n this.callSuper('_set', key, value);\n\n if (typeof coordProps[key] !== 'undefined') {\n this._setWidthHeight();\n }\n\n return this;\n },\n\n /**\n * @private\n * @return {Number} leftToOriginX Distance from left edge of canvas to originX of Line.\n */\n _getLeftToOriginX: makeEdgeToOriginGetter({\n // property names\n origin: 'originX',\n axis1: 'x1',\n axis2: 'x2',\n dimension: 'width'\n }, {\n // possible values of origin\n nearest: 'left',\n center: 'center',\n farthest: 'right'\n }),\n\n /**\n * @private\n * @return {Number} topToOriginY Distance from top edge of canvas to originY of Line.\n */\n _getTopToOriginY: makeEdgeToOriginGetter({\n // property names\n origin: 'originY',\n axis1: 'y1',\n axis2: 'y2',\n dimension: 'height'\n }, {\n // possible values of origin\n nearest: 'top',\n center: 'center',\n farthest: 'bottom'\n }),\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _render: function (ctx) {\n ctx.beginPath();\n\n if (!this.strokeDashArray || this.strokeDashArray && supportsLineDash) {\n // move from center (of virtual box) to its left/top corner\n // we can't assume x1, y1 is top left and x2, y2 is bottom right\n var p = this.calcLinePoints();\n ctx.moveTo(p.x1, p.y1);\n ctx.lineTo(p.x2, p.y2);\n }\n\n ctx.lineWidth = this.strokeWidth; // TODO: test this\n // make sure setting \"fill\" changes color of a line\n // (by copying fillStyle to strokeStyle, since line is stroked, not filled)\n\n var origStrokeStyle = ctx.strokeStyle;\n ctx.strokeStyle = this.stroke || ctx.fillStyle;\n this.stroke && this._renderStroke(ctx);\n ctx.strokeStyle = origStrokeStyle;\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderDashedStroke: function (ctx) {\n var p = this.calcLinePoints();\n ctx.beginPath();\n fabric.util.drawDashedLine(ctx, p.x1, p.y1, p.x2, p.y2, this.strokeDashArray);\n ctx.closePath();\n },\n\n /**\n * This function is an helper for svg import. it returns the center of the object in the svg\n * untransformed coordinates\n * @private\n * @return {Object} center point from element coordinates\n */\n _findCenterFromElement: function () {\n return {\n x: (this.x1 + this.x2) / 2,\n y: (this.y1 + this.y2) / 2\n };\n },\n\n /**\n * Returns object representation of an instance\n * @methd toObject\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject: function (propertiesToInclude) {\n return extend(this.callSuper('toObject', propertiesToInclude), this.calcLinePoints());\n },\n\n /*\n * Calculate object dimensions from its properties\n * @private\n */\n _getNonTransformedDimensions: function () {\n var dim = this.callSuper('_getNonTransformedDimensions');\n\n if (this.strokeLineCap === 'butt') {\n if (this.width === 0) {\n dim.y -= this.strokeWidth;\n }\n\n if (this.height === 0) {\n dim.x -= this.strokeWidth;\n }\n }\n\n return dim;\n },\n\n /**\n * Recalculates line points given width and height\n * @private\n */\n calcLinePoints: function () {\n var xMult = this.x1 <= this.x2 ? -1 : 1,\n yMult = this.y1 <= this.y2 ? -1 : 1,\n x1 = xMult * this.width * 0.5,\n y1 = yMult * this.height * 0.5,\n x2 = xMult * this.width * -0.5,\n y2 = yMult * this.height * -0.5;\n return {\n x1: x1,\n x2: x2,\n y1: y1,\n y2: y2\n };\n },\n\n /* _TO_SVG_START_ */\n\n /**\n * Returns svg representation of an instance\n * @return {Array} an array of strings with the specific svg representation\n * of the instance\n */\n _toSVG: function () {\n var p = this.calcLinePoints();\n return ['<line ', 'COMMON_PARTS', 'x1=\"', p.x1, '\" y1=\"', p.y1, '\" x2=\"', p.x2, '\" y2=\"', p.y2, '\" />\\n'];\n }\n /* _TO_SVG_END_ */\n\n });\n /* _FROM_SVG_START_ */\n\n /**\n * List of attribute names to account for when parsing SVG element (used by {@link fabric.Line.fromElement})\n * @static\n * @memberOf fabric.Line\n * @see http://www.w3.org/TR/SVG/shapes.html#LineElement\n */\n\n fabric.Line.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat('x1 y1 x2 y2'.split(' '));\n /**\n * Returns fabric.Line instance from an SVG element\n * @static\n * @memberOf fabric.Line\n * @param {SVGElement} element Element to parse\n * @param {Object} [options] Options object\n * @param {Function} [callback] callback function invoked after parsing\n */\n\n fabric.Line.fromElement = function (element, callback, options) {\n options = options || {};\n var parsedAttributes = fabric.parseAttributes(element, fabric.Line.ATTRIBUTE_NAMES),\n points = [parsedAttributes.x1 || 0, parsedAttributes.y1 || 0, parsedAttributes.x2 || 0, parsedAttributes.y2 || 0];\n callback(new fabric.Line(points, extend(parsedAttributes, options)));\n };\n /* _FROM_SVG_END_ */\n\n /**\n * Returns fabric.Line instance from an object representation\n * @static\n * @memberOf fabric.Line\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] invoked with new instance as first argument\n */\n\n\n fabric.Line.fromObject = function (object, callback) {\n function _callback(instance) {\n delete instance.points;\n callback && callback(instance);\n }\n\n ;\n var options = clone(object, true);\n options.points = [object.x1, object.y1, object.x2, object.y2];\n\n fabric.Object._fromObject('Line', options, _callback, 'points');\n };\n /**\n * Produces a function that calculates distance from canvas edge to Line origin.\n */\n\n\n function makeEdgeToOriginGetter(propertyNames, originValues) {\n var origin = propertyNames.origin,\n axis1 = propertyNames.axis1,\n axis2 = propertyNames.axis2,\n dimension = propertyNames.dimension,\n nearest = originValues.nearest,\n center = originValues.center,\n farthest = originValues.farthest;\n return function () {\n switch (this.get(origin)) {\n case nearest:\n return Math.min(this.get(axis1), this.get(axis2));\n\n case center:\n return Math.min(this.get(axis1), this.get(axis2)) + 0.5 * this.get(dimension);\n\n case farthest:\n return Math.max(this.get(axis1), this.get(axis2));\n }\n };\n }\n})(typeof exports !== 'undefined' ? exports : this);\n\n(function (global) {\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = {}),\n pi = Math.PI;\n\n if (fabric.Circle) {\n fabric.warn('fabric.Circle is already defined.');\n return;\n }\n /**\n * Circle class\n * @class fabric.Circle\n * @extends fabric.Object\n * @see {@link fabric.Circle#initialize} for constructor definition\n */\n\n\n fabric.Circle = fabric.util.createClass(fabric.Object,\n /** @lends fabric.Circle.prototype */\n {\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'circle',\n\n /**\n * Radius of this circle\n * @type Number\n * @default\n */\n radius: 0,\n\n /**\n * Start angle of the circle, moving clockwise\n * deprectated type, this should be in degree, this was an oversight.\n * probably will change to degrees in next major version\n * @type Number\n * @default 0\n */\n startAngle: 0,\n\n /**\n * End angle of the circle\n * deprectated type, this should be in degree, this was an oversight.\n * probably will change to degrees in next major version\n * @type Number\n * @default 2Pi\n */\n endAngle: pi * 2,\n cacheProperties: fabric.Object.prototype.cacheProperties.concat('radius', 'startAngle', 'endAngle'),\n\n /**\n * @private\n * @param {String} key\n * @param {*} value\n * @return {fabric.Circle} thisArg\n */\n _set: function (key, value) {\n this.callSuper('_set', key, value);\n\n if (key === 'radius') {\n this.setRadius(value);\n }\n\n return this;\n },\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject: function (propertiesToInclude) {\n return this.callSuper('toObject', ['radius', 'startAngle', 'endAngle'].concat(propertiesToInclude));\n },\n\n /* _TO_SVG_START_ */\n\n /**\n * Returns svg representation of an instance\n * @return {Array} an array of strings with the specific svg representation\n * of the instance\n */\n _toSVG: function () {\n var svgString,\n x = 0,\n y = 0,\n angle = (this.endAngle - this.startAngle) % (2 * pi);\n\n if (angle === 0) {\n svgString = ['<circle ', 'COMMON_PARTS', 'cx=\"' + x + '\" cy=\"' + y + '\" ', 'r=\"', this.radius, '\" />\\n'];\n } else {\n var startX = fabric.util.cos(this.startAngle) * this.radius,\n startY = fabric.util.sin(this.startAngle) * this.radius,\n endX = fabric.util.cos(this.endAngle) * this.radius,\n endY = fabric.util.sin(this.endAngle) * this.radius,\n largeFlag = angle > pi ? '1' : '0';\n svgString = ['<path d=\"M ' + startX + ' ' + startY, ' A ' + this.radius + ' ' + this.radius, ' 0 ', +largeFlag + ' 1', ' ' + endX + ' ' + endY, '\" ', 'COMMON_PARTS', ' />\\n'];\n }\n\n return svgString;\n },\n\n /* _TO_SVG_END_ */\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx context to render on\n */\n _render: function (ctx) {\n ctx.beginPath();\n ctx.arc(0, 0, this.radius, this.startAngle, this.endAngle, false);\n\n this._renderPaintInOrder(ctx);\n },\n\n /**\n * Returns horizontal radius of an object (according to how an object is scaled)\n * @return {Number}\n */\n getRadiusX: function () {\n return this.get('radius') * this.get('scaleX');\n },\n\n /**\n * Returns vertical radius of an object (according to how an object is scaled)\n * @return {Number}\n */\n getRadiusY: function () {\n return this.get('radius') * this.get('scaleY');\n },\n\n /**\n * Sets radius of an object (and updates width accordingly)\n * @return {fabric.Circle} thisArg\n */\n setRadius: function (value) {\n this.radius = value;\n return this.set('width', value * 2).set('height', value * 2);\n }\n });\n /* _FROM_SVG_START_ */\n\n /**\n * List of attribute names to account for when parsing SVG element (used by {@link fabric.Circle.fromElement})\n * @static\n * @memberOf fabric.Circle\n * @see: http://www.w3.org/TR/SVG/shapes.html#CircleElement\n */\n\n fabric.Circle.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat('cx cy r'.split(' '));\n /**\n * Returns {@link fabric.Circle} instance from an SVG element\n * @static\n * @memberOf fabric.Circle\n * @param {SVGElement} element Element to parse\n * @param {Function} [callback] Options callback invoked after parsing is finished\n * @param {Object} [options] Options object\n * @throws {Error} If value of `r` attribute is missing or invalid\n */\n\n fabric.Circle.fromElement = function (element, callback) {\n var parsedAttributes = fabric.parseAttributes(element, fabric.Circle.ATTRIBUTE_NAMES);\n\n if (!isValidRadius(parsedAttributes)) {\n throw new Error('value of `r` attribute is required and can not be negative');\n }\n\n parsedAttributes.left = (parsedAttributes.left || 0) - parsedAttributes.radius;\n parsedAttributes.top = (parsedAttributes.top || 0) - parsedAttributes.radius;\n callback(new fabric.Circle(parsedAttributes));\n };\n /**\n * @private\n */\n\n\n function isValidRadius(attributes) {\n return 'radius' in attributes && attributes.radius >= 0;\n }\n /* _FROM_SVG_END_ */\n\n /**\n * Returns {@link fabric.Circle} instance from an object representation\n * @static\n * @memberOf fabric.Circle\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] invoked with new instance as first argument\n * @return {Object} Instance of fabric.Circle\n */\n\n\n fabric.Circle.fromObject = function (object, callback) {\n return fabric.Object._fromObject('Circle', object, callback);\n };\n})(typeof exports !== 'undefined' ? exports : this);\n\n(function (global) {\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = {});\n\n if (fabric.Triangle) {\n fabric.warn('fabric.Triangle is already defined');\n return;\n }\n /**\n * Triangle class\n * @class fabric.Triangle\n * @extends fabric.Object\n * @return {fabric.Triangle} thisArg\n * @see {@link fabric.Triangle#initialize} for constructor definition\n */\n\n\n fabric.Triangle = fabric.util.createClass(fabric.Object,\n /** @lends fabric.Triangle.prototype */\n {\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'triangle',\n\n /**\n * Width is set to 100 to compensate the old initialize code that was setting it to 100\n * @type Number\n * @default\n */\n width: 100,\n\n /**\n * Height is set to 100 to compensate the old initialize code that was setting it to 100\n * @type Number\n * @default\n */\n height: 100,\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _render: function (ctx) {\n var widthBy2 = this.width / 2,\n heightBy2 = this.height / 2;\n ctx.beginPath();\n ctx.moveTo(-widthBy2, heightBy2);\n ctx.lineTo(0, -heightBy2);\n ctx.lineTo(widthBy2, heightBy2);\n ctx.closePath();\n\n this._renderPaintInOrder(ctx);\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderDashedStroke: function (ctx) {\n var widthBy2 = this.width / 2,\n heightBy2 = this.height / 2;\n ctx.beginPath();\n fabric.util.drawDashedLine(ctx, -widthBy2, heightBy2, 0, -heightBy2, this.strokeDashArray);\n fabric.util.drawDashedLine(ctx, 0, -heightBy2, widthBy2, heightBy2, this.strokeDashArray);\n fabric.util.drawDashedLine(ctx, widthBy2, heightBy2, -widthBy2, heightBy2, this.strokeDashArray);\n ctx.closePath();\n },\n\n /* _TO_SVG_START_ */\n\n /**\n * Returns svg representation of an instance\n * @return {Array} an array of strings with the specific svg representation\n * of the instance\n */\n _toSVG: function () {\n var widthBy2 = this.width / 2,\n heightBy2 = this.height / 2,\n points = [-widthBy2 + ' ' + heightBy2, '0 ' + -heightBy2, widthBy2 + ' ' + heightBy2].join(',');\n return ['<polygon ', 'COMMON_PARTS', 'points=\"', points, '\" />'];\n }\n /* _TO_SVG_END_ */\n\n });\n /**\n * Returns {@link fabric.Triangle} instance from an object representation\n * @static\n * @memberOf fabric.Triangle\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] invoked with new instance as first argument\n */\n\n fabric.Triangle.fromObject = function (object, callback) {\n return fabric.Object._fromObject('Triangle', object, callback);\n };\n})(typeof exports !== 'undefined' ? exports : this);\n\n(function (global) {\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = {}),\n piBy2 = Math.PI * 2;\n\n if (fabric.Ellipse) {\n fabric.warn('fabric.Ellipse is already defined.');\n return;\n }\n /**\n * Ellipse class\n * @class fabric.Ellipse\n * @extends fabric.Object\n * @return {fabric.Ellipse} thisArg\n * @see {@link fabric.Ellipse#initialize} for constructor definition\n */\n\n\n fabric.Ellipse = fabric.util.createClass(fabric.Object,\n /** @lends fabric.Ellipse.prototype */\n {\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'ellipse',\n\n /**\n * Horizontal radius\n * @type Number\n * @default\n */\n rx: 0,\n\n /**\n * Vertical radius\n * @type Number\n * @default\n */\n ry: 0,\n cacheProperties: fabric.Object.prototype.cacheProperties.concat('rx', 'ry'),\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n * @return {fabric.Ellipse} thisArg\n */\n initialize: function (options) {\n this.callSuper('initialize', options);\n this.set('rx', options && options.rx || 0);\n this.set('ry', options && options.ry || 0);\n },\n\n /**\n * @private\n * @param {String} key\n * @param {*} value\n * @return {fabric.Ellipse} thisArg\n */\n _set: function (key, value) {\n this.callSuper('_set', key, value);\n\n switch (key) {\n case 'rx':\n this.rx = value;\n this.set('width', value * 2);\n break;\n\n case 'ry':\n this.ry = value;\n this.set('height', value * 2);\n break;\n }\n\n return this;\n },\n\n /**\n * Returns horizontal radius of an object (according to how an object is scaled)\n * @return {Number}\n */\n getRx: function () {\n return this.get('rx') * this.get('scaleX');\n },\n\n /**\n * Returns Vertical radius of an object (according to how an object is scaled)\n * @return {Number}\n */\n getRy: function () {\n return this.get('ry') * this.get('scaleY');\n },\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject: function (propertiesToInclude) {\n return this.callSuper('toObject', ['rx', 'ry'].concat(propertiesToInclude));\n },\n\n /* _TO_SVG_START_ */\n\n /**\n * Returns svg representation of an instance\n * @return {Array} an array of strings with the specific svg representation\n * of the instance\n */\n _toSVG: function () {\n return ['<ellipse ', 'COMMON_PARTS', 'cx=\"0\" cy=\"0\" ', 'rx=\"', this.rx, '\" ry=\"', this.ry, '\" />\\n'];\n },\n\n /* _TO_SVG_END_ */\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx context to render on\n */\n _render: function (ctx) {\n ctx.beginPath();\n ctx.save();\n ctx.transform(1, 0, 0, this.ry / this.rx, 0, 0);\n ctx.arc(0, 0, this.rx, 0, piBy2, false);\n ctx.restore();\n\n this._renderPaintInOrder(ctx);\n }\n });\n /* _FROM_SVG_START_ */\n\n /**\n * List of attribute names to account for when parsing SVG element (used by {@link fabric.Ellipse.fromElement})\n * @static\n * @memberOf fabric.Ellipse\n * @see http://www.w3.org/TR/SVG/shapes.html#EllipseElement\n */\n\n fabric.Ellipse.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat('cx cy rx ry'.split(' '));\n /**\n * Returns {@link fabric.Ellipse} instance from an SVG element\n * @static\n * @memberOf fabric.Ellipse\n * @param {SVGElement} element Element to parse\n * @param {Function} [callback] Options callback invoked after parsing is finished\n * @return {fabric.Ellipse}\n */\n\n fabric.Ellipse.fromElement = function (element, callback) {\n var parsedAttributes = fabric.parseAttributes(element, fabric.Ellipse.ATTRIBUTE_NAMES);\n parsedAttributes.left = (parsedAttributes.left || 0) - parsedAttributes.rx;\n parsedAttributes.top = (parsedAttributes.top || 0) - parsedAttributes.ry;\n callback(new fabric.Ellipse(parsedAttributes));\n };\n /* _FROM_SVG_END_ */\n\n /**\n * Returns {@link fabric.Ellipse} instance from an object representation\n * @static\n * @memberOf fabric.Ellipse\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] invoked with new instance as first argument\n * @return {fabric.Ellipse}\n */\n\n\n fabric.Ellipse.fromObject = function (object, callback) {\n return fabric.Object._fromObject('Ellipse', object, callback);\n };\n})(typeof exports !== 'undefined' ? exports : this);\n\n(function (global) {\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = {}),\n extend = fabric.util.object.extend;\n\n if (fabric.Rect) {\n fabric.warn('fabric.Rect is already defined');\n return;\n }\n /**\n * Rectangle class\n * @class fabric.Rect\n * @extends fabric.Object\n * @return {fabric.Rect} thisArg\n * @see {@link fabric.Rect#initialize} for constructor definition\n */\n\n\n fabric.Rect = fabric.util.createClass(fabric.Object,\n /** @lends fabric.Rect.prototype */\n {\n /**\n * List of properties to consider when checking if state of an object is changed ({@link fabric.Object#hasStateChanged})\n * as well as for history (undo/redo) purposes\n * @type Array\n */\n stateProperties: fabric.Object.prototype.stateProperties.concat('rx', 'ry'),\n\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'rect',\n\n /**\n * Horizontal border radius\n * @type Number\n * @default\n */\n rx: 0,\n\n /**\n * Vertical border radius\n * @type Number\n * @default\n */\n ry: 0,\n cacheProperties: fabric.Object.prototype.cacheProperties.concat('rx', 'ry'),\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n * @return {Object} thisArg\n */\n initialize: function (options) {\n this.callSuper('initialize', options);\n\n this._initRxRy();\n },\n\n /**\n * Initializes rx/ry attributes\n * @private\n */\n _initRxRy: function () {\n if (this.rx && !this.ry) {\n this.ry = this.rx;\n } else if (this.ry && !this.rx) {\n this.rx = this.ry;\n }\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _render: function (ctx) {\n // 1x1 case (used in spray brush) optimization was removed because\n // with caching and higher zoom level this makes more damage than help\n var rx = this.rx ? Math.min(this.rx, this.width / 2) : 0,\n ry = this.ry ? Math.min(this.ry, this.height / 2) : 0,\n w = this.width,\n h = this.height,\n x = -this.width / 2,\n y = -this.height / 2,\n isRounded = rx !== 0 || ry !== 0,\n\n /* \"magic number\" for bezier approximations of arcs (http://itc.ktu.lt/itc354/Riskus354.pdf) */\n k = 1 - 0.5522847498;\n ctx.beginPath();\n ctx.moveTo(x + rx, y);\n ctx.lineTo(x + w - rx, y);\n isRounded && ctx.bezierCurveTo(x + w - k * rx, y, x + w, y + k * ry, x + w, y + ry);\n ctx.lineTo(x + w, y + h - ry);\n isRounded && ctx.bezierCurveTo(x + w, y + h - k * ry, x + w - k * rx, y + h, x + w - rx, y + h);\n ctx.lineTo(x + rx, y + h);\n isRounded && ctx.bezierCurveTo(x + k * rx, y + h, x, y + h - k * ry, x, y + h - ry);\n ctx.lineTo(x, y + ry);\n isRounded && ctx.bezierCurveTo(x, y + k * ry, x + k * rx, y, x + rx, y);\n ctx.closePath();\n\n this._renderPaintInOrder(ctx);\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderDashedStroke: function (ctx) {\n var x = -this.width / 2,\n y = -this.height / 2,\n w = this.width,\n h = this.height;\n ctx.beginPath();\n fabric.util.drawDashedLine(ctx, x, y, x + w, y, this.strokeDashArray);\n fabric.util.drawDashedLine(ctx, x + w, y, x + w, y + h, this.strokeDashArray);\n fabric.util.drawDashedLine(ctx, x + w, y + h, x, y + h, this.strokeDashArray);\n fabric.util.drawDashedLine(ctx, x, y + h, x, y, this.strokeDashArray);\n ctx.closePath();\n },\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject: function (propertiesToInclude) {\n return this.callSuper('toObject', ['rx', 'ry'].concat(propertiesToInclude));\n },\n\n /* _TO_SVG_START_ */\n\n /**\n * Returns svg representation of an instance\n * @return {Array} an array of strings with the specific svg representation\n * of the instance\n */\n _toSVG: function () {\n var x = -this.width / 2,\n y = -this.height / 2;\n return ['<rect ', 'COMMON_PARTS', 'x=\"', x, '\" y=\"', y, '\" rx=\"', this.rx, '\" ry=\"', this.ry, '\" width=\"', this.width, '\" height=\"', this.height, '\" />\\n'];\n }\n /* _TO_SVG_END_ */\n\n });\n /* _FROM_SVG_START_ */\n\n /**\n * List of attribute names to account for when parsing SVG element (used by `fabric.Rect.fromElement`)\n * @static\n * @memberOf fabric.Rect\n * @see: http://www.w3.org/TR/SVG/shapes.html#RectElement\n */\n\n fabric.Rect.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat('x y rx ry width height'.split(' '));\n /**\n * Returns {@link fabric.Rect} instance from an SVG element\n * @static\n * @memberOf fabric.Rect\n * @param {SVGElement} element Element to parse\n * @param {Function} callback callback function invoked after parsing\n * @param {Object} [options] Options object\n */\n\n fabric.Rect.fromElement = function (element, callback, options) {\n if (!element) {\n return callback(null);\n }\n\n options = options || {};\n var parsedAttributes = fabric.parseAttributes(element, fabric.Rect.ATTRIBUTE_NAMES);\n parsedAttributes.left = parsedAttributes.left || 0;\n parsedAttributes.top = parsedAttributes.top || 0;\n parsedAttributes.height = parsedAttributes.height || 0;\n parsedAttributes.width = parsedAttributes.width || 0;\n var rect = new fabric.Rect(extend(options ? fabric.util.object.clone(options) : {}, parsedAttributes));\n rect.visible = rect.visible && rect.width > 0 && rect.height > 0;\n callback(rect);\n };\n /* _FROM_SVG_END_ */\n\n /**\n * Returns {@link fabric.Rect} instance from an object representation\n * @static\n * @memberOf fabric.Rect\n * @param {Object} object Object to create an instance from\n * @param {Function} [callback] Callback to invoke when an fabric.Rect instance is created\n */\n\n\n fabric.Rect.fromObject = function (object, callback) {\n return fabric.Object._fromObject('Rect', object, callback);\n };\n})(typeof exports !== 'undefined' ? exports : this);\n\n(function (global) {\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = {}),\n extend = fabric.util.object.extend,\n min = fabric.util.array.min,\n max = fabric.util.array.max,\n toFixed = fabric.util.toFixed;\n\n if (fabric.Polyline) {\n fabric.warn('fabric.Polyline is already defined');\n return;\n }\n /**\n * Polyline class\n * @class fabric.Polyline\n * @extends fabric.Object\n * @see {@link fabric.Polyline#initialize} for constructor definition\n */\n\n\n fabric.Polyline = fabric.util.createClass(fabric.Object,\n /** @lends fabric.Polyline.prototype */\n {\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'polyline',\n\n /**\n * Points array\n * @type Array\n * @default\n */\n points: null,\n cacheProperties: fabric.Object.prototype.cacheProperties.concat('points'),\n\n /**\n * Constructor\n * @param {Array} points Array of points (where each point is an object with x and y)\n * @param {Object} [options] Options object\n * @return {fabric.Polyline} thisArg\n * @example\n * var poly = new fabric.Polyline([\n * { x: 10, y: 10 },\n * { x: 50, y: 30 },\n * { x: 40, y: 70 },\n * { x: 60, y: 50 },\n * { x: 100, y: 150 },\n * { x: 40, y: 100 }\n * ], {\n * stroke: 'red',\n * left: 100,\n * top: 100\n * });\n */\n initialize: function (points, options) {\n options = options || {};\n this.points = points || [];\n this.callSuper('initialize', options);\n\n this._setPositionDimensions(options);\n },\n _setPositionDimensions: function (options) {\n var calcDim = this._calcDimensions(options),\n correctLeftTop;\n\n this.width = calcDim.width;\n this.height = calcDim.height;\n\n if (!options.fromSVG) {\n correctLeftTop = this.translateToGivenOrigin({\n x: calcDim.left - this.strokeWidth / 2,\n y: calcDim.top - this.strokeWidth / 2\n }, 'left', 'top', this.originX, this.originY);\n }\n\n if (typeof options.left === 'undefined') {\n this.left = options.fromSVG ? calcDim.left : correctLeftTop.x;\n }\n\n if (typeof options.top === 'undefined') {\n this.top = options.fromSVG ? calcDim.top : correctLeftTop.y;\n }\n\n this.pathOffset = {\n x: calcDim.left + this.width / 2,\n y: calcDim.top + this.height / 2\n };\n },\n\n /**\n * Calculate the polygon min and max point from points array,\n * returning an object with left, top, widht, height to measure the\n * polygon size\n * @return {Object} object.left X coordinate of the polygon leftmost point\n * @return {Object} object.top Y coordinate of the polygon topmost point\n * @return {Object} object.width distance between X coordinates of the polygon leftmost and rightmost point\n * @return {Object} object.height distance between Y coordinates of the polygon topmost and bottommost point\n * @private\n */\n _calcDimensions: function () {\n var points = this.points,\n minX = min(points, 'x') || 0,\n minY = min(points, 'y') || 0,\n maxX = max(points, 'x') || 0,\n maxY = max(points, 'y') || 0,\n width = maxX - minX,\n height = maxY - minY;\n return {\n left: minX,\n top: minY,\n width: width,\n height: height\n };\n },\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} Object representation of an instance\n */\n toObject: function (propertiesToInclude) {\n return extend(this.callSuper('toObject', propertiesToInclude), {\n points: this.points.concat()\n });\n },\n\n /* _TO_SVG_START_ */\n\n /**\n * Returns svg representation of an instance\n * @return {Array} an array of strings with the specific svg representation\n * of the instance\n */\n _toSVG: function () {\n var points = [],\n diffX = this.pathOffset.x,\n diffY = this.pathOffset.y,\n NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS;\n\n for (var i = 0, len = this.points.length; i < len; i++) {\n points.push(toFixed(this.points[i].x - diffX, NUM_FRACTION_DIGITS), ',', toFixed(this.points[i].y - diffY, NUM_FRACTION_DIGITS), ' ');\n }\n\n return ['<' + this.type + ' ', 'COMMON_PARTS', 'points=\"', points.join(''), '\" />\\n'];\n },\n\n /* _TO_SVG_END_ */\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n commonRender: function (ctx) {\n var point,\n len = this.points.length,\n x = this.pathOffset.x,\n y = this.pathOffset.y;\n\n if (!len || isNaN(this.points[len - 1].y)) {\n // do not draw if no points or odd points\n // NaN comes from parseFloat of a empty string in parser\n return false;\n }\n\n ctx.beginPath();\n ctx.moveTo(this.points[0].x - x, this.points[0].y - y);\n\n for (var i = 0; i < len; i++) {\n point = this.points[i];\n ctx.lineTo(point.x - x, point.y - y);\n }\n\n return true;\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _render: function (ctx) {\n if (!this.commonRender(ctx)) {\n return;\n }\n\n this._renderPaintInOrder(ctx);\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderDashedStroke: function (ctx) {\n var p1, p2;\n ctx.beginPath();\n\n for (var i = 0, len = this.points.length; i < len; i++) {\n p1 = this.points[i];\n p2 = this.points[i + 1] || p1;\n fabric.util.drawDashedLine(ctx, p1.x, p1.y, p2.x, p2.y, this.strokeDashArray);\n }\n },\n\n /**\n * Returns complexity of an instance\n * @return {Number} complexity of this instance\n */\n complexity: function () {\n return this.get('points').length;\n }\n });\n /* _FROM_SVG_START_ */\n\n /**\n * List of attribute names to account for when parsing SVG element (used by {@link fabric.Polyline.fromElement})\n * @static\n * @memberOf fabric.Polyline\n * @see: http://www.w3.org/TR/SVG/shapes.html#PolylineElement\n */\n\n fabric.Polyline.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat();\n /**\n * Returns fabric.Polyline instance from an SVG element\n * @static\n * @memberOf fabric.Polyline\n * @param {SVGElement} element Element to parser\n * @param {Function} callback callback function invoked after parsing\n * @param {Object} [options] Options object\n */\n\n fabric.Polyline.fromElementGenerator = function (_class) {\n return function (element, callback, options) {\n if (!element) {\n return callback(null);\n }\n\n options || (options = {});\n var points = fabric.parsePointsAttribute(element.getAttribute('points')),\n parsedAttributes = fabric.parseAttributes(element, fabric[_class].ATTRIBUTE_NAMES);\n parsedAttributes.fromSVG = true;\n callback(new fabric[_class](points, extend(parsedAttributes, options)));\n };\n };\n\n fabric.Polyline.fromElement = fabric.Polyline.fromElementGenerator('Polyline');\n /* _FROM_SVG_END_ */\n\n /**\n * Returns fabric.Polyline instance from an object representation\n * @static\n * @memberOf fabric.Polyline\n * @param {Object} object Object to create an instance from\n * @param {Function} [callback] Callback to invoke when an fabric.Path instance is created\n */\n\n fabric.Polyline.fromObject = function (object, callback) {\n return fabric.Object._fromObject('Polyline', object, callback, 'points');\n };\n})(typeof exports !== 'undefined' ? exports : this);\n\n(function (global) {\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = {});\n\n if (fabric.Polygon) {\n fabric.warn('fabric.Polygon is already defined');\n return;\n }\n /**\n * Polygon class\n * @class fabric.Polygon\n * @extends fabric.Polyline\n * @see {@link fabric.Polygon#initialize} for constructor definition\n */\n\n\n fabric.Polygon = fabric.util.createClass(fabric.Polyline,\n /** @lends fabric.Polygon.prototype */\n {\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'polygon',\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _render: function (ctx) {\n if (!this.commonRender(ctx)) {\n return;\n }\n\n ctx.closePath();\n\n this._renderPaintInOrder(ctx);\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderDashedStroke: function (ctx) {\n this.callSuper('_renderDashedStroke', ctx);\n ctx.closePath();\n }\n });\n /* _FROM_SVG_START_ */\n\n /**\n * List of attribute names to account for when parsing SVG element (used by `fabric.Polygon.fromElement`)\n * @static\n * @memberOf fabric.Polygon\n * @see: http://www.w3.org/TR/SVG/shapes.html#PolygonElement\n */\n\n fabric.Polygon.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat();\n /**\n * Returns {@link fabric.Polygon} instance from an SVG element\n * @static\n * @memberOf fabric.Polygon\n * @param {SVGElement} element Element to parse\n * @param {Function} callback callback function invoked after parsing\n * @param {Object} [options] Options object\n */\n\n fabric.Polygon.fromElement = fabric.Polyline.fromElementGenerator('Polygon');\n /* _FROM_SVG_END_ */\n\n /**\n * Returns fabric.Polygon instance from an object representation\n * @static\n * @memberOf fabric.Polygon\n * @param {Object} object Object to create an instance from\n * @param {Function} [callback] Callback to invoke when an fabric.Path instance is created\n */\n\n fabric.Polygon.fromObject = function (object, callback) {\n return fabric.Object._fromObject('Polygon', object, callback, 'points');\n };\n})(typeof exports !== 'undefined' ? exports : this);\n\n(function (global) {\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = {}),\n min = fabric.util.array.min,\n max = fabric.util.array.max,\n extend = fabric.util.object.extend,\n _toString = Object.prototype.toString,\n toFixed = fabric.util.toFixed;\n\n if (fabric.Path) {\n fabric.warn('fabric.Path is already defined');\n return;\n }\n /**\n * Path class\n * @class fabric.Path\n * @extends fabric.Object\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#path_and_pathgroup}\n * @see {@link fabric.Path#initialize} for constructor definition\n */\n\n\n fabric.Path = fabric.util.createClass(fabric.Object,\n /** @lends fabric.Path.prototype */\n {\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'path',\n\n /**\n * Array of path points\n * @type Array\n * @default\n */\n path: null,\n cacheProperties: fabric.Object.prototype.cacheProperties.concat('path', 'fillRule'),\n stateProperties: fabric.Object.prototype.stateProperties.concat('path'),\n\n /**\n * Constructor\n * @param {Array|String} path Path data (sequence of coordinates and corresponding \"command\" tokens)\n * @param {Object} [options] Options object\n * @return {fabric.Path} thisArg\n */\n initialize: function (path, options) {\n options = options || {};\n this.callSuper('initialize', options);\n\n if (!path) {\n path = [];\n }\n\n var fromArray = _toString.call(path) === '[object Array]';\n this.path = fromArray ? fabric.util.makePathSimpler(path) : fabric.util.makePathSimpler(fabric.util.parsePath(path));\n\n if (!this.path) {\n return;\n }\n\n fabric.Polyline.prototype._setPositionDimensions.call(this, options);\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx context to render path on\n */\n _renderPathCommands: function (ctx) {\n var current,\n // current instruction\n subpathStartX = 0,\n subpathStartY = 0,\n x = 0,\n // current x\n y = 0,\n // current y\n controlX = 0,\n // current control point x\n controlY = 0,\n // current control point y\n l = -this.pathOffset.x,\n t = -this.pathOffset.y;\n ctx.beginPath();\n\n for (var i = 0, len = this.path.length; i < len; ++i) {\n current = this.path[i];\n\n switch (current[0]) {\n // first letter\n case 'L':\n // lineto, absolute\n x = current[1];\n y = current[2];\n ctx.lineTo(x + l, y + t);\n break;\n\n case 'M':\n // moveTo, absolute\n x = current[1];\n y = current[2];\n subpathStartX = x;\n subpathStartY = y;\n ctx.moveTo(x + l, y + t);\n break;\n\n case 'C':\n // bezierCurveTo, absolute\n x = current[5];\n y = current[6];\n controlX = current[3];\n controlY = current[4];\n ctx.bezierCurveTo(current[1] + l, current[2] + t, controlX + l, controlY + t, x + l, y + t);\n break;\n\n case 'Q':\n // quadraticCurveTo, absolute\n ctx.quadraticCurveTo(current[1] + l, current[2] + t, current[3] + l, current[4] + t);\n x = current[3];\n y = current[4];\n controlX = current[1];\n controlY = current[2];\n break;\n\n case 'z':\n case 'Z':\n x = subpathStartX;\n y = subpathStartY;\n ctx.closePath();\n break;\n }\n }\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx context to render path on\n */\n _render: function (ctx) {\n this._renderPathCommands(ctx);\n\n this._renderPaintInOrder(ctx);\n },\n\n /**\n * Returns string representation of an instance\n * @return {String} string representation of an instance\n */\n toString: function () {\n return '#<fabric.Path (' + this.complexity() + '): { \"top\": ' + this.top + ', \"left\": ' + this.left + ' }>';\n },\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject: function (propertiesToInclude) {\n return extend(this.callSuper('toObject', propertiesToInclude), {\n path: this.path.map(function (item) {\n return item.slice();\n })\n });\n },\n\n /**\n * Returns dataless object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toDatalessObject: function (propertiesToInclude) {\n var o = this.toObject(['sourcePath'].concat(propertiesToInclude));\n\n if (o.sourcePath) {\n delete o.path;\n }\n\n return o;\n },\n\n /* _TO_SVG_START_ */\n\n /**\n * Returns svg representation of an instance\n * @return {Array} an array of strings with the specific svg representation\n * of the instance\n */\n _toSVG: function () {\n var path = this.path.map(function (path) {\n return path.join(' ');\n }).join(' ');\n return ['<path ', 'COMMON_PARTS', 'd=\"', path, '\" stroke-linecap=\"round\" ', '/>\\n'];\n },\n _getOffsetTransform: function () {\n var digits = fabric.Object.NUM_FRACTION_DIGITS;\n return ' translate(' + toFixed(-this.pathOffset.x, digits) + ', ' + toFixed(-this.pathOffset.y, digits) + ')';\n },\n\n /**\n * Returns svg clipPath representation of an instance\n * @param {Function} [reviver] Method for further parsing of svg representation.\n * @return {String} svg representation of an instance\n */\n toClipPathSVG: function (reviver) {\n var additionalTransform = this._getOffsetTransform();\n\n return '\\t' + this._createBaseClipPathSVGMarkup(this._toSVG(), {\n reviver: reviver,\n additionalTransform: additionalTransform\n });\n },\n\n /**\n * Returns svg representation of an instance\n * @param {Function} [reviver] Method for further parsing of svg representation.\n * @return {String} svg representation of an instance\n */\n toSVG: function (reviver) {\n var additionalTransform = this._getOffsetTransform();\n\n return this._createBaseSVGMarkup(this._toSVG(), {\n reviver: reviver,\n additionalTransform: additionalTransform\n });\n },\n\n /* _TO_SVG_END_ */\n\n /**\n * Returns number representation of an instance complexity\n * @return {Number} complexity of this instance\n */\n complexity: function () {\n return this.path.length;\n },\n\n /**\n * @private\n */\n _calcDimensions: function () {\n var aX = [],\n aY = [],\n current,\n // current instruction\n subpathStartX = 0,\n subpathStartY = 0,\n x = 0,\n // current x\n y = 0,\n // current y\n bounds;\n\n for (var i = 0, len = this.path.length; i < len; ++i) {\n current = this.path[i];\n\n switch (current[0]) {\n // first letter\n case 'L':\n // lineto, absolute\n x = current[1];\n y = current[2];\n bounds = [];\n break;\n\n case 'M':\n // moveTo, absolute\n x = current[1];\n y = current[2];\n subpathStartX = x;\n subpathStartY = y;\n bounds = [];\n break;\n\n case 'C':\n // bezierCurveTo, absolute\n bounds = fabric.util.getBoundsOfCurve(x, y, current[1], current[2], current[3], current[4], current[5], current[6]);\n x = current[5];\n y = current[6];\n break;\n\n case 'Q':\n // quadraticCurveTo, absolute\n bounds = fabric.util.getBoundsOfCurve(x, y, current[1], current[2], current[1], current[2], current[3], current[4]);\n x = current[3];\n y = current[4];\n break;\n\n case 'z':\n case 'Z':\n x = subpathStartX;\n y = subpathStartY;\n break;\n }\n\n bounds.forEach(function (point) {\n aX.push(point.x);\n aY.push(point.y);\n });\n aX.push(x);\n aY.push(y);\n }\n\n var minX = min(aX) || 0,\n minY = min(aY) || 0,\n maxX = max(aX) || 0,\n maxY = max(aY) || 0,\n deltaX = maxX - minX,\n deltaY = maxY - minY;\n return {\n left: minX,\n top: minY,\n width: deltaX,\n height: deltaY\n };\n }\n });\n /**\n * Creates an instance of fabric.Path from an object\n * @static\n * @memberOf fabric.Path\n * @param {Object} object\n * @param {Function} [callback] Callback to invoke when an fabric.Path instance is created\n */\n\n fabric.Path.fromObject = function (object, callback) {\n if (typeof object.sourcePath === 'string') {\n var pathUrl = object.sourcePath;\n fabric.loadSVGFromURL(pathUrl, function (elements) {\n var path = elements[0];\n path.setOptions(object);\n callback && callback(path);\n });\n } else {\n fabric.Object._fromObject('Path', object, callback, 'path');\n }\n };\n /* _FROM_SVG_START_ */\n\n /**\n * List of attribute names to account for when parsing SVG element (used by `fabric.Path.fromElement`)\n * @static\n * @memberOf fabric.Path\n * @see http://www.w3.org/TR/SVG/paths.html#PathElement\n */\n\n\n fabric.Path.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat(['d']);\n /**\n * Creates an instance of fabric.Path from an SVG <path> element\n * @static\n * @memberOf fabric.Path\n * @param {SVGElement} element to parse\n * @param {Function} callback Callback to invoke when an fabric.Path instance is created\n * @param {Object} [options] Options object\n * @param {Function} [callback] Options callback invoked after parsing is finished\n */\n\n fabric.Path.fromElement = function (element, callback, options) {\n var parsedAttributes = fabric.parseAttributes(element, fabric.Path.ATTRIBUTE_NAMES);\n parsedAttributes.fromSVG = true;\n callback(new fabric.Path(parsedAttributes.d, extend(parsedAttributes, options)));\n };\n /* _FROM_SVG_END_ */\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n(function (global) {\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = {}),\n min = fabric.util.array.min,\n max = fabric.util.array.max;\n\n if (fabric.Group) {\n return;\n }\n /**\n * Group class\n * @class fabric.Group\n * @extends fabric.Object\n * @mixes fabric.Collection\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#groups}\n * @see {@link fabric.Group#initialize} for constructor definition\n */\n\n\n fabric.Group = fabric.util.createClass(fabric.Object, fabric.Collection,\n /** @lends fabric.Group.prototype */\n {\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'group',\n\n /**\n * Width of stroke\n * @type Number\n * @default\n */\n strokeWidth: 0,\n\n /**\n * Indicates if click, mouseover, mouseout events & hoverCursor should also check for subtargets\n * @type Boolean\n * @default\n */\n subTargetCheck: false,\n\n /**\n * Groups are container, do not render anything on theyr own, ence no cache properties\n * @type Array\n * @default\n */\n cacheProperties: [],\n\n /**\n * setOnGroup is a method used for TextBox that is no more used since 2.0.0 The behavior is still\n * available setting this boolean to true.\n * @type Boolean\n * @since 2.0.0\n * @default\n */\n useSetOnGroup: false,\n\n /**\n * Constructor\n * @param {Object} objects Group objects\n * @param {Object} [options] Options object\n * @param {Boolean} [isAlreadyGrouped] if true, objects have been grouped already.\n * @return {Object} thisArg\n */\n initialize: function (objects, options, isAlreadyGrouped) {\n options = options || {};\n this._objects = []; // if objects enclosed in a group have been grouped already,\n // we cannot change properties of objects.\n // Thus we need to set options to group without objects,\n\n isAlreadyGrouped && this.callSuper('initialize', options);\n this._objects = objects || [];\n\n for (var i = this._objects.length; i--;) {\n this._objects[i].group = this;\n }\n\n if (!isAlreadyGrouped) {\n var center = options && options.centerPoint; // we want to set origins before calculating the bounding box.\n // so that the topleft can be set with that in mind.\n // if specific top and left are passed, are overwritten later\n // with the callSuper('initialize', options)\n\n if (options.originX !== undefined) {\n this.originX = options.originX;\n }\n\n if (options.originY !== undefined) {\n this.originY = options.originY;\n } // if coming from svg i do not want to calc bounds.\n // i assume width and height are passed along options\n\n\n center || this._calcBounds();\n\n this._updateObjectsCoords(center);\n\n delete options.centerPoint;\n this.callSuper('initialize', options);\n } else {\n this._updateObjectsACoords();\n }\n\n this.setCoords();\n },\n\n /**\n * @private\n */\n _updateObjectsACoords: function () {\n var skipControls = true;\n\n for (var i = this._objects.length; i--;) {\n this._objects[i].setCoords(skipControls);\n }\n },\n\n /**\n * @private\n * @param {Boolean} [skipCoordsChange] if true, coordinates of objects enclosed in a group do not change\n */\n _updateObjectsCoords: function (center) {\n var center = center || this.getCenterPoint();\n\n for (var i = this._objects.length; i--;) {\n this._updateObjectCoords(this._objects[i], center);\n }\n },\n\n /**\n * @private\n * @param {Object} object\n * @param {fabric.Point} center, current center of group.\n */\n _updateObjectCoords: function (object, center) {\n var objectLeft = object.left,\n objectTop = object.top,\n skipControls = true;\n object.set({\n left: objectLeft - center.x,\n top: objectTop - center.y\n });\n object.group = this;\n object.setCoords(skipControls);\n },\n\n /**\n * Returns string represenation of a group\n * @return {String}\n */\n toString: function () {\n return '#<fabric.Group: (' + this.complexity() + ')>';\n },\n\n /**\n * Adds an object to a group; Then recalculates group's dimension, position.\n * @param {Object} object\n * @return {fabric.Group} thisArg\n * @chainable\n */\n addWithUpdate: function (object) {\n this._restoreObjectsState();\n\n fabric.util.resetObjectTransform(this);\n\n if (object) {\n this._objects.push(object);\n\n object.group = this;\n\n object._set('canvas', this.canvas);\n }\n\n this._calcBounds();\n\n this._updateObjectsCoords();\n\n this.setCoords();\n this.dirty = true;\n return this;\n },\n\n /**\n * Removes an object from a group; Then recalculates group's dimension, position.\n * @param {Object} object\n * @return {fabric.Group} thisArg\n * @chainable\n */\n removeWithUpdate: function (object) {\n this._restoreObjectsState();\n\n fabric.util.resetObjectTransform(this);\n this.remove(object);\n\n this._calcBounds();\n\n this._updateObjectsCoords();\n\n this.setCoords();\n this.dirty = true;\n return this;\n },\n\n /**\n * @private\n */\n _onObjectAdded: function (object) {\n this.dirty = true;\n object.group = this;\n\n object._set('canvas', this.canvas);\n },\n\n /**\n * @private\n */\n _onObjectRemoved: function (object) {\n this.dirty = true;\n delete object.group;\n },\n\n /**\n * @private\n */\n _set: function (key, value) {\n var i = this._objects.length;\n\n if (this.useSetOnGroup) {\n while (i--) {\n this._objects[i].setOnGroup(key, value);\n }\n }\n\n if (key === 'canvas') {\n while (i--) {\n this._objects[i]._set(key, value);\n }\n }\n\n fabric.Object.prototype._set.call(this, key, value);\n },\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject: function (propertiesToInclude) {\n var _includeDefaultValues = this.includeDefaultValues;\n\n var objsToObject = this._objects.map(function (obj) {\n var originalDefaults = obj.includeDefaultValues;\n obj.includeDefaultValues = _includeDefaultValues;\n\n var _obj = obj.toObject(propertiesToInclude);\n\n obj.includeDefaultValues = originalDefaults;\n return _obj;\n });\n\n var obj = fabric.Object.prototype.toObject.call(this, propertiesToInclude);\n obj.objects = objsToObject;\n return obj;\n },\n\n /**\n * Returns object representation of an instance, in dataless mode.\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toDatalessObject: function (propertiesToInclude) {\n var objsToObject,\n sourcePath = this.sourcePath;\n\n if (sourcePath) {\n objsToObject = sourcePath;\n } else {\n var _includeDefaultValues = this.includeDefaultValues;\n objsToObject = this._objects.map(function (obj) {\n var originalDefaults = obj.includeDefaultValues;\n obj.includeDefaultValues = _includeDefaultValues;\n\n var _obj = obj.toDatalessObject(propertiesToInclude);\n\n obj.includeDefaultValues = originalDefaults;\n return _obj;\n });\n }\n\n var obj = fabric.Object.prototype.toDatalessObject.call(this, propertiesToInclude);\n obj.objects = objsToObject;\n return obj;\n },\n\n /**\n * Renders instance on a given context\n * @param {CanvasRenderingContext2D} ctx context to render instance on\n */\n render: function (ctx) {\n this._transformDone = true;\n this.callSuper('render', ctx);\n this._transformDone = false;\n },\n\n /**\n * Decide if the object should cache or not. Create its own cache level\n * needsItsOwnCache should be used when the object drawing method requires\n * a cache step. None of the fabric classes requires it.\n * Generally you do not cache objects in groups because the group is already cached.\n * @return {Boolean}\n */\n shouldCache: function () {\n var ownCache = fabric.Object.prototype.shouldCache.call(this);\n\n if (ownCache) {\n for (var i = 0, len = this._objects.length; i < len; i++) {\n if (this._objects[i].willDrawShadow()) {\n this.ownCaching = false;\n return false;\n }\n }\n }\n\n return ownCache;\n },\n\n /**\n * Check if this object or a child object will cast a shadow\n * @return {Boolean}\n */\n willDrawShadow: function () {\n if (fabric.Object.prototype.willDrawShadow.call(this)) {\n return true;\n }\n\n for (var i = 0, len = this._objects.length; i < len; i++) {\n if (this._objects[i].willDrawShadow()) {\n return true;\n }\n }\n\n return false;\n },\n\n /**\n * Check if this group or its parent group are caching, recursively up\n * @return {Boolean}\n */\n isOnACache: function () {\n return this.ownCaching || this.group && this.group.isOnACache();\n },\n\n /**\n * Execute the drawing operation for an object on a specified context\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n drawObject: function (ctx) {\n for (var i = 0, len = this._objects.length; i < len; i++) {\n this._objects[i].render(ctx);\n }\n\n this._drawClipPath(ctx);\n },\n\n /**\n * Check if cache is dirty\n */\n isCacheDirty: function (skipCanvas) {\n if (this.callSuper('isCacheDirty', skipCanvas)) {\n return true;\n }\n\n if (!this.statefullCache) {\n return false;\n }\n\n for (var i = 0, len = this._objects.length; i < len; i++) {\n if (this._objects[i].isCacheDirty(true)) {\n if (this._cacheCanvas) {\n // if this group has not a cache canvas there is nothing to clean\n var x = this.cacheWidth / this.zoomX,\n y = this.cacheHeight / this.zoomY;\n\n this._cacheContext.clearRect(-x / 2, -y / 2, x, y);\n }\n\n return true;\n }\n }\n\n return false;\n },\n\n /**\n * Retores original state of each of group objects (original state is that which was before group was created).\n * @private\n * @return {fabric.Group} thisArg\n * @chainable\n */\n _restoreObjectsState: function () {\n this._objects.forEach(this._restoreObjectState, this);\n\n return this;\n },\n\n /**\n * Realises the transform from this group onto the supplied object\n * i.e. it tells you what would happen if the supplied object was in\n * the group, and then the group was destroyed. It mutates the supplied\n * object.\n * @param {fabric.Object} object\n * @return {fabric.Object} transformedObject\n */\n realizeTransform: function (object) {\n var matrix = object.calcTransformMatrix(),\n options = fabric.util.qrDecompose(matrix),\n center = new fabric.Point(options.translateX, options.translateY);\n object.flipX = false;\n object.flipY = false;\n object.set('scaleX', options.scaleX);\n object.set('scaleY', options.scaleY);\n object.skewX = options.skewX;\n object.skewY = options.skewY;\n object.angle = options.angle;\n object.setPositionByOrigin(center, 'center', 'center');\n return object;\n },\n\n /**\n * Restores original state of a specified object in group\n * @private\n * @param {fabric.Object} object\n * @return {fabric.Group} thisArg\n */\n _restoreObjectState: function (object) {\n this.realizeTransform(object);\n delete object.group;\n object.setCoords();\n return this;\n },\n\n /**\n * Destroys a group (restoring state of its objects)\n * @return {fabric.Group} thisArg\n * @chainable\n */\n destroy: function () {\n // when group is destroyed objects needs to get a repaint to be eventually\n // displayed on canvas.\n this._objects.forEach(function (object) {\n object.set('dirty', true);\n });\n\n return this._restoreObjectsState();\n },\n\n /**\n * make a group an active selection, remove the group from canvas\n * the group has to be on canvas for this to work.\n * @return {fabric.ActiveSelection} thisArg\n * @chainable\n */\n toActiveSelection: function () {\n if (!this.canvas) {\n return;\n }\n\n var objects = this._objects,\n canvas = this.canvas;\n this._objects = [];\n var options = this.toObject();\n delete options.objects;\n var activeSelection = new fabric.ActiveSelection([]);\n activeSelection.set(options);\n activeSelection.type = 'activeSelection';\n canvas.remove(this);\n objects.forEach(function (object) {\n object.group = activeSelection;\n object.dirty = true;\n canvas.add(object);\n });\n activeSelection.canvas = canvas;\n activeSelection._objects = objects;\n canvas._activeObject = activeSelection;\n activeSelection.setCoords();\n return activeSelection;\n },\n\n /**\n * Destroys a group (restoring state of its objects)\n * @return {fabric.Group} thisArg\n * @chainable\n */\n ungroupOnCanvas: function () {\n return this._restoreObjectsState();\n },\n\n /**\n * Sets coordinates of all objects inside group\n * @return {fabric.Group} thisArg\n * @chainable\n */\n setObjectsCoords: function () {\n var skipControls = true;\n this.forEachObject(function (object) {\n object.setCoords(skipControls);\n });\n return this;\n },\n\n /**\n * @private\n */\n _calcBounds: function (onlyWidthHeight) {\n var aX = [],\n aY = [],\n o,\n prop,\n props = ['tr', 'br', 'bl', 'tl'],\n i = 0,\n iLen = this._objects.length,\n j,\n jLen = props.length;\n\n for (; i < iLen; ++i) {\n o = this._objects[i];\n o.aCoords = o.calcACoords();\n\n for (j = 0; j < jLen; j++) {\n prop = props[j];\n aX.push(o.aCoords[prop].x);\n aY.push(o.aCoords[prop].y);\n }\n }\n\n this._getBounds(aX, aY, onlyWidthHeight);\n },\n\n /**\n * @private\n */\n _getBounds: function (aX, aY, onlyWidthHeight) {\n var minXY = new fabric.Point(min(aX), min(aY)),\n maxXY = new fabric.Point(max(aX), max(aY)),\n top = minXY.y || 0,\n left = minXY.x || 0,\n width = maxXY.x - minXY.x || 0,\n height = maxXY.y - minXY.y || 0;\n this.width = width;\n this.height = height;\n\n if (!onlyWidthHeight) {\n // the bounding box always finds the topleft most corner.\n // whatever is the group origin, we set up here the left/top position.\n this.setPositionByOrigin({\n x: left,\n y: top\n }, 'left', 'top');\n }\n },\n\n /* _TO_SVG_START_ */\n\n /**\n * Returns svg representation of an instance\n * @param {Function} [reviver] Method for further parsing of svg representation.\n * @return {String} svg representation of an instance\n */\n _toSVG: function (reviver) {\n var svgString = ['<g ', 'COMMON_PARTS', ' >\\n'];\n\n for (var i = 0, len = this._objects.length; i < len; i++) {\n svgString.push('\\t\\t', this._objects[i].toSVG(reviver));\n }\n\n svgString.push('</g>\\n');\n return svgString;\n },\n\n /**\n * Returns styles-string for svg-export, specific version for group\n * @return {String}\n */\n getSvgStyles: function () {\n var opacity = typeof this.opacity !== 'undefined' && this.opacity !== 1 ? 'opacity: ' + this.opacity + ';' : '',\n visibility = this.visible ? '' : ' visibility: hidden;';\n return [opacity, this.getSvgFilter(), visibility].join('');\n },\n\n /**\n * Returns svg clipPath representation of an instance\n * @param {Function} [reviver] Method for further parsing of svg representation.\n * @return {String} svg representation of an instance\n */\n toClipPathSVG: function (reviver) {\n var svgString = [];\n\n for (var i = 0, len = this._objects.length; i < len; i++) {\n svgString.push('\\t', this._objects[i].toClipPathSVG(reviver));\n }\n\n return this._createBaseClipPathSVGMarkup(svgString, {\n reviver: reviver\n });\n }\n /* _TO_SVG_END_ */\n\n });\n /**\n * Returns {@link fabric.Group} instance from an object representation\n * @static\n * @memberOf fabric.Group\n * @param {Object} object Object to create a group from\n * @param {Function} [callback] Callback to invoke when an group instance is created\n */\n\n fabric.Group.fromObject = function (object, callback) {\n var objects = object.objects,\n options = fabric.util.object.clone(object, true);\n delete options.objects;\n\n if (typeof objects === 'string') {\n // it has to be an url or something went wrong.\n fabric.loadSVGFromURL(objects, function (elements) {\n var group = fabric.util.groupSVGElements(elements, object, objects);\n group.set(options);\n callback && callback(group);\n });\n return;\n }\n\n fabric.util.enlivenObjects(objects, function (enlivenedObjects) {\n fabric.util.enlivenObjects([object.clipPath], function (enlivedClipPath) {\n var options = fabric.util.object.clone(object, true);\n options.clipPath = enlivedClipPath[0];\n delete options.objects;\n callback && callback(new fabric.Group(enlivenedObjects, options, true));\n });\n });\n };\n})(typeof exports !== 'undefined' ? exports : this);\n\n(function (global) {\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = {});\n\n if (fabric.ActiveSelection) {\n return;\n }\n /**\n * Group class\n * @class fabric.ActiveSelection\n * @extends fabric.Group\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#groups}\n * @see {@link fabric.ActiveSelection#initialize} for constructor definition\n */\n\n\n fabric.ActiveSelection = fabric.util.createClass(fabric.Group,\n /** @lends fabric.ActiveSelection.prototype */\n {\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'activeSelection',\n\n /**\n * Constructor\n * @param {Object} objects ActiveSelection objects\n * @param {Object} [options] Options object\n * @return {Object} thisArg\n */\n initialize: function (objects, options) {\n options = options || {};\n this._objects = objects || [];\n\n for (var i = this._objects.length; i--;) {\n this._objects[i].group = this;\n }\n\n if (options.originX) {\n this.originX = options.originX;\n }\n\n if (options.originY) {\n this.originY = options.originY;\n }\n\n this._calcBounds();\n\n this._updateObjectsCoords();\n\n fabric.Object.prototype.initialize.call(this, options);\n this.setCoords();\n },\n\n /**\n * Change te activeSelection to a normal group,\n * High level function that automatically adds it to canvas as\n * active object. no events fired.\n * @since 2.0.0\n * @return {fabric.Group}\n */\n toGroup: function () {\n var objects = this._objects.concat();\n\n this._objects = [];\n var options = fabric.Object.prototype.toObject.call(this);\n var newGroup = new fabric.Group([]);\n delete options.type;\n newGroup.set(options);\n objects.forEach(function (object) {\n object.canvas.remove(object);\n object.group = newGroup;\n });\n newGroup._objects = objects;\n\n if (!this.canvas) {\n return newGroup;\n }\n\n var canvas = this.canvas;\n canvas.add(newGroup);\n canvas._activeObject = newGroup;\n newGroup.setCoords();\n return newGroup;\n },\n\n /**\n * If returns true, deselection is cancelled.\n * @since 2.0.0\n * @return {Boolean} [cancel]\n */\n onDeselect: function () {\n this.destroy();\n return false;\n },\n\n /**\n * Returns string representation of a group\n * @return {String}\n */\n toString: function () {\n return '#<fabric.ActiveSelection: (' + this.complexity() + ')>';\n },\n\n /**\n * Decide if the object should cache or not. Create its own cache level\n * objectCaching is a global flag, wins over everything\n * needsItsOwnCache should be used when the object drawing method requires\n * a cache step. None of the fabric classes requires it.\n * Generally you do not cache objects in groups because the group outside is cached.\n * @return {Boolean}\n */\n shouldCache: function () {\n return false;\n },\n\n /**\n * Check if this group or its parent group are caching, recursively up\n * @return {Boolean}\n */\n isOnACache: function () {\n return false;\n },\n\n /**\n * Renders controls and borders for the object\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Object} [styleOverride] properties to override the object style\n * @param {Object} [childrenOverride] properties to override the children overrides\n */\n _renderControls: function (ctx, styleOverride, childrenOverride) {\n ctx.save();\n ctx.globalAlpha = this.isMoving ? this.borderOpacityWhenMoving : 1;\n this.callSuper('_renderControls', ctx, styleOverride);\n childrenOverride = childrenOverride || {};\n\n if (typeof childrenOverride.hasControls === 'undefined') {\n childrenOverride.hasControls = false;\n }\n\n childrenOverride.forActiveSelection = true;\n\n for (var i = 0, len = this._objects.length; i < len; i++) {\n this._objects[i]._renderControls(ctx, childrenOverride);\n }\n\n ctx.restore();\n }\n });\n /**\n * Returns {@link fabric.ActiveSelection} instance from an object representation\n * @static\n * @memberOf fabric.ActiveSelection\n * @param {Object} object Object to create a group from\n * @param {Function} [callback] Callback to invoke when an ActiveSelection instance is created\n */\n\n fabric.ActiveSelection.fromObject = function (object, callback) {\n fabric.util.enlivenObjects(object.objects, function (enlivenedObjects) {\n delete object.objects;\n callback && callback(new fabric.ActiveSelection(enlivenedObjects, object, true));\n });\n };\n})(typeof exports !== 'undefined' ? exports : this);\n\n(function (global) {\n 'use strict';\n\n var extend = fabric.util.object.extend;\n\n if (!global.fabric) {\n global.fabric = {};\n }\n\n if (global.fabric.Image) {\n fabric.warn('fabric.Image is already defined.');\n return;\n }\n /**\n * Image class\n * @class fabric.Image\n * @extends fabric.Object\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#images}\n * @see {@link fabric.Image#initialize} for constructor definition\n */\n\n\n fabric.Image = fabric.util.createClass(fabric.Object,\n /** @lends fabric.Image.prototype */\n {\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'image',\n\n /**\n * Width of a stroke.\n * For image quality a stroke multiple of 2 gives better results.\n * @type Number\n * @default\n */\n strokeWidth: 0,\n\n /**\n * When calling {@link fabric.Image.getSrc}, return value from element src with `element.getAttribute('src')`.\n * This allows for relative urls as image src.\n * @since 2.7.0\n * @type Boolean\n * @default\n */\n srcFromAttribute: false,\n\n /**\n * private\n * contains last value of scaleX to detect\n * if the Image got resized after the last Render\n * @type Number\n */\n _lastScaleX: 1,\n\n /**\n * private\n * contains last value of scaleY to detect\n * if the Image got resized after the last Render\n * @type Number\n */\n _lastScaleY: 1,\n\n /**\n * private\n * contains last value of scaling applied by the apply filter chain\n * @type Number\n */\n _filterScalingX: 1,\n\n /**\n * private\n * contains last value of scaling applied by the apply filter chain\n * @type Number\n */\n _filterScalingY: 1,\n\n /**\n * minimum scale factor under which any resizeFilter is triggered to resize the image\n * 0 will disable the automatic resize. 1 will trigger automatically always.\n * number bigger than 1 are not implemented yet.\n * @type Number\n */\n minimumScaleTrigger: 0.5,\n\n /**\n * List of properties to consider when checking if\n * state of an object is changed ({@link fabric.Object#hasStateChanged})\n * as well as for history (undo/redo) purposes\n * @type Array\n */\n stateProperties: fabric.Object.prototype.stateProperties.concat('cropX', 'cropY'),\n\n /**\n * key used to retrieve the texture representing this image\n * @since 2.0.0\n * @type String\n * @default\n */\n cacheKey: '',\n\n /**\n * Image crop in pixels from original image size.\n * @since 2.0.0\n * @type Number\n * @default\n */\n cropX: 0,\n\n /**\n * Image crop in pixels from original image size.\n * @since 2.0.0\n * @type Number\n * @default\n */\n cropY: 0,\n\n /**\n * Indicates whether this canvas will use image smoothing when painting this image.\n * Also influence if the cacheCanvas for this image uses imageSmoothing\n * @since 4.0.0-beta.11\n * @type Boolean\n * @default\n */\n imageSmoothing: true,\n\n /**\n * Constructor\n * @param {HTMLImageElement | String} element Image element\n * @param {Object} [options] Options object\n * @param {function} [callback] callback function to call after eventual filters applied.\n * @return {fabric.Image} thisArg\n */\n initialize: function (element, options) {\n options || (options = {});\n this.filters = [];\n this.cacheKey = 'texture' + fabric.Object.__uid++;\n this.callSuper('initialize', options);\n\n this._initElement(element, options);\n },\n\n /**\n * Returns image element which this instance if based on\n * @return {HTMLImageElement} Image element\n */\n getElement: function () {\n return this._element || {};\n },\n\n /**\n * Sets image element for this instance to a specified one.\n * If filters defined they are applied to new image.\n * You might need to call `canvas.renderAll` and `object.setCoords` after replacing, to render new image and update controls area.\n * @param {HTMLImageElement} element\n * @param {Object} [options] Options object\n * @return {fabric.Image} thisArg\n * @chainable\n */\n setElement: function (element, options) {\n this.removeTexture(this.cacheKey);\n this.removeTexture(this.cacheKey + '_filtered');\n this._element = element;\n this._originalElement = element;\n\n this._initConfig(options);\n\n if (this.filters.length !== 0) {\n this.applyFilters();\n } // resizeFilters work on the already filtered copy.\n // we need to apply resizeFilters AFTER normal filters.\n // applyResizeFilters is run more often than normal fiters\n // and is triggered by user interactions rather than dev code\n\n\n if (this.resizeFilter) {\n this.applyResizeFilters();\n }\n\n return this;\n },\n\n /**\n * Delete a single texture if in webgl mode\n */\n removeTexture: function (key) {\n var backend = fabric.filterBackend;\n\n if (backend && backend.evictCachesForKey) {\n backend.evictCachesForKey(key);\n }\n },\n\n /**\n * Delete textures, reference to elements and eventually JSDOM cleanup\n */\n dispose: function () {\n this.removeTexture(this.cacheKey);\n this.removeTexture(this.cacheKey + '_filtered');\n this._cacheContext = undefined;\n ['_originalElement', '_element', '_filteredEl', '_cacheCanvas'].forEach(function (element) {\n fabric.util.cleanUpJsdomNode(this[element]);\n this[element] = undefined;\n }.bind(this));\n },\n\n /**\n * Get the crossOrigin value (of the corresponding image element)\n */\n getCrossOrigin: function () {\n return this._originalElement && (this._originalElement.crossOrigin || null);\n },\n\n /**\n * Returns original size of an image\n * @return {Object} Object with \"width\" and \"height\" properties\n */\n getOriginalSize: function () {\n var element = this.getElement();\n return {\n width: element.naturalWidth || element.width,\n height: element.naturalHeight || element.height\n };\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _stroke: function (ctx) {\n if (!this.stroke || this.strokeWidth === 0) {\n return;\n }\n\n var w = this.width / 2,\n h = this.height / 2;\n ctx.beginPath();\n ctx.moveTo(-w, -h);\n ctx.lineTo(w, -h);\n ctx.lineTo(w, h);\n ctx.lineTo(-w, h);\n ctx.lineTo(-w, -h);\n ctx.closePath();\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderDashedStroke: function (ctx) {\n var x = -this.width / 2,\n y = -this.height / 2,\n w = this.width,\n h = this.height;\n ctx.save();\n\n this._setStrokeStyles(ctx, this);\n\n ctx.beginPath();\n fabric.util.drawDashedLine(ctx, x, y, x + w, y, this.strokeDashArray);\n fabric.util.drawDashedLine(ctx, x + w, y, x + w, y + h, this.strokeDashArray);\n fabric.util.drawDashedLine(ctx, x + w, y + h, x, y + h, this.strokeDashArray);\n fabric.util.drawDashedLine(ctx, x, y + h, x, y, this.strokeDashArray);\n ctx.closePath();\n ctx.restore();\n },\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} Object representation of an instance\n */\n toObject: function (propertiesToInclude) {\n var filters = [];\n this.filters.forEach(function (filterObj) {\n if (filterObj) {\n filters.push(filterObj.toObject());\n }\n });\n var object = extend(this.callSuper('toObject', ['cropX', 'cropY'].concat(propertiesToInclude)), {\n src: this.getSrc(),\n crossOrigin: this.getCrossOrigin(),\n filters: filters\n });\n\n if (this.resizeFilter) {\n object.resizeFilter = this.resizeFilter.toObject();\n }\n\n return object;\n },\n\n /**\n * Returns true if an image has crop applied, inspecting values of cropX,cropY,width,hight.\n * @return {Boolean}\n */\n hasCrop: function () {\n return this.cropX || this.cropY || this.width < this._element.width || this.height < this._element.height;\n },\n\n /* _TO_SVG_START_ */\n\n /**\n * Returns svg representation of an instance\n * @return {Array} an array of strings with the specific svg representation\n * of the instance\n */\n _toSVG: function () {\n var svgString = [],\n imageMarkup = [],\n strokeSvg,\n element = this._element,\n x = -this.width / 2,\n y = -this.height / 2,\n clipPath = '',\n imageRendering = '';\n\n if (!element) {\n return [];\n }\n\n if (this.hasCrop()) {\n var clipPathId = fabric.Object.__uid++;\n svgString.push('<clipPath id=\"imageCrop_' + clipPathId + '\">\\n', '\\t<rect x=\"' + x + '\" y=\"' + y + '\" width=\"' + this.width + '\" height=\"' + this.height + '\" />\\n', '</clipPath>\\n');\n clipPath = ' clip-path=\"url(#imageCrop_' + clipPathId + ')\" ';\n }\n\n if (!this.imageSmoothing) {\n imageRendering = '\" image-rendering=\"optimizeSpeed';\n }\n\n imageMarkup.push('\\t<image ', 'COMMON_PARTS', 'xlink:href=\"', this.getSvgSrc(true), '\" x=\"', x - this.cropX, '\" y=\"', y - this.cropY, // we're essentially moving origin of transformation from top/left corner to the center of the shape\n // by wrapping it in container <g> element with actual transformation, then offsetting object to the top/left\n // so that object's center aligns with container's left/top\n '\" width=\"', element.width || element.naturalWidth, '\" height=\"', element.height || element.height, imageRendering, '\"', clipPath, '></image>\\n');\n\n if (this.stroke || this.strokeDashArray) {\n var origFill = this.fill;\n this.fill = null;\n strokeSvg = ['\\t<rect ', 'x=\"', x, '\" y=\"', y, '\" width=\"', this.width, '\" height=\"', this.height, '\" style=\"', this.getSvgStyles(), '\"/>\\n'];\n this.fill = origFill;\n }\n\n if (this.paintFirst !== 'fill') {\n svgString = svgString.concat(strokeSvg, imageMarkup);\n } else {\n svgString = svgString.concat(imageMarkup, strokeSvg);\n }\n\n return svgString;\n },\n\n /* _TO_SVG_END_ */\n\n /**\n * Returns source of an image\n * @param {Boolean} filtered indicates if the src is needed for svg\n * @return {String} Source of an image\n */\n getSrc: function (filtered) {\n var element = filtered ? this._element : this._originalElement;\n\n if (element) {\n if (element.toDataURL) {\n return element.toDataURL();\n }\n\n if (this.srcFromAttribute) {\n return element.getAttribute('src');\n } else {\n return element.src;\n }\n } else {\n return this.src || '';\n }\n },\n\n /**\n * Sets source of an image\n * @param {String} src Source string (URL)\n * @param {Function} [callback] Callback is invoked when image has been loaded (and all filters have been applied)\n * @param {Object} [options] Options object\n * @param {String} [options.crossOrigin] crossOrigin value (one of \"\", \"anonymous\", \"use-credentials\")\n * @see https://developer.mozilla.org/en-US/docs/HTML/CORS_settings_attributes\n * @return {fabric.Image} thisArg\n * @chainable\n */\n setSrc: function (src, callback, options) {\n fabric.util.loadImage(src, function (img, isError) {\n this.setElement(img, options);\n\n this._setWidthHeight();\n\n callback && callback(this, isError);\n }, this, options && options.crossOrigin);\n return this;\n },\n\n /**\n * Returns string representation of an instance\n * @return {String} String representation of an instance\n */\n toString: function () {\n return '#<fabric.Image: { src: \"' + this.getSrc() + '\" }>';\n },\n applyResizeFilters: function () {\n var filter = this.resizeFilter,\n minimumScale = this.minimumScaleTrigger,\n objectScale = this.getTotalObjectScaling(),\n scaleX = objectScale.scaleX,\n scaleY = objectScale.scaleY,\n elementToFilter = this._filteredEl || this._originalElement;\n\n if (this.group) {\n this.set('dirty', true);\n }\n\n if (!filter || scaleX > minimumScale && scaleY > minimumScale) {\n this._element = elementToFilter;\n this._filterScalingX = 1;\n this._filterScalingY = 1;\n this._lastScaleX = scaleX;\n this._lastScaleY = scaleY;\n return;\n }\n\n if (!fabric.filterBackend) {\n fabric.filterBackend = fabric.initFilterBackend();\n }\n\n var canvasEl = fabric.util.createCanvasElement(),\n cacheKey = this._filteredEl ? this.cacheKey + '_filtered' : this.cacheKey,\n sourceWidth = elementToFilter.width,\n sourceHeight = elementToFilter.height;\n canvasEl.width = sourceWidth;\n canvasEl.height = sourceHeight;\n this._element = canvasEl;\n this._lastScaleX = filter.scaleX = scaleX;\n this._lastScaleY = filter.scaleY = scaleY;\n fabric.filterBackend.applyFilters([filter], elementToFilter, sourceWidth, sourceHeight, this._element, cacheKey);\n this._filterScalingX = canvasEl.width / this._originalElement.width;\n this._filterScalingY = canvasEl.height / this._originalElement.height;\n },\n\n /**\n * Applies filters assigned to this image (from \"filters\" array) or from filter param\n * @method applyFilters\n * @param {Array} filters to be applied\n * @param {Boolean} forResizing specify if the filter operation is a resize operation\n * @return {thisArg} return the fabric.Image object\n * @chainable\n */\n applyFilters: function (filters) {\n filters = filters || this.filters || [];\n filters = filters.filter(function (filter) {\n return filter && !filter.isNeutralState();\n });\n this.set('dirty', true); // needs to clear out or WEBGL will not resize correctly\n\n this.removeTexture(this.cacheKey + '_filtered');\n\n if (filters.length === 0) {\n this._element = this._originalElement;\n this._filteredEl = null;\n this._filterScalingX = 1;\n this._filterScalingY = 1;\n return this;\n }\n\n var imgElement = this._originalElement,\n sourceWidth = imgElement.naturalWidth || imgElement.width,\n sourceHeight = imgElement.naturalHeight || imgElement.height;\n\n if (this._element === this._originalElement) {\n // if the element is the same we need to create a new element\n var canvasEl = fabric.util.createCanvasElement();\n canvasEl.width = sourceWidth;\n canvasEl.height = sourceHeight;\n this._element = canvasEl;\n this._filteredEl = canvasEl;\n } else {\n // clear the existing element to get new filter data\n // also dereference the eventual resized _element\n this._element = this._filteredEl;\n\n this._filteredEl.getContext('2d').clearRect(0, 0, sourceWidth, sourceHeight); // we also need to resize again at next renderAll, so remove saved _lastScaleX/Y\n\n\n this._lastScaleX = 1;\n this._lastScaleY = 1;\n }\n\n if (!fabric.filterBackend) {\n fabric.filterBackend = fabric.initFilterBackend();\n }\n\n fabric.filterBackend.applyFilters(filters, this._originalElement, sourceWidth, sourceHeight, this._element, this.cacheKey);\n\n if (this._originalElement.width !== this._element.width || this._originalElement.height !== this._element.height) {\n this._filterScalingX = this._element.width / this._originalElement.width;\n this._filterScalingY = this._element.height / this._originalElement.height;\n }\n\n return this;\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _render: function (ctx) {\n fabric.util.setImageSmoothing(ctx, this.imageSmoothing);\n\n if (this.isMoving !== true && this.resizeFilter && this._needsResize()) {\n this.applyResizeFilters();\n }\n\n this._stroke(ctx);\n\n this._renderPaintInOrder(ctx);\n },\n\n /**\n * Paint the cached copy of the object on the target context.\n * it will set the imageSmoothing for the draw operation\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n drawCacheOnCanvas: function (ctx) {\n fabric.util.setImageSmoothing(ctx, this.imageSmoothing);\n fabric.Object.prototype.drawCacheOnCanvas.call(this, ctx);\n },\n\n /**\n * Decide if the object should cache or not. Create its own cache level\n * needsItsOwnCache should be used when the object drawing method requires\n * a cache step. None of the fabric classes requires it.\n * Generally you do not cache objects in groups because the group outside is cached.\n * This is the special image version where we would like to avoid caching where possible.\n * Essentially images do not benefit from caching. They may require caching, and in that\n * case we do it. Also caching an image usually ends in a loss of details.\n * A full performance audit should be done.\n * @return {Boolean}\n */\n shouldCache: function () {\n return this.needsItsOwnCache();\n },\n _renderFill: function (ctx) {\n var elementToDraw = this._element;\n\n if (!elementToDraw) {\n return;\n }\n\n var scaleX = this._filterScalingX,\n scaleY = this._filterScalingY,\n w = this.width,\n h = this.height,\n min = Math.min,\n max = Math.max,\n // crop values cannot be lesser than 0.\n cropX = max(this.cropX, 0),\n cropY = max(this.cropY, 0),\n elWidth = elementToDraw.naturalWidth || elementToDraw.width,\n elHeight = elementToDraw.naturalHeight || elementToDraw.height,\n sX = cropX * scaleX,\n sY = cropY * scaleY,\n // the width height cannot exceed element width/height, starting from the crop offset.\n sW = min(w * scaleX, elWidth - sX),\n sH = min(h * scaleY, elHeight - sY),\n x = -w / 2,\n y = -h / 2,\n maxDestW = min(w, elWidth / scaleX - cropX),\n maxDestH = min(h, elHeight / scaleX - cropY);\n elementToDraw && ctx.drawImage(elementToDraw, sX, sY, sW, sH, x, y, maxDestW, maxDestH);\n },\n\n /**\n * needed to check if image needs resize\n * @private\n */\n _needsResize: function () {\n var scale = this.getTotalObjectScaling();\n return scale.scaleX !== this._lastScaleX || scale.scaleY !== this._lastScaleY;\n },\n\n /**\n * @private\n */\n _resetWidthHeight: function () {\n this.set(this.getOriginalSize());\n },\n\n /**\n * The Image class's initialization method. This method is automatically\n * called by the constructor.\n * @private\n * @param {HTMLImageElement|String} element The element representing the image\n * @param {Object} [options] Options object\n */\n _initElement: function (element, options) {\n this.setElement(fabric.util.getById(element), options);\n fabric.util.addClass(this.getElement(), fabric.Image.CSS_CANVAS);\n },\n\n /**\n * @private\n * @param {Object} [options] Options object\n */\n _initConfig: function (options) {\n options || (options = {});\n this.setOptions(options);\n\n this._setWidthHeight(options);\n },\n\n /**\n * @private\n * @param {Array} filters to be initialized\n * @param {Function} callback Callback to invoke when all fabric.Image.filters instances are created\n */\n _initFilters: function (filters, callback) {\n if (filters && filters.length) {\n fabric.util.enlivenObjects(filters, function (enlivenedObjects) {\n callback && callback(enlivenedObjects);\n }, 'fabric.Image.filters');\n } else {\n callback && callback();\n }\n },\n\n /**\n * @private\n * Set the width and the height of the image object, using the element or the\n * options.\n * @param {Object} [options] Object with width/height properties\n */\n _setWidthHeight: function (options) {\n options || (options = {});\n var el = this.getElement();\n this.width = options.width || el.naturalWidth || el.width || 0;\n this.height = options.height || el.naturalHeight || el.height || 0;\n },\n\n /**\n * Calculate offset for center and scale factor for the image in order to respect\n * the preserveAspectRatio attribute\n * @private\n * @return {Object}\n */\n parsePreserveAspectRatioAttribute: function () {\n var pAR = fabric.util.parsePreserveAspectRatioAttribute(this.preserveAspectRatio || ''),\n rWidth = this._element.width,\n rHeight = this._element.height,\n scaleX = 1,\n scaleY = 1,\n offsetLeft = 0,\n offsetTop = 0,\n cropX = 0,\n cropY = 0,\n offset,\n pWidth = this.width,\n pHeight = this.height,\n parsedAttributes = {\n width: pWidth,\n height: pHeight\n };\n\n if (pAR && (pAR.alignX !== 'none' || pAR.alignY !== 'none')) {\n if (pAR.meetOrSlice === 'meet') {\n scaleX = scaleY = fabric.util.findScaleToFit(this._element, parsedAttributes);\n offset = (pWidth - rWidth * scaleX) / 2;\n\n if (pAR.alignX === 'Min') {\n offsetLeft = -offset;\n }\n\n if (pAR.alignX === 'Max') {\n offsetLeft = offset;\n }\n\n offset = (pHeight - rHeight * scaleY) / 2;\n\n if (pAR.alignY === 'Min') {\n offsetTop = -offset;\n }\n\n if (pAR.alignY === 'Max') {\n offsetTop = offset;\n }\n }\n\n if (pAR.meetOrSlice === 'slice') {\n scaleX = scaleY = fabric.util.findScaleToCover(this._element, parsedAttributes);\n offset = rWidth - pWidth / scaleX;\n\n if (pAR.alignX === 'Mid') {\n cropX = offset / 2;\n }\n\n if (pAR.alignX === 'Max') {\n cropX = offset;\n }\n\n offset = rHeight - pHeight / scaleY;\n\n if (pAR.alignY === 'Mid') {\n cropY = offset / 2;\n }\n\n if (pAR.alignY === 'Max') {\n cropY = offset;\n }\n\n rWidth = pWidth / scaleX;\n rHeight = pHeight / scaleY;\n }\n } else {\n scaleX = pWidth / rWidth;\n scaleY = pHeight / rHeight;\n }\n\n return {\n width: rWidth,\n height: rHeight,\n scaleX: scaleX,\n scaleY: scaleY,\n offsetLeft: offsetLeft,\n offsetTop: offsetTop,\n cropX: cropX,\n cropY: cropY\n };\n }\n });\n /**\n * Default CSS class name for canvas\n * @static\n * @type String\n * @default\n */\n\n fabric.Image.CSS_CANVAS = 'canvas-img';\n /**\n * Alias for getSrc\n * @static\n */\n\n fabric.Image.prototype.getSvgSrc = fabric.Image.prototype.getSrc;\n /**\n * Creates an instance of fabric.Image from its object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {Function} callback Callback to invoke when an image instance is created\n */\n\n fabric.Image.fromObject = function (_object, callback) {\n var object = fabric.util.object.clone(_object);\n fabric.util.loadImage(object.src, function (img, isError) {\n if (isError) {\n callback && callback(null, true);\n return;\n }\n\n fabric.Image.prototype._initFilters.call(object, object.filters, function (filters) {\n object.filters = filters || [];\n\n fabric.Image.prototype._initFilters.call(object, [object.resizeFilter], function (resizeFilters) {\n object.resizeFilter = resizeFilters[0];\n fabric.util.enlivenObjects([object.clipPath], function (enlivedProps) {\n object.clipPath = enlivedProps[0];\n var image = new fabric.Image(img, object);\n callback(image, false);\n });\n });\n });\n }, null, object.crossOrigin);\n };\n /**\n * Creates an instance of fabric.Image from an URL string\n * @static\n * @param {String} url URL to create an image from\n * @param {Function} [callback] Callback to invoke when image is created (newly created image is passed as a first argument). Second argument is a boolean indicating if an error occured or not.\n * @param {Object} [imgOptions] Options object\n */\n\n\n fabric.Image.fromURL = function (url, callback, imgOptions) {\n fabric.util.loadImage(url, function (img, isError) {\n callback && callback(new fabric.Image(img, imgOptions), isError);\n }, null, imgOptions && imgOptions.crossOrigin);\n };\n /* _FROM_SVG_START_ */\n\n /**\n * List of attribute names to account for when parsing SVG element (used by {@link fabric.Image.fromElement})\n * @static\n * @see {@link http://www.w3.org/TR/SVG/struct.html#ImageElement}\n */\n\n\n fabric.Image.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat('x y width height preserveAspectRatio xlink:href crossOrigin image-rendering'.split(' '));\n /**\n * Returns {@link fabric.Image} instance from an SVG element\n * @static\n * @param {SVGElement} element Element to parse\n * @param {Object} [options] Options object\n * @param {Function} callback Callback to execute when fabric.Image object is created\n * @return {fabric.Image} Instance of fabric.Image\n */\n\n fabric.Image.fromElement = function (element, callback, options) {\n var parsedAttributes = fabric.parseAttributes(element, fabric.Image.ATTRIBUTE_NAMES);\n fabric.Image.fromURL(parsedAttributes['xlink:href'], callback, extend(options ? fabric.util.object.clone(options) : {}, parsedAttributes));\n };\n /* _FROM_SVG_END_ */\n\n})(typeof exports !== 'undefined' ? exports : this);\n\nfabric.util.object.extend(fabric.Object.prototype,\n/** @lends fabric.Object.prototype */\n{\n /**\n * @private\n * @return {Number} angle value\n */\n _getAngleValueForStraighten: function () {\n var angle = this.angle % 360;\n\n if (angle > 0) {\n return Math.round((angle - 1) / 90) * 90;\n }\n\n return Math.round(angle / 90) * 90;\n },\n\n /**\n * Straightens an object (rotating it from current angle to one of 0, 90, 180, 270, etc. depending on which is closer)\n * @return {fabric.Object} thisArg\n * @chainable\n */\n straighten: function () {\n this.rotate(this._getAngleValueForStraighten());\n return this;\n },\n\n /**\n * Same as {@link fabric.Object.prototype.straighten} but with animation\n * @param {Object} callbacks Object with callback functions\n * @param {Function} [callbacks.onComplete] Invoked on completion\n * @param {Function} [callbacks.onChange] Invoked on every step of animation\n * @return {fabric.Object} thisArg\n * @chainable\n */\n fxStraighten: function (callbacks) {\n callbacks = callbacks || {};\n\n var empty = function () {},\n onComplete = callbacks.onComplete || empty,\n onChange = callbacks.onChange || empty,\n _this = this;\n\n fabric.util.animate({\n startValue: this.get('angle'),\n endValue: this._getAngleValueForStraighten(),\n duration: this.FX_DURATION,\n onChange: function (value) {\n _this.rotate(value);\n\n onChange();\n },\n onComplete: function () {\n _this.setCoords();\n\n onComplete();\n }\n });\n return this;\n }\n});\nfabric.util.object.extend(fabric.StaticCanvas.prototype,\n/** @lends fabric.StaticCanvas.prototype */\n{\n /**\n * Straightens object, then rerenders canvas\n * @param {fabric.Object} object Object to straighten\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n straightenObject: function (object) {\n object.straighten();\n this.requestRenderAll();\n return this;\n },\n\n /**\n * Same as {@link fabric.Canvas.prototype.straightenObject}, but animated\n * @param {fabric.Object} object Object to straighten\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n fxStraightenObject: function (object) {\n object.fxStraighten({\n onChange: this.requestRenderAllBound\n });\n return this;\n }\n});\n\n(function () {\n 'use strict';\n /**\n * Tests if webgl supports certain precision\n * @param {WebGL} Canvas WebGL context to test on\n * @param {String} Precision to test can be any of following: 'lowp', 'mediump', 'highp'\n * @returns {Boolean} Whether the user's browser WebGL supports given precision.\n */\n\n function testPrecision(gl, precision) {\n var fragmentSource = 'precision ' + precision + ' float;\\nvoid main(){}';\n var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);\n gl.shaderSource(fragmentShader, fragmentSource);\n gl.compileShader(fragmentShader);\n\n if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {\n return false;\n }\n\n return true;\n }\n /**\n * Indicate whether this filtering backend is supported by the user's browser.\n * @param {Number} tileSize check if the tileSize is supported\n * @returns {Boolean} Whether the user's browser supports WebGL.\n */\n\n\n fabric.isWebglSupported = function (tileSize) {\n if (fabric.isLikelyNode) {\n return false;\n }\n\n tileSize = tileSize || fabric.WebglFilterBackend.prototype.tileSize;\n var canvas = document.createElement('canvas');\n var gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');\n var isSupported = false; // eslint-disable-next-line\n\n if (gl) {\n fabric.maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE);\n isSupported = fabric.maxTextureSize >= tileSize;\n var precisions = ['highp', 'mediump', 'lowp'];\n\n for (var i = 0; i < 3; i++) {\n if (testPrecision(gl, precisions[i])) {\n fabric.webGlPrecision = precisions[i];\n break;\n }\n\n ;\n }\n }\n\n this.isSupported = isSupported;\n return isSupported;\n };\n\n fabric.WebglFilterBackend = WebglFilterBackend;\n /**\n * WebGL filter backend.\n */\n\n function WebglFilterBackend(options) {\n if (options && options.tileSize) {\n this.tileSize = options.tileSize;\n }\n\n this.setupGLContext(this.tileSize, this.tileSize);\n this.captureGPUInfo();\n }\n\n ;\n WebglFilterBackend.prototype =\n /** @lends fabric.WebglFilterBackend.prototype */\n {\n tileSize: 2048,\n\n /**\n * Experimental. This object is a sort of repository of help layers used to avoid\n * of recreating them during frequent filtering. If you are previewing a filter with\n * a slider you problably do not want to create help layers every filter step.\n * in this object there will be appended some canvases, created once, resized sometimes\n * cleared never. Clearing is left to the developer.\n **/\n resources: {},\n\n /**\n * Setup a WebGL context suitable for filtering, and bind any needed event handlers.\n */\n setupGLContext: function (width, height) {\n this.dispose();\n this.createWebGLCanvas(width, height); // eslint-disable-next-line\n\n this.aPosition = new Float32Array([0, 0, 0, 1, 1, 0, 1, 1]);\n this.chooseFastestCopyGLTo2DMethod(width, height);\n },\n\n /**\n * Pick a method to copy data from GL context to 2d canvas. In some browsers using\n * putImageData is faster than drawImage for that specific operation.\n */\n chooseFastestCopyGLTo2DMethod: function (width, height) {\n var canMeasurePerf = typeof window.performance !== 'undefined',\n canUseImageData;\n\n try {\n new ImageData(1, 1);\n canUseImageData = true;\n } catch (e) {\n canUseImageData = false;\n } // eslint-disable-next-line no-undef\n\n\n var canUseArrayBuffer = typeof ArrayBuffer !== 'undefined'; // eslint-disable-next-line no-undef\n\n var canUseUint8Clamped = typeof Uint8ClampedArray !== 'undefined';\n\n if (!(canMeasurePerf && canUseImageData && canUseArrayBuffer && canUseUint8Clamped)) {\n return;\n }\n\n var targetCanvas = fabric.util.createCanvasElement(); // eslint-disable-next-line no-undef\n\n var imageBuffer = new ArrayBuffer(width * height * 4);\n\n if (fabric.forceGLPutImageData) {\n this.imageBuffer = imageBuffer;\n this.copyGLTo2D = copyGLTo2DPutImageData;\n return;\n }\n\n var testContext = {\n imageBuffer: imageBuffer,\n destinationWidth: width,\n destinationHeight: height,\n targetCanvas: targetCanvas\n };\n var startTime, drawImageTime, putImageDataTime;\n targetCanvas.width = width;\n targetCanvas.height = height;\n startTime = window.performance.now();\n copyGLTo2DDrawImage.call(testContext, this.gl, testContext);\n drawImageTime = window.performance.now() - startTime;\n startTime = window.performance.now();\n copyGLTo2DPutImageData.call(testContext, this.gl, testContext);\n putImageDataTime = window.performance.now() - startTime;\n\n if (drawImageTime > putImageDataTime) {\n this.imageBuffer = imageBuffer;\n this.copyGLTo2D = copyGLTo2DPutImageData;\n } else {\n this.copyGLTo2D = copyGLTo2DDrawImage;\n }\n },\n\n /**\n * Create a canvas element and associated WebGL context and attaches them as\n * class properties to the GLFilterBackend class.\n */\n createWebGLCanvas: function (width, height) {\n var canvas = fabric.util.createCanvasElement();\n canvas.width = width;\n canvas.height = height;\n var glOptions = {\n alpha: true,\n premultipliedAlpha: false,\n depth: false,\n stencil: false,\n antialias: false\n },\n gl = canvas.getContext('webgl', glOptions);\n\n if (!gl) {\n gl = canvas.getContext('experimental-webgl', glOptions);\n }\n\n if (!gl) {\n return;\n }\n\n gl.clearColor(0, 0, 0, 0); // this canvas can fire webglcontextlost and webglcontextrestored\n\n this.canvas = canvas;\n this.gl = gl;\n },\n\n /**\n * Attempts to apply the requested filters to the source provided, drawing the filtered output\n * to the provided target canvas.\n *\n * @param {Array} filters The filters to apply.\n * @param {HTMLImageElement|HTMLCanvasElement} source The source to be filtered.\n * @param {Number} width The width of the source input.\n * @param {Number} height The height of the source input.\n * @param {HTMLCanvasElement} targetCanvas The destination for filtered output to be drawn.\n * @param {String|undefined} cacheKey A key used to cache resources related to the source. If\n * omitted, caching will be skipped.\n */\n applyFilters: function (filters, source, width, height, targetCanvas, cacheKey) {\n var gl = this.gl;\n var cachedTexture;\n\n if (cacheKey) {\n cachedTexture = this.getCachedTexture(cacheKey, source);\n }\n\n var pipelineState = {\n originalWidth: source.width || source.originalWidth,\n originalHeight: source.height || source.originalHeight,\n sourceWidth: width,\n sourceHeight: height,\n destinationWidth: width,\n destinationHeight: height,\n context: gl,\n sourceTexture: this.createTexture(gl, width, height, !cachedTexture && source),\n targetTexture: this.createTexture(gl, width, height),\n originalTexture: cachedTexture || this.createTexture(gl, width, height, !cachedTexture && source),\n passes: filters.length,\n webgl: true,\n aPosition: this.aPosition,\n programCache: this.programCache,\n pass: 0,\n filterBackend: this,\n targetCanvas: targetCanvas\n };\n var tempFbo = gl.createFramebuffer();\n gl.bindFramebuffer(gl.FRAMEBUFFER, tempFbo);\n filters.forEach(function (filter) {\n filter && filter.applyTo(pipelineState);\n });\n resizeCanvasIfNeeded(pipelineState);\n this.copyGLTo2D(gl, pipelineState);\n gl.bindTexture(gl.TEXTURE_2D, null);\n gl.deleteTexture(pipelineState.sourceTexture);\n gl.deleteTexture(pipelineState.targetTexture);\n gl.deleteFramebuffer(tempFbo);\n targetCanvas.getContext('2d').setTransform(1, 0, 0, 1, 0, 0);\n return pipelineState;\n },\n\n /**\n * Detach event listeners, remove references, and clean up caches.\n */\n dispose: function () {\n if (this.canvas) {\n this.canvas = null;\n this.gl = null;\n }\n\n this.clearWebGLCaches();\n },\n\n /**\n * Wipe out WebGL-related caches.\n */\n clearWebGLCaches: function () {\n this.programCache = {};\n this.textureCache = {};\n },\n\n /**\n * Create a WebGL texture object.\n *\n * Accepts specific dimensions to initialize the textuer to or a source image.\n *\n * @param {WebGLRenderingContext} gl The GL context to use for creating the texture.\n * @param {Number} width The width to initialize the texture at.\n * @param {Number} height The height to initialize the texture.\n * @param {HTMLImageElement|HTMLCanvasElement} textureImageSource A source for the texture data.\n * @returns {WebGLTexture}\n */\n createTexture: function (gl, width, height, textureImageSource) {\n var texture = gl.createTexture();\n gl.bindTexture(gl.TEXTURE_2D, texture);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n\n if (textureImageSource) {\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, textureImageSource);\n } else {\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);\n }\n\n return texture;\n },\n\n /**\n * Can be optionally used to get a texture from the cache array\n *\n * If an existing texture is not found, a new texture is created and cached.\n *\n * @param {String} uniqueId A cache key to use to find an existing texture.\n * @param {HTMLImageElement|HTMLCanvasElement} textureImageSource A source to use to create the\n * texture cache entry if one does not already exist.\n */\n getCachedTexture: function (uniqueId, textureImageSource) {\n if (this.textureCache[uniqueId]) {\n return this.textureCache[uniqueId];\n } else {\n var texture = this.createTexture(this.gl, textureImageSource.width, textureImageSource.height, textureImageSource);\n this.textureCache[uniqueId] = texture;\n return texture;\n }\n },\n\n /**\n * Clear out cached resources related to a source image that has been\n * filtered previously.\n *\n * @param {String} cacheKey The cache key provided when the source image was filtered.\n */\n evictCachesForKey: function (cacheKey) {\n if (this.textureCache[cacheKey]) {\n this.gl.deleteTexture(this.textureCache[cacheKey]);\n delete this.textureCache[cacheKey];\n }\n },\n copyGLTo2D: copyGLTo2DDrawImage,\n\n /**\n * Attempt to extract GPU information strings from a WebGL context.\n *\n * Useful information when debugging or blacklisting specific GPUs.\n *\n * @returns {Object} A GPU info object with renderer and vendor strings.\n */\n captureGPUInfo: function () {\n if (this.gpuInfo) {\n return this.gpuInfo;\n }\n\n var gl = this.gl,\n gpuInfo = {\n renderer: '',\n vendor: ''\n };\n\n if (!gl) {\n return gpuInfo;\n }\n\n var ext = gl.getExtension('WEBGL_debug_renderer_info');\n\n if (ext) {\n var renderer = gl.getParameter(ext.UNMASKED_RENDERER_WEBGL);\n var vendor = gl.getParameter(ext.UNMASKED_VENDOR_WEBGL);\n\n if (renderer) {\n gpuInfo.renderer = renderer.toLowerCase();\n }\n\n if (vendor) {\n gpuInfo.vendor = vendor.toLowerCase();\n }\n }\n\n this.gpuInfo = gpuInfo;\n return gpuInfo;\n }\n };\n})();\n\nfunction resizeCanvasIfNeeded(pipelineState) {\n var targetCanvas = pipelineState.targetCanvas,\n width = targetCanvas.width,\n height = targetCanvas.height,\n dWidth = pipelineState.destinationWidth,\n dHeight = pipelineState.destinationHeight;\n\n if (width !== dWidth || height !== dHeight) {\n targetCanvas.width = dWidth;\n targetCanvas.height = dHeight;\n }\n}\n/**\n * Copy an input WebGL canvas on to an output 2D canvas.\n *\n * The WebGL canvas is assumed to be upside down, with the top-left pixel of the\n * desired output image appearing in the bottom-left corner of the WebGL canvas.\n *\n * @param {WebGLRenderingContext} sourceContext The WebGL context to copy from.\n * @param {HTMLCanvasElement} targetCanvas The 2D target canvas to copy on to.\n * @param {Object} pipelineState The 2D target canvas to copy on to.\n */\n\n\nfunction copyGLTo2DDrawImage(gl, pipelineState) {\n var glCanvas = gl.canvas,\n targetCanvas = pipelineState.targetCanvas,\n ctx = targetCanvas.getContext('2d');\n ctx.translate(0, targetCanvas.height); // move it down again\n\n ctx.scale(1, -1); // vertical flip\n // where is my image on the big glcanvas?\n\n var sourceY = glCanvas.height - targetCanvas.height;\n ctx.drawImage(glCanvas, 0, sourceY, targetCanvas.width, targetCanvas.height, 0, 0, targetCanvas.width, targetCanvas.height);\n}\n/**\n * Copy an input WebGL canvas on to an output 2D canvas using 2d canvas' putImageData\n * API. Measurably faster than using ctx.drawImage in Firefox (version 54 on OSX Sierra).\n *\n * @param {WebGLRenderingContext} sourceContext The WebGL context to copy from.\n * @param {HTMLCanvasElement} targetCanvas The 2D target canvas to copy on to.\n * @param {Object} pipelineState The 2D target canvas to copy on to.\n */\n\n\nfunction copyGLTo2DPutImageData(gl, pipelineState) {\n var targetCanvas = pipelineState.targetCanvas,\n ctx = targetCanvas.getContext('2d'),\n dWidth = pipelineState.destinationWidth,\n dHeight = pipelineState.destinationHeight,\n numBytes = dWidth * dHeight * 4; // eslint-disable-next-line no-undef\n\n var u8 = new Uint8Array(this.imageBuffer, 0, numBytes); // eslint-disable-next-line no-undef\n\n var u8Clamped = new Uint8ClampedArray(this.imageBuffer, 0, numBytes);\n gl.readPixels(0, 0, dWidth, dHeight, gl.RGBA, gl.UNSIGNED_BYTE, u8);\n var imgData = new ImageData(u8Clamped, dWidth, dHeight);\n ctx.putImageData(imgData, 0, 0);\n}\n\n(function () {\n 'use strict';\n\n var noop = function () {};\n\n fabric.Canvas2dFilterBackend = Canvas2dFilterBackend;\n /**\n * Canvas 2D filter backend.\n */\n\n function Canvas2dFilterBackend() {}\n\n ;\n Canvas2dFilterBackend.prototype =\n /** @lends fabric.Canvas2dFilterBackend.prototype */\n {\n evictCachesForKey: noop,\n dispose: noop,\n clearWebGLCaches: noop,\n\n /**\n * Experimental. This object is a sort of repository of help layers used to avoid\n * of recreating them during frequent filtering. If you are previewing a filter with\n * a slider you probably do not want to create help layers every filter step.\n * in this object there will be appended some canvases, created once, resized sometimes\n * cleared never. Clearing is left to the developer.\n **/\n resources: {},\n\n /**\n * Apply a set of filters against a source image and draw the filtered output\n * to the provided destination canvas.\n *\n * @param {EnhancedFilter} filters The filter to apply.\n * @param {HTMLImageElement|HTMLCanvasElement} sourceElement The source to be filtered.\n * @param {Number} sourceWidth The width of the source input.\n * @param {Number} sourceHeight The height of the source input.\n * @param {HTMLCanvasElement} targetCanvas The destination for filtered output to be drawn.\n */\n applyFilters: function (filters, sourceElement, sourceWidth, sourceHeight, targetCanvas) {\n var ctx = targetCanvas.getContext('2d');\n ctx.drawImage(sourceElement, 0, 0, sourceWidth, sourceHeight);\n var imageData = ctx.getImageData(0, 0, sourceWidth, sourceHeight);\n var originalImageData = ctx.getImageData(0, 0, sourceWidth, sourceHeight);\n var pipelineState = {\n sourceWidth: sourceWidth,\n sourceHeight: sourceHeight,\n imageData: imageData,\n originalEl: sourceElement,\n originalImageData: originalImageData,\n canvasEl: targetCanvas,\n ctx: ctx,\n filterBackend: this\n };\n filters.forEach(function (filter) {\n filter.applyTo(pipelineState);\n });\n\n if (pipelineState.imageData.width !== sourceWidth || pipelineState.imageData.height !== sourceHeight) {\n targetCanvas.width = pipelineState.imageData.width;\n targetCanvas.height = pipelineState.imageData.height;\n }\n\n ctx.putImageData(pipelineState.imageData, 0, 0);\n return pipelineState;\n }\n };\n})();\n/**\n * @namespace fabric.Image.filters\n * @memberOf fabric.Image\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#image_filters}\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n */\n\n\nfabric.Image = fabric.Image || {};\nfabric.Image.filters = fabric.Image.filters || {};\n/**\n * Root filter class from which all filter classes inherit from\n * @class fabric.Image.filters.BaseFilter\n * @memberOf fabric.Image.filters\n */\n\nfabric.Image.filters.BaseFilter = fabric.util.createClass(\n/** @lends fabric.Image.filters.BaseFilter.prototype */\n{\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'BaseFilter',\n\n /**\n * Array of attributes to send with buffers. do not modify\n * @private\n */\n vertexSource: 'attribute vec2 aPosition;\\n' + 'varying vec2 vTexCoord;\\n' + 'void main() {\\n' + 'vTexCoord = aPosition;\\n' + 'gl_Position = vec4(aPosition * 2.0 - 1.0, 0.0, 1.0);\\n' + '}',\n fragmentSource: 'precision highp float;\\n' + 'varying vec2 vTexCoord;\\n' + 'uniform sampler2D uTexture;\\n' + 'void main() {\\n' + 'gl_FragColor = texture2D(uTexture, vTexCoord);\\n' + '}',\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n */\n initialize: function (options) {\n if (options) {\n this.setOptions(options);\n }\n },\n\n /**\n * Sets filter's properties from options\n * @param {Object} [options] Options object\n */\n setOptions: function (options) {\n for (var prop in options) {\n this[prop] = options[prop];\n }\n },\n\n /**\n * Compile this filter's shader program.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context to use for shader compilation.\n * @param {String} fragmentSource fragmentShader source for compilation\n * @param {String} vertexSource vertexShader source for compilation\n */\n createProgram: function (gl, fragmentSource, vertexSource) {\n fragmentSource = fragmentSource || this.fragmentSource;\n vertexSource = vertexSource || this.vertexSource;\n\n if (fabric.webGlPrecision !== 'highp') {\n fragmentSource = fragmentSource.replace(/precision highp float/g, 'precision ' + fabric.webGlPrecision + ' float');\n }\n\n var vertexShader = gl.createShader(gl.VERTEX_SHADER);\n gl.shaderSource(vertexShader, vertexSource);\n gl.compileShader(vertexShader);\n\n if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {\n throw new Error( // eslint-disable-next-line prefer-template\n 'Vertex shader compile error for ' + this.type + ': ' + gl.getShaderInfoLog(vertexShader));\n }\n\n var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);\n gl.shaderSource(fragmentShader, fragmentSource);\n gl.compileShader(fragmentShader);\n\n if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {\n throw new Error( // eslint-disable-next-line prefer-template\n 'Fragment shader compile error for ' + this.type + ': ' + gl.getShaderInfoLog(fragmentShader));\n }\n\n var program = gl.createProgram();\n gl.attachShader(program, vertexShader);\n gl.attachShader(program, fragmentShader);\n gl.linkProgram(program);\n\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n throw new Error( // eslint-disable-next-line prefer-template\n 'Shader link error for \"${this.type}\" ' + gl.getProgramInfoLog(program));\n }\n\n var attributeLocations = this.getAttributeLocations(gl, program);\n var uniformLocations = this.getUniformLocations(gl, program) || {};\n uniformLocations.uStepW = gl.getUniformLocation(program, 'uStepW');\n uniformLocations.uStepH = gl.getUniformLocation(program, 'uStepH');\n return {\n program: program,\n attributeLocations: attributeLocations,\n uniformLocations: uniformLocations\n };\n },\n\n /**\n * Return a map of attribute names to WebGLAttributeLocation objects.\n *\n * @param {WebGLRenderingContext} gl The canvas context used to compile the shader program.\n * @param {WebGLShaderProgram} program The shader program from which to take attribute locations.\n * @returns {Object} A map of attribute names to attribute locations.\n */\n getAttributeLocations: function (gl, program) {\n return {\n aPosition: gl.getAttribLocation(program, 'aPosition')\n };\n },\n\n /**\n * Return a map of uniform names to WebGLUniformLocation objects.\n *\n * Intended to be overridden by subclasses.\n *\n * @param {WebGLRenderingContext} gl The canvas context used to compile the shader program.\n * @param {WebGLShaderProgram} program The shader program from which to take uniform locations.\n * @returns {Object} A map of uniform names to uniform locations.\n */\n getUniformLocations: function ()\n /* gl, program */\n {\n // in case i do not need any special uniform i need to return an empty object\n return {};\n },\n\n /**\n * Send attribute data from this filter to its shader program on the GPU.\n *\n * @param {WebGLRenderingContext} gl The canvas context used to compile the shader program.\n * @param {Object} attributeLocations A map of shader attribute names to their locations.\n */\n sendAttributeData: function (gl, attributeLocations, aPositionData) {\n var attributeLocation = attributeLocations.aPosition;\n var buffer = gl.createBuffer();\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer);\n gl.enableVertexAttribArray(attributeLocation);\n gl.vertexAttribPointer(attributeLocation, 2, gl.FLOAT, false, 0, 0);\n gl.bufferData(gl.ARRAY_BUFFER, aPositionData, gl.STATIC_DRAW);\n },\n _setupFrameBuffer: function (options) {\n var gl = options.context,\n width,\n height;\n\n if (options.passes > 1) {\n width = options.destinationWidth;\n height = options.destinationHeight;\n\n if (options.sourceWidth !== width || options.sourceHeight !== height) {\n gl.deleteTexture(options.targetTexture);\n options.targetTexture = options.filterBackend.createTexture(gl, width, height);\n }\n\n gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, options.targetTexture, 0);\n } else {\n // draw last filter on canvas and not to framebuffer.\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n gl.finish();\n }\n },\n _swapTextures: function (options) {\n options.passes--;\n options.pass++;\n var temp = options.targetTexture;\n options.targetTexture = options.sourceTexture;\n options.sourceTexture = temp;\n },\n\n /**\n * Generic isNeutral implementation for one parameter based filters.\n * Used only in image applyFilters to discard filters that will not have an effect\n * on the image\n * Other filters may need their own verison ( ColorMatrix, HueRotation, gamma, ComposedFilter )\n * @param {Object} options\n **/\n isNeutralState: function ()\n /* options */\n {\n var main = this.mainParameter,\n _class = fabric.Image.filters[this.type].prototype;\n\n if (main) {\n if (Array.isArray(_class[main])) {\n for (var i = _class[main].length; i--;) {\n if (this[main][i] !== _class[main][i]) {\n return false;\n }\n }\n\n return true;\n } else {\n return _class[main] === this[main];\n }\n } else {\n return false;\n }\n },\n\n /**\n * Apply this filter to the input image data provided.\n *\n * Determines whether to use WebGL or Canvas2D based on the options.webgl flag.\n *\n * @param {Object} options\n * @param {Number} options.passes The number of filters remaining to be executed\n * @param {Boolean} options.webgl Whether to use webgl to render the filter.\n * @param {WebGLTexture} options.sourceTexture The texture setup as the source to be filtered.\n * @param {WebGLTexture} options.targetTexture The texture where filtered output should be drawn.\n * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n */\n applyTo: function (options) {\n if (options.webgl) {\n this._setupFrameBuffer(options);\n\n this.applyToWebGL(options);\n\n this._swapTextures(options);\n } else {\n this.applyTo2d(options);\n }\n },\n\n /**\n * Retrieves the cached shader.\n * @param {Object} options\n * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n */\n retrieveShader: function (options) {\n if (!options.programCache.hasOwnProperty(this.type)) {\n options.programCache[this.type] = this.createProgram(options.context);\n }\n\n return options.programCache[this.type];\n },\n\n /**\n * Apply this filter using webgl.\n *\n * @param {Object} options\n * @param {Number} options.passes The number of filters remaining to be executed\n * @param {Boolean} options.webgl Whether to use webgl to render the filter.\n * @param {WebGLTexture} options.originalTexture The texture of the original input image.\n * @param {WebGLTexture} options.sourceTexture The texture setup as the source to be filtered.\n * @param {WebGLTexture} options.targetTexture The texture where filtered output should be drawn.\n * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n */\n applyToWebGL: function (options) {\n var gl = options.context;\n var shader = this.retrieveShader(options);\n\n if (options.pass === 0 && options.originalTexture) {\n gl.bindTexture(gl.TEXTURE_2D, options.originalTexture);\n } else {\n gl.bindTexture(gl.TEXTURE_2D, options.sourceTexture);\n }\n\n gl.useProgram(shader.program);\n this.sendAttributeData(gl, shader.attributeLocations, options.aPosition);\n gl.uniform1f(shader.uniformLocations.uStepW, 1 / options.sourceWidth);\n gl.uniform1f(shader.uniformLocations.uStepH, 1 / options.sourceHeight);\n this.sendUniformData(gl, shader.uniformLocations);\n gl.viewport(0, 0, options.destinationWidth, options.destinationHeight);\n gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);\n },\n bindAdditionalTexture: function (gl, texture, textureUnit) {\n gl.activeTexture(textureUnit);\n gl.bindTexture(gl.TEXTURE_2D, texture); // reset active texture to 0 as usual\n\n gl.activeTexture(gl.TEXTURE0);\n },\n unbindAdditionalTexture: function (gl, textureUnit) {\n gl.activeTexture(textureUnit);\n gl.bindTexture(gl.TEXTURE_2D, null);\n gl.activeTexture(gl.TEXTURE0);\n },\n getMainParameter: function () {\n return this[this.mainParameter];\n },\n setMainParameter: function (value) {\n this[this.mainParameter] = value;\n },\n\n /**\n * Send uniform data from this filter to its shader program on the GPU.\n *\n * Intended to be overridden by subclasses.\n *\n * @param {WebGLRenderingContext} gl The canvas context used to compile the shader program.\n * @param {Object} uniformLocations A map of shader uniform names to their locations.\n */\n sendUniformData: function ()\n /* gl, uniformLocations */\n {// Intentionally left blank. Override me in subclasses.\n },\n\n /**\n * If needed by a 2d filter, this functions can create an helper canvas to be used\n * remember that options.targetCanvas is available for use till end of chain.\n */\n createHelpLayer: function (options) {\n if (!options.helpLayer) {\n var helpLayer = document.createElement('canvas');\n helpLayer.width = options.sourceWidth;\n helpLayer.height = options.sourceHeight;\n options.helpLayer = helpLayer;\n }\n },\n\n /**\n * Returns object representation of an instance\n * @return {Object} Object representation of an instance\n */\n toObject: function () {\n var object = {\n type: this.type\n },\n mainP = this.mainParameter;\n\n if (mainP) {\n object[mainP] = this[mainP];\n }\n\n return object;\n },\n\n /**\n * Returns a JSON representation of an instance\n * @return {Object} JSON\n */\n toJSON: function () {\n // delegate, not alias\n return this.toObject();\n }\n});\n\nfabric.Image.filters.BaseFilter.fromObject = function (object, callback) {\n var filter = new fabric.Image.filters[object.type](object);\n callback && callback(filter);\n return filter;\n};\n\n(function (global) {\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = {}),\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n /**\n * Color Matrix filter class\n * @class fabric.Image.filters.ColorMatrix\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link fabric.Image.filters.ColorMatrix#initialize} for constructor definition\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @see {@Link http://www.webwasp.co.uk/tutorials/219/Color_Matrix_Filter.php}\n * @see {@Link http://phoboslab.org/log/2013/11/fast-image-filters-with-webgl}\n * @example <caption>Kodachrome filter</caption>\n * var filter = new fabric.Image.filters.ColorMatrix({\n * matrix: [\n 1.1285582396593525, -0.3967382283601348, -0.03992559172921793, 0, 63.72958762196502,\n -0.16404339962244616, 1.0835251566291304, -0.05498805115633132, 0, 24.732407896706203,\n -0.16786010706155763, -0.5603416277695248, 1.6014850761964943, 0, 35.62982807460946,\n 0, 0, 0, 1, 0\n ]\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n */\n\n filters.ColorMatrix = createClass(filters.BaseFilter,\n /** @lends fabric.Image.filters.ColorMatrix.prototype */\n {\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'ColorMatrix',\n fragmentSource: 'precision highp float;\\n' + 'uniform sampler2D uTexture;\\n' + 'varying vec2 vTexCoord;\\n' + 'uniform mat4 uColorMatrix;\\n' + 'uniform vec4 uConstants;\\n' + 'void main() {\\n' + 'vec4 color = texture2D(uTexture, vTexCoord);\\n' + 'color *= uColorMatrix;\\n' + 'color += uConstants;\\n' + 'gl_FragColor = color;\\n' + '}',\n\n /**\n * Colormatrix for pixels.\n * array of 20 floats. Numbers in positions 4, 9, 14, 19 loose meaning\n * outside the -1, 1 range.\n * 0.0039215686 is the part of 1 that get translated to 1 in 2d\n * @param {Array} matrix array of 20 numbers.\n * @default\n */\n matrix: [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0],\n mainParameter: 'matrix',\n\n /**\n * Lock the colormatrix on the color part, skipping alpha, manly for non webgl scenario\n * to save some calculation\n */\n colorsOnly: true,\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n */\n initialize: function (options) {\n this.callSuper('initialize', options); // create a new array instead mutating the prototype with push\n\n this.matrix = this.matrix.slice(0);\n },\n\n /**\n * Apply the ColorMatrix operation to a Uint8Array representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8Array to be filtered.\n */\n applyTo2d: function (options) {\n var imageData = options.imageData,\n data = imageData.data,\n iLen = data.length,\n m = this.matrix,\n r,\n g,\n b,\n a,\n i,\n colorsOnly = this.colorsOnly;\n\n for (i = 0; i < iLen; i += 4) {\n r = data[i];\n g = data[i + 1];\n b = data[i + 2];\n\n if (colorsOnly) {\n data[i] = r * m[0] + g * m[1] + b * m[2] + m[4] * 255;\n data[i + 1] = r * m[5] + g * m[6] + b * m[7] + m[9] * 255;\n data[i + 2] = r * m[10] + g * m[11] + b * m[12] + m[14] * 255;\n } else {\n a = data[i + 3];\n data[i] = r * m[0] + g * m[1] + b * m[2] + a * m[3] + m[4] * 255;\n data[i + 1] = r * m[5] + g * m[6] + b * m[7] + a * m[8] + m[9] * 255;\n data[i + 2] = r * m[10] + g * m[11] + b * m[12] + a * m[13] + m[14] * 255;\n data[i + 3] = r * m[15] + g * m[16] + b * m[17] + a * m[18] + m[19] * 255;\n }\n }\n },\n\n /**\n * Return WebGL uniform locations for this filter's shader.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {WebGLShaderProgram} program This filter's compiled shader program.\n */\n getUniformLocations: function (gl, program) {\n return {\n uColorMatrix: gl.getUniformLocation(program, 'uColorMatrix'),\n uConstants: gl.getUniformLocation(program, 'uConstants')\n };\n },\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData: function (gl, uniformLocations) {\n var m = this.matrix,\n matrix = [m[0], m[1], m[2], m[3], m[5], m[6], m[7], m[8], m[10], m[11], m[12], m[13], m[15], m[16], m[17], m[18]],\n constants = [m[4], m[9], m[14], m[19]];\n gl.uniformMatrix4fv(uniformLocations.uColorMatrix, false, matrix);\n gl.uniform4fv(uniformLocations.uConstants, constants);\n }\n });\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] function to invoke after filter creation\n * @return {fabric.Image.filters.ColorMatrix} Instance of fabric.Image.filters.ColorMatrix\n */\n\n fabric.Image.filters.ColorMatrix.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n})(typeof exports !== 'undefined' ? exports : this);\n\n(function (global) {\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = {}),\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n /**\n * Brightness filter class\n * @class fabric.Image.filters.Brightness\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link fabric.Image.filters.Brightness#initialize} for constructor definition\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example\n * var filter = new fabric.Image.filters.Brightness({\n * brightness: 0.05\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n */\n\n filters.Brightness = createClass(filters.BaseFilter,\n /** @lends fabric.Image.filters.Brightness.prototype */\n {\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'Brightness',\n\n /**\n * Fragment source for the brightness program\n */\n fragmentSource: 'precision highp float;\\n' + 'uniform sampler2D uTexture;\\n' + 'uniform float uBrightness;\\n' + 'varying vec2 vTexCoord;\\n' + 'void main() {\\n' + 'vec4 color = texture2D(uTexture, vTexCoord);\\n' + 'color.rgb += uBrightness;\\n' + 'gl_FragColor = color;\\n' + '}',\n\n /**\n * Brightness value, from -1 to 1.\n * translated to -255 to 255 for 2d\n * 0.0039215686 is the part of 1 that get translated to 1 in 2d\n * @param {Number} brightness\n * @default\n */\n brightness: 0,\n\n /**\n * Describe the property that is the filter parameter\n * @param {String} m\n * @default\n */\n mainParameter: 'brightness',\n\n /**\n * Apply the Brightness operation to a Uint8ClampedArray representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n */\n applyTo2d: function (options) {\n if (this.brightness === 0) {\n return;\n }\n\n var imageData = options.imageData,\n data = imageData.data,\n i,\n len = data.length,\n brightness = Math.round(this.brightness * 255);\n\n for (i = 0; i < len; i += 4) {\n data[i] = data[i] + brightness;\n data[i + 1] = data[i + 1] + brightness;\n data[i + 2] = data[i + 2] + brightness;\n }\n },\n\n /**\n * Return WebGL uniform locations for this filter's shader.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {WebGLShaderProgram} program This filter's compiled shader program.\n */\n getUniformLocations: function (gl, program) {\n return {\n uBrightness: gl.getUniformLocation(program, 'uBrightness')\n };\n },\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData: function (gl, uniformLocations) {\n gl.uniform1f(uniformLocations.uBrightness, this.brightness);\n }\n });\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.Brightness} Instance of fabric.Image.filters.Brightness\n */\n\n fabric.Image.filters.Brightness.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n})(typeof exports !== 'undefined' ? exports : this);\n\n(function (global) {\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = {}),\n extend = fabric.util.object.extend,\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n /**\n * Adapted from <a href=\"http://www.html5rocks.com/en/tutorials/canvas/imagefilters/\">html5rocks article</a>\n * @class fabric.Image.filters.Convolute\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link fabric.Image.filters.Convolute#initialize} for constructor definition\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example <caption>Sharpen filter</caption>\n * var filter = new fabric.Image.filters.Convolute({\n * matrix: [ 0, -1, 0,\n * -1, 5, -1,\n * 0, -1, 0 ]\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n * canvas.renderAll();\n * @example <caption>Blur filter</caption>\n * var filter = new fabric.Image.filters.Convolute({\n * matrix: [ 1/9, 1/9, 1/9,\n * 1/9, 1/9, 1/9,\n * 1/9, 1/9, 1/9 ]\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n * canvas.renderAll();\n * @example <caption>Emboss filter</caption>\n * var filter = new fabric.Image.filters.Convolute({\n * matrix: [ 1, 1, 1,\n * 1, 0.7, -1,\n * -1, -1, -1 ]\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n * canvas.renderAll();\n * @example <caption>Emboss filter with opaqueness</caption>\n * var filter = new fabric.Image.filters.Convolute({\n * opaque: true,\n * matrix: [ 1, 1, 1,\n * 1, 0.7, -1,\n * -1, -1, -1 ]\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n * canvas.renderAll();\n */\n\n filters.Convolute = createClass(filters.BaseFilter,\n /** @lends fabric.Image.filters.Convolute.prototype */\n {\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'Convolute',\n\n /*\n * Opaque value (true/false)\n */\n opaque: false,\n\n /*\n * matrix for the filter, max 9x9\n */\n matrix: [0, 0, 0, 0, 1, 0, 0, 0, 0],\n\n /**\n * Fragment source for the brightness program\n */\n fragmentSource: {\n Convolute_3_1: 'precision highp float;\\n' + 'uniform sampler2D uTexture;\\n' + 'uniform float uMatrix[9];\\n' + 'uniform float uStepW;\\n' + 'uniform float uStepH;\\n' + 'varying vec2 vTexCoord;\\n' + 'void main() {\\n' + 'vec4 color = vec4(0, 0, 0, 0);\\n' + 'for (float h = 0.0; h < 3.0; h+=1.0) {\\n' + 'for (float w = 0.0; w < 3.0; w+=1.0) {\\n' + 'vec2 matrixPos = vec2(uStepW * (w - 1), uStepH * (h - 1));\\n' + 'color += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 3.0 + w)];\\n' + '}\\n' + '}\\n' + 'gl_FragColor = color;\\n' + '}',\n Convolute_3_0: 'precision highp float;\\n' + 'uniform sampler2D uTexture;\\n' + 'uniform float uMatrix[9];\\n' + 'uniform float uStepW;\\n' + 'uniform float uStepH;\\n' + 'varying vec2 vTexCoord;\\n' + 'void main() {\\n' + 'vec4 color = vec4(0, 0, 0, 1);\\n' + 'for (float h = 0.0; h < 3.0; h+=1.0) {\\n' + 'for (float w = 0.0; w < 3.0; w+=1.0) {\\n' + 'vec2 matrixPos = vec2(uStepW * (w - 1.0), uStepH * (h - 1.0));\\n' + 'color.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 3.0 + w)];\\n' + '}\\n' + '}\\n' + 'float alpha = texture2D(uTexture, vTexCoord).a;\\n' + 'gl_FragColor = color;\\n' + 'gl_FragColor.a = alpha;\\n' + '}',\n Convolute_5_1: 'precision highp float;\\n' + 'uniform sampler2D uTexture;\\n' + 'uniform float uMatrix[25];\\n' + 'uniform float uStepW;\\n' + 'uniform float uStepH;\\n' + 'varying vec2 vTexCoord;\\n' + 'void main() {\\n' + 'vec4 color = vec4(0, 0, 0, 0);\\n' + 'for (float h = 0.0; h < 5.0; h+=1.0) {\\n' + 'for (float w = 0.0; w < 5.0; w+=1.0) {\\n' + 'vec2 matrixPos = vec2(uStepW * (w - 2.0), uStepH * (h - 2.0));\\n' + 'color += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 5.0 + w)];\\n' + '}\\n' + '}\\n' + 'gl_FragColor = color;\\n' + '}',\n Convolute_5_0: 'precision highp float;\\n' + 'uniform sampler2D uTexture;\\n' + 'uniform float uMatrix[25];\\n' + 'uniform float uStepW;\\n' + 'uniform float uStepH;\\n' + 'varying vec2 vTexCoord;\\n' + 'void main() {\\n' + 'vec4 color = vec4(0, 0, 0, 1);\\n' + 'for (float h = 0.0; h < 5.0; h+=1.0) {\\n' + 'for (float w = 0.0; w < 5.0; w+=1.0) {\\n' + 'vec2 matrixPos = vec2(uStepW * (w - 2.0), uStepH * (h - 2.0));\\n' + 'color.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 5.0 + w)];\\n' + '}\\n' + '}\\n' + 'float alpha = texture2D(uTexture, vTexCoord).a;\\n' + 'gl_FragColor = color;\\n' + 'gl_FragColor.a = alpha;\\n' + '}',\n Convolute_7_1: 'precision highp float;\\n' + 'uniform sampler2D uTexture;\\n' + 'uniform float uMatrix[49];\\n' + 'uniform float uStepW;\\n' + 'uniform float uStepH;\\n' + 'varying vec2 vTexCoord;\\n' + 'void main() {\\n' + 'vec4 color = vec4(0, 0, 0, 0);\\n' + 'for (float h = 0.0; h < 7.0; h+=1.0) {\\n' + 'for (float w = 0.0; w < 7.0; w+=1.0) {\\n' + 'vec2 matrixPos = vec2(uStepW * (w - 3.0), uStepH * (h - 3.0));\\n' + 'color += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 7.0 + w)];\\n' + '}\\n' + '}\\n' + 'gl_FragColor = color;\\n' + '}',\n Convolute_7_0: 'precision highp float;\\n' + 'uniform sampler2D uTexture;\\n' + 'uniform float uMatrix[49];\\n' + 'uniform float uStepW;\\n' + 'uniform float uStepH;\\n' + 'varying vec2 vTexCoord;\\n' + 'void main() {\\n' + 'vec4 color = vec4(0, 0, 0, 1);\\n' + 'for (float h = 0.0; h < 7.0; h+=1.0) {\\n' + 'for (float w = 0.0; w < 7.0; w+=1.0) {\\n' + 'vec2 matrixPos = vec2(uStepW * (w - 3.0), uStepH * (h - 3.0));\\n' + 'color.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 7.0 + w)];\\n' + '}\\n' + '}\\n' + 'float alpha = texture2D(uTexture, vTexCoord).a;\\n' + 'gl_FragColor = color;\\n' + 'gl_FragColor.a = alpha;\\n' + '}',\n Convolute_9_1: 'precision highp float;\\n' + 'uniform sampler2D uTexture;\\n' + 'uniform float uMatrix[81];\\n' + 'uniform float uStepW;\\n' + 'uniform float uStepH;\\n' + 'varying vec2 vTexCoord;\\n' + 'void main() {\\n' + 'vec4 color = vec4(0, 0, 0, 0);\\n' + 'for (float h = 0.0; h < 9.0; h+=1.0) {\\n' + 'for (float w = 0.0; w < 9.0; w+=1.0) {\\n' + 'vec2 matrixPos = vec2(uStepW * (w - 4.0), uStepH * (h - 4.0));\\n' + 'color += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 9.0 + w)];\\n' + '}\\n' + '}\\n' + 'gl_FragColor = color;\\n' + '}',\n Convolute_9_0: 'precision highp float;\\n' + 'uniform sampler2D uTexture;\\n' + 'uniform float uMatrix[81];\\n' + 'uniform float uStepW;\\n' + 'uniform float uStepH;\\n' + 'varying vec2 vTexCoord;\\n' + 'void main() {\\n' + 'vec4 color = vec4(0, 0, 0, 1);\\n' + 'for (float h = 0.0; h < 9.0; h+=1.0) {\\n' + 'for (float w = 0.0; w < 9.0; w+=1.0) {\\n' + 'vec2 matrixPos = vec2(uStepW * (w - 4.0), uStepH * (h - 4.0));\\n' + 'color.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 9.0 + w)];\\n' + '}\\n' + '}\\n' + 'float alpha = texture2D(uTexture, vTexCoord).a;\\n' + 'gl_FragColor = color;\\n' + 'gl_FragColor.a = alpha;\\n' + '}'\n },\n\n /**\n * Constructor\n * @memberOf fabric.Image.filters.Convolute.prototype\n * @param {Object} [options] Options object\n * @param {Boolean} [options.opaque=false] Opaque value (true/false)\n * @param {Array} [options.matrix] Filter matrix\n */\n\n /**\n * Retrieves the cached shader.\n * @param {Object} options\n * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n */\n retrieveShader: function (options) {\n var size = Math.sqrt(this.matrix.length);\n var cacheKey = this.type + '_' + size + '_' + (this.opaque ? 1 : 0);\n var shaderSource = this.fragmentSource[cacheKey];\n\n if (!options.programCache.hasOwnProperty(cacheKey)) {\n options.programCache[cacheKey] = this.createProgram(options.context, shaderSource);\n }\n\n return options.programCache[cacheKey];\n },\n\n /**\n * Apply the Brightness operation to a Uint8ClampedArray representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n */\n applyTo2d: function (options) {\n var imageData = options.imageData,\n data = imageData.data,\n weights = this.matrix,\n side = Math.round(Math.sqrt(weights.length)),\n halfSide = Math.floor(side / 2),\n sw = imageData.width,\n sh = imageData.height,\n output = options.ctx.createImageData(sw, sh),\n dst = output.data,\n // go through the destination image pixels\n alphaFac = this.opaque ? 1 : 0,\n r,\n g,\n b,\n a,\n dstOff,\n scx,\n scy,\n srcOff,\n wt,\n x,\n y,\n cx,\n cy;\n\n for (y = 0; y < sh; y++) {\n for (x = 0; x < sw; x++) {\n dstOff = (y * sw + x) * 4; // calculate the weighed sum of the source image pixels that\n // fall under the convolution matrix\n\n r = 0;\n g = 0;\n b = 0;\n a = 0;\n\n for (cy = 0; cy < side; cy++) {\n for (cx = 0; cx < side; cx++) {\n scy = y + cy - halfSide;\n scx = x + cx - halfSide; // eslint-disable-next-line max-depth\n\n if (scy < 0 || scy >= sh || scx < 0 || scx >= sw) {\n continue;\n }\n\n srcOff = (scy * sw + scx) * 4;\n wt = weights[cy * side + cx];\n r += data[srcOff] * wt;\n g += data[srcOff + 1] * wt;\n b += data[srcOff + 2] * wt; // eslint-disable-next-line max-depth\n\n if (!alphaFac) {\n a += data[srcOff + 3] * wt;\n }\n }\n }\n\n dst[dstOff] = r;\n dst[dstOff + 1] = g;\n dst[dstOff + 2] = b;\n\n if (!alphaFac) {\n dst[dstOff + 3] = a;\n } else {\n dst[dstOff + 3] = data[dstOff + 3];\n }\n }\n }\n\n options.imageData = output;\n },\n\n /**\n * Return WebGL uniform locations for this filter's shader.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {WebGLShaderProgram} program This filter's compiled shader program.\n */\n getUniformLocations: function (gl, program) {\n return {\n uMatrix: gl.getUniformLocation(program, 'uMatrix'),\n uOpaque: gl.getUniformLocation(program, 'uOpaque'),\n uHalfSize: gl.getUniformLocation(program, 'uHalfSize'),\n uSize: gl.getUniformLocation(program, 'uSize')\n };\n },\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData: function (gl, uniformLocations) {\n gl.uniform1fv(uniformLocations.uMatrix, this.matrix);\n },\n\n /**\n * Returns object representation of an instance\n * @return {Object} Object representation of an instance\n */\n toObject: function () {\n return extend(this.callSuper('toObject'), {\n opaque: this.opaque,\n matrix: this.matrix\n });\n }\n });\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.Convolute} Instance of fabric.Image.filters.Convolute\n */\n\n fabric.Image.filters.Convolute.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n})(typeof exports !== 'undefined' ? exports : this);\n\n(function (global) {\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = {}),\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n /**\n * Grayscale image filter class\n * @class fabric.Image.filters.Grayscale\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example\n * var filter = new fabric.Image.filters.Grayscale();\n * object.filters.push(filter);\n * object.applyFilters();\n */\n\n filters.Grayscale = createClass(filters.BaseFilter,\n /** @lends fabric.Image.filters.Grayscale.prototype */\n {\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'Grayscale',\n fragmentSource: {\n average: 'precision highp float;\\n' + 'uniform sampler2D uTexture;\\n' + 'varying vec2 vTexCoord;\\n' + 'void main() {\\n' + 'vec4 color = texture2D(uTexture, vTexCoord);\\n' + 'float average = (color.r + color.b + color.g) / 3.0;\\n' + 'gl_FragColor = vec4(average, average, average, color.a);\\n' + '}',\n lightness: 'precision highp float;\\n' + 'uniform sampler2D uTexture;\\n' + 'uniform int uMode;\\n' + 'varying vec2 vTexCoord;\\n' + 'void main() {\\n' + 'vec4 col = texture2D(uTexture, vTexCoord);\\n' + 'float average = (max(max(col.r, col.g),col.b) + min(min(col.r, col.g),col.b)) / 2.0;\\n' + 'gl_FragColor = vec4(average, average, average, col.a);\\n' + '}',\n luminosity: 'precision highp float;\\n' + 'uniform sampler2D uTexture;\\n' + 'uniform int uMode;\\n' + 'varying vec2 vTexCoord;\\n' + 'void main() {\\n' + 'vec4 col = texture2D(uTexture, vTexCoord);\\n' + 'float average = 0.21 * col.r + 0.72 * col.g + 0.07 * col.b;\\n' + 'gl_FragColor = vec4(average, average, average, col.a);\\n' + '}'\n },\n\n /**\n * Grayscale mode, between 'average', 'lightness', 'luminosity'\n * @param {String} type\n * @default\n */\n mode: 'average',\n mainParameter: 'mode',\n\n /**\n * Apply the Grayscale operation to a Uint8Array representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8Array to be filtered.\n */\n applyTo2d: function (options) {\n var imageData = options.imageData,\n data = imageData.data,\n i,\n len = data.length,\n value,\n mode = this.mode;\n\n for (i = 0; i < len; i += 4) {\n if (mode === 'average') {\n value = (data[i] + data[i + 1] + data[i + 2]) / 3;\n } else if (mode === 'lightness') {\n value = (Math.min(data[i], data[i + 1], data[i + 2]) + Math.max(data[i], data[i + 1], data[i + 2])) / 2;\n } else if (mode === 'luminosity') {\n value = 0.21 * data[i] + 0.72 * data[i + 1] + 0.07 * data[i + 2];\n }\n\n data[i] = value;\n data[i + 1] = value;\n data[i + 2] = value;\n }\n },\n\n /**\n * Retrieves the cached shader.\n * @param {Object} options\n * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n */\n retrieveShader: function (options) {\n var cacheKey = this.type + '_' + this.mode;\n\n if (!options.programCache.hasOwnProperty(cacheKey)) {\n var shaderSource = this.fragmentSource[this.mode];\n options.programCache[cacheKey] = this.createProgram(options.context, shaderSource);\n }\n\n return options.programCache[cacheKey];\n },\n\n /**\n * Return WebGL uniform locations for this filter's shader.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {WebGLShaderProgram} program This filter's compiled shader program.\n */\n getUniformLocations: function (gl, program) {\n return {\n uMode: gl.getUniformLocation(program, 'uMode')\n };\n },\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData: function (gl, uniformLocations) {\n // default average mode.\n var mode = 1;\n gl.uniform1i(uniformLocations.uMode, mode);\n },\n\n /**\n * Grayscale filter isNeutralState implementation\n * The filter is never neutral\n * on the image\n **/\n isNeutralState: function () {\n return false;\n }\n });\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.Grayscale} Instance of fabric.Image.filters.Grayscale\n */\n\n fabric.Image.filters.Grayscale.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n})(typeof exports !== 'undefined' ? exports : this);\n\n(function (global) {\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = {}),\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n /**\n * Invert filter class\n * @class fabric.Image.filters.Invert\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example\n * var filter = new fabric.Image.filters.Invert();\n * object.filters.push(filter);\n * object.applyFilters(canvas.renderAll.bind(canvas));\n */\n\n filters.Invert = createClass(filters.BaseFilter,\n /** @lends fabric.Image.filters.Invert.prototype */\n {\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'Invert',\n fragmentSource: 'precision highp float;\\n' + 'uniform sampler2D uTexture;\\n' + 'uniform int uInvert;\\n' + 'varying vec2 vTexCoord;\\n' + 'void main() {\\n' + 'vec4 color = texture2D(uTexture, vTexCoord);\\n' + 'if (uInvert == 1) {\\n' + 'gl_FragColor = vec4(1.0 - color.r,1.0 -color.g,1.0 -color.b,color.a);\\n' + '} else {\\n' + 'gl_FragColor = color;\\n' + '}\\n' + '}',\n\n /**\n * Filter invert. if false, does nothing\n * @param {Boolean} invert\n * @default\n */\n invert: true,\n mainParameter: 'invert',\n\n /**\n * Apply the Invert operation to a Uint8Array representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8Array to be filtered.\n */\n applyTo2d: function (options) {\n var imageData = options.imageData,\n data = imageData.data,\n i,\n len = data.length;\n\n for (i = 0; i < len; i += 4) {\n data[i] = 255 - data[i];\n data[i + 1] = 255 - data[i + 1];\n data[i + 2] = 255 - data[i + 2];\n }\n },\n\n /**\n * Invert filter isNeutralState implementation\n * Used only in image applyFilters to discard filters that will not have an effect\n * on the image\n * @param {Object} options\n **/\n isNeutralState: function () {\n return !this.invert;\n },\n\n /**\n * Return WebGL uniform locations for this filter's shader.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {WebGLShaderProgram} program This filter's compiled shader program.\n */\n getUniformLocations: function (gl, program) {\n return {\n uInvert: gl.getUniformLocation(program, 'uInvert')\n };\n },\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData: function (gl, uniformLocations) {\n gl.uniform1i(uniformLocations.uInvert, this.invert);\n }\n });\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.Invert} Instance of fabric.Image.filters.Invert\n */\n\n fabric.Image.filters.Invert.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n})(typeof exports !== 'undefined' ? exports : this);\n\n(function (global) {\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = {}),\n extend = fabric.util.object.extend,\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n /**\n * Noise filter class\n * @class fabric.Image.filters.Noise\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link fabric.Image.filters.Noise#initialize} for constructor definition\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example\n * var filter = new fabric.Image.filters.Noise({\n * noise: 700\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n * canvas.renderAll();\n */\n\n filters.Noise = createClass(filters.BaseFilter,\n /** @lends fabric.Image.filters.Noise.prototype */\n {\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'Noise',\n\n /**\n * Fragment source for the noise program\n */\n fragmentSource: 'precision highp float;\\n' + 'uniform sampler2D uTexture;\\n' + 'uniform float uStepH;\\n' + 'uniform float uNoise;\\n' + 'uniform float uSeed;\\n' + 'varying vec2 vTexCoord;\\n' + 'float rand(vec2 co, float seed, float vScale) {\\n' + 'return fract(sin(dot(co.xy * vScale ,vec2(12.9898 , 78.233))) * 43758.5453 * (seed + 0.01) / 2.0);\\n' + '}\\n' + 'void main() {\\n' + 'vec4 color = texture2D(uTexture, vTexCoord);\\n' + 'color.rgb += (0.5 - rand(vTexCoord, uSeed, 0.1 / uStepH)) * uNoise;\\n' + 'gl_FragColor = color;\\n' + '}',\n\n /**\n * Describe the property that is the filter parameter\n * @param {String} m\n * @default\n */\n mainParameter: 'noise',\n\n /**\n * Noise value, from\n * @param {Number} noise\n * @default\n */\n noise: 0,\n\n /**\n * Apply the Brightness operation to a Uint8ClampedArray representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n */\n applyTo2d: function (options) {\n if (this.noise === 0) {\n return;\n }\n\n var imageData = options.imageData,\n data = imageData.data,\n i,\n len = data.length,\n noise = this.noise,\n rand;\n\n for (i = 0, len = data.length; i < len; i += 4) {\n rand = (0.5 - Math.random()) * noise;\n data[i] += rand;\n data[i + 1] += rand;\n data[i + 2] += rand;\n }\n },\n\n /**\n * Return WebGL uniform locations for this filter's shader.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {WebGLShaderProgram} program This filter's compiled shader program.\n */\n getUniformLocations: function (gl, program) {\n return {\n uNoise: gl.getUniformLocation(program, 'uNoise'),\n uSeed: gl.getUniformLocation(program, 'uSeed')\n };\n },\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData: function (gl, uniformLocations) {\n gl.uniform1f(uniformLocations.uNoise, this.noise / 255);\n gl.uniform1f(uniformLocations.uSeed, Math.random());\n },\n\n /**\n * Returns object representation of an instance\n * @return {Object} Object representation of an instance\n */\n toObject: function () {\n return extend(this.callSuper('toObject'), {\n noise: this.noise\n });\n }\n });\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {Function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.Noise} Instance of fabric.Image.filters.Noise\n */\n\n fabric.Image.filters.Noise.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n})(typeof exports !== 'undefined' ? exports : this);\n\n(function (global) {\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = {}),\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n /**\n * Pixelate filter class\n * @class fabric.Image.filters.Pixelate\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link fabric.Image.filters.Pixelate#initialize} for constructor definition\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example\n * var filter = new fabric.Image.filters.Pixelate({\n * blocksize: 8\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n */\n\n filters.Pixelate = createClass(filters.BaseFilter,\n /** @lends fabric.Image.filters.Pixelate.prototype */\n {\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'Pixelate',\n blocksize: 4,\n mainParameter: 'blocksize',\n\n /**\n * Fragment source for the Pixelate program\n */\n fragmentSource: 'precision highp float;\\n' + 'uniform sampler2D uTexture;\\n' + 'uniform float uBlocksize;\\n' + 'uniform float uStepW;\\n' + 'uniform float uStepH;\\n' + 'varying vec2 vTexCoord;\\n' + 'void main() {\\n' + 'float blockW = uBlocksize * uStepW;\\n' + 'float blockH = uBlocksize * uStepW;\\n' + 'int posX = int(vTexCoord.x / blockW);\\n' + 'int posY = int(vTexCoord.y / blockH);\\n' + 'float fposX = float(posX);\\n' + 'float fposY = float(posY);\\n' + 'vec2 squareCoords = vec2(fposX * blockW, fposY * blockH);\\n' + 'vec4 color = texture2D(uTexture, squareCoords);\\n' + 'gl_FragColor = color;\\n' + '}',\n\n /**\n * Apply the Pixelate operation to a Uint8ClampedArray representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n */\n applyTo2d: function (options) {\n var imageData = options.imageData,\n data = imageData.data,\n iLen = imageData.height,\n jLen = imageData.width,\n index,\n i,\n j,\n r,\n g,\n b,\n a,\n _i,\n _j,\n _iLen,\n _jLen;\n\n for (i = 0; i < iLen; i += this.blocksize) {\n for (j = 0; j < jLen; j += this.blocksize) {\n index = i * 4 * jLen + j * 4;\n r = data[index];\n g = data[index + 1];\n b = data[index + 2];\n a = data[index + 3];\n _iLen = Math.min(i + this.blocksize, iLen);\n _jLen = Math.min(j + this.blocksize, jLen);\n\n for (_i = i; _i < _iLen; _i++) {\n for (_j = j; _j < _jLen; _j++) {\n index = _i * 4 * jLen + _j * 4;\n data[index] = r;\n data[index + 1] = g;\n data[index + 2] = b;\n data[index + 3] = a;\n }\n }\n }\n }\n },\n\n /**\n * Indicate when the filter is not gonna apply changes to the image\n **/\n isNeutralState: function () {\n return this.blocksize === 1;\n },\n\n /**\n * Return WebGL uniform locations for this filter's shader.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {WebGLShaderProgram} program This filter's compiled shader program.\n */\n getUniformLocations: function (gl, program) {\n return {\n uBlocksize: gl.getUniformLocation(program, 'uBlocksize'),\n uStepW: gl.getUniformLocation(program, 'uStepW'),\n uStepH: gl.getUniformLocation(program, 'uStepH')\n };\n },\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData: function (gl, uniformLocations) {\n gl.uniform1f(uniformLocations.uBlocksize, this.blocksize);\n }\n });\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {Function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.Pixelate} Instance of fabric.Image.filters.Pixelate\n */\n\n fabric.Image.filters.Pixelate.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n})(typeof exports !== 'undefined' ? exports : this);\n\n(function (global) {\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = {}),\n extend = fabric.util.object.extend,\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n /**\n * Remove white filter class\n * @class fabric.Image.filters.RemoveColor\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link fabric.Image.filters.RemoveColor#initialize} for constructor definition\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example\n * var filter = new fabric.Image.filters.RemoveColor({\n * threshold: 0.2,\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n * canvas.renderAll();\n */\n\n filters.RemoveColor = createClass(filters.BaseFilter,\n /** @lends fabric.Image.filters.RemoveColor.prototype */\n {\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'RemoveColor',\n\n /**\n * Color to remove, in any format understood by fabric.Color.\n * @param {String} type\n * @default\n */\n color: '#FFFFFF',\n\n /**\n * Fragment source for the brightness program\n */\n fragmentSource: 'precision highp float;\\n' + 'uniform sampler2D uTexture;\\n' + 'uniform vec4 uLow;\\n' + 'uniform vec4 uHigh;\\n' + 'varying vec2 vTexCoord;\\n' + 'void main() {\\n' + 'gl_FragColor = texture2D(uTexture, vTexCoord);\\n' + 'if(all(greaterThan(gl_FragColor.rgb,uLow.rgb)) && all(greaterThan(uHigh.rgb,gl_FragColor.rgb))) {\\n' + 'gl_FragColor.a = 0.0;\\n' + '}\\n' + '}',\n\n /**\n * distance to actual color, as value up or down from each r,g,b\n * between 0 and 1\n **/\n distance: 0.02,\n\n /**\n * For color to remove inside distance, use alpha channel for a smoother deletion\n * NOT IMPLEMENTED YET\n **/\n useAlpha: false,\n\n /**\n * Constructor\n * @memberOf fabric.Image.filters.RemoveWhite.prototype\n * @param {Object} [options] Options object\n * @param {Number} [options.color=#RRGGBB] Threshold value\n * @param {Number} [options.distance=10] Distance value\n */\n\n /**\n * Applies filter to canvas element\n * @param {Object} canvasEl Canvas element to apply filter to\n */\n applyTo2d: function (options) {\n var imageData = options.imageData,\n data = imageData.data,\n i,\n distance = this.distance * 255,\n r,\n g,\n b,\n source = new fabric.Color(this.color).getSource(),\n lowC = [source[0] - distance, source[1] - distance, source[2] - distance],\n highC = [source[0] + distance, source[1] + distance, source[2] + distance];\n\n for (i = 0; i < data.length; i += 4) {\n r = data[i];\n g = data[i + 1];\n b = data[i + 2];\n\n if (r > lowC[0] && g > lowC[1] && b > lowC[2] && r < highC[0] && g < highC[1] && b < highC[2]) {\n data[i + 3] = 0;\n }\n }\n },\n\n /**\n * Return WebGL uniform locations for this filter's shader.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {WebGLShaderProgram} program This filter's compiled shader program.\n */\n getUniformLocations: function (gl, program) {\n return {\n uLow: gl.getUniformLocation(program, 'uLow'),\n uHigh: gl.getUniformLocation(program, 'uHigh')\n };\n },\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData: function (gl, uniformLocations) {\n var source = new fabric.Color(this.color).getSource(),\n distance = parseFloat(this.distance),\n lowC = [0 + source[0] / 255 - distance, 0 + source[1] / 255 - distance, 0 + source[2] / 255 - distance, 1],\n highC = [source[0] / 255 + distance, source[1] / 255 + distance, source[2] / 255 + distance, 1];\n gl.uniform4fv(uniformLocations.uLow, lowC);\n gl.uniform4fv(uniformLocations.uHigh, highC);\n },\n\n /**\n * Returns object representation of an instance\n * @return {Object} Object representation of an instance\n */\n toObject: function () {\n return extend(this.callSuper('toObject'), {\n color: this.color,\n distance: this.distance\n });\n }\n });\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {Function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.RemoveColor} Instance of fabric.Image.filters.RemoveWhite\n */\n\n fabric.Image.filters.RemoveColor.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n})(typeof exports !== 'undefined' ? exports : this);\n\n(function (global) {\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = {}),\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n var matrices = {\n Brownie: [0.59970, 0.34553, -0.27082, 0, 0.186, -0.03770, 0.86095, 0.15059, 0, -0.1449, 0.24113, -0.07441, 0.44972, 0, -0.02965, 0, 0, 0, 1, 0],\n Vintage: [0.62793, 0.32021, -0.03965, 0, 0.03784, 0.02578, 0.64411, 0.03259, 0, 0.02926, 0.04660, -0.08512, 0.52416, 0, 0.02023, 0, 0, 0, 1, 0],\n Kodachrome: [1.12855, -0.39673, -0.03992, 0, 0.24991, -0.16404, 1.08352, -0.05498, 0, 0.09698, -0.16786, -0.56034, 1.60148, 0, 0.13972, 0, 0, 0, 1, 0],\n Technicolor: [1.91252, -0.85453, -0.09155, 0, 0.04624, -0.30878, 1.76589, -0.10601, 0, -0.27589, -0.23110, -0.75018, 1.84759, 0, 0.12137, 0, 0, 0, 1, 0],\n Polaroid: [1.438, -0.062, -0.062, 0, 0, -0.122, 1.378, -0.122, 0, 0, -0.016, -0.016, 1.483, 0, 0, 0, 0, 0, 1, 0],\n Sepia: [0.393, 0.769, 0.189, 0, 0, 0.349, 0.686, 0.168, 0, 0, 0.272, 0.534, 0.131, 0, 0, 0, 0, 0, 1, 0],\n BlackWhite: [1.5, 1.5, 1.5, 0, -1, 1.5, 1.5, 1.5, 0, -1, 1.5, 1.5, 1.5, 0, -1, 0, 0, 0, 1, 0]\n };\n\n for (var key in matrices) {\n filters[key] = createClass(filters.ColorMatrix,\n /** @lends fabric.Image.filters.Sepia.prototype */\n {\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: key,\n\n /**\n * Colormatrix for the effect\n * array of 20 floats. Numbers in positions 4, 9, 14, 19 loose meaning\n * outside the -1, 1 range.\n * @param {Array} matrix array of 20 numbers.\n * @default\n */\n matrix: matrices[key],\n\n /**\n * Lock the matrix export for this kind of static, parameter less filters.\n */\n mainParameter: false,\n\n /**\n * Lock the colormatrix on the color part, skipping alpha\n */\n colorsOnly: true\n });\n fabric.Image.filters[key].fromObject = fabric.Image.filters.BaseFilter.fromObject;\n }\n})(typeof exports !== 'undefined' ? exports : this);\n\n(function (global) {\n 'use strict';\n\n var fabric = global.fabric,\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n /**\n * Color Blend filter class\n * @class fabric.Image.filter.BlendColor\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @example\n * var filter = new fabric.Image.filters.BlendColor({\n * color: '#000',\n * mode: 'multiply'\n * });\n *\n * var filter = new fabric.Image.filters.BlendImage({\n * image: fabricImageObject,\n * mode: 'multiply',\n * alpha: 0.5\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n * canvas.renderAll();\n */\n\n filters.BlendColor = createClass(filters.BaseFilter,\n /** @lends fabric.Image.filters.Blend.prototype */\n {\n type: 'BlendColor',\n\n /**\n * Color to make the blend operation with. default to a reddish color since black or white\n * gives always strong result.\n **/\n color: '#F95C63',\n\n /**\n * Blend mode for the filter: one of multiply, add, diff, screen, subtract,\n * darken, lighten, overlay, exclusion, tint.\n **/\n mode: 'multiply',\n\n /**\n * alpha value. represent the strength of the blend color operation.\n **/\n alpha: 1,\n\n /**\n * Fragment source for the Multiply program\n */\n fragmentSource: {\n multiply: 'gl_FragColor.rgb *= uColor.rgb;\\n',\n screen: 'gl_FragColor.rgb = 1.0 - (1.0 - gl_FragColor.rgb) * (1.0 - uColor.rgb);\\n',\n add: 'gl_FragColor.rgb += uColor.rgb;\\n',\n diff: 'gl_FragColor.rgb = abs(gl_FragColor.rgb - uColor.rgb);\\n',\n subtract: 'gl_FragColor.rgb -= uColor.rgb;\\n',\n lighten: 'gl_FragColor.rgb = max(gl_FragColor.rgb, uColor.rgb);\\n',\n darken: 'gl_FragColor.rgb = min(gl_FragColor.rgb, uColor.rgb);\\n',\n exclusion: 'gl_FragColor.rgb += uColor.rgb - 2.0 * (uColor.rgb * gl_FragColor.rgb);\\n',\n overlay: 'if (uColor.r < 0.5) {\\n' + 'gl_FragColor.r *= 2.0 * uColor.r;\\n' + '} else {\\n' + 'gl_FragColor.r = 1.0 - 2.0 * (1.0 - gl_FragColor.r) * (1.0 - uColor.r);\\n' + '}\\n' + 'if (uColor.g < 0.5) {\\n' + 'gl_FragColor.g *= 2.0 * uColor.g;\\n' + '} else {\\n' + 'gl_FragColor.g = 1.0 - 2.0 * (1.0 - gl_FragColor.g) * (1.0 - uColor.g);\\n' + '}\\n' + 'if (uColor.b < 0.5) {\\n' + 'gl_FragColor.b *= 2.0 * uColor.b;\\n' + '} else {\\n' + 'gl_FragColor.b = 1.0 - 2.0 * (1.0 - gl_FragColor.b) * (1.0 - uColor.b);\\n' + '}\\n',\n tint: 'gl_FragColor.rgb *= (1.0 - uColor.a);\\n' + 'gl_FragColor.rgb += uColor.rgb;\\n'\n },\n\n /**\n * build the fragment source for the filters, joining the common part with\n * the specific one.\n * @param {String} mode the mode of the filter, a key of this.fragmentSource\n * @return {String} the source to be compiled\n * @private\n */\n buildSource: function (mode) {\n return 'precision highp float;\\n' + 'uniform sampler2D uTexture;\\n' + 'uniform vec4 uColor;\\n' + 'varying vec2 vTexCoord;\\n' + 'void main() {\\n' + 'vec4 color = texture2D(uTexture, vTexCoord);\\n' + 'gl_FragColor = color;\\n' + 'if (color.a > 0.0) {\\n' + this.fragmentSource[mode] + '}\\n' + '}';\n },\n\n /**\n * Retrieves the cached shader.\n * @param {Object} options\n * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n */\n retrieveShader: function (options) {\n var cacheKey = this.type + '_' + this.mode,\n shaderSource;\n\n if (!options.programCache.hasOwnProperty(cacheKey)) {\n shaderSource = this.buildSource(this.mode);\n options.programCache[cacheKey] = this.createProgram(options.context, shaderSource);\n }\n\n return options.programCache[cacheKey];\n },\n\n /**\n * Apply the Blend operation to a Uint8ClampedArray representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n */\n applyTo2d: function (options) {\n var imageData = options.imageData,\n data = imageData.data,\n iLen = data.length,\n tr,\n tg,\n tb,\n r,\n g,\n b,\n source,\n alpha1 = 1 - this.alpha;\n source = new fabric.Color(this.color).getSource();\n tr = source[0] * this.alpha;\n tg = source[1] * this.alpha;\n tb = source[2] * this.alpha;\n\n for (var i = 0; i < iLen; i += 4) {\n r = data[i];\n g = data[i + 1];\n b = data[i + 2];\n\n switch (this.mode) {\n case 'multiply':\n data[i] = r * tr / 255;\n data[i + 1] = g * tg / 255;\n data[i + 2] = b * tb / 255;\n break;\n\n case 'screen':\n data[i] = 255 - (255 - r) * (255 - tr) / 255;\n data[i + 1] = 255 - (255 - g) * (255 - tg) / 255;\n data[i + 2] = 255 - (255 - b) * (255 - tb) / 255;\n break;\n\n case 'add':\n data[i] = r + tr;\n data[i + 1] = g + tg;\n data[i + 2] = b + tb;\n break;\n\n case 'diff':\n case 'difference':\n data[i] = Math.abs(r - tr);\n data[i + 1] = Math.abs(g - tg);\n data[i + 2] = Math.abs(b - tb);\n break;\n\n case 'subtract':\n data[i] = r - tr;\n data[i + 1] = g - tg;\n data[i + 2] = b - tb;\n break;\n\n case 'darken':\n data[i] = Math.min(r, tr);\n data[i + 1] = Math.min(g, tg);\n data[i + 2] = Math.min(b, tb);\n break;\n\n case 'lighten':\n data[i] = Math.max(r, tr);\n data[i + 1] = Math.max(g, tg);\n data[i + 2] = Math.max(b, tb);\n break;\n\n case 'overlay':\n data[i] = tr < 128 ? 2 * r * tr / 255 : 255 - 2 * (255 - r) * (255 - tr) / 255;\n data[i + 1] = tg < 128 ? 2 * g * tg / 255 : 255 - 2 * (255 - g) * (255 - tg) / 255;\n data[i + 2] = tb < 128 ? 2 * b * tb / 255 : 255 - 2 * (255 - b) * (255 - tb) / 255;\n break;\n\n case 'exclusion':\n data[i] = tr + r - 2 * tr * r / 255;\n data[i + 1] = tg + g - 2 * tg * g / 255;\n data[i + 2] = tb + b - 2 * tb * b / 255;\n break;\n\n case 'tint':\n data[i] = tr + r * alpha1;\n data[i + 1] = tg + g * alpha1;\n data[i + 2] = tb + b * alpha1;\n }\n }\n },\n\n /**\n * Return WebGL uniform locations for this filter's shader.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {WebGLShaderProgram} program This filter's compiled shader program.\n */\n getUniformLocations: function (gl, program) {\n return {\n uColor: gl.getUniformLocation(program, 'uColor')\n };\n },\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData: function (gl, uniformLocations) {\n var source = new fabric.Color(this.color).getSource();\n source[0] = this.alpha * source[0] / 255;\n source[1] = this.alpha * source[1] / 255;\n source[2] = this.alpha * source[2] / 255;\n source[3] = this.alpha;\n gl.uniform4fv(uniformLocations.uColor, source);\n },\n\n /**\n * Returns object representation of an instance\n * @return {Object} Object representation of an instance\n */\n toObject: function () {\n return {\n type: this.type,\n color: this.color,\n mode: this.mode,\n alpha: this.alpha\n };\n }\n });\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.BlendColor} Instance of fabric.Image.filters.BlendColor\n */\n\n fabric.Image.filters.BlendColor.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n})(typeof exports !== 'undefined' ? exports : this);\n\n(function (global) {\n 'use strict';\n\n var fabric = global.fabric,\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n /**\n * Image Blend filter class\n * @class fabric.Image.filter.BlendImage\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @example\n * var filter = new fabric.Image.filters.BlendColor({\n * color: '#000',\n * mode: 'multiply'\n * });\n *\n * var filter = new fabric.Image.filters.BlendImage({\n * image: fabricImageObject,\n * mode: 'multiply',\n * alpha: 0.5\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n * canvas.renderAll();\n */\n\n filters.BlendImage = createClass(filters.BaseFilter,\n /** @lends fabric.Image.filters.BlendImage.prototype */\n {\n type: 'BlendImage',\n\n /**\n * Color to make the blend operation with. default to a reddish color since black or white\n * gives always strong result.\n **/\n image: null,\n\n /**\n * Blend mode for the filter: one of multiply, add, diff, screen, subtract,\n * darken, lighten, overlay, exclusion, tint.\n **/\n mode: 'multiply',\n\n /**\n * alpha value. represent the strength of the blend image operation.\n * not implemented.\n **/\n alpha: 1,\n vertexSource: 'attribute vec2 aPosition;\\n' + 'varying vec2 vTexCoord;\\n' + 'varying vec2 vTexCoord2;\\n' + 'uniform mat3 uTransformMatrix;\\n' + 'void main() {\\n' + 'vTexCoord = aPosition;\\n' + 'vTexCoord2 = (uTransformMatrix * vec3(aPosition, 1.0)).xy;\\n' + 'gl_Position = vec4(aPosition * 2.0 - 1.0, 0.0, 1.0);\\n' + '}',\n\n /**\n * Fragment source for the Multiply program\n */\n fragmentSource: {\n multiply: 'precision highp float;\\n' + 'uniform sampler2D uTexture;\\n' + 'uniform sampler2D uImage;\\n' + 'uniform vec4 uColor;\\n' + 'varying vec2 vTexCoord;\\n' + 'varying vec2 vTexCoord2;\\n' + 'void main() {\\n' + 'vec4 color = texture2D(uTexture, vTexCoord);\\n' + 'vec4 color2 = texture2D(uImage, vTexCoord2);\\n' + 'color.rgba *= color2.rgba;\\n' + 'gl_FragColor = color;\\n' + '}',\n mask: 'precision highp float;\\n' + 'uniform sampler2D uTexture;\\n' + 'uniform sampler2D uImage;\\n' + 'uniform vec4 uColor;\\n' + 'varying vec2 vTexCoord;\\n' + 'varying vec2 vTexCoord2;\\n' + 'void main() {\\n' + 'vec4 color = texture2D(uTexture, vTexCoord);\\n' + 'vec4 color2 = texture2D(uImage, vTexCoord2);\\n' + 'color.a = color2.a;\\n' + 'gl_FragColor = color;\\n' + '}'\n },\n\n /**\n * Retrieves the cached shader.\n * @param {Object} options\n * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n */\n retrieveShader: function (options) {\n var cacheKey = this.type + '_' + this.mode;\n var shaderSource = this.fragmentSource[this.mode];\n\n if (!options.programCache.hasOwnProperty(cacheKey)) {\n options.programCache[cacheKey] = this.createProgram(options.context, shaderSource);\n }\n\n return options.programCache[cacheKey];\n },\n applyToWebGL: function (options) {\n // load texture to blend.\n var gl = options.context,\n texture = this.createTexture(options.filterBackend, this.image);\n this.bindAdditionalTexture(gl, texture, gl.TEXTURE1);\n this.callSuper('applyToWebGL', options);\n this.unbindAdditionalTexture(gl, gl.TEXTURE1);\n },\n createTexture: function (backend, image) {\n return backend.getCachedTexture(image.cacheKey, image._element);\n },\n\n /**\n * Calculate a transformMatrix to adapt the image to blend over\n * @param {Object} options\n * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n */\n calculateMatrix: function () {\n var image = this.image,\n width = image._element.width,\n height = image._element.height;\n return [1 / image.scaleX, 0, 0, 0, 1 / image.scaleY, 0, -image.left / width, -image.top / height, 1];\n },\n\n /**\n * Apply the Blend operation to a Uint8ClampedArray representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n */\n applyTo2d: function (options) {\n var imageData = options.imageData,\n resources = options.filterBackend.resources,\n data = imageData.data,\n iLen = data.length,\n width = imageData.width,\n height = imageData.height,\n tr,\n tg,\n tb,\n ta,\n r,\n g,\n b,\n a,\n canvas1,\n context,\n image = this.image,\n blendData;\n\n if (!resources.blendImage) {\n resources.blendImage = fabric.util.createCanvasElement();\n }\n\n canvas1 = resources.blendImage;\n context = canvas1.getContext('2d');\n\n if (canvas1.width !== width || canvas1.height !== height) {\n canvas1.width = width;\n canvas1.height = height;\n } else {\n context.clearRect(0, 0, width, height);\n }\n\n context.setTransform(image.scaleX, 0, 0, image.scaleY, image.left, image.top);\n context.drawImage(image._element, 0, 0, width, height);\n blendData = context.getImageData(0, 0, width, height).data;\n\n for (var i = 0; i < iLen; i += 4) {\n r = data[i];\n g = data[i + 1];\n b = data[i + 2];\n a = data[i + 3];\n tr = blendData[i];\n tg = blendData[i + 1];\n tb = blendData[i + 2];\n ta = blendData[i + 3];\n\n switch (this.mode) {\n case 'multiply':\n data[i] = r * tr / 255;\n data[i + 1] = g * tg / 255;\n data[i + 2] = b * tb / 255;\n data[i + 3] = a * ta / 255;\n break;\n\n case 'mask':\n data[i + 3] = ta;\n break;\n }\n }\n },\n\n /**\n * Return WebGL uniform locations for this filter's shader.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {WebGLShaderProgram} program This filter's compiled shader program.\n */\n getUniformLocations: function (gl, program) {\n return {\n uTransformMatrix: gl.getUniformLocation(program, 'uTransformMatrix'),\n uImage: gl.getUniformLocation(program, 'uImage')\n };\n },\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData: function (gl, uniformLocations) {\n var matrix = this.calculateMatrix();\n gl.uniform1i(uniformLocations.uImage, 1); // texture unit 1.\n\n gl.uniformMatrix3fv(uniformLocations.uTransformMatrix, false, matrix);\n },\n\n /**\n * Returns object representation of an instance\n * @return {Object} Object representation of an instance\n */\n toObject: function () {\n return {\n type: this.type,\n image: this.image && this.image.toObject(),\n mode: this.mode,\n alpha: this.alpha\n };\n }\n });\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {function} callback to be invoked after filter creation\n * @return {fabric.Image.filters.BlendImage} Instance of fabric.Image.filters.BlendImage\n */\n\n fabric.Image.filters.BlendImage.fromObject = function (object, callback) {\n fabric.Image.fromObject(object.image, function (image) {\n var options = fabric.util.object.clone(object);\n options.image = image;\n callback(new fabric.Image.filters.BlendImage(options));\n });\n };\n})(typeof exports !== 'undefined' ? exports : this);\n\n(function (global) {\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = {}),\n pow = Math.pow,\n floor = Math.floor,\n sqrt = Math.sqrt,\n abs = Math.abs,\n round = Math.round,\n sin = Math.sin,\n ceil = Math.ceil,\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n /**\n * Resize image filter class\n * @class fabric.Image.filters.Resize\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example\n * var filter = new fabric.Image.filters.Resize();\n * object.filters.push(filter);\n * object.applyFilters(canvas.renderAll.bind(canvas));\n */\n\n filters.Resize = createClass(filters.BaseFilter,\n /** @lends fabric.Image.filters.Resize.prototype */\n {\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'Resize',\n\n /**\n * Resize type\n * for webgl resizeType is just lanczos, for canvas2d can be:\n * bilinear, hermite, sliceHack, lanczos.\n * @param {String} resizeType\n * @default\n */\n resizeType: 'hermite',\n\n /**\n * Scale factor for resizing, x axis\n * @param {Number} scaleX\n * @default\n */\n scaleX: 1,\n\n /**\n * Scale factor for resizing, y axis\n * @param {Number} scaleY\n * @default\n */\n scaleY: 1,\n\n /**\n * LanczosLobes parameter for lanczos filter, valid for resizeType lanczos\n * @param {Number} lanczosLobes\n * @default\n */\n lanczosLobes: 3,\n\n /**\n * Return WebGL uniform locations for this filter's shader.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {WebGLShaderProgram} program This filter's compiled shader program.\n */\n getUniformLocations: function (gl, program) {\n return {\n uDelta: gl.getUniformLocation(program, 'uDelta'),\n uTaps: gl.getUniformLocation(program, 'uTaps')\n };\n },\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData: function (gl, uniformLocations) {\n gl.uniform2fv(uniformLocations.uDelta, this.horizontal ? [1 / this.width, 0] : [0, 1 / this.height]);\n gl.uniform1fv(uniformLocations.uTaps, this.taps);\n },\n\n /**\n * Retrieves the cached shader.\n * @param {Object} options\n * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n */\n retrieveShader: function (options) {\n var filterWindow = this.getFilterWindow(),\n cacheKey = this.type + '_' + filterWindow;\n\n if (!options.programCache.hasOwnProperty(cacheKey)) {\n var fragmentShader = this.generateShader(filterWindow);\n options.programCache[cacheKey] = this.createProgram(options.context, fragmentShader);\n }\n\n return options.programCache[cacheKey];\n },\n getFilterWindow: function () {\n var scale = this.tempScale;\n return Math.ceil(this.lanczosLobes / scale);\n },\n getTaps: function () {\n var lobeFunction = this.lanczosCreate(this.lanczosLobes),\n scale = this.tempScale,\n filterWindow = this.getFilterWindow(),\n taps = new Array(filterWindow);\n\n for (var i = 1; i <= filterWindow; i++) {\n taps[i - 1] = lobeFunction(i * scale);\n }\n\n return taps;\n },\n\n /**\n * Generate vertex and shader sources from the necessary steps numbers\n * @param {Number} filterWindow\n */\n generateShader: function (filterWindow) {\n var offsets = new Array(filterWindow),\n fragmentShader = this.fragmentSourceTOP,\n filterWindow;\n\n for (var i = 1; i <= filterWindow; i++) {\n offsets[i - 1] = i + '.0 * uDelta';\n }\n\n fragmentShader += 'uniform float uTaps[' + filterWindow + '];\\n';\n fragmentShader += 'void main() {\\n';\n fragmentShader += ' vec4 color = texture2D(uTexture, vTexCoord);\\n';\n fragmentShader += ' float sum = 1.0;\\n';\n offsets.forEach(function (offset, i) {\n fragmentShader += ' color += texture2D(uTexture, vTexCoord + ' + offset + ') * uTaps[' + i + '];\\n';\n fragmentShader += ' color += texture2D(uTexture, vTexCoord - ' + offset + ') * uTaps[' + i + '];\\n';\n fragmentShader += ' sum += 2.0 * uTaps[' + i + '];\\n';\n });\n fragmentShader += ' gl_FragColor = color / sum;\\n';\n fragmentShader += '}';\n return fragmentShader;\n },\n fragmentSourceTOP: 'precision highp float;\\n' + 'uniform sampler2D uTexture;\\n' + 'uniform vec2 uDelta;\\n' + 'varying vec2 vTexCoord;\\n',\n\n /**\n * Apply the resize filter to the image\n * Determines whether to use WebGL or Canvas2D based on the options.webgl flag.\n *\n * @param {Object} options\n * @param {Number} options.passes The number of filters remaining to be executed\n * @param {Boolean} options.webgl Whether to use webgl to render the filter.\n * @param {WebGLTexture} options.sourceTexture The texture setup as the source to be filtered.\n * @param {WebGLTexture} options.targetTexture The texture where filtered output should be drawn.\n * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n */\n applyTo: function (options) {\n if (options.webgl) {\n options.passes++;\n this.width = options.sourceWidth;\n this.horizontal = true;\n this.dW = Math.round(this.width * this.scaleX);\n this.dH = options.sourceHeight;\n this.tempScale = this.dW / this.width;\n this.taps = this.getTaps();\n options.destinationWidth = this.dW;\n\n this._setupFrameBuffer(options);\n\n this.applyToWebGL(options);\n\n this._swapTextures(options);\n\n options.sourceWidth = options.destinationWidth;\n this.height = options.sourceHeight;\n this.horizontal = false;\n this.dH = Math.round(this.height * this.scaleY);\n this.tempScale = this.dH / this.height;\n this.taps = this.getTaps();\n options.destinationHeight = this.dH;\n\n this._setupFrameBuffer(options);\n\n this.applyToWebGL(options);\n\n this._swapTextures(options);\n\n options.sourceHeight = options.destinationHeight;\n } else {\n this.applyTo2d(options);\n }\n },\n isNeutralState: function () {\n return this.scaleX === 1 && this.scaleY === 1;\n },\n lanczosCreate: function (lobes) {\n return function (x) {\n if (x >= lobes || x <= -lobes) {\n return 0.0;\n }\n\n if (x < 1.19209290E-07 && x > -1.19209290E-07) {\n return 1.0;\n }\n\n x *= Math.PI;\n var xx = x / lobes;\n return sin(x) / x * sin(xx) / xx;\n };\n },\n\n /**\n * Applies filter to canvas element\n * @memberOf fabric.Image.filters.Resize.prototype\n * @param {Object} canvasEl Canvas element to apply filter to\n * @param {Number} scaleX\n * @param {Number} scaleY\n */\n applyTo2d: function (options) {\n var imageData = options.imageData,\n scaleX = this.scaleX,\n scaleY = this.scaleY;\n this.rcpScaleX = 1 / scaleX;\n this.rcpScaleY = 1 / scaleY;\n var oW = imageData.width,\n oH = imageData.height,\n dW = round(oW * scaleX),\n dH = round(oH * scaleY),\n newData;\n\n if (this.resizeType === 'sliceHack') {\n newData = this.sliceByTwo(options, oW, oH, dW, dH);\n } else if (this.resizeType === 'hermite') {\n newData = this.hermiteFastResize(options, oW, oH, dW, dH);\n } else if (this.resizeType === 'bilinear') {\n newData = this.bilinearFiltering(options, oW, oH, dW, dH);\n } else if (this.resizeType === 'lanczos') {\n newData = this.lanczosResize(options, oW, oH, dW, dH);\n }\n\n options.imageData = newData;\n },\n\n /**\n * Filter sliceByTwo\n * @param {Object} canvasEl Canvas element to apply filter to\n * @param {Number} oW Original Width\n * @param {Number} oH Original Height\n * @param {Number} dW Destination Width\n * @param {Number} dH Destination Height\n * @returns {ImageData}\n */\n sliceByTwo: function (options, oW, oH, dW, dH) {\n var imageData = options.imageData,\n mult = 0.5,\n doneW = false,\n doneH = false,\n stepW = oW * mult,\n stepH = oH * mult,\n resources = fabric.filterBackend.resources,\n tmpCanvas,\n ctx,\n sX = 0,\n sY = 0,\n dX = oW,\n dY = 0;\n\n if (!resources.sliceByTwo) {\n resources.sliceByTwo = document.createElement('canvas');\n }\n\n tmpCanvas = resources.sliceByTwo;\n\n if (tmpCanvas.width < oW * 1.5 || tmpCanvas.height < oH) {\n tmpCanvas.width = oW * 1.5;\n tmpCanvas.height = oH;\n }\n\n ctx = tmpCanvas.getContext('2d');\n ctx.clearRect(0, 0, oW * 1.5, oH);\n ctx.putImageData(imageData, 0, 0);\n dW = floor(dW);\n dH = floor(dH);\n\n while (!doneW || !doneH) {\n oW = stepW;\n oH = stepH;\n\n if (dW < floor(stepW * mult)) {\n stepW = floor(stepW * mult);\n } else {\n stepW = dW;\n doneW = true;\n }\n\n if (dH < floor(stepH * mult)) {\n stepH = floor(stepH * mult);\n } else {\n stepH = dH;\n doneH = true;\n }\n\n ctx.drawImage(tmpCanvas, sX, sY, oW, oH, dX, dY, stepW, stepH);\n sX = dX;\n sY = dY;\n dY += stepH;\n }\n\n return ctx.getImageData(sX, sY, dW, dH);\n },\n\n /**\n * Filter lanczosResize\n * @param {Object} canvasEl Canvas element to apply filter to\n * @param {Number} oW Original Width\n * @param {Number} oH Original Height\n * @param {Number} dW Destination Width\n * @param {Number} dH Destination Height\n * @returns {ImageData}\n */\n lanczosResize: function (options, oW, oH, dW, dH) {\n function process(u) {\n var v, i, weight, idx, a, red, green, blue, alpha, fX, fY;\n center.x = (u + 0.5) * ratioX;\n icenter.x = floor(center.x);\n\n for (v = 0; v < dH; v++) {\n center.y = (v + 0.5) * ratioY;\n icenter.y = floor(center.y);\n a = 0;\n red = 0;\n green = 0;\n blue = 0;\n alpha = 0;\n\n for (i = icenter.x - range2X; i <= icenter.x + range2X; i++) {\n if (i < 0 || i >= oW) {\n continue;\n }\n\n fX = floor(1000 * abs(i - center.x));\n\n if (!cacheLanc[fX]) {\n cacheLanc[fX] = {};\n }\n\n for (var j = icenter.y - range2Y; j <= icenter.y + range2Y; j++) {\n if (j < 0 || j >= oH) {\n continue;\n }\n\n fY = floor(1000 * abs(j - center.y));\n\n if (!cacheLanc[fX][fY]) {\n cacheLanc[fX][fY] = lanczos(sqrt(pow(fX * rcpRatioX, 2) + pow(fY * rcpRatioY, 2)) / 1000);\n }\n\n weight = cacheLanc[fX][fY];\n\n if (weight > 0) {\n idx = (j * oW + i) * 4;\n a += weight;\n red += weight * srcData[idx];\n green += weight * srcData[idx + 1];\n blue += weight * srcData[idx + 2];\n alpha += weight * srcData[idx + 3];\n }\n }\n }\n\n idx = (v * dW + u) * 4;\n destData[idx] = red / a;\n destData[idx + 1] = green / a;\n destData[idx + 2] = blue / a;\n destData[idx + 3] = alpha / a;\n }\n\n if (++u < dW) {\n return process(u);\n } else {\n return destImg;\n }\n }\n\n var srcData = options.imageData.data,\n destImg = options.ctx.createImageData(dW, dH),\n destData = destImg.data,\n lanczos = this.lanczosCreate(this.lanczosLobes),\n ratioX = this.rcpScaleX,\n ratioY = this.rcpScaleY,\n rcpRatioX = 2 / this.rcpScaleX,\n rcpRatioY = 2 / this.rcpScaleY,\n range2X = ceil(ratioX * this.lanczosLobes / 2),\n range2Y = ceil(ratioY * this.lanczosLobes / 2),\n cacheLanc = {},\n center = {},\n icenter = {};\n return process(0);\n },\n\n /**\n * bilinearFiltering\n * @param {Object} canvasEl Canvas element to apply filter to\n * @param {Number} oW Original Width\n * @param {Number} oH Original Height\n * @param {Number} dW Destination Width\n * @param {Number} dH Destination Height\n * @returns {ImageData}\n */\n bilinearFiltering: function (options, oW, oH, dW, dH) {\n var a,\n b,\n c,\n d,\n x,\n y,\n i,\n j,\n xDiff,\n yDiff,\n chnl,\n color,\n offset = 0,\n origPix,\n ratioX = this.rcpScaleX,\n ratioY = this.rcpScaleY,\n w4 = 4 * (oW - 1),\n img = options.imageData,\n pixels = img.data,\n destImage = options.ctx.createImageData(dW, dH),\n destPixels = destImage.data;\n\n for (i = 0; i < dH; i++) {\n for (j = 0; j < dW; j++) {\n x = floor(ratioX * j);\n y = floor(ratioY * i);\n xDiff = ratioX * j - x;\n yDiff = ratioY * i - y;\n origPix = 4 * (y * oW + x);\n\n for (chnl = 0; chnl < 4; chnl++) {\n a = pixels[origPix + chnl];\n b = pixels[origPix + 4 + chnl];\n c = pixels[origPix + w4 + chnl];\n d = pixels[origPix + w4 + 4 + chnl];\n color = a * (1 - xDiff) * (1 - yDiff) + b * xDiff * (1 - yDiff) + c * yDiff * (1 - xDiff) + d * xDiff * yDiff;\n destPixels[offset++] = color;\n }\n }\n }\n\n return destImage;\n },\n\n /**\n * hermiteFastResize\n * @param {Object} canvasEl Canvas element to apply filter to\n * @param {Number} oW Original Width\n * @param {Number} oH Original Height\n * @param {Number} dW Destination Width\n * @param {Number} dH Destination Height\n * @returns {ImageData}\n */\n hermiteFastResize: function (options, oW, oH, dW, dH) {\n var ratioW = this.rcpScaleX,\n ratioH = this.rcpScaleY,\n ratioWHalf = ceil(ratioW / 2),\n ratioHHalf = ceil(ratioH / 2),\n img = options.imageData,\n data = img.data,\n img2 = options.ctx.createImageData(dW, dH),\n data2 = img2.data;\n\n for (var j = 0; j < dH; j++) {\n for (var i = 0; i < dW; i++) {\n var x2 = (i + j * dW) * 4,\n weight = 0,\n weights = 0,\n weightsAlpha = 0,\n gxR = 0,\n gxG = 0,\n gxB = 0,\n gxA = 0,\n centerY = (j + 0.5) * ratioH;\n\n for (var yy = floor(j * ratioH); yy < (j + 1) * ratioH; yy++) {\n var dy = abs(centerY - (yy + 0.5)) / ratioHHalf,\n centerX = (i + 0.5) * ratioW,\n w0 = dy * dy;\n\n for (var xx = floor(i * ratioW); xx < (i + 1) * ratioW; xx++) {\n var dx = abs(centerX - (xx + 0.5)) / ratioWHalf,\n w = sqrt(w0 + dx * dx);\n /* eslint-disable max-depth */\n\n if (w > 1 && w < -1) {\n continue;\n } //hermite filter\n\n\n weight = 2 * w * w * w - 3 * w * w + 1;\n\n if (weight > 0) {\n dx = 4 * (xx + yy * oW); //alpha\n\n gxA += weight * data[dx + 3];\n weightsAlpha += weight; //colors\n\n if (data[dx + 3] < 255) {\n weight = weight * data[dx + 3] / 250;\n }\n\n gxR += weight * data[dx];\n gxG += weight * data[dx + 1];\n gxB += weight * data[dx + 2];\n weights += weight;\n }\n /* eslint-enable max-depth */\n\n }\n }\n\n data2[x2] = gxR / weights;\n data2[x2 + 1] = gxG / weights;\n data2[x2 + 2] = gxB / weights;\n data2[x2 + 3] = gxA / weightsAlpha;\n }\n }\n\n return img2;\n },\n\n /**\n * Returns object representation of an instance\n * @return {Object} Object representation of an instance\n */\n toObject: function () {\n return {\n type: this.type,\n scaleX: this.scaleX,\n scaleY: this.scaleY,\n resizeType: this.resizeType,\n lanczosLobes: this.lanczosLobes\n };\n }\n });\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {Function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.Resize} Instance of fabric.Image.filters.Resize\n */\n\n fabric.Image.filters.Resize.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n})(typeof exports !== 'undefined' ? exports : this);\n\n(function (global) {\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = {}),\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n /**\n * Contrast filter class\n * @class fabric.Image.filters.Contrast\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link fabric.Image.filters.Contrast#initialize} for constructor definition\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example\n * var filter = new fabric.Image.filters.Contrast({\n * contrast: 0.25\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n */\n\n filters.Contrast = createClass(filters.BaseFilter,\n /** @lends fabric.Image.filters.Contrast.prototype */\n {\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'Contrast',\n fragmentSource: 'precision highp float;\\n' + 'uniform sampler2D uTexture;\\n' + 'uniform float uContrast;\\n' + 'varying vec2 vTexCoord;\\n' + 'void main() {\\n' + 'vec4 color = texture2D(uTexture, vTexCoord);\\n' + 'float contrastF = 1.015 * (uContrast + 1.0) / (1.0 * (1.015 - uContrast));\\n' + 'color.rgb = contrastF * (color.rgb - 0.5) + 0.5;\\n' + 'gl_FragColor = color;\\n' + '}',\n\n /**\n * contrast value, range from -1 to 1.\n * @param {Number} contrast\n * @default 0\n */\n contrast: 0,\n mainParameter: 'contrast',\n\n /**\n * Constructor\n * @memberOf fabric.Image.filters.Contrast.prototype\n * @param {Object} [options] Options object\n * @param {Number} [options.contrast=0] Value to contrast the image up (-1...1)\n */\n\n /**\n * Apply the Contrast operation to a Uint8Array representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8Array to be filtered.\n */\n applyTo2d: function (options) {\n if (this.contrast === 0) {\n return;\n }\n\n var imageData = options.imageData,\n i,\n len,\n data = imageData.data,\n len = data.length,\n contrast = Math.floor(this.contrast * 255),\n contrastF = 259 * (contrast + 255) / (255 * (259 - contrast));\n\n for (i = 0; i < len; i += 4) {\n data[i] = contrastF * (data[i] - 128) + 128;\n data[i + 1] = contrastF * (data[i + 1] - 128) + 128;\n data[i + 2] = contrastF * (data[i + 2] - 128) + 128;\n }\n },\n\n /**\n * Return WebGL uniform locations for this filter's shader.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {WebGLShaderProgram} program This filter's compiled shader program.\n */\n getUniformLocations: function (gl, program) {\n return {\n uContrast: gl.getUniformLocation(program, 'uContrast')\n };\n },\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData: function (gl, uniformLocations) {\n gl.uniform1f(uniformLocations.uContrast, this.contrast);\n }\n });\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.Contrast} Instance of fabric.Image.filters.Contrast\n */\n\n fabric.Image.filters.Contrast.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n})(typeof exports !== 'undefined' ? exports : this);\n\n(function (global) {\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = {}),\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n /**\n * Saturate filter class\n * @class fabric.Image.filters.Saturation\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link fabric.Image.filters.Saturation#initialize} for constructor definition\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example\n * var filter = new fabric.Image.filters.Saturation({\n * saturation: 100\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n */\n\n filters.Saturation = createClass(filters.BaseFilter,\n /** @lends fabric.Image.filters.Saturation.prototype */\n {\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'Saturation',\n fragmentSource: 'precision highp float;\\n' + 'uniform sampler2D uTexture;\\n' + 'uniform float uSaturation;\\n' + 'varying vec2 vTexCoord;\\n' + 'void main() {\\n' + 'vec4 color = texture2D(uTexture, vTexCoord);\\n' + 'float rgMax = max(color.r, color.g);\\n' + 'float rgbMax = max(rgMax, color.b);\\n' + 'color.r += rgbMax != color.r ? (rgbMax - color.r) * uSaturation : 0.00;\\n' + 'color.g += rgbMax != color.g ? (rgbMax - color.g) * uSaturation : 0.00;\\n' + 'color.b += rgbMax != color.b ? (rgbMax - color.b) * uSaturation : 0.00;\\n' + 'gl_FragColor = color;\\n' + '}',\n saturation: 0,\n mainParameter: 'saturation',\n\n /**\n * Constructor\n * @memberOf fabric.Image.filters.Saturate.prototype\n * @param {Object} [options] Options object\n * @param {Number} [options.saturate=0] Value to saturate the image (-1...1)\n */\n\n /**\n * Apply the Saturation operation to a Uint8ClampedArray representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n */\n applyTo2d: function (options) {\n if (this.saturation === 0) {\n return;\n }\n\n var imageData = options.imageData,\n data = imageData.data,\n len = data.length,\n adjust = -this.saturation,\n i,\n max;\n\n for (i = 0; i < len; i += 4) {\n max = Math.max(data[i], data[i + 1], data[i + 2]);\n data[i] += max !== data[i] ? (max - data[i]) * adjust : 0;\n data[i + 1] += max !== data[i + 1] ? (max - data[i + 1]) * adjust : 0;\n data[i + 2] += max !== data[i + 2] ? (max - data[i + 2]) * adjust : 0;\n }\n },\n\n /**\n * Return WebGL uniform locations for this filter's shader.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {WebGLShaderProgram} program This filter's compiled shader program.\n */\n getUniformLocations: function (gl, program) {\n return {\n uSaturation: gl.getUniformLocation(program, 'uSaturation')\n };\n },\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData: function (gl, uniformLocations) {\n gl.uniform1f(uniformLocations.uSaturation, -this.saturation);\n }\n });\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {Function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.Saturation} Instance of fabric.Image.filters.Saturate\n */\n\n fabric.Image.filters.Saturation.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n})(typeof exports !== 'undefined' ? exports : this);\n\n(function (global) {\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = {}),\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n /**\n * Blur filter class\n * @class fabric.Image.filters.Blur\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link fabric.Image.filters.Blur#initialize} for constructor definition\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example\n * var filter = new fabric.Image.filters.Blur({\n * blur: 0.5\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n * canvas.renderAll();\n */\n\n filters.Blur = createClass(filters.BaseFilter,\n /** @lends fabric.Image.filters.Blur.prototype */\n {\n type: 'Blur',\n\n /*\n 'gl_FragColor = vec4(0.0);',\n 'gl_FragColor += texture2D(texture, vTexCoord + -7 * uDelta)*0.0044299121055113265;',\n 'gl_FragColor += texture2D(texture, vTexCoord + -6 * uDelta)*0.00895781211794;',\n 'gl_FragColor += texture2D(texture, vTexCoord + -5 * uDelta)*0.0215963866053;',\n 'gl_FragColor += texture2D(texture, vTexCoord + -4 * uDelta)*0.0443683338718;',\n 'gl_FragColor += texture2D(texture, vTexCoord + -3 * uDelta)*0.0776744219933;',\n 'gl_FragColor += texture2D(texture, vTexCoord + -2 * uDelta)*0.115876621105;',\n 'gl_FragColor += texture2D(texture, vTexCoord + -1 * uDelta)*0.147308056121;',\n 'gl_FragColor += texture2D(texture, vTexCoord )*0.159576912161;',\n 'gl_FragColor += texture2D(texture, vTexCoord + 1 * uDelta)*0.147308056121;',\n 'gl_FragColor += texture2D(texture, vTexCoord + 2 * uDelta)*0.115876621105;',\n 'gl_FragColor += texture2D(texture, vTexCoord + 3 * uDelta)*0.0776744219933;',\n 'gl_FragColor += texture2D(texture, vTexCoord + 4 * uDelta)*0.0443683338718;',\n 'gl_FragColor += texture2D(texture, vTexCoord + 5 * uDelta)*0.0215963866053;',\n 'gl_FragColor += texture2D(texture, vTexCoord + 6 * uDelta)*0.00895781211794;',\n 'gl_FragColor += texture2D(texture, vTexCoord + 7 * uDelta)*0.0044299121055113265;',\n */\n\n /* eslint-disable max-len */\n fragmentSource: 'precision highp float;\\n' + 'uniform sampler2D uTexture;\\n' + 'uniform vec2 uDelta;\\n' + 'varying vec2 vTexCoord;\\n' + 'const float nSamples = 15.0;\\n' + 'vec3 v3offset = vec3(12.9898, 78.233, 151.7182);\\n' + 'float random(vec3 scale) {\\n' +\n /* use the fragment position for a different seed per-pixel */\n 'return fract(sin(dot(gl_FragCoord.xyz, scale)) * 43758.5453);\\n' + '}\\n' + 'void main() {\\n' + 'vec4 color = vec4(0.0);\\n' + 'float total = 0.0;\\n' + 'float offset = random(v3offset);\\n' + 'for (float t = -nSamples; t <= nSamples; t++) {\\n' + 'float percent = (t + offset - 0.5) / nSamples;\\n' + 'float weight = 1.0 - abs(percent);\\n' + 'color += texture2D(uTexture, vTexCoord + uDelta * percent) * weight;\\n' + 'total += weight;\\n' + '}\\n' + 'gl_FragColor = color / total;\\n' + '}',\n\n /* eslint-enable max-len */\n\n /**\n * blur value, in percentage of image dimensions.\n * specific to keep the image blur constant at different resolutions\n * range bewteen 0 and 1.\n */\n blur: 0,\n mainParameter: 'blur',\n applyTo: function (options) {\n if (options.webgl) {\n // this aspectRatio is used to give the same blur to vertical and horizontal\n this.aspectRatio = options.sourceWidth / options.sourceHeight;\n options.passes++;\n\n this._setupFrameBuffer(options);\n\n this.horizontal = true;\n this.applyToWebGL(options);\n\n this._swapTextures(options);\n\n this._setupFrameBuffer(options);\n\n this.horizontal = false;\n this.applyToWebGL(options);\n\n this._swapTextures(options);\n } else {\n this.applyTo2d(options);\n }\n },\n applyTo2d: function (options) {\n // paint canvasEl with current image data.\n //options.ctx.putImageData(options.imageData, 0, 0);\n options.imageData = this.simpleBlur(options);\n },\n simpleBlur: function (options) {\n var resources = options.filterBackend.resources,\n canvas1,\n canvas2,\n width = options.imageData.width,\n height = options.imageData.height;\n\n if (!resources.blurLayer1) {\n resources.blurLayer1 = fabric.util.createCanvasElement();\n resources.blurLayer2 = fabric.util.createCanvasElement();\n }\n\n canvas1 = resources.blurLayer1;\n canvas2 = resources.blurLayer2;\n\n if (canvas1.width !== width || canvas1.height !== height) {\n canvas2.width = canvas1.width = width;\n canvas2.height = canvas1.height = height;\n }\n\n var ctx1 = canvas1.getContext('2d'),\n ctx2 = canvas2.getContext('2d'),\n nSamples = 15,\n random,\n percent,\n j,\n i,\n blur = this.blur * 0.06 * 0.5; // load first canvas\n\n ctx1.putImageData(options.imageData, 0, 0);\n ctx2.clearRect(0, 0, width, height);\n\n for (i = -nSamples; i <= nSamples; i++) {\n random = (Math.random() - 0.5) / 4;\n percent = i / nSamples;\n j = blur * percent * width + random;\n ctx2.globalAlpha = 1 - Math.abs(percent);\n ctx2.drawImage(canvas1, j, random);\n ctx1.drawImage(canvas2, 0, 0);\n ctx2.globalAlpha = 1;\n ctx2.clearRect(0, 0, canvas2.width, canvas2.height);\n }\n\n for (i = -nSamples; i <= nSamples; i++) {\n random = (Math.random() - 0.5) / 4;\n percent = i / nSamples;\n j = blur * percent * height + random;\n ctx2.globalAlpha = 1 - Math.abs(percent);\n ctx2.drawImage(canvas1, random, j);\n ctx1.drawImage(canvas2, 0, 0);\n ctx2.globalAlpha = 1;\n ctx2.clearRect(0, 0, canvas2.width, canvas2.height);\n }\n\n options.ctx.drawImage(canvas1, 0, 0);\n var newImageData = options.ctx.getImageData(0, 0, canvas1.width, canvas1.height);\n ctx1.globalAlpha = 1;\n ctx1.clearRect(0, 0, canvas1.width, canvas1.height);\n return newImageData;\n },\n\n /**\n * Return WebGL uniform locations for this filter's shader.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {WebGLShaderProgram} program This filter's compiled shader program.\n */\n getUniformLocations: function (gl, program) {\n return {\n delta: gl.getUniformLocation(program, 'uDelta')\n };\n },\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData: function (gl, uniformLocations) {\n var delta = this.chooseRightDelta();\n gl.uniform2fv(uniformLocations.delta, delta);\n },\n\n /**\n * choose right value of image percentage to blur with\n * @returns {Array} a numeric array with delta values\n */\n chooseRightDelta: function () {\n var blurScale = 1,\n delta = [0, 0],\n blur;\n\n if (this.horizontal) {\n if (this.aspectRatio > 1) {\n // image is wide, i want to shrink radius horizontal\n blurScale = 1 / this.aspectRatio;\n }\n } else {\n if (this.aspectRatio < 1) {\n // image is tall, i want to shrink radius vertical\n blurScale = this.aspectRatio;\n }\n }\n\n blur = blurScale * this.blur * 0.12;\n\n if (this.horizontal) {\n delta[0] = blur;\n } else {\n delta[1] = blur;\n }\n\n return delta;\n }\n });\n /**\n * Deserialize a JSON definition of a BlurFilter into a concrete instance.\n */\n\n filters.Blur.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n})(typeof exports !== 'undefined' ? exports : this);\n\n(function (global) {\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = {}),\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n /**\n * Gamma filter class\n * @class fabric.Image.filters.Gamma\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link fabric.Image.filters.Gamma#initialize} for constructor definition\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example\n * var filter = new fabric.Image.filters.Gamma({\n * gamma: [1, 0.5, 2.1]\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n */\n\n filters.Gamma = createClass(filters.BaseFilter,\n /** @lends fabric.Image.filters.Gamma.prototype */\n {\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'Gamma',\n fragmentSource: 'precision highp float;\\n' + 'uniform sampler2D uTexture;\\n' + 'uniform vec3 uGamma;\\n' + 'varying vec2 vTexCoord;\\n' + 'void main() {\\n' + 'vec4 color = texture2D(uTexture, vTexCoord);\\n' + 'vec3 correction = (1.0 / uGamma);\\n' + 'color.r = pow(color.r, correction.r);\\n' + 'color.g = pow(color.g, correction.g);\\n' + 'color.b = pow(color.b, correction.b);\\n' + 'gl_FragColor = color;\\n' + 'gl_FragColor.rgb *= color.a;\\n' + '}',\n\n /**\n * Gamma array value, from 0.01 to 2.2.\n * @param {Array} gamma\n * @default\n */\n gamma: [1, 1, 1],\n\n /**\n * Describe the property that is the filter parameter\n * @param {String} m\n * @default\n */\n mainParameter: 'gamma',\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n */\n initialize: function (options) {\n this.gamma = [1, 1, 1];\n filters.BaseFilter.prototype.initialize.call(this, options);\n },\n\n /**\n * Apply the Gamma operation to a Uint8Array representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8Array to be filtered.\n */\n applyTo2d: function (options) {\n var imageData = options.imageData,\n data = imageData.data,\n gamma = this.gamma,\n len = data.length,\n rInv = 1 / gamma[0],\n gInv = 1 / gamma[1],\n bInv = 1 / gamma[2],\n i;\n\n if (!this.rVals) {\n // eslint-disable-next-line\n this.rVals = new Uint8Array(256); // eslint-disable-next-line\n\n this.gVals = new Uint8Array(256); // eslint-disable-next-line\n\n this.bVals = new Uint8Array(256);\n } // This is an optimization - pre-compute a look-up table for each color channel\n // instead of performing these pow calls for each pixel in the image.\n\n\n for (i = 0, len = 256; i < len; i++) {\n this.rVals[i] = Math.pow(i / 255, rInv) * 255;\n this.gVals[i] = Math.pow(i / 255, gInv) * 255;\n this.bVals[i] = Math.pow(i / 255, bInv) * 255;\n }\n\n for (i = 0, len = data.length; i < len; i += 4) {\n data[i] = this.rVals[data[i]];\n data[i + 1] = this.gVals[data[i + 1]];\n data[i + 2] = this.bVals[data[i + 2]];\n }\n },\n\n /**\n * Return WebGL uniform locations for this filter's shader.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {WebGLShaderProgram} program This filter's compiled shader program.\n */\n getUniformLocations: function (gl, program) {\n return {\n uGamma: gl.getUniformLocation(program, 'uGamma')\n };\n },\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData: function (gl, uniformLocations) {\n gl.uniform3fv(uniformLocations.uGamma, this.gamma);\n }\n });\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.Gamma} Instance of fabric.Image.filters.Gamma\n */\n\n fabric.Image.filters.Gamma.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n})(typeof exports !== 'undefined' ? exports : this);\n\n(function (global) {\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = {}),\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n /**\n * A container class that knows how to apply a sequence of filters to an input image.\n */\n\n filters.Composed = createClass(filters.BaseFilter,\n /** @lends fabric.Image.filters.Composed.prototype */\n {\n type: 'Composed',\n\n /**\n * A non sparse array of filters to apply\n */\n subFilters: [],\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n */\n initialize: function (options) {\n this.callSuper('initialize', options); // create a new array instead mutating the prototype with push\n\n this.subFilters = this.subFilters.slice(0);\n },\n\n /**\n * Apply this container's filters to the input image provided.\n *\n * @param {Object} options\n * @param {Number} options.passes The number of filters remaining to be applied.\n */\n applyTo: function (options) {\n options.passes += this.subFilters.length - 1;\n this.subFilters.forEach(function (filter) {\n filter.applyTo(options);\n });\n },\n\n /**\n * Serialize this filter into JSON.\n *\n * @returns {Object} A JSON representation of this filter.\n */\n toObject: function () {\n return fabric.util.object.extend(this.callSuper('toObject'), {\n subFilters: this.subFilters.map(function (filter) {\n return filter.toObject();\n })\n });\n },\n isNeutralState: function () {\n return !this.subFilters.some(function (filter) {\n return !filter.isNeutralState();\n });\n }\n });\n /**\n * Deserialize a JSON definition of a ComposedFilter into a concrete instance.\n */\n\n fabric.Image.filters.Composed.fromObject = function (object, callback) {\n var filters = object.subFilters || [],\n subFilters = filters.map(function (filter) {\n return new fabric.Image.filters[filter.type](filter);\n }),\n instance = new fabric.Image.filters.Composed({\n subFilters: subFilters\n });\n callback && callback(instance);\n return instance;\n };\n})(typeof exports !== 'undefined' ? exports : this);\n\n(function (global) {\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = {}),\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n /**\n * HueRotation filter class\n * @class fabric.Image.filters.HueRotation\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link fabric.Image.filters.HueRotation#initialize} for constructor definition\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example\n * var filter = new fabric.Image.filters.HueRotation({\n * rotation: -0.5\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n */\n\n filters.HueRotation = createClass(filters.ColorMatrix,\n /** @lends fabric.Image.filters.HueRotation.prototype */\n {\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'HueRotation',\n\n /**\n * HueRotation value, from -1 to 1.\n * the unit is radians\n * @param {Number} myParameter\n * @default\n */\n rotation: 0,\n\n /**\n * Describe the property that is the filter parameter\n * @param {String} m\n * @default\n */\n mainParameter: 'rotation',\n calculateMatrix: function () {\n var rad = this.rotation * Math.PI,\n cos = fabric.util.cos(rad),\n sin = fabric.util.sin(rad),\n aThird = 1 / 3,\n aThirdSqtSin = Math.sqrt(aThird) * sin,\n OneMinusCos = 1 - cos;\n this.matrix = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0];\n this.matrix[0] = cos + OneMinusCos / 3;\n this.matrix[1] = aThird * OneMinusCos - aThirdSqtSin;\n this.matrix[2] = aThird * OneMinusCos + aThirdSqtSin;\n this.matrix[5] = aThird * OneMinusCos + aThirdSqtSin;\n this.matrix[6] = cos + aThird * OneMinusCos;\n this.matrix[7] = aThird * OneMinusCos - aThirdSqtSin;\n this.matrix[10] = aThird * OneMinusCos - aThirdSqtSin;\n this.matrix[11] = aThird * OneMinusCos + aThirdSqtSin;\n this.matrix[12] = cos + aThird * OneMinusCos;\n },\n\n /**\n * HueRotation isNeutralState implementation\n * Used only in image applyFilters to discard filters that will not have an effect\n * on the image\n * @param {Object} options\n **/\n isNeutralState: function (options) {\n this.calculateMatrix();\n return filters.BaseFilter.prototype.isNeutralState.call(this, options);\n },\n\n /**\n * Apply this filter to the input image data provided.\n *\n * Determines whether to use WebGL or Canvas2D based on the options.webgl flag.\n *\n * @param {Object} options\n * @param {Number} options.passes The number of filters remaining to be executed\n * @param {Boolean} options.webgl Whether to use webgl to render the filter.\n * @param {WebGLTexture} options.sourceTexture The texture setup as the source to be filtered.\n * @param {WebGLTexture} options.targetTexture The texture where filtered output should be drawn.\n * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n */\n applyTo: function (options) {\n this.calculateMatrix();\n filters.BaseFilter.prototype.applyTo.call(this, options);\n }\n });\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.HueRotation} Instance of fabric.Image.filters.HueRotation\n */\n\n fabric.Image.filters.HueRotation.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n})(typeof exports !== 'undefined' ? exports : this);\n\n(function (global) {\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = {}),\n clone = fabric.util.object.clone;\n\n if (fabric.Text) {\n fabric.warn('fabric.Text is already defined');\n return;\n }\n /**\n * Text class\n * @class fabric.Text\n * @extends fabric.Object\n * @return {fabric.Text} thisArg\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#text}\n * @see {@link fabric.Text#initialize} for constructor definition\n */\n\n\n fabric.Text = fabric.util.createClass(fabric.Object,\n /** @lends fabric.Text.prototype */\n {\n /**\n * Properties which when set cause object to change dimensions\n * @type Array\n * @private\n */\n _dimensionAffectingProps: ['fontSize', 'fontWeight', 'fontFamily', 'fontStyle', 'lineHeight', 'text', 'charSpacing', 'textAlign', 'styles'],\n\n /**\n * @private\n */\n _reNewline: /\\r?\\n/,\n\n /**\n * Use this regular expression to filter for whitespaces that is not a new line.\n * Mostly used when text is 'justify' aligned.\n * @private\n */\n _reSpacesAndTabs: /[ \\t\\r]/g,\n\n /**\n * Use this regular expression to filter for whitespace that is not a new line.\n * Mostly used when text is 'justify' aligned.\n * @private\n */\n _reSpaceAndTab: /[ \\t\\r]/,\n\n /**\n * Use this regular expression to filter consecutive groups of non spaces.\n * Mostly used when text is 'justify' aligned.\n * @private\n */\n _reWords: /\\S+/g,\n\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'text',\n\n /**\n * Font size (in pixels)\n * @type Number\n * @default\n */\n fontSize: 40,\n\n /**\n * Font weight (e.g. bold, normal, 400, 600, 800)\n * @type {(Number|String)}\n * @default\n */\n fontWeight: 'normal',\n\n /**\n * Font family\n * @type String\n * @default\n */\n fontFamily: 'Times New Roman',\n\n /**\n * Text decoration underline.\n * @type Boolean\n * @default\n */\n underline: false,\n\n /**\n * Text decoration overline.\n * @type Boolean\n * @default\n */\n overline: false,\n\n /**\n * Text decoration linethrough.\n * @type Boolean\n * @default\n */\n linethrough: false,\n\n /**\n * Text alignment. Possible values: \"left\", \"center\", \"right\", \"justify\",\n * \"justify-left\", \"justify-center\" or \"justify-right\".\n * @type String\n * @default\n */\n textAlign: 'left',\n\n /**\n * Font style . Possible values: \"\", \"normal\", \"italic\" or \"oblique\".\n * @type String\n * @default\n */\n fontStyle: 'normal',\n\n /**\n * Line height\n * @type Number\n * @default\n */\n lineHeight: 1.16,\n\n /**\n * Superscript schema object (minimum overlap)\n * @type {Object}\n * @default\n */\n superscript: {\n size: 0.60,\n // fontSize factor\n baseline: -0.35 // baseline-shift factor (upwards)\n\n },\n\n /**\n * Subscript schema object (minimum overlap)\n * @type {Object}\n * @default\n */\n subscript: {\n size: 0.60,\n // fontSize factor\n baseline: 0.11 // baseline-shift factor (downwards)\n\n },\n\n /**\n * Background color of text lines\n * @type String\n * @default\n */\n textBackgroundColor: '',\n\n /**\n * List of properties to consider when checking if\n * state of an object is changed ({@link fabric.Object#hasStateChanged})\n * as well as for history (undo/redo) purposes\n * @type Array\n */\n stateProperties: fabric.Object.prototype.stateProperties.concat('fontFamily', 'fontWeight', 'fontSize', 'text', 'underline', 'overline', 'linethrough', 'textAlign', 'fontStyle', 'lineHeight', 'textBackgroundColor', 'charSpacing', 'styles'),\n\n /**\n * List of properties to consider when checking if cache needs refresh\n * @type Array\n */\n cacheProperties: fabric.Object.prototype.cacheProperties.concat('fontFamily', 'fontWeight', 'fontSize', 'text', 'underline', 'overline', 'linethrough', 'textAlign', 'fontStyle', 'lineHeight', 'textBackgroundColor', 'charSpacing', 'styles'),\n\n /**\n * When defined, an object is rendered via stroke and this property specifies its color.\n * <b>Backwards incompatibility note:</b> This property was named \"strokeStyle\" until v1.1.6\n * @type String\n * @default\n */\n stroke: null,\n\n /**\n * Shadow object representing shadow of this shape.\n * <b>Backwards incompatibility note:</b> This property was named \"textShadow\" (String) until v1.2.11\n * @type fabric.Shadow\n * @default\n */\n shadow: null,\n\n /**\n * @private\n */\n _fontSizeFraction: 0.222,\n\n /**\n * @private\n */\n offsets: {\n underline: 0.10,\n linethrough: -0.315,\n overline: -0.88\n },\n\n /**\n * Text Line proportion to font Size (in pixels)\n * @type Number\n * @default\n */\n _fontSizeMult: 1.13,\n\n /**\n * additional space between characters\n * expressed in thousands of em unit\n * @type Number\n * @default\n */\n charSpacing: 0,\n\n /**\n * Object containing character styles - top-level properties -> line numbers,\n * 2nd-level properties - charater numbers\n * @type Object\n * @default\n */\n styles: null,\n\n /**\n * Reference to a context to measure text char or couple of chars\n * the cacheContext of the canvas will be used or a freshly created one if the object is not on canvas\n * once created it will be referenced on fabric._measuringContext to avoide creating a canvas for every\n * text object created.\n * @type {CanvasRenderingContext2D}\n * @default\n */\n _measuringContext: null,\n\n /**\n * Baseline shift, stlyes only, keep at 0 for the main text object\n * @type {Number}\n * @default\n */\n deltaY: 0,\n\n /**\n * Array of properties that define a style unit (of 'styles').\n * @type {Array}\n * @default\n */\n _styleProperties: ['stroke', 'strokeWidth', 'fill', 'fontFamily', 'fontSize', 'fontWeight', 'fontStyle', 'underline', 'overline', 'linethrough', 'deltaY', 'textBackgroundColor'],\n\n /**\n * contains characters bounding boxes\n */\n __charBounds: [],\n\n /**\n * use this size when measuring text. To avoid IE11 rounding errors\n * @type {Number}\n * @default\n * @readonly\n * @private\n */\n CACHE_FONT_SIZE: 400,\n\n /**\n * contains the min text width to avoid getting 0\n * @type {Number}\n * @default\n */\n MIN_TEXT_WIDTH: 2,\n\n /**\n * Constructor\n * @param {String} text Text string\n * @param {Object} [options] Options object\n * @return {fabric.Text} thisArg\n */\n initialize: function (text, options) {\n this.styles = options ? options.styles || {} : {};\n this.text = text;\n this.__skipDimension = true;\n this.callSuper('initialize', options);\n this.__skipDimension = false;\n this.initDimensions();\n this.setCoords();\n this.setupState({\n propertySet: '_dimensionAffectingProps'\n });\n },\n\n /**\n * Return a contex for measurement of text string.\n * if created it gets stored for reuse\n * @param {String} text Text string\n * @param {Object} [options] Options object\n * @return {fabric.Text} thisArg\n */\n getMeasuringContext: function () {\n // if we did not return we have to measure something.\n if (!fabric._measuringContext) {\n fabric._measuringContext = this.canvas && this.canvas.contextCache || fabric.util.createCanvasElement().getContext('2d');\n }\n\n return fabric._measuringContext;\n },\n\n /**\n * @private\n * Divides text into lines of text and lines of graphemes.\n */\n _splitText: function () {\n var newLines = this._splitTextIntoLines(this.text);\n\n this.textLines = newLines.lines;\n this._textLines = newLines.graphemeLines;\n this._unwrappedTextLines = newLines._unwrappedLines;\n this._text = newLines.graphemeText;\n return newLines;\n },\n\n /**\n * Initialize or update text dimensions.\n * Updates this.width and this.height with the proper values.\n * Does not return dimensions.\n */\n initDimensions: function () {\n if (this.__skipDimension) {\n return;\n }\n\n this._splitText();\n\n this._clearCache();\n\n this.width = this.calcTextWidth() || this.cursorWidth || this.MIN_TEXT_WIDTH;\n\n if (this.textAlign.indexOf('justify') !== -1) {\n // once text is measured we need to make space fatter to make justified text.\n this.enlargeSpaces();\n }\n\n this.height = this.calcTextHeight();\n this.saveState({\n propertySet: '_dimensionAffectingProps'\n });\n },\n\n /**\n * Enlarge space boxes and shift the others\n */\n enlargeSpaces: function () {\n var diffSpace, currentLineWidth, numberOfSpaces, accumulatedSpace, line, charBound, spaces;\n\n for (var i = 0, len = this._textLines.length; i < len; i++) {\n if (this.textAlign !== 'justify' && (i === len - 1 || this.isEndOfWrapping(i))) {\n continue;\n }\n\n accumulatedSpace = 0;\n line = this._textLines[i];\n currentLineWidth = this.getLineWidth(i);\n\n if (currentLineWidth < this.width && (spaces = this.textLines[i].match(this._reSpacesAndTabs))) {\n numberOfSpaces = spaces.length;\n diffSpace = (this.width - currentLineWidth) / numberOfSpaces;\n\n for (var j = 0, jlen = line.length; j <= jlen; j++) {\n charBound = this.__charBounds[i][j];\n\n if (this._reSpaceAndTab.test(line[j])) {\n charBound.width += diffSpace;\n charBound.kernedWidth += diffSpace;\n charBound.left += accumulatedSpace;\n accumulatedSpace += diffSpace;\n } else {\n charBound.left += accumulatedSpace;\n }\n }\n }\n }\n },\n\n /**\n * Detect if the text line is ended with an hard break\n * text and itext do not have wrapping, return false\n * @return {Boolean}\n */\n isEndOfWrapping: function (lineIndex) {\n return lineIndex === this._textLines.length - 1;\n },\n\n /**\n * Detect if a line has a linebreak and so we need to account for it when moving\n * and counting style.\n * It return always for text and Itext.\n * @return Number\n */\n missingNewlineOffset: function () {\n return 1;\n },\n\n /**\n * Returns string representation of an instance\n * @return {String} String representation of text object\n */\n toString: function () {\n return '#<fabric.Text (' + this.complexity() + '): { \"text\": \"' + this.text + '\", \"fontFamily\": \"' + this.fontFamily + '\" }>';\n },\n\n /**\n * Return the dimension and the zoom level needed to create a cache canvas\n * big enough to host the object to be cached.\n * @private\n * @param {Object} dim.x width of object to be cached\n * @param {Object} dim.y height of object to be cached\n * @return {Object}.width width of canvas\n * @return {Object}.height height of canvas\n * @return {Object}.zoomX zoomX zoom value to unscale the canvas before drawing cache\n * @return {Object}.zoomY zoomY zoom value to unscale the canvas before drawing cache\n */\n _getCacheCanvasDimensions: function () {\n var dims = this.callSuper('_getCacheCanvasDimensions');\n var fontSize = this.fontSize;\n dims.width += fontSize * dims.zoomX;\n dims.height += fontSize * dims.zoomY;\n return dims;\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _render: function (ctx) {\n this._setTextStyles(ctx);\n\n this._renderTextLinesBackground(ctx);\n\n this._renderTextDecoration(ctx, 'underline');\n\n this._renderText(ctx);\n\n this._renderTextDecoration(ctx, 'overline');\n\n this._renderTextDecoration(ctx, 'linethrough');\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderText: function (ctx) {\n if (this.paintFirst === 'stroke') {\n this._renderTextStroke(ctx);\n\n this._renderTextFill(ctx);\n } else {\n this._renderTextFill(ctx);\n\n this._renderTextStroke(ctx);\n }\n },\n\n /**\n * Set the font parameter of the context with the object properties or with charStyle\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Object} [charStyle] object with font style properties\n * @param {String} [charStyle.fontFamily] Font Family\n * @param {Number} [charStyle.fontSize] Font size in pixels. ( without px suffix )\n * @param {String} [charStyle.fontWeight] Font weight\n * @param {String} [charStyle.fontStyle] Font style (italic|normal)\n */\n _setTextStyles: function (ctx, charStyle, forMeasuring) {\n ctx.textBaseline = 'alphabetic';\n ctx.font = this._getFontDeclaration(charStyle, forMeasuring);\n },\n\n /**\n * calculate and return the text Width measuring each line.\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @return {Number} Maximum width of fabric.Text object\n */\n calcTextWidth: function () {\n var maxWidth = this.getLineWidth(0);\n\n for (var i = 1, len = this._textLines.length; i < len; i++) {\n var currentLineWidth = this.getLineWidth(i);\n\n if (currentLineWidth > maxWidth) {\n maxWidth = currentLineWidth;\n }\n }\n\n return maxWidth;\n },\n\n /**\n * @private\n * @param {String} method Method name (\"fillText\" or \"strokeText\")\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {String} line Text to render\n * @param {Number} left Left position of text\n * @param {Number} top Top position of text\n * @param {Number} lineIndex Index of a line in a text\n */\n _renderTextLine: function (method, ctx, line, left, top, lineIndex) {\n this._renderChars(method, ctx, line, left, top, lineIndex);\n },\n\n /**\n * Renders the text background for lines, taking care of style\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderTextLinesBackground: function (ctx) {\n if (!this.textBackgroundColor && !this.styleHas('textBackgroundColor')) {\n return;\n }\n\n var lineTopOffset = 0,\n heightOfLine,\n lineLeftOffset,\n originalFill = ctx.fillStyle,\n line,\n lastColor,\n leftOffset = this._getLeftOffset(),\n topOffset = this._getTopOffset(),\n boxStart = 0,\n boxWidth = 0,\n charBox,\n currentColor;\n\n for (var i = 0, len = this._textLines.length; i < len; i++) {\n heightOfLine = this.getHeightOfLine(i);\n\n if (!this.textBackgroundColor && !this.styleHas('textBackgroundColor', i)) {\n lineTopOffset += heightOfLine;\n continue;\n }\n\n line = this._textLines[i];\n lineLeftOffset = this._getLineLeftOffset(i);\n boxWidth = 0;\n boxStart = 0;\n lastColor = this.getValueOfPropertyAt(i, 0, 'textBackgroundColor');\n\n for (var j = 0, jlen = line.length; j < jlen; j++) {\n charBox = this.__charBounds[i][j];\n currentColor = this.getValueOfPropertyAt(i, j, 'textBackgroundColor');\n\n if (currentColor !== lastColor) {\n ctx.fillStyle = lastColor;\n lastColor && ctx.fillRect(leftOffset + lineLeftOffset + boxStart, topOffset + lineTopOffset, boxWidth, heightOfLine / this.lineHeight);\n boxStart = charBox.left;\n boxWidth = charBox.width;\n lastColor = currentColor;\n } else {\n boxWidth += charBox.kernedWidth;\n }\n }\n\n if (currentColor) {\n ctx.fillStyle = currentColor;\n ctx.fillRect(leftOffset + lineLeftOffset + boxStart, topOffset + lineTopOffset, boxWidth, heightOfLine / this.lineHeight);\n }\n\n lineTopOffset += heightOfLine;\n }\n\n ctx.fillStyle = originalFill; // if there is text background color no\n // other shadows should be casted\n\n this._removeShadow(ctx);\n },\n\n /**\n * @private\n * @param {Object} decl style declaration for cache\n * @param {String} decl.fontFamily fontFamily\n * @param {String} decl.fontStyle fontStyle\n * @param {String} decl.fontWeight fontWeight\n * @return {Object} reference to cache\n */\n getFontCache: function (decl) {\n var fontFamily = decl.fontFamily.toLowerCase();\n\n if (!fabric.charWidthsCache[fontFamily]) {\n fabric.charWidthsCache[fontFamily] = {};\n }\n\n var cache = fabric.charWidthsCache[fontFamily],\n cacheProp = decl.fontStyle.toLowerCase() + '_' + (decl.fontWeight + '').toLowerCase();\n\n if (!cache[cacheProp]) {\n cache[cacheProp] = {};\n }\n\n return cache[cacheProp];\n },\n\n /**\n * apply all the character style to canvas for rendering\n * @private\n * @param {String} _char\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @param {Object} [decl]\n */\n _applyCharStyles: function (method, ctx, lineIndex, charIndex, styleDeclaration) {\n this._setFillStyles(ctx, styleDeclaration);\n\n this._setStrokeStyles(ctx, styleDeclaration);\n\n ctx.font = this._getFontDeclaration(styleDeclaration);\n },\n\n /**\n * measure and return the width of a single character.\n * possibly overridden to accommodate different measure logic or\n * to hook some external lib for character measurement\n * @private\n * @param {String} _char, char to be measured\n * @param {Object} charStyle style of char to be measured\n * @param {String} [previousChar] previous char\n * @param {Object} [prevCharStyle] style of previous char\n */\n _measureChar: function (_char, charStyle, previousChar, prevCharStyle) {\n // first i try to return from cache\n var fontCache = this.getFontCache(charStyle),\n fontDeclaration = this._getFontDeclaration(charStyle),\n previousFontDeclaration = this._getFontDeclaration(prevCharStyle),\n couple = previousChar + _char,\n stylesAreEqual = fontDeclaration === previousFontDeclaration,\n width,\n coupleWidth,\n previousWidth,\n fontMultiplier = charStyle.fontSize / this.CACHE_FONT_SIZE,\n kernedWidth;\n\n if (previousChar && fontCache[previousChar] !== undefined) {\n previousWidth = fontCache[previousChar];\n }\n\n if (fontCache[_char] !== undefined) {\n kernedWidth = width = fontCache[_char];\n }\n\n if (stylesAreEqual && fontCache[couple] !== undefined) {\n coupleWidth = fontCache[couple];\n kernedWidth = coupleWidth - previousWidth;\n }\n\n if (width === undefined || previousWidth === undefined || coupleWidth === undefined) {\n var ctx = this.getMeasuringContext(); // send a TRUE to specify measuring font size CACHE_FONT_SIZE\n\n this._setTextStyles(ctx, charStyle, true);\n }\n\n if (width === undefined) {\n kernedWidth = width = ctx.measureText(_char).width;\n fontCache[_char] = width;\n }\n\n if (previousWidth === undefined && stylesAreEqual && previousChar) {\n previousWidth = ctx.measureText(previousChar).width;\n fontCache[previousChar] = previousWidth;\n }\n\n if (stylesAreEqual && coupleWidth === undefined) {\n // we can measure the kerning couple and subtract the width of the previous character\n coupleWidth = ctx.measureText(couple).width;\n fontCache[couple] = coupleWidth;\n kernedWidth = coupleWidth - previousWidth;\n }\n\n return {\n width: width * fontMultiplier,\n kernedWidth: kernedWidth * fontMultiplier\n };\n },\n\n /**\n * Computes height of character at given position\n * @param {Number} line the line index number\n * @param {Number} _char the character index number\n * @return {Number} fontSize of the character\n */\n getHeightOfChar: function (line, _char) {\n return this.getValueOfPropertyAt(line, _char, 'fontSize');\n },\n\n /**\n * measure a text line measuring all characters.\n * @param {Number} lineIndex line number\n * @return {Number} Line width\n */\n measureLine: function (lineIndex) {\n var lineInfo = this._measureLine(lineIndex);\n\n if (this.charSpacing !== 0) {\n lineInfo.width -= this._getWidthOfCharSpacing();\n }\n\n if (lineInfo.width < 0) {\n lineInfo.width = 0;\n }\n\n return lineInfo;\n },\n\n /**\n * measure every grapheme of a line, populating __charBounds\n * @param {Number} lineIndex\n * @return {Object} object.width total width of characters\n * @return {Object} object.widthOfSpaces length of chars that match this._reSpacesAndTabs\n */\n _measureLine: function (lineIndex) {\n var width = 0,\n i,\n grapheme,\n line = this._textLines[lineIndex],\n prevGrapheme,\n graphemeInfo,\n numOfSpaces = 0,\n lineBounds = new Array(line.length);\n this.__charBounds[lineIndex] = lineBounds;\n\n for (i = 0; i < line.length; i++) {\n grapheme = line[i];\n graphemeInfo = this._getGraphemeBox(grapheme, lineIndex, i, prevGrapheme);\n lineBounds[i] = graphemeInfo;\n width += graphemeInfo.kernedWidth;\n prevGrapheme = grapheme;\n } // this latest bound box represent the last character of the line\n // to simplify cursor handling in interactive mode.\n\n\n lineBounds[i] = {\n left: graphemeInfo ? graphemeInfo.left + graphemeInfo.width : 0,\n width: 0,\n kernedWidth: 0,\n height: this.fontSize\n };\n return {\n width: width,\n numOfSpaces: numOfSpaces\n };\n },\n\n /**\n * Measure and return the info of a single grapheme.\n * needs the the info of previous graphemes already filled\n * @private\n * @param {String} grapheme to be measured\n * @param {Number} lineIndex index of the line where the char is\n * @param {Number} charIndex position in the line\n * @param {String} [prevGrapheme] character preceding the one to be measured\n */\n _getGraphemeBox: function (grapheme, lineIndex, charIndex, prevGrapheme, skipLeft) {\n var style = this.getCompleteStyleDeclaration(lineIndex, charIndex),\n prevStyle = prevGrapheme ? this.getCompleteStyleDeclaration(lineIndex, charIndex - 1) : {},\n info = this._measureChar(grapheme, style, prevGrapheme, prevStyle),\n kernedWidth = info.kernedWidth,\n width = info.width,\n charSpacing;\n\n if (this.charSpacing !== 0) {\n charSpacing = this._getWidthOfCharSpacing();\n width += charSpacing;\n kernedWidth += charSpacing;\n }\n\n var box = {\n width: width,\n left: 0,\n height: style.fontSize,\n kernedWidth: kernedWidth,\n deltaY: style.deltaY\n };\n\n if (charIndex > 0 && !skipLeft) {\n var previousBox = this.__charBounds[lineIndex][charIndex - 1];\n box.left = previousBox.left + previousBox.width + info.kernedWidth - info.width;\n }\n\n return box;\n },\n\n /**\n * Calculate height of line at 'lineIndex'\n * @param {Number} lineIndex index of line to calculate\n * @return {Number}\n */\n getHeightOfLine: function (lineIndex) {\n if (this.__lineHeights[lineIndex]) {\n return this.__lineHeights[lineIndex];\n }\n\n var line = this._textLines[lineIndex],\n // char 0 is measured before the line cycle because it nneds to char\n // emptylines\n maxHeight = this.getHeightOfChar(lineIndex, 0);\n\n for (var i = 1, len = line.length; i < len; i++) {\n maxHeight = Math.max(this.getHeightOfChar(lineIndex, i), maxHeight);\n }\n\n return this.__lineHeights[lineIndex] = maxHeight * this.lineHeight * this._fontSizeMult;\n },\n\n /**\n * Calculate text box height\n */\n calcTextHeight: function () {\n var lineHeight,\n height = 0;\n\n for (var i = 0, len = this._textLines.length; i < len; i++) {\n lineHeight = this.getHeightOfLine(i);\n height += i === len - 1 ? lineHeight / this.lineHeight : lineHeight;\n }\n\n return height;\n },\n\n /**\n * @private\n * @return {Number} Left offset\n */\n _getLeftOffset: function () {\n return -this.width / 2;\n },\n\n /**\n * @private\n * @return {Number} Top offset\n */\n _getTopOffset: function () {\n return -this.height / 2;\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {String} method Method name (\"fillText\" or \"strokeText\")\n */\n _renderTextCommon: function (ctx, method) {\n ctx.save();\n\n var lineHeights = 0,\n left = this._getLeftOffset(),\n top = this._getTopOffset(),\n offsets = this._applyPatternGradientTransform(ctx, method === 'fillText' ? this.fill : this.stroke);\n\n for (var i = 0, len = this._textLines.length; i < len; i++) {\n var heightOfLine = this.getHeightOfLine(i),\n maxHeight = heightOfLine / this.lineHeight,\n leftOffset = this._getLineLeftOffset(i);\n\n this._renderTextLine(method, ctx, this._textLines[i], left + leftOffset - offsets.offsetX, top + lineHeights + maxHeight - offsets.offsetY, i);\n\n lineHeights += heightOfLine;\n }\n\n ctx.restore();\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderTextFill: function (ctx) {\n if (!this.fill && !this.styleHas('fill')) {\n return;\n }\n\n this._renderTextCommon(ctx, 'fillText');\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderTextStroke: function (ctx) {\n if ((!this.stroke || this.strokeWidth === 0) && this.isEmptyStyles()) {\n return;\n }\n\n if (this.shadow && !this.shadow.affectStroke) {\n this._removeShadow(ctx);\n }\n\n ctx.save();\n\n this._setLineDash(ctx, this.strokeDashArray);\n\n ctx.beginPath();\n\n this._renderTextCommon(ctx, 'strokeText');\n\n ctx.closePath();\n ctx.restore();\n },\n\n /**\n * @private\n * @param {String} method fillText or strokeText.\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Array} line Content of the line, splitted in an array by grapheme\n * @param {Number} left\n * @param {Number} top\n * @param {Number} lineIndex\n */\n _renderChars: function (method, ctx, line, left, top, lineIndex) {\n // set proper line offset\n var lineHeight = this.getHeightOfLine(lineIndex),\n isJustify = this.textAlign.indexOf('justify') !== -1,\n actualStyle,\n nextStyle,\n charsToRender = '',\n charBox,\n boxWidth = 0,\n timeToRender,\n shortCut = !isJustify && this.charSpacing === 0 && this.isEmptyStyles(lineIndex);\n ctx.save();\n top -= lineHeight * this._fontSizeFraction / this.lineHeight;\n\n if (shortCut) {\n // render all the line in one pass without checking\n this._renderChar(method, ctx, lineIndex, 0, line.join(''), left, top, lineHeight);\n\n ctx.restore();\n return;\n }\n\n for (var i = 0, len = line.length - 1; i <= len; i++) {\n timeToRender = i === len || this.charSpacing;\n charsToRender += line[i];\n charBox = this.__charBounds[lineIndex][i];\n\n if (boxWidth === 0) {\n left += charBox.kernedWidth - charBox.width;\n boxWidth += charBox.width;\n } else {\n boxWidth += charBox.kernedWidth;\n }\n\n if (isJustify && !timeToRender) {\n if (this._reSpaceAndTab.test(line[i])) {\n timeToRender = true;\n }\n }\n\n if (!timeToRender) {\n // if we have charSpacing, we render char by char\n actualStyle = actualStyle || this.getCompleteStyleDeclaration(lineIndex, i);\n nextStyle = this.getCompleteStyleDeclaration(lineIndex, i + 1);\n timeToRender = this._hasStyleChanged(actualStyle, nextStyle);\n }\n\n if (timeToRender) {\n this._renderChar(method, ctx, lineIndex, i, charsToRender, left, top, lineHeight);\n\n charsToRender = '';\n actualStyle = nextStyle;\n left += boxWidth;\n boxWidth = 0;\n }\n }\n\n ctx.restore();\n },\n\n /**\n * @private\n * @param {String} method\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @param {String} _char\n * @param {Number} left Left coordinate\n * @param {Number} top Top coordinate\n * @param {Number} lineHeight Height of the line\n */\n _renderChar: function (method, ctx, lineIndex, charIndex, _char, left, top) {\n var decl = this._getStyleDeclaration(lineIndex, charIndex),\n fullDecl = this.getCompleteStyleDeclaration(lineIndex, charIndex),\n shouldFill = method === 'fillText' && fullDecl.fill,\n shouldStroke = method === 'strokeText' && fullDecl.stroke && fullDecl.strokeWidth;\n\n if (!shouldStroke && !shouldFill) {\n return;\n }\n\n decl && ctx.save();\n\n this._applyCharStyles(method, ctx, lineIndex, charIndex, fullDecl);\n\n if (decl && decl.textBackgroundColor) {\n this._removeShadow(ctx);\n }\n\n if (decl && decl.deltaY) {\n top += decl.deltaY;\n }\n\n shouldFill && ctx.fillText(_char, left, top);\n shouldStroke && ctx.strokeText(_char, left, top);\n decl && ctx.restore();\n },\n\n /**\n * Turns the character into a 'superior figure' (i.e. 'superscript')\n * @param {Number} start selection start\n * @param {Number} end selection end\n * @returns {fabric.Text} thisArg\n * @chainable\n */\n setSuperscript: function (start, end) {\n return this._setScript(start, end, this.superscript);\n },\n\n /**\n * Turns the character into an 'inferior figure' (i.e. 'subscript')\n * @param {Number} start selection start\n * @param {Number} end selection end\n * @returns {fabric.Text} thisArg\n * @chainable\n */\n setSubscript: function (start, end) {\n return this._setScript(start, end, this.subscript);\n },\n\n /**\n * Applies 'schema' at given position\n * @private\n * @param {Number} start selection start\n * @param {Number} end selection end\n * @param {Number} schema\n * @returns {fabric.Text} thisArg\n * @chainable\n */\n _setScript: function (start, end, schema) {\n var loc = this.get2DCursorLocation(start, true),\n fontSize = this.getValueOfPropertyAt(loc.lineIndex, loc.charIndex, 'fontSize'),\n dy = this.getValueOfPropertyAt(loc.lineIndex, loc.charIndex, 'deltaY'),\n style = {\n fontSize: fontSize * schema.size,\n deltaY: dy + fontSize * schema.baseline\n };\n this.setSelectionStyles(style, start, end);\n return this;\n },\n\n /**\n * @private\n * @param {Object} prevStyle\n * @param {Object} thisStyle\n */\n _hasStyleChanged: function (prevStyle, thisStyle) {\n return prevStyle.fill !== thisStyle.fill || prevStyle.stroke !== thisStyle.stroke || prevStyle.strokeWidth !== thisStyle.strokeWidth || prevStyle.fontSize !== thisStyle.fontSize || prevStyle.fontFamily !== thisStyle.fontFamily || prevStyle.fontWeight !== thisStyle.fontWeight || prevStyle.fontStyle !== thisStyle.fontStyle || prevStyle.deltaY !== thisStyle.deltaY;\n },\n\n /**\n * @private\n * @param {Object} prevStyle\n * @param {Object} thisStyle\n */\n _hasStyleChangedForSvg: function (prevStyle, thisStyle) {\n return this._hasStyleChanged(prevStyle, thisStyle) || prevStyle.overline !== thisStyle.overline || prevStyle.underline !== thisStyle.underline || prevStyle.linethrough !== thisStyle.linethrough;\n },\n\n /**\n * @private\n * @param {Number} lineIndex index text line\n * @return {Number} Line left offset\n */\n _getLineLeftOffset: function (lineIndex) {\n var lineWidth = this.getLineWidth(lineIndex);\n\n if (this.textAlign === 'center') {\n return (this.width - lineWidth) / 2;\n }\n\n if (this.textAlign === 'right') {\n return this.width - lineWidth;\n }\n\n if (this.textAlign === 'justify-center' && this.isEndOfWrapping(lineIndex)) {\n return (this.width - lineWidth) / 2;\n }\n\n if (this.textAlign === 'justify-right' && this.isEndOfWrapping(lineIndex)) {\n return this.width - lineWidth;\n }\n\n return 0;\n },\n\n /**\n * @private\n */\n _clearCache: function () {\n this.__lineWidths = [];\n this.__lineHeights = [];\n this.__charBounds = [];\n },\n\n /**\n * @private\n */\n _shouldClearDimensionCache: function () {\n var shouldClear = this._forceClearCache;\n shouldClear || (shouldClear = this.hasStateChanged('_dimensionAffectingProps'));\n\n if (shouldClear) {\n this.dirty = true;\n this._forceClearCache = false;\n }\n\n return shouldClear;\n },\n\n /**\n * Measure a single line given its index. Used to calculate the initial\n * text bounding box. The values are calculated and stored in __lineWidths cache.\n * @private\n * @param {Number} lineIndex line number\n * @return {Number} Line width\n */\n getLineWidth: function (lineIndex) {\n if (this.__lineWidths[lineIndex]) {\n return this.__lineWidths[lineIndex];\n }\n\n var width,\n line = this._textLines[lineIndex],\n lineInfo;\n\n if (line === '') {\n width = 0;\n } else {\n lineInfo = this.measureLine(lineIndex);\n width = lineInfo.width;\n }\n\n this.__lineWidths[lineIndex] = width;\n return width;\n },\n _getWidthOfCharSpacing: function () {\n if (this.charSpacing !== 0) {\n return this.fontSize * this.charSpacing / 1000;\n }\n\n return 0;\n },\n\n /**\n * Retrieves the value of property at given character position\n * @param {Number} lineIndex the line number\n * @param {Number} charIndex the charater number\n * @param {String} property the property name\n * @returns the value of 'property'\n */\n getValueOfPropertyAt: function (lineIndex, charIndex, property) {\n var charStyle = this._getStyleDeclaration(lineIndex, charIndex);\n\n if (charStyle && typeof charStyle[property] !== 'undefined') {\n return charStyle[property];\n }\n\n return this[property];\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderTextDecoration: function (ctx, type) {\n if (!this[type] && !this.styleHas(type)) {\n return;\n }\n\n var heightOfLine,\n size,\n _size,\n lineLeftOffset,\n dy,\n _dy,\n line,\n lastDecoration,\n leftOffset = this._getLeftOffset(),\n topOffset = this._getTopOffset(),\n top,\n boxStart,\n boxWidth,\n charBox,\n currentDecoration,\n maxHeight,\n currentFill,\n lastFill,\n charSpacing = this._getWidthOfCharSpacing();\n\n for (var i = 0, len = this._textLines.length; i < len; i++) {\n heightOfLine = this.getHeightOfLine(i);\n\n if (!this[type] && !this.styleHas(type, i)) {\n topOffset += heightOfLine;\n continue;\n }\n\n line = this._textLines[i];\n maxHeight = heightOfLine / this.lineHeight;\n lineLeftOffset = this._getLineLeftOffset(i);\n boxStart = 0;\n boxWidth = 0;\n lastDecoration = this.getValueOfPropertyAt(i, 0, type);\n lastFill = this.getValueOfPropertyAt(i, 0, 'fill');\n top = topOffset + maxHeight * (1 - this._fontSizeFraction);\n size = this.getHeightOfChar(i, 0);\n dy = this.getValueOfPropertyAt(i, 0, 'deltaY');\n\n for (var j = 0, jlen = line.length; j < jlen; j++) {\n charBox = this.__charBounds[i][j];\n currentDecoration = this.getValueOfPropertyAt(i, j, type);\n currentFill = this.getValueOfPropertyAt(i, j, 'fill');\n _size = this.getHeightOfChar(i, j);\n _dy = this.getValueOfPropertyAt(i, j, 'deltaY');\n\n if ((currentDecoration !== lastDecoration || currentFill !== lastFill || _size !== size || _dy !== dy) && boxWidth > 0) {\n ctx.fillStyle = lastFill;\n lastDecoration && lastFill && ctx.fillRect(leftOffset + lineLeftOffset + boxStart, top + this.offsets[type] * size + dy, boxWidth, this.fontSize / 15);\n boxStart = charBox.left;\n boxWidth = charBox.width;\n lastDecoration = currentDecoration;\n lastFill = currentFill;\n size = _size;\n dy = _dy;\n } else {\n boxWidth += charBox.kernedWidth;\n }\n }\n\n ctx.fillStyle = currentFill;\n currentDecoration && currentFill && ctx.fillRect(leftOffset + lineLeftOffset + boxStart, top + this.offsets[type] * size + dy, boxWidth - charSpacing, this.fontSize / 15);\n topOffset += heightOfLine;\n } // if there is text background color no\n // other shadows should be casted\n\n\n this._removeShadow(ctx);\n },\n\n /**\n * return font declaration string for canvas context\n * @param {Object} [styleObject] object\n * @returns {String} font declaration formatted for canvas context.\n */\n _getFontDeclaration: function (styleObject, forMeasuring) {\n var style = styleObject || this,\n family = this.fontFamily,\n fontIsGeneric = fabric.Text.genericFonts.indexOf(family.toLowerCase()) > -1;\n var fontFamily = family === undefined || family.indexOf('\\'') > -1 || family.indexOf(',') > -1 || family.indexOf('\"') > -1 || fontIsGeneric ? style.fontFamily : '\"' + style.fontFamily + '\"';\n return [// node-canvas needs \"weight style\", while browsers need \"style weight\"\n // verify if this can be fixed in JSDOM\n fabric.isLikelyNode ? style.fontWeight : style.fontStyle, fabric.isLikelyNode ? style.fontStyle : style.fontWeight, forMeasuring ? this.CACHE_FONT_SIZE + 'px' : style.fontSize + 'px', fontFamily].join(' ');\n },\n\n /**\n * Renders text instance on a specified context\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n render: function (ctx) {\n // do not render if object is not visible\n if (!this.visible) {\n return;\n }\n\n if (this.canvas && this.canvas.skipOffscreen && !this.group && !this.isOnScreen()) {\n return;\n }\n\n if (this._shouldClearDimensionCache()) {\n this.initDimensions();\n }\n\n this.callSuper('render', ctx);\n },\n\n /**\n * Returns the text as an array of lines.\n * @param {String} text text to split\n * @returns {Array} Lines in the text\n */\n _splitTextIntoLines: function (text) {\n var lines = text.split(this._reNewline),\n newLines = new Array(lines.length),\n newLine = ['\\n'],\n newText = [];\n\n for (var i = 0; i < lines.length; i++) {\n newLines[i] = fabric.util.string.graphemeSplit(lines[i]);\n newText = newText.concat(newLines[i], newLine);\n }\n\n newText.pop();\n return {\n _unwrappedLines: newLines,\n lines: lines,\n graphemeText: newText,\n graphemeLines: newLines\n };\n },\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} Object representation of an instance\n */\n toObject: function (propertiesToInclude) {\n var additionalProperties = ['text', 'fontSize', 'fontWeight', 'fontFamily', 'fontStyle', 'lineHeight', 'underline', 'overline', 'linethrough', 'textAlign', 'textBackgroundColor', 'charSpacing'].concat(propertiesToInclude);\n var obj = this.callSuper('toObject', additionalProperties);\n obj.styles = clone(this.styles, true);\n return obj;\n },\n\n /**\n * Sets property to a given value. When changing position/dimension -related properties (left, top, scale, angle, etc.) `set` does not update position of object's borders/controls. If you need to update those, call `setCoords()`.\n * @param {String|Object} key Property name or object (if object, iterate over the object properties)\n * @param {Object|Function} value Property value (if function, the value is passed into it and its return value is used as a new one)\n * @return {fabric.Object} thisArg\n * @chainable\n */\n set: function (key, value) {\n this.callSuper('set', key, value);\n var needsDims = false;\n\n if (typeof key === 'object') {\n for (var _key in key) {\n needsDims = needsDims || this._dimensionAffectingProps.indexOf(_key) !== -1;\n }\n } else {\n needsDims = this._dimensionAffectingProps.indexOf(key) !== -1;\n }\n\n if (needsDims) {\n this.initDimensions();\n this.setCoords();\n }\n\n return this;\n },\n\n /**\n * Returns complexity of an instance\n * @return {Number} complexity\n */\n complexity: function () {\n return 1;\n }\n });\n /* _FROM_SVG_START_ */\n\n /**\n * List of attribute names to account for when parsing SVG element (used by {@link fabric.Text.fromElement})\n * @static\n * @memberOf fabric.Text\n * @see: http://www.w3.org/TR/SVG/text.html#TextElement\n */\n\n fabric.Text.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat('x y dx dy font-family font-style font-weight font-size letter-spacing text-decoration text-anchor'.split(' '));\n /**\n * Default SVG font size\n * @static\n * @memberOf fabric.Text\n */\n\n fabric.Text.DEFAULT_SVG_FONT_SIZE = 16;\n /**\n * Returns fabric.Text instance from an SVG element (<b>not yet implemented</b>)\n * @static\n * @memberOf fabric.Text\n * @param {SVGElement} element Element to parse\n * @param {Function} callback callback function invoked after parsing\n * @param {Object} [options] Options object\n */\n\n fabric.Text.fromElement = function (element, callback, options) {\n if (!element) {\n return callback(null);\n }\n\n var parsedAttributes = fabric.parseAttributes(element, fabric.Text.ATTRIBUTE_NAMES),\n parsedAnchor = parsedAttributes.textAnchor || 'left';\n options = fabric.util.object.extend(options ? clone(options) : {}, parsedAttributes);\n options.top = options.top || 0;\n options.left = options.left || 0;\n\n if (parsedAttributes.textDecoration) {\n var textDecoration = parsedAttributes.textDecoration;\n\n if (textDecoration.indexOf('underline') !== -1) {\n options.underline = true;\n }\n\n if (textDecoration.indexOf('overline') !== -1) {\n options.overline = true;\n }\n\n if (textDecoration.indexOf('line-through') !== -1) {\n options.linethrough = true;\n }\n\n delete options.textDecoration;\n }\n\n if ('dx' in parsedAttributes) {\n options.left += parsedAttributes.dx;\n }\n\n if ('dy' in parsedAttributes) {\n options.top += parsedAttributes.dy;\n }\n\n if (!('fontSize' in options)) {\n options.fontSize = fabric.Text.DEFAULT_SVG_FONT_SIZE;\n }\n\n var textContent = ''; // The XML is not properly parsed in IE9 so a workaround to get\n // textContent is through firstChild.data. Another workaround would be\n // to convert XML loaded from a file to be converted using DOMParser (same way loadSVGFromString() does)\n\n if (!('textContent' in element)) {\n if ('firstChild' in element && element.firstChild !== null) {\n if ('data' in element.firstChild && element.firstChild.data !== null) {\n textContent = element.firstChild.data;\n }\n }\n } else {\n textContent = element.textContent;\n }\n\n textContent = textContent.replace(/^\\s+|\\s+$|\\n+/g, '').replace(/\\s+/g, ' ');\n var originalStrokeWidth = options.strokeWidth;\n options.strokeWidth = 0;\n var text = new fabric.Text(textContent, options),\n textHeightScaleFactor = text.getScaledHeight() / text.height,\n lineHeightDiff = (text.height + text.strokeWidth) * text.lineHeight - text.height,\n scaledDiff = lineHeightDiff * textHeightScaleFactor,\n textHeight = text.getScaledHeight() + scaledDiff,\n offX = 0;\n /*\n Adjust positioning:\n x/y attributes in SVG correspond to the bottom-left corner of text bounding box\n fabric output by default at top, left.\n */\n\n if (parsedAnchor === 'center') {\n offX = text.getScaledWidth() / 2;\n }\n\n if (parsedAnchor === 'right') {\n offX = text.getScaledWidth();\n }\n\n text.set({\n left: text.left - offX,\n top: text.top - (textHeight - text.fontSize * (0.07 + text._fontSizeFraction)) / text.lineHeight,\n strokeWidth: typeof originalStrokeWidth !== 'undefined' ? originalStrokeWidth : 1\n });\n callback(text);\n };\n /* _FROM_SVG_END_ */\n\n /**\n * Returns fabric.Text instance from an object representation\n * @static\n * @memberOf fabric.Text\n * @param {Object} object Object to create an instance from\n * @param {Function} [callback] Callback to invoke when an fabric.Text instance is created\n */\n\n\n fabric.Text.fromObject = function (object, callback) {\n return fabric.Object._fromObject('Text', object, callback, 'text');\n };\n\n fabric.Text.genericFonts = ['sans-serif', 'serif', 'cursive', 'fantasy', 'monospace'];\n fabric.util.createAccessors && fabric.util.createAccessors(fabric.Text);\n})(typeof exports !== 'undefined' ? exports : this);\n\n(function () {\n fabric.util.object.extend(fabric.Text.prototype,\n /** @lends fabric.Text.prototype */\n {\n /**\n * Returns true if object has no styling or no styling in a line\n * @param {Number} lineIndex , lineIndex is on wrapped lines.\n * @return {Boolean}\n */\n isEmptyStyles: function (lineIndex) {\n if (!this.styles) {\n return true;\n }\n\n if (typeof lineIndex !== 'undefined' && !this.styles[lineIndex]) {\n return true;\n }\n\n var obj = typeof lineIndex === 'undefined' ? this.styles : {\n line: this.styles[lineIndex]\n };\n\n for (var p1 in obj) {\n for (var p2 in obj[p1]) {\n // eslint-disable-next-line no-unused-vars\n for (var p3 in obj[p1][p2]) {\n return false;\n }\n }\n }\n\n return true;\n },\n\n /**\n * Returns true if object has a style property or has it ina specified line\n * This function is used to detect if a text will use a particular property or not.\n * @param {String} property to check for\n * @param {Number} lineIndex to check the style on\n * @return {Boolean}\n */\n styleHas: function (property, lineIndex) {\n if (!this.styles || !property || property === '') {\n return false;\n }\n\n if (typeof lineIndex !== 'undefined' && !this.styles[lineIndex]) {\n return false;\n }\n\n var obj = typeof lineIndex === 'undefined' ? this.styles : {\n 0: this.styles[lineIndex]\n }; // eslint-disable-next-line\n\n for (var p1 in obj) {\n // eslint-disable-next-line\n for (var p2 in obj[p1]) {\n if (typeof obj[p1][p2][property] !== 'undefined') {\n return true;\n }\n }\n }\n\n return false;\n },\n\n /**\n * Check if characters in a text have a value for a property\n * whose value matches the textbox's value for that property. If so,\n * the character-level property is deleted. If the character\n * has no other properties, then it is also deleted. Finally,\n * if the line containing that character has no other characters\n * then it also is deleted.\n *\n * @param {string} property The property to compare between characters and text.\n */\n cleanStyle: function (property) {\n if (!this.styles || !property || property === '') {\n return false;\n }\n\n var obj = this.styles,\n stylesCount = 0,\n letterCount,\n stylePropertyValue,\n allStyleObjectPropertiesMatch = true,\n graphemeCount = 0,\n styleObject; // eslint-disable-next-line\n\n for (var p1 in obj) {\n letterCount = 0; // eslint-disable-next-line\n\n for (var p2 in obj[p1]) {\n var styleObject = obj[p1][p2],\n stylePropertyHasBeenSet = styleObject.hasOwnProperty(property);\n stylesCount++;\n\n if (stylePropertyHasBeenSet) {\n if (!stylePropertyValue) {\n stylePropertyValue = styleObject[property];\n } else if (styleObject[property] !== stylePropertyValue) {\n allStyleObjectPropertiesMatch = false;\n }\n\n if (styleObject[property] === this[property]) {\n delete styleObject[property];\n }\n } else {\n allStyleObjectPropertiesMatch = false;\n }\n\n if (Object.keys(styleObject).length !== 0) {\n letterCount++;\n } else {\n delete obj[p1][p2];\n }\n }\n\n if (letterCount === 0) {\n delete obj[p1];\n }\n } // if every grapheme has the same style set then\n // delete those styles and set it on the parent\n\n\n for (var i = 0; i < this._textLines.length; i++) {\n graphemeCount += this._textLines[i].length;\n }\n\n if (allStyleObjectPropertiesMatch && stylesCount === graphemeCount) {\n this[property] = stylePropertyValue;\n this.removeStyle(property);\n }\n },\n\n /**\n * Remove a style property or properties from all individual character styles\n * in a text object. Deletes the character style object if it contains no other style\n * props. Deletes a line style object if it contains no other character styles.\n *\n * @param {String} props The property to remove from character styles.\n */\n removeStyle: function (property) {\n if (!this.styles || !property || property === '') {\n return;\n }\n\n var obj = this.styles,\n line,\n lineNum,\n charNum;\n\n for (lineNum in obj) {\n line = obj[lineNum];\n\n for (charNum in line) {\n delete line[charNum][property];\n\n if (Object.keys(line[charNum]).length === 0) {\n delete line[charNum];\n }\n }\n\n if (Object.keys(line).length === 0) {\n delete obj[lineNum];\n }\n }\n },\n\n /**\n * @private\n */\n _extendStyles: function (index, styles) {\n var loc = this.get2DCursorLocation(index);\n\n if (!this._getLineStyle(loc.lineIndex)) {\n this._setLineStyle(loc.lineIndex);\n }\n\n if (!this._getStyleDeclaration(loc.lineIndex, loc.charIndex)) {\n this._setStyleDeclaration(loc.lineIndex, loc.charIndex, {});\n }\n\n fabric.util.object.extend(this._getStyleDeclaration(loc.lineIndex, loc.charIndex), styles);\n },\n\n /**\n * Returns 2d representation (lineIndex and charIndex) of cursor (or selection start)\n * @param {Number} [selectionStart] Optional index. When not given, current selectionStart is used.\n * @param {Boolean} [skipWrapping] consider the location for unwrapped lines. useful to manage styles.\n */\n get2DCursorLocation: function (selectionStart, skipWrapping) {\n if (typeof selectionStart === 'undefined') {\n selectionStart = this.selectionStart;\n }\n\n var lines = skipWrapping ? this._unwrappedTextLines : this._textLines,\n len = lines.length;\n\n for (var i = 0; i < len; i++) {\n if (selectionStart <= lines[i].length) {\n return {\n lineIndex: i,\n charIndex: selectionStart\n };\n }\n\n selectionStart -= lines[i].length + this.missingNewlineOffset(i);\n }\n\n return {\n lineIndex: i - 1,\n charIndex: lines[i - 1].length < selectionStart ? lines[i - 1].length : selectionStart\n };\n },\n\n /**\n * Gets style of a current selection/cursor (at the start position)\n * if startIndex or endIndex are not provided, slectionStart or selectionEnd will be used.\n * @param {Number} [startIndex] Start index to get styles at\n * @param {Number} [endIndex] End index to get styles at, if not specified selectionEnd or startIndex + 1\n * @param {Boolean} [complete] get full style or not\n * @return {Array} styles an array with one, zero or more Style objects\n */\n getSelectionStyles: function (startIndex, endIndex, complete) {\n if (typeof startIndex === 'undefined') {\n startIndex = this.selectionStart || 0;\n }\n\n if (typeof endIndex === 'undefined') {\n endIndex = this.selectionEnd || startIndex;\n }\n\n var styles = [];\n\n for (var i = startIndex; i < endIndex; i++) {\n styles.push(this.getStyleAtPosition(i, complete));\n }\n\n return styles;\n },\n\n /**\n * Gets style of a current selection/cursor position\n * @param {Number} position to get styles at\n * @param {Boolean} [complete] full style if true\n * @return {Object} style Style object at a specified index\n * @private\n */\n getStyleAtPosition: function (position, complete) {\n var loc = this.get2DCursorLocation(position),\n style = complete ? this.getCompleteStyleDeclaration(loc.lineIndex, loc.charIndex) : this._getStyleDeclaration(loc.lineIndex, loc.charIndex);\n return style || {};\n },\n\n /**\n * Sets style of a current selection, if no selection exist, do not set anything.\n * @param {Object} [styles] Styles object\n * @param {Number} [startIndex] Start index to get styles at\n * @param {Number} [endIndex] End index to get styles at, if not specified selectionEnd or startIndex + 1\n * @return {fabric.IText} thisArg\n * @chainable\n */\n setSelectionStyles: function (styles, startIndex, endIndex) {\n if (typeof startIndex === 'undefined') {\n startIndex = this.selectionStart || 0;\n }\n\n if (typeof endIndex === 'undefined') {\n endIndex = this.selectionEnd || startIndex;\n }\n\n for (var i = startIndex; i < endIndex; i++) {\n this._extendStyles(i, styles);\n }\n /* not included in _extendStyles to avoid clearing cache more than once */\n\n\n this._forceClearCache = true;\n return this;\n },\n\n /**\n * get the reference, not a clone, of the style object for a given character\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @return {Object} style object\n */\n _getStyleDeclaration: function (lineIndex, charIndex) {\n var lineStyle = this.styles && this.styles[lineIndex];\n\n if (!lineStyle) {\n return null;\n }\n\n return lineStyle[charIndex];\n },\n\n /**\n * return a new object that contains all the style property for a character\n * the object returned is newly created\n * @param {Number} lineIndex of the line where the character is\n * @param {Number} charIndex position of the character on the line\n * @return {Object} style object\n */\n getCompleteStyleDeclaration: function (lineIndex, charIndex) {\n var style = this._getStyleDeclaration(lineIndex, charIndex) || {},\n styleObject = {},\n prop;\n\n for (var i = 0; i < this._styleProperties.length; i++) {\n prop = this._styleProperties[i];\n styleObject[prop] = typeof style[prop] === 'undefined' ? this[prop] : style[prop];\n }\n\n return styleObject;\n },\n\n /**\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @param {Object} style\n * @private\n */\n _setStyleDeclaration: function (lineIndex, charIndex, style) {\n this.styles[lineIndex][charIndex] = style;\n },\n\n /**\n *\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @private\n */\n _deleteStyleDeclaration: function (lineIndex, charIndex) {\n delete this.styles[lineIndex][charIndex];\n },\n\n /**\n * @param {Number} lineIndex\n * @return {Boolean} if the line exists or not\n * @private\n */\n _getLineStyle: function (lineIndex) {\n return !!this.styles[lineIndex];\n },\n\n /**\n * Set the line style to an empty object so that is initialized\n * @param {Number} lineIndex\n * @private\n */\n _setLineStyle: function (lineIndex) {\n this.styles[lineIndex] = {};\n },\n\n /**\n * @param {Number} lineIndex\n * @private\n */\n _deleteLineStyle: function (lineIndex) {\n delete this.styles[lineIndex];\n }\n });\n})();\n\n(function () {\n function parseDecoration(object) {\n if (object.textDecoration) {\n object.textDecoration.indexOf('underline') > -1 && (object.underline = true);\n object.textDecoration.indexOf('line-through') > -1 && (object.linethrough = true);\n object.textDecoration.indexOf('overline') > -1 && (object.overline = true);\n delete object.textDecoration;\n }\n }\n /**\n * IText class (introduced in <b>v1.4</b>) Events are also fired with \"text:\"\n * prefix when observing canvas.\n * @class fabric.IText\n * @extends fabric.Text\n * @mixes fabric.Observable\n *\n * @fires changed\n * @fires selection:changed\n * @fires editing:entered\n * @fires editing:exited\n *\n * @return {fabric.IText} thisArg\n * @see {@link fabric.IText#initialize} for constructor definition\n *\n * <p>Supported key combinations:</p>\n * <pre>\n * Move cursor: left, right, up, down\n * Select character: shift + left, shift + right\n * Select text vertically: shift + up, shift + down\n * Move cursor by word: alt + left, alt + right\n * Select words: shift + alt + left, shift + alt + right\n * Move cursor to line start/end: cmd + left, cmd + right or home, end\n * Select till start/end of line: cmd + shift + left, cmd + shift + right or shift + home, shift + end\n * Jump to start/end of text: cmd + up, cmd + down\n * Select till start/end of text: cmd + shift + up, cmd + shift + down or shift + pgUp, shift + pgDown\n * Delete character: backspace\n * Delete word: alt + backspace\n * Delete line: cmd + backspace\n * Forward delete: delete\n * Copy text: ctrl/cmd + c\n * Paste text: ctrl/cmd + v\n * Cut text: ctrl/cmd + x\n * Select entire text: ctrl/cmd + a\n * Quit editing tab or esc\n * </pre>\n *\n * <p>Supported mouse/touch combination</p>\n * <pre>\n * Position cursor: click/touch\n * Create selection: click/touch & drag\n * Create selection: click & shift + click\n * Select word: double click\n * Select line: triple click\n * </pre>\n */\n\n\n fabric.IText = fabric.util.createClass(fabric.Text, fabric.Observable,\n /** @lends fabric.IText.prototype */\n {\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'i-text',\n\n /**\n * Index where text selection starts (or where cursor is when there is no selection)\n * @type Number\n * @default\n */\n selectionStart: 0,\n\n /**\n * Index where text selection ends\n * @type Number\n * @default\n */\n selectionEnd: 0,\n\n /**\n * Color of text selection\n * @type String\n * @default\n */\n selectionColor: 'rgba(17,119,255,0.3)',\n\n /**\n * Indicates whether text is in editing mode\n * @type Boolean\n * @default\n */\n isEditing: false,\n\n /**\n * Indicates whether a text can be edited\n * @type Boolean\n * @default\n */\n editable: true,\n\n /**\n * Border color of text object while it's in editing mode\n * @type String\n * @default\n */\n editingBorderColor: 'rgba(102,153,255,0.25)',\n\n /**\n * Width of cursor (in px)\n * @type Number\n * @default\n */\n cursorWidth: 2,\n\n /**\n * Color of text cursor color in editing mode.\n * if not set (default) will take color from the text.\n * if set to a color value that fabric can understand, it will\n * be used instead of the color of the text at the current position.\n * @type String\n * @default\n */\n cursorColor: '',\n\n /**\n * Delay between cursor blink (in ms)\n * @type Number\n * @default\n */\n cursorDelay: 1000,\n\n /**\n * Duration of cursor fadein (in ms)\n * @type Number\n * @default\n */\n cursorDuration: 600,\n\n /**\n * Indicates whether internal text char widths can be cached\n * @type Boolean\n * @default\n */\n caching: true,\n\n /**\n * @private\n */\n _reSpace: /\\s|\\n/,\n\n /**\n * @private\n */\n _currentCursorOpacity: 0,\n\n /**\n * @private\n */\n _selectionDirection: null,\n\n /**\n * @private\n */\n _abortCursorAnimation: false,\n\n /**\n * @private\n */\n __widthOfSpace: [],\n\n /**\n * Helps determining when the text is in composition, so that the cursor\n * rendering is altered.\n */\n inCompositionMode: false,\n\n /**\n * Constructor\n * @param {String} text Text string\n * @param {Object} [options] Options object\n * @return {fabric.IText} thisArg\n */\n initialize: function (text, options) {\n this.callSuper('initialize', text, options);\n this.initBehavior();\n },\n\n /**\n * Sets selection start (left boundary of a selection)\n * @param {Number} index Index to set selection start to\n */\n setSelectionStart: function (index) {\n index = Math.max(index, 0);\n\n this._updateAndFire('selectionStart', index);\n },\n\n /**\n * Sets selection end (right boundary of a selection)\n * @param {Number} index Index to set selection end to\n */\n setSelectionEnd: function (index) {\n index = Math.min(index, this.text.length);\n\n this._updateAndFire('selectionEnd', index);\n },\n\n /**\n * @private\n * @param {String} property 'selectionStart' or 'selectionEnd'\n * @param {Number} index new position of property\n */\n _updateAndFire: function (property, index) {\n if (this[property] !== index) {\n this._fireSelectionChanged();\n\n this[property] = index;\n }\n\n this._updateTextarea();\n },\n\n /**\n * Fires the even of selection changed\n * @private\n */\n _fireSelectionChanged: function () {\n this.fire('selection:changed');\n this.canvas && this.canvas.fire('text:selection:changed', {\n target: this\n });\n },\n\n /**\n * Initialize text dimensions. Render all text on given context\n * or on a offscreen canvas to get the text width with measureText.\n * Updates this.width and this.height with the proper values.\n * Does not return dimensions.\n * @private\n */\n initDimensions: function () {\n this.isEditing && this.initDelayedCursor();\n this.clearContextTop();\n this.callSuper('initDimensions');\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n render: function (ctx) {\n this.clearContextTop();\n this.callSuper('render', ctx); // clear the cursorOffsetCache, so we ensure to calculate once per renderCursor\n // the correct position but not at every cursor animation.\n\n this.cursorOffsetCache = {};\n this.renderCursorOrSelection();\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _render: function (ctx) {\n this.callSuper('_render', ctx);\n },\n\n /**\n * Prepare and clean the contextTop\n */\n clearContextTop: function (skipRestore) {\n if (!this.isEditing || !this.canvas || !this.canvas.contextTop) {\n return;\n }\n\n var ctx = this.canvas.contextTop,\n v = this.canvas.viewportTransform;\n ctx.save();\n ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]);\n this.transform(ctx);\n\n this._clearTextArea(ctx);\n\n skipRestore || ctx.restore();\n },\n\n /**\n * Renders cursor or selection (depending on what exists)\n * it does on the contextTop. If contextTop is not available, do nothing.\n */\n renderCursorOrSelection: function () {\n if (!this.isEditing || !this.canvas || !this.canvas.contextTop) {\n return;\n }\n\n var boundaries = this._getCursorBoundaries(),\n ctx = this.canvas.contextTop;\n\n this.clearContextTop(true);\n\n if (this.selectionStart === this.selectionEnd) {\n this.renderCursor(boundaries, ctx);\n } else {\n this.renderSelection(boundaries, ctx);\n }\n\n ctx.restore();\n },\n _clearTextArea: function (ctx) {\n // we add 4 pixel, to be sure to do not leave any pixel out\n var width = this.width + 4,\n height = this.height + 4;\n ctx.clearRect(-width / 2, -height / 2, width, height);\n },\n\n /**\n * Returns cursor boundaries (left, top, leftOffset, topOffset)\n * @private\n * @param {Array} chars Array of characters\n * @param {String} typeOfBoundaries\n */\n _getCursorBoundaries: function (position) {\n // left/top are left/top of entire text box\n // leftOffset/topOffset are offset from that left/top point of a text box\n if (typeof position === 'undefined') {\n position = this.selectionStart;\n }\n\n var left = this._getLeftOffset(),\n top = this._getTopOffset(),\n offsets = this._getCursorBoundariesOffsets(position);\n\n return {\n left: left,\n top: top,\n leftOffset: offsets.left,\n topOffset: offsets.top\n };\n },\n\n /**\n * @private\n */\n _getCursorBoundariesOffsets: function (position) {\n if (this.cursorOffsetCache && 'top' in this.cursorOffsetCache) {\n return this.cursorOffsetCache;\n }\n\n var lineLeftOffset,\n lineIndex,\n charIndex,\n topOffset = 0,\n leftOffset = 0,\n boundaries,\n cursorPosition = this.get2DCursorLocation(position);\n charIndex = cursorPosition.charIndex;\n lineIndex = cursorPosition.lineIndex;\n\n for (var i = 0; i < lineIndex; i++) {\n topOffset += this.getHeightOfLine(i);\n }\n\n lineLeftOffset = this._getLineLeftOffset(lineIndex);\n var bound = this.__charBounds[lineIndex][charIndex];\n bound && (leftOffset = bound.left);\n\n if (this.charSpacing !== 0 && charIndex === this._textLines[lineIndex].length) {\n leftOffset -= this._getWidthOfCharSpacing();\n }\n\n boundaries = {\n top: topOffset,\n left: lineLeftOffset + (leftOffset > 0 ? leftOffset : 0)\n };\n this.cursorOffsetCache = boundaries;\n return this.cursorOffsetCache;\n },\n\n /**\n * Renders cursor\n * @param {Object} boundaries\n * @param {CanvasRenderingContext2D} ctx transformed context to draw on\n */\n renderCursor: function (boundaries, ctx) {\n var cursorLocation = this.get2DCursorLocation(),\n lineIndex = cursorLocation.lineIndex,\n charIndex = cursorLocation.charIndex > 0 ? cursorLocation.charIndex - 1 : 0,\n charHeight = this.getValueOfPropertyAt(lineIndex, charIndex, 'fontSize'),\n multiplier = this.scaleX * this.canvas.getZoom(),\n cursorWidth = this.cursorWidth / multiplier,\n topOffset = boundaries.topOffset,\n dy = this.getValueOfPropertyAt(lineIndex, charIndex, 'deltaY');\n topOffset += (1 - this._fontSizeFraction) * this.getHeightOfLine(lineIndex) / this.lineHeight - charHeight * (1 - this._fontSizeFraction);\n\n if (this.inCompositionMode) {\n this.renderSelection(boundaries, ctx);\n }\n\n ctx.fillStyle = this.cursorColor || this.getValueOfPropertyAt(lineIndex, charIndex, 'fill');\n ctx.globalAlpha = this.__isMousedown ? 1 : this._currentCursorOpacity;\n ctx.fillRect(boundaries.left + boundaries.leftOffset - cursorWidth / 2, topOffset + boundaries.top + dy, cursorWidth, charHeight);\n },\n\n /**\n * Renders text selection\n * @param {Object} boundaries Object with left/top/leftOffset/topOffset\n * @param {CanvasRenderingContext2D} ctx transformed context to draw on\n */\n renderSelection: function (boundaries, ctx) {\n var selectionStart = this.inCompositionMode ? this.hiddenTextarea.selectionStart : this.selectionStart,\n selectionEnd = this.inCompositionMode ? this.hiddenTextarea.selectionEnd : this.selectionEnd,\n isJustify = this.textAlign.indexOf('justify') !== -1,\n start = this.get2DCursorLocation(selectionStart),\n end = this.get2DCursorLocation(selectionEnd),\n startLine = start.lineIndex,\n endLine = end.lineIndex,\n startChar = start.charIndex < 0 ? 0 : start.charIndex,\n endChar = end.charIndex < 0 ? 0 : end.charIndex;\n\n for (var i = startLine; i <= endLine; i++) {\n var lineOffset = this._getLineLeftOffset(i) || 0,\n lineHeight = this.getHeightOfLine(i),\n realLineHeight = 0,\n boxStart = 0,\n boxEnd = 0;\n\n if (i === startLine) {\n boxStart = this.__charBounds[startLine][startChar].left;\n }\n\n if (i >= startLine && i < endLine) {\n boxEnd = isJustify && !this.isEndOfWrapping(i) ? this.width : this.getLineWidth(i) || 5; // WTF is this 5?\n } else if (i === endLine) {\n if (endChar === 0) {\n boxEnd = this.__charBounds[endLine][endChar].left;\n } else {\n var charSpacing = this._getWidthOfCharSpacing();\n\n boxEnd = this.__charBounds[endLine][endChar - 1].left + this.__charBounds[endLine][endChar - 1].width - charSpacing;\n }\n }\n\n realLineHeight = lineHeight;\n\n if (this.lineHeight < 1 || i === endLine && this.lineHeight > 1) {\n lineHeight /= this.lineHeight;\n }\n\n if (this.inCompositionMode) {\n ctx.fillStyle = this.compositionColor || 'black';\n ctx.fillRect(boundaries.left + lineOffset + boxStart, boundaries.top + boundaries.topOffset + lineHeight, boxEnd - boxStart, 1);\n } else {\n ctx.fillStyle = this.selectionColor;\n ctx.fillRect(boundaries.left + lineOffset + boxStart, boundaries.top + boundaries.topOffset, boxEnd - boxStart, lineHeight);\n }\n\n boundaries.topOffset += realLineHeight;\n }\n },\n\n /**\n * High level function to know the height of the cursor.\n * the currentChar is the one that precedes the cursor\n * Returns fontSize of char at the current cursor\n * Unused from the library, is for the end user\n * @return {Number} Character font size\n */\n getCurrentCharFontSize: function () {\n var cp = this._getCurrentCharIndex();\n\n return this.getValueOfPropertyAt(cp.l, cp.c, 'fontSize');\n },\n\n /**\n * High level function to know the color of the cursor.\n * the currentChar is the one that precedes the cursor\n * Returns color (fill) of char at the current cursor\n * Unused from the library, is for the end user\n * @return {String} Character color (fill)\n */\n getCurrentCharColor: function () {\n var cp = this._getCurrentCharIndex();\n\n return this.getValueOfPropertyAt(cp.l, cp.c, 'fill');\n },\n\n /**\n * Returns the cursor position for the getCurrent.. functions\n * @private\n */\n _getCurrentCharIndex: function () {\n var cursorPosition = this.get2DCursorLocation(this.selectionStart, true),\n charIndex = cursorPosition.charIndex > 0 ? cursorPosition.charIndex - 1 : 0;\n return {\n l: cursorPosition.lineIndex,\n c: charIndex\n };\n }\n });\n /**\n * Returns fabric.IText instance from an object representation\n * @static\n * @memberOf fabric.IText\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] invoked with new instance as argument\n */\n\n fabric.IText.fromObject = function (object, callback) {\n parseDecoration(object);\n\n if (object.styles) {\n for (var i in object.styles) {\n for (var j in object.styles[i]) {\n parseDecoration(object.styles[i][j]);\n }\n }\n }\n\n fabric.Object._fromObject('IText', object, callback, 'text');\n };\n})();\n\n(function () {\n var clone = fabric.util.object.clone;\n fabric.util.object.extend(fabric.IText.prototype,\n /** @lends fabric.IText.prototype */\n {\n /**\n * Initializes all the interactive behavior of IText\n */\n initBehavior: function () {\n this.initAddedHandler();\n this.initRemovedHandler();\n this.initCursorSelectionHandlers();\n this.initDoubleClickSimulation();\n this.mouseMoveHandler = this.mouseMoveHandler.bind(this);\n },\n onDeselect: function () {\n this.isEditing && this.exitEditing();\n this.selected = false;\n },\n\n /**\n * Initializes \"added\" event handler\n */\n initAddedHandler: function () {\n var _this = this;\n\n this.on('added', function () {\n var canvas = _this.canvas;\n\n if (canvas) {\n if (!canvas._hasITextHandlers) {\n canvas._hasITextHandlers = true;\n\n _this._initCanvasHandlers(canvas);\n }\n\n canvas._iTextInstances = canvas._iTextInstances || [];\n\n canvas._iTextInstances.push(_this);\n }\n });\n },\n initRemovedHandler: function () {\n var _this = this;\n\n this.on('removed', function () {\n var canvas = _this.canvas;\n\n if (canvas) {\n canvas._iTextInstances = canvas._iTextInstances || [];\n fabric.util.removeFromArray(canvas._iTextInstances, _this);\n\n if (canvas._iTextInstances.length === 0) {\n canvas._hasITextHandlers = false;\n\n _this._removeCanvasHandlers(canvas);\n }\n }\n });\n },\n\n /**\n * register canvas event to manage exiting on other instances\n * @private\n */\n _initCanvasHandlers: function (canvas) {\n canvas._mouseUpITextHandler = function () {\n if (canvas._iTextInstances) {\n canvas._iTextInstances.forEach(function (obj) {\n obj.__isMousedown = false;\n });\n }\n };\n\n canvas.on('mouse:up', canvas._mouseUpITextHandler);\n },\n\n /**\n * remove canvas event to manage exiting on other instances\n * @private\n */\n _removeCanvasHandlers: function (canvas) {\n canvas.off('mouse:up', canvas._mouseUpITextHandler);\n },\n\n /**\n * @private\n */\n _tick: function () {\n this._currentTickState = this._animateCursor(this, 1, this.cursorDuration, '_onTickComplete');\n },\n\n /**\n * @private\n */\n _animateCursor: function (obj, targetOpacity, duration, completeMethod) {\n var tickState;\n tickState = {\n isAborted: false,\n abort: function () {\n this.isAborted = true;\n }\n };\n obj.animate('_currentCursorOpacity', targetOpacity, {\n duration: duration,\n onComplete: function () {\n if (!tickState.isAborted) {\n obj[completeMethod]();\n }\n },\n onChange: function () {\n // we do not want to animate a selection, only cursor\n if (obj.canvas && obj.selectionStart === obj.selectionEnd) {\n obj.renderCursorOrSelection();\n }\n },\n abort: function () {\n return tickState.isAborted;\n }\n });\n return tickState;\n },\n\n /**\n * @private\n */\n _onTickComplete: function () {\n var _this = this;\n\n if (this._cursorTimeout1) {\n clearTimeout(this._cursorTimeout1);\n }\n\n this._cursorTimeout1 = setTimeout(function () {\n _this._currentTickCompleteState = _this._animateCursor(_this, 0, this.cursorDuration / 2, '_tick');\n }, 100);\n },\n\n /**\n * Initializes delayed cursor\n */\n initDelayedCursor: function (restart) {\n var _this = this,\n delay = restart ? 0 : this.cursorDelay;\n\n this.abortCursorAnimation();\n this._currentCursorOpacity = 1;\n this._cursorTimeout2 = setTimeout(function () {\n _this._tick();\n }, delay);\n },\n\n /**\n * Aborts cursor animation and clears all timeouts\n */\n abortCursorAnimation: function () {\n var shouldClear = this._currentTickState || this._currentTickCompleteState,\n canvas = this.canvas;\n this._currentTickState && this._currentTickState.abort();\n this._currentTickCompleteState && this._currentTickCompleteState.abort();\n clearTimeout(this._cursorTimeout1);\n clearTimeout(this._cursorTimeout2);\n this._currentCursorOpacity = 0; // to clear just itext area we need to transform the context\n // it may not be worth it\n\n if (shouldClear && canvas) {\n canvas.clearContext(canvas.contextTop || canvas.contextContainer);\n }\n },\n\n /**\n * Selects entire text\n * @return {fabric.IText} thisArg\n * @chainable\n */\n selectAll: function () {\n this.selectionStart = 0;\n this.selectionEnd = this._text.length;\n\n this._fireSelectionChanged();\n\n this._updateTextarea();\n\n return this;\n },\n\n /**\n * Returns selected text\n * @return {String}\n */\n getSelectedText: function () {\n return this._text.slice(this.selectionStart, this.selectionEnd).join('');\n },\n\n /**\n * Find new selection index representing start of current word according to current selection index\n * @param {Number} startFrom Current selection index\n * @return {Number} New selection index\n */\n findWordBoundaryLeft: function (startFrom) {\n var offset = 0,\n index = startFrom - 1; // remove space before cursor first\n\n if (this._reSpace.test(this._text[index])) {\n while (this._reSpace.test(this._text[index])) {\n offset++;\n index--;\n }\n }\n\n while (/\\S/.test(this._text[index]) && index > -1) {\n offset++;\n index--;\n }\n\n return startFrom - offset;\n },\n\n /**\n * Find new selection index representing end of current word according to current selection index\n * @param {Number} startFrom Current selection index\n * @return {Number} New selection index\n */\n findWordBoundaryRight: function (startFrom) {\n var offset = 0,\n index = startFrom; // remove space after cursor first\n\n if (this._reSpace.test(this._text[index])) {\n while (this._reSpace.test(this._text[index])) {\n offset++;\n index++;\n }\n }\n\n while (/\\S/.test(this._text[index]) && index < this._text.length) {\n offset++;\n index++;\n }\n\n return startFrom + offset;\n },\n\n /**\n * Find new selection index representing start of current line according to current selection index\n * @param {Number} startFrom Current selection index\n * @return {Number} New selection index\n */\n findLineBoundaryLeft: function (startFrom) {\n var offset = 0,\n index = startFrom - 1;\n\n while (!/\\n/.test(this._text[index]) && index > -1) {\n offset++;\n index--;\n }\n\n return startFrom - offset;\n },\n\n /**\n * Find new selection index representing end of current line according to current selection index\n * @param {Number} startFrom Current selection index\n * @return {Number} New selection index\n */\n findLineBoundaryRight: function (startFrom) {\n var offset = 0,\n index = startFrom;\n\n while (!/\\n/.test(this._text[index]) && index < this._text.length) {\n offset++;\n index++;\n }\n\n return startFrom + offset;\n },\n\n /**\n * Finds index corresponding to beginning or end of a word\n * @param {Number} selectionStart Index of a character\n * @param {Number} direction 1 or -1\n * @return {Number} Index of the beginning or end of a word\n */\n searchWordBoundary: function (selectionStart, direction) {\n var text = this._text,\n index = this._reSpace.test(text[selectionStart]) ? selectionStart - 1 : selectionStart,\n _char = text[index],\n // wrong\n reNonWord = fabric.reNonWord;\n\n while (!reNonWord.test(_char) && index > 0 && index < text.length) {\n index += direction;\n _char = text[index];\n }\n\n if (reNonWord.test(_char)) {\n index += direction === 1 ? 0 : 1;\n }\n\n return index;\n },\n\n /**\n * Selects a word based on the index\n * @param {Number} selectionStart Index of a character\n */\n selectWord: function (selectionStart) {\n selectionStart = selectionStart || this.selectionStart;\n var newSelectionStart = this.searchWordBoundary(selectionStart, -1),\n\n /* search backwards */\n newSelectionEnd = this.searchWordBoundary(selectionStart, 1);\n /* search forward */\n\n this.selectionStart = newSelectionStart;\n this.selectionEnd = newSelectionEnd;\n\n this._fireSelectionChanged();\n\n this._updateTextarea();\n\n this.renderCursorOrSelection();\n },\n\n /**\n * Selects a line based on the index\n * @param {Number} selectionStart Index of a character\n * @return {fabric.IText} thisArg\n * @chainable\n */\n selectLine: function (selectionStart) {\n selectionStart = selectionStart || this.selectionStart;\n var newSelectionStart = this.findLineBoundaryLeft(selectionStart),\n newSelectionEnd = this.findLineBoundaryRight(selectionStart);\n this.selectionStart = newSelectionStart;\n this.selectionEnd = newSelectionEnd;\n\n this._fireSelectionChanged();\n\n this._updateTextarea();\n\n return this;\n },\n\n /**\n * Enters editing state\n * @return {fabric.IText} thisArg\n * @chainable\n */\n enterEditing: function (e) {\n if (this.isEditing || !this.editable) {\n return;\n }\n\n if (this.canvas) {\n this.canvas.calcOffset();\n this.exitEditingOnOthers(this.canvas);\n }\n\n this.isEditing = true;\n this.initHiddenTextarea(e);\n this.hiddenTextarea.focus();\n this.hiddenTextarea.value = this.text;\n\n this._updateTextarea();\n\n this._saveEditingProps();\n\n this._setEditingProps();\n\n this._textBeforeEdit = this.text;\n\n this._tick();\n\n this.fire('editing:entered');\n\n this._fireSelectionChanged();\n\n if (!this.canvas) {\n return this;\n }\n\n this.canvas.fire('text:editing:entered', {\n target: this\n });\n this.initMouseMoveHandler();\n this.canvas.requestRenderAll();\n return this;\n },\n exitEditingOnOthers: function (canvas) {\n if (canvas._iTextInstances) {\n canvas._iTextInstances.forEach(function (obj) {\n obj.selected = false;\n\n if (obj.isEditing) {\n obj.exitEditing();\n }\n });\n }\n },\n\n /**\n * Initializes \"mousemove\" event handler\n */\n initMouseMoveHandler: function () {\n this.canvas.on('mouse:move', this.mouseMoveHandler);\n },\n\n /**\n * @private\n */\n mouseMoveHandler: function (options) {\n if (!this.__isMousedown || !this.isEditing) {\n return;\n }\n\n var newSelectionStart = this.getSelectionStartFromPointer(options.e),\n currentStart = this.selectionStart,\n currentEnd = this.selectionEnd;\n\n if ((newSelectionStart !== this.__selectionStartOnMouseDown || currentStart === currentEnd) && (currentStart === newSelectionStart || currentEnd === newSelectionStart)) {\n return;\n }\n\n if (newSelectionStart > this.__selectionStartOnMouseDown) {\n this.selectionStart = this.__selectionStartOnMouseDown;\n this.selectionEnd = newSelectionStart;\n } else {\n this.selectionStart = newSelectionStart;\n this.selectionEnd = this.__selectionStartOnMouseDown;\n }\n\n if (this.selectionStart !== currentStart || this.selectionEnd !== currentEnd) {\n this.restartCursorIfNeeded();\n\n this._fireSelectionChanged();\n\n this._updateTextarea();\n\n this.renderCursorOrSelection();\n }\n },\n\n /**\n * @private\n */\n _setEditingProps: function () {\n this.hoverCursor = 'text';\n\n if (this.canvas) {\n this.canvas.defaultCursor = this.canvas.moveCursor = 'text';\n }\n\n this.borderColor = this.editingBorderColor;\n this.hasControls = this.selectable = false;\n this.lockMovementX = this.lockMovementY = true;\n },\n\n /**\n * convert from textarea to grapheme indexes\n */\n fromStringToGraphemeSelection: function (start, end, text) {\n var smallerTextStart = text.slice(0, start),\n graphemeStart = fabric.util.string.graphemeSplit(smallerTextStart).length;\n\n if (start === end) {\n return {\n selectionStart: graphemeStart,\n selectionEnd: graphemeStart\n };\n }\n\n var smallerTextEnd = text.slice(start, end),\n graphemeEnd = fabric.util.string.graphemeSplit(smallerTextEnd).length;\n return {\n selectionStart: graphemeStart,\n selectionEnd: graphemeStart + graphemeEnd\n };\n },\n\n /**\n * convert from fabric to textarea values\n */\n fromGraphemeToStringSelection: function (start, end, _text) {\n var smallerTextStart = _text.slice(0, start),\n graphemeStart = smallerTextStart.join('').length;\n\n if (start === end) {\n return {\n selectionStart: graphemeStart,\n selectionEnd: graphemeStart\n };\n }\n\n var smallerTextEnd = _text.slice(start, end),\n graphemeEnd = smallerTextEnd.join('').length;\n\n return {\n selectionStart: graphemeStart,\n selectionEnd: graphemeStart + graphemeEnd\n };\n },\n\n /**\n * @private\n */\n _updateTextarea: function () {\n this.cursorOffsetCache = {};\n\n if (!this.hiddenTextarea) {\n return;\n }\n\n if (!this.inCompositionMode) {\n var newSelection = this.fromGraphemeToStringSelection(this.selectionStart, this.selectionEnd, this._text);\n this.hiddenTextarea.selectionStart = newSelection.selectionStart;\n this.hiddenTextarea.selectionEnd = newSelection.selectionEnd;\n }\n\n this.updateTextareaPosition();\n },\n\n /**\n * @private\n */\n updateFromTextArea: function () {\n if (!this.hiddenTextarea) {\n return;\n }\n\n this.cursorOffsetCache = {};\n this.text = this.hiddenTextarea.value;\n\n if (this._shouldClearDimensionCache()) {\n this.initDimensions();\n this.setCoords();\n }\n\n var newSelection = this.fromStringToGraphemeSelection(this.hiddenTextarea.selectionStart, this.hiddenTextarea.selectionEnd, this.hiddenTextarea.value);\n this.selectionEnd = this.selectionStart = newSelection.selectionEnd;\n\n if (!this.inCompositionMode) {\n this.selectionStart = newSelection.selectionStart;\n }\n\n this.updateTextareaPosition();\n },\n\n /**\n * @private\n */\n updateTextareaPosition: function () {\n if (this.selectionStart === this.selectionEnd) {\n var style = this._calcTextareaPosition();\n\n this.hiddenTextarea.style.left = style.left;\n this.hiddenTextarea.style.top = style.top;\n }\n },\n\n /**\n * @private\n * @return {Object} style contains style for hiddenTextarea\n */\n _calcTextareaPosition: function () {\n if (!this.canvas) {\n return {\n x: 1,\n y: 1\n };\n }\n\n var desiredPosition = this.inCompositionMode ? this.compositionStart : this.selectionStart,\n boundaries = this._getCursorBoundaries(desiredPosition),\n cursorLocation = this.get2DCursorLocation(desiredPosition),\n lineIndex = cursorLocation.lineIndex,\n charIndex = cursorLocation.charIndex,\n charHeight = this.getValueOfPropertyAt(lineIndex, charIndex, 'fontSize') * this.lineHeight,\n leftOffset = boundaries.leftOffset,\n m = this.calcTransformMatrix(),\n p = {\n x: boundaries.left + leftOffset,\n y: boundaries.top + boundaries.topOffset + charHeight\n },\n retinaScaling = this.canvas.getRetinaScaling(),\n upperCanvas = this.canvas.upperCanvasEl,\n upperCanvasWidth = upperCanvas.width / retinaScaling,\n upperCanvasHeight = upperCanvas.height / retinaScaling,\n maxWidth = upperCanvasWidth - charHeight,\n maxHeight = upperCanvasHeight - charHeight,\n scaleX = upperCanvas.clientWidth / upperCanvasWidth,\n scaleY = upperCanvas.clientHeight / upperCanvasHeight;\n\n p = fabric.util.transformPoint(p, m);\n p = fabric.util.transformPoint(p, this.canvas.viewportTransform);\n p.x *= scaleX;\n p.y *= scaleY;\n\n if (p.x < 0) {\n p.x = 0;\n }\n\n if (p.x > maxWidth) {\n p.x = maxWidth;\n }\n\n if (p.y < 0) {\n p.y = 0;\n }\n\n if (p.y > maxHeight) {\n p.y = maxHeight;\n } // add canvas offset on document\n\n\n p.x += this.canvas._offset.left;\n p.y += this.canvas._offset.top;\n return {\n left: p.x + 'px',\n top: p.y + 'px',\n fontSize: charHeight + 'px',\n charHeight: charHeight\n };\n },\n\n /**\n * @private\n */\n _saveEditingProps: function () {\n this._savedProps = {\n hasControls: this.hasControls,\n borderColor: this.borderColor,\n lockMovementX: this.lockMovementX,\n lockMovementY: this.lockMovementY,\n hoverCursor: this.hoverCursor,\n selectable: this.selectable,\n defaultCursor: this.canvas && this.canvas.defaultCursor,\n moveCursor: this.canvas && this.canvas.moveCursor\n };\n },\n\n /**\n * @private\n */\n _restoreEditingProps: function () {\n if (!this._savedProps) {\n return;\n }\n\n this.hoverCursor = this._savedProps.hoverCursor;\n this.hasControls = this._savedProps.hasControls;\n this.borderColor = this._savedProps.borderColor;\n this.selectable = this._savedProps.selectable;\n this.lockMovementX = this._savedProps.lockMovementX;\n this.lockMovementY = this._savedProps.lockMovementY;\n\n if (this.canvas) {\n this.canvas.defaultCursor = this._savedProps.defaultCursor;\n this.canvas.moveCursor = this._savedProps.moveCursor;\n }\n },\n\n /**\n * Exits from editing state\n * @return {fabric.IText} thisArg\n * @chainable\n */\n exitEditing: function () {\n var isTextChanged = this._textBeforeEdit !== this.text;\n var hiddenTextarea = this.hiddenTextarea;\n this.selected = false;\n this.isEditing = false;\n this.selectionEnd = this.selectionStart;\n\n if (hiddenTextarea) {\n hiddenTextarea.blur && hiddenTextarea.blur();\n hiddenTextarea.parentNode && hiddenTextarea.parentNode.removeChild(hiddenTextarea);\n }\n\n this.hiddenTextarea = null;\n this.abortCursorAnimation();\n\n this._restoreEditingProps();\n\n this._currentCursorOpacity = 0;\n\n if (this._shouldClearDimensionCache()) {\n this.initDimensions();\n this.setCoords();\n }\n\n this.fire('editing:exited');\n isTextChanged && this.fire('modified');\n\n if (this.canvas) {\n this.canvas.off('mouse:move', this.mouseMoveHandler);\n this.canvas.fire('text:editing:exited', {\n target: this\n });\n isTextChanged && this.canvas.fire('object:modified', {\n target: this\n });\n }\n\n return this;\n },\n\n /**\n * @private\n */\n _removeExtraneousStyles: function () {\n for (var prop in this.styles) {\n if (!this._textLines[prop]) {\n delete this.styles[prop];\n }\n }\n },\n\n /**\n * remove and reflow a style block from start to end.\n * @param {Number} start linear start position for removal (included in removal)\n * @param {Number} end linear end position for removal ( excluded from removal )\n */\n removeStyleFromTo: function (start, end) {\n var cursorStart = this.get2DCursorLocation(start, true),\n cursorEnd = this.get2DCursorLocation(end, true),\n lineStart = cursorStart.lineIndex,\n charStart = cursorStart.charIndex,\n lineEnd = cursorEnd.lineIndex,\n charEnd = cursorEnd.charIndex,\n i,\n styleObj;\n\n if (lineStart !== lineEnd) {\n // step1 remove the trailing of lineStart\n if (this.styles[lineStart]) {\n for (i = charStart; i < this._unwrappedTextLines[lineStart].length; i++) {\n delete this.styles[lineStart][i];\n }\n } // step2 move the trailing of lineEnd to lineStart if needed\n\n\n if (this.styles[lineEnd]) {\n for (i = charEnd; i < this._unwrappedTextLines[lineEnd].length; i++) {\n styleObj = this.styles[lineEnd][i];\n\n if (styleObj) {\n this.styles[lineStart] || (this.styles[lineStart] = {});\n this.styles[lineStart][charStart + i - charEnd] = styleObj;\n }\n }\n } // step3 detects lines will be completely removed.\n\n\n for (i = lineStart + 1; i <= lineEnd; i++) {\n delete this.styles[i];\n } // step4 shift remaining lines.\n\n\n this.shiftLineStyles(lineEnd, lineStart - lineEnd);\n } else {\n // remove and shift left on the same line\n if (this.styles[lineStart]) {\n styleObj = this.styles[lineStart];\n\n var diff = charEnd - charStart,\n numericChar,\n _char;\n\n for (i = charStart; i < charEnd; i++) {\n delete styleObj[i];\n }\n\n for (_char in this.styles[lineStart]) {\n numericChar = parseInt(_char, 10);\n\n if (numericChar >= charEnd) {\n styleObj[numericChar - diff] = styleObj[_char];\n delete styleObj[_char];\n }\n }\n }\n }\n },\n\n /**\n * Shifts line styles up or down\n * @param {Number} lineIndex Index of a line\n * @param {Number} offset Can any number?\n */\n shiftLineStyles: function (lineIndex, offset) {\n // shift all line styles by offset upward or downward\n // do not clone deep. we need new array, not new style objects\n var clonedStyles = clone(this.styles);\n\n for (var line in this.styles) {\n var numericLine = parseInt(line, 10);\n\n if (numericLine > lineIndex) {\n this.styles[numericLine + offset] = clonedStyles[numericLine];\n\n if (!clonedStyles[numericLine - offset]) {\n delete this.styles[numericLine];\n }\n }\n }\n },\n restartCursorIfNeeded: function () {\n if (!this._currentTickState || this._currentTickState.isAborted || !this._currentTickCompleteState || this._currentTickCompleteState.isAborted) {\n this.initDelayedCursor();\n }\n },\n\n /**\n * Handle insertion of more consecutive style lines for when one or more\n * newlines gets added to the text. Since current style needs to be shifted\n * first we shift the current style of the number lines needed, then we add\n * new lines from the last to the first.\n * @param {Number} lineIndex Index of a line\n * @param {Number} charIndex Index of a char\n * @param {Number} qty number of lines to add\n * @param {Array} copiedStyle Array of objects styles\n */\n insertNewlineStyleObject: function (lineIndex, charIndex, qty, copiedStyle) {\n var currentCharStyle,\n newLineStyles = {},\n somethingAdded = false,\n isEndOfLine = this._unwrappedTextLines[lineIndex].length === charIndex;\n qty || (qty = 1);\n this.shiftLineStyles(lineIndex, qty);\n\n if (this.styles[lineIndex]) {\n currentCharStyle = this.styles[lineIndex][charIndex === 0 ? charIndex : charIndex - 1];\n } // we clone styles of all chars\n // after cursor onto the current line\n\n\n for (var index in this.styles[lineIndex]) {\n var numIndex = parseInt(index, 10);\n\n if (numIndex >= charIndex) {\n somethingAdded = true;\n newLineStyles[numIndex - charIndex] = this.styles[lineIndex][index]; // remove lines from the previous line since they're on a new line now\n\n if (!(isEndOfLine && charIndex === 0)) {\n delete this.styles[lineIndex][index];\n }\n }\n }\n\n var styleCarriedOver = false;\n\n if (somethingAdded && !isEndOfLine) {\n // if is end of line, the extra style we copied\n // is probably not something we want\n this.styles[lineIndex + qty] = newLineStyles;\n styleCarriedOver = true;\n }\n\n if (styleCarriedOver) {\n // skip the last line of since we already prepared it.\n qty--;\n } // for the all the lines or all the other lines\n // we clone current char style onto the next (otherwise empty) line\n\n\n while (qty > 0) {\n if (copiedStyle && copiedStyle[qty - 1]) {\n this.styles[lineIndex + qty] = {\n 0: clone(copiedStyle[qty - 1])\n };\n } else if (currentCharStyle) {\n this.styles[lineIndex + qty] = {\n 0: clone(currentCharStyle)\n };\n } else {\n delete this.styles[lineIndex + qty];\n }\n\n qty--;\n }\n\n this._forceClearCache = true;\n },\n\n /**\n * Inserts style object for a given line/char index\n * @param {Number} lineIndex Index of a line\n * @param {Number} charIndex Index of a char\n * @param {Number} quantity number Style object to insert, if given\n * @param {Array} copiedStyle array of style objects\n */\n insertCharStyleObject: function (lineIndex, charIndex, quantity, copiedStyle) {\n if (!this.styles) {\n this.styles = {};\n }\n\n var currentLineStyles = this.styles[lineIndex],\n currentLineStylesCloned = currentLineStyles ? clone(currentLineStyles) : {};\n quantity || (quantity = 1); // shift all char styles by quantity forward\n // 0,1,2,3 -> (charIndex=2) -> 0,1,3,4 -> (insert 2) -> 0,1,2,3,4\n\n for (var index in currentLineStylesCloned) {\n var numericIndex = parseInt(index, 10);\n\n if (numericIndex >= charIndex) {\n currentLineStyles[numericIndex + quantity] = currentLineStylesCloned[numericIndex]; // only delete the style if there was nothing moved there\n\n if (!currentLineStylesCloned[numericIndex - quantity]) {\n delete currentLineStyles[numericIndex];\n }\n }\n }\n\n this._forceClearCache = true;\n\n if (copiedStyle) {\n while (quantity--) {\n if (!Object.keys(copiedStyle[quantity]).length) {\n continue;\n }\n\n if (!this.styles[lineIndex]) {\n this.styles[lineIndex] = {};\n }\n\n this.styles[lineIndex][charIndex + quantity] = clone(copiedStyle[quantity]);\n }\n\n return;\n }\n\n if (!currentLineStyles) {\n return;\n }\n\n var newStyle = currentLineStyles[charIndex ? charIndex - 1 : 1];\n\n while (newStyle && quantity--) {\n this.styles[lineIndex][charIndex + quantity] = clone(newStyle);\n }\n },\n\n /**\n * Inserts style object(s)\n * @param {Array} insertedText Characters at the location where style is inserted\n * @param {Number} start cursor index for inserting style\n * @param {Array} [copiedStyle] array of style objects to insert.\n */\n insertNewStyleBlock: function (insertedText, start, copiedStyle) {\n var cursorLoc = this.get2DCursorLocation(start, true),\n addedLines = [0],\n linesLength = 0; // get an array of how many char per lines are being added.\n\n for (var i = 0; i < insertedText.length; i++) {\n if (insertedText[i] === '\\n') {\n linesLength++;\n addedLines[linesLength] = 0;\n } else {\n addedLines[linesLength]++;\n }\n } // for the first line copy the style from the current char position.\n\n\n if (addedLines[0] > 0) {\n this.insertCharStyleObject(cursorLoc.lineIndex, cursorLoc.charIndex, addedLines[0], copiedStyle);\n copiedStyle = copiedStyle && copiedStyle.slice(addedLines[0] + 1);\n }\n\n linesLength && this.insertNewlineStyleObject(cursorLoc.lineIndex, cursorLoc.charIndex + addedLines[0], linesLength);\n\n for (var i = 1; i < linesLength; i++) {\n if (addedLines[i] > 0) {\n this.insertCharStyleObject(cursorLoc.lineIndex + i, 0, addedLines[i], copiedStyle);\n } else if (copiedStyle) {\n this.styles[cursorLoc.lineIndex + i][0] = copiedStyle[0];\n }\n\n copiedStyle = copiedStyle && copiedStyle.slice(addedLines[i] + 1);\n } // we use i outside the loop to get it like linesLength\n\n\n if (addedLines[i] > 0) {\n this.insertCharStyleObject(cursorLoc.lineIndex + i, 0, addedLines[i], copiedStyle);\n }\n },\n\n /**\n * Set the selectionStart and selectionEnd according to the new position of cursor\n * mimic the key - mouse navigation when shift is pressed.\n */\n setSelectionStartEndWithShift: function (start, end, newSelection) {\n if (newSelection <= start) {\n if (end === start) {\n this._selectionDirection = 'left';\n } else if (this._selectionDirection === 'right') {\n this._selectionDirection = 'left';\n this.selectionEnd = start;\n }\n\n this.selectionStart = newSelection;\n } else if (newSelection > start && newSelection < end) {\n if (this._selectionDirection === 'right') {\n this.selectionEnd = newSelection;\n } else {\n this.selectionStart = newSelection;\n }\n } else {\n // newSelection is > selection start and end\n if (end === start) {\n this._selectionDirection = 'right';\n } else if (this._selectionDirection === 'left') {\n this._selectionDirection = 'right';\n this.selectionStart = end;\n }\n\n this.selectionEnd = newSelection;\n }\n },\n setSelectionInBoundaries: function () {\n var length = this.text.length;\n\n if (this.selectionStart > length) {\n this.selectionStart = length;\n } else if (this.selectionStart < 0) {\n this.selectionStart = 0;\n }\n\n if (this.selectionEnd > length) {\n this.selectionEnd = length;\n } else if (this.selectionEnd < 0) {\n this.selectionEnd = 0;\n }\n }\n });\n})();\n\nfabric.util.object.extend(fabric.IText.prototype,\n/** @lends fabric.IText.prototype */\n{\n /**\n * Initializes \"dbclick\" event handler\n */\n initDoubleClickSimulation: function () {\n // for double click\n this.__lastClickTime = +new Date(); // for triple click\n\n this.__lastLastClickTime = +new Date();\n this.__lastPointer = {};\n this.on('mousedown', this.onMouseDown);\n },\n\n /**\n * Default event handler to simulate triple click\n * @private\n */\n onMouseDown: function (options) {\n if (!this.canvas) {\n return;\n }\n\n this.__newClickTime = +new Date();\n var newPointer = options.pointer;\n\n if (this.isTripleClick(newPointer)) {\n this.fire('tripleclick', options);\n\n this._stopEvent(options.e);\n }\n\n this.__lastLastClickTime = this.__lastClickTime;\n this.__lastClickTime = this.__newClickTime;\n this.__lastPointer = newPointer;\n this.__lastIsEditing = this.isEditing;\n this.__lastSelected = this.selected;\n },\n isTripleClick: function (newPointer) {\n return this.__newClickTime - this.__lastClickTime < 500 && this.__lastClickTime - this.__lastLastClickTime < 500 && this.__lastPointer.x === newPointer.x && this.__lastPointer.y === newPointer.y;\n },\n\n /**\n * @private\n */\n _stopEvent: function (e) {\n e.preventDefault && e.preventDefault();\n e.stopPropagation && e.stopPropagation();\n },\n\n /**\n * Initializes event handlers related to cursor or selection\n */\n initCursorSelectionHandlers: function () {\n this.initMousedownHandler();\n this.initMouseupHandler();\n this.initClicks();\n },\n\n /**\n * Default handler for double click, select a word\n */\n doubleClickHandler: function (options) {\n if (!this.isEditing) {\n return;\n }\n\n this.selectWord(this.getSelectionStartFromPointer(options.e));\n },\n\n /**\n * Default handler for triple click, select a line\n */\n tripleClickHandler: function (options) {\n if (!this.isEditing) {\n return;\n }\n\n this.selectLine(this.getSelectionStartFromPointer(options.e));\n },\n\n /**\n * Initializes double and triple click event handlers\n */\n initClicks: function () {\n this.on('mousedblclick', this.doubleClickHandler);\n this.on('tripleclick', this.tripleClickHandler);\n },\n\n /**\n * Default event handler for the basic functionalities needed on _mouseDown\n * can be overridden to do something different.\n * Scope of this implementation is: find the click position, set selectionStart\n * find selectionEnd, initialize the drawing of either cursor or selection area\n * initializing a mousedDown on a text area will cancel fabricjs knowledge of\n * current compositionMode. It will be set to false.\n */\n _mouseDownHandler: function (options) {\n if (!this.canvas || !this.editable || options.e.button && options.e.button !== 1) {\n return;\n }\n\n this.__isMousedown = true;\n\n if (this.selected) {\n this.inCompositionMode = false;\n this.setCursorByClick(options.e);\n }\n\n if (this.isEditing) {\n this.__selectionStartOnMouseDown = this.selectionStart;\n\n if (this.selectionStart === this.selectionEnd) {\n this.abortCursorAnimation();\n }\n\n this.renderCursorOrSelection();\n }\n },\n\n /**\n * Default event handler for the basic functionalities needed on mousedown:before\n * can be overridden to do something different.\n * Scope of this implementation is: verify the object is already selected when mousing down\n */\n _mouseDownHandlerBefore: function (options) {\n if (!this.canvas || !this.editable || options.e.button && options.e.button !== 1) {\n return;\n } // we want to avoid that an object that was selected and then becomes unselectable,\n // may trigger editing mode in some way.\n\n\n this.selected = this === this.canvas._activeObject;\n },\n\n /**\n * Initializes \"mousedown\" event handler\n */\n initMousedownHandler: function () {\n this.on('mousedown', this._mouseDownHandler);\n this.on('mousedown:before', this._mouseDownHandlerBefore);\n },\n\n /**\n * Initializes \"mouseup\" event handler\n */\n initMouseupHandler: function () {\n this.on('mouseup', this.mouseUpHandler);\n },\n\n /**\n * standard hander for mouse up, overridable\n * @private\n */\n mouseUpHandler: function (options) {\n this.__isMousedown = false;\n\n if (!this.editable || this.group || options.transform && options.transform.actionPerformed || options.e.button && options.e.button !== 1) {\n return;\n }\n\n if (this.canvas) {\n var currentActive = this.canvas._activeObject;\n\n if (currentActive && currentActive !== this) {\n // avoid running this logic when there is an active object\n // this because is possible with shift click and fast clicks,\n // to rapidly deselect and reselect this object and trigger an enterEdit\n return;\n }\n }\n\n if (this.__lastSelected && !this.__corner) {\n this.selected = false;\n this.__lastSelected = false;\n this.enterEditing(options.e);\n\n if (this.selectionStart === this.selectionEnd) {\n this.initDelayedCursor(true);\n } else {\n this.renderCursorOrSelection();\n }\n } else {\n this.selected = true;\n }\n },\n\n /**\n * Changes cursor location in a text depending on passed pointer (x/y) object\n * @param {Event} e Event object\n */\n setCursorByClick: function (e) {\n var newSelection = this.getSelectionStartFromPointer(e),\n start = this.selectionStart,\n end = this.selectionEnd;\n\n if (e.shiftKey) {\n this.setSelectionStartEndWithShift(start, end, newSelection);\n } else {\n this.selectionStart = newSelection;\n this.selectionEnd = newSelection;\n }\n\n if (this.isEditing) {\n this._fireSelectionChanged();\n\n this._updateTextarea();\n }\n },\n\n /**\n * Returns index of a character corresponding to where an object was clicked\n * @param {Event} e Event object\n * @return {Number} Index of a character\n */\n getSelectionStartFromPointer: function (e) {\n var mouseOffset = this.getLocalPointer(e),\n prevWidth = 0,\n width = 0,\n height = 0,\n charIndex = 0,\n lineIndex = 0,\n lineLeftOffset,\n line;\n\n for (var i = 0, len = this._textLines.length; i < len; i++) {\n if (height <= mouseOffset.y) {\n height += this.getHeightOfLine(i) * this.scaleY;\n lineIndex = i;\n\n if (i > 0) {\n charIndex += this._textLines[i - 1].length + this.missingNewlineOffset(i - 1);\n }\n } else {\n break;\n }\n }\n\n lineLeftOffset = this._getLineLeftOffset(lineIndex);\n width = lineLeftOffset * this.scaleX;\n line = this._textLines[lineIndex];\n\n for (var j = 0, jlen = line.length; j < jlen; j++) {\n prevWidth = width; // i removed something about flipX here, check.\n\n width += this.__charBounds[lineIndex][j].kernedWidth * this.scaleX;\n\n if (width <= mouseOffset.x) {\n charIndex++;\n } else {\n break;\n }\n }\n\n return this._getNewSelectionStartFromOffset(mouseOffset, prevWidth, width, charIndex, jlen);\n },\n\n /**\n * @private\n */\n _getNewSelectionStartFromOffset: function (mouseOffset, prevWidth, width, index, jlen) {\n // we need Math.abs because when width is after the last char, the offset is given as 1, while is 0\n var distanceBtwLastCharAndCursor = mouseOffset.x - prevWidth,\n distanceBtwNextCharAndCursor = width - mouseOffset.x,\n offset = distanceBtwNextCharAndCursor > distanceBtwLastCharAndCursor || distanceBtwNextCharAndCursor < 0 ? 0 : 1,\n newSelectionStart = index + offset; // if object is horizontally flipped, mirror cursor location from the end\n\n if (this.flipX) {\n newSelectionStart = jlen - newSelectionStart;\n }\n\n if (newSelectionStart > this._text.length) {\n newSelectionStart = this._text.length;\n }\n\n return newSelectionStart;\n }\n});\nfabric.util.object.extend(fabric.IText.prototype,\n/** @lends fabric.IText.prototype */\n{\n /**\n * Initializes hidden textarea (needed to bring up keyboard in iOS)\n */\n initHiddenTextarea: function () {\n this.hiddenTextarea = fabric.document.createElement('textarea');\n this.hiddenTextarea.setAttribute('autocapitalize', 'off');\n this.hiddenTextarea.setAttribute('autocorrect', 'off');\n this.hiddenTextarea.setAttribute('autocomplete', 'off');\n this.hiddenTextarea.setAttribute('spellcheck', 'false');\n this.hiddenTextarea.setAttribute('data-fabric-hiddentextarea', '');\n this.hiddenTextarea.setAttribute('wrap', 'off');\n\n var style = this._calcTextareaPosition(); // line-height: 1px; was removed from the style to fix this:\n // https://bugs.chromium.org/p/chromium/issues/detail?id=870966\n\n\n this.hiddenTextarea.style.cssText = 'position: absolute; top: ' + style.top + '; left: ' + style.left + '; z-index: -999; opacity: 0; width: 1px; height: 1px; font-size: 1px;' + ' paddingーtop: ' + style.fontSize + ';';\n fabric.document.body.appendChild(this.hiddenTextarea);\n fabric.util.addListener(this.hiddenTextarea, 'keydown', this.onKeyDown.bind(this));\n fabric.util.addListener(this.hiddenTextarea, 'keyup', this.onKeyUp.bind(this));\n fabric.util.addListener(this.hiddenTextarea, 'input', this.onInput.bind(this));\n fabric.util.addListener(this.hiddenTextarea, 'copy', this.copy.bind(this));\n fabric.util.addListener(this.hiddenTextarea, 'cut', this.copy.bind(this));\n fabric.util.addListener(this.hiddenTextarea, 'paste', this.paste.bind(this));\n fabric.util.addListener(this.hiddenTextarea, 'compositionstart', this.onCompositionStart.bind(this));\n fabric.util.addListener(this.hiddenTextarea, 'compositionupdate', this.onCompositionUpdate.bind(this));\n fabric.util.addListener(this.hiddenTextarea, 'compositionend', this.onCompositionEnd.bind(this));\n\n if (!this._clickHandlerInitialized && this.canvas) {\n fabric.util.addListener(this.canvas.upperCanvasEl, 'click', this.onClick.bind(this));\n this._clickHandlerInitialized = true;\n }\n },\n\n /**\n * For functionalities on keyDown\n * Map a special key to a function of the instance/prototype\n * If you need different behaviour for ESC or TAB or arrows, you have to change\n * this map setting the name of a function that you build on the fabric.Itext or\n * your prototype.\n * the map change will affect all Instances unless you need for only some text Instances\n * in that case you have to clone this object and assign your Instance.\n * this.keysMap = fabric.util.object.clone(this.keysMap);\n * The function must be in fabric.Itext.prototype.myFunction And will receive event as args[0]\n */\n keysMap: {\n 9: 'exitEditing',\n 27: 'exitEditing',\n 33: 'moveCursorUp',\n 34: 'moveCursorDown',\n 35: 'moveCursorRight',\n 36: 'moveCursorLeft',\n 37: 'moveCursorLeft',\n 38: 'moveCursorUp',\n 39: 'moveCursorRight',\n 40: 'moveCursorDown'\n },\n\n /**\n * For functionalities on keyUp + ctrl || cmd\n */\n ctrlKeysMapUp: {\n 67: 'copy',\n 88: 'cut'\n },\n\n /**\n * For functionalities on keyDown + ctrl || cmd\n */\n ctrlKeysMapDown: {\n 65: 'selectAll'\n },\n onClick: function () {\n // No need to trigger click event here, focus is enough to have the keyboard appear on Android\n this.hiddenTextarea && this.hiddenTextarea.focus();\n },\n\n /**\n * Handles keydown event\n * only used for arrows and combination of modifier keys.\n * @param {Event} e Event object\n */\n onKeyDown: function (e) {\n if (!this.isEditing) {\n return;\n }\n\n if (e.keyCode in this.keysMap) {\n this[this.keysMap[e.keyCode]](e);\n } else if (e.keyCode in this.ctrlKeysMapDown && (e.ctrlKey || e.metaKey)) {\n this[this.ctrlKeysMapDown[e.keyCode]](e);\n } else {\n return;\n }\n\n e.stopImmediatePropagation();\n e.preventDefault();\n\n if (e.keyCode >= 33 && e.keyCode <= 40) {\n // if i press an arrow key just update selection\n this.inCompositionMode = false;\n this.clearContextTop();\n this.renderCursorOrSelection();\n } else {\n this.canvas && this.canvas.requestRenderAll();\n }\n },\n\n /**\n * Handles keyup event\n * We handle KeyUp because ie11 and edge have difficulties copy/pasting\n * if a copy/cut event fired, keyup is dismissed\n * @param {Event} e Event object\n */\n onKeyUp: function (e) {\n if (!this.isEditing || this._copyDone || this.inCompositionMode) {\n this._copyDone = false;\n return;\n }\n\n if (e.keyCode in this.ctrlKeysMapUp && (e.ctrlKey || e.metaKey)) {\n this[this.ctrlKeysMapUp[e.keyCode]](e);\n } else {\n return;\n }\n\n e.stopImmediatePropagation();\n e.preventDefault();\n this.canvas && this.canvas.requestRenderAll();\n },\n\n /**\n * Handles onInput event\n * @param {Event} e Event object\n */\n onInput: function (e) {\n var fromPaste = this.fromPaste;\n this.fromPaste = false;\n e && e.stopPropagation();\n\n if (!this.isEditing) {\n return;\n } // decisions about style changes.\n\n\n var nextText = this._splitTextIntoLines(this.hiddenTextarea.value).graphemeText,\n charCount = this._text.length,\n nextCharCount = nextText.length,\n removedText,\n insertedText,\n charDiff = nextCharCount - charCount,\n selectionStart = this.selectionStart,\n selectionEnd = this.selectionEnd,\n selection = selectionStart !== selectionEnd,\n copiedStyle,\n removeFrom,\n removeTo;\n\n if (this.hiddenTextarea.value === '') {\n this.styles = {};\n this.updateFromTextArea();\n this.fire('changed');\n\n if (this.canvas) {\n this.canvas.fire('text:changed', {\n target: this\n });\n this.canvas.requestRenderAll();\n }\n\n return;\n }\n\n var textareaSelection = this.fromStringToGraphemeSelection(this.hiddenTextarea.selectionStart, this.hiddenTextarea.selectionEnd, this.hiddenTextarea.value);\n var backDelete = selectionStart > textareaSelection.selectionStart;\n\n if (selection) {\n removedText = this._text.slice(selectionStart, selectionEnd);\n charDiff += selectionEnd - selectionStart;\n } else if (nextCharCount < charCount) {\n if (backDelete) {\n removedText = this._text.slice(selectionEnd + charDiff, selectionEnd);\n } else {\n removedText = this._text.slice(selectionStart, selectionStart - charDiff);\n }\n }\n\n insertedText = nextText.slice(textareaSelection.selectionEnd - charDiff, textareaSelection.selectionEnd);\n\n if (removedText && removedText.length) {\n if (insertedText.length) {\n // let's copy some style before deleting.\n // we want to copy the style before the cursor OR the style at the cursor if selection\n // is bigger than 0.\n copiedStyle = this.getSelectionStyles(selectionStart, selectionStart + 1, false); // now duplicate the style one for each inserted text.\n\n copiedStyle = insertedText.map(function () {\n // this return an array of references, but that is fine since we are\n // copying the style later.\n return copiedStyle[0];\n });\n }\n\n if (selection) {\n removeFrom = selectionStart;\n removeTo = selectionEnd;\n } else if (backDelete) {\n // detect differencies between forwardDelete and backDelete\n removeFrom = selectionEnd - removedText.length;\n removeTo = selectionEnd;\n } else {\n removeFrom = selectionEnd;\n removeTo = selectionEnd + removedText.length;\n }\n\n this.removeStyleFromTo(removeFrom, removeTo);\n }\n\n if (insertedText.length) {\n if (fromPaste && insertedText.join('') === fabric.copiedText && !fabric.disableStyleCopyPaste) {\n copiedStyle = fabric.copiedTextStyle;\n }\n\n this.insertNewStyleBlock(insertedText, selectionStart, copiedStyle);\n }\n\n this.updateFromTextArea();\n this.fire('changed');\n\n if (this.canvas) {\n this.canvas.fire('text:changed', {\n target: this\n });\n this.canvas.requestRenderAll();\n }\n },\n\n /**\n * Composition start\n */\n onCompositionStart: function () {\n this.inCompositionMode = true;\n },\n\n /**\n * Composition end\n */\n onCompositionEnd: function () {\n this.inCompositionMode = false;\n },\n // /**\n // * Composition update\n // */\n onCompositionUpdate: function (e) {\n this.compositionStart = e.target.selectionStart;\n this.compositionEnd = e.target.selectionEnd;\n this.updateTextareaPosition();\n },\n\n /**\n * Copies selected text\n * @param {Event} e Event object\n */\n copy: function () {\n if (this.selectionStart === this.selectionEnd) {\n //do not cut-copy if no selection\n return;\n }\n\n fabric.copiedText = this.getSelectedText();\n\n if (!fabric.disableStyleCopyPaste) {\n fabric.copiedTextStyle = this.getSelectionStyles(this.selectionStart, this.selectionEnd, true);\n } else {\n fabric.copiedTextStyle = null;\n }\n\n this._copyDone = true;\n },\n\n /**\n * Pastes text\n * @param {Event} e Event object\n */\n paste: function () {\n this.fromPaste = true;\n },\n\n /**\n * @private\n * @param {Event} e Event object\n * @return {Object} Clipboard data object\n */\n _getClipboardData: function (e) {\n return e && e.clipboardData || fabric.window.clipboardData;\n },\n\n /**\n * Finds the width in pixels before the cursor on the same line\n * @private\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @return {Number} widthBeforeCursor width before cursor\n */\n _getWidthBeforeCursor: function (lineIndex, charIndex) {\n var widthBeforeCursor = this._getLineLeftOffset(lineIndex),\n bound;\n\n if (charIndex > 0) {\n bound = this.__charBounds[lineIndex][charIndex - 1];\n widthBeforeCursor += bound.left + bound.width;\n }\n\n return widthBeforeCursor;\n },\n\n /**\n * Gets start offset of a selection\n * @param {Event} e Event object\n * @param {Boolean} isRight\n * @return {Number}\n */\n getDownCursorOffset: function (e, isRight) {\n var selectionProp = this._getSelectionForOffset(e, isRight),\n cursorLocation = this.get2DCursorLocation(selectionProp),\n lineIndex = cursorLocation.lineIndex; // if on last line, down cursor goes to end of line\n\n\n if (lineIndex === this._textLines.length - 1 || e.metaKey || e.keyCode === 34) {\n // move to the end of a text\n return this._text.length - selectionProp;\n }\n\n var charIndex = cursorLocation.charIndex,\n widthBeforeCursor = this._getWidthBeforeCursor(lineIndex, charIndex),\n indexOnOtherLine = this._getIndexOnLine(lineIndex + 1, widthBeforeCursor),\n textAfterCursor = this._textLines[lineIndex].slice(charIndex);\n\n return textAfterCursor.length + indexOnOtherLine + 1 + this.missingNewlineOffset(lineIndex);\n },\n\n /**\n * private\n * Helps finding if the offset should be counted from Start or End\n * @param {Event} e Event object\n * @param {Boolean} isRight\n * @return {Number}\n */\n _getSelectionForOffset: function (e, isRight) {\n if (e.shiftKey && this.selectionStart !== this.selectionEnd && isRight) {\n return this.selectionEnd;\n } else {\n return this.selectionStart;\n }\n },\n\n /**\n * @param {Event} e Event object\n * @param {Boolean} isRight\n * @return {Number}\n */\n getUpCursorOffset: function (e, isRight) {\n var selectionProp = this._getSelectionForOffset(e, isRight),\n cursorLocation = this.get2DCursorLocation(selectionProp),\n lineIndex = cursorLocation.lineIndex;\n\n if (lineIndex === 0 || e.metaKey || e.keyCode === 33) {\n // if on first line, up cursor goes to start of line\n return -selectionProp;\n }\n\n var charIndex = cursorLocation.charIndex,\n widthBeforeCursor = this._getWidthBeforeCursor(lineIndex, charIndex),\n indexOnOtherLine = this._getIndexOnLine(lineIndex - 1, widthBeforeCursor),\n textBeforeCursor = this._textLines[lineIndex].slice(0, charIndex),\n missingNewlineOffset = this.missingNewlineOffset(lineIndex - 1); // return a negative offset\n\n\n return -this._textLines[lineIndex - 1].length + indexOnOtherLine - textBeforeCursor.length + (1 - missingNewlineOffset);\n },\n\n /**\n * for a given width it founds the matching character.\n * @private\n */\n _getIndexOnLine: function (lineIndex, width) {\n var line = this._textLines[lineIndex],\n lineLeftOffset = this._getLineLeftOffset(lineIndex),\n widthOfCharsOnLine = lineLeftOffset,\n indexOnLine = 0,\n charWidth,\n foundMatch;\n\n for (var j = 0, jlen = line.length; j < jlen; j++) {\n charWidth = this.__charBounds[lineIndex][j].width;\n widthOfCharsOnLine += charWidth;\n\n if (widthOfCharsOnLine > width) {\n foundMatch = true;\n var leftEdge = widthOfCharsOnLine - charWidth,\n rightEdge = widthOfCharsOnLine,\n offsetFromLeftEdge = Math.abs(leftEdge - width),\n offsetFromRightEdge = Math.abs(rightEdge - width);\n indexOnLine = offsetFromRightEdge < offsetFromLeftEdge ? j : j - 1;\n break;\n }\n } // reached end\n\n\n if (!foundMatch) {\n indexOnLine = line.length - 1;\n }\n\n return indexOnLine;\n },\n\n /**\n * Moves cursor down\n * @param {Event} e Event object\n */\n moveCursorDown: function (e) {\n if (this.selectionStart >= this._text.length && this.selectionEnd >= this._text.length) {\n return;\n }\n\n this._moveCursorUpOrDown('Down', e);\n },\n\n /**\n * Moves cursor up\n * @param {Event} e Event object\n */\n moveCursorUp: function (e) {\n if (this.selectionStart === 0 && this.selectionEnd === 0) {\n return;\n }\n\n this._moveCursorUpOrDown('Up', e);\n },\n\n /**\n * Moves cursor up or down, fires the events\n * @param {String} direction 'Up' or 'Down'\n * @param {Event} e Event object\n */\n _moveCursorUpOrDown: function (direction, e) {\n // getUpCursorOffset\n // getDownCursorOffset\n var action = 'get' + direction + 'CursorOffset',\n offset = this[action](e, this._selectionDirection === 'right');\n\n if (e.shiftKey) {\n this.moveCursorWithShift(offset);\n } else {\n this.moveCursorWithoutShift(offset);\n }\n\n if (offset !== 0) {\n this.setSelectionInBoundaries();\n this.abortCursorAnimation();\n this._currentCursorOpacity = 1;\n this.initDelayedCursor();\n\n this._fireSelectionChanged();\n\n this._updateTextarea();\n }\n },\n\n /**\n * Moves cursor with shift\n * @param {Number} offset\n */\n moveCursorWithShift: function (offset) {\n var newSelection = this._selectionDirection === 'left' ? this.selectionStart + offset : this.selectionEnd + offset;\n this.setSelectionStartEndWithShift(this.selectionStart, this.selectionEnd, newSelection);\n return offset !== 0;\n },\n\n /**\n * Moves cursor up without shift\n * @param {Number} offset\n */\n moveCursorWithoutShift: function (offset) {\n if (offset < 0) {\n this.selectionStart += offset;\n this.selectionEnd = this.selectionStart;\n } else {\n this.selectionEnd += offset;\n this.selectionStart = this.selectionEnd;\n }\n\n return offset !== 0;\n },\n\n /**\n * Moves cursor left\n * @param {Event} e Event object\n */\n moveCursorLeft: function (e) {\n if (this.selectionStart === 0 && this.selectionEnd === 0) {\n return;\n }\n\n this._moveCursorLeftOrRight('Left', e);\n },\n\n /**\n * @private\n * @return {Boolean} true if a change happened\n */\n _move: function (e, prop, direction) {\n var newValue;\n\n if (e.altKey) {\n newValue = this['findWordBoundary' + direction](this[prop]);\n } else if (e.metaKey || e.keyCode === 35 || e.keyCode === 36) {\n newValue = this['findLineBoundary' + direction](this[prop]);\n } else {\n this[prop] += direction === 'Left' ? -1 : 1;\n return true;\n }\n\n if (typeof newValue !== undefined && this[prop] !== newValue) {\n this[prop] = newValue;\n return true;\n }\n },\n\n /**\n * @private\n */\n _moveLeft: function (e, prop) {\n return this._move(e, prop, 'Left');\n },\n\n /**\n * @private\n */\n _moveRight: function (e, prop) {\n return this._move(e, prop, 'Right');\n },\n\n /**\n * Moves cursor left without keeping selection\n * @param {Event} e\n */\n moveCursorLeftWithoutShift: function (e) {\n var change = true;\n this._selectionDirection = 'left'; // only move cursor when there is no selection,\n // otherwise we discard it, and leave cursor on same place\n\n if (this.selectionEnd === this.selectionStart && this.selectionStart !== 0) {\n change = this._moveLeft(e, 'selectionStart');\n }\n\n this.selectionEnd = this.selectionStart;\n return change;\n },\n\n /**\n * Moves cursor left while keeping selection\n * @param {Event} e\n */\n moveCursorLeftWithShift: function (e) {\n if (this._selectionDirection === 'right' && this.selectionStart !== this.selectionEnd) {\n return this._moveLeft(e, 'selectionEnd');\n } else if (this.selectionStart !== 0) {\n this._selectionDirection = 'left';\n return this._moveLeft(e, 'selectionStart');\n }\n },\n\n /**\n * Moves cursor right\n * @param {Event} e Event object\n */\n moveCursorRight: function (e) {\n if (this.selectionStart >= this._text.length && this.selectionEnd >= this._text.length) {\n return;\n }\n\n this._moveCursorLeftOrRight('Right', e);\n },\n\n /**\n * Moves cursor right or Left, fires event\n * @param {String} direction 'Left', 'Right'\n * @param {Event} e Event object\n */\n _moveCursorLeftOrRight: function (direction, e) {\n var actionName = 'moveCursor' + direction + 'With';\n this._currentCursorOpacity = 1;\n\n if (e.shiftKey) {\n actionName += 'Shift';\n } else {\n actionName += 'outShift';\n }\n\n if (this[actionName](e)) {\n this.abortCursorAnimation();\n this.initDelayedCursor();\n\n this._fireSelectionChanged();\n\n this._updateTextarea();\n }\n },\n\n /**\n * Moves cursor right while keeping selection\n * @param {Event} e\n */\n moveCursorRightWithShift: function (e) {\n if (this._selectionDirection === 'left' && this.selectionStart !== this.selectionEnd) {\n return this._moveRight(e, 'selectionStart');\n } else if (this.selectionEnd !== this._text.length) {\n this._selectionDirection = 'right';\n return this._moveRight(e, 'selectionEnd');\n }\n },\n\n /**\n * Moves cursor right without keeping selection\n * @param {Event} e Event object\n */\n moveCursorRightWithoutShift: function (e) {\n var changed = true;\n this._selectionDirection = 'right';\n\n if (this.selectionStart === this.selectionEnd) {\n changed = this._moveRight(e, 'selectionStart');\n this.selectionEnd = this.selectionStart;\n } else {\n this.selectionStart = this.selectionEnd;\n }\n\n return changed;\n },\n\n /**\n * Removes characters from start/end\n * start/end ar per grapheme position in _text array.\n *\n * @param {Number} start\n * @param {Number} end default to start + 1\n */\n removeChars: function (start, end) {\n if (typeof end === 'undefined') {\n end = start + 1;\n }\n\n this.removeStyleFromTo(start, end);\n\n this._text.splice(start, end - start);\n\n this.text = this._text.join('');\n this.set('dirty', true);\n\n if (this._shouldClearDimensionCache()) {\n this.initDimensions();\n this.setCoords();\n }\n\n this._removeExtraneousStyles();\n },\n\n /**\n * insert characters at start position, before start position.\n * start equal 1 it means the text get inserted between actual grapheme 0 and 1\n * if style array is provided, it must be as the same length of text in graphemes\n * if end is provided and is bigger than start, old text is replaced.\n * start/end ar per grapheme position in _text array.\n *\n * @param {String} text text to insert\n * @param {Array} style array of style objects\n * @param {Number} start\n * @param {Number} end default to start + 1\n */\n insertChars: function (text, style, start, end) {\n if (typeof end === 'undefined') {\n end = start;\n }\n\n if (end > start) {\n this.removeStyleFromTo(start, end);\n }\n\n var graphemes = fabric.util.string.graphemeSplit(text);\n this.insertNewStyleBlock(graphemes, start, style);\n this._text = [].concat(this._text.slice(0, start), graphemes, this._text.slice(end));\n this.text = this._text.join('');\n this.set('dirty', true);\n\n if (this._shouldClearDimensionCache()) {\n this.initDimensions();\n this.setCoords();\n }\n\n this._removeExtraneousStyles();\n }\n});\n/* _TO_SVG_START_ */\n\n(function () {\n var toFixed = fabric.util.toFixed,\n multipleSpacesRegex = / +/g;\n fabric.util.object.extend(fabric.Text.prototype,\n /** @lends fabric.Text.prototype */\n {\n /**\n * Returns SVG representation of an instance\n * @param {Function} [reviver] Method for further parsing of svg representation.\n * @return {String} svg representation of an instance\n */\n _toSVG: function () {\n var offsets = this._getSVGLeftTopOffsets(),\n textAndBg = this._getSVGTextAndBg(offsets.textTop, offsets.textLeft);\n\n return this._wrapSVGTextAndBg(textAndBg);\n },\n\n /**\n * Returns svg representation of an instance\n * @param {Function} [reviver] Method for further parsing of svg representation.\n * @return {String} svg representation of an instance\n */\n toSVG: function (reviver) {\n return this._createBaseSVGMarkup(this._toSVG(), {\n reviver: reviver,\n noStyle: true,\n withShadow: true\n });\n },\n\n /**\n * @private\n */\n _getSVGLeftTopOffsets: function () {\n return {\n textLeft: -this.width / 2,\n textTop: -this.height / 2,\n lineTop: this.getHeightOfLine(0)\n };\n },\n\n /**\n * @private\n */\n _wrapSVGTextAndBg: function (textAndBg) {\n var noShadow = true,\n textDecoration = this.getSvgTextDecoration(this);\n return [textAndBg.textBgRects.join(''), '\\t\\t<text xml:space=\"preserve\" ', this.fontFamily ? 'font-family=\"' + this.fontFamily.replace(/\"/g, '\\'') + '\" ' : '', this.fontSize ? 'font-size=\"' + this.fontSize + '\" ' : '', this.fontStyle ? 'font-style=\"' + this.fontStyle + '\" ' : '', this.fontWeight ? 'font-weight=\"' + this.fontWeight + '\" ' : '', textDecoration ? 'text-decoration=\"' + textDecoration + '\" ' : '', 'style=\"', this.getSvgStyles(noShadow), '\"', this.addPaintOrder(), ' >', textAndBg.textSpans.join(''), '</text>\\n'];\n },\n\n /**\n * @private\n * @param {Number} textTopOffset Text top offset\n * @param {Number} textLeftOffset Text left offset\n * @return {Object}\n */\n _getSVGTextAndBg: function (textTopOffset, textLeftOffset) {\n var textSpans = [],\n textBgRects = [],\n height = textTopOffset,\n lineOffset; // bounding-box background\n\n this._setSVGBg(textBgRects); // text and text-background\n\n\n for (var i = 0, len = this._textLines.length; i < len; i++) {\n lineOffset = this._getLineLeftOffset(i);\n\n if (this.textBackgroundColor || this.styleHas('textBackgroundColor', i)) {\n this._setSVGTextLineBg(textBgRects, i, textLeftOffset + lineOffset, height);\n }\n\n this._setSVGTextLineText(textSpans, i, textLeftOffset + lineOffset, height);\n\n height += this.getHeightOfLine(i);\n }\n\n return {\n textSpans: textSpans,\n textBgRects: textBgRects\n };\n },\n\n /**\n * @private\n */\n _createTextCharSpan: function (_char, styleDecl, left, top) {\n var shouldUseWhitespace = _char !== _char.trim() || _char.match(multipleSpacesRegex),\n styleProps = this.getSvgSpanStyles(styleDecl, shouldUseWhitespace),\n fillStyles = styleProps ? 'style=\"' + styleProps + '\"' : '',\n dy = styleDecl.deltaY,\n dySpan = '',\n NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS;\n\n if (dy) {\n dySpan = ' dy=\"' + toFixed(dy, NUM_FRACTION_DIGITS) + '\" ';\n }\n\n return ['<tspan x=\"', toFixed(left, NUM_FRACTION_DIGITS), '\" y=\"', toFixed(top, NUM_FRACTION_DIGITS), '\" ', dySpan, fillStyles, '>', fabric.util.string.escapeXml(_char), '</tspan>'].join('');\n },\n _setSVGTextLineText: function (textSpans, lineIndex, textLeftOffset, textTopOffset) {\n // set proper line offset\n var lineHeight = this.getHeightOfLine(lineIndex),\n isJustify = this.textAlign.indexOf('justify') !== -1,\n actualStyle,\n nextStyle,\n charsToRender = '',\n charBox,\n style,\n boxWidth = 0,\n line = this._textLines[lineIndex],\n timeToRender;\n textTopOffset += lineHeight * (1 - this._fontSizeFraction) / this.lineHeight;\n\n for (var i = 0, len = line.length - 1; i <= len; i++) {\n timeToRender = i === len || this.charSpacing;\n charsToRender += line[i];\n charBox = this.__charBounds[lineIndex][i];\n\n if (boxWidth === 0) {\n textLeftOffset += charBox.kernedWidth - charBox.width;\n boxWidth += charBox.width;\n } else {\n boxWidth += charBox.kernedWidth;\n }\n\n if (isJustify && !timeToRender) {\n if (this._reSpaceAndTab.test(line[i])) {\n timeToRender = true;\n }\n }\n\n if (!timeToRender) {\n // if we have charSpacing, we render char by char\n actualStyle = actualStyle || this.getCompleteStyleDeclaration(lineIndex, i);\n nextStyle = this.getCompleteStyleDeclaration(lineIndex, i + 1);\n timeToRender = this._hasStyleChangedForSvg(actualStyle, nextStyle);\n }\n\n if (timeToRender) {\n style = this._getStyleDeclaration(lineIndex, i) || {};\n textSpans.push(this._createTextCharSpan(charsToRender, style, textLeftOffset, textTopOffset));\n charsToRender = '';\n actualStyle = nextStyle;\n textLeftOffset += boxWidth;\n boxWidth = 0;\n }\n }\n },\n _pushTextBgRect: function (textBgRects, color, left, top, width, height) {\n var NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS;\n textBgRects.push('\\t\\t<rect ', this._getFillAttributes(color), ' x=\"', toFixed(left, NUM_FRACTION_DIGITS), '\" y=\"', toFixed(top, NUM_FRACTION_DIGITS), '\" width=\"', toFixed(width, NUM_FRACTION_DIGITS), '\" height=\"', toFixed(height, NUM_FRACTION_DIGITS), '\"></rect>\\n');\n },\n _setSVGTextLineBg: function (textBgRects, i, leftOffset, textTopOffset) {\n var line = this._textLines[i],\n heightOfLine = this.getHeightOfLine(i) / this.lineHeight,\n boxWidth = 0,\n boxStart = 0,\n charBox,\n currentColor,\n lastColor = this.getValueOfPropertyAt(i, 0, 'textBackgroundColor');\n\n for (var j = 0, jlen = line.length; j < jlen; j++) {\n charBox = this.__charBounds[i][j];\n currentColor = this.getValueOfPropertyAt(i, j, 'textBackgroundColor');\n\n if (currentColor !== lastColor) {\n lastColor && this._pushTextBgRect(textBgRects, lastColor, leftOffset + boxStart, textTopOffset, boxWidth, heightOfLine);\n boxStart = charBox.left;\n boxWidth = charBox.width;\n lastColor = currentColor;\n } else {\n boxWidth += charBox.kernedWidth;\n }\n }\n\n currentColor && this._pushTextBgRect(textBgRects, currentColor, leftOffset + boxStart, textTopOffset, boxWidth, heightOfLine);\n },\n\n /**\n * Adobe Illustrator (at least CS5) is unable to render rgba()-based fill values\n * we work around it by \"moving\" alpha channel into opacity attribute and setting fill's alpha to 1\n *\n * @private\n * @param {*} value\n * @return {String}\n */\n _getFillAttributes: function (value) {\n var fillColor = value && typeof value === 'string' ? new fabric.Color(value) : '';\n\n if (!fillColor || !fillColor.getSource() || fillColor.getAlpha() === 1) {\n return 'fill=\"' + value + '\"';\n }\n\n return 'opacity=\"' + fillColor.getAlpha() + '\" fill=\"' + fillColor.setAlpha(1).toRgb() + '\"';\n },\n\n /**\n * @private\n */\n _getSVGLineTopOffset: function (lineIndex) {\n var lineTopOffset = 0,\n lastHeight = 0;\n\n for (var j = 0; j < lineIndex; j++) {\n lineTopOffset += this.getHeightOfLine(j);\n }\n\n lastHeight = this.getHeightOfLine(j);\n return {\n lineTop: lineTopOffset,\n offset: (this._fontSizeMult - this._fontSizeFraction) * lastHeight / (this.lineHeight * this._fontSizeMult)\n };\n },\n\n /**\n * Returns styles-string for svg-export\n * @param {Boolean} skipShadow a boolean to skip shadow filter output\n * @return {String}\n */\n getSvgStyles: function (skipShadow) {\n var svgStyle = fabric.Object.prototype.getSvgStyles.call(this, skipShadow);\n return svgStyle + ' white-space: pre;';\n }\n });\n})();\n/* _TO_SVG_END_ */\n\n\n(function (global) {\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = {});\n /**\n * Textbox class, based on IText, allows the user to resize the text rectangle\n * and wraps lines automatically. Textboxes have their Y scaling locked, the\n * user can only change width. Height is adjusted automatically based on the\n * wrapping of lines.\n * @class fabric.Textbox\n * @extends fabric.IText\n * @mixes fabric.Observable\n * @return {fabric.Textbox} thisArg\n * @see {@link fabric.Textbox#initialize} for constructor definition\n */\n\n fabric.Textbox = fabric.util.createClass(fabric.IText, fabric.Observable, {\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'textbox',\n\n /**\n * Minimum width of textbox, in pixels.\n * @type Number\n * @default\n */\n minWidth: 20,\n\n /**\n * Minimum calculated width of a textbox, in pixels.\n * fixed to 2 so that an empty textbox cannot go to 0\n * and is still selectable without text.\n * @type Number\n * @default\n */\n dynamicMinWidth: 2,\n\n /**\n * Cached array of text wrapping.\n * @type Array\n */\n __cachedLines: null,\n\n /**\n * Override standard Object class values\n */\n lockScalingFlip: true,\n\n /**\n * Override standard Object class values\n * Textbox needs this on false\n */\n noScaleCache: false,\n\n /**\n * Properties which when set cause object to change dimensions\n * @type Object\n * @private\n */\n _dimensionAffectingProps: fabric.Text.prototype._dimensionAffectingProps.concat('width'),\n\n /**\n * Use this regular expression to split strings in breakable lines\n * @private\n */\n _wordJoiners: /[ \\t\\r]/,\n\n /**\n * Use this boolean property in order to split strings that have no white space concept.\n * this is a cheap way to help with chinese/japaense\n * @type Boolean\n * @since 2.6.0\n */\n splitByGrapheme: false,\n\n /**\n * Unlike superclass's version of this function, Textbox does not update\n * its width.\n * @private\n * @override\n */\n initDimensions: function () {\n if (this.__skipDimension) {\n return;\n }\n\n this.isEditing && this.initDelayedCursor();\n this.clearContextTop();\n\n this._clearCache(); // clear dynamicMinWidth as it will be different after we re-wrap line\n\n\n this.dynamicMinWidth = 0; // wrap lines\n\n this._styleMap = this._generateStyleMap(this._splitText()); // if after wrapping, the width is smaller than dynamicMinWidth, change the width and re-wrap\n\n if (this.dynamicMinWidth > this.width) {\n this._set('width', this.dynamicMinWidth);\n }\n\n if (this.textAlign.indexOf('justify') !== -1) {\n // once text is measured we need to make space fatter to make justified text.\n this.enlargeSpaces();\n } // clear cache and re-calculate height\n\n\n this.height = this.calcTextHeight();\n this.saveState({\n propertySet: '_dimensionAffectingProps'\n });\n },\n\n /**\n * Generate an object that translates the style object so that it is\n * broken up by visual lines (new lines and automatic wrapping).\n * The original text styles object is broken up by actual lines (new lines only),\n * which is only sufficient for Text / IText\n * @private\n */\n _generateStyleMap: function (textInfo) {\n var realLineCount = 0,\n realLineCharCount = 0,\n charCount = 0,\n map = {};\n\n for (var i = 0; i < textInfo.graphemeLines.length; i++) {\n if (textInfo.graphemeText[charCount] === '\\n' && i > 0) {\n realLineCharCount = 0;\n charCount++;\n realLineCount++;\n } else if (!this.splitByGrapheme && this._reSpaceAndTab.test(textInfo.graphemeText[charCount]) && i > 0) {\n // this case deals with space's that are removed from end of lines when wrapping\n realLineCharCount++;\n charCount++;\n }\n\n map[i] = {\n line: realLineCount,\n offset: realLineCharCount\n };\n charCount += textInfo.graphemeLines[i].length;\n realLineCharCount += textInfo.graphemeLines[i].length;\n }\n\n return map;\n },\n\n /**\n * Returns true if object has a style property or has it on a specified line\n * @param {Number} lineIndex\n * @return {Boolean}\n */\n styleHas: function (property, lineIndex) {\n if (this._styleMap && !this.isWrapping) {\n var map = this._styleMap[lineIndex];\n\n if (map) {\n lineIndex = map.line;\n }\n }\n\n return fabric.Text.prototype.styleHas.call(this, property, lineIndex);\n },\n\n /**\n * Returns true if object has no styling or no styling in a line\n * @param {Number} lineIndex , lineIndex is on wrapped lines.\n * @return {Boolean}\n */\n isEmptyStyles: function (lineIndex) {\n if (!this.styles) {\n return true;\n }\n\n var offset = 0,\n nextLineIndex = lineIndex + 1,\n nextOffset,\n obj,\n shouldLimit = false,\n map = this._styleMap[lineIndex],\n mapNextLine = this._styleMap[lineIndex + 1];\n\n if (map) {\n lineIndex = map.line;\n offset = map.offset;\n }\n\n if (mapNextLine) {\n nextLineIndex = mapNextLine.line;\n shouldLimit = nextLineIndex === lineIndex;\n nextOffset = mapNextLine.offset;\n }\n\n obj = typeof lineIndex === 'undefined' ? this.styles : {\n line: this.styles[lineIndex]\n };\n\n for (var p1 in obj) {\n for (var p2 in obj[p1]) {\n if (p2 >= offset && (!shouldLimit || p2 < nextOffset)) {\n // eslint-disable-next-line no-unused-vars\n for (var p3 in obj[p1][p2]) {\n return false;\n }\n }\n }\n }\n\n return true;\n },\n\n /**\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @private\n */\n _getStyleDeclaration: function (lineIndex, charIndex) {\n if (this._styleMap && !this.isWrapping) {\n var map = this._styleMap[lineIndex];\n\n if (!map) {\n return null;\n }\n\n lineIndex = map.line;\n charIndex = map.offset + charIndex;\n }\n\n return this.callSuper('_getStyleDeclaration', lineIndex, charIndex);\n },\n\n /**\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @param {Object} style\n * @private\n */\n _setStyleDeclaration: function (lineIndex, charIndex, style) {\n var map = this._styleMap[lineIndex];\n lineIndex = map.line;\n charIndex = map.offset + charIndex;\n this.styles[lineIndex][charIndex] = style;\n },\n\n /**\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @private\n */\n _deleteStyleDeclaration: function (lineIndex, charIndex) {\n var map = this._styleMap[lineIndex];\n lineIndex = map.line;\n charIndex = map.offset + charIndex;\n delete this.styles[lineIndex][charIndex];\n },\n\n /**\n * probably broken need a fix\n * Returns the real style line that correspond to the wrapped lineIndex line\n * Used just to verify if the line does exist or not.\n * @param {Number} lineIndex\n * @returns {Boolean} if the line exists or not\n * @private\n */\n _getLineStyle: function (lineIndex) {\n var map = this._styleMap[lineIndex];\n return !!this.styles[map.line];\n },\n\n /**\n * Set the line style to an empty object so that is initialized\n * @param {Number} lineIndex\n * @param {Object} style\n * @private\n */\n _setLineStyle: function (lineIndex) {\n var map = this._styleMap[lineIndex];\n this.styles[map.line] = {};\n },\n\n /**\n * Wraps text using the 'width' property of Textbox. First this function\n * splits text on newlines, so we preserve newlines entered by the user.\n * Then it wraps each line using the width of the Textbox by calling\n * _wrapLine().\n * @param {Array} lines The string array of text that is split into lines\n * @param {Number} desiredWidth width you want to wrap to\n * @returns {Array} Array of lines\n */\n _wrapText: function (lines, desiredWidth) {\n var wrapped = [],\n i;\n this.isWrapping = true;\n\n for (i = 0; i < lines.length; i++) {\n wrapped = wrapped.concat(this._wrapLine(lines[i], i, desiredWidth));\n }\n\n this.isWrapping = false;\n return wrapped;\n },\n\n /**\n * Helper function to measure a string of text, given its lineIndex and charIndex offset\n * it gets called when charBounds are not available yet.\n * @param {CanvasRenderingContext2D} ctx\n * @param {String} text\n * @param {number} lineIndex\n * @param {number} charOffset\n * @returns {number}\n * @private\n */\n _measureWord: function (word, lineIndex, charOffset) {\n var width = 0,\n prevGrapheme,\n skipLeft = true;\n charOffset = charOffset || 0;\n\n for (var i = 0, len = word.length; i < len; i++) {\n var box = this._getGraphemeBox(word[i], lineIndex, i + charOffset, prevGrapheme, skipLeft);\n\n width += box.kernedWidth;\n prevGrapheme = word[i];\n }\n\n return width;\n },\n\n /**\n * Wraps a line of text using the width of the Textbox and a context.\n * @param {Array} line The grapheme array that represent the line\n * @param {Number} lineIndex\n * @param {Number} desiredWidth width you want to wrap the line to\n * @param {Number} reservedSpace space to remove from wrapping for custom functionalities\n * @returns {Array} Array of line(s) into which the given text is wrapped\n * to.\n */\n _wrapLine: function (_line, lineIndex, desiredWidth, reservedSpace) {\n var lineWidth = 0,\n splitByGrapheme = this.splitByGrapheme,\n graphemeLines = [],\n line = [],\n // spaces in different languges?\n words = splitByGrapheme ? fabric.util.string.graphemeSplit(_line) : _line.split(this._wordJoiners),\n word = '',\n offset = 0,\n infix = splitByGrapheme ? '' : ' ',\n wordWidth = 0,\n infixWidth = 0,\n largestWordWidth = 0,\n lineJustStarted = true,\n additionalSpace = this._getWidthOfCharSpacing(),\n reservedSpace = reservedSpace || 0; // fix a difference between split and graphemeSplit\n\n\n if (words.length === 0) {\n words.push([]);\n }\n\n desiredWidth -= reservedSpace;\n\n for (var i = 0; i < words.length; i++) {\n // if using splitByGrapheme words are already in graphemes.\n word = splitByGrapheme ? words[i] : fabric.util.string.graphemeSplit(words[i]);\n wordWidth = this._measureWord(word, lineIndex, offset);\n offset += word.length;\n lineWidth += infixWidth + wordWidth - additionalSpace;\n\n if (lineWidth >= desiredWidth && !lineJustStarted) {\n graphemeLines.push(line);\n line = [];\n lineWidth = wordWidth;\n lineJustStarted = true;\n } else {\n lineWidth += additionalSpace;\n }\n\n if (!lineJustStarted && !splitByGrapheme) {\n line.push(infix);\n }\n\n line = line.concat(word);\n infixWidth = splitByGrapheme ? 0 : this._measureWord([infix], lineIndex, offset);\n offset++;\n lineJustStarted = false; // keep track of largest word\n\n if (wordWidth > largestWordWidth) {\n largestWordWidth = wordWidth;\n }\n }\n\n i && graphemeLines.push(line);\n\n if (largestWordWidth + reservedSpace > this.dynamicMinWidth) {\n this.dynamicMinWidth = largestWordWidth - additionalSpace + reservedSpace;\n }\n\n return graphemeLines;\n },\n\n /**\n * Detect if the text line is ended with an hard break\n * text and itext do not have wrapping, return false\n * @param {Number} lineIndex text to split\n * @return {Boolean}\n */\n isEndOfWrapping: function (lineIndex) {\n if (!this._styleMap[lineIndex + 1]) {\n // is last line, return true;\n return true;\n }\n\n if (this._styleMap[lineIndex + 1].line !== this._styleMap[lineIndex].line) {\n // this is last line before a line break, return true;\n return true;\n }\n\n return false;\n },\n\n /**\n * Detect if a line has a linebreak and so we need to account for it when moving\n * and counting style.\n * @return Number\n */\n missingNewlineOffset: function (lineIndex) {\n if (this.splitByGrapheme) {\n return this.isEndOfWrapping(lineIndex) ? 1 : 0;\n }\n\n return 1;\n },\n\n /**\n * Gets lines of text to render in the Textbox. This function calculates\n * text wrapping on the fly every time it is called.\n * @param {String} text text to split\n * @returns {Array} Array of lines in the Textbox.\n * @override\n */\n _splitTextIntoLines: function (text) {\n var newText = fabric.Text.prototype._splitTextIntoLines.call(this, text),\n graphemeLines = this._wrapText(newText.lines, this.width),\n lines = new Array(graphemeLines.length);\n\n for (var i = 0; i < graphemeLines.length; i++) {\n lines[i] = graphemeLines[i].join('');\n }\n\n newText.lines = lines;\n newText.graphemeLines = graphemeLines;\n return newText;\n },\n getMinWidth: function () {\n return Math.max(this.minWidth, this.dynamicMinWidth);\n },\n _removeExtraneousStyles: function () {\n var linesToKeep = {};\n\n for (var prop in this._styleMap) {\n if (this._textLines[prop]) {\n linesToKeep[this._styleMap[prop].line] = 1;\n }\n }\n\n for (var prop in this.styles) {\n if (!linesToKeep[prop]) {\n delete this.styles[prop];\n }\n }\n },\n\n /**\n * Returns object representation of an instance\n * @method toObject\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject: function (propertiesToInclude) {\n return this.callSuper('toObject', ['minWidth', 'splitByGrapheme'].concat(propertiesToInclude));\n }\n });\n /**\n * Returns fabric.Textbox instance from an object representation\n * @static\n * @memberOf fabric.Textbox\n * @param {Object} object Object to create an instance from\n * @param {Function} [callback] Callback to invoke when an fabric.Textbox instance is created\n */\n\n fabric.Textbox.fromObject = function (object, callback) {\n return fabric.Object._fromObject('Textbox', object, callback, 'text');\n };\n})(typeof exports !== 'undefined' ? exports : this);\n\n(function () {\n var controlsUtils = fabric.controlsUtils,\n scaleSkewStyleHandler = controlsUtils.scaleSkewCursorStyleHandler,\n scaleStyleHandler = controlsUtils.scaleCursorStyleHandler,\n scalingEqually = controlsUtils.scalingEqually,\n scalingYOrSkewingX = controlsUtils.scalingYOrSkewingX,\n scalingXOrSkewingY = controlsUtils.scalingXOrSkewingY,\n scaleOrSkewActionName = controlsUtils.scaleOrSkewActionName,\n objectControls = fabric.Object.prototype.controls;\n objectControls.ml = new fabric.Control({\n x: -0.5,\n y: 0,\n cursorStyleHandler: scaleSkewStyleHandler,\n actionHandler: scalingXOrSkewingY,\n getActionName: scaleOrSkewActionName\n });\n objectControls.mr = new fabric.Control({\n x: 0.5,\n y: 0,\n cursorStyleHandler: scaleSkewStyleHandler,\n actionHandler: scalingXOrSkewingY,\n getActionName: scaleOrSkewActionName\n });\n objectControls.mb = new fabric.Control({\n x: 0,\n y: 0.5,\n cursorStyleHandler: scaleSkewStyleHandler,\n actionHandler: scalingYOrSkewingX,\n getActionName: scaleOrSkewActionName\n });\n objectControls.mt = new fabric.Control({\n x: 0,\n y: -0.5,\n cursorStyleHandler: scaleSkewStyleHandler,\n actionHandler: scalingYOrSkewingX,\n getActionName: scaleOrSkewActionName\n });\n objectControls.tl = new fabric.Control({\n x: -0.5,\n y: -0.5,\n cursorStyleHandler: scaleStyleHandler,\n actionHandler: scalingEqually\n });\n objectControls.tr = new fabric.Control({\n x: 0.5,\n y: -0.5,\n cursorStyleHandler: scaleStyleHandler,\n actionHandler: scalingEqually\n });\n objectControls.bl = new fabric.Control({\n x: -0.5,\n y: 0.5,\n cursorStyleHandler: scaleStyleHandler,\n actionHandler: scalingEqually\n });\n objectControls.br = new fabric.Control({\n x: 0.5,\n y: 0.5,\n cursorStyleHandler: scaleStyleHandler,\n actionHandler: scalingEqually\n });\n objectControls.mtr = new fabric.Control({\n x: 0,\n y: -0.5,\n actionHandler: controlsUtils.rotationWithSnapping,\n cursorStyleHandler: controlsUtils.rotationStyleHandler,\n offsetY: -40,\n withConnection: true,\n actionName: 'rotate'\n });\n\n if (fabric.Textbox) {\n // this is breaking the prototype inheritance, no time / ideas to fix it.\n // is important to document that if you want to have all objects to have a\n // specific custom control, you have to add it to Object prototype and to Textbox\n // prototype. The controls are shared as references. So changes to control `tr`\n // can still apply to all objects if needed.\n var textBoxControls = fabric.Textbox.prototype.controls = {};\n textBoxControls.mtr = objectControls.mtr;\n textBoxControls.tr = objectControls.tr;\n textBoxControls.br = objectControls.br;\n textBoxControls.tl = objectControls.tl;\n textBoxControls.bl = objectControls.bl;\n textBoxControls.mt = objectControls.mt;\n textBoxControls.mb = objectControls.mb;\n textBoxControls.mr = new fabric.Control({\n x: 0.5,\n y: 0,\n actionHandler: controlsUtils.changeWidth,\n cursorStyleHandler: scaleSkewStyleHandler,\n actionName: 'resizing'\n });\n textBoxControls.ml = new fabric.Control({\n x: -0.5,\n y: 0,\n actionHandler: controlsUtils.changeWidth,\n cursorStyleHandler: scaleSkewStyleHandler,\n actionName: 'resizing'\n });\n }\n})();","map":{"version":3,"sources":["C:/Users/kkwan_000/Desktop/git/2017110269/minsung/node_modules/fabric/dist/fabric.js"],"names":["fabric","version","exports","define","amd","document","window","HTMLDocument","Document","implementation","createHTMLDocument","jsdom","require","virtualWindow","JSDOM","decodeURIComponent","features","FetchExternalResources","resources","jsdomImplForWrapper","implForWrapper","nodeCanvas","Canvas","DOMParser","isTouchSupported","navigator","maxTouchPoints","isLikelyNode","Buffer","SHARED_ATTRIBUTES","DPI","reNum","commaWsp","rePathCommand","reNonWord","fontPaths","iMatrix","svgNS","perfLimitSizeTotal","maxCacheSideLimit","minCacheSideLimit","charWidthsCache","textureSize","disableStyleCopyPaste","enableGLFiltering","devicePixelRatio","webkitDevicePixelRatio","mozDevicePixelRatio","browserShadowBlurConstant","arcToSegmentsCache","boundsOfCurveCache","cachesBoundsOfCurve","forceGLPutImageData","initFilterBackend","isWebglSupported","console","log","maxTextureSize","WebglFilterBackend","tileSize","Canvas2dFilterBackend","_removeEventListener","eventName","handler","__eventListeners","eventListener","indexOf","util","array","fill","on","arguments","length","prop","push","off","call","fire","options","listenersForEvent","i","len","filter","value","Observable","Collection","_objects","add","apply","_onObjectAdded","renderOnAddRemove","requestRenderAll","insertAt","object","index","nonSplicing","objects","splice","remove","somethingRemoved","_onObjectRemoved","forEachObject","callback","context","getObjects","type","concat","o","item","isEmpty","size","contains","complexity","reduce","memo","current","CommonMethods","_setOptions","set","_initGradient","filler","property","colorStops","Gradient","_initPattern","source","Pattern","_setObject","obj","_set","key","toggle","get","global","sqrt","Math","atan2","pow","PiBy180","PI","PiBy2","cos","angle","angleSlice","sin","sign","removeFromArray","idx","getRandomInt","min","max","floor","random","degreesToRadians","degrees","radiansToDegrees","radians","rotatePoint","point","origin","subtractEquals","v","rotateVector","Point","x","y","addEquals","vector","rx","ry","transformPoint","p","t","ignoreOffset","makeBoundingBoxFromPoints","points","transform","xPoints","minX","maxX","width","yPoints","minY","maxY","height","left","top","invertTransform","a","r","toFixed","number","fractionDigits","parseFloat","Number","parseUnit","fontSize","unit","exec","Text","DEFAULT_SVG_FONT_SIZE","falseFunction","getKlass","namespace","string","camelize","charAt","toUpperCase","slice","resolveNamespace","getSvgAttributes","attributes","parts","split","loadImage","url","crossOrigin","img","createImage","onLoadCallback","onload","onerror","src","undefined","substring","loadImageInDom","div","createElement","style","position","appendChild","querySelector","parentNode","removeChild","enlivenObjects","reviver","enlivenedObjects","numLoadedObjects","numTotalObjects","onLoaded","forEach","klass","fromObject","error","enlivenPatterns","patterns","numLoadedPatterns","numPatterns","enlivenedPatterns","pattern","groupSVGElements","elements","path","centerPoint","Group","sourcePath","populateWithProperties","destination","properties","Object","prototype","toString","drawDashedLine","ctx","x2","y2","da","dx","dy","rot","dc","di","draw","save","translate","moveTo","rotate","restore","createCanvasElement","copyCanvasElement","canvas","newCanvas","getContext","drawImage","toDataURL","canvasEl","format","quality","multiplyTransformMatrices","b","is2x2","qrDecompose","denom","scaleX","scaleY","skewX","skewY","translateX","translateY","calcRotateMatrix","theta","calcDimensionsMatrix","scaleMatrix","flipX","flipY","multiply","tan","composeMatrix","matrix","resetObjectTransform","target","saveObjectTransform","isTransparent","tolerance","_isTransparent","temp","imageData","getImageData","l","data","parsePreserveAspectRatioAttribute","attribute","meetOrSlice","alignX","alignY","aspectRatioAttrs","align","pop","clearFabricFontCache","fontFamily","toLowerCase","limitDimsByArea","ar","maximumArea","roughWidth","perfLimitSizeY","capValue","findScaleToFit","findScaleToCover","matrixToSVG","map","NUM_FRACTION_DIGITS","join","sizeAfterTransform","dimX","dimY","transformMatrix","bbox","_join","Array","commandLengths","m","h","c","s","q","repeatedCommands","M","segmentToBezier","th2","th3","cosTh","sinTh","cx1","cy1","mT","fromX","fromY","costh2","sinth2","costh3","sinth3","toX","toY","cp1X","cp1Y","cp2X","cp2Y","arcToSegments","large","sweep","rotateX","th","abs","px","py","rx2","ry2","py2","px2","pl","root","cx","cy","mTheta","calcVectorAngle","dtheta","segments","ceil","result","mDelta","ux","uy","vx","vy","ta","tb","getBoundsOfCurve","x0","y0","x1","y1","x3","y3","argsString","tvalues","bounds","t1","t2","b2ac","sqrtb2ac","j","jlen","mt","fromArcToBeizers","fx","fy","coords","tx","ty","segsNorm","makePathSimpler","converted","destinationPath","previous","controlX","controlY","calcLineLength","CB1","CB2","CB3","CB4","getPointOnCubicBezierIterator","p1x","p1y","p2x","p2y","p3x","p3y","p4x","p4y","pct","c1","c2","c3","c4","QB1","QB2","QB3","getPointOnQuadraticBezierIterator","pathIterator","iterator","tempP","tmpLen","perc","getPathSegmentsInfo","totalLength","info","tempInfo","command","destX","destY","getPointOnPath","infos","distance","segInfo","segPercent","segment","lerp","parsePath","pathString","currentPath","parsed","re","rNumber","rNumberCommaWsp","rFlagCommaWsp","rArcSeq","regArcArgumentSequence","RegExp","match","coordsStr","coordsParsed","trim","args","isNaN","commandLength","repeatedCommand","k","klen","getBoundsOfArc","bound","segs","drawArc","unshift","beizers","beizer","bezierCurveTo","invoke","method","byProperty","find","value1","value2","condition","extend","deep","Element","hasOwnProperty","clone","replace","character","capitalize","firstLetterOnly","escapeXml","graphemeSplit","textstring","chr","graphemes","getWholeChar","str","code","charCodeAt","next","prev","emptyFunction","IS_DONTENUM_BUGGY","addMethods","parent","superclass","constructor","returnValue","valueOf","Subclass","callSuper","methodName","parentMethod","_this","superClassMethod","createClass","shift","initialize","subclasses","couldUseAttachEvent","attachEvent","touchEvents","addListener","element","addEventListener","removeListener","removeEventListener","getTouchInfo","event","touchProp","changedTouches","getPointer","scroll","getScrollLeftTop","_evt","clientX","clientY","isTouchEvent","pointerType","setStyle","styles","elementStyle","cssText","setOpacity","normalizedProperty","styleFloat","parseEl","supportsOpacity","opacity","supportsFilters","reOpacity","es","currentStyle","hasLayout","zoom","test","_slice","getById","id","getElementById","sliceCanConvertNodelists","toArray","arrayLike","childNodes","err","arr","makeElement","tagName","el","className","htmlFor","setAttribute","addClass","wrapElement","wrapper","replaceChild","docElement","documentElement","body","scrollLeft","scrollTop","host","nodeType","getElementOffset","docElem","doc","ownerDocument","box","offset","scrollLeftTop","offsetAttributes","borderLeftWidth","borderTopWidth","paddingLeft","paddingTop","attr","parseInt","getElementStyle","getBoundingClientRect","clientLeft","clientTop","defaultView","getComputedStyle","selectProp","makeElementUnselectable","onselectstart","unselectable","makeElementSelectable","getNodeCanvas","impl","_canvas","_image","cleanUpJsdomNode","_currentSrc","_attributes","_classList","setImageSmoothing","imageSmoothingEnabled","webkitImageSmoothingEnabled","mozImageSmoothingEnabled","msImageSmoothingEnabled","oImageSmoothingEnabled","addParamToUrl","param","emptyFn","request","onComplete","xhr","XMLHttpRequest","parameters","onreadystatechange","readyState","open","setRequestHeader","send","warn","noop","defaultEasing","d","animate","requestAnimFrame","timestamp","start","Date","duration","finish","time","onChange","abort","easing","startValue","endValue","byValue","onStart","tick","ticktime","currentTime","timePerc","valuePerc","_requestAnimFrame","requestAnimationFrame","webkitRequestAnimationFrame","mozRequestAnimationFrame","oRequestAnimationFrame","msRequestAnimationFrame","setTimeout","_cancelAnimFrame","cancelAnimationFrame","clearTimeout","cancelAnimFrame","calculateColor","begin","end","pos","color","animateColor","fromColor","toColor","startColor","Color","getSource","endColor","originalOnComplete","originalOnChange","posValue","colorEasing","isArray","normalize","asin","elastic","opts","easeOutCubic","easeInOutCubic","easeInQuart","easeOutQuart","easeInOutQuart","easeInQuint","easeOutQuint","easeInOutQuint","easeInSine","easeOutSine","easeInOutSine","easeInExpo","easeOutExpo","easeInOutExpo","easeInCirc","easeOutCirc","easeInOutCirc","easeInElastic","easeOutElastic","easeInOutElastic","easeInBack","easeOutBack","easeInOutBack","easeInBounce","easeOutBounce","easeInOutBounce","ease","easeInQuad","easeOutQuad","easeInOutQuad","easeInCubic","svgValidTagNames","svgViewBoxElements","svgInvalidAncestors","svgValidParents","attributesMap","display","visibility","colorAttributes","stroke","fSize","cPath","svgValidTagNamesRegEx","getSvgRegex","svgViewBoxElementsRegEx","svgInvalidAncestorsRegEx","svgValidParentsRegEx","cssRules","gradientDefs","clipPaths","normalizeAttr","normalizeValue","parentAttributes","parseTransformAttribute","visible","fillIndex","strokeIndex","_setStrokeFillOpacity","setAlpha","getAlpha","toRgba","_getMultipleNodes","nodeNames","nodeName","nodeArray","nodeList","getElementsByTagName","rotateMatrix","multiplierX","multiplierY","skewMatrix","translateMatrix","scale","transforms","transformList","reTransformList","reTransform","attributeValue","matrices","operation","combinedMatrix","parseStyleString","oStyle","chunk","pair","parseStyleObject","getGlobalStylesForElement","svgUid","rule","elementMatchesRule","selectors","firstMatching","parentMatching","selectorMatches","doesSomeParentMatch","selector","classNames","getAttribute","matcher","elementById","node","nodelist","parseUseDirectives","xlink","substr","el2","cloneNode","currentTrans","oldLength","attrs","applyViewboxTransform","el3","createElementNS","setAttributeNS","nodeValue","firstChild","removeAttribute","reViewBoxAttrValue","viewBoxAttr","viewBoxWidth","viewBoxHeight","widthAttr","heightAttr","preserveAspectRatio","missingViewBox","missingDimAttr","toBeParsed","parsedDim","widthDiff","heightDiff","hasAncestorWithNodeName","parseSVGDocument","parsingOptions","__uid","descendants","selectNodes","getGradientDefs","getCSSRules","parseElements","instances","recursivelyParseGradientsXlink","gradient","gradientsAttrs","xlinkAttr","xLink","referencedGradient","hasAttribute","children","referenceClone","reFontDeclaration","parseFontDeclaration","fontStyle","fontWeight","lineHeight","tagArray","elList","parseAttributes","parentFontSize","ownAttributes","cssAttrs","parseStyleAttribute","normalizedAttr","normalizedValue","normalizedStyle","font","mergedAttrs","ElementsParser","parse","parsePointsAttribute","parsedPoints","allRules","rules","styleContents","textContent","ruleObj","declaration","propertyValuePairs","_rule","loadSVGFromURL","xml","responseXML","results","_options","allElements","loadSVGFromString","parser","parseFromString","regexUrl","proto","numElements","createObjects","createObject","findTag","fromElement","createCallback","checkIfDone","resolveGradient","Image","_originalElement","_removeTransformMatrix","resolveClipPath","extractPropertyDefinition","storage","regex","lastIndex","gradientDef","opacityAttr","createClipPathCallback","container","_newObj","fillRule","clipRule","usingElement","clipPath","objTransformInv","gTransform","calcTransformMatrix","clipPathTag","clipPathOwner","setPositionByOrigin","that","scalarAdd","scalar","scalarAddEquals","subtract","scalarSubtract","scalarSubtractEquals","multiplyEquals","divide","divideEquals","eq","lt","lte","gt","gte","distanceFrom","midPointFrom","setXY","setX","setY","setFromPoint","swap","Intersection","status","appendPoint","appendPoints","intersectLineLine","a1","a2","b1","b2","uaT","ubT","uB","ua","ub","intersectLinePolygon","inter","intersectPolygonPolygon","points1","points2","intersectPolygonRectangle","r1","r2","topRight","bottomLeft","inter1","inter2","inter3","inter4","setSource","_tryParsingColor","colorNameMap","sourceFromHex","sourceFromRgb","sourceFromHsl","_rgbToHsl","g","round","_source","toRgb","toHsl","hsl","toHsla","toHex","toHexa","alpha","toGrayscale","average","currentAlpha","toBlackWhite","threshold","overlayWith","otherColor","otherAlpha","otherSource","reRGBa","reHSLa","reHex","aliceblue","antiquewhite","aqua","aquamarine","azure","beige","bisque","black","blanchedalmond","blue","blueviolet","brown","burlywood","cadetblue","chartreuse","chocolate","coral","cornflowerblue","cornsilk","crimson","cyan","darkblue","darkcyan","darkgoldenrod","darkgray","darkgrey","darkgreen","darkkhaki","darkmagenta","darkolivegreen","darkorange","darkorchid","darkred","darksalmon","darkseagreen","darkslateblue","darkslategray","darkslategrey","darkturquoise","darkviolet","deeppink","deepskyblue","dimgray","dimgrey","dodgerblue","firebrick","floralwhite","forestgreen","fuchsia","gainsboro","ghostwhite","gold","goldenrod","gray","grey","green","greenyellow","honeydew","hotpink","indianred","indigo","ivory","khaki","lavender","lavenderblush","lawngreen","lemonchiffon","lightblue","lightcoral","lightcyan","lightgoldenrodyellow","lightgray","lightgrey","lightgreen","lightpink","lightsalmon","lightseagreen","lightskyblue","lightslategray","lightslategrey","lightsteelblue","lightyellow","lime","limegreen","linen","magenta","maroon","mediumaquamarine","mediumblue","mediumorchid","mediumpurple","mediumseagreen","mediumslateblue","mediumspringgreen","mediumturquoise","mediumvioletred","midnightblue","mintcream","mistyrose","moccasin","navajowhite","navy","oldlace","olive","olivedrab","orange","orangered","orchid","palegoldenrod","palegreen","paleturquoise","palevioletred","papayawhip","peachpuff","peru","pink","plum","powderblue","purple","rebeccapurple","red","rosybrown","royalblue","saddlebrown","salmon","sandybrown","seagreen","seashell","sienna","silver","skyblue","slateblue","slategray","slategrey","snow","springgreen","steelblue","teal","thistle","tomato","turquoise","violet","wheat","white","whitesmoke","yellow","yellowgreen","hue2rgb","fromRgb","fromSource","fromRgba","fromHsl","fromHsla","fromHex","isShortNotation","isRGBa","oColor","scaleMap","skewMap","controls","LEFT","TOP","RIGHT","BOTTOM","CENTER","opposite","bottom","right","center","findCornerQuadrant","fabricObject","control","cornerAngle","fireEvent","canvasOptions","scaleIsProportional","eventData","uniScaleKey","uniformIsToggled","uniformScaling","isTransformCentered","originX","originY","scalingIsForbidden","by","scaleProportionally","lockX","lockScalingX","lockY","lockScalingY","scaleCursorStyleHandler","notAllowed","n","skewCursorStyleHandler","lockSkewingY","lockSkewingX","scaleSkewCursorStyleHandler","altActionKey","scaleOrSkewActionName","isAlternative","rotationStyleHandler","lockRotation","cursorStyle","commonEventInfo","e","pointer","wrapWithFixedAnchor","actionHandler","getCenterPoint","constraint","translateToOriginPoint","actionPerformed","getLocalPoint","corner","getZoom","padding","localPoint","toLocalPoint","offsetX","offsetY","targetHasOneFlip","compensateScaleForSkew","oppositeSkew","scaleToCompensate","axis","reference","newDim","_getTransformedDimensions","newValue","skewObjectX","dimNoSkew","totalSkewSize","currentSkew","newSkew","hasSkewed","dimBeforeSkewing","skewObjectY","skewHandlerX","localPointFromCenter","finalHandler","skewHandlerY","rotationWithSnapping","pivotPoint","lastAngle","ey","ex","curAngle","hasRotated","snapAngle","snapThreshold","rightAngleLocked","leftAngleLocked","scaleObject","newPoint","dim","forbidScaling","signX","signY","gestureScale","lockScalingFlip","original","originalDistance","hasScaled","oldScaleX","oldScaleY","scaleObjectFromCorner","scaleObjectX","scaleObjectY","scalingYOrSkewingX","scalingY","scalingXOrSkewingY","scalingX","changeWidth","strokePadding","strokeWidth","strokeUniform","multiplier","oldWidth","hasResized","newWidth","dragHandler","newLeft","newTop","moveX","moveY","scalingEqually","controlsUtils","renderCircleControl","styleOverride","cornerSize","transparentCorners","cornerStrokeColor","fillStyle","cornerColor","strokeStyle","lineWidth","beginPath","arc","renderSquareControl","sizeBy2","strokeCornerColor","strokeRect","Control","actionName","withConnection","mouseDownHandler","mouseUpHandler","getActionHandler","getMouseDownHandler","getMouseUpHandler","cursorStyleHandler","getActionName","getVisibility","controlKey","objectVisibility","_controlsVisibility","setVisibility","positionHandler","finalMatrix","render","cornerStyle","getColorStop","colorAlpha","keyValuePairs","getLinearCoords","getRadialCoords","gradientTransform","gradientUnits","keys","option","addColorStop","toObject","propertiesToInclude","toSVG","markup","commonAttributes","needsSwap","withViewport","additionalTransform","sort","pathOffset","reverse","minRadius","maxRadius","percentageShift","colorStop","toLive","createLinearGradient","createRadialGradient","instance","svgOptions","colorStopEls","__convertPercentUnitsToValues","propValue","finalValue","repeat","patternTransform","setOptions","isError","patternSource","patternWidth","patternHeight","patternOffsetX","patternOffsetY","patternImgSrc","complete","naturalWidth","naturalHeight","createPattern","Shadow","blur","affectStroke","includeDefaultValues","nonScaling","_parseShadow","shadow","shadowStr","offsetsAndBlur","reOffsetsAndBlur","fBoxX","fBoxY","BLUR_BOX","StaticCanvas","CANVAS_INIT_ERROR","Error","renderAndResetBound","renderAndReset","bind","requestRenderAllBound","_initStatic","backgroundColor","backgroundImage","overlayColor","overlayImage","stateful","controlsAboveOverlay","allowTouchScrolling","viewportTransform","backgroundVpt","overlayVpt","enableRetinaScaling","vptCoords","skipOffscreen","cb","_createLowerCanvas","_initOptions","interactive","_initRetinaScaling","setOverlayImage","setBackgroundImage","setBackgroundColor","setOverlayColor","calcOffset","_isRetinaScaling","getRetinaScaling","scaleRatio","__initRetinaScaling","lowerCanvasEl","contextContainer","upperCanvasEl","contextTop","_offset","image","__setBgOverlayImage","__setBgOverlayColor","_createCanvasElement","_applyCanvasStyle","getWidth","getHeight","setWidth","setDimensions","setHeight","dimensions","cssValue","cssOnly","_setBackstoreDimension","hasLostContext","backstoreOnly","_setCssDimension","_isCurrentlyDrawing","freeDrawingBrush","_setBrushStyles","cacheCanvasEl","wrapperEl","setViewportTransform","vpt","activeObject","_activeObject","group","setCoords","calcViewportBoundaries","zoomToPoint","before","after","setZoom","absolutePan","relativePan","getElement","setupState","clearContext","clearRect","clear","_hasITextHandlers","_mouseUpITextHandler","_iTextInstances","renderAll","canvasToDrawOn","renderCanvas","isRendering","iVpt","tl","br","tr","bl","cancelRequestedRender","_renderBackground","_renderObjects","drawControls","shouldCache","_transformDone","renderCache","forClipping","drawClipPathOnCanvas","_renderOverlay","globalCompositeOperation","zoomX","zoomY","_cacheCanvas","cacheTranslationX","cacheTranslationY","_renderBackgroundOrOverlay","needsVpt","lineTo","closePath","getCenter","centerObjectH","_centerObject","centerObjectV","centerObject","viewportCenterObject","vpCenter","getVpCenter","viewportCenterObjectH","viewportCenterObjectV","toDatalessJSON","toDatalessObject","_toObjectMethod","_toObjects","_toObject","__serializeBgOverlay","excludeFromExport","originalValue","bgImage","overlay","background","svgViewportTransformation","_setSVGPreamble","_setSVGHeader","clipPathId","_setSVGBgOverlayColor","_setSVGBgOverlayImage","_setSVGObjects","suppressPreamble","encoding","viewBox","createSVGFontFacesMarkup","createSVGRefElementsMarkup","createSVGClipPathMarkup","toClipPathSVG","shouldTransform","fontList","row","rowIndex","_char","charIndex","_setSVGObject","finalWidth","finalHeight","shouldInvert","sendToBack","activeSelection","objs","bringToFront","sendBackwards","intersecting","newIdx","objsMoved","_findNewLowerIndex","isIntersecting","intersectsWithObject","isContainedWithinObject","bringForward","_findNewUpperIndex","dispose","DataURLExporter","EMPTY_JSON","supports","setLineDash","toJSON","createPNGStream","createJPEGStream","BaseBrush","strokeLineCap","strokeLineJoin","strokeMiterLimit","strokeDashArray","lineCap","miterLimit","lineJoin","_saveAndTransform","_setShadow","shadowColor","shadowBlur","shadowOffsetX","shadowOffsetY","needsFullRender","_resetShadow","PencilBrush","decimate","_points","_drawSegment","p1","p2","midPoint","quadraticCurveTo","onMouseDown","_isMainEvent","_prepareForDrawing","_captureDrawingPath","_render","onMouseMove","oldEnd","onMouseUp","_finalizeAndAddPath","_reset","_addPoint","pointerPoint","convertPointsToSVGPath","multSignX","multSignY","manyPoints","createPath","pathData","Path","decimatePoints","adjustedDistance","lastPoint","newPoints","cDistance","CircleBrush","drawDot","addPoint","dot","radius","originalRenderOnAddRemove","circles","circle","Circle","circleRadius","circleColor","SprayBrush","density","dotWidth","dotWidthVariance","randomOpacity","optimizeOverlapping","sprayChunks","addSprayChunk","sprayChunkPoints","rects","ilen","sprayChunk","rect","Rect","_getOptimizedRects","uniqueRects","uniqueRectsArray","globalAlpha","fillRect","PatternBrush","getPatternSrc","dotDistance","patternCanvas","patternCtx","getPatternSrcFunction","String","getPattern","topLeft","_getLeftTopCoords","supportLineDash","STROKE_OFFSET","_initInteractive","_createCacheCanvas","centeredScaling","centeredRotation","centeredKey","selection","selectionKey","altSelectionKey","selectionColor","selectionDashArray","selectionBorderColor","selectionLineWidth","selectionFullyContained","hoverCursor","moveCursor","defaultCursor","freeDrawingCursor","rotationCursor","notAllowedCursor","containerClass","perPixelTargetFind","targetFindTolerance","skipTargetFind","isDrawingMode","preserveObjectStacking","stopContextMenu","fireRightClick","fireMiddleClick","targets","_hoveredTarget","_hoveredTargets","_currentTransform","_groupSelector","_initWrapperElement","_createUpperCanvas","_initEventListeners","_chooseObjectsToRender","activeObjects","getActiveObjects","objsToRender","activeGroupObjects","contextTopDirty","renderTopLayer","_drawSelection","renderTop","_normalizePointer","invertedM","vptPointer","restorePointerVpt","isTargetTransparent","normalizedPointer","targetRelativeX","targetRelativeY","_cacheContext","contextCache","originalColor","selectionBackgroundColor","_renderControls","hasBorders","_isSelectionKeyPressed","selectionKeyPressed","_shouldClearSelection","evented","selectable","_shouldCenterTransform","action","altKey","centerTransform","_getOriginFromCorner","_getActionFromCorner","alreadySelected","_setupCurrentTransform","__corner","lastX","lastY","shiftKey","_beforeTransform","setCursor","cursor","groupSelector","aleft","atop","_setLineDash","findTarget","skipGroup","ignoreZoom","aObjects","activeTarget","activeTargetSubs","isTouch","_searchPossibleTargets","_findTargetCorner","_checkTarget","globalPointer","containsPoint","isEditing","subTarget","objToCheck","pointerToUse","subTargetCheck","_absolutePointer","_pointer","boundsWidth","boundsHeight","cssScale","retinaScaling","lowerCanvasClass","_copyCanvasStyle","fromEl","toEl","getSelectionContext","getSelectionElement","getActiveObject","active","_discardActiveObject","_fireSelectionEvents","oldObjects","somethingChanged","added","removed","opt","oldObject","selected","deselected","updated","setActiveObject","currentActives","_setActiveObject","onSelect","onDeselect","discardActiveObject","removeListeners","originalProperties","_realizeGroupTransformOnObject","_unwindGroupTransformOnObject","layoutProps","originalValues","realizeTransform","clearContextTop","RIGHT_CLICK","MIDDLE_CLICK","LEFT_CLICK","addEventOptions","passive","checkClick","button","mainTouchId","_bindEvents","addOrRemove","_getEventPrefix","enablePointerEvents","functor","eventjsFunctor","canvasElement","eventTypePrefix","_onResize","_onMouseDown","_onMouseMove","_onMouseOut","_onMouseEnter","_onMouseWheel","_onContextMenu","_onDoubleClick","_onDragOver","_onDragEnter","_onDragLeave","_onDrop","_onTouchStart","eventjs","_onGesture","_onDrag","_onOrientationChange","_onShake","_onLongPress","_onMouseUp","_onTouchEnd","eventsBound","_simpleEventHandler","self","__onTransformGesture","__onDrag","__onMouseWheel","_target","hiddenTextarea","focus","__onOrientationChange","__onShake","__onLongPress","preventDefault","_fireEnterLeaveEvents","stopPropagation","_cacheTransformEventData","_handleEvent","_resetTransformEventData","getPointerId","evt","identifier","pointerId","isPrimary","touches","__onMouseDown","__onMouseUp","_willAddMouseDown","__onMouseMove","_shouldRender","shouldRender","isClick","_onMouseUpInDrawingMode","_finalizeCurrentTransform","targetWasActive","_maybeGroupObjects","isMoving","_setCursorFromEvent","eventType","subTargets","absolutePointer","currentTarget","currentSubTargets","_scaling","hasStateChanged","_addEventOptions","_fire","_onMouseDownInDrawingMode","_onMouseMoveInDrawingMode","_previousPointer","shouldGroup","_shouldGroup","_handleGrouping","saveState","_fireOverOutEvents","_transformObject","fireSyntheticInOutEvents","oldTarget","evtOut","canvasEvtOut","evtIn","canvasEvtIn","_draggedoverTarget","config","inOpt","outOpt","outFires","inFires","targetChanged","previousTarget","nextTarget","reset","_performTransformAction","getCornerCursor","_updateActiveSelection","_createActiveSelection","currentActiveObjects","removeWithUpdate","addWithUpdate","_createGroup","isActiveLower","groupObjects","exitEditing","ActiveSelection","_groupSelectedObjects","_collectObjects","aGroup","currentObject","selectionX1Y1","selectionX2Y2","allowIntersect","intersectsWithRect","isContainedWithinRect","toCanvasElement","cropping","scaledWidth","scaledHeight","originalWidth","originalHeight","newZoom","vp","originalInteractive","newVp","originalRetina","originalContextTop","loadFromJSON","json","serialized","JSON","_enlivenObjects","_setBgOverlay","enlivenedCanvasClip","__setupCanvas","loaded","cbIfLoaded","__setBgOverlay","enlivedObject","_toDataURL","_toDataURLWithMultiplier","toDataURLWithMultiplier","stringify","cloneWithoutData","backgroundImageOpacity","backgroundImageStretch","supportsLineDash","objectCaching","ALIASING_LIMIT","touchCornerSize","borderColor","borderDashArray","cornerDashArray","strokeDashOffset","borderOpacityWhenMoving","borderScaleFactor","minScaleLimit","hasControls","lockMovementX","lockMovementY","statefullCache","noScaleCache","dirty","paintFirst","stateProperties","cacheProperties","colorProperties","inverted","absolutePositioned","_cacheProperties","_updateCacheCanvas","_limitCacheSize","dims","limitedDims","capped","_getCacheCanvasDimensions","objectScale","getTotalObjectScaling","neededX","neededY","targetCanvas","minCacheSize","drawingWidth","drawingHeight","dimensionsChanged","cacheWidth","cacheHeight","zoomChanged","shouldRedraw","additionalWidth","additionalHeight","shouldResizeCanvas","canvasWidth","canvasHeight","sizeGrowing","sizeShrinking","setTransform","needFullTransform","_removeDefaultValues","getObjectScaling","retina","getObjectOpacity","shouldConstrainValue","isChanged","groupNeedsUpdate","_constrainScale","isOnACache","setOnGroup","getViewportTransform","isNotVisible","isOnScreen","_setupCompositeOperation","drawSelectionBackground","_setOpacity","drawCacheOnCanvas","_removeCacheCanvas","drawObject","propertySet","isCacheDirty","hasStroke","hasFill","needsItsOwnCache","ownCaching","willDrawShadow","drawClipPathOnCache","originalFill","originalStroke","_setClippingProperties","_setStrokeStyles","_setFillStyles","_drawClipPath","skipCanvas","_getNonTransformedDimensions","_removeShadow","decl","lineDashOffset","dashArray","alternative","drawBorders","forActiveSelection","drawBordersInGroup","scaling","multX","multY","_applyPatternGradientTransform","_renderPaintInOrder","_renderStroke","_renderFill","_renderDashedStroke","_applyPatternForTransformedGradient","pCanvas","pCtx","_findCenterFromElement","_assignTransformMatrixProps","preserveAspectRatioOptions","cropX","cropY","offsetLeft","offsetTop","objectForm","_fromObject","cloneAsImage","utils","origParams","originalGroup","originalShadow","withoutTransform","withoutShadow","boundingRect","getBoundingRect","shadowOffset","originalCanvas","isType","shouldCenterOrigin","_setOriginToCenter","_resetOrigin","centerH","viewportCenterH","centerV","viewportCenterV","viewportCenter","getLocalPointer","pClicked","objectLeftTop","createAccessors","extraParam","enlivedProps","originXOffset","originYOffset","translateToGivenOrigin","fromOriginX","fromOriginY","toOriginX","toOriginY","translateToCenterPoint","leftTop","getPointByOrigin","adjustPosition","to","hypotFull","getScaledWidth","xFull","yFull","offsetFrom","offsetTo","_originalOriginX","_originalOriginY","originPoint","arrayFromCoords","multiplyMatrices","oCoords","aCoords","lineCoords","ownMatrixCache","matrixCache","_getCoords","absolute","calculate","calcACoords","calcLineCoords","getCoords","pointTL","pointBR","intersection","other","otherCoords","lines","_getImageLines","_findCrossPoints","some","_containsCenterOfCanvas","isPartiallyOnScreen","allPointsAreOutside","every","topline","rightline","bottomline","leftline","xi","xcount","iLine","lineKey","getScaledHeight","scaleToWidth","boundingRectFactor","scaleToHeight","calcCoords","calcOCoords","cosP","sinP","cosPSinP","cosPMinusSinP","_calcRotateMatrix","_calcTranslateMatrix","startMatrix","_calculateCurrentDimensions","forEachControl","w","skipCorners","_setCornerCoords","transformMatrixKey","sep","prefix","calcOwnMatrix","cache","tMatrix","_calcDimensionsTransformMatrix","flipping","noSkew","_finalizeDimensions","getSvgColorString","getSvgStyles","skipShadow","getSvgFilter","getSvgSpanStyles","useWhiteSpace","term","textDecoration","getSvgTextDecoration","deltaY","decoration","getSvgCommons","getSvgTransform","full","svgTransform","_setSVGBg","textBgRects","_getFillAttributes","_createBaseSVGMarkup","_toSVG","_createBaseClipPathSVGMarkup","objectMarkup","commonPieces","noStyle","styleInfo","shadowInfo","withShadow","vectorEffect","absoluteClipPath","clipPathMarkup","addPaintOrder","originalSet","saveProps","props","tmpObj","_isEqual","origValue","currentValue","firstPass","dashedPropertySet","forTouch","isControlVisible","touchCorner","fn","newTheta","cosTheta","sinTheta","cornerHypotenuse","touchHypotenuse","cosHalfOffset","sinHalfOffset","touchCosHalfOffset","touchSinHalfOffset","wh","shouldStroke","setControlVisible","setControlsVisibility","FX_DURATION","fxCenterObjectH","callbacks","empty","fxCenterObjectV","fxRemove","propsToAnimate","skipCallbacks","_animate","propPair","propIsColor","from","valueProgress","timeProgress","coordProps","Line","_setWidthHeight","_getLeftToOriginX","_getTopToOriginY","makeEdgeToOriginGetter","axis1","axis2","dimension","nearest","farthest","calcLinePoints","origStrokeStyle","xMult","yMult","ATTRIBUTE_NAMES","parsedAttributes","_callback","propertyNames","originValues","pi","startAngle","endAngle","setRadius","svgString","startX","startY","endX","endY","largeFlag","getRadiusX","getRadiusY","isValidRadius","Triangle","widthBy2","heightBy2","piBy2","Ellipse","getRx","getRy","_initRxRy","isRounded","Polyline","_setPositionDimensions","calcDim","_calcDimensions","correctLeftTop","fromSVG","diffX","diffY","commonRender","fromElementGenerator","_class","Polygon","_toString","fromArray","_renderPathCommands","subpathStartX","subpathStartY","_getOffsetTransform","digits","aX","aY","deltaX","pathUrl","useSetOnGroup","isAlreadyGrouped","_calcBounds","_updateObjectsCoords","_updateObjectsACoords","skipControls","_updateObjectCoords","objectLeft","objectTop","_restoreObjectsState","_includeDefaultValues","objsToObject","originalDefaults","_obj","ownCache","_restoreObjectState","destroy","toActiveSelection","ungroupOnCanvas","setObjectsCoords","onlyWidthHeight","iLen","jLen","_getBounds","minXY","maxXY","enlivedClipPath","toGroup","newGroup","childrenOverride","srcFromAttribute","_lastScaleX","_lastScaleY","_filterScalingX","_filterScalingY","minimumScaleTrigger","cacheKey","imageSmoothing","filters","_initElement","_element","setElement","removeTexture","_initConfig","applyFilters","resizeFilter","applyResizeFilters","backend","filterBackend","evictCachesForKey","getCrossOrigin","getOriginalSize","_stroke","filterObj","getSrc","hasCrop","imageMarkup","strokeSvg","imageRendering","getSvgSrc","origFill","filtered","setSrc","minimumScale","elementToFilter","_filteredEl","sourceWidth","sourceHeight","isNeutralState","imgElement","_needsResize","elementToDraw","elWidth","elHeight","sX","sY","sW","sH","maxDestW","maxDestH","_resetWidthHeight","CSS_CANVAS","_initFilters","pAR","rWidth","rHeight","pWidth","pHeight","_object","resizeFilters","fromURL","imgOptions","_getAngleValueForStraighten","straighten","fxStraighten","straightenObject","fxStraightenObject","testPrecision","gl","precision","fragmentSource","fragmentShader","createShader","FRAGMENT_SHADER","shaderSource","compileShader","getShaderParameter","COMPILE_STATUS","isSupported","getParameter","MAX_TEXTURE_SIZE","precisions","webGlPrecision","setupGLContext","captureGPUInfo","createWebGLCanvas","aPosition","Float32Array","chooseFastestCopyGLTo2DMethod","canMeasurePerf","performance","canUseImageData","ImageData","canUseArrayBuffer","ArrayBuffer","canUseUint8Clamped","Uint8ClampedArray","imageBuffer","copyGLTo2D","copyGLTo2DPutImageData","testContext","destinationWidth","destinationHeight","startTime","drawImageTime","putImageDataTime","now","copyGLTo2DDrawImage","glOptions","premultipliedAlpha","depth","stencil","antialias","clearColor","cachedTexture","getCachedTexture","pipelineState","sourceTexture","createTexture","targetTexture","originalTexture","passes","webgl","programCache","pass","tempFbo","createFramebuffer","bindFramebuffer","FRAMEBUFFER","applyTo","resizeCanvasIfNeeded","bindTexture","TEXTURE_2D","deleteTexture","deleteFramebuffer","clearWebGLCaches","textureCache","textureImageSource","texture","texParameteri","TEXTURE_MAG_FILTER","NEAREST","TEXTURE_MIN_FILTER","TEXTURE_WRAP_S","CLAMP_TO_EDGE","TEXTURE_WRAP_T","texImage2D","RGBA","UNSIGNED_BYTE","uniqueId","gpuInfo","renderer","vendor","ext","getExtension","UNMASKED_RENDERER_WEBGL","UNMASKED_VENDOR_WEBGL","dWidth","dHeight","glCanvas","sourceY","numBytes","u8","Uint8Array","u8Clamped","readPixels","imgData","putImageData","sourceElement","originalImageData","originalEl","BaseFilter","vertexSource","createProgram","vertexShader","VERTEX_SHADER","getShaderInfoLog","program","attachShader","linkProgram","getProgramParameter","LINK_STATUS","getProgramInfoLog","attributeLocations","getAttributeLocations","uniformLocations","getUniformLocations","uStepW","getUniformLocation","uStepH","getAttribLocation","sendAttributeData","aPositionData","attributeLocation","buffer","createBuffer","bindBuffer","ARRAY_BUFFER","enableVertexAttribArray","vertexAttribPointer","FLOAT","bufferData","STATIC_DRAW","_setupFrameBuffer","framebufferTexture2D","COLOR_ATTACHMENT0","_swapTextures","main","mainParameter","applyToWebGL","applyTo2d","retrieveShader","shader","useProgram","uniform1f","sendUniformData","viewport","drawArrays","TRIANGLE_STRIP","bindAdditionalTexture","textureUnit","activeTexture","TEXTURE0","unbindAdditionalTexture","getMainParameter","setMainParameter","createHelpLayer","helpLayer","mainP","ColorMatrix","colorsOnly","uColorMatrix","uConstants","constants","uniformMatrix4fv","uniform4fv","Brightness","brightness","uBrightness","Convolute","opaque","Convolute_3_1","Convolute_3_0","Convolute_5_1","Convolute_5_0","Convolute_7_1","Convolute_7_0","Convolute_9_1","Convolute_9_0","weights","side","halfSide","sw","sh","output","createImageData","dst","alphaFac","dstOff","scx","scy","srcOff","wt","uMatrix","uOpaque","uHalfSize","uSize","uniform1fv","Grayscale","lightness","luminosity","mode","uMode","uniform1i","Invert","invert","uInvert","Noise","noise","rand","uNoise","uSeed","Pixelate","blocksize","_i","_j","_iLen","_jLen","uBlocksize","RemoveColor","useAlpha","lowC","highC","uLow","uHigh","Brownie","Vintage","Kodachrome","Technicolor","Polaroid","Sepia","BlackWhite","BlendColor","screen","diff","lighten","darken","exclusion","tint","buildSource","tg","alpha1","uColor","BlendImage","mask","TEXTURE1","calculateMatrix","canvas1","blendData","blendImage","uTransformMatrix","uImage","uniformMatrix3fv","Resize","resizeType","lanczosLobes","uDelta","uTaps","uniform2fv","horizontal","taps","filterWindow","getFilterWindow","generateShader","tempScale","getTaps","lobeFunction","lanczosCreate","offsets","fragmentSourceTOP","dW","dH","lobes","xx","rcpScaleX","rcpScaleY","oW","oH","newData","sliceByTwo","hermiteFastResize","bilinearFiltering","lanczosResize","mult","doneW","doneH","stepW","stepH","tmpCanvas","dX","dY","process","u","weight","fX","fY","ratioX","icenter","ratioY","range2X","cacheLanc","range2Y","lanczos","rcpRatioX","rcpRatioY","srcData","destData","destImg","xDiff","yDiff","chnl","origPix","w4","pixels","destImage","destPixels","ratioW","ratioH","ratioWHalf","ratioHHalf","img2","data2","weightsAlpha","gxR","gxG","gxB","gxA","centerY","yy","centerX","w0","Contrast","contrast","contrastF","uContrast","Saturation","saturation","adjust","uSaturation","Blur","aspectRatio","simpleBlur","canvas2","blurLayer1","blurLayer2","ctx1","ctx2","nSamples","percent","newImageData","delta","chooseRightDelta","blurScale","Gamma","gamma","rInv","gInv","bInv","rVals","gVals","bVals","uGamma","uniform3fv","Composed","subFilters","HueRotation","rotation","rad","aThird","aThirdSqtSin","OneMinusCos","_dimensionAffectingProps","_reNewline","_reSpacesAndTabs","_reSpaceAndTab","_reWords","underline","overline","linethrough","textAlign","superscript","baseline","subscript","textBackgroundColor","_fontSizeFraction","_fontSizeMult","charSpacing","_measuringContext","_styleProperties","__charBounds","CACHE_FONT_SIZE","MIN_TEXT_WIDTH","text","__skipDimension","initDimensions","getMeasuringContext","_splitText","newLines","_splitTextIntoLines","textLines","_textLines","graphemeLines","_unwrappedTextLines","_unwrappedLines","_text","graphemeText","_clearCache","calcTextWidth","cursorWidth","enlargeSpaces","calcTextHeight","diffSpace","currentLineWidth","numberOfSpaces","accumulatedSpace","line","charBound","spaces","isEndOfWrapping","getLineWidth","kernedWidth","lineIndex","missingNewlineOffset","_setTextStyles","_renderTextLinesBackground","_renderTextDecoration","_renderText","_renderTextStroke","_renderTextFill","charStyle","forMeasuring","textBaseline","_getFontDeclaration","maxWidth","_renderTextLine","_renderChars","styleHas","lineTopOffset","heightOfLine","lineLeftOffset","lastColor","leftOffset","_getLeftOffset","topOffset","_getTopOffset","boxStart","boxWidth","charBox","currentColor","getHeightOfLine","_getLineLeftOffset","getValueOfPropertyAt","getFontCache","cacheProp","_applyCharStyles","styleDeclaration","_measureChar","previousChar","prevCharStyle","fontCache","fontDeclaration","previousFontDeclaration","couple","stylesAreEqual","coupleWidth","previousWidth","fontMultiplier","measureText","getHeightOfChar","measureLine","lineInfo","_measureLine","_getWidthOfCharSpacing","grapheme","prevGrapheme","graphemeInfo","numOfSpaces","lineBounds","_getGraphemeBox","skipLeft","getCompleteStyleDeclaration","prevStyle","previousBox","__lineHeights","maxHeight","_renderTextCommon","lineHeights","isEmptyStyles","isJustify","actualStyle","nextStyle","charsToRender","timeToRender","shortCut","_renderChar","_hasStyleChanged","_getStyleDeclaration","fullDecl","shouldFill","fillText","strokeText","setSuperscript","_setScript","setSubscript","schema","loc","get2DCursorLocation","setSelectionStyles","thisStyle","_hasStyleChangedForSvg","__lineWidths","_shouldClearDimensionCache","shouldClear","_forceClearCache","_size","_dy","lastDecoration","currentDecoration","currentFill","lastFill","styleObject","family","fontIsGeneric","genericFonts","newLine","newText","additionalProperties","needsDims","_key","parsedAnchor","textAnchor","originalStrokeWidth","textHeightScaleFactor","lineHeightDiff","scaledDiff","textHeight","offX","p3","cleanStyle","stylesCount","letterCount","stylePropertyValue","allStyleObjectPropertiesMatch","graphemeCount","stylePropertyHasBeenSet","removeStyle","lineNum","charNum","_extendStyles","_getLineStyle","_setLineStyle","_setStyleDeclaration","selectionStart","skipWrapping","getSelectionStyles","startIndex","endIndex","selectionEnd","getStyleAtPosition","lineStyle","_deleteStyleDeclaration","_deleteLineStyle","parseDecoration","IText","editable","editingBorderColor","cursorColor","cursorDelay","cursorDuration","caching","_reSpace","_currentCursorOpacity","_selectionDirection","_abortCursorAnimation","__widthOfSpace","inCompositionMode","initBehavior","setSelectionStart","_updateAndFire","setSelectionEnd","_fireSelectionChanged","_updateTextarea","initDelayedCursor","cursorOffsetCache","renderCursorOrSelection","skipRestore","_clearTextArea","boundaries","_getCursorBoundaries","renderCursor","renderSelection","_getCursorBoundariesOffsets","cursorPosition","cursorLocation","charHeight","__isMousedown","startLine","endLine","startChar","endChar","lineOffset","realLineHeight","boxEnd","compositionColor","getCurrentCharFontSize","cp","_getCurrentCharIndex","getCurrentCharColor","initAddedHandler","initRemovedHandler","initCursorSelectionHandlers","initDoubleClickSimulation","mouseMoveHandler","_initCanvasHandlers","_removeCanvasHandlers","_tick","_currentTickState","_animateCursor","targetOpacity","completeMethod","tickState","isAborted","_onTickComplete","_cursorTimeout1","_currentTickCompleteState","restart","delay","abortCursorAnimation","_cursorTimeout2","selectAll","getSelectedText","findWordBoundaryLeft","startFrom","findWordBoundaryRight","findLineBoundaryLeft","findLineBoundaryRight","searchWordBoundary","direction","selectWord","newSelectionStart","newSelectionEnd","selectLine","enterEditing","exitEditingOnOthers","initHiddenTextarea","_saveEditingProps","_setEditingProps","_textBeforeEdit","initMouseMoveHandler","getSelectionStartFromPointer","currentStart","currentEnd","__selectionStartOnMouseDown","restartCursorIfNeeded","fromStringToGraphemeSelection","smallerTextStart","graphemeStart","smallerTextEnd","graphemeEnd","fromGraphemeToStringSelection","newSelection","updateTextareaPosition","updateFromTextArea","_calcTextareaPosition","desiredPosition","compositionStart","upperCanvas","upperCanvasWidth","upperCanvasHeight","clientWidth","clientHeight","_savedProps","_restoreEditingProps","isTextChanged","_removeExtraneousStyles","removeStyleFromTo","cursorStart","cursorEnd","lineStart","charStart","lineEnd","charEnd","styleObj","shiftLineStyles","numericChar","clonedStyles","numericLine","insertNewlineStyleObject","qty","copiedStyle","currentCharStyle","newLineStyles","somethingAdded","isEndOfLine","numIndex","styleCarriedOver","insertCharStyleObject","quantity","currentLineStyles","currentLineStylesCloned","numericIndex","newStyle","insertNewStyleBlock","insertedText","cursorLoc","addedLines","linesLength","setSelectionStartEndWithShift","setSelectionInBoundaries","__lastClickTime","__lastLastClickTime","__lastPointer","__newClickTime","newPointer","isTripleClick","_stopEvent","__lastIsEditing","__lastSelected","initMousedownHandler","initMouseupHandler","initClicks","doubleClickHandler","tripleClickHandler","_mouseDownHandler","setCursorByClick","_mouseDownHandlerBefore","currentActive","mouseOffset","prevWidth","_getNewSelectionStartFromOffset","distanceBtwLastCharAndCursor","distanceBtwNextCharAndCursor","onKeyDown","onKeyUp","onInput","copy","paste","onCompositionStart","onCompositionUpdate","onCompositionEnd","_clickHandlerInitialized","onClick","keysMap","ctrlKeysMapUp","ctrlKeysMapDown","keyCode","ctrlKey","metaKey","stopImmediatePropagation","_copyDone","fromPaste","nextText","charCount","nextCharCount","removedText","charDiff","removeFrom","removeTo","textareaSelection","backDelete","copiedText","copiedTextStyle","compositionEnd","_getClipboardData","clipboardData","_getWidthBeforeCursor","widthBeforeCursor","getDownCursorOffset","isRight","selectionProp","_getSelectionForOffset","indexOnOtherLine","_getIndexOnLine","textAfterCursor","getUpCursorOffset","textBeforeCursor","widthOfCharsOnLine","indexOnLine","charWidth","foundMatch","leftEdge","rightEdge","offsetFromLeftEdge","offsetFromRightEdge","moveCursorDown","_moveCursorUpOrDown","moveCursorUp","moveCursorWithShift","moveCursorWithoutShift","moveCursorLeft","_moveCursorLeftOrRight","_move","_moveLeft","_moveRight","moveCursorLeftWithoutShift","change","moveCursorLeftWithShift","moveCursorRight","moveCursorRightWithShift","moveCursorRightWithoutShift","changed","removeChars","insertChars","multipleSpacesRegex","_getSVGLeftTopOffsets","textAndBg","_getSVGTextAndBg","textTop","textLeft","_wrapSVGTextAndBg","lineTop","noShadow","textSpans","textTopOffset","textLeftOffset","_setSVGTextLineBg","_setSVGTextLineText","_createTextCharSpan","styleDecl","shouldUseWhitespace","styleProps","fillStyles","dySpan","_pushTextBgRect","fillColor","_getSVGLineTopOffset","lastHeight","svgStyle","Textbox","minWidth","dynamicMinWidth","__cachedLines","_wordJoiners","splitByGrapheme","_styleMap","_generateStyleMap","textInfo","realLineCount","realLineCharCount","isWrapping","nextLineIndex","nextOffset","shouldLimit","mapNextLine","_wrapText","desiredWidth","wrapped","_wrapLine","_measureWord","word","charOffset","_line","reservedSpace","words","infix","wordWidth","infixWidth","largestWordWidth","lineJustStarted","additionalSpace","getMinWidth","linesToKeep","scaleSkewStyleHandler","scaleStyleHandler","objectControls","ml","mr","mb","mtr","textBoxControls"],"mappings":"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1C,EAAyD,KAAKC,gBAA9D;;AACA,UAAI,KAAKC,aAAT,EAAwB;AACtB,aAAKH,mBAAL,CAAyBD,UAAzB,EAAqC,KAAKI,aAA1C,EAAyD,KAAKC,UAA9D;AACD;AACF,KA3N6G;AA6N9GJ,IAAAA,mBAAmB,EAAE,UAASD,UAAT,EAAqBvoC,MAArB,EAA6BjL,OAA7B,EAAsC;AACzDiL,MAAAA,MAAM,CAACqU,YAAP,CAAoB,OAApB,EAA6B,KAAKza,KAAL,GAAa2uC,UAA1C;AACAvoC,MAAAA,MAAM,CAACqU,YAAP,CAAoB,QAApB,EAA8B,KAAKra,MAAL,GAAcuuC,UAA5C;AACAxzC,MAAAA,OAAO,CAACsrB,KAAR,CAAckoB,UAAd,EAA0BA,UAA1B;AACD,KAjO6G;;AAoO9G;AACJ;AACA;AACA;AACA;AACA;AACIH,IAAAA,UAAU,EAAE,YAAY;AACtB,WAAKS,OAAL,GAAe5zB,gBAAgB,CAAC,KAAKwzB,aAAN,CAA/B;AACA,aAAO,IAAP;AACD,KA7O6G;;AA+O9G;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACIT,IAAAA,eAAe,EAAE,UAAUc,KAAV,EAAiBh0C,QAAjB,EAA2BxB,OAA3B,EAAoC;AACnD,aAAO,KAAKy1C,mBAAL,CAAyB,cAAzB,EAAyCD,KAAzC,EAAgDh0C,QAAhD,EAA0DxB,OAA1D,CAAP;AACD,KAhS6G;;AAkS9G;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;A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A;AACA;AACA;AACIM,IAAAA,YAAY,EAAc,KA1awE;;AA4alG;AACJ;AACA;AACA;AACA;AACID,IAAAA,YAAY,EAAc,KAjbwE;;AAmblG;AACJ;AACA;AACA;AACA;AACIiE,IAAAA,eAAe,EAAW,KAxbwE;;AA0blG;AACJ;AACA;AACA;AACA;AACA;AACI2P,IAAAA,iBAAiB,EAAS,KAhcwE;;AAkclG;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACIyb,IAAAA,aAAa,EAAaA,aA1cwE;;AA4clG;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACIa,IAAAA,cAAc,EAAa,KAtduE;;AAwdlG;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACIC,IAAAA,YAAY,EAAe,IAjeuE;;AAmelG;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACIlrB,IAAAA,aAAa,EAAe,KA7esE;;AA+elG;AACJ;AACA;AACA;AACA;AACA;AACImrB,IAAAA,KAAK,EAAiB,IArf4E;;AAuflG;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACInP,IAAAA,QAAQ,EAAE,CA/fwF;;AAigBlG;AACJ;AACA;AACA;AACA;AACIoP,IAAAA,UAAU,EAAY,MAtgB4E;;AAwgBlG;AACJ;AACA;AACA;AACA;AACA;AACIC,IAAAA,eAAe,EAAE,CACf,qFACA,oGADA,GAEA,6EAFA,GAGA,wDAJe,EAKfnvD,KALe,CAKT,GALS,CA9gBiF;;AAqhBlG;AACJ;AACA;AACA;AACA;AACA;AACA;AACIovD,IAAAA,eAAe,EAAE,CACf,kFACA,0FAFe,EAGfpvD,KAHe,CAGT,GAHS,CA5hBiF;;AAiiBlG;AACJ;AACA;AACA;AACIqvD,IAAAA,eAAe,EACb,6BADe,CAEfrvD,KAFe,CAET,GAFS,CAriBiF;;AAyiBlG;AACJ;AACA;AACA;AACA;AACA;AACA;AACIqtB,IAAAA,QAAQ,EAAE3sB,SAhjBwF;;AAkjBlG;AACJ;AACA;AACA;AACA;AACA;AACA;AACI4uD,IAAAA,QAAQ,EAAE,KAzjB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","sourcesContent":["/* build: `node build.js modules=ALL exclude=gestures,accessors requirejs minifier=uglifyjs` */\n/*! Fabric.js Copyright 2008-2015, Printio (Juriy Zaytsev, Maxim Chernyak) */\n\nvar fabric = fabric || { version: '4.2.0' };\nif (typeof exports !== 'undefined') {\n exports.fabric = fabric;\n}\n/* _AMD_START_ */\nelse if (typeof define === 'function' && define.amd) {\n define([], function() { return fabric; });\n}\n/* _AMD_END_ */\nif (typeof document !== 'undefined' && typeof window !== 'undefined') {\n if (document instanceof (typeof HTMLDocument !== 'undefined' ? HTMLDocument : Document)) {\n fabric.document = document;\n }\n else {\n fabric.document = document.implementation.createHTMLDocument('');\n }\n fabric.window = window;\n}\nelse {\n // assume we're running under node.js when document/window are not present\n var jsdom = require('jsdom');\n var virtualWindow = new jsdom.JSDOM(\n decodeURIComponent('%3C!DOCTYPE%20html%3E%3Chtml%3E%3Chead%3E%3C%2Fhead%3E%3Cbody%3E%3C%2Fbody%3E%3C%2Fhtml%3E'),\n {\n features: {\n FetchExternalResources: ['img']\n },\n resources: 'usable'\n }).window;\n fabric.document = virtualWindow.document;\n fabric.jsdomImplForWrapper = require('jsdom/lib/jsdom/living/generated/utils').implForWrapper;\n fabric.nodeCanvas = require('jsdom/lib/jsdom/utils').Canvas;\n fabric.window = virtualWindow;\n DOMParser = fabric.window.DOMParser;\n}\n\n/**\n * True when in environment that supports touch events\n * @type boolean\n */\nfabric.isTouchSupported = 'ontouchstart' in fabric.window || 'ontouchstart' in fabric.document ||\n (fabric.window && fabric.window.navigator && fabric.window.navigator.maxTouchPoints > 0);\n\n/**\n * True when in environment that's probably Node.js\n * @type boolean\n */\nfabric.isLikelyNode = typeof Buffer !== 'undefined' &&\n typeof window === 'undefined';\n\n/* _FROM_SVG_START_ */\n/**\n * Attributes parsed from all SVG elements\n * @type array\n */\nfabric.SHARED_ATTRIBUTES = [\n 'display',\n 'transform',\n 'fill', 'fill-opacity', 'fill-rule',\n 'opacity',\n 'stroke', 'stroke-dasharray', 'stroke-linecap', 'stroke-dashoffset',\n 'stroke-linejoin', 'stroke-miterlimit',\n 'stroke-opacity', 'stroke-width',\n 'id', 'paint-order', 'vector-effect',\n 'instantiated_by_use', 'clip-path',\n];\n/* _FROM_SVG_END_ */\n\n/**\n * Pixel per Inch as a default value set to 96. Can be changed for more realistic conversion.\n */\nfabric.DPI = 96;\nfabric.reNum = '(?:[-+]?(?:\\\\d+|\\\\d*\\\\.\\\\d+)(?:[eE][-+]?\\\\d+)?)';\nfabric.commaWsp = '(?:\\\\s+,?\\\\s*|,\\\\s*)'\nfabric.rePathCommand = /([-+]?((\\d+\\.\\d+)|((\\d+)|(\\.\\d+)))(?:[eE][-+]?\\d+)?)/ig;\nfabric.reNonWord = /[ \\n\\.,;!\\?\\-]/;\nfabric.fontPaths = { };\nfabric.iMatrix = [1, 0, 0, 1, 0, 0];\nfabric.svgNS = 'http://www.w3.org/2000/svg';\n\n/**\n * Pixel limit for cache canvases. 1Mpx , 4Mpx should be fine.\n * @since 1.7.14\n * @type Number\n * @default\n */\nfabric.perfLimitSizeTotal = 2097152;\n\n/**\n * Pixel limit for cache canvases width or height. IE fixes the maximum at 5000\n * @since 1.7.14\n * @type Number\n * @default\n */\nfabric.maxCacheSideLimit = 4096;\n\n/**\n * Lowest pixel limit for cache canvases, set at 256PX\n * @since 1.7.14\n * @type Number\n * @default\n */\nfabric.minCacheSideLimit = 256;\n\n/**\n * Cache Object for widths of chars in text rendering.\n */\nfabric.charWidthsCache = { };\n\n/**\n * if webgl is enabled and available, textureSize will determine the size\n * of the canvas backend\n * @since 2.0.0\n * @type Number\n * @default\n */\nfabric.textureSize = 2048;\n\n/**\n * When 'true', style information is not retained when copy/pasting text, making\n * pasted text use destination style.\n * Defaults to 'false'.\n * @type Boolean\n * @default\n */\nfabric.disableStyleCopyPaste = false;\n\n/**\n * Enable webgl for filtering picture is available\n * A filtering backend will be initialized, this will both take memory and\n * time since a default 2048x2048 canvas will be created for the gl context\n * @since 2.0.0\n * @type Boolean\n * @default\n */\nfabric.enableGLFiltering = true;\n\n/**\n * Device Pixel Ratio\n * @see https://developer.apple.com/library/safari/documentation/AudioVideo/Conceptual/HTML-canvas-guide/SettingUptheCanvas/SettingUptheCanvas.html\n */\nfabric.devicePixelRatio = fabric.window.devicePixelRatio ||\n fabric.window.webkitDevicePixelRatio ||\n fabric.window.mozDevicePixelRatio ||\n 1;\n/**\n * Browser-specific constant to adjust CanvasRenderingContext2D.shadowBlur value,\n * which is unitless and not rendered equally across browsers.\n *\n * Values that work quite well (as of October 2017) are:\n * - Chrome: 1.5\n * - Edge: 1.75\n * - Firefox: 0.9\n * - Safari: 0.95\n *\n * @since 2.0.0\n * @type Number\n * @default 1\n */\nfabric.browserShadowBlurConstant = 1;\n\n/**\n * This object contains the result of arc to beizer conversion for faster retrieving if the same arc needs to be converted again.\n * It was an internal variable, is accessible since version 2.3.4\n */\nfabric.arcToSegmentsCache = { };\n\n/**\n * This object keeps the results of the boundsOfCurve calculation mapped by the joined arguments necessary to calculate it.\n * It does speed up calculation, if you parse and add always the same paths, but in case of heavy usage of freedrawing\n * you do not get any speed benefit and you get a big object in memory.\n * The object was a private variable before, while now is appended to the lib so that you have access to it and you\n * can eventually clear it.\n * It was an internal variable, is accessible since version 2.3.4\n */\nfabric.boundsOfCurveCache = { };\n\n/**\n * If disabled boundsOfCurveCache is not used. For apps that make heavy usage of pencil drawing probably disabling it is better\n * @default true\n */\nfabric.cachesBoundsOfCurve = true;\n\n/**\n * Skip performance testing of setupGLContext and force the use of putImageData that seems to be the one that works best on\n * Chrome + old hardware. if your users are experiencing empty images after filtering you may try to force this to true\n * this has to be set before instantiating the filtering backend ( before filtering the first image )\n * @type Boolean\n * @default false\n */\nfabric.forceGLPutImageData = false;\n\nfabric.initFilterBackend = function() {\n if (fabric.enableGLFiltering && fabric.isWebglSupported && fabric.isWebglSupported(fabric.textureSize)) {\n console.log('max texture size: ' + fabric.maxTextureSize);\n return (new fabric.WebglFilterBackend({ tileSize: fabric.textureSize }));\n }\n else if (fabric.Canvas2dFilterBackend) {\n return (new fabric.Canvas2dFilterBackend());\n }\n};\n\n\nif (typeof document !== 'undefined' && typeof window !== 'undefined') {\n // ensure globality even if entire library were function wrapped (as in Meteor.js packaging system)\n window.fabric = fabric;\n}\n\n\n(function() {\n\n /**\n * @private\n * @param {String} eventName\n * @param {Function} handler\n */\n function _removeEventListener(eventName, handler) {\n if (!this.__eventListeners[eventName]) {\n return;\n }\n var eventListener = this.__eventListeners[eventName];\n if (handler) {\n eventListener[eventListener.indexOf(handler)] = false;\n }\n else {\n fabric.util.array.fill(eventListener, false);\n }\n }\n\n /**\n * Observes specified event\n * @memberOf fabric.Observable\n * @alias on\n * @param {String|Object} eventName Event name (eg. 'after:render') or object with key/value pairs (eg. {'after:render': handler, 'selection:cleared': handler})\n * @param {Function} handler Function that receives a notification when an event of the specified type occurs\n * @return {Self} thisArg\n * @chainable\n */\n function on(eventName, handler) {\n if (!this.__eventListeners) {\n this.__eventListeners = { };\n }\n // one object with key/value pairs was passed\n if (arguments.length === 1) {\n for (var prop in eventName) {\n this.on(prop, eventName[prop]);\n }\n }\n else {\n if (!this.__eventListeners[eventName]) {\n this.__eventListeners[eventName] = [];\n }\n this.__eventListeners[eventName].push(handler);\n }\n return this;\n }\n\n /**\n * Stops event observing for a particular event handler. Calling this method\n * without arguments removes all handlers for all events\n * @memberOf fabric.Observable\n * @alias off\n * @param {String|Object} eventName Event name (eg. 'after:render') or object with key/value pairs (eg. {'after:render': handler, 'selection:cleared': handler})\n * @param {Function} handler Function to be deleted from EventListeners\n * @return {Self} thisArg\n * @chainable\n */\n function off(eventName, handler) {\n if (!this.__eventListeners) {\n return this;\n }\n\n // remove all key/value pairs (event name -> event handler)\n if (arguments.length === 0) {\n for (eventName in this.__eventListeners) {\n _removeEventListener.call(this, eventName);\n }\n }\n // one object with key/value pairs was passed\n else if (arguments.length === 1 && typeof arguments[0] === 'object') {\n for (var prop in eventName) {\n _removeEventListener.call(this, prop, eventName[prop]);\n }\n }\n else {\n _removeEventListener.call(this, eventName, handler);\n }\n return this;\n }\n\n /**\n * Fires event with an optional options object\n * @memberOf fabric.Observable\n * @param {String} eventName Event name to fire\n * @param {Object} [options] Options object\n * @return {Self} thisArg\n * @chainable\n */\n function fire(eventName, options) {\n if (!this.__eventListeners) {\n return this;\n }\n\n var listenersForEvent = this.__eventListeners[eventName];\n if (!listenersForEvent) {\n return this;\n }\n\n for (var i = 0, len = listenersForEvent.length; i < len; i++) {\n listenersForEvent[i] && listenersForEvent[i].call(this, options || { });\n }\n this.__eventListeners[eventName] = listenersForEvent.filter(function(value) {\n return value !== false;\n });\n return this;\n }\n\n /**\n * @namespace fabric.Observable\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#events}\n * @see {@link http://fabricjs.com/events|Events demo}\n */\n fabric.Observable = {\n fire: fire,\n on: on,\n off: off,\n };\n})();\n\n\n/**\n * @namespace fabric.Collection\n */\nfabric.Collection = {\n\n _objects: [],\n\n /**\n * Adds objects to collection, Canvas or Group, then renders canvas\n * (if `renderOnAddRemove` is not `false`).\n * in case of Group no changes to bounding box are made.\n * Objects should be instances of (or inherit from) fabric.Object\n * Use of this function is highly discouraged for groups.\n * you can add a bunch of objects with the add method but then you NEED\n * to run a addWithUpdate call for the Group class or position/bbox will be wrong.\n * @param {...fabric.Object} object Zero or more fabric instances\n * @return {Self} thisArg\n * @chainable\n */\n add: function () {\n this._objects.push.apply(this._objects, arguments);\n if (this._onObjectAdded) {\n for (var i = 0, length = arguments.length; i < length; i++) {\n this._onObjectAdded(arguments[i]);\n }\n }\n this.renderOnAddRemove && this.requestRenderAll();\n return this;\n },\n\n /**\n * Inserts an object into collection at specified index, then renders canvas (if `renderOnAddRemove` is not `false`)\n * An object should be an instance of (or inherit from) fabric.Object\n * Use of this function is highly discouraged for groups.\n * you can add a bunch of objects with the insertAt method but then you NEED\n * to run a addWithUpdate call for the Group class or position/bbox will be wrong.\n * @param {Object} object Object to insert\n * @param {Number} index Index to insert object at\n * @param {Boolean} nonSplicing When `true`, no splicing (shifting) of objects occurs\n * @return {Self} thisArg\n * @chainable\n */\n insertAt: function (object, index, nonSplicing) {\n var objects = this._objects;\n if (nonSplicing) {\n objects[index] = object;\n }\n else {\n objects.splice(index, 0, object);\n }\n this._onObjectAdded && this._onObjectAdded(object);\n this.renderOnAddRemove && this.requestRenderAll();\n return this;\n },\n\n /**\n * Removes objects from a collection, then renders canvas (if `renderOnAddRemove` is not `false`)\n * @param {...fabric.Object} object Zero or more fabric instances\n * @return {Self} thisArg\n * @chainable\n */\n remove: function() {\n var objects = this._objects,\n index, somethingRemoved = false;\n\n for (var i = 0, length = arguments.length; i < length; i++) {\n index = objects.indexOf(arguments[i]);\n\n // only call onObjectRemoved if an object was actually removed\n if (index !== -1) {\n somethingRemoved = true;\n objects.splice(index, 1);\n this._onObjectRemoved && this._onObjectRemoved(arguments[i]);\n }\n }\n\n this.renderOnAddRemove && somethingRemoved && this.requestRenderAll();\n return this;\n },\n\n /**\n * Executes given function for each object in this group\n * @param {Function} callback\n * Callback invoked with current object as first argument,\n * index - as second and an array of all objects - as third.\n * Callback is invoked in a context of Global Object (e.g. `window`)\n * when no `context` argument is given\n *\n * @param {Object} context Context (aka thisObject)\n * @return {Self} thisArg\n * @chainable\n */\n forEachObject: function(callback, context) {\n var objects = this.getObjects();\n for (var i = 0, len = objects.length; i < len; i++) {\n callback.call(context, objects[i], i, objects);\n }\n return this;\n },\n\n /**\n * Returns an array of children objects of this instance\n * Type parameter introduced in 1.3.10\n * since 2.3.5 this method return always a COPY of the array;\n * @param {String} [type] When specified, only objects of this type are returned\n * @return {Array}\n */\n getObjects: function(type) {\n if (typeof type === 'undefined') {\n return this._objects.concat();\n }\n return this._objects.filter(function(o) {\n return o.type === type;\n });\n },\n\n /**\n * Returns object at specified index\n * @param {Number} index\n * @return {Self} thisArg\n */\n item: function (index) {\n return this._objects[index];\n },\n\n /**\n * Returns true if collection contains no objects\n * @return {Boolean} true if collection is empty\n */\n isEmpty: function () {\n return this._objects.length === 0;\n },\n\n /**\n * Returns a size of a collection (i.e: length of an array containing its objects)\n * @return {Number} Collection size\n */\n size: function() {\n return this._objects.length;\n },\n\n /**\n * Returns true if collection contains an object\n * @param {Object} object Object to check against\n * @return {Boolean} `true` if collection contains an object\n */\n contains: function(object) {\n return this._objects.indexOf(object) > -1;\n },\n\n /**\n * Returns number representation of a collection complexity\n * @return {Number} complexity\n */\n complexity: function () {\n return this._objects.reduce(function (memo, current) {\n memo += current.complexity ? current.complexity() : 0;\n return memo;\n }, 0);\n }\n};\n\n\n/**\n * @namespace fabric.CommonMethods\n */\nfabric.CommonMethods = {\n\n /**\n * Sets object's properties from options\n * @param {Object} [options] Options object\n */\n _setOptions: function(options) {\n for (var prop in options) {\n this.set(prop, options[prop]);\n }\n },\n\n /**\n * @private\n * @param {Object} [filler] Options object\n * @param {String} [property] property to set the Gradient to\n */\n _initGradient: function(filler, property) {\n if (filler && filler.colorStops && !(filler instanceof fabric.Gradient)) {\n this.set(property, new fabric.Gradient(filler));\n }\n },\n\n /**\n * @private\n * @param {Object} [filler] Options object\n * @param {String} [property] property to set the Pattern to\n * @param {Function} [callback] callback to invoke after pattern load\n */\n _initPattern: function(filler, property, callback) {\n if (filler && filler.source && !(filler instanceof fabric.Pattern)) {\n this.set(property, new fabric.Pattern(filler, callback));\n }\n else {\n callback && callback();\n }\n },\n\n /**\n * @private\n */\n _setObject: function(obj) {\n for (var prop in obj) {\n this._set(prop, obj[prop]);\n }\n },\n\n /**\n * Sets property to a given value. When changing position/dimension -related properties (left, top, scale, angle, etc.) `set` does not update position of object's borders/controls. If you need to update those, call `setCoords()`.\n * @param {String|Object} key Property name or object (if object, iterate over the object properties)\n * @param {Object|Function} value Property value (if function, the value is passed into it and its return value is used as a new one)\n * @return {fabric.Object} thisArg\n * @chainable\n */\n set: function(key, value) {\n if (typeof key === 'object') {\n this._setObject(key);\n }\n else {\n this._set(key, value);\n }\n return this;\n },\n\n _set: function(key, value) {\n this[key] = value;\n },\n\n /**\n * Toggles specified property from `true` to `false` or from `false` to `true`\n * @param {String} property Property to toggle\n * @return {fabric.Object} thisArg\n * @chainable\n */\n toggle: function(property) {\n var value = this.get(property);\n if (typeof value === 'boolean') {\n this.set(property, !value);\n }\n return this;\n },\n\n /**\n * Basic getter\n * @param {String} property Property name\n * @return {*} value of a property\n */\n get: function(property) {\n return this[property];\n }\n};\n\n\n(function(global) {\n\n var sqrt = Math.sqrt,\n atan2 = Math.atan2,\n pow = Math.pow,\n PiBy180 = Math.PI / 180,\n PiBy2 = Math.PI / 2;\n\n /**\n * @namespace fabric.util\n */\n fabric.util = {\n\n /**\n * Calculate the cos of an angle, avoiding returning floats for known results\n * @static\n * @memberOf fabric.util\n * @param {Number} angle the angle in radians or in degree\n * @return {Number}\n */\n cos: function(angle) {\n if (angle === 0) { return 1; }\n if (angle < 0) {\n // cos(a) = cos(-a)\n angle = -angle;\n }\n var angleSlice = angle / PiBy2;\n switch (angleSlice) {\n case 1: case 3: return 0;\n case 2: return -1;\n }\n return Math.cos(angle);\n },\n\n /**\n * Calculate the sin of an angle, avoiding returning floats for known results\n * @static\n * @memberOf fabric.util\n * @param {Number} angle the angle in radians or in degree\n * @return {Number}\n */\n sin: function(angle) {\n if (angle === 0) { return 0; }\n var angleSlice = angle / PiBy2, sign = 1;\n if (angle < 0) {\n // sin(-a) = -sin(a)\n sign = -1;\n }\n switch (angleSlice) {\n case 1: return sign;\n case 2: return 0;\n case 3: return -sign;\n }\n return Math.sin(angle);\n },\n\n /**\n * Removes value from an array.\n * Presence of value (and its position in an array) is determined via `Array.prototype.indexOf`\n * @static\n * @memberOf fabric.util\n * @param {Array} array\n * @param {*} value\n * @return {Array} original array\n */\n removeFromArray: function(array, value) {\n var idx = array.indexOf(value);\n if (idx !== -1) {\n array.splice(idx, 1);\n }\n return array;\n },\n\n /**\n * Returns random number between 2 specified ones.\n * @static\n * @memberOf fabric.util\n * @param {Number} min lower limit\n * @param {Number} max upper limit\n * @return {Number} random value (between min and max)\n */\n getRandomInt: function(min, max) {\n return Math.floor(Math.random() * (max - min + 1)) + min;\n },\n\n /**\n * Transforms degrees to radians.\n * @static\n * @memberOf fabric.util\n * @param {Number} degrees value in degrees\n * @return {Number} value in radians\n */\n degreesToRadians: function(degrees) {\n return degrees * PiBy180;\n },\n\n /**\n * Transforms radians to degrees.\n * @static\n * @memberOf fabric.util\n * @param {Number} radians value in radians\n * @return {Number} value in degrees\n */\n radiansToDegrees: function(radians) {\n return radians / PiBy180;\n },\n\n /**\n * Rotates `point` around `origin` with `radians`\n * @static\n * @memberOf fabric.util\n * @param {fabric.Point} point The point to rotate\n * @param {fabric.Point} origin The origin of the rotation\n * @param {Number} radians The radians of the angle for the rotation\n * @return {fabric.Point} The new rotated point\n */\n rotatePoint: function(point, origin, radians) {\n point.subtractEquals(origin);\n var v = fabric.util.rotateVector(point, radians);\n return new fabric.Point(v.x, v.y).addEquals(origin);\n },\n\n /**\n * Rotates `vector` with `radians`\n * @static\n * @memberOf fabric.util\n * @param {Object} vector The vector to rotate (x and y)\n * @param {Number} radians The radians of the angle for the rotation\n * @return {Object} The new rotated point\n */\n rotateVector: function(vector, radians) {\n var sin = fabric.util.sin(radians),\n cos = fabric.util.cos(radians),\n rx = vector.x * cos - vector.y * sin,\n ry = vector.x * sin + vector.y * cos;\n return {\n x: rx,\n y: ry\n };\n },\n\n /**\n * Apply transform t to point p\n * @static\n * @memberOf fabric.util\n * @param {fabric.Point} p The point to transform\n * @param {Array} t The transform\n * @param {Boolean} [ignoreOffset] Indicates that the offset should not be applied\n * @return {fabric.Point} The transformed point\n */\n transformPoint: function(p, t, ignoreOffset) {\n if (ignoreOffset) {\n return new fabric.Point(\n t[0] * p.x + t[2] * p.y,\n t[1] * p.x + t[3] * p.y\n );\n }\n return new fabric.Point(\n t[0] * p.x + t[2] * p.y + t[4],\n t[1] * p.x + t[3] * p.y + t[5]\n );\n },\n\n /**\n * Returns coordinates of points's bounding rectangle (left, top, width, height)\n * @param {Array} points 4 points array\n * @param {Array} [transform] an array of 6 numbers representing a 2x3 transform matrix\n * @return {Object} Object with left, top, width, height properties\n */\n makeBoundingBoxFromPoints: function(points, transform) {\n if (transform) {\n for (var i = 0; i < points.length; i++) {\n points[i] = fabric.util.transformPoint(points[i], transform);\n }\n }\n var xPoints = [points[0].x, points[1].x, points[2].x, points[3].x],\n minX = fabric.util.array.min(xPoints),\n maxX = fabric.util.array.max(xPoints),\n width = maxX - minX,\n yPoints = [points[0].y, points[1].y, points[2].y, points[3].y],\n minY = fabric.util.array.min(yPoints),\n maxY = fabric.util.array.max(yPoints),\n height = maxY - minY;\n\n return {\n left: minX,\n top: minY,\n width: width,\n height: height\n };\n },\n\n /**\n * Invert transformation t\n * @static\n * @memberOf fabric.util\n * @param {Array} t The transform\n * @return {Array} The inverted transform\n */\n invertTransform: function(t) {\n var a = 1 / (t[0] * t[3] - t[1] * t[2]),\n r = [a * t[3], -a * t[1], -a * t[2], a * t[0]],\n o = fabric.util.transformPoint({ x: t[4], y: t[5] }, r, true);\n r[4] = -o.x;\n r[5] = -o.y;\n return r;\n },\n\n /**\n * A wrapper around Number#toFixed, which contrary to native method returns number, not string.\n * @static\n * @memberOf fabric.util\n * @param {Number|String} number number to operate on\n * @param {Number} fractionDigits number of fraction digits to \"leave\"\n * @return {Number}\n */\n toFixed: function(number, fractionDigits) {\n return parseFloat(Number(number).toFixed(fractionDigits));\n },\n\n /**\n * Converts from attribute value to pixel value if applicable.\n * Returns converted pixels or original value not converted.\n * @param {Number|String} value number to operate on\n * @param {Number} fontSize\n * @return {Number|String}\n */\n parseUnit: function(value, fontSize) {\n var unit = /\\D{0,2}$/.exec(value),\n number = parseFloat(value);\n if (!fontSize) {\n fontSize = fabric.Text.DEFAULT_SVG_FONT_SIZE;\n }\n switch (unit[0]) {\n case 'mm':\n return number * fabric.DPI / 25.4;\n\n case 'cm':\n return number * fabric.DPI / 2.54;\n\n case 'in':\n return number * fabric.DPI;\n\n case 'pt':\n return number * fabric.DPI / 72; // or * 4 / 3\n\n case 'pc':\n return number * fabric.DPI / 72 * 12; // or * 16\n\n case 'em':\n return number * fontSize;\n\n default:\n return number;\n }\n },\n\n /**\n * Function which always returns `false`.\n * @static\n * @memberOf fabric.util\n * @return {Boolean}\n */\n falseFunction: function() {\n return false;\n },\n\n /**\n * Returns klass \"Class\" object of given namespace\n * @memberOf fabric.util\n * @param {String} type Type of object (eg. 'circle')\n * @param {String} namespace Namespace to get klass \"Class\" object from\n * @return {Object} klass \"Class\"\n */\n getKlass: function(type, namespace) {\n // capitalize first letter only\n type = fabric.util.string.camelize(type.charAt(0).toUpperCase() + type.slice(1));\n return fabric.util.resolveNamespace(namespace)[type];\n },\n\n /**\n * Returns array of attributes for given svg that fabric parses\n * @memberOf fabric.util\n * @param {String} type Type of svg element (eg. 'circle')\n * @return {Array} string names of supported attributes\n */\n getSvgAttributes: function(type) {\n var attributes = [\n 'instantiated_by_use',\n 'style',\n 'id',\n 'class'\n ];\n switch (type) {\n case 'linearGradient':\n attributes = attributes.concat(['x1', 'y1', 'x2', 'y2', 'gradientUnits', 'gradientTransform']);\n break;\n case 'radialGradient':\n attributes = attributes.concat(['gradientUnits', 'gradientTransform', 'cx', 'cy', 'r', 'fx', 'fy', 'fr']);\n break;\n case 'stop':\n attributes = attributes.concat(['offset', 'stop-color', 'stop-opacity']);\n break;\n }\n return attributes;\n },\n\n /**\n * Returns object of given namespace\n * @memberOf fabric.util\n * @param {String} namespace Namespace string e.g. 'fabric.Image.filter' or 'fabric'\n * @return {Object} Object for given namespace (default fabric)\n */\n resolveNamespace: function(namespace) {\n if (!namespace) {\n return fabric;\n }\n\n var parts = namespace.split('.'),\n len = parts.length, i,\n obj = global || fabric.window;\n\n for (i = 0; i < len; ++i) {\n obj = obj[parts[i]];\n }\n\n return obj;\n },\n\n /**\n * Loads image element from given url and passes it to a callback\n * @memberOf fabric.util\n * @param {String} url URL representing an image\n * @param {Function} callback Callback; invoked with loaded image\n * @param {*} [context] Context to invoke callback in\n * @param {Object} [crossOrigin] crossOrigin value to set image element to\n */\n loadImage: function(url, callback, context, crossOrigin) {\n if (!url) {\n callback && callback.call(context, url);\n return;\n }\n\n var img = fabric.util.createImage();\n\n /** @ignore */\n var onLoadCallback = function () {\n callback && callback.call(context, img, false);\n img = img.onload = img.onerror = null;\n };\n\n img.onload = onLoadCallback;\n /** @ignore */\n img.onerror = function() {\n fabric.log('Error loading ' + img.src);\n callback && callback.call(context, null, true);\n img = img.onload = img.onerror = null;\n };\n\n // data-urls appear to be buggy with crossOrigin\n // https://github.com/kangax/fabric.js/commit/d0abb90f1cd5c5ef9d2a94d3fb21a22330da3e0a#commitcomment-4513767\n // see https://code.google.com/p/chromium/issues/detail?id=315152\n // https://bugzilla.mozilla.org/show_bug.cgi?id=935069\n // crossOrigin null is the same as not set.\n if (url.indexOf('data') !== 0 &&\n crossOrigin !== undefined &&\n crossOrigin !== null) {\n img.crossOrigin = crossOrigin;\n }\n\n // IE10 / IE11-Fix: SVG contents from data: URI\n // will only be available if the IMG is present\n // in the DOM (and visible)\n if (url.substring(0,14) === 'data:image/svg') {\n img.onload = null;\n fabric.util.loadImageInDom(img, onLoadCallback);\n }\n\n img.src = url;\n },\n\n /**\n * Attaches SVG image with data: URL to the dom\n * @memberOf fabric.util\n * @param {Object} img Image object with data:image/svg src\n * @param {Function} callback Callback; invoked with loaded image\n * @return {Object} DOM element (div containing the SVG image)\n */\n loadImageInDom: function(img, onLoadCallback) {\n var div = fabric.document.createElement('div');\n div.style.width = div.style.height = '1px';\n div.style.left = div.style.top = '-100%';\n div.style.position = 'absolute';\n div.appendChild(img);\n fabric.document.querySelector('body').appendChild(div);\n /**\n * Wrap in function to:\n * 1. Call existing callback\n * 2. Cleanup DOM\n */\n img.onload = function () {\n onLoadCallback();\n div.parentNode.removeChild(div);\n div = null;\n };\n },\n\n /**\n * Creates corresponding fabric instances from their object representations\n * @static\n * @memberOf fabric.util\n * @param {Array} objects Objects to enliven\n * @param {Function} callback Callback to invoke when all objects are created\n * @param {String} namespace Namespace to get klass \"Class\" object from\n * @param {Function} reviver Method for further parsing of object elements,\n * called after each fabric object created.\n */\n enlivenObjects: function(objects, callback, namespace, reviver) {\n objects = objects || [];\n\n var enlivenedObjects = [],\n numLoadedObjects = 0,\n numTotalObjects = objects.length;\n\n function onLoaded() {\n if (++numLoadedObjects === numTotalObjects) {\n callback && callback(enlivenedObjects.filter(function(obj) {\n // filter out undefined objects (objects that gave error)\n return obj;\n }));\n }\n }\n\n if (!numTotalObjects) {\n callback && callback(enlivenedObjects);\n return;\n }\n\n objects.forEach(function (o, index) {\n // if sparse array\n if (!o || !o.type) {\n onLoaded();\n return;\n }\n var klass = fabric.util.getKlass(o.type, namespace);\n klass.fromObject(o, function (obj, error) {\n error || (enlivenedObjects[index] = obj);\n reviver && reviver(o, obj, error);\n onLoaded();\n });\n });\n },\n\n /**\n * Create and wait for loading of patterns\n * @static\n * @memberOf fabric.util\n * @param {Array} patterns Objects to enliven\n * @param {Function} callback Callback to invoke when all objects are created\n * called after each fabric object created.\n */\n enlivenPatterns: function(patterns, callback) {\n patterns = patterns || [];\n\n function onLoaded() {\n if (++numLoadedPatterns === numPatterns) {\n callback && callback(enlivenedPatterns);\n }\n }\n\n var enlivenedPatterns = [],\n numLoadedPatterns = 0,\n numPatterns = patterns.length;\n\n if (!numPatterns) {\n callback && callback(enlivenedPatterns);\n return;\n }\n\n patterns.forEach(function (p, index) {\n if (p && p.source) {\n new fabric.Pattern(p, function(pattern) {\n enlivenedPatterns[index] = pattern;\n onLoaded();\n });\n }\n else {\n enlivenedPatterns[index] = p;\n onLoaded();\n }\n });\n },\n\n /**\n * Groups SVG elements (usually those retrieved from SVG document)\n * @static\n * @memberOf fabric.util\n * @param {Array} elements SVG elements to group\n * @param {Object} [options] Options object\n * @param {String} path Value to set sourcePath to\n * @return {fabric.Object|fabric.Group}\n */\n groupSVGElements: function(elements, options, path) {\n var object;\n if (elements && elements.length === 1) {\n return elements[0];\n }\n if (options) {\n if (options.width && options.height) {\n options.centerPoint = {\n x: options.width / 2,\n y: options.height / 2\n };\n }\n else {\n delete options.width;\n delete options.height;\n }\n }\n object = new fabric.Group(elements, options);\n if (typeof path !== 'undefined') {\n object.sourcePath = path;\n }\n return object;\n },\n\n /**\n * Populates an object with properties of another object\n * @static\n * @memberOf fabric.util\n * @param {Object} source Source object\n * @param {Object} destination Destination object\n * @return {Array} properties Properties names to include\n */\n populateWithProperties: function(source, destination, properties) {\n if (properties && Object.prototype.toString.call(properties) === '[object Array]') {\n for (var i = 0, len = properties.length; i < len; i++) {\n if (properties[i] in source) {\n destination[properties[i]] = source[properties[i]];\n }\n }\n }\n },\n\n /**\n * Draws a dashed line between two points\n *\n * This method is used to draw dashed line around selection area.\n * See <a href=\"http://stackoverflow.com/questions/4576724/dotted-stroke-in-canvas\">dotted stroke in canvas</a>\n *\n * @param {CanvasRenderingContext2D} ctx context\n * @param {Number} x start x coordinate\n * @param {Number} y start y coordinate\n * @param {Number} x2 end x coordinate\n * @param {Number} y2 end y coordinate\n * @param {Array} da dash array pattern\n */\n drawDashedLine: function(ctx, x, y, x2, y2, da) {\n var dx = x2 - x,\n dy = y2 - y,\n len = sqrt(dx * dx + dy * dy),\n rot = atan2(dy, dx),\n dc = da.length,\n di = 0,\n draw = true;\n\n ctx.save();\n ctx.translate(x, y);\n ctx.moveTo(0, 0);\n ctx.rotate(rot);\n\n x = 0;\n while (len > x) {\n x += da[di++ % dc];\n if (x > len) {\n x = len;\n }\n ctx[draw ? 'lineTo' : 'moveTo'](x, 0);\n draw = !draw;\n }\n\n ctx.restore();\n },\n\n /**\n * Creates canvas element\n * @static\n * @memberOf fabric.util\n * @return {CanvasElement} initialized canvas element\n */\n createCanvasElement: function() {\n return fabric.document.createElement('canvas');\n },\n\n /**\n * Creates a canvas element that is a copy of another and is also painted\n * @param {CanvasElement} canvas to copy size and content of\n * @static\n * @memberOf fabric.util\n * @return {CanvasElement} initialized canvas element\n */\n copyCanvasElement: function(canvas) {\n var newCanvas = fabric.util.createCanvasElement();\n newCanvas.width = canvas.width;\n newCanvas.height = canvas.height;\n newCanvas.getContext('2d').drawImage(canvas, 0, 0);\n return newCanvas;\n },\n\n /**\n * since 2.6.0 moved from canvas instance to utility.\n * @param {CanvasElement} canvasEl to copy size and content of\n * @param {String} format 'jpeg' or 'png', in some browsers 'webp' is ok too\n * @param {Number} quality <= 1 and > 0\n * @static\n * @memberOf fabric.util\n * @return {String} data url\n */\n toDataURL: function(canvasEl, format, quality) {\n return canvasEl.toDataURL('image/' + format, quality);\n },\n\n /**\n * Creates image element (works on client and node)\n * @static\n * @memberOf fabric.util\n * @return {HTMLImageElement} HTML image element\n */\n createImage: function() {\n return fabric.document.createElement('img');\n },\n\n /**\n * Multiply matrix A by matrix B to nest transformations\n * @static\n * @memberOf fabric.util\n * @param {Array} a First transformMatrix\n * @param {Array} b Second transformMatrix\n * @param {Boolean} is2x2 flag to multiply matrices as 2x2 matrices\n * @return {Array} The product of the two transform matrices\n */\n multiplyTransformMatrices: function(a, b, is2x2) {\n // Matrix multiply a * b\n return [\n a[0] * b[0] + a[2] * b[1],\n a[1] * b[0] + a[3] * b[1],\n a[0] * b[2] + a[2] * b[3],\n a[1] * b[2] + a[3] * b[3],\n is2x2 ? 0 : a[0] * b[4] + a[2] * b[5] + a[4],\n is2x2 ? 0 : a[1] * b[4] + a[3] * b[5] + a[5]\n ];\n },\n\n /**\n * Decomposes standard 2x3 matrix into transform components\n * @static\n * @memberOf fabric.util\n * @param {Array} a transformMatrix\n * @return {Object} Components of transform\n */\n qrDecompose: function(a) {\n var angle = atan2(a[1], a[0]),\n denom = pow(a[0], 2) + pow(a[1], 2),\n scaleX = sqrt(denom),\n scaleY = (a[0] * a[3] - a[2] * a[1]) / scaleX,\n skewX = atan2(a[0] * a[2] + a[1] * a [3], denom);\n return {\n angle: angle / PiBy180,\n scaleX: scaleX,\n scaleY: scaleY,\n skewX: skewX / PiBy180,\n skewY: 0,\n translateX: a[4],\n translateY: a[5]\n };\n },\n\n /**\n * Returns a transform matrix starting from an object of the same kind of\n * the one returned from qrDecompose, useful also if you want to calculate some\n * transformations from an object that is not enlived yet\n * @static\n * @memberOf fabric.util\n * @param {Object} options\n * @param {Number} [options.angle] angle in degrees\n * @return {Number[]} transform matrix\n */\n calcRotateMatrix: function(options) {\n if (!options.angle) {\n return fabric.iMatrix.concat();\n }\n var theta = fabric.util.degreesToRadians(options.angle),\n cos = fabric.util.cos(theta),\n sin = fabric.util.sin(theta);\n return [cos, sin, -sin, cos, 0, 0];\n },\n\n /**\n * Returns a transform matrix starting from an object of the same kind of\n * the one returned from qrDecompose, useful also if you want to calculate some\n * transformations from an object that is not enlived yet.\n * is called DimensionsTransformMatrix because those properties are the one that influence\n * the size of the resulting box of the object.\n * @static\n * @memberOf fabric.util\n * @param {Object} options\n * @param {Number} [options.scaleX]\n * @param {Number} [options.scaleY]\n * @param {Boolean} [options.flipX]\n * @param {Boolean} [options.flipY]\n * @param {Number} [options.skewX]\n * @param {Number} [options.skewX]\n * @return {Number[]} transform matrix\n */\n calcDimensionsMatrix: function(options) {\n var scaleX = typeof options.scaleX === 'undefined' ? 1 : options.scaleX,\n scaleY = typeof options.scaleY === 'undefined' ? 1 : options.scaleY,\n scaleMatrix = [\n options.flipX ? -scaleX : scaleX,\n 0,\n 0,\n options.flipY ? -scaleY : scaleY,\n 0,\n 0],\n multiply = fabric.util.multiplyTransformMatrices,\n degreesToRadians = fabric.util.degreesToRadians;\n if (options.skewX) {\n scaleMatrix = multiply(\n scaleMatrix,\n [1, 0, Math.tan(degreesToRadians(options.skewX)), 1],\n true);\n }\n if (options.skewY) {\n scaleMatrix = multiply(\n scaleMatrix,\n [1, Math.tan(degreesToRadians(options.skewY)), 0, 1],\n true);\n }\n return scaleMatrix;\n },\n\n /**\n * Returns a transform matrix starting from an object of the same kind of\n * the one returned from qrDecompose, useful also if you want to calculate some\n * transformations from an object that is not enlived yet\n * @static\n * @memberOf fabric.util\n * @param {Object} options\n * @param {Number} [options.angle]\n * @param {Number} [options.scaleX]\n * @param {Number} [options.scaleY]\n * @param {Boolean} [options.flipX]\n * @param {Boolean} [options.flipY]\n * @param {Number} [options.skewX]\n * @param {Number} [options.skewX]\n * @param {Number} [options.translateX]\n * @param {Number} [options.translateY]\n * @return {Number[]} transform matrix\n */\n composeMatrix: function(options) {\n var matrix = [1, 0, 0, 1, options.translateX || 0, options.translateY || 0],\n multiply = fabric.util.multiplyTransformMatrices;\n if (options.angle) {\n matrix = multiply(matrix, fabric.util.calcRotateMatrix(options));\n }\n if (options.scaleX !== 1 || options.scaleY !== 1 ||\n options.skewX || options.skewY || options.flipX || options.flipY) {\n matrix = multiply(matrix, fabric.util.calcDimensionsMatrix(options));\n }\n return matrix;\n },\n\n /**\n * reset an object transform state to neutral. Top and left are not accounted for\n * @static\n * @memberOf fabric.util\n * @param {fabric.Object} target object to transform\n */\n resetObjectTransform: function (target) {\n target.scaleX = 1;\n target.scaleY = 1;\n target.skewX = 0;\n target.skewY = 0;\n target.flipX = false;\n target.flipY = false;\n target.rotate(0);\n },\n\n /**\n * Extract Object transform values\n * @static\n * @memberOf fabric.util\n * @param {fabric.Object} target object to read from\n * @return {Object} Components of transform\n */\n saveObjectTransform: function (target) {\n return {\n scaleX: target.scaleX,\n scaleY: target.scaleY,\n skewX: target.skewX,\n skewY: target.skewY,\n angle: target.angle,\n left: target.left,\n flipX: target.flipX,\n flipY: target.flipY,\n top: target.top\n };\n },\n\n /**\n * Returns true if context has transparent pixel\n * at specified location (taking tolerance into account)\n * @param {CanvasRenderingContext2D} ctx context\n * @param {Number} x x coordinate\n * @param {Number} y y coordinate\n * @param {Number} tolerance Tolerance\n */\n isTransparent: function(ctx, x, y, tolerance) {\n\n // If tolerance is > 0 adjust start coords to take into account.\n // If moves off Canvas fix to 0\n if (tolerance > 0) {\n if (x > tolerance) {\n x -= tolerance;\n }\n else {\n x = 0;\n }\n if (y > tolerance) {\n y -= tolerance;\n }\n else {\n y = 0;\n }\n }\n\n var _isTransparent = true, i, temp,\n imageData = ctx.getImageData(x, y, (tolerance * 2) || 1, (tolerance * 2) || 1),\n l = imageData.data.length;\n\n // Split image data - for tolerance > 1, pixelDataSize = 4;\n for (i = 3; i < l; i += 4) {\n temp = imageData.data[i];\n _isTransparent = temp <= 0;\n if (_isTransparent === false) {\n break; // Stop if colour found\n }\n }\n\n imageData = null;\n\n return _isTransparent;\n },\n\n /**\n * Parse preserveAspectRatio attribute from element\n * @param {string} attribute to be parsed\n * @return {Object} an object containing align and meetOrSlice attribute\n */\n parsePreserveAspectRatioAttribute: function(attribute) {\n var meetOrSlice = 'meet', alignX = 'Mid', alignY = 'Mid',\n aspectRatioAttrs = attribute.split(' '), align;\n\n if (aspectRatioAttrs && aspectRatioAttrs.length) {\n meetOrSlice = aspectRatioAttrs.pop();\n if (meetOrSlice !== 'meet' && meetOrSlice !== 'slice') {\n align = meetOrSlice;\n meetOrSlice = 'meet';\n }\n else if (aspectRatioAttrs.length) {\n align = aspectRatioAttrs.pop();\n }\n }\n //divide align in alignX and alignY\n alignX = align !== 'none' ? align.slice(1, 4) : 'none';\n alignY = align !== 'none' ? align.slice(5, 8) : 'none';\n return {\n meetOrSlice: meetOrSlice,\n alignX: alignX,\n alignY: alignY\n };\n },\n\n /**\n * Clear char widths cache for the given font family or all the cache if no\n * fontFamily is specified.\n * Use it if you know you are loading fonts in a lazy way and you are not waiting\n * for custom fonts to load properly when adding text objects to the canvas.\n * If a text object is added when its own font is not loaded yet, you will get wrong\n * measurement and so wrong bounding boxes.\n * After the font cache is cleared, either change the textObject text content or call\n * initDimensions() to trigger a recalculation\n * @memberOf fabric.util\n * @param {String} [fontFamily] font family to clear\n */\n clearFabricFontCache: function(fontFamily) {\n fontFamily = (fontFamily || '').toLowerCase();\n if (!fontFamily) {\n fabric.charWidthsCache = { };\n }\n else if (fabric.charWidthsCache[fontFamily]) {\n delete fabric.charWidthsCache[fontFamily];\n }\n },\n\n /**\n * Given current aspect ratio, determines the max width and height that can\n * respect the total allowed area for the cache.\n * @memberOf fabric.util\n * @param {Number} ar aspect ratio\n * @param {Number} maximumArea Maximum area you want to achieve\n * @return {Object.x} Limited dimensions by X\n * @return {Object.y} Limited dimensions by Y\n */\n limitDimsByArea: function(ar, maximumArea) {\n var roughWidth = Math.sqrt(maximumArea * ar),\n perfLimitSizeY = Math.floor(maximumArea / roughWidth);\n return { x: Math.floor(roughWidth), y: perfLimitSizeY };\n },\n\n capValue: function(min, value, max) {\n return Math.max(min, Math.min(value, max));\n },\n\n /**\n * Finds the scale for the object source to fit inside the object destination,\n * keeping aspect ratio intact.\n * respect the total allowed area for the cache.\n * @memberOf fabric.util\n * @param {Object | fabric.Object} source\n * @param {Number} source.height natural unscaled height of the object\n * @param {Number} source.width natural unscaled width of the object\n * @param {Object | fabric.Object} destination\n * @param {Number} destination.height natural unscaled height of the object\n * @param {Number} destination.width natural unscaled width of the object\n * @return {Number} scale factor to apply to source to fit into destination\n */\n findScaleToFit: function(source, destination) {\n return Math.min(destination.width / source.width, destination.height / source.height);\n },\n\n /**\n * Finds the scale for the object source to cover entirely the object destination,\n * keeping aspect ratio intact.\n * respect the total allowed area for the cache.\n * @memberOf fabric.util\n * @param {Object | fabric.Object} source\n * @param {Number} source.height natural unscaled height of the object\n * @param {Number} source.width natural unscaled width of the object\n * @param {Object | fabric.Object} destination\n * @param {Number} destination.height natural unscaled height of the object\n * @param {Number} destination.width natural unscaled width of the object\n * @return {Number} scale factor to apply to source to cover destination\n */\n findScaleToCover: function(source, destination) {\n return Math.max(destination.width / source.width, destination.height / source.height);\n },\n\n /**\n * given an array of 6 number returns something like `\"matrix(...numbers)\"`\n * @memberOf fabric.util\n * @param {Array} trasnform an array with 6 numbers\n * @return {String} transform matrix for svg\n * @return {Object.y} Limited dimensions by Y\n */\n matrixToSVG: function(transform) {\n return 'matrix(' + transform.map(function(value) {\n return fabric.util.toFixed(value, fabric.Object.NUM_FRACTION_DIGITS);\n }).join(' ') + ')';\n },\n\n /**\n * given a width and height, return the size of the bounding box\n * that can contains the box with width/height with applied transform\n * described in options.\n * Use to calculate the boxes around objects for controls.\n * @memberOf fabric.util\n * @param {Number} width\n * @param {Number} height\n * @param {Object} options\n * @param {Number} options.scaleX\n * @param {Number} options.scaleY\n * @param {Number} options.skewX\n * @param {Number} options.skewY\n * @return {Object.x} width of containing\n * @return {Object.y} height of containing\n */\n sizeAfterTransform: function(width, height, options) {\n var dimX = width / 2, dimY = height / 2,\n points = [\n {\n x: -dimX,\n y: -dimY\n },\n {\n x: dimX,\n y: -dimY\n },\n {\n x: -dimX,\n y: dimY\n },\n {\n x: dimX,\n y: dimY\n }],\n transformMatrix = fabric.util.calcDimensionsMatrix(options),\n bbox = fabric.util.makeBoundingBoxFromPoints(points, transformMatrix);\n return {\n x: bbox.width,\n y: bbox.height,\n };\n }\n };\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function() {\n var _join = Array.prototype.join,\n commandLengths = {\n m: 2,\n l: 2,\n h: 1,\n v: 1,\n c: 6,\n s: 4,\n q: 4,\n t: 2,\n a: 7\n },\n repeatedCommands = {\n m: 'l',\n M: 'L'\n };\n function segmentToBezier(th2, th3, cosTh, sinTh, rx, ry, cx1, cy1, mT, fromX, fromY) {\n var costh2 = fabric.util.cos(th2),\n sinth2 = fabric.util.sin(th2),\n costh3 = fabric.util.cos(th3),\n sinth3 = fabric.util.sin(th3),\n toX = cosTh * rx * costh3 - sinTh * ry * sinth3 + cx1,\n toY = sinTh * rx * costh3 + cosTh * ry * sinth3 + cy1,\n cp1X = fromX + mT * ( -cosTh * rx * sinth2 - sinTh * ry * costh2),\n cp1Y = fromY + mT * ( -sinTh * rx * sinth2 + cosTh * ry * costh2),\n cp2X = toX + mT * ( cosTh * rx * sinth3 + sinTh * ry * costh3),\n cp2Y = toY + mT * ( sinTh * rx * sinth3 - cosTh * ry * costh3);\n\n return ['C',\n cp1X, cp1Y,\n cp2X, cp2Y,\n toX, toY\n ];\n }\n\n /* Adapted from http://dxr.mozilla.org/mozilla-central/source/content/svg/content/src/nsSVGPathDataParser.cpp\n * by Andrea Bogazzi code is under MPL. if you don't have a copy of the license you can take it here\n * http://mozilla.org/MPL/2.0/\n */\n function arcToSegments(toX, toY, rx, ry, large, sweep, rotateX) {\n var PI = Math.PI, th = rotateX * PI / 180,\n sinTh = fabric.util.sin(th),\n cosTh = fabric.util.cos(th),\n fromX = 0, fromY = 0;\n\n rx = Math.abs(rx);\n ry = Math.abs(ry);\n\n var px = -cosTh * toX * 0.5 - sinTh * toY * 0.5,\n py = -cosTh * toY * 0.5 + sinTh * toX * 0.5,\n rx2 = rx * rx, ry2 = ry * ry, py2 = py * py, px2 = px * px,\n pl = rx2 * ry2 - rx2 * py2 - ry2 * px2,\n root = 0;\n\n if (pl < 0) {\n var s = Math.sqrt(1 - pl / (rx2 * ry2));\n rx *= s;\n ry *= s;\n }\n else {\n root = (large === sweep ? -1.0 : 1.0) *\n Math.sqrt( pl / (rx2 * py2 + ry2 * px2));\n }\n\n var cx = root * rx * py / ry,\n cy = -root * ry * px / rx,\n cx1 = cosTh * cx - sinTh * cy + toX * 0.5,\n cy1 = sinTh * cx + cosTh * cy + toY * 0.5,\n mTheta = calcVectorAngle(1, 0, (px - cx) / rx, (py - cy) / ry),\n dtheta = calcVectorAngle((px - cx) / rx, (py - cy) / ry, (-px - cx) / rx, (-py - cy) / ry);\n\n if (sweep === 0 && dtheta > 0) {\n dtheta -= 2 * PI;\n }\n else if (sweep === 1 && dtheta < 0) {\n dtheta += 2 * PI;\n }\n\n // Convert into cubic bezier segments <= 90deg\n var segments = Math.ceil(Math.abs(dtheta / PI * 2)),\n result = [], mDelta = dtheta / segments,\n mT = 8 / 3 * Math.sin(mDelta / 4) * Math.sin(mDelta / 4) / Math.sin(mDelta / 2),\n th3 = mTheta + mDelta;\n\n for (var i = 0; i < segments; i++) {\n result[i] = segmentToBezier(mTheta, th3, cosTh, sinTh, rx, ry, cx1, cy1, mT, fromX, fromY);\n fromX = result[i][5];\n fromY = result[i][6];\n mTheta = th3;\n th3 += mDelta;\n }\n return result;\n }\n\n /*\n * Private\n */\n function calcVectorAngle(ux, uy, vx, vy) {\n var ta = Math.atan2(uy, ux),\n tb = Math.atan2(vy, vx);\n if (tb >= ta) {\n return tb - ta;\n }\n else {\n return 2 * Math.PI - (ta - tb);\n }\n }\n\n /**\n * Calculate bounding box of a beziercurve\n * @param {Number} x0 starting point\n * @param {Number} y0\n * @param {Number} x1 first control point\n * @param {Number} y1\n * @param {Number} x2 secondo control point\n * @param {Number} y2\n * @param {Number} x3 end of beizer\n * @param {Number} y3\n */\n // taken from http://jsbin.com/ivomiq/56/edit no credits available for that.\n // TODO: can we normalize this with the starting points set at 0 and then translated the bbox?\n function getBoundsOfCurve(x0, y0, x1, y1, x2, y2, x3, y3) {\n var argsString;\n if (fabric.cachesBoundsOfCurve) {\n argsString = _join.call(arguments);\n if (fabric.boundsOfCurveCache[argsString]) {\n return fabric.boundsOfCurveCache[argsString];\n }\n }\n\n var sqrt = Math.sqrt,\n min = Math.min, max = Math.max,\n abs = Math.abs, tvalues = [],\n bounds = [[], []],\n a, b, c, t, t1, t2, b2ac, sqrtb2ac;\n\n b = 6 * x0 - 12 * x1 + 6 * x2;\n a = -3 * x0 + 9 * x1 - 9 * x2 + 3 * x3;\n c = 3 * x1 - 3 * x0;\n\n for (var i = 0; i < 2; ++i) {\n if (i > 0) {\n b = 6 * y0 - 12 * y1 + 6 * y2;\n a = -3 * y0 + 9 * y1 - 9 * y2 + 3 * y3;\n c = 3 * y1 - 3 * y0;\n }\n\n if (abs(a) < 1e-12) {\n if (abs(b) < 1e-12) {\n continue;\n }\n t = -c / b;\n if (0 < t && t < 1) {\n tvalues.push(t);\n }\n continue;\n }\n b2ac = b * b - 4 * c * a;\n if (b2ac < 0) {\n continue;\n }\n sqrtb2ac = sqrt(b2ac);\n t1 = (-b + sqrtb2ac) / (2 * a);\n if (0 < t1 && t1 < 1) {\n tvalues.push(t1);\n }\n t2 = (-b - sqrtb2ac) / (2 * a);\n if (0 < t2 && t2 < 1) {\n tvalues.push(t2);\n }\n }\n\n var x, y, j = tvalues.length, jlen = j, mt;\n while (j--) {\n t = tvalues[j];\n mt = 1 - t;\n x = (mt * mt * mt * x0) + (3 * mt * mt * t * x1) + (3 * mt * t * t * x2) + (t * t * t * x3);\n bounds[0][j] = x;\n\n y = (mt * mt * mt * y0) + (3 * mt * mt * t * y1) + (3 * mt * t * t * y2) + (t * t * t * y3);\n bounds[1][j] = y;\n }\n\n bounds[0][jlen] = x0;\n bounds[1][jlen] = y0;\n bounds[0][jlen + 1] = x3;\n bounds[1][jlen + 1] = y3;\n var result = [\n {\n x: min.apply(null, bounds[0]),\n y: min.apply(null, bounds[1])\n },\n {\n x: max.apply(null, bounds[0]),\n y: max.apply(null, bounds[1])\n }\n ];\n if (fabric.cachesBoundsOfCurve) {\n fabric.boundsOfCurveCache[argsString] = result;\n }\n return result;\n }\n\n /**\n * Converts arc to a bunch of beizer curves\n * @param {Number} fx starting point x\n * @param {Number} fy starting point y\n * @param {Array} coords Arc command\n */\n function fromArcToBeizers(fx, fy, coords) {\n var rx = coords[1],\n ry = coords[2],\n rot = coords[3],\n large = coords[4],\n sweep = coords[5],\n tx = coords[6],\n ty = coords[7],\n segsNorm = arcToSegments(tx - fx, ty - fy, rx, ry, large, sweep, rot);\n\n for (var i = 0, len = segsNorm.length; i < len; i++) {\n segsNorm[i][1] += fx;\n segsNorm[i][2] += fy;\n segsNorm[i][3] += fx;\n segsNorm[i][4] += fy;\n segsNorm[i][5] += fx;\n segsNorm[i][6] += fy;\n }\n return segsNorm;\n };\n\n\n function makePathSimpler(path) {\n // x and y represent the last point of the path. the previous command point.\n // we add them to each relative command to make it an absolute comment.\n // we also swap the v V h H with L, because are easier to transform.\n var x = 0, y = 0, len = path.length,\n // x1 and y1 represent the last point of the subpath. the subpath is started with\n // m or M command. When a z or Z command is drawn, x and y need to be resetted to\n // the last x1 and y1.\n x1 = 0, y1 = 0, current, i, converted,\n // previous will host the letter of the previous command, to handle S and T.\n // controlX and controlY will host the previous reflected control point\n destinationPath = [], previous, controlX, controlY;\n for (i = 0; i < len; ++i) {\n converted = false;\n current = path[i].slice(0);\n switch (current[0]) { // first letter\n case 'l': // lineto, relative\n current[0] = 'L';\n current[1] += x;\n current[2] += y;\n // falls through\n case 'L':\n x = current[1];\n y = current[2];\n break;\n case 'h': // horizontal lineto, relative\n current[1] += x;\n // falls through\n case 'H':\n current[0] = 'L';\n current[2] = y;\n x = current[1];\n break;\n case 'v': // vertical lineto, relative\n current[1] += y;\n // falls through\n case 'V':\n current[0] = 'L';\n y = current[1];\n current[1] = x;\n current[2] = y;\n break;\n case 'm': // moveTo, relative\n current[0] = 'M';\n current[1] += x;\n current[2] += y;\n // falls through\n case 'M':\n x = current[1];\n y = current[2];\n x1 = current[1];\n y1 = current[2];\n break;\n case 'c': // bezierCurveTo, relative\n current[0] = 'C';\n current[1] += x;\n current[2] += y;\n current[3] += x;\n current[4] += y;\n current[5] += x;\n current[6] += y;\n // falls through\n case 'C':\n controlX = current[3];\n controlY = current[4];\n x = current[5];\n y = current[6];\n break;\n case 's': // shorthand cubic bezierCurveTo, relative\n current[0] = 'S';\n current[1] += x;\n current[2] += y;\n current[3] += x;\n current[4] += y;\n // falls through\n case 'S':\n // would be sScC but since we are swapping sSc for C, we check just that.\n if (previous === 'C') {\n // calculate reflection of previous control points\n controlX = 2 * x - controlX;\n controlY = 2 * y - controlY;\n }\n else {\n // If there is no previous command or if the previous command was not a C, c, S, or s,\n // the control point is coincident with the current point\n controlX = x;\n controlY = y;\n }\n x = current[3];\n y = current[4];\n current[0] = 'C';\n current[5] = current[3];\n current[6] = current[4];\n current[3] = current[1];\n current[4] = current[2];\n current[1] = controlX;\n current[2] = controlY;\n // current[3] and current[4] are NOW the second control point.\n // we keep it for the next reflection.\n controlX = current[3];\n controlY = current[4];\n break;\n case 'q': // quadraticCurveTo, relative\n current[0] = 'Q';\n current[1] += x;\n current[2] += y;\n current[3] += x;\n current[4] += y;\n // falls through\n case 'Q':\n controlX = current[1];\n controlY = current[2];\n x = current[3];\n y = current[4];\n break;\n case 't': // shorthand quadraticCurveTo, relative\n current[0] = 'T';\n current[1] += x;\n current[2] += y;\n // falls through\n case 'T':\n if (previous === 'Q') {\n // calculate reflection of previous control point\n controlX = 2 * x - controlX;\n controlY = 2 * y - controlY;\n }\n else {\n // If there is no previous command or if the previous command was not a Q, q, T or t,\n // assume the control point is coincident with the current point\n controlX = x;\n controlY = y;\n }\n current[0] = 'Q';\n x = current[1];\n y = current[2];\n current[1] = controlX;\n current[2] = controlY;\n current[3] = x;\n current[4] = y;\n break;\n case 'a':\n current[0] = 'A';\n current[6] += x;\n current[7] += y;\n // falls through\n case 'A':\n converted = true;\n destinationPath = destinationPath.concat(fromArcToBeizers(x, y, current));\n x = current[6];\n y = current[7];\n break;\n case 'z':\n case 'Z':\n x = x1;\n y = y1;\n break;\n default:\n }\n if (!converted) {\n destinationPath.push(current);\n }\n previous = current[0];\n }\n return destinationPath;\n };\n\n /**\n * Calc length from point x1,y1 to x2,y2\n * @param {Number} x1 starting point x\n * @param {Number} y1 starting point y\n * @param {Number} x2 starting point x\n * @param {Number} y2 starting point y\n * @return {Number} length of segment\n */\n function calcLineLength(x1, y1, x2, y2) {\n return Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));\n }\n\n // functions for the Cubic beizer\n // taken from: https://github.com/konvajs/konva/blob/7.0.5/src/shapes/Path.ts#L350\n function CB1(t) {\n return t * t * t;\n }\n function CB2(t) {\n return 3 * t * t * (1 - t);\n }\n function CB3(t) {\n return 3 * t * (1 - t) * (1 - t);\n }\n function CB4(t) {\n return (1 - t) * (1 - t) * (1 - t);\n }\n\n function getPointOnCubicBezierIterator(p1x, p1y, p2x, p2y, p3x, p3y, p4x, p4y) {\n return function(pct) {\n var c1 = CB1(pct), c2 = CB2(pct), c3 = CB3(pct), c4 = CB4(pct);\n return {\n x: p4x * c1 + p3x * c2 + p2x * c3 + p1x * c4,\n y: p4y * c1 + p3y * c2 + p2y * c3 + p1y * c4\n };\n };\n }\n\n function QB1(t) {\n return t * t;\n }\n\n function QB2(t) {\n return 2 * t * (1 - t);\n }\n\n function QB3(t) {\n return (1 - t) * (1 - t);\n }\n\n function getPointOnQuadraticBezierIterator(p1x, p1y, p2x, p2y, p3x, p3y) {\n return function(pct) {\n var c1 = QB1(pct), c2 = QB2(pct), c3 = QB3(pct);\n return {\n x: p3x * c1 + p2x * c2 + p1x * c3,\n y: p3y * c1 + p2y * c2 + p1y * c3\n };\n };\n }\n\n function pathIterator(iterator, x1, y1) {\n var tempP = { x: x1, y: y1 }, p, tmpLen = 0, perc;\n for (perc = 0.01; perc <= 1; perc += 0.01) {\n p = iterator(perc);\n tmpLen += calcLineLength(tempP.x, tempP.y, p.x, p.y);\n tempP = p;\n }\n return tmpLen;\n }\n\n //measures the length of a pre-simplified path\n function getPathSegmentsInfo(path) {\n var totalLength = 0, len = path.length, current,\n //x2 and y2 are the coords of segment start\n //x1 and y1 are the coords of the current point\n x1 = 0, y1 = 0, x2 = 0, y2 = 0, info = [], iterator, tempInfo;\n for (var i = 0; i < len; i++) {\n current = path[i];\n tempInfo = {\n x: x1,\n y: y1,\n command: current[0],\n };\n switch (current[0]) { //first letter\n case 'M':\n tempInfo.length = 0;\n x2 = x1 = current[1];\n y2 = y1 = current[2];\n break;\n case 'L':\n tempInfo.length = calcLineLength(x1, y1, current[1], current[2]);\n x1 = current[1];\n y1 = current[2];\n break;\n case 'C':\n iterator = getPointOnCubicBezierIterator(\n x1,\n y1,\n current[1],\n current[2],\n current[3],\n current[4],\n current[5],\n current[6]\n );\n tempInfo.length = pathIterator(iterator, x1, y1);\n x1 = current[5];\n y1 = current[6];\n break;\n case 'Q':\n iterator = getPointOnQuadraticBezierIterator(\n x1,\n y1,\n current[1],\n current[2],\n current[3],\n current[4]\n );\n tempInfo.length = pathIterator(iterator, x1, y1);\n x1 = current[3];\n y1 = current[4];\n break;\n case 'Z':\n case 'z':\n // we add those in order to ease calculations later\n tempInfo.destX = x2;\n tempInfo.destY = y2;\n tempInfo.length = calcLineLength(x1, y1, x2, y2);\n x1 = x2;\n y1 = y2;\n break;\n }\n totalLength += tempInfo.length;\n info.push(tempInfo);\n }\n info.push({ length: totalLength, x: x1, y: y1 });\n return info;\n }\n\n function getPointOnPath(path, perc, infos) {\n if (!infos) {\n infos = getPathSegmentsInfo(path);\n }\n var distance = infos[infos.length - 1] * perc, i = 0;\n while ((distance - infos[i] > 0) && i < infos.length) {\n distance -= infos[i];\n i++;\n }\n var segInfo = infos[i], segPercent = distance / segInfo.length,\n command = segInfo.length, segment = path[i];\n switch (command) {\n case 'Z':\n case 'z':\n return new fabric.Point(segInfo.x, segInfo.y).lerp(\n new fabric.Point(segInfo.destX, segInfo.destY),\n segPercent\n );\n break;\n case 'L':\n return new fabric.Point(segInfo.x, segInfo.y).lerp(\n new fabric.Point(segment[1], segment[2]),\n segPercent\n );\n break;\n case 'C':\n return getPointOnCubicBezierIterator(\n segInfo.x,\n segInfo.y,\n segment[1],\n segment[2],\n segment[3],\n segment[4],\n segment[5],\n segment[6]\n )(segPercent);\n break;\n case 'Q':\n return getPointOnQuadraticBezierIterator(\n segInfo.x,\n segInfo.y,\n segment[1],\n segment[2],\n segment[3],\n segment[4]\n )(segPercent);\n break;\n }\n }\n\n function parsePath(pathString) {\n var result = [],\n coords = [],\n currentPath,\n parsed,\n re = fabric.rePathCommand,\n rNumber = '[-+]?(?:\\\\d*\\\\.\\\\d+|\\\\d+\\\\.?)(?:[eE][-+]?\\\\d+)?\\\\s*',\n rNumberCommaWsp = '(' + rNumber + ')' + fabric.commaWsp,\n rFlagCommaWsp = '([01])' + fabric.commaWsp + '?',\n rArcSeq = rNumberCommaWsp + '?' + rNumberCommaWsp + '?' + rNumberCommaWsp + rFlagCommaWsp + rFlagCommaWsp +\n rNumberCommaWsp + '?(' + rNumber + ')',\n regArcArgumentSequence = new RegExp(rArcSeq, 'g'),\n match,\n coordsStr,\n // one of commands (m,M,l,L,q,Q,c,C,etc.) followed by non-command characters (i.e. command values)\n path;\n if (!pathString || !pathString.match) {\n return result;\n }\n path = pathString.match(/[mzlhvcsqta][^mzlhvcsqta]*/gi);\n\n for (var i = 0, coordsParsed, len = path.length; i < len; i++) {\n currentPath = path[i];\n\n coordsStr = currentPath.slice(1).trim();\n coords.length = 0;\n\n var command = currentPath.charAt(0);\n coordsParsed = [command];\n\n if (command.toLowerCase() === 'a') {\n // arcs have special flags that apparently don't require spaces so handle special\n for (var args; (args = regArcArgumentSequence.exec(coordsStr));) {\n for (var j = 1; j < args.length; j++) {\n coords.push(args[j]);\n }\n }\n }\n else {\n while ((match = re.exec(coordsStr))) {\n coords.push(match[0]);\n }\n }\n\n for (var j = 0, jlen = coords.length; j < jlen; j++) {\n parsed = parseFloat(coords[j]);\n if (!isNaN(parsed)) {\n coordsParsed.push(parsed);\n }\n }\n\n var commandLength = commandLengths[command.toLowerCase()],\n repeatedCommand = repeatedCommands[command] || command;\n\n if (coordsParsed.length - 1 > commandLength) {\n for (var k = 1, klen = coordsParsed.length; k < klen; k += commandLength) {\n result.push([command].concat(coordsParsed.slice(k, k + commandLength)));\n command = repeatedCommand;\n }\n }\n else {\n result.push(coordsParsed);\n }\n }\n\n return result;\n };\n\n /**\n * Calculate bounding box of a elliptic-arc\n * @deprecated\n * @param {Number} fx start point of arc\n * @param {Number} fy\n * @param {Number} rx horizontal radius\n * @param {Number} ry vertical radius\n * @param {Number} rot angle of horizontal axis\n * @param {Number} large 1 or 0, whatever the arc is the big or the small on the 2 points\n * @param {Number} sweep 1 or 0, 1 clockwise or counterclockwise direction\n * @param {Number} tx end point of arc\n * @param {Number} ty\n */\n function getBoundsOfArc(fx, fy, rx, ry, rot, large, sweep, tx, ty) {\n\n var fromX = 0, fromY = 0, bound, bounds = [],\n segs = arcToSegments(tx - fx, ty - fy, rx, ry, large, sweep, rot);\n\n for (var i = 0, len = segs.length; i < len; i++) {\n bound = getBoundsOfCurve(fromX, fromY, segs[i][1], segs[i][2], segs[i][3], segs[i][4], segs[i][5], segs[i][6]);\n bounds.push({ x: bound[0].x + fx, y: bound[0].y + fy });\n bounds.push({ x: bound[1].x + fx, y: bound[1].y + fy });\n fromX = segs[i][5];\n fromY = segs[i][6];\n }\n return bounds;\n };\n\n /**\n * Draws arc\n * @param {CanvasRenderingContext2D} ctx\n * @param {Number} fx\n * @param {Number} fy\n * @param {Array} coords coords of the arc, without the front 'A/a'\n */\n function drawArc(ctx, fx, fy, coords) {\n coords = coords.slice(0).unshift('X'); // command A or a does not matter\n var beizers = fromArcToBeizers(fx, fy, coords);\n beizers.forEach(function(beizer) {\n ctx.bezierCurveTo.apply(ctx, beizer.slice(1));\n });\n };\n\n fabric.util.parsePath = parsePath;\n fabric.util.makePathSimpler = makePathSimpler;\n fabric.util.getPathSegmentsInfo = getPathSegmentsInfo;\n fabric.util.fromArcToBeizers = fromArcToBeizers;\n fabric.util.getBoundsOfCurve = getBoundsOfCurve;\n fabric.util.getPointOnPath = getPointOnPath;\n // kept because we do not want to make breaking changes.\n // but useless and deprecated.\n fabric.util.getBoundsOfArc = getBoundsOfArc;\n fabric.util.drawArc = drawArc;\n})();\n\n\n(function() {\n\n var slice = Array.prototype.slice;\n\n /**\n * Invokes method on all items in a given array\n * @memberOf fabric.util.array\n * @param {Array} array Array to iterate over\n * @param {String} method Name of a method to invoke\n * @return {Array}\n */\n function invoke(array, method) {\n var args = slice.call(arguments, 2), result = [];\n for (var i = 0, len = array.length; i < len; i++) {\n result[i] = args.length ? array[i][method].apply(array[i], args) : array[i][method].call(array[i]);\n }\n return result;\n }\n\n /**\n * Finds maximum value in array (not necessarily \"first\" one)\n * @memberOf fabric.util.array\n * @param {Array} array Array to iterate over\n * @param {String} byProperty\n * @return {*}\n */\n function max(array, byProperty) {\n return find(array, byProperty, function(value1, value2) {\n return value1 >= value2;\n });\n }\n\n /**\n * Finds minimum value in array (not necessarily \"first\" one)\n * @memberOf fabric.util.array\n * @param {Array} array Array to iterate over\n * @param {String} byProperty\n * @return {*}\n */\n function min(array, byProperty) {\n return find(array, byProperty, function(value1, value2) {\n return value1 < value2;\n });\n }\n\n /**\n * @private\n */\n function fill(array, value) {\n var k = array.length;\n while (k--) {\n array[k] = value;\n }\n return array;\n }\n\n /**\n * @private\n */\n function find(array, byProperty, condition) {\n if (!array || array.length === 0) {\n return;\n }\n\n var i = array.length - 1,\n result = byProperty ? array[i][byProperty] : array[i];\n if (byProperty) {\n while (i--) {\n if (condition(array[i][byProperty], result)) {\n result = array[i][byProperty];\n }\n }\n }\n else {\n while (i--) {\n if (condition(array[i], result)) {\n result = array[i];\n }\n }\n }\n return result;\n }\n\n /**\n * @namespace fabric.util.array\n */\n fabric.util.array = {\n fill: fill,\n invoke: invoke,\n min: min,\n max: max\n };\n\n})();\n\n\n(function() {\n /**\n * Copies all enumerable properties of one js object to another\n * this does not and cannot compete with generic utils.\n * Does not clone or extend fabric.Object subclasses.\n * This is mostly for internal use and has extra handling for fabricJS objects\n * it skips the canvas and group properties in deep cloning.\n * @memberOf fabric.util.object\n * @param {Object} destination Where to copy to\n * @param {Object} source Where to copy from\n * @return {Object}\n */\n\n function extend(destination, source, deep) {\n // JScript DontEnum bug is not taken care of\n // the deep clone is for internal use, is not meant to avoid\n // javascript traps or cloning html element or self referenced objects.\n if (deep) {\n if (!fabric.isLikelyNode && source instanceof Element) {\n // avoid cloning deep images, canvases,\n destination = source;\n }\n else if (source instanceof Array) {\n destination = [];\n for (var i = 0, len = source.length; i < len; i++) {\n destination[i] = extend({ }, source[i], deep);\n }\n }\n else if (source && typeof source === 'object') {\n for (var property in source) {\n if (property === 'canvas' || property === 'group') {\n // we do not want to clone this props at all.\n // we want to keep the keys in the copy\n destination[property] = null;\n }\n else if (source.hasOwnProperty(property)) {\n destination[property] = extend({ }, source[property], deep);\n }\n }\n }\n else {\n // this sounds odd for an extend but is ok for recursive use\n destination = source;\n }\n }\n else {\n for (var property in source) {\n destination[property] = source[property];\n }\n }\n return destination;\n }\n\n /**\n * Creates an empty object and copies all enumerable properties of another object to it\n * @memberOf fabric.util.object\n * TODO: this function return an empty object if you try to clone null\n * @param {Object} object Object to clone\n * @return {Object}\n */\n function clone(object, deep) {\n return extend({ }, object, deep);\n }\n\n /** @namespace fabric.util.object */\n fabric.util.object = {\n extend: extend,\n clone: clone\n };\n fabric.util.object.extend(fabric.util, fabric.Observable);\n})();\n\n\n(function() {\n\n /**\n * Camelizes a string\n * @memberOf fabric.util.string\n * @param {String} string String to camelize\n * @return {String} Camelized version of a string\n */\n function camelize(string) {\n return string.replace(/-+(.)?/g, function(match, character) {\n return character ? character.toUpperCase() : '';\n });\n }\n\n /**\n * Capitalizes a string\n * @memberOf fabric.util.string\n * @param {String} string String to capitalize\n * @param {Boolean} [firstLetterOnly] If true only first letter is capitalized\n * and other letters stay untouched, if false first letter is capitalized\n * and other letters are converted to lowercase.\n * @return {String} Capitalized version of a string\n */\n function capitalize(string, firstLetterOnly) {\n return string.charAt(0).toUpperCase() +\n (firstLetterOnly ? string.slice(1) : string.slice(1).toLowerCase());\n }\n\n /**\n * Escapes XML in a string\n * @memberOf fabric.util.string\n * @param {String} string String to escape\n * @return {String} Escaped version of a string\n */\n function escapeXml(string) {\n return string.replace(/&/g, '&')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n .replace(/</g, '<')\n .replace(/>/g, '>');\n }\n\n /**\n * Divide a string in the user perceived single units\n * @memberOf fabric.util.string\n * @param {String} textstring String to escape\n * @return {Array} array containing the graphemes\n */\n function graphemeSplit(textstring) {\n var i = 0, chr, graphemes = [];\n for (i = 0, chr; i < textstring.length; i++) {\n if ((chr = getWholeChar(textstring, i)) === false) {\n continue;\n }\n graphemes.push(chr);\n }\n return graphemes;\n }\n\n // taken from mdn in the charAt doc page.\n function getWholeChar(str, i) {\n var code = str.charCodeAt(i);\n\n if (isNaN(code)) {\n return ''; // Position not found\n }\n if (code < 0xD800 || code > 0xDFFF) {\n return str.charAt(i);\n }\n\n // High surrogate (could change last hex to 0xDB7F to treat high private\n // surrogates as single characters)\n if (0xD800 <= code && code <= 0xDBFF) {\n if (str.length <= (i + 1)) {\n throw 'High surrogate without following low surrogate';\n }\n var next = str.charCodeAt(i + 1);\n if (0xDC00 > next || next > 0xDFFF) {\n throw 'High surrogate without following low surrogate';\n }\n return str.charAt(i) + str.charAt(i + 1);\n }\n // Low surrogate (0xDC00 <= code && code <= 0xDFFF)\n if (i === 0) {\n throw 'Low surrogate without preceding high surrogate';\n }\n var prev = str.charCodeAt(i - 1);\n\n // (could change last hex to 0xDB7F to treat high private\n // surrogates as single characters)\n if (0xD800 > prev || prev > 0xDBFF) {\n throw 'Low surrogate without preceding high surrogate';\n }\n // We can pass over low surrogates now as the second component\n // in a pair which we have already processed\n return false;\n }\n\n\n /**\n * String utilities\n * @namespace fabric.util.string\n */\n fabric.util.string = {\n camelize: camelize,\n capitalize: capitalize,\n escapeXml: escapeXml,\n graphemeSplit: graphemeSplit\n };\n})();\n\n\n(function() {\n\n var slice = Array.prototype.slice, emptyFunction = function() { },\n\n IS_DONTENUM_BUGGY = (function() {\n for (var p in { toString: 1 }) {\n if (p === 'toString') {\n return false;\n }\n }\n return true;\n })(),\n\n /** @ignore */\n addMethods = function(klass, source, parent) {\n for (var property in source) {\n\n if (property in klass.prototype &&\n typeof klass.prototype[property] === 'function' &&\n (source[property] + '').indexOf('callSuper') > -1) {\n\n klass.prototype[property] = (function(property) {\n return function() {\n\n var superclass = this.constructor.superclass;\n this.constructor.superclass = parent;\n var returnValue = source[property].apply(this, arguments);\n this.constructor.superclass = superclass;\n\n if (property !== 'initialize') {\n return returnValue;\n }\n };\n })(property);\n }\n else {\n klass.prototype[property] = source[property];\n }\n\n if (IS_DONTENUM_BUGGY) {\n if (source.toString !== Object.prototype.toString) {\n klass.prototype.toString = source.toString;\n }\n if (source.valueOf !== Object.prototype.valueOf) {\n klass.prototype.valueOf = source.valueOf;\n }\n }\n }\n };\n\n function Subclass() { }\n\n function callSuper(methodName) {\n var parentMethod = null,\n _this = this;\n\n // climb prototype chain to find method not equal to callee's method\n while (_this.constructor.superclass) {\n var superClassMethod = _this.constructor.superclass.prototype[methodName];\n if (_this[methodName] !== superClassMethod) {\n parentMethod = superClassMethod;\n break;\n }\n // eslint-disable-next-line\n _this = _this.constructor.superclass.prototype;\n }\n\n if (!parentMethod) {\n return console.log('tried to callSuper ' + methodName + ', method not found in prototype chain', this);\n }\n\n return (arguments.length > 1)\n ? parentMethod.apply(this, slice.call(arguments, 1))\n : parentMethod.call(this);\n }\n\n /**\n * Helper for creation of \"classes\".\n * @memberOf fabric.util\n * @param {Function} [parent] optional \"Class\" to inherit from\n * @param {Object} [properties] Properties shared by all instances of this class\n * (be careful modifying objects defined here as this would affect all instances)\n */\n function createClass() {\n var parent = null,\n properties = slice.call(arguments, 0);\n\n if (typeof properties[0] === 'function') {\n parent = properties.shift();\n }\n function klass() {\n this.initialize.apply(this, arguments);\n }\n\n klass.superclass = parent;\n klass.subclasses = [];\n\n if (parent) {\n Subclass.prototype = parent.prototype;\n klass.prototype = new Subclass();\n parent.subclasses.push(klass);\n }\n for (var i = 0, length = properties.length; i < length; i++) {\n addMethods(klass, properties[i], parent);\n }\n if (!klass.prototype.initialize) {\n klass.prototype.initialize = emptyFunction;\n }\n klass.prototype.constructor = klass;\n klass.prototype.callSuper = callSuper;\n return klass;\n }\n\n fabric.util.createClass = createClass;\n})();\n\n\n(function () {\n // since ie11 can use addEventListener but they do not support options, i need to check\n var couldUseAttachEvent = !!fabric.document.createElement('div').attachEvent,\n touchEvents = ['touchstart', 'touchmove', 'touchend'];\n /**\n * Adds an event listener to an element\n * @function\n * @memberOf fabric.util\n * @param {HTMLElement} element\n * @param {String} eventName\n * @param {Function} handler\n */\n fabric.util.addListener = function(element, eventName, handler, options) {\n element && element.addEventListener(eventName, handler, couldUseAttachEvent ? false : options);\n };\n\n /**\n * Removes an event listener from an element\n * @function\n * @memberOf fabric.util\n * @param {HTMLElement} element\n * @param {String} eventName\n * @param {Function} handler\n */\n fabric.util.removeListener = function(element, eventName, handler, options) {\n element && element.removeEventListener(eventName, handler, couldUseAttachEvent ? false : options);\n };\n\n function getTouchInfo(event) {\n var touchProp = event.changedTouches;\n if (touchProp && touchProp[0]) {\n return touchProp[0];\n }\n return event;\n }\n\n fabric.util.getPointer = function(event) {\n var element = event.target,\n scroll = fabric.util.getScrollLeftTop(element),\n _evt = getTouchInfo(event);\n return {\n x: _evt.clientX + scroll.left,\n y: _evt.clientY + scroll.top\n };\n };\n\n fabric.util.isTouchEvent = function(event) {\n return touchEvents.indexOf(event.type) > -1 || event.pointerType === 'touch';\n };\n})();\n\n\n(function () {\n\n /**\n * Cross-browser wrapper for setting element's style\n * @memberOf fabric.util\n * @param {HTMLElement} element\n * @param {Object} styles\n * @return {HTMLElement} Element that was passed as a first argument\n */\n function setStyle(element, styles) {\n var elementStyle = element.style;\n if (!elementStyle) {\n return element;\n }\n if (typeof styles === 'string') {\n element.style.cssText += ';' + styles;\n return styles.indexOf('opacity') > -1\n ? setOpacity(element, styles.match(/opacity:\\s*(\\d?\\.?\\d*)/)[1])\n : element;\n }\n for (var property in styles) {\n if (property === 'opacity') {\n setOpacity(element, styles[property]);\n }\n else {\n var normalizedProperty = (property === 'float' || property === 'cssFloat')\n ? (typeof elementStyle.styleFloat === 'undefined' ? 'cssFloat' : 'styleFloat')\n : property;\n elementStyle[normalizedProperty] = styles[property];\n }\n }\n return element;\n }\n\n var parseEl = fabric.document.createElement('div'),\n supportsOpacity = typeof parseEl.style.opacity === 'string',\n supportsFilters = typeof parseEl.style.filter === 'string',\n reOpacity = /alpha\\s*\\(\\s*opacity\\s*=\\s*([^\\)]+)\\)/,\n\n /** @ignore */\n setOpacity = function (element) { return element; };\n\n if (supportsOpacity) {\n /** @ignore */\n setOpacity = function(element, value) {\n element.style.opacity = value;\n return element;\n };\n }\n else if (supportsFilters) {\n /** @ignore */\n setOpacity = function(element, value) {\n var es = element.style;\n if (element.currentStyle && !element.currentStyle.hasLayout) {\n es.zoom = 1;\n }\n if (reOpacity.test(es.filter)) {\n value = value >= 0.9999 ? '' : ('alpha(opacity=' + (value * 100) + ')');\n es.filter = es.filter.replace(reOpacity, value);\n }\n else {\n es.filter += ' alpha(opacity=' + (value * 100) + ')';\n }\n return element;\n };\n }\n\n fabric.util.setStyle = setStyle;\n\n})();\n\n\n(function() {\n\n var _slice = Array.prototype.slice;\n\n /**\n * Takes id and returns an element with that id (if one exists in a document)\n * @memberOf fabric.util\n * @param {String|HTMLElement} id\n * @return {HTMLElement|null}\n */\n function getById(id) {\n return typeof id === 'string' ? fabric.document.getElementById(id) : id;\n }\n\n var sliceCanConvertNodelists,\n /**\n * Converts an array-like object (e.g. arguments or NodeList) to an array\n * @memberOf fabric.util\n * @param {Object} arrayLike\n * @return {Array}\n */\n toArray = function(arrayLike) {\n return _slice.call(arrayLike, 0);\n };\n\n try {\n sliceCanConvertNodelists = toArray(fabric.document.childNodes) instanceof Array;\n }\n catch (err) { }\n\n if (!sliceCanConvertNodelists) {\n toArray = function(arrayLike) {\n var arr = new Array(arrayLike.length), i = arrayLike.length;\n while (i--) {\n arr[i] = arrayLike[i];\n }\n return arr;\n };\n }\n\n /**\n * Creates specified element with specified attributes\n * @memberOf fabric.util\n * @param {String} tagName Type of an element to create\n * @param {Object} [attributes] Attributes to set on an element\n * @return {HTMLElement} Newly created element\n */\n function makeElement(tagName, attributes) {\n var el = fabric.document.createElement(tagName);\n for (var prop in attributes) {\n if (prop === 'class') {\n el.className = attributes[prop];\n }\n else if (prop === 'for') {\n el.htmlFor = attributes[prop];\n }\n else {\n el.setAttribute(prop, attributes[prop]);\n }\n }\n return el;\n }\n\n /**\n * Adds class to an element\n * @memberOf fabric.util\n * @param {HTMLElement} element Element to add class to\n * @param {String} className Class to add to an element\n */\n function addClass(element, className) {\n if (element && (' ' + element.className + ' ').indexOf(' ' + className + ' ') === -1) {\n element.className += (element.className ? ' ' : '') + className;\n }\n }\n\n /**\n * Wraps element with another element\n * @memberOf fabric.util\n * @param {HTMLElement} element Element to wrap\n * @param {HTMLElement|String} wrapper Element to wrap with\n * @param {Object} [attributes] Attributes to set on a wrapper\n * @return {HTMLElement} wrapper\n */\n function wrapElement(element, wrapper, attributes) {\n if (typeof wrapper === 'string') {\n wrapper = makeElement(wrapper, attributes);\n }\n if (element.parentNode) {\n element.parentNode.replaceChild(wrapper, element);\n }\n wrapper.appendChild(element);\n return wrapper;\n }\n\n /**\n * Returns element scroll offsets\n * @memberOf fabric.util\n * @param {HTMLElement} element Element to operate on\n * @return {Object} Object with left/top values\n */\n function getScrollLeftTop(element) {\n\n var left = 0,\n top = 0,\n docElement = fabric.document.documentElement,\n body = fabric.document.body || {\n scrollLeft: 0, scrollTop: 0\n };\n\n // While loop checks (and then sets element to) .parentNode OR .host\n // to account for ShadowDOM. We still want to traverse up out of ShadowDOM,\n // but the .parentNode of a root ShadowDOM node will always be null, instead\n // it should be accessed through .host. See http://stackoverflow.com/a/24765528/4383938\n while (element && (element.parentNode || element.host)) {\n\n // Set element to element parent, or 'host' in case of ShadowDOM\n element = element.parentNode || element.host;\n\n if (element === fabric.document) {\n left = body.scrollLeft || docElement.scrollLeft || 0;\n top = body.scrollTop || docElement.scrollTop || 0;\n }\n else {\n left += element.scrollLeft || 0;\n top += element.scrollTop || 0;\n }\n\n if (element.nodeType === 1 && element.style.position === 'fixed') {\n break;\n }\n }\n\n return { left: left, top: top };\n }\n\n /**\n * Returns offset for a given element\n * @function\n * @memberOf fabric.util\n * @param {HTMLElement} element Element to get offset for\n * @return {Object} Object with \"left\" and \"top\" properties\n */\n function getElementOffset(element) {\n var docElem,\n doc = element && element.ownerDocument,\n box = { left: 0, top: 0 },\n offset = { left: 0, top: 0 },\n scrollLeftTop,\n offsetAttributes = {\n borderLeftWidth: 'left',\n borderTopWidth: 'top',\n paddingLeft: 'left',\n paddingTop: 'top'\n };\n\n if (!doc) {\n return offset;\n }\n\n for (var attr in offsetAttributes) {\n offset[offsetAttributes[attr]] += parseInt(getElementStyle(element, attr), 10) || 0;\n }\n\n docElem = doc.documentElement;\n if ( typeof element.getBoundingClientRect !== 'undefined' ) {\n box = element.getBoundingClientRect();\n }\n\n scrollLeftTop = getScrollLeftTop(element);\n\n return {\n left: box.left + scrollLeftTop.left - (docElem.clientLeft || 0) + offset.left,\n top: box.top + scrollLeftTop.top - (docElem.clientTop || 0) + offset.top\n };\n }\n\n /**\n * Returns style attribute value of a given element\n * @memberOf fabric.util\n * @param {HTMLElement} element Element to get style attribute for\n * @param {String} attr Style attribute to get for element\n * @return {String} Style attribute value of the given element.\n */\n var getElementStyle;\n if (fabric.document.defaultView && fabric.document.defaultView.getComputedStyle) {\n getElementStyle = function(element, attr) {\n var style = fabric.document.defaultView.getComputedStyle(element, null);\n return style ? style[attr] : undefined;\n };\n }\n else {\n getElementStyle = function(element, attr) {\n var value = element.style[attr];\n if (!value && element.currentStyle) {\n value = element.currentStyle[attr];\n }\n return value;\n };\n }\n\n (function () {\n var style = fabric.document.documentElement.style,\n selectProp = 'userSelect' in style\n ? 'userSelect'\n : 'MozUserSelect' in style\n ? 'MozUserSelect'\n : 'WebkitUserSelect' in style\n ? 'WebkitUserSelect'\n : 'KhtmlUserSelect' in style\n ? 'KhtmlUserSelect'\n : '';\n\n /**\n * Makes element unselectable\n * @memberOf fabric.util\n * @param {HTMLElement} element Element to make unselectable\n * @return {HTMLElement} Element that was passed in\n */\n function makeElementUnselectable(element) {\n if (typeof element.onselectstart !== 'undefined') {\n element.onselectstart = fabric.util.falseFunction;\n }\n if (selectProp) {\n element.style[selectProp] = 'none';\n }\n else if (typeof element.unselectable === 'string') {\n element.unselectable = 'on';\n }\n return element;\n }\n\n /**\n * Makes element selectable\n * @memberOf fabric.util\n * @param {HTMLElement} element Element to make selectable\n * @return {HTMLElement} Element that was passed in\n */\n function makeElementSelectable(element) {\n if (typeof element.onselectstart !== 'undefined') {\n element.onselectstart = null;\n }\n if (selectProp) {\n element.style[selectProp] = '';\n }\n else if (typeof element.unselectable === 'string') {\n element.unselectable = '';\n }\n return element;\n }\n\n fabric.util.makeElementUnselectable = makeElementUnselectable;\n fabric.util.makeElementSelectable = makeElementSelectable;\n })();\n\n function getNodeCanvas(element) {\n var impl = fabric.jsdomImplForWrapper(element);\n return impl._canvas || impl._image;\n };\n\n function cleanUpJsdomNode(element) {\n if (!fabric.isLikelyNode) {\n return;\n }\n var impl = fabric.jsdomImplForWrapper(element);\n if (impl) {\n impl._image = null;\n impl._canvas = null;\n // unsure if necessary\n impl._currentSrc = null;\n impl._attributes = null;\n impl._classList = null;\n }\n }\n\n function setImageSmoothing(ctx, value) {\n ctx.imageSmoothingEnabled = ctx.imageSmoothingEnabled || ctx.webkitImageSmoothingEnabled\n || ctx.mozImageSmoothingEnabled || ctx.msImageSmoothingEnabled || ctx.oImageSmoothingEnabled;\n ctx.imageSmoothingEnabled = value;\n }\n\n /**\n * setImageSmoothing sets the context imageSmoothingEnabled property.\n * Used by canvas and by ImageObject.\n * @memberOf fabric.util\n * @since 4.0.0\n * @param {HTMLRenderingContext2D} ctx to set on\n * @param {Boolean} value true or false\n */\n fabric.util.setImageSmoothing = setImageSmoothing;\n fabric.util.getById = getById;\n fabric.util.toArray = toArray;\n fabric.util.addClass = addClass;\n fabric.util.makeElement = makeElement;\n fabric.util.wrapElement = wrapElement;\n fabric.util.getScrollLeftTop = getScrollLeftTop;\n fabric.util.getElementOffset = getElementOffset;\n fabric.util.getNodeCanvas = getNodeCanvas;\n fabric.util.cleanUpJsdomNode = cleanUpJsdomNode;\n\n})();\n\n\n(function() {\n\n function addParamToUrl(url, param) {\n return url + (/\\?/.test(url) ? '&' : '?') + param;\n }\n\n function emptyFn() { }\n\n /**\n * Cross-browser abstraction for sending XMLHttpRequest\n * @memberOf fabric.util\n * @param {String} url URL to send XMLHttpRequest to\n * @param {Object} [options] Options object\n * @param {String} [options.method=\"GET\"]\n * @param {String} [options.parameters] parameters to append to url in GET or in body\n * @param {String} [options.body] body to send with POST or PUT request\n * @param {Function} options.onComplete Callback to invoke when request is completed\n * @return {XMLHttpRequest} request\n */\n function request(url, options) {\n options || (options = { });\n\n var method = options.method ? options.method.toUpperCase() : 'GET',\n onComplete = options.onComplete || function() { },\n xhr = new fabric.window.XMLHttpRequest(),\n body = options.body || options.parameters;\n\n /** @ignore */\n xhr.onreadystatechange = function() {\n if (xhr.readyState === 4) {\n onComplete(xhr);\n xhr.onreadystatechange = emptyFn;\n }\n };\n\n if (method === 'GET') {\n body = null;\n if (typeof options.parameters === 'string') {\n url = addParamToUrl(url, options.parameters);\n }\n }\n\n xhr.open(method, url, true);\n\n if (method === 'POST' || method === 'PUT') {\n xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');\n }\n\n xhr.send(body);\n return xhr;\n }\n\n fabric.util.request = request;\n})();\n\n\n/**\n * Wrapper around `console.log` (when available)\n * @param {*} [values] Values to log\n */\nfabric.log = console.log;\n\n/**\n * Wrapper around `console.warn` (when available)\n * @param {*} [values] Values to log as a warning\n */\nfabric.warn = console.warn;\n\n\n(function() {\n\n function noop() {\n return false;\n }\n\n function defaultEasing(t, b, c, d) {\n return -c * Math.cos(t / d * (Math.PI / 2)) + c + b;\n }\n\n /**\n * Changes value from one to another within certain period of time, invoking callbacks as value is being changed.\n * @memberOf fabric.util\n * @param {Object} [options] Animation options\n * @param {Function} [options.onChange] Callback; invoked on every value change\n * @param {Function} [options.onComplete] Callback; invoked when value change is completed\n * @param {Number} [options.startValue=0] Starting value\n * @param {Number} [options.endValue=100] Ending value\n * @param {Number} [options.byValue=100] Value to modify the property by\n * @param {Function} [options.easing] Easing function\n * @param {Number} [options.duration=500] Duration of change (in ms)\n * @param {Function} [options.abort] Additional function with logic. If returns true, onComplete is called.\n */\n function animate(options) {\n\n requestAnimFrame(function(timestamp) {\n options || (options = { });\n\n var start = timestamp || +new Date(),\n duration = options.duration || 500,\n finish = start + duration, time,\n onChange = options.onChange || noop,\n abort = options.abort || noop,\n onComplete = options.onComplete || noop,\n easing = options.easing || defaultEasing,\n startValue = 'startValue' in options ? options.startValue : 0,\n endValue = 'endValue' in options ? options.endValue : 100,\n byValue = options.byValue || endValue - startValue;\n\n options.onStart && options.onStart();\n\n (function tick(ticktime) {\n // TODO: move abort call after calculation\n // and pass (current,valuePerc, timePerc) as arguments\n time = ticktime || +new Date();\n var currentTime = time > finish ? duration : (time - start),\n timePerc = currentTime / duration,\n current = easing(currentTime, startValue, byValue, duration),\n valuePerc = Math.abs((current - startValue) / byValue);\n if (abort()) {\n onComplete(endValue, 1, 1);\n return;\n }\n if (time > finish) {\n onChange(endValue, 1, 1);\n onComplete(endValue, 1, 1);\n return;\n }\n else {\n onChange(current, valuePerc, timePerc);\n requestAnimFrame(tick);\n }\n })(start);\n });\n }\n\n var _requestAnimFrame = fabric.window.requestAnimationFrame ||\n fabric.window.webkitRequestAnimationFrame ||\n fabric.window.mozRequestAnimationFrame ||\n fabric.window.oRequestAnimationFrame ||\n fabric.window.msRequestAnimationFrame ||\n function(callback) {\n return fabric.window.setTimeout(callback, 1000 / 60);\n };\n\n var _cancelAnimFrame = fabric.window.cancelAnimationFrame || fabric.window.clearTimeout;\n\n /**\n * requestAnimationFrame polyfill based on http://paulirish.com/2011/requestanimationframe-for-smart-animating/\n * In order to get a precise start time, `requestAnimFrame` should be called as an entry into the method\n * @memberOf fabric.util\n * @param {Function} callback Callback to invoke\n * @param {DOMElement} element optional Element to associate with animation\n */\n function requestAnimFrame() {\n return _requestAnimFrame.apply(fabric.window, arguments);\n }\n\n function cancelAnimFrame() {\n return _cancelAnimFrame.apply(fabric.window, arguments);\n }\n\n fabric.util.animate = animate;\n fabric.util.requestAnimFrame = requestAnimFrame;\n fabric.util.cancelAnimFrame = cancelAnimFrame;\n})();\n\n\n(function() {\n // Calculate an in-between color. Returns a \"rgba()\" string.\n // Credit: Edwin Martin <edwin@bitstorm.org>\n // http://www.bitstorm.org/jquery/color-animation/jquery.animate-colors.js\n function calculateColor(begin, end, pos) {\n var color = 'rgba('\n + parseInt((begin[0] + pos * (end[0] - begin[0])), 10) + ','\n + parseInt((begin[1] + pos * (end[1] - begin[1])), 10) + ','\n + parseInt((begin[2] + pos * (end[2] - begin[2])), 10);\n\n color += ',' + (begin && end ? parseFloat(begin[3] + pos * (end[3] - begin[3])) : 1);\n color += ')';\n return color;\n }\n\n /**\n * Changes the color from one to another within certain period of time, invoking callbacks as value is being changed.\n * @memberOf fabric.util\n * @param {String} fromColor The starting color in hex or rgb(a) format.\n * @param {String} toColor The starting color in hex or rgb(a) format.\n * @param {Number} [duration] Duration of change (in ms).\n * @param {Object} [options] Animation options\n * @param {Function} [options.onChange] Callback; invoked on every value change\n * @param {Function} [options.onComplete] Callback; invoked when value change is completed\n * @param {Function} [options.colorEasing] Easing function. Note that this function only take two arguments (currentTime, duration). Thus the regular animation easing functions cannot be used.\n * @param {Function} [options.abort] Additional function with logic. If returns true, onComplete is called.\n */\n function animateColor(fromColor, toColor, duration, options) {\n var startColor = new fabric.Color(fromColor).getSource(),\n endColor = new fabric.Color(toColor).getSource(),\n originalOnComplete = options.onComplete,\n originalOnChange = options.onChange;\n options = options || {};\n\n fabric.util.animate(fabric.util.object.extend(options, {\n duration: duration || 500,\n startValue: startColor,\n endValue: endColor,\n byValue: endColor,\n easing: function (currentTime, startValue, byValue, duration) {\n var posValue = options.colorEasing\n ? options.colorEasing(currentTime, duration)\n : 1 - Math.cos(currentTime / duration * (Math.PI / 2));\n return calculateColor(startValue, byValue, posValue);\n },\n // has to take in account for color restoring;\n onComplete: function(current, valuePerc, timePerc) {\n if (originalOnComplete) {\n return originalOnComplete(\n calculateColor(endColor, endColor, 0),\n valuePerc,\n timePerc\n );\n }\n },\n onChange: function(current, valuePerc, timePerc) {\n if (originalOnChange) {\n if (Array.isArray(current)) {\n return originalOnChange(\n calculateColor(current, current, 0),\n valuePerc,\n timePerc\n );\n }\n originalOnChange(current, valuePerc, timePerc);\n }\n }\n }));\n }\n\n fabric.util.animateColor = animateColor;\n\n})();\n\n\n(function() {\n\n function normalize(a, c, p, s) {\n if (a < Math.abs(c)) {\n a = c;\n s = p / 4;\n }\n else {\n //handle the 0/0 case:\n if (c === 0 && a === 0) {\n s = p / (2 * Math.PI) * Math.asin(1);\n }\n else {\n s = p / (2 * Math.PI) * Math.asin(c / a);\n }\n }\n return { a: a, c: c, p: p, s: s };\n }\n\n function elastic(opts, t, d) {\n return opts.a *\n Math.pow(2, 10 * (t -= 1)) *\n Math.sin( (t * d - opts.s) * (2 * Math.PI) / opts.p );\n }\n\n /**\n * Cubic easing out\n * @memberOf fabric.util.ease\n */\n function easeOutCubic(t, b, c, d) {\n return c * ((t = t / d - 1) * t * t + 1) + b;\n }\n\n /**\n * Cubic easing in and out\n * @memberOf fabric.util.ease\n */\n function easeInOutCubic(t, b, c, d) {\n t /= d / 2;\n if (t < 1) {\n return c / 2 * t * t * t + b;\n }\n return c / 2 * ((t -= 2) * t * t + 2) + b;\n }\n\n /**\n * Quartic easing in\n * @memberOf fabric.util.ease\n */\n function easeInQuart(t, b, c, d) {\n return c * (t /= d) * t * t * t + b;\n }\n\n /**\n * Quartic easing out\n * @memberOf fabric.util.ease\n */\n function easeOutQuart(t, b, c, d) {\n return -c * ((t = t / d - 1) * t * t * t - 1) + b;\n }\n\n /**\n * Quartic easing in and out\n * @memberOf fabric.util.ease\n */\n function easeInOutQuart(t, b, c, d) {\n t /= d / 2;\n if (t < 1) {\n return c / 2 * t * t * t * t + b;\n }\n return -c / 2 * ((t -= 2) * t * t * t - 2) + b;\n }\n\n /**\n * Quintic easing in\n * @memberOf fabric.util.ease\n */\n function easeInQuint(t, b, c, d) {\n return c * (t /= d) * t * t * t * t + b;\n }\n\n /**\n * Quintic easing out\n * @memberOf fabric.util.ease\n */\n function easeOutQuint(t, b, c, d) {\n return c * ((t = t / d - 1) * t * t * t * t + 1) + b;\n }\n\n /**\n * Quintic easing in and out\n * @memberOf fabric.util.ease\n */\n function easeInOutQuint(t, b, c, d) {\n t /= d / 2;\n if (t < 1) {\n return c / 2 * t * t * t * t * t + b;\n }\n return c / 2 * ((t -= 2) * t * t * t * t + 2) + b;\n }\n\n /**\n * Sinusoidal easing in\n * @memberOf fabric.util.ease\n */\n function easeInSine(t, b, c, d) {\n return -c * Math.cos(t / d * (Math.PI / 2)) + c + b;\n }\n\n /**\n * Sinusoidal easing out\n * @memberOf fabric.util.ease\n */\n function easeOutSine(t, b, c, d) {\n return c * Math.sin(t / d * (Math.PI / 2)) + b;\n }\n\n /**\n * Sinusoidal easing in and out\n * @memberOf fabric.util.ease\n */\n function easeInOutSine(t, b, c, d) {\n return -c / 2 * (Math.cos(Math.PI * t / d) - 1) + b;\n }\n\n /**\n * Exponential easing in\n * @memberOf fabric.util.ease\n */\n function easeInExpo(t, b, c, d) {\n return (t === 0) ? b : c * Math.pow(2, 10 * (t / d - 1)) + b;\n }\n\n /**\n * Exponential easing out\n * @memberOf fabric.util.ease\n */\n function easeOutExpo(t, b, c, d) {\n return (t === d) ? b + c : c * (-Math.pow(2, -10 * t / d) + 1) + b;\n }\n\n /**\n * Exponential easing in and out\n * @memberOf fabric.util.ease\n */\n function easeInOutExpo(t, b, c, d) {\n if (t === 0) {\n return b;\n }\n if (t === d) {\n return b + c;\n }\n t /= d / 2;\n if (t < 1) {\n return c / 2 * Math.pow(2, 10 * (t - 1)) + b;\n }\n return c / 2 * (-Math.pow(2, -10 * --t) + 2) + b;\n }\n\n /**\n * Circular easing in\n * @memberOf fabric.util.ease\n */\n function easeInCirc(t, b, c, d) {\n return -c * (Math.sqrt(1 - (t /= d) * t) - 1) + b;\n }\n\n /**\n * Circular easing out\n * @memberOf fabric.util.ease\n */\n function easeOutCirc(t, b, c, d) {\n return c * Math.sqrt(1 - (t = t / d - 1) * t) + b;\n }\n\n /**\n * Circular easing in and out\n * @memberOf fabric.util.ease\n */\n function easeInOutCirc(t, b, c, d) {\n t /= d / 2;\n if (t < 1) {\n return -c / 2 * (Math.sqrt(1 - t * t) - 1) + b;\n }\n return c / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1) + b;\n }\n\n /**\n * Elastic easing in\n * @memberOf fabric.util.ease\n */\n function easeInElastic(t, b, c, d) {\n var s = 1.70158, p = 0, a = c;\n if (t === 0) {\n return b;\n }\n t /= d;\n if (t === 1) {\n return b + c;\n }\n if (!p) {\n p = d * 0.3;\n }\n var opts = normalize(a, c, p, s);\n return -elastic(opts, t, d) + b;\n }\n\n /**\n * Elastic easing out\n * @memberOf fabric.util.ease\n */\n function easeOutElastic(t, b, c, d) {\n var s = 1.70158, p = 0, a = c;\n if (t === 0) {\n return b;\n }\n t /= d;\n if (t === 1) {\n return b + c;\n }\n if (!p) {\n p = d * 0.3;\n }\n var opts = normalize(a, c, p, s);\n return opts.a * Math.pow(2, -10 * t) * Math.sin((t * d - opts.s) * (2 * Math.PI) / opts.p ) + opts.c + b;\n }\n\n /**\n * Elastic easing in and out\n * @memberOf fabric.util.ease\n */\n function easeInOutElastic(t, b, c, d) {\n var s = 1.70158, p = 0, a = c;\n if (t === 0) {\n return b;\n }\n t /= d / 2;\n if (t === 2) {\n return b + c;\n }\n if (!p) {\n p = d * (0.3 * 1.5);\n }\n var opts = normalize(a, c, p, s);\n if (t < 1) {\n return -0.5 * elastic(opts, t, d) + b;\n }\n return opts.a * Math.pow(2, -10 * (t -= 1)) *\n Math.sin((t * d - opts.s) * (2 * Math.PI) / opts.p ) * 0.5 + opts.c + b;\n }\n\n /**\n * Backwards easing in\n * @memberOf fabric.util.ease\n */\n function easeInBack(t, b, c, d, s) {\n if (s === undefined) {\n s = 1.70158;\n }\n return c * (t /= d) * t * ((s + 1) * t - s) + b;\n }\n\n /**\n * Backwards easing out\n * @memberOf fabric.util.ease\n */\n function easeOutBack(t, b, c, d, s) {\n if (s === undefined) {\n s = 1.70158;\n }\n return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b;\n }\n\n /**\n * Backwards easing in and out\n * @memberOf fabric.util.ease\n */\n function easeInOutBack(t, b, c, d, s) {\n if (s === undefined) {\n s = 1.70158;\n }\n t /= d / 2;\n if (t < 1) {\n return c / 2 * (t * t * (((s *= (1.525)) + 1) * t - s)) + b;\n }\n return c / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2) + b;\n }\n\n /**\n * Bouncing easing in\n * @memberOf fabric.util.ease\n */\n function easeInBounce(t, b, c, d) {\n return c - easeOutBounce (d - t, 0, c, d) + b;\n }\n\n /**\n * Bouncing easing out\n * @memberOf fabric.util.ease\n */\n function easeOutBounce(t, b, c, d) {\n if ((t /= d) < (1 / 2.75)) {\n return c * (7.5625 * t * t) + b;\n }\n else if (t < (2 / 2.75)) {\n return c * (7.5625 * (t -= (1.5 / 2.75)) * t + 0.75) + b;\n }\n else if (t < (2.5 / 2.75)) {\n return c * (7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375) + b;\n }\n else {\n return c * (7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375) + b;\n }\n }\n\n /**\n * Bouncing easing in and out\n * @memberOf fabric.util.ease\n */\n function easeInOutBounce(t, b, c, d) {\n if (t < d / 2) {\n return easeInBounce (t * 2, 0, c, d) * 0.5 + b;\n }\n return easeOutBounce(t * 2 - d, 0, c, d) * 0.5 + c * 0.5 + b;\n }\n\n /**\n * Easing functions\n * See <a href=\"http://gizma.com/easing/\">Easing Equations by Robert Penner</a>\n * @namespace fabric.util.ease\n */\n fabric.util.ease = {\n\n /**\n * Quadratic easing in\n * @memberOf fabric.util.ease\n */\n easeInQuad: function(t, b, c, d) {\n return c * (t /= d) * t + b;\n },\n\n /**\n * Quadratic easing out\n * @memberOf fabric.util.ease\n */\n easeOutQuad: function(t, b, c, d) {\n return -c * (t /= d) * (t - 2) + b;\n },\n\n /**\n * Quadratic easing in and out\n * @memberOf fabric.util.ease\n */\n easeInOutQuad: function(t, b, c, d) {\n t /= (d / 2);\n if (t < 1) {\n return c / 2 * t * t + b;\n }\n return -c / 2 * ((--t) * (t - 2) - 1) + b;\n },\n\n /**\n * Cubic easing in\n * @memberOf fabric.util.ease\n */\n easeInCubic: function(t, b, c, d) {\n return c * (t /= d) * t * t + b;\n },\n\n easeOutCubic: easeOutCubic,\n easeInOutCubic: easeInOutCubic,\n easeInQuart: easeInQuart,\n easeOutQuart: easeOutQuart,\n easeInOutQuart: easeInOutQuart,\n easeInQuint: easeInQuint,\n easeOutQuint: easeOutQuint,\n easeInOutQuint: easeInOutQuint,\n easeInSine: easeInSine,\n easeOutSine: easeOutSine,\n easeInOutSine: easeInOutSine,\n easeInExpo: easeInExpo,\n easeOutExpo: easeOutExpo,\n easeInOutExpo: easeInOutExpo,\n easeInCirc: easeInCirc,\n easeOutCirc: easeOutCirc,\n easeInOutCirc: easeInOutCirc,\n easeInElastic: easeInElastic,\n easeOutElastic: easeOutElastic,\n easeInOutElastic: easeInOutElastic,\n easeInBack: easeInBack,\n easeOutBack: easeOutBack,\n easeInOutBack: easeInOutBack,\n easeInBounce: easeInBounce,\n easeOutBounce: easeOutBounce,\n easeInOutBounce: easeInOutBounce\n };\n\n})();\n\n\n(function(global) {\n\n 'use strict';\n\n /**\n * @name fabric\n * @namespace\n */\n\n var fabric = global.fabric || (global.fabric = { }),\n extend = fabric.util.object.extend,\n clone = fabric.util.object.clone,\n toFixed = fabric.util.toFixed,\n parseUnit = fabric.util.parseUnit,\n multiplyTransformMatrices = fabric.util.multiplyTransformMatrices,\n\n svgValidTagNames = ['path', 'circle', 'polygon', 'polyline', 'ellipse', 'rect', 'line',\n 'image', 'text'],\n svgViewBoxElements = ['symbol', 'image', 'marker', 'pattern', 'view', 'svg'],\n svgInvalidAncestors = ['pattern', 'defs', 'symbol', 'metadata', 'clipPath', 'mask', 'desc'],\n svgValidParents = ['symbol', 'g', 'a', 'svg', 'clipPath', 'defs'],\n\n attributesMap = {\n cx: 'left',\n x: 'left',\n r: 'radius',\n cy: 'top',\n y: 'top',\n display: 'visible',\n visibility: 'visible',\n transform: 'transformMatrix',\n 'fill-opacity': 'fillOpacity',\n 'fill-rule': 'fillRule',\n 'font-family': 'fontFamily',\n 'font-size': 'fontSize',\n 'font-style': 'fontStyle',\n 'font-weight': 'fontWeight',\n 'letter-spacing': 'charSpacing',\n 'paint-order': 'paintFirst',\n 'stroke-dasharray': 'strokeDashArray',\n 'stroke-dashoffset': 'strokeDashOffset',\n 'stroke-linecap': 'strokeLineCap',\n 'stroke-linejoin': 'strokeLineJoin',\n 'stroke-miterlimit': 'strokeMiterLimit',\n 'stroke-opacity': 'strokeOpacity',\n 'stroke-width': 'strokeWidth',\n 'text-decoration': 'textDecoration',\n 'text-anchor': 'textAnchor',\n opacity: 'opacity',\n 'clip-path': 'clipPath',\n 'clip-rule': 'clipRule',\n 'vector-effect': 'strokeUniform',\n 'image-rendering': 'imageSmoothing',\n },\n\n colorAttributes = {\n stroke: 'strokeOpacity',\n fill: 'fillOpacity'\n },\n\n fSize = 'font-size', cPath = 'clip-path';\n\n fabric.svgValidTagNamesRegEx = getSvgRegex(svgValidTagNames);\n fabric.svgViewBoxElementsRegEx = getSvgRegex(svgViewBoxElements);\n fabric.svgInvalidAncestorsRegEx = getSvgRegex(svgInvalidAncestors);\n fabric.svgValidParentsRegEx = getSvgRegex(svgValidParents);\n\n fabric.cssRules = { };\n fabric.gradientDefs = { };\n fabric.clipPaths = { };\n\n function normalizeAttr(attr) {\n // transform attribute names\n if (attr in attributesMap) {\n return attributesMap[attr];\n }\n return attr;\n }\n\n function normalizeValue(attr, value, parentAttributes, fontSize) {\n var isArray = Object.prototype.toString.call(value) === '[object Array]',\n parsed;\n\n if ((attr === 'fill' || attr === 'stroke') && value === 'none') {\n value = '';\n }\n else if (attr === 'strokeUniform') {\n return (value === 'non-scaling-stroke');\n }\n else if (attr === 'strokeDashArray') {\n if (value === 'none') {\n value = null;\n }\n else {\n value = value.replace(/,/g, ' ').split(/\\s+/).map(parseFloat);\n }\n }\n else if (attr === 'transformMatrix') {\n if (parentAttributes && parentAttributes.transformMatrix) {\n value = multiplyTransformMatrices(\n parentAttributes.transformMatrix, fabric.parseTransformAttribute(value));\n }\n else {\n value = fabric.parseTransformAttribute(value);\n }\n }\n else if (attr === 'visible') {\n value = value !== 'none' && value !== 'hidden';\n // display=none on parent element always takes precedence over child element\n if (parentAttributes && parentAttributes.visible === false) {\n value = false;\n }\n }\n else if (attr === 'opacity') {\n value = parseFloat(value);\n if (parentAttributes && typeof parentAttributes.opacity !== 'undefined') {\n value *= parentAttributes.opacity;\n }\n }\n else if (attr === 'textAnchor' /* text-anchor */) {\n value = value === 'start' ? 'left' : value === 'end' ? 'right' : 'center';\n }\n else if (attr === 'charSpacing') {\n // parseUnit returns px and we convert it to em\n parsed = parseUnit(value, fontSize) / fontSize * 1000;\n }\n else if (attr === 'paintFirst') {\n var fillIndex = value.indexOf('fill');\n var strokeIndex = value.indexOf('stroke');\n var value = 'fill';\n if (fillIndex > -1 && strokeIndex > -1 && strokeIndex < fillIndex) {\n value = 'stroke';\n }\n else if (fillIndex === -1 && strokeIndex > -1) {\n value = 'stroke';\n }\n }\n else if (attr === 'href' || attr === 'xlink:href' || attr === 'font') {\n return value;\n }\n else if (attr === 'imageSmoothing') {\n return (value === 'optimizeQuality' ? true : false);\n }\n else {\n parsed = isArray ? value.map(parseUnit) : parseUnit(value, fontSize);\n }\n\n return (!isArray && isNaN(parsed) ? value : parsed);\n }\n\n /**\n * @private\n */\n function getSvgRegex(arr) {\n return new RegExp('^(' + arr.join('|') + ')\\\\b', 'i');\n }\n\n /**\n * @private\n * @param {Object} attributes Array of attributes to parse\n */\n function _setStrokeFillOpacity(attributes) {\n for (var attr in colorAttributes) {\n\n if (typeof attributes[colorAttributes[attr]] === 'undefined' || attributes[attr] === '') {\n continue;\n }\n\n if (typeof attributes[attr] === 'undefined') {\n if (!fabric.Object.prototype[attr]) {\n continue;\n }\n attributes[attr] = fabric.Object.prototype[attr];\n }\n\n if (attributes[attr].indexOf('url(') === 0) {\n continue;\n }\n\n var color = new fabric.Color(attributes[attr]);\n attributes[attr] = color.setAlpha(toFixed(color.getAlpha() * attributes[colorAttributes[attr]], 2)).toRgba();\n }\n return attributes;\n }\n\n /**\n * @private\n */\n function _getMultipleNodes(doc, nodeNames) {\n var nodeName, nodeArray = [], nodeList, i, len;\n for (i = 0, len = nodeNames.length; i < len; i++) {\n nodeName = nodeNames[i];\n nodeList = doc.getElementsByTagName(nodeName);\n nodeArray = nodeArray.concat(Array.prototype.slice.call(nodeList));\n }\n return nodeArray;\n }\n\n /**\n * Parses \"transform\" attribute, returning an array of values\n * @static\n * @function\n * @memberOf fabric\n * @param {String} attributeValue String containing attribute value\n * @return {Array} Array of 6 elements representing transformation matrix\n */\n fabric.parseTransformAttribute = (function() {\n function rotateMatrix(matrix, args) {\n var cos = fabric.util.cos(args[0]), sin = fabric.util.sin(args[0]),\n x = 0, y = 0;\n if (args.length === 3) {\n x = args[1];\n y = args[2];\n }\n\n matrix[0] = cos;\n matrix[1] = sin;\n matrix[2] = -sin;\n matrix[3] = cos;\n matrix[4] = x - (cos * x - sin * y);\n matrix[5] = y - (sin * x + cos * y);\n }\n\n function scaleMatrix(matrix, args) {\n var multiplierX = args[0],\n multiplierY = (args.length === 2) ? args[1] : args[0];\n\n matrix[0] = multiplierX;\n matrix[3] = multiplierY;\n }\n\n function skewMatrix(matrix, args, pos) {\n matrix[pos] = Math.tan(fabric.util.degreesToRadians(args[0]));\n }\n\n function translateMatrix(matrix, args) {\n matrix[4] = args[0];\n if (args.length === 2) {\n matrix[5] = args[1];\n }\n }\n\n // identity matrix\n var iMatrix = fabric.iMatrix,\n\n // == begin transform regexp\n number = fabric.reNum,\n\n commaWsp = fabric.commaWsp,\n\n skewX = '(?:(skewX)\\\\s*\\\\(\\\\s*(' + number + ')\\\\s*\\\\))',\n\n skewY = '(?:(skewY)\\\\s*\\\\(\\\\s*(' + number + ')\\\\s*\\\\))',\n\n rotate = '(?:(rotate)\\\\s*\\\\(\\\\s*(' + number + ')(?:' +\n commaWsp + '(' + number + ')' +\n commaWsp + '(' + number + '))?\\\\s*\\\\))',\n\n scale = '(?:(scale)\\\\s*\\\\(\\\\s*(' + number + ')(?:' +\n commaWsp + '(' + number + '))?\\\\s*\\\\))',\n\n translate = '(?:(translate)\\\\s*\\\\(\\\\s*(' + number + ')(?:' +\n commaWsp + '(' + number + '))?\\\\s*\\\\))',\n\n matrix = '(?:(matrix)\\\\s*\\\\(\\\\s*' +\n '(' + number + ')' + commaWsp +\n '(' + number + ')' + commaWsp +\n '(' + number + ')' + commaWsp +\n '(' + number + ')' + commaWsp +\n '(' + number + ')' + commaWsp +\n '(' + number + ')' +\n '\\\\s*\\\\))',\n\n transform = '(?:' +\n matrix + '|' +\n translate + '|' +\n scale + '|' +\n rotate + '|' +\n skewX + '|' +\n skewY +\n ')',\n\n transforms = '(?:' + transform + '(?:' + commaWsp + '*' + transform + ')*' + ')',\n\n transformList = '^\\\\s*(?:' + transforms + '?)\\\\s*$',\n\n // http://www.w3.org/TR/SVG/coords.html#TransformAttribute\n reTransformList = new RegExp(transformList),\n // == end transform regexp\n\n reTransform = new RegExp(transform, 'g');\n\n return function(attributeValue) {\n\n // start with identity matrix\n var matrix = iMatrix.concat(),\n matrices = [];\n\n // return if no argument was given or\n // an argument does not match transform attribute regexp\n if (!attributeValue || (attributeValue && !reTransformList.test(attributeValue))) {\n return matrix;\n }\n\n attributeValue.replace(reTransform, function(match) {\n\n var m = new RegExp(transform).exec(match).filter(function (match) {\n // match !== '' && match != null\n return (!!match);\n }),\n operation = m[1],\n args = m.slice(2).map(parseFloat);\n\n switch (operation) {\n case 'translate':\n translateMatrix(matrix, args);\n break;\n case 'rotate':\n args[0] = fabric.util.degreesToRadians(args[0]);\n rotateMatrix(matrix, args);\n break;\n case 'scale':\n scaleMatrix(matrix, args);\n break;\n case 'skewX':\n skewMatrix(matrix, args, 2);\n break;\n case 'skewY':\n skewMatrix(matrix, args, 1);\n break;\n case 'matrix':\n matrix = args;\n break;\n }\n\n // snapshot current matrix into matrices array\n matrices.push(matrix.concat());\n // reset\n matrix = iMatrix.concat();\n });\n\n var combinedMatrix = matrices[0];\n while (matrices.length > 1) {\n matrices.shift();\n combinedMatrix = fabric.util.multiplyTransformMatrices(combinedMatrix, matrices[0]);\n }\n return combinedMatrix;\n };\n })();\n\n /**\n * @private\n */\n function parseStyleString(style, oStyle) {\n var attr, value;\n style.replace(/;\\s*$/, '').split(';').forEach(function (chunk) {\n var pair = chunk.split(':');\n\n attr = pair[0].trim().toLowerCase();\n value = pair[1].trim();\n\n oStyle[attr] = value;\n });\n }\n\n /**\n * @private\n */\n function parseStyleObject(style, oStyle) {\n var attr, value;\n for (var prop in style) {\n if (typeof style[prop] === 'undefined') {\n continue;\n }\n\n attr = prop.toLowerCase();\n value = style[prop];\n\n oStyle[attr] = value;\n }\n }\n\n /**\n * @private\n */\n function getGlobalStylesForElement(element, svgUid) {\n var styles = { };\n for (var rule in fabric.cssRules[svgUid]) {\n if (elementMatchesRule(element, rule.split(' '))) {\n for (var property in fabric.cssRules[svgUid][rule]) {\n styles[property] = fabric.cssRules[svgUid][rule][property];\n }\n }\n }\n return styles;\n }\n\n /**\n * @private\n */\n function elementMatchesRule(element, selectors) {\n var firstMatching, parentMatching = true;\n //start from rightmost selector.\n firstMatching = selectorMatches(element, selectors.pop());\n if (firstMatching && selectors.length) {\n parentMatching = doesSomeParentMatch(element, selectors);\n }\n return firstMatching && parentMatching && (selectors.length === 0);\n }\n\n function doesSomeParentMatch(element, selectors) {\n var selector, parentMatching = true;\n while (element.parentNode && element.parentNode.nodeType === 1 && selectors.length) {\n if (parentMatching) {\n selector = selectors.pop();\n }\n element = element.parentNode;\n parentMatching = selectorMatches(element, selector);\n }\n return selectors.length === 0;\n }\n\n /**\n * @private\n */\n function selectorMatches(element, selector) {\n var nodeName = element.nodeName,\n classNames = element.getAttribute('class'),\n id = element.getAttribute('id'), matcher, i;\n // i check if a selector matches slicing away part from it.\n // if i get empty string i should match\n matcher = new RegExp('^' + nodeName, 'i');\n selector = selector.replace(matcher, '');\n if (id && selector.length) {\n matcher = new RegExp('#' + id + '(?![a-zA-Z\\\\-]+)', 'i');\n selector = selector.replace(matcher, '');\n }\n if (classNames && selector.length) {\n classNames = classNames.split(' ');\n for (i = classNames.length; i--;) {\n matcher = new RegExp('\\\\.' + classNames[i] + '(?![a-zA-Z\\\\-]+)', 'i');\n selector = selector.replace(matcher, '');\n }\n }\n return selector.length === 0;\n }\n\n /**\n * @private\n * to support IE8 missing getElementById on SVGdocument and on node xmlDOM\n */\n function elementById(doc, id) {\n var el;\n doc.getElementById && (el = doc.getElementById(id));\n if (el) {\n return el;\n }\n var node, i, len, nodelist = doc.getElementsByTagName('*');\n for (i = 0, len = nodelist.length; i < len; i++) {\n node = nodelist[i];\n if (id === node.getAttribute('id')) {\n return node;\n }\n }\n }\n\n /**\n * @private\n */\n function parseUseDirectives(doc) {\n var nodelist = _getMultipleNodes(doc, ['use', 'svg:use']), i = 0;\n while (nodelist.length && i < nodelist.length) {\n var el = nodelist[i],\n xlink = (el.getAttribute('xlink:href') || el.getAttribute('href')).substr(1),\n x = el.getAttribute('x') || 0,\n y = el.getAttribute('y') || 0,\n el2 = elementById(doc, xlink).cloneNode(true),\n currentTrans = (el2.getAttribute('transform') || '') + ' translate(' + x + ', ' + y + ')',\n parentNode, oldLength = nodelist.length, attr, j, attrs, len, namespace = fabric.svgNS;\n\n applyViewboxTransform(el2);\n if (/^svg$/i.test(el2.nodeName)) {\n var el3 = el2.ownerDocument.createElementNS(namespace, 'g');\n for (j = 0, attrs = el2.attributes, len = attrs.length; j < len; j++) {\n attr = attrs.item(j);\n el3.setAttributeNS(namespace, attr.nodeName, attr.nodeValue);\n }\n // el2.firstChild != null\n while (el2.firstChild) {\n el3.appendChild(el2.firstChild);\n }\n el2 = el3;\n }\n\n for (j = 0, attrs = el.attributes, len = attrs.length; j < len; j++) {\n attr = attrs.item(j);\n if (attr.nodeName === 'x' || attr.nodeName === 'y' ||\n attr.nodeName === 'xlink:href' || attr.nodeName === 'href') {\n continue;\n }\n\n if (attr.nodeName === 'transform') {\n currentTrans = attr.nodeValue + ' ' + currentTrans;\n }\n else {\n el2.setAttribute(attr.nodeName, attr.nodeValue);\n }\n }\n\n el2.setAttribute('transform', currentTrans);\n el2.setAttribute('instantiated_by_use', '1');\n el2.removeAttribute('id');\n parentNode = el.parentNode;\n parentNode.replaceChild(el2, el);\n // some browsers do not shorten nodelist after replaceChild (IE8)\n if (nodelist.length === oldLength) {\n i++;\n }\n }\n }\n\n // http://www.w3.org/TR/SVG/coords.html#ViewBoxAttribute\n // matches, e.g.: +14.56e-12, etc.\n var reViewBoxAttrValue = new RegExp(\n '^' +\n '\\\\s*(' + fabric.reNum + '+)\\\\s*,?' +\n '\\\\s*(' + fabric.reNum + '+)\\\\s*,?' +\n '\\\\s*(' + fabric.reNum + '+)\\\\s*,?' +\n '\\\\s*(' + fabric.reNum + '+)\\\\s*' +\n '$'\n );\n\n /**\n * Add a <g> element that envelop all child elements and makes the viewbox transformMatrix descend on all elements\n */\n function applyViewboxTransform(element) {\n if (!fabric.svgViewBoxElementsRegEx.test(element.nodeName)) {\n return;\n }\n var viewBoxAttr = element.getAttribute('viewBox'),\n scaleX = 1,\n scaleY = 1,\n minX = 0,\n minY = 0,\n viewBoxWidth, viewBoxHeight, matrix, el,\n widthAttr = element.getAttribute('width'),\n heightAttr = element.getAttribute('height'),\n x = element.getAttribute('x') || 0,\n y = element.getAttribute('y') || 0,\n preserveAspectRatio = element.getAttribute('preserveAspectRatio') || '',\n missingViewBox = (!viewBoxAttr || !(viewBoxAttr = viewBoxAttr.match(reViewBoxAttrValue))),\n missingDimAttr = (!widthAttr || !heightAttr || widthAttr === '100%' || heightAttr === '100%'),\n toBeParsed = missingViewBox && missingDimAttr,\n parsedDim = { }, translateMatrix = '', widthDiff = 0, heightDiff = 0;\n\n parsedDim.width = 0;\n parsedDim.height = 0;\n parsedDim.toBeParsed = toBeParsed;\n\n if (missingViewBox) {\n if (((x || y) && element.parentNode.nodeName !== '#document')) {\n translateMatrix = ' translate(' + parseUnit(x) + ' ' + parseUnit(y) + ') ';\n matrix = (element.getAttribute('transform') || '') + translateMatrix;\n element.setAttribute('transform', matrix);\n element.removeAttribute('x');\n element.removeAttribute('y');\n }\n }\n\n if (toBeParsed) {\n return parsedDim;\n }\n\n if (missingViewBox) {\n parsedDim.width = parseUnit(widthAttr);\n parsedDim.height = parseUnit(heightAttr);\n // set a transform for elements that have x y and are inner(only) SVGs\n return parsedDim;\n }\n minX = -parseFloat(viewBoxAttr[1]);\n minY = -parseFloat(viewBoxAttr[2]);\n viewBoxWidth = parseFloat(viewBoxAttr[3]);\n viewBoxHeight = parseFloat(viewBoxAttr[4]);\n parsedDim.minX = minX;\n parsedDim.minY = minY;\n parsedDim.viewBoxWidth = viewBoxWidth;\n parsedDim.viewBoxHeight = viewBoxHeight;\n if (!missingDimAttr) {\n parsedDim.width = parseUnit(widthAttr);\n parsedDim.height = parseUnit(heightAttr);\n scaleX = parsedDim.width / viewBoxWidth;\n scaleY = parsedDim.height / viewBoxHeight;\n }\n else {\n parsedDim.width = viewBoxWidth;\n parsedDim.height = viewBoxHeight;\n }\n\n // default is to preserve aspect ratio\n preserveAspectRatio = fabric.util.parsePreserveAspectRatioAttribute(preserveAspectRatio);\n if (preserveAspectRatio.alignX !== 'none') {\n //translate all container for the effect of Mid, Min, Max\n if (preserveAspectRatio.meetOrSlice === 'meet') {\n scaleY = scaleX = (scaleX > scaleY ? scaleY : scaleX);\n // calculate additional translation to move the viewbox\n }\n if (preserveAspectRatio.meetOrSlice === 'slice') {\n scaleY = scaleX = (scaleX > scaleY ? scaleX : scaleY);\n // calculate additional translation to move the viewbox\n }\n widthDiff = parsedDim.width - viewBoxWidth * scaleX;\n heightDiff = parsedDim.height - viewBoxHeight * scaleX;\n if (preserveAspectRatio.alignX === 'Mid') {\n widthDiff /= 2;\n }\n if (preserveAspectRatio.alignY === 'Mid') {\n heightDiff /= 2;\n }\n if (preserveAspectRatio.alignX === 'Min') {\n widthDiff = 0;\n }\n if (preserveAspectRatio.alignY === 'Min') {\n heightDiff = 0;\n }\n }\n\n if (scaleX === 1 && scaleY === 1 && minX === 0 && minY === 0 && x === 0 && y === 0) {\n return parsedDim;\n }\n if ((x || y) && element.parentNode.nodeName !== '#document') {\n translateMatrix = ' translate(' + parseUnit(x) + ' ' + parseUnit(y) + ') ';\n }\n\n matrix = translateMatrix + ' matrix(' + scaleX +\n ' 0' +\n ' 0 ' +\n scaleY + ' ' +\n (minX * scaleX + widthDiff) + ' ' +\n (minY * scaleY + heightDiff) + ') ';\n // seems unused.\n // parsedDim.viewboxTransform = fabric.parseTransformAttribute(matrix);\n if (element.nodeName === 'svg') {\n el = element.ownerDocument.createElementNS(fabric.svgNS, 'g');\n // element.firstChild != null\n while (element.firstChild) {\n el.appendChild(element.firstChild);\n }\n element.appendChild(el);\n }\n else {\n el = element;\n el.removeAttribute('x');\n el.removeAttribute('y');\n matrix = el.getAttribute('transform') + matrix;\n }\n el.setAttribute('transform', matrix);\n return parsedDim;\n }\n\n function hasAncestorWithNodeName(element, nodeName) {\n while (element && (element = element.parentNode)) {\n if (element.nodeName && nodeName.test(element.nodeName.replace('svg:', ''))\n && !element.getAttribute('instantiated_by_use')) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Parses an SVG document, converts it to an array of corresponding fabric.* instances and passes them to a callback\n * @static\n * @function\n * @memberOf fabric\n * @param {SVGDocument} doc SVG document to parse\n * @param {Function} callback Callback to call when parsing is finished;\n * It's being passed an array of elements (parsed from a document).\n * @param {Function} [reviver] Method for further parsing of SVG elements, called after each fabric object created.\n * @param {Object} [parsingOptions] options for parsing document\n * @param {String} [parsingOptions.crossOrigin] crossOrigin settings\n */\n fabric.parseSVGDocument = function(doc, callback, reviver, parsingOptions) {\n if (!doc) {\n return;\n }\n\n parseUseDirectives(doc);\n\n var svgUid = fabric.Object.__uid++, i, len,\n options = applyViewboxTransform(doc),\n descendants = fabric.util.toArray(doc.getElementsByTagName('*'));\n options.crossOrigin = parsingOptions && parsingOptions.crossOrigin;\n options.svgUid = svgUid;\n\n if (descendants.length === 0 && fabric.isLikelyNode) {\n // we're likely in node, where \"o3-xml\" library fails to gEBTN(\"*\")\n // https://github.com/ajaxorg/node-o3-xml/issues/21\n descendants = doc.selectNodes('//*[name(.)!=\"svg\"]');\n var arr = [];\n for (i = 0, len = descendants.length; i < len; i++) {\n arr[i] = descendants[i];\n }\n descendants = arr;\n }\n\n var elements = descendants.filter(function(el) {\n applyViewboxTransform(el);\n return fabric.svgValidTagNamesRegEx.test(el.nodeName.replace('svg:', '')) &&\n !hasAncestorWithNodeName(el, fabric.svgInvalidAncestorsRegEx); // http://www.w3.org/TR/SVG/struct.html#DefsElement\n });\n if (!elements || (elements && !elements.length)) {\n callback && callback([], {});\n return;\n }\n var clipPaths = { };\n descendants.filter(function(el) {\n return el.nodeName.replace('svg:', '') === 'clipPath';\n }).forEach(function(el) {\n var id = el.getAttribute('id');\n clipPaths[id] = fabric.util.toArray(el.getElementsByTagName('*')).filter(function(el) {\n return fabric.svgValidTagNamesRegEx.test(el.nodeName.replace('svg:', ''));\n });\n });\n fabric.gradientDefs[svgUid] = fabric.getGradientDefs(doc);\n fabric.cssRules[svgUid] = fabric.getCSSRules(doc);\n fabric.clipPaths[svgUid] = clipPaths;\n // Precedence of rules: style > class > attribute\n fabric.parseElements(elements, function(instances, elements) {\n if (callback) {\n callback(instances, options, elements, descendants);\n delete fabric.gradientDefs[svgUid];\n delete fabric.cssRules[svgUid];\n delete fabric.clipPaths[svgUid];\n }\n }, clone(options), reviver, parsingOptions);\n };\n\n function recursivelyParseGradientsXlink(doc, gradient) {\n var gradientsAttrs = ['gradientTransform', 'x1', 'x2', 'y1', 'y2', 'gradientUnits', 'cx', 'cy', 'r', 'fx', 'fy'],\n xlinkAttr = 'xlink:href',\n xLink = gradient.getAttribute(xlinkAttr).substr(1),\n referencedGradient = elementById(doc, xLink);\n if (referencedGradient && referencedGradient.getAttribute(xlinkAttr)) {\n recursivelyParseGradientsXlink(doc, referencedGradient);\n }\n gradientsAttrs.forEach(function(attr) {\n if (referencedGradient && !gradient.hasAttribute(attr) && referencedGradient.hasAttribute(attr)) {\n gradient.setAttribute(attr, referencedGradient.getAttribute(attr));\n }\n });\n if (!gradient.children.length) {\n var referenceClone = referencedGradient.cloneNode(true);\n while (referenceClone.firstChild) {\n gradient.appendChild(referenceClone.firstChild);\n }\n }\n gradient.removeAttribute(xlinkAttr);\n }\n\n var reFontDeclaration = new RegExp(\n '(normal|italic)?\\\\s*(normal|small-caps)?\\\\s*' +\n '(normal|bold|bolder|lighter|100|200|300|400|500|600|700|800|900)?\\\\s*(' +\n fabric.reNum +\n '(?:px|cm|mm|em|pt|pc|in)*)(?:\\\\/(normal|' + fabric.reNum + '))?\\\\s+(.*)');\n\n extend(fabric, {\n /**\n * Parses a short font declaration, building adding its properties to a style object\n * @static\n * @function\n * @memberOf fabric\n * @param {String} value font declaration\n * @param {Object} oStyle definition\n */\n parseFontDeclaration: function(value, oStyle) {\n var match = value.match(reFontDeclaration);\n\n if (!match) {\n return;\n }\n var fontStyle = match[1],\n // font variant is not used\n // fontVariant = match[2],\n fontWeight = match[3],\n fontSize = match[4],\n lineHeight = match[5],\n fontFamily = match[6];\n\n if (fontStyle) {\n oStyle.fontStyle = fontStyle;\n }\n if (fontWeight) {\n oStyle.fontWeight = isNaN(parseFloat(fontWeight)) ? fontWeight : parseFloat(fontWeight);\n }\n if (fontSize) {\n oStyle.fontSize = parseUnit(fontSize);\n }\n if (fontFamily) {\n oStyle.fontFamily = fontFamily;\n }\n if (lineHeight) {\n oStyle.lineHeight = lineHeight === 'normal' ? 1 : lineHeight;\n }\n },\n\n /**\n * Parses an SVG document, returning all of the gradient declarations found in it\n * @static\n * @function\n * @memberOf fabric\n * @param {SVGDocument} doc SVG document to parse\n * @return {Object} Gradient definitions; key corresponds to element id, value -- to gradient definition element\n */\n getGradientDefs: function(doc) {\n var tagArray = [\n 'linearGradient',\n 'radialGradient',\n 'svg:linearGradient',\n 'svg:radialGradient'],\n elList = _getMultipleNodes(doc, tagArray),\n el, j = 0, gradientDefs = { };\n j = elList.length;\n while (j--) {\n el = elList[j];\n if (el.getAttribute('xlink:href')) {\n recursivelyParseGradientsXlink(doc, el);\n }\n gradientDefs[el.getAttribute('id')] = el;\n }\n return gradientDefs;\n },\n\n /**\n * Returns an object of attributes' name/value, given element and an array of attribute names;\n * Parses parent \"g\" nodes recursively upwards.\n * @static\n * @memberOf fabric\n * @param {DOMElement} element Element to parse\n * @param {Array} attributes Array of attributes to parse\n * @return {Object} object containing parsed attributes' names/values\n */\n parseAttributes: function(element, attributes, svgUid) {\n\n if (!element) {\n return;\n }\n\n var value,\n parentAttributes = { },\n fontSize, parentFontSize;\n\n if (typeof svgUid === 'undefined') {\n svgUid = element.getAttribute('svgUid');\n }\n // if there's a parent container (`g` or `a` or `symbol` node), parse its attributes recursively upwards\n if (element.parentNode && fabric.svgValidParentsRegEx.test(element.parentNode.nodeName)) {\n parentAttributes = fabric.parseAttributes(element.parentNode, attributes, svgUid);\n }\n\n var ownAttributes = attributes.reduce(function(memo, attr) {\n value = element.getAttribute(attr);\n if (value) { // eslint-disable-line\n memo[attr] = value;\n }\n return memo;\n }, { });\n // add values parsed from style, which take precedence over attributes\n // (see: http://www.w3.org/TR/SVG/styling.html#UsingPresentationAttributes)\n var cssAttrs = extend(\n getGlobalStylesForElement(element, svgUid),\n fabric.parseStyleAttribute(element)\n );\n ownAttributes = extend(\n ownAttributes,\n cssAttrs\n );\n if (cssAttrs[cPath]) {\n element.setAttribute(cPath, cssAttrs[cPath]);\n }\n fontSize = parentFontSize = parentAttributes.fontSize || fabric.Text.DEFAULT_SVG_FONT_SIZE;\n if (ownAttributes[fSize]) {\n // looks like the minimum should be 9px when dealing with ems. this is what looks like in browsers.\n ownAttributes[fSize] = fontSize = parseUnit(ownAttributes[fSize], parentFontSize);\n }\n\n var normalizedAttr, normalizedValue, normalizedStyle = {};\n for (var attr in ownAttributes) {\n normalizedAttr = normalizeAttr(attr);\n normalizedValue = normalizeValue(normalizedAttr, ownAttributes[attr], parentAttributes, fontSize);\n normalizedStyle[normalizedAttr] = normalizedValue;\n }\n if (normalizedStyle && normalizedStyle.font) {\n fabric.parseFontDeclaration(normalizedStyle.font, normalizedStyle);\n }\n var mergedAttrs = extend(parentAttributes, normalizedStyle);\n return fabric.svgValidParentsRegEx.test(element.nodeName) ? mergedAttrs : _setStrokeFillOpacity(mergedAttrs);\n },\n\n /**\n * Transforms an array of svg elements to corresponding fabric.* instances\n * @static\n * @memberOf fabric\n * @param {Array} elements Array of elements to parse\n * @param {Function} callback Being passed an array of fabric instances (transformed from SVG elements)\n * @param {Object} [options] Options object\n * @param {Function} [reviver] Method for further parsing of SVG elements, called after each fabric object created.\n */\n parseElements: function(elements, callback, options, reviver, parsingOptions) {\n new fabric.ElementsParser(elements, callback, options, reviver, parsingOptions).parse();\n },\n\n /**\n * Parses \"style\" attribute, retuning an object with values\n * @static\n * @memberOf fabric\n * @param {SVGElement} element Element to parse\n * @return {Object} Objects with values parsed from style attribute of an element\n */\n parseStyleAttribute: function(element) {\n var oStyle = { },\n style = element.getAttribute('style');\n\n if (!style) {\n return oStyle;\n }\n\n if (typeof style === 'string') {\n parseStyleString(style, oStyle);\n }\n else {\n parseStyleObject(style, oStyle);\n }\n\n return oStyle;\n },\n\n /**\n * Parses \"points\" attribute, returning an array of values\n * @static\n * @memberOf fabric\n * @param {String} points points attribute string\n * @return {Array} array of points\n */\n parsePointsAttribute: function(points) {\n\n // points attribute is required and must not be empty\n if (!points) {\n return null;\n }\n\n // replace commas with whitespace and remove bookending whitespace\n points = points.replace(/,/g, ' ').trim();\n\n points = points.split(/\\s+/);\n var parsedPoints = [], i, len;\n\n for (i = 0, len = points.length; i < len; i += 2) {\n parsedPoints.push({\n x: parseFloat(points[i]),\n y: parseFloat(points[i + 1])\n });\n }\n\n // odd number of points is an error\n // if (parsedPoints.length % 2 !== 0) {\n // return null;\n // }\n\n return parsedPoints;\n },\n\n /**\n * Returns CSS rules for a given SVG document\n * @static\n * @function\n * @memberOf fabric\n * @param {SVGDocument} doc SVG document to parse\n * @return {Object} CSS rules of this document\n */\n getCSSRules: function(doc) {\n var styles = doc.getElementsByTagName('style'), i, len,\n allRules = { }, rules;\n\n // very crude parsing of style contents\n for (i = 0, len = styles.length; i < len; i++) {\n // <style/> could produce `undefined`, covering this case with ''\n var styleContents = styles[i].textContent || '';\n\n // remove comments\n styleContents = styleContents.replace(/\\/\\*[\\s\\S]*?\\*\\//g, '');\n if (styleContents.trim() === '') {\n continue;\n }\n rules = styleContents.match(/[^{]*\\{[\\s\\S]*?\\}/g);\n rules = rules.map(function(rule) { return rule.trim(); });\n // eslint-disable-next-line no-loop-func\n rules.forEach(function(rule) {\n\n var match = rule.match(/([\\s\\S]*?)\\s*\\{([^}]*)\\}/),\n ruleObj = { }, declaration = match[2].trim(),\n propertyValuePairs = declaration.replace(/;$/, '').split(/\\s*;\\s*/);\n\n for (i = 0, len = propertyValuePairs.length; i < len; i++) {\n var pair = propertyValuePairs[i].split(/\\s*:\\s*/),\n property = pair[0],\n value = pair[1];\n ruleObj[property] = value;\n }\n rule = match[1];\n rule.split(',').forEach(function(_rule) {\n _rule = _rule.replace(/^svg/i, '').trim();\n if (_rule === '') {\n return;\n }\n if (allRules[_rule]) {\n fabric.util.object.extend(allRules[_rule], ruleObj);\n }\n else {\n allRules[_rule] = fabric.util.object.clone(ruleObj);\n }\n });\n });\n }\n return allRules;\n },\n\n /**\n * Takes url corresponding to an SVG document, and parses it into a set of fabric objects.\n * Note that SVG is fetched via XMLHttpRequest, so it needs to conform to SOP (Same Origin Policy)\n * @memberOf fabric\n * @param {String} url\n * @param {Function} callback\n * @param {Function} [reviver] Method for further parsing of SVG elements, called after each fabric object created.\n * @param {Object} [options] Object containing options for parsing\n * @param {String} [options.crossOrigin] crossOrigin crossOrigin setting to use for external resources\n */\n loadSVGFromURL: function(url, callback, reviver, options) {\n\n url = url.replace(/^\\n\\s*/, '').trim();\n new fabric.util.request(url, {\n method: 'get',\n onComplete: onComplete\n });\n\n function onComplete(r) {\n\n var xml = r.responseXML;\n if (!xml || !xml.documentElement) {\n callback && callback(null);\n return false;\n }\n\n fabric.parseSVGDocument(xml.documentElement, function (results, _options, elements, allElements) {\n callback && callback(results, _options, elements, allElements);\n }, reviver, options);\n }\n },\n\n /**\n * Takes string corresponding to an SVG document, and parses it into a set of fabric objects\n * @memberOf fabric\n * @param {String} string\n * @param {Function} callback\n * @param {Function} [reviver] Method for further parsing of SVG elements, called after each fabric object created.\n * @param {Object} [options] Object containing options for parsing\n * @param {String} [options.crossOrigin] crossOrigin crossOrigin setting to use for external resources\n */\n loadSVGFromString: function(string, callback, reviver, options) {\n var parser = new fabric.window.DOMParser(),\n doc = parser.parseFromString(string.trim(), 'text/xml');\n fabric.parseSVGDocument(doc.documentElement, function (results, _options, elements, allElements) {\n callback(results, _options, elements, allElements);\n }, reviver, options);\n }\n });\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\nfabric.ElementsParser = function(elements, callback, options, reviver, parsingOptions, doc) {\n this.elements = elements;\n this.callback = callback;\n this.options = options;\n this.reviver = reviver;\n this.svgUid = (options && options.svgUid) || 0;\n this.parsingOptions = parsingOptions;\n this.regexUrl = /^url\\(['\"]?#([^'\"]+)['\"]?\\)/g;\n this.doc = doc;\n};\n\n(function(proto) {\n proto.parse = function() {\n this.instances = new Array(this.elements.length);\n this.numElements = this.elements.length;\n this.createObjects();\n };\n\n proto.createObjects = function() {\n var _this = this;\n this.elements.forEach(function(element, i) {\n element.setAttribute('svgUid', _this.svgUid);\n _this.createObject(element, i);\n });\n };\n\n proto.findTag = function(el) {\n return fabric[fabric.util.string.capitalize(el.tagName.replace('svg:', ''))];\n };\n\n proto.createObject = function(el, index) {\n var klass = this.findTag(el);\n if (klass && klass.fromElement) {\n try {\n klass.fromElement(el, this.createCallback(index, el), this.options);\n }\n catch (err) {\n fabric.log(err);\n }\n }\n else {\n this.checkIfDone();\n }\n };\n\n proto.createCallback = function(index, el) {\n var _this = this;\n return function(obj) {\n var _options;\n _this.resolveGradient(obj, el, 'fill');\n _this.resolveGradient(obj, el, 'stroke');\n if (obj instanceof fabric.Image && obj._originalElement) {\n _options = obj.parsePreserveAspectRatioAttribute(el);\n }\n obj._removeTransformMatrix(_options);\n _this.resolveClipPath(obj, el);\n _this.reviver && _this.reviver(el, obj);\n _this.instances[index] = obj;\n _this.checkIfDone();\n };\n };\n\n proto.extractPropertyDefinition = function(obj, property, storage) {\n var value = obj[property], regex = this.regexUrl;\n if (!regex.test(value)) {\n return;\n }\n regex.lastIndex = 0;\n var id = regex.exec(value)[1];\n regex.lastIndex = 0;\n return fabric[storage][this.svgUid][id];\n };\n\n proto.resolveGradient = function(obj, el, property) {\n var gradientDef = this.extractPropertyDefinition(obj, property, 'gradientDefs');\n if (gradientDef) {\n var opacityAttr = el.getAttribute(property + '-opacity');\n var gradient = fabric.Gradient.fromElement(gradientDef, obj, opacityAttr, this.options);\n obj.set(property, gradient);\n }\n };\n\n proto.createClipPathCallback = function(obj, container) {\n return function(_newObj) {\n _newObj._removeTransformMatrix();\n _newObj.fillRule = _newObj.clipRule;\n container.push(_newObj);\n };\n };\n\n proto.resolveClipPath = function(obj, usingElement) {\n var clipPath = this.extractPropertyDefinition(obj, 'clipPath', 'clipPaths'),\n element, klass, objTransformInv, container, gTransform, options;\n if (clipPath) {\n container = [];\n objTransformInv = fabric.util.invertTransform(obj.calcTransformMatrix());\n // move the clipPath tag as sibling to the real element that is using it\n var clipPathTag = clipPath[0].parentNode;\n var clipPathOwner = usingElement;\n while (clipPathOwner.parentNode && clipPathOwner.getAttribute('clip-path') !== obj.clipPath) {\n clipPathOwner = clipPathOwner.parentNode;\n }\n clipPathOwner.parentNode.appendChild(clipPathTag);\n for (var i = 0; i < clipPath.length; i++) {\n element = clipPath[i];\n klass = this.findTag(element);\n klass.fromElement(\n element,\n this.createClipPathCallback(obj, container),\n this.options\n );\n }\n if (container.length === 1) {\n clipPath = container[0];\n }\n else {\n clipPath = new fabric.Group(container);\n }\n gTransform = fabric.util.multiplyTransformMatrices(\n objTransformInv,\n clipPath.calcTransformMatrix()\n );\n if (clipPath.clipPath) {\n this.resolveClipPath(clipPath, clipPathOwner);\n }\n var options = fabric.util.qrDecompose(gTransform);\n clipPath.flipX = false;\n clipPath.flipY = false;\n clipPath.set('scaleX', options.scaleX);\n clipPath.set('scaleY', options.scaleY);\n clipPath.angle = options.angle;\n clipPath.skewX = options.skewX;\n clipPath.skewY = 0;\n clipPath.setPositionByOrigin({ x: options.translateX, y: options.translateY }, 'center', 'center');\n obj.clipPath = clipPath;\n }\n else {\n // if clip-path does not resolve to any element, delete the property.\n delete obj.clipPath;\n }\n };\n\n proto.checkIfDone = function() {\n if (--this.numElements === 0) {\n this.instances = this.instances.filter(function(el) {\n // eslint-disable-next-line no-eq-null, eqeqeq\n return el != null;\n });\n this.callback(this.instances, this.elements);\n }\n };\n})(fabric.ElementsParser.prototype);\n\n\n(function(global) {\n\n 'use strict';\n\n /* Adaptation of work of Kevin Lindsey (kevin@kevlindev.com) */\n\n var fabric = global.fabric || (global.fabric = { });\n\n if (fabric.Point) {\n fabric.warn('fabric.Point is already defined');\n return;\n }\n\n fabric.Point = Point;\n\n /**\n * Point class\n * @class fabric.Point\n * @memberOf fabric\n * @constructor\n * @param {Number} x\n * @param {Number} y\n * @return {fabric.Point} thisArg\n */\n function Point(x, y) {\n this.x = x;\n this.y = y;\n }\n\n Point.prototype = /** @lends fabric.Point.prototype */ {\n\n type: 'point',\n\n constructor: Point,\n\n /**\n * Adds another point to this one and returns another one\n * @param {fabric.Point} that\n * @return {fabric.Point} new Point instance with added values\n */\n add: function (that) {\n return new Point(this.x + that.x, this.y + that.y);\n },\n\n /**\n * Adds another point to this one\n * @param {fabric.Point} that\n * @return {fabric.Point} thisArg\n * @chainable\n */\n addEquals: function (that) {\n this.x += that.x;\n this.y += that.y;\n return this;\n },\n\n /**\n * Adds value to this point and returns a new one\n * @param {Number} scalar\n * @return {fabric.Point} new Point with added value\n */\n scalarAdd: function (scalar) {\n return new Point(this.x + scalar, this.y + scalar);\n },\n\n /**\n * Adds value to this point\n * @param {Number} scalar\n * @return {fabric.Point} thisArg\n * @chainable\n */\n scalarAddEquals: function (scalar) {\n this.x += scalar;\n this.y += scalar;\n return this;\n },\n\n /**\n * Subtracts another point from this point and returns a new one\n * @param {fabric.Point} that\n * @return {fabric.Point} new Point object with subtracted values\n */\n subtract: function (that) {\n return new Point(this.x - that.x, this.y - that.y);\n },\n\n /**\n * Subtracts another point from this point\n * @param {fabric.Point} that\n * @return {fabric.Point} thisArg\n * @chainable\n */\n subtractEquals: function (that) {\n this.x -= that.x;\n this.y -= that.y;\n return this;\n },\n\n /**\n * Subtracts value from this point and returns a new one\n * @param {Number} scalar\n * @return {fabric.Point}\n */\n scalarSubtract: function (scalar) {\n return new Point(this.x - scalar, this.y - scalar);\n },\n\n /**\n * Subtracts value from this point\n * @param {Number} scalar\n * @return {fabric.Point} thisArg\n * @chainable\n */\n scalarSubtractEquals: function (scalar) {\n this.x -= scalar;\n this.y -= scalar;\n return this;\n },\n\n /**\n * Multiplies this point by a value and returns a new one\n * TODO: rename in scalarMultiply in 2.0\n * @param {Number} scalar\n * @return {fabric.Point}\n */\n multiply: function (scalar) {\n return new Point(this.x * scalar, this.y * scalar);\n },\n\n /**\n * Multiplies this point by a value\n * TODO: rename in scalarMultiplyEquals in 2.0\n * @param {Number} scalar\n * @return {fabric.Point} thisArg\n * @chainable\n */\n multiplyEquals: function (scalar) {\n this.x *= scalar;\n this.y *= scalar;\n return this;\n },\n\n /**\n * Divides this point by a value and returns a new one\n * TODO: rename in scalarDivide in 2.0\n * @param {Number} scalar\n * @return {fabric.Point}\n */\n divide: function (scalar) {\n return new Point(this.x / scalar, this.y / scalar);\n },\n\n /**\n * Divides this point by a value\n * TODO: rename in scalarDivideEquals in 2.0\n * @param {Number} scalar\n * @return {fabric.Point} thisArg\n * @chainable\n */\n divideEquals: function (scalar) {\n this.x /= scalar;\n this.y /= scalar;\n return this;\n },\n\n /**\n * Returns true if this point is equal to another one\n * @param {fabric.Point} that\n * @return {Boolean}\n */\n eq: function (that) {\n return (this.x === that.x && this.y === that.y);\n },\n\n /**\n * Returns true if this point is less than another one\n * @param {fabric.Point} that\n * @return {Boolean}\n */\n lt: function (that) {\n return (this.x < that.x && this.y < that.y);\n },\n\n /**\n * Returns true if this point is less than or equal to another one\n * @param {fabric.Point} that\n * @return {Boolean}\n */\n lte: function (that) {\n return (this.x <= that.x && this.y <= that.y);\n },\n\n /**\n\n * Returns true if this point is greater another one\n * @param {fabric.Point} that\n * @return {Boolean}\n */\n gt: function (that) {\n return (this.x > that.x && this.y > that.y);\n },\n\n /**\n * Returns true if this point is greater than or equal to another one\n * @param {fabric.Point} that\n * @return {Boolean}\n */\n gte: function (that) {\n return (this.x >= that.x && this.y >= that.y);\n },\n\n /**\n * Returns new point which is the result of linear interpolation with this one and another one\n * @param {fabric.Point} that\n * @param {Number} t , position of interpolation, between 0 and 1 default 0.5\n * @return {fabric.Point}\n */\n lerp: function (that, t) {\n if (typeof t === 'undefined') {\n t = 0.5;\n }\n t = Math.max(Math.min(1, t), 0);\n return new Point(this.x + (that.x - this.x) * t, this.y + (that.y - this.y) * t);\n },\n\n /**\n * Returns distance from this point and another one\n * @param {fabric.Point} that\n * @return {Number}\n */\n distanceFrom: function (that) {\n var dx = this.x - that.x,\n dy = this.y - that.y;\n return Math.sqrt(dx * dx + dy * dy);\n },\n\n /**\n * Returns the point between this point and another one\n * @param {fabric.Point} that\n * @return {fabric.Point}\n */\n midPointFrom: function (that) {\n return this.lerp(that);\n },\n\n /**\n * Returns a new point which is the min of this and another one\n * @param {fabric.Point} that\n * @return {fabric.Point}\n */\n min: function (that) {\n return new Point(Math.min(this.x, that.x), Math.min(this.y, that.y));\n },\n\n /**\n * Returns a new point which is the max of this and another one\n * @param {fabric.Point} that\n * @return {fabric.Point}\n */\n max: function (that) {\n return new Point(Math.max(this.x, that.x), Math.max(this.y, that.y));\n },\n\n /**\n * Returns string representation of this point\n * @return {String}\n */\n toString: function () {\n return this.x + ',' + this.y;\n },\n\n /**\n * Sets x/y of this point\n * @param {Number} x\n * @param {Number} y\n * @chainable\n */\n setXY: function (x, y) {\n this.x = x;\n this.y = y;\n return this;\n },\n\n /**\n * Sets x of this point\n * @param {Number} x\n * @chainable\n */\n setX: function (x) {\n this.x = x;\n return this;\n },\n\n /**\n * Sets y of this point\n * @param {Number} y\n * @chainable\n */\n setY: function (y) {\n this.y = y;\n return this;\n },\n\n /**\n * Sets x/y of this point from another point\n * @param {fabric.Point} that\n * @chainable\n */\n setFromPoint: function (that) {\n this.x = that.x;\n this.y = that.y;\n return this;\n },\n\n /**\n * Swaps x/y of this point and another point\n * @param {fabric.Point} that\n */\n swap: function (that) {\n var x = this.x,\n y = this.y;\n this.x = that.x;\n this.y = that.y;\n that.x = x;\n that.y = y;\n },\n\n /**\n * return a cloned instance of the point\n * @return {fabric.Point}\n */\n clone: function () {\n return new Point(this.x, this.y);\n }\n };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n /* Adaptation of work of Kevin Lindsey (kevin@kevlindev.com) */\n var fabric = global.fabric || (global.fabric = { });\n\n if (fabric.Intersection) {\n fabric.warn('fabric.Intersection is already defined');\n return;\n }\n\n /**\n * Intersection class\n * @class fabric.Intersection\n * @memberOf fabric\n * @constructor\n */\n function Intersection(status) {\n this.status = status;\n this.points = [];\n }\n\n fabric.Intersection = Intersection;\n\n fabric.Intersection.prototype = /** @lends fabric.Intersection.prototype */ {\n\n constructor: Intersection,\n\n /**\n * Appends a point to intersection\n * @param {fabric.Point} point\n * @return {fabric.Intersection} thisArg\n * @chainable\n */\n appendPoint: function (point) {\n this.points.push(point);\n return this;\n },\n\n /**\n * Appends points to intersection\n * @param {Array} points\n * @return {fabric.Intersection} thisArg\n * @chainable\n */\n appendPoints: function (points) {\n this.points = this.points.concat(points);\n return this;\n }\n };\n\n /**\n * Checks if one line intersects another\n * TODO: rename in intersectSegmentSegment\n * @static\n * @param {fabric.Point} a1\n * @param {fabric.Point} a2\n * @param {fabric.Point} b1\n * @param {fabric.Point} b2\n * @return {fabric.Intersection}\n */\n fabric.Intersection.intersectLineLine = function (a1, a2, b1, b2) {\n var result,\n uaT = (b2.x - b1.x) * (a1.y - b1.y) - (b2.y - b1.y) * (a1.x - b1.x),\n ubT = (a2.x - a1.x) * (a1.y - b1.y) - (a2.y - a1.y) * (a1.x - b1.x),\n uB = (b2.y - b1.y) * (a2.x - a1.x) - (b2.x - b1.x) * (a2.y - a1.y);\n if (uB !== 0) {\n var ua = uaT / uB,\n ub = ubT / uB;\n if (0 <= ua && ua <= 1 && 0 <= ub && ub <= 1) {\n result = new Intersection('Intersection');\n result.appendPoint(new fabric.Point(a1.x + ua * (a2.x - a1.x), a1.y + ua * (a2.y - a1.y)));\n }\n else {\n result = new Intersection();\n }\n }\n else {\n if (uaT === 0 || ubT === 0) {\n result = new Intersection('Coincident');\n }\n else {\n result = new Intersection('Parallel');\n }\n }\n return result;\n };\n\n /**\n * Checks if line intersects polygon\n * TODO: rename in intersectSegmentPolygon\n * fix detection of coincident\n * @static\n * @param {fabric.Point} a1\n * @param {fabric.Point} a2\n * @param {Array} points\n * @return {fabric.Intersection}\n */\n fabric.Intersection.intersectLinePolygon = function(a1, a2, points) {\n var result = new Intersection(),\n length = points.length,\n b1, b2, inter, i;\n\n for (i = 0; i < length; i++) {\n b1 = points[i];\n b2 = points[(i + 1) % length];\n inter = Intersection.intersectLineLine(a1, a2, b1, b2);\n\n result.appendPoints(inter.points);\n }\n if (result.points.length > 0) {\n result.status = 'Intersection';\n }\n return result;\n };\n\n /**\n * Checks if polygon intersects another polygon\n * @static\n * @param {Array} points1\n * @param {Array} points2\n * @return {fabric.Intersection}\n */\n fabric.Intersection.intersectPolygonPolygon = function (points1, points2) {\n var result = new Intersection(),\n length = points1.length, i;\n\n for (i = 0; i < length; i++) {\n var a1 = points1[i],\n a2 = points1[(i + 1) % length],\n inter = Intersection.intersectLinePolygon(a1, a2, points2);\n\n result.appendPoints(inter.points);\n }\n if (result.points.length > 0) {\n result.status = 'Intersection';\n }\n return result;\n };\n\n /**\n * Checks if polygon intersects rectangle\n * @static\n * @param {Array} points\n * @param {fabric.Point} r1\n * @param {fabric.Point} r2\n * @return {fabric.Intersection}\n */\n fabric.Intersection.intersectPolygonRectangle = function (points, r1, r2) {\n var min = r1.min(r2),\n max = r1.max(r2),\n topRight = new fabric.Point(max.x, min.y),\n bottomLeft = new fabric.Point(min.x, max.y),\n inter1 = Intersection.intersectLinePolygon(min, topRight, points),\n inter2 = Intersection.intersectLinePolygon(topRight, max, points),\n inter3 = Intersection.intersectLinePolygon(max, bottomLeft, points),\n inter4 = Intersection.intersectLinePolygon(bottomLeft, min, points),\n result = new Intersection();\n\n result.appendPoints(inter1.points);\n result.appendPoints(inter2.points);\n result.appendPoints(inter3.points);\n result.appendPoints(inter4.points);\n\n if (result.points.length > 0) {\n result.status = 'Intersection';\n }\n return result;\n };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { });\n\n if (fabric.Color) {\n fabric.warn('fabric.Color is already defined.');\n return;\n }\n\n /**\n * Color class\n * The purpose of {@link fabric.Color} is to abstract and encapsulate common color operations;\n * {@link fabric.Color} is a constructor and creates instances of {@link fabric.Color} objects.\n *\n * @class fabric.Color\n * @param {String} color optional in hex or rgb(a) or hsl format or from known color list\n * @return {fabric.Color} thisArg\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-2/#colors}\n */\n function Color(color) {\n if (!color) {\n this.setSource([0, 0, 0, 1]);\n }\n else {\n this._tryParsingColor(color);\n }\n }\n\n fabric.Color = Color;\n\n fabric.Color.prototype = /** @lends fabric.Color.prototype */ {\n\n /**\n * @private\n * @param {String|Array} color Color value to parse\n */\n _tryParsingColor: function(color) {\n var source;\n\n if (color in Color.colorNameMap) {\n color = Color.colorNameMap[color];\n }\n\n if (color === 'transparent') {\n source = [255, 255, 255, 0];\n }\n\n if (!source) {\n source = Color.sourceFromHex(color);\n }\n if (!source) {\n source = Color.sourceFromRgb(color);\n }\n if (!source) {\n source = Color.sourceFromHsl(color);\n }\n if (!source) {\n //if color is not recognize let's make black as canvas does\n source = [0, 0, 0, 1];\n }\n if (source) {\n this.setSource(source);\n }\n },\n\n /**\n * Adapted from <a href=\"https://rawgithub.com/mjijackson/mjijackson.github.com/master/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript.html\">https://github.com/mjijackson</a>\n * @private\n * @param {Number} r Red color value\n * @param {Number} g Green color value\n * @param {Number} b Blue color value\n * @return {Array} Hsl color\n */\n _rgbToHsl: function(r, g, b) {\n r /= 255; g /= 255; b /= 255;\n\n var h, s, l,\n max = fabric.util.array.max([r, g, b]),\n min = fabric.util.array.min([r, g, b]);\n\n l = (max + min) / 2;\n\n if (max === min) {\n h = s = 0; // achromatic\n }\n else {\n var d = max - min;\n s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n switch (max) {\n case r:\n h = (g - b) / d + (g < b ? 6 : 0);\n break;\n case g:\n h = (b - r) / d + 2;\n break;\n case b:\n h = (r - g) / d + 4;\n break;\n }\n h /= 6;\n }\n\n return [\n Math.round(h * 360),\n Math.round(s * 100),\n Math.round(l * 100)\n ];\n },\n\n /**\n * Returns source of this color (where source is an array representation; ex: [200, 200, 100, 1])\n * @return {Array}\n */\n getSource: function() {\n return this._source;\n },\n\n /**\n * Sets source of this color (where source is an array representation; ex: [200, 200, 100, 1])\n * @param {Array} source\n */\n setSource: function(source) {\n this._source = source;\n },\n\n /**\n * Returns color representation in RGB format\n * @return {String} ex: rgb(0-255,0-255,0-255)\n */\n toRgb: function() {\n var source = this.getSource();\n return 'rgb(' + source[0] + ',' + source[1] + ',' + source[2] + ')';\n },\n\n /**\n * Returns color representation in RGBA format\n * @return {String} ex: rgba(0-255,0-255,0-255,0-1)\n */\n toRgba: function() {\n var source = this.getSource();\n return 'rgba(' + source[0] + ',' + source[1] + ',' + source[2] + ',' + source[3] + ')';\n },\n\n /**\n * Returns color representation in HSL format\n * @return {String} ex: hsl(0-360,0%-100%,0%-100%)\n */\n toHsl: function() {\n var source = this.getSource(),\n hsl = this._rgbToHsl(source[0], source[1], source[2]);\n\n return 'hsl(' + hsl[0] + ',' + hsl[1] + '%,' + hsl[2] + '%)';\n },\n\n /**\n * Returns color representation in HSLA format\n * @return {String} ex: hsla(0-360,0%-100%,0%-100%,0-1)\n */\n toHsla: function() {\n var source = this.getSource(),\n hsl = this._rgbToHsl(source[0], source[1], source[2]);\n\n return 'hsla(' + hsl[0] + ',' + hsl[1] + '%,' + hsl[2] + '%,' + source[3] + ')';\n },\n\n /**\n * Returns color representation in HEX format\n * @return {String} ex: FF5555\n */\n toHex: function() {\n var source = this.getSource(), r, g, b;\n\n r = source[0].toString(16);\n r = (r.length === 1) ? ('0' + r) : r;\n\n g = source[1].toString(16);\n g = (g.length === 1) ? ('0' + g) : g;\n\n b = source[2].toString(16);\n b = (b.length === 1) ? ('0' + b) : b;\n\n return r.toUpperCase() + g.toUpperCase() + b.toUpperCase();\n },\n\n /**\n * Returns color representation in HEXA format\n * @return {String} ex: FF5555CC\n */\n toHexa: function() {\n var source = this.getSource(), a;\n\n a = Math.round(source[3] * 255);\n a = a.toString(16);\n a = (a.length === 1) ? ('0' + a) : a;\n\n return this.toHex() + a.toUpperCase();\n },\n\n /**\n * Gets value of alpha channel for this color\n * @return {Number} 0-1\n */\n getAlpha: function() {\n return this.getSource()[3];\n },\n\n /**\n * Sets value of alpha channel for this color\n * @param {Number} alpha Alpha value 0-1\n * @return {fabric.Color} thisArg\n */\n setAlpha: function(alpha) {\n var source = this.getSource();\n source[3] = alpha;\n this.setSource(source);\n return this;\n },\n\n /**\n * Transforms color to its grayscale representation\n * @return {fabric.Color} thisArg\n */\n toGrayscale: function() {\n var source = this.getSource(),\n average = parseInt((source[0] * 0.3 + source[1] * 0.59 + source[2] * 0.11).toFixed(0), 10),\n currentAlpha = source[3];\n this.setSource([average, average, average, currentAlpha]);\n return this;\n },\n\n /**\n * Transforms color to its black and white representation\n * @param {Number} threshold\n * @return {fabric.Color} thisArg\n */\n toBlackWhite: function(threshold) {\n var source = this.getSource(),\n average = (source[0] * 0.3 + source[1] * 0.59 + source[2] * 0.11).toFixed(0),\n currentAlpha = source[3];\n\n threshold = threshold || 127;\n\n average = (Number(average) < Number(threshold)) ? 0 : 255;\n this.setSource([average, average, average, currentAlpha]);\n return this;\n },\n\n /**\n * Overlays color with another color\n * @param {String|fabric.Color} otherColor\n * @return {fabric.Color} thisArg\n */\n overlayWith: function(otherColor) {\n if (!(otherColor instanceof Color)) {\n otherColor = new Color(otherColor);\n }\n\n var result = [],\n alpha = this.getAlpha(),\n otherAlpha = 0.5,\n source = this.getSource(),\n otherSource = otherColor.getSource(), i;\n\n for (i = 0; i < 3; i++) {\n result.push(Math.round((source[i] * (1 - otherAlpha)) + (otherSource[i] * otherAlpha)));\n }\n\n result[3] = alpha;\n this.setSource(result);\n return this;\n }\n };\n\n /**\n * Regex matching color in RGB or RGBA formats (ex: rgb(0, 0, 0), rgba(255, 100, 10, 0.5), rgba( 255 , 100 , 10 , 0.5 ), rgb(1,1,1), rgba(100%, 60%, 10%, 0.5))\n * @static\n * @field\n * @memberOf fabric.Color\n */\n // eslint-disable-next-line max-len\n 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*)?\\)$/i;\n\n /**\n * Regex matching color in HSL or HSLA formats (ex: hsl(200, 80%, 10%), hsla(300, 50%, 80%, 0.5), hsla( 300 , 50% , 80% , 0.5 ))\n * @static\n * @field\n * @memberOf fabric.Color\n */\n fabric.Color.reHSLa = /^hsla?\\(\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3}\\%)\\s*,\\s*(\\d{1,3}\\%)\\s*(?:\\s*,\\s*(\\d+(?:\\.\\d+)?)\\s*)?\\)$/i;\n\n /**\n * Regex matching color in HEX format (ex: #FF5544CC, #FF5555, 010155, aff)\n * @static\n * @field\n * @memberOf fabric.Color\n */\n fabric.Color.reHex = /^#?([0-9a-f]{8}|[0-9a-f]{6}|[0-9a-f]{4}|[0-9a-f]{3})$/i;\n\n /**\n * Map of the 148 color names with HEX code\n * @static\n * @field\n * @memberOf fabric.Color\n * @see: https://www.w3.org/TR/css3-color/#svg-color\n */\n fabric.Color.colorNameMap = {\n aliceblue: '#F0F8FF',\n antiquewhite: '#FAEBD7',\n aqua: '#00FFFF',\n aquamarine: '#7FFFD4',\n azure: '#F0FFFF',\n beige: '#F5F5DC',\n bisque: '#FFE4C4',\n black: '#000000',\n blanchedalmond: '#FFEBCD',\n blue: '#0000FF',\n blueviolet: '#8A2BE2',\n brown: '#A52A2A',\n burlywood: '#DEB887',\n cadetblue: '#5F9EA0',\n chartreuse: '#7FFF00',\n chocolate: '#D2691E',\n coral: '#FF7F50',\n cornflowerblue: '#6495ED',\n cornsilk: '#FFF8DC',\n crimson: '#DC143C',\n cyan: '#00FFFF',\n darkblue: '#00008B',\n darkcyan: '#008B8B',\n darkgoldenrod: '#B8860B',\n darkgray: '#A9A9A9',\n darkgrey: '#A9A9A9',\n darkgreen: '#006400',\n darkkhaki: '#BDB76B',\n darkmagenta: '#8B008B',\n darkolivegreen: '#556B2F',\n darkorange: '#FF8C00',\n darkorchid: '#9932CC',\n darkred: '#8B0000',\n darksalmon: '#E9967A',\n darkseagreen: '#8FBC8F',\n darkslateblue: '#483D8B',\n darkslategray: '#2F4F4F',\n darkslategrey: '#2F4F4F',\n darkturquoise: '#00CED1',\n darkviolet: '#9400D3',\n deeppink: '#FF1493',\n deepskyblue: '#00BFFF',\n dimgray: '#696969',\n dimgrey: '#696969',\n dodgerblue: '#1E90FF',\n firebrick: '#B22222',\n floralwhite: '#FFFAF0',\n forestgreen: '#228B22',\n fuchsia: '#FF00FF',\n gainsboro: '#DCDCDC',\n ghostwhite: '#F8F8FF',\n gold: '#FFD700',\n goldenrod: '#DAA520',\n gray: '#808080',\n grey: '#808080',\n green: '#008000',\n greenyellow: '#ADFF2F',\n honeydew: '#F0FFF0',\n hotpink: '#FF69B4',\n indianred: '#CD5C5C',\n indigo: '#4B0082',\n ivory: '#FFFFF0',\n khaki: '#F0E68C',\n lavender: '#E6E6FA',\n lavenderblush: '#FFF0F5',\n lawngreen: '#7CFC00',\n lemonchiffon: '#FFFACD',\n lightblue: '#ADD8E6',\n lightcoral: '#F08080',\n lightcyan: '#E0FFFF',\n lightgoldenrodyellow: '#FAFAD2',\n lightgray: '#D3D3D3',\n lightgrey: '#D3D3D3',\n lightgreen: '#90EE90',\n lightpink: '#FFB6C1',\n lightsalmon: '#FFA07A',\n lightseagreen: '#20B2AA',\n lightskyblue: '#87CEFA',\n lightslategray: '#778899',\n lightslategrey: '#778899',\n lightsteelblue: '#B0C4DE',\n lightyellow: '#FFFFE0',\n lime: '#00FF00',\n limegreen: '#32CD32',\n linen: '#FAF0E6',\n magenta: '#FF00FF',\n maroon: '#800000',\n mediumaquamarine: '#66CDAA',\n mediumblue: '#0000CD',\n mediumorchid: '#BA55D3',\n mediumpurple: '#9370DB',\n mediumseagreen: '#3CB371',\n mediumslateblue: '#7B68EE',\n mediumspringgreen: '#00FA9A',\n mediumturquoise: '#48D1CC',\n mediumvioletred: '#C71585',\n midnightblue: '#191970',\n mintcream: '#F5FFFA',\n mistyrose: '#FFE4E1',\n moccasin: '#FFE4B5',\n navajowhite: '#FFDEAD',\n navy: '#000080',\n oldlace: '#FDF5E6',\n olive: '#808000',\n olivedrab: '#6B8E23',\n orange: '#FFA500',\n orangered: '#FF4500',\n orchid: '#DA70D6',\n palegoldenrod: '#EEE8AA',\n palegreen: '#98FB98',\n paleturquoise: '#AFEEEE',\n palevioletred: '#DB7093',\n papayawhip: '#FFEFD5',\n peachpuff: '#FFDAB9',\n peru: '#CD853F',\n pink: '#FFC0CB',\n plum: '#DDA0DD',\n powderblue: '#B0E0E6',\n purple: '#800080',\n rebeccapurple: '#663399',\n red: '#FF0000',\n rosybrown: '#BC8F8F',\n royalblue: '#4169E1',\n saddlebrown: '#8B4513',\n salmon: '#FA8072',\n sandybrown: '#F4A460',\n seagreen: '#2E8B57',\n seashell: '#FFF5EE',\n sienna: '#A0522D',\n silver: '#C0C0C0',\n skyblue: '#87CEEB',\n slateblue: '#6A5ACD',\n slategray: '#708090',\n slategrey: '#708090',\n snow: '#FFFAFA',\n springgreen: '#00FF7F',\n steelblue: '#4682B4',\n tan: '#D2B48C',\n teal: '#008080',\n thistle: '#D8BFD8',\n tomato: '#FF6347',\n turquoise: '#40E0D0',\n violet: '#EE82EE',\n wheat: '#F5DEB3',\n white: '#FFFFFF',\n whitesmoke: '#F5F5F5',\n yellow: '#FFFF00',\n yellowgreen: '#9ACD32'\n };\n\n /**\n * @private\n * @param {Number} p\n * @param {Number} q\n * @param {Number} t\n * @return {Number}\n */\n function hue2rgb(p, q, t) {\n if (t < 0) {\n t += 1;\n }\n if (t > 1) {\n t -= 1;\n }\n if (t < 1 / 6) {\n return p + (q - p) * 6 * t;\n }\n if (t < 1 / 2) {\n return q;\n }\n if (t < 2 / 3) {\n return p + (q - p) * (2 / 3 - t) * 6;\n }\n return p;\n }\n\n /**\n * Returns new color object, when given a color in RGB format\n * @memberOf fabric.Color\n * @param {String} color Color value ex: rgb(0-255,0-255,0-255)\n * @return {fabric.Color}\n */\n fabric.Color.fromRgb = function(color) {\n return Color.fromSource(Color.sourceFromRgb(color));\n };\n\n /**\n * Returns array representation (ex: [100, 100, 200, 1]) of a color that's in RGB or RGBA format\n * @memberOf fabric.Color\n * @param {String} color Color value ex: rgb(0-255,0-255,0-255), rgb(0%-100%,0%-100%,0%-100%)\n * @return {Array} source\n */\n fabric.Color.sourceFromRgb = function(color) {\n var match = color.match(Color.reRGBa);\n if (match) {\n var r = parseInt(match[1], 10) / (/%$/.test(match[1]) ? 100 : 1) * (/%$/.test(match[1]) ? 255 : 1),\n g = parseInt(match[2], 10) / (/%$/.test(match[2]) ? 100 : 1) * (/%$/.test(match[2]) ? 255 : 1),\n b = parseInt(match[3], 10) / (/%$/.test(match[3]) ? 100 : 1) * (/%$/.test(match[3]) ? 255 : 1);\n\n return [\n parseInt(r, 10),\n parseInt(g, 10),\n parseInt(b, 10),\n match[4] ? parseFloat(match[4]) : 1\n ];\n }\n };\n\n /**\n * Returns new color object, when given a color in RGBA format\n * @static\n * @function\n * @memberOf fabric.Color\n * @param {String} color\n * @return {fabric.Color}\n */\n fabric.Color.fromRgba = Color.fromRgb;\n\n /**\n * Returns new color object, when given a color in HSL format\n * @param {String} color Color value ex: hsl(0-260,0%-100%,0%-100%)\n * @memberOf fabric.Color\n * @return {fabric.Color}\n */\n fabric.Color.fromHsl = function(color) {\n return Color.fromSource(Color.sourceFromHsl(color));\n };\n\n /**\n * Returns array representation (ex: [100, 100, 200, 1]) of a color that's in HSL or HSLA format.\n * Adapted from <a href=\"https://rawgithub.com/mjijackson/mjijackson.github.com/master/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript.html\">https://github.com/mjijackson</a>\n * @memberOf fabric.Color\n * @param {String} color Color value ex: hsl(0-360,0%-100%,0%-100%) or hsla(0-360,0%-100%,0%-100%, 0-1)\n * @return {Array} source\n * @see http://http://www.w3.org/TR/css3-color/#hsl-color\n */\n fabric.Color.sourceFromHsl = function(color) {\n var match = color.match(Color.reHSLa);\n if (!match) {\n return;\n }\n\n var h = (((parseFloat(match[1]) % 360) + 360) % 360) / 360,\n s = parseFloat(match[2]) / (/%$/.test(match[2]) ? 100 : 1),\n l = parseFloat(match[3]) / (/%$/.test(match[3]) ? 100 : 1),\n r, g, b;\n\n if (s === 0) {\n r = g = b = l;\n }\n else {\n var q = l <= 0.5 ? l * (s + 1) : l + s - l * s,\n p = l * 2 - q;\n\n r = hue2rgb(p, q, h + 1 / 3);\n g = hue2rgb(p, q, h);\n b = hue2rgb(p, q, h - 1 / 3);\n }\n\n return [\n Math.round(r * 255),\n Math.round(g * 255),\n Math.round(b * 255),\n match[4] ? parseFloat(match[4]) : 1\n ];\n };\n\n /**\n * Returns new color object, when given a color in HSLA format\n * @static\n * @function\n * @memberOf fabric.Color\n * @param {String} color\n * @return {fabric.Color}\n */\n fabric.Color.fromHsla = Color.fromHsl;\n\n /**\n * Returns new color object, when given a color in HEX format\n * @static\n * @memberOf fabric.Color\n * @param {String} color Color value ex: FF5555\n * @return {fabric.Color}\n */\n fabric.Color.fromHex = function(color) {\n return Color.fromSource(Color.sourceFromHex(color));\n };\n\n /**\n * Returns array representation (ex: [100, 100, 200, 1]) of a color that's in HEX format\n * @static\n * @memberOf fabric.Color\n * @param {String} color ex: FF5555 or FF5544CC (RGBa)\n * @return {Array} source\n */\n fabric.Color.sourceFromHex = function(color) {\n if (color.match(Color.reHex)) {\n var value = color.slice(color.indexOf('#') + 1),\n isShortNotation = (value.length === 3 || value.length === 4),\n isRGBa = (value.length === 8 || value.length === 4),\n r = isShortNotation ? (value.charAt(0) + value.charAt(0)) : value.substring(0, 2),\n g = isShortNotation ? (value.charAt(1) + value.charAt(1)) : value.substring(2, 4),\n b = isShortNotation ? (value.charAt(2) + value.charAt(2)) : value.substring(4, 6),\n a = isRGBa ? (isShortNotation ? (value.charAt(3) + value.charAt(3)) : value.substring(6, 8)) : 'FF';\n\n return [\n parseInt(r, 16),\n parseInt(g, 16),\n parseInt(b, 16),\n parseFloat((parseInt(a, 16) / 255).toFixed(2))\n ];\n }\n };\n\n /**\n * Returns new color object, when given color in array representation (ex: [200, 100, 100, 0.5])\n * @static\n * @memberOf fabric.Color\n * @param {Array} source\n * @return {fabric.Color}\n */\n fabric.Color.fromSource = function(source) {\n var oColor = new Color();\n oColor.setSource(source);\n return oColor;\n };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n scaleMap = ['e', 'se', 's', 'sw', 'w', 'nw', 'n', 'ne', 'e'],\n skewMap = ['ns', 'nesw', 'ew', 'nwse'],\n controls = {},\n LEFT = 'left', TOP = 'top', RIGHT = 'right', BOTTOM = 'bottom', CENTER = 'center',\n opposite = {\n top: BOTTOM,\n bottom: TOP,\n left: RIGHT,\n right: LEFT,\n center: CENTER,\n }, radiansToDegrees = fabric.util.radiansToDegrees,\n sign = (Math.sign || function(x) { return ((x > 0) - (x < 0)) || +x; });\n\n /**\n * Combine control position and object angle to find the control direction compared\n * to the object center.\n * @param {fabric.Object} fabricObject the fabric object for which we are rendering controls\n * @param {fabric.Control} control the control class\n * @return {Number} 0 - 7 a quadrant number\n */\n function findCornerQuadrant(fabricObject, control) {\n var cornerAngle = fabricObject.angle + radiansToDegrees(Math.atan2(control.y, control.x)) + 360;\n return Math.round((cornerAngle % 360) / 45);\n }\n\n function fireEvent(eventName, options) {\n var target = options.transform.target,\n canvas = target.canvas,\n canvasOptions = fabric.util.object.clone(options);\n canvasOptions.target = target;\n canvas && canvas.fire('object:' + eventName, canvasOptions);\n target.fire(eventName, options);\n }\n\n /**\n * Inspect event and fabricObject properties to understand if the scaling action\n * @param {Event} eventData from the user action\n * @param {fabric.Object} fabricObject the fabric object about to scale\n * @return {Boolean} true if scale is proportional\n */\n function scaleIsProportional(eventData, fabricObject) {\n var canvas = fabricObject.canvas, uniScaleKey = canvas.uniScaleKey,\n uniformIsToggled = eventData[uniScaleKey];\n return (canvas.uniformScaling && !uniformIsToggled) ||\n (!canvas.uniformScaling && uniformIsToggled);\n }\n\n /**\n * Checks if transform is centered\n * @param {Object} transform transform data\n * @return {Boolean} true if transform is centered\n */\n function isTransformCentered(transform) {\n return transform.originX === CENTER && transform.originY === CENTER;\n }\n\n /**\n * Inspect fabricObject to understand if the current scaling action is allowed\n * @param {fabric.Object} fabricObject the fabric object about to scale\n * @param {String} by 'x' or 'y' or ''\n * @param {Boolean} scaleProportionally true if we are trying to scale proportionally\n * @return {Boolean} true if scaling is not allowed at current conditions\n */\n function scalingIsForbidden(fabricObject, by, scaleProportionally) {\n var lockX = fabricObject.lockScalingX, lockY = fabricObject.lockScalingY;\n if (lockX && lockY) {\n return true;\n }\n if (!by && (lockX || lockY) && scaleProportionally) {\n return true;\n }\n if (lockX && by === 'x') {\n return true;\n }\n if (lockY && by === 'y') {\n return true;\n }\n return false;\n }\n\n /**\n * return the correct cursor style for the scale action\n * @param {Event} eventData the javascript event that is causing the scale\n * @param {fabric.Control} control the control that is interested in the action\n * @param {fabric.Object} fabricObject the fabric object that is interested in the action\n * @return {String} a valid css string for the cursor\n */\n function scaleCursorStyleHandler(eventData, control, fabricObject) {\n var notAllowed = 'not-allowed',\n scaleProportionally = scaleIsProportional(eventData, fabricObject),\n by = '';\n if (control.x !== 0 && control.y === 0) {\n by = 'x';\n }\n else if (control.x === 0 && control.y !== 0) {\n by = 'y';\n }\n if (scalingIsForbidden(fabricObject, by, scaleProportionally)) {\n return notAllowed;\n }\n var n = findCornerQuadrant(fabricObject, control);\n return scaleMap[n] + '-resize';\n }\n\n /**\n * return the correct cursor style for the skew action\n * @param {Event} eventData the javascript event that is causing the scale\n * @param {fabric.Control} control the control that is interested in the action\n * @param {fabric.Object} fabricObject the fabric object that is interested in the action\n * @return {String} a valid css string for the cursor\n */\n function skewCursorStyleHandler(eventData, control, fabricObject) {\n var notAllowed = 'not-allowed';\n if (control.x !== 0 && fabricObject.lockSkewingY) {\n return notAllowed;\n }\n if (control.y !== 0 && fabricObject.lockSkewingX) {\n return notAllowed;\n }\n var n = findCornerQuadrant(fabricObject, control) % 4;\n return skewMap[n] + '-resize';\n }\n\n /**\n * Combine skew and scale style handlers to cover fabric standard use case\n * @param {Event} eventData the javascript event that is causing the scale\n * @param {fabric.Control} control the control that is interested in the action\n * @param {fabric.Object} fabricObject the fabric object that is interested in the action\n * @return {String} a valid css string for the cursor\n */\n function scaleSkewCursorStyleHandler(eventData, control, fabricObject) {\n if (eventData[fabricObject.canvas.altActionKey]) {\n return controls.skewCursorStyleHandler(eventData, control, fabricObject);\n }\n return controls.scaleCursorStyleHandler(eventData, control, fabricObject);\n }\n\n /**\n * Inspect event, control and fabricObject to return the correct action name\n * @param {Event} eventData the javascript event that is causing the scale\n * @param {fabric.Control} control the control that is interested in the action\n * @param {fabric.Object} fabricObject the fabric object that is interested in the action\n * @return {String} an action name\n */\n function scaleOrSkewActionName(eventData, control, fabricObject) {\n var isAlternative = eventData[fabricObject.canvas.altActionKey];\n if (control.x === 0) {\n // then is scaleY or skewX\n return isAlternative ? 'skewX' : 'scaleY';\n }\n if (control.y === 0) {\n // then is scaleY or skewX\n return isAlternative ? 'skewY' : 'scaleX';\n }\n }\n\n /**\n * Find the correct style for the control that is used for rotation.\n * this function is very simple and it just take care of not-allowed or standard cursor\n * @param {Event} eventData the javascript event that is causing the scale\n * @param {fabric.Control} control the control that is interested in the action\n * @param {fabric.Object} fabricObject the fabric object that is interested in the action\n * @return {String} a valid css string for the cursor\n */\n function rotationStyleHandler(eventData, control, fabricObject) {\n if (fabricObject.lockRotation) {\n return 'not-allowed';\n }\n return control.cursorStyle;\n }\n\n function commonEventInfo(eventData, transform, x, y) {\n return {\n e: eventData,\n transform: transform,\n pointer: {\n x: x,\n y: y,\n }\n };\n }\n\n /**\n * Wrap an action handler with saving/restoring object position on the transform.\n * this is the code that permits to objects to keep their position while transforming.\n * @param {Function} actionHandler the function to wrap\n * @return {Function} a function with an action handler signature\n */\n function wrapWithFixedAnchor(actionHandler) {\n return function(eventData, transform, x, y) {\n var target = transform.target, centerPoint = target.getCenterPoint(),\n constraint = target.translateToOriginPoint(centerPoint, transform.originX, transform.originY),\n actionPerformed = actionHandler(eventData, transform, x, y);\n target.setPositionByOrigin(constraint, transform.originX, transform.originY);\n return actionPerformed;\n };\n }\n\n /**\n * Transforms a point described by x and y in a distance from the top left corner of the object\n * bounding box.\n * @param {Object} transform\n * @param {String} originX\n * @param {String} originY\n * @param {number} x\n * @param {number} y\n * @return {Fabric.Point} the normalized point\n */\n function getLocalPoint(transform, originX, originY, x, y) {\n var target = transform.target,\n control = target.controls[transform.corner],\n zoom = target.canvas.getZoom(),\n padding = target.padding / zoom,\n localPoint = target.toLocalPoint(new fabric.Point(x, y), originX, originY);\n if (localPoint.x >= padding) {\n localPoint.x -= padding;\n }\n if (localPoint.x <= -padding) {\n localPoint.x += padding;\n }\n if (localPoint.y >= padding) {\n localPoint.y -= padding;\n }\n if (localPoint.y <= padding) {\n localPoint.y += padding;\n }\n localPoint.x -= control.offsetX;\n localPoint.y -= control.offsetY;\n return localPoint;\n }\n\n /**\n * Detect if the fabric object is flipped on one side.\n * @param {fabric.Object} target\n * @return {Boolean} true if one flip, but not two.\n */\n function targetHasOneFlip(target) {\n return (target.flipX && !target.flipY) || (!target.flipX && target.flipY);\n }\n\n /**\n * Utility function to compensate the scale factor when skew is applied on both axes\n * @private\n */\n function compensateScaleForSkew(target, oppositeSkew, scaleToCompensate, axis, reference) {\n if (target[oppositeSkew] !== 0) {\n var newDim = target._getTransformedDimensions()[axis];\n var newValue = reference / newDim * target[scaleToCompensate];\n target.set(scaleToCompensate, newValue);\n }\n }\n\n /**\n * Action handler for skewing on the X axis\n * @private\n */\n function skewObjectX(eventData, transform, x, y) {\n var target = transform.target,\n // find how big the object would be, if there was no skewX. takes in account scaling\n dimNoSkew = target._getTransformedDimensions(0, target.skewY),\n localPoint = getLocalPoint(transform, transform.originX, transform.originY, x, y),\n // the mouse is in the center of the object, and we want it to stay there.\n // so the object will grow twice as much as the mouse.\n // this makes the skew growth to localPoint * 2 - dimNoSkew.\n totalSkewSize = Math.abs(localPoint.x * 2) - dimNoSkew.x,\n currentSkew = target.skewX, newSkew;\n if (totalSkewSize < 2) {\n // let's make it easy to go back to position 0.\n newSkew = 0;\n }\n else {\n newSkew = radiansToDegrees(\n Math.atan2((totalSkewSize / target.scaleX), (dimNoSkew.y / target.scaleY))\n );\n // now we have to find the sign of the skew.\n // it mostly depend on the origin of transformation.\n if (transform.originX === LEFT && transform.originY === BOTTOM) {\n newSkew = -newSkew;\n }\n if (transform.originX === RIGHT && transform.originY === TOP) {\n newSkew = -newSkew;\n }\n if (targetHasOneFlip(target)) {\n newSkew = -newSkew;\n }\n }\n var hasSkewed = currentSkew !== newSkew;\n if (hasSkewed) {\n var dimBeforeSkewing = target._getTransformedDimensions().y;\n target.set('skewX', newSkew);\n compensateScaleForSkew(target, 'skewY', 'scaleY', 'y', dimBeforeSkewing);\n fireEvent('skewing', commonEventInfo(eventData, transform, x, y));\n }\n return hasSkewed;\n }\n\n /**\n * Action handler for skewing on the Y axis\n * @private\n */\n function skewObjectY(eventData, transform, x, y) {\n var target = transform.target,\n // find how big the object would be, if there was no skewX. takes in account scaling\n dimNoSkew = target._getTransformedDimensions(target.skewX, 0),\n localPoint = getLocalPoint(transform, transform.originX, transform.originY, x, y),\n // the mouse is in the center of the object, and we want it to stay there.\n // so the object will grow twice as much as the mouse.\n // this makes the skew growth to localPoint * 2 - dimNoSkew.\n totalSkewSize = Math.abs(localPoint.y * 2) - dimNoSkew.y,\n currentSkew = target.skewY, newSkew;\n if (totalSkewSize < 2) {\n // let's make it easy to go back to position 0.\n newSkew = 0;\n }\n else {\n newSkew = radiansToDegrees(\n Math.atan2((totalSkewSize / target.scaleY), (dimNoSkew.x / target.scaleX))\n );\n // now we have to find the sign of the skew.\n // it mostly depend on the origin of transformation.\n if (transform.originX === LEFT && transform.originY === BOTTOM) {\n newSkew = -newSkew;\n }\n if (transform.originX === RIGHT && transform.originY === TOP) {\n newSkew = -newSkew;\n }\n if (targetHasOneFlip(target)) {\n newSkew = -newSkew;\n }\n }\n var hasSkewed = currentSkew !== newSkew;\n if (hasSkewed) {\n var dimBeforeSkewing = target._getTransformedDimensions().x;\n target.set('skewY', newSkew);\n compensateScaleForSkew(target, 'skewX', 'scaleX', 'x', dimBeforeSkewing);\n fireEvent('skewing', commonEventInfo(eventData, transform, x, y));\n }\n return hasSkewed;\n }\n\n /**\n * Wrapped Action handler for skewing on the Y axis, takes care of the\n * skew direction and determine the correct transform origin for the anchor point\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @return {Boolean} true if some change happened\n */\n function skewHandlerX(eventData, transform, x, y) {\n // step1 figure out and change transform origin.\n // if skewX > 0 and originY bottom we anchor on right\n // if skewX > 0 and originY top we anchor on left\n // if skewX < 0 and originY bottom we anchor on left\n // if skewX < 0 and originY top we anchor on right\n // if skewX is 0, we look for mouse position to understand where are we going.\n var target = transform.target, currentSkew = target.skewX, originX, originY = transform.originY;\n if (target.lockSkewingX) {\n return false;\n }\n if (currentSkew === 0) {\n var localPointFromCenter = getLocalPoint(transform, CENTER, CENTER, x, y);\n if (localPointFromCenter.x > 0) {\n // we are pulling right, anchor left;\n originX = LEFT;\n }\n else {\n // we are pulling right, anchor right\n originX = RIGHT;\n }\n }\n else {\n if (currentSkew > 0) {\n originX = originY === TOP ? LEFT : RIGHT;\n }\n if (currentSkew < 0) {\n originX = originY === TOP ? RIGHT : LEFT;\n }\n // is the object flipped on one side only? swap the origin.\n if (targetHasOneFlip(target)) {\n originX = originX === LEFT ? RIGHT : LEFT;\n }\n }\n\n // once we have the origin, we find the anchor point\n transform.originX = originX;\n var finalHandler = wrapWithFixedAnchor(skewObjectX);\n return finalHandler(eventData, transform, x, y);\n }\n\n /**\n * Wrapped Action handler for skewing on the Y axis, takes care of the\n * skew direction and determine the correct transform origin for the anchor point\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @return {Boolean} true if some change happened\n */\n function skewHandlerY(eventData, transform, x, y) {\n // step1 figure out and change transform origin.\n // if skewY > 0 and originX left we anchor on top\n // if skewY > 0 and originX right we anchor on bottom\n // if skewY < 0 and originX left we anchor on bottom\n // if skewY < 0 and originX right we anchor on top\n // if skewY is 0, we look for mouse position to understand where are we going.\n var target = transform.target, currentSkew = target.skewY, originY, originX = transform.originX;\n if (target.lockSkewingY) {\n return false;\n }\n if (currentSkew === 0) {\n var localPointFromCenter = getLocalPoint(transform, CENTER, CENTER, x, y);\n if (localPointFromCenter.y > 0) {\n // we are pulling down, anchor up;\n originY = TOP;\n }\n else {\n // we are pulling up, anchor down\n originY = BOTTOM;\n }\n }\n else {\n if (currentSkew > 0) {\n originY = originX === LEFT ? TOP : BOTTOM;\n }\n if (currentSkew < 0) {\n originY = originX === LEFT ? BOTTOM : TOP;\n }\n // is the object flipped on one side only? swap the origin.\n if (targetHasOneFlip(target)) {\n originY = originY === TOP ? BOTTOM : TOP;\n }\n }\n\n // once we have the origin, we find the anchor point\n transform.originY = originY;\n var finalHandler = wrapWithFixedAnchor(skewObjectY);\n return finalHandler(eventData, transform, x, y);\n }\n\n /**\n * Action handler for rotation and snapping, without anchor point.\n * Needs to be wrapped with `wrapWithFixedAnchor` to be effective\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @return {Boolean} true if some change happened\n * @private\n */\n function rotationWithSnapping(eventData, transform, x, y) {\n var t = transform,\n target = t.target,\n pivotPoint = target.translateToOriginPoint(target.getCenterPoint(), t.originX, t.originY);\n\n if (target.lockRotation) {\n return false;\n }\n\n var lastAngle = Math.atan2(t.ey - pivotPoint.y, t.ex - pivotPoint.x),\n curAngle = Math.atan2(y - pivotPoint.y, x - pivotPoint.x),\n angle = radiansToDegrees(curAngle - lastAngle + t.theta),\n hasRotated = true;\n\n if (target.snapAngle > 0) {\n var snapAngle = target.snapAngle,\n snapThreshold = target.snapThreshold || snapAngle,\n rightAngleLocked = Math.ceil(angle / snapAngle) * snapAngle,\n leftAngleLocked = Math.floor(angle / snapAngle) * snapAngle;\n\n if (Math.abs(angle - leftAngleLocked) < snapThreshold) {\n angle = leftAngleLocked;\n }\n else if (Math.abs(angle - rightAngleLocked) < snapThreshold) {\n angle = rightAngleLocked;\n }\n }\n\n // normalize angle to positive value\n if (angle < 0) {\n angle = 360 + angle;\n }\n angle %= 360;\n\n hasRotated = target.angle !== angle;\n target.angle = angle;\n if (hasRotated) {\n fireEvent('rotating', commonEventInfo(eventData, transform, x, y));\n }\n return hasRotated;\n }\n\n /**\n * Basic scaling logic, reused with different constrain for scaling X,Y, freely or equally.\n * Needs to be wrapped with `wrapWithFixedAnchor` to be effective\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @param {Object} options additional information for scaling\n * @param {String} options.by 'x', 'y', 'equally' or '' to indicate type of scaling\n * @return {Boolean} true if some change happened\n * @private\n */\n function scaleObject(eventData, transform, x, y, options) {\n options = options || {};\n var target = transform.target,\n lockScalingX = target.lockScalingX, lockScalingY = target.lockScalingY,\n by = options.by, newPoint, scaleX, scaleY, dim,\n scaleProportionally = scaleIsProportional(eventData, target),\n forbidScaling = scalingIsForbidden(target, by, scaleProportionally),\n signX, signY, gestureScale = transform.gestureScale;\n\n if (forbidScaling) {\n return false;\n }\n if (gestureScale) {\n scaleX = transform.scaleX * gestureScale;\n scaleY = transform.scaleY * gestureScale;\n }\n else {\n newPoint = getLocalPoint(transform, transform.originX, transform.originY, x, y);\n // use of sign: We use sign to detect change of direction of an action. sign usually change when\n // we cross the origin point with the mouse. So a scale flip for example. There is an issue when scaling\n // by center and scaling using one middle control ( default: mr, mt, ml, mb), the mouse movement can easily\n // cross many time the origin point and flip the object. so we need a way to filter out the noise.\n // This ternary here should be ok to filter out X scaling when we want Y only and vice versa.\n signX = by !== 'y' ? sign(newPoint.x) : 1;\n signY = by !== 'x' ? sign(newPoint.y) : 1;\n if (!transform.signX) {\n transform.signX = signX;\n }\n if (!transform.signY) {\n transform.signY = signY;\n }\n\n if (target.lockScalingFlip &&\n (transform.signX !== signX || transform.signY !== signY)\n ) {\n return false;\n }\n\n dim = target._getTransformedDimensions();\n // missing detection of flip and logic to switch the origin\n if (scaleProportionally && !by) {\n // uniform scaling\n var distance = Math.abs(newPoint.x) + Math.abs(newPoint.y),\n original = transform.original,\n originalDistance = Math.abs(dim.x * original.scaleX / target.scaleX) +\n Math.abs(dim.y * original.scaleY / target.scaleY),\n scale = distance / originalDistance, hasScaled;\n scaleX = original.scaleX * scale;\n scaleY = original.scaleY * scale;\n }\n else {\n scaleX = Math.abs(newPoint.x * target.scaleX / dim.x);\n scaleY = Math.abs(newPoint.y * target.scaleY / dim.y);\n }\n // if we are scaling by center, we need to double the scale\n if (isTransformCentered(transform)) {\n scaleX *= 2;\n scaleY *= 2;\n }\n if (transform.signX !== signX && by !== 'y') {\n transform.originX = opposite[transform.originX];\n scaleX *= -1;\n transform.signX = signX;\n }\n if (transform.signY !== signY && by !== 'x') {\n transform.originY = opposite[transform.originY];\n scaleY *= -1;\n transform.signY = signY;\n }\n }\n // minScale is taken are in the setter.\n var oldScaleX = target.scaleX, oldScaleY = target.scaleY;\n if (!by) {\n !lockScalingX && target.set('scaleX', scaleX);\n !lockScalingY && target.set('scaleY', scaleY);\n }\n else {\n // forbidden cases already handled on top here.\n by === 'x' && target.set('scaleX', scaleX);\n by === 'y' && target.set('scaleY', scaleY);\n }\n hasScaled = oldScaleX !== target.scaleX || oldScaleY !== target.scaleY;\n if (hasScaled) {\n fireEvent('scaling', commonEventInfo(eventData, transform, x, y));\n }\n return hasScaled;\n }\n\n /**\n * Generic scaling logic, to scale from corners either equally or freely.\n * Needs to be wrapped with `wrapWithFixedAnchor` to be effective\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @return {Boolean} true if some change happened\n */\n function scaleObjectFromCorner(eventData, transform, x, y) {\n return scaleObject(eventData, transform, x, y);\n }\n\n /**\n * Scaling logic for the X axis.\n * Needs to be wrapped with `wrapWithFixedAnchor` to be effective\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @return {Boolean} true if some change happened\n */\n function scaleObjectX(eventData, transform, x, y) {\n return scaleObject(eventData, transform, x, y , { by: 'x' });\n }\n\n /**\n * Scaling logic for the Y axis.\n * Needs to be wrapped with `wrapWithFixedAnchor` to be effective\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @return {Boolean} true if some change happened\n */\n function scaleObjectY(eventData, transform, x, y) {\n return scaleObject(eventData, transform, x, y , { by: 'y' });\n }\n\n /**\n * Composed action handler to either scale Y or skew X\n * Needs to be wrapped with `wrapWithFixedAnchor` to be effective\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @return {Boolean} true if some change happened\n */\n function scalingYOrSkewingX(eventData, transform, x, y) {\n // ok some safety needed here.\n if (eventData[transform.target.canvas.altActionKey]) {\n return controls.skewHandlerX(eventData, transform, x, y);\n }\n return controls.scalingY(eventData, transform, x, y);\n }\n\n /**\n * Composed action handler to either scale X or skew Y\n * Needs to be wrapped with `wrapWithFixedAnchor` to be effective\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @return {Boolean} true if some change happened\n */\n function scalingXOrSkewingY(eventData, transform, x, y) {\n // ok some safety needed here.\n if (eventData[transform.target.canvas.altActionKey]) {\n return controls.skewHandlerY(eventData, transform, x, y);\n }\n return controls.scalingX(eventData, transform, x, y);\n }\n\n /**\n * Action handler to change textbox width\n * Needs to be wrapped with `wrapWithFixedAnchor` to be effective\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @return {Boolean} true if some change happened\n */\n function changeWidth(eventData, transform, x, y) {\n var target = transform.target, localPoint = getLocalPoint(transform, transform.originX, transform.originY, x, y),\n strokePadding = target.strokeWidth / (target.strokeUniform ? target.scaleX : 1),\n multiplier = isTransformCentered(transform) ? 2 : 1,\n oldWidth = target.width, hasResized,\n newWidth = Math.abs(localPoint.x * multiplier / target.scaleX) - strokePadding;\n target.set('width', Math.max(newWidth, 0));\n hasResized = oldWidth !== newWidth;\n if (hasResized) {\n fireEvent('resizing', commonEventInfo(eventData, transform, x, y));\n }\n return hasResized;\n }\n\n /**\n * Action handler\n * @private\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @return {Boolean} true if the translation occurred\n */\n function dragHandler(eventData, transform, x, y) {\n var target = transform.target,\n newLeft = x - transform.offsetX,\n newTop = y - transform.offsetY,\n moveX = !target.get('lockMovementX') && target.left !== newLeft,\n moveY = !target.get('lockMovementY') && target.top !== newTop;\n moveX && target.set('left', newLeft);\n moveY && target.set('top', newTop);\n if (moveX || moveY) {\n fireEvent('moving', commonEventInfo(eventData, transform, x, y));\n }\n return moveX || moveY;\n }\n\n controls.scaleCursorStyleHandler = scaleCursorStyleHandler;\n controls.skewCursorStyleHandler = skewCursorStyleHandler;\n controls.scaleSkewCursorStyleHandler = scaleSkewCursorStyleHandler;\n controls.rotationWithSnapping = wrapWithFixedAnchor(rotationWithSnapping);\n controls.scalingEqually = wrapWithFixedAnchor(scaleObjectFromCorner);\n controls.scalingX = wrapWithFixedAnchor(scaleObjectX);\n controls.scalingY = wrapWithFixedAnchor(scaleObjectY);\n controls.scalingYOrSkewingX = scalingYOrSkewingX;\n controls.scalingXOrSkewingY = scalingXOrSkewingY;\n controls.changeWidth = wrapWithFixedAnchor(changeWidth);\n controls.skewHandlerX = skewHandlerX;\n controls.skewHandlerY = skewHandlerY;\n controls.dragHandler = dragHandler;\n controls.scaleOrSkewActionName = scaleOrSkewActionName;\n controls.rotationStyleHandler = rotationStyleHandler;\n controls.fireEvent = fireEvent;\n controls.wrapWithFixedAnchor = wrapWithFixedAnchor;\n controls.getLocalPoint = getLocalPoint;\n fabric.controlsUtils = controls;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n degreesToRadians = fabric.util.degreesToRadians,\n controls = fabric.controlsUtils;\n\n /**\n * Render a round control, as per fabric features.\n * This function is written to respect object properties like transparentCorners, cornerSize\n * cornerColor, cornerStrokeColor\n * plus the addition of offsetY and offsetX.\n * @param {CanvasRenderingContext2D} ctx context to render on\n * @param {Number} left x coordinate where the control center should be\n * @param {Number} top y coordinate where the control center should be\n * @param {Object} styleOverride override for fabric.Object controls style\n * @param {fabric.Object} fabricObject the fabric object for which we are rendering controls\n */\n function renderCircleControl (ctx, left, top, styleOverride, fabricObject) {\n styleOverride = styleOverride || {};\n var size = styleOverride.cornerSize || fabricObject.cornerSize,\n transparentCorners = typeof styleOverride.transparentCorners !== 'undefined' ?\n styleOverride.transparentCorners : this.transparentCorners,\n methodName = transparentCorners ? 'stroke' : 'fill',\n stroke = !transparentCorners && (styleOverride.cornerStrokeColor || fabricObject.cornerStrokeColor);\n ctx.save();\n ctx.fillStyle = styleOverride.cornerColor || fabricObject.cornerColor;\n ctx.strokeStyle = styleOverride.cornerStrokeColor || fabricObject.cornerStrokeColor;\n // this is still wrong\n ctx.lineWidth = 1;\n ctx.beginPath();\n ctx.arc(left, top, size / 2, 0, 2 * Math.PI, false);\n ctx[methodName]();\n if (stroke) {\n ctx.stroke();\n }\n ctx.restore();\n }\n\n /**\n * Render a square control, as per fabric features.\n * This function is written to respect object properties like transparentCorners, cornerSize\n * cornerColor, cornerStrokeColor\n * plus the addition of offsetY and offsetX.\n * @param {CanvasRenderingContext2D} ctx context to render on\n * @param {Number} left x coordinate where the control center should be\n * @param {Number} top y coordinate where the control center should be\n * @param {Object} styleOverride override for fabric.Object controls style\n * @param {fabric.Object} fabricObject the fabric object for which we are rendering controls\n */\n function renderSquareControl(ctx, left, top, styleOverride, fabricObject) {\n styleOverride = styleOverride || {};\n var size = styleOverride.cornerSize || fabricObject.cornerSize,\n transparentCorners = typeof styleOverride.transparentCorners !== 'undefined' ?\n styleOverride.transparentCorners : fabricObject.transparentCorners,\n methodName = transparentCorners ? 'stroke' : 'fill',\n stroke = !transparentCorners && (\n styleOverride.cornerStrokeColor || fabricObject.cornerStrokeColor\n ), sizeBy2 = size / 2;\n ctx.save();\n ctx.fillStyle = styleOverride.cornerColor || fabricObject.cornerColor;\n ctx.strokeStyle = styleOverride.strokeCornerColor || fabricObject.strokeCornerColor;\n // this is still wrong\n ctx.lineWidth = 1;\n ctx.translate(left, top);\n ctx.rotate(degreesToRadians(fabricObject.angle));\n // this does not work, and fixed with ( && ) does not make sense.\n // to have real transparent corners we need the controls on upperCanvas\n // transparentCorners || ctx.clearRect(-sizeBy2, -sizeBy2, size, size);\n ctx[methodName + 'Rect'](-sizeBy2, -sizeBy2, size, size);\n if (stroke) {\n ctx.strokeRect(-sizeBy2, -sizeBy2, size, size);\n }\n ctx.restore();\n }\n\n controls.renderCircleControl = renderCircleControl;\n controls.renderSquareControl = renderSquareControl;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { });\n\n function Control(options) {\n for (var i in options) {\n this[i] = options[i];\n }\n }\n\n fabric.Control = Control;\n\n fabric.Control.prototype = /** @lends fabric.Control.prototype */ {\n\n /**\n * keep track of control visibility.\n * mainly for backward compatibility.\n * if you do not want to see a control, you can remove it\n * from the controlset.\n * @type {Boolean}\n * @default true\n */\n visible: true,\n\n /**\n * Name of the action that the controll will likely execute.\n * This is optional. FabricJS uses to identify what the user is doing for some\n * extra optimizations. If you are writing a custom control and you want to know\n * somewhere else in the code what is going on, you can use this string here.\n * you can also provide a custom getActionName if your control run multiple actions\n * depending on some external state.\n * default to scale since is the most common, used on 4 corners by default\n * @type {String}\n * @default 'scale'\n */\n actionName: 'scale',\n\n /**\n * Drawing angle of the control.\n * NOT used for now, but name marked as needed for internal logic\n * example: to reuse the same drawing function for different rotated controls\n * @type {Number}\n * @default 0\n */\n angle: 0,\n\n /**\n * Relative position of the control. X\n * 0,0 is the center of the Object, while -0.5 (left) or 0.5 (right) are the extremities\n * of the bounding box.\n * @type {Number}\n * @default 0\n */\n x: 0,\n\n /**\n * Relative position of the control. Y\n * 0,0 is the center of the Object, while -0.5 (top) or 0.5 (bottom) are the extremities\n * of the bounding box.\n * @type {Number}\n * @default 0\n */\n y: 0,\n\n /**\n * Horizontal offset of the control from the defined position. In pixels\n * Positive offset moves the control to the right, negative to the left.\n * It used when you want to have position of control that does not scale with\n * the bounding box. Example: rotation control is placed at x:0, y: 0.5 on\n * the boundindbox, with an offset of 30 pixels vertivally. Those 30 pixels will\n * stay 30 pixels no matter how the object is big. Another example is having 2\n * controls in the corner, that stay in the same position when the object scale.\n * of the bounding box.\n * @type {Number}\n * @default 0\n */\n offsetX: 0,\n\n /**\n * Vertical offset of the control from the defined position. In pixels\n * Positive offset moves the control to the bottom, negative to the top.\n * @type {Number}\n * @default 0\n */\n offsetY: 0,\n\n /**\n * Css cursor style to display when the control is hovered.\n * if the method `cursorStyleHandler` is provided, this property is ignored.\n * @type {String}\n * @default 'crosshair'\n */\n cursorStyle: 'crosshair',\n\n /**\n * If controls has an offsetY or offsetX, draw a line that connects\n * the control to the bounding box\n * @type {Boolean}\n * @default false\n */\n withConnection: false,\n\n /**\n * The control actionHandler, provide one to handle action ( control being moved )\n * @param {Event} eventData the native mouse event\n * @param {Object} transformData properties of the current transform\n * @param {fabric.Object} object on which the control is displayed\n * @return {Function}\n */\n actionHandler: function(/* eventData, transformData, fabricObject */) { },\n\n /**\n * The control handler for mouse down, provide one to handle mouse down on control\n * @param {Event} eventData the native mouse event\n * @param {Object} transformData properties of the current transform\n * @param {fabric.Object} object on which the control is displayed\n * @return {Function}\n */\n mouseDownHandler: function(/* eventData, transformData, fabricObject */) { },\n\n /**\n * The control mouseUpHandler, provide one to handle an effect on mouse up.\n * @param {Event} eventData the native mouse event\n * @param {Object} transformData properties of the current transform\n * @param {fabric.Object} object on which the control is displayed\n * @return {Function}\n */\n mouseUpHandler: function(/* eventData, transformData, fabricObject */) { },\n\n /**\n * Returns control actionHandler\n * @param {Event} eventData the native mouse event\n * @param {Object} transformData properties of the current transform\n * @param {fabric.Object} object on which the control is displayed\n * @return {Function}\n */\n getActionHandler: function(/* eventData, transformData, fabricObject */) {\n return this.actionHandler;\n },\n\n /**\n * Returns control mouseDown handler\n * @param {Event} eventData the native mouse event\n * @param {Object} transformData properties of the current transform\n * @param {fabric.Object} object on which the control is displayed\n * @return {Function}\n */\n getMouseDownHandler: function(/* eventData, fabricObject, control */) {\n return this.mouseDownHandler;\n },\n\n /**\n * Returns control mouseUp handler\n * @param {Event} eventData the native mouse event\n * @param {Object} transformData properties of the current transform\n * @param {fabric.Object} object on which the control is displayed\n * @return {Function}\n */\n getMouseUpHandler: function(/* eventData, fabricObject, control */) {\n return this.mouseUpHandler;\n },\n\n /**\n * Returns control cursorStyle for css using cursorStyle. If you need a more elaborate\n * function you can pass one in the constructor\n * the cursorStyle property\n * @param {Event} eventData the native mouse event\n * @param {fabric.Control} control the current control ( likely this)\n * @param {fabric.Object} object on which the control is displayed\n * @return {String}\n */\n cursorStyleHandler: function(eventData, control /* fabricObject */) {\n return control.cursorStyle;\n },\n\n /**\n * Returns the action name. The basic implementation just return the actionName property.\n * @param {Event} eventData the native mouse event\n * @param {fabric.Control} control the current control ( likely this)\n * @param {fabric.Object} object on which the control is displayed\n * @return {String}\n */\n getActionName: function(eventData, control /* fabricObject */) {\n return control.actionName;\n },\n\n /**\n * Returns controls visibility\n * @param {fabric.Object} object on which the control is displayed\n * @param {String} controlKey key where the control is memorized on the\n * @return {Boolean}\n */\n getVisibility: function(fabricObject, controlKey) {\n var objectVisibility = fabricObject._controlsVisibility;\n if (objectVisibility && typeof objectVisibility[controlKey] !== 'undefined') {\n return objectVisibility[controlKey];\n }\n return this.visible;\n },\n\n /**\n * Sets controls visibility\n * @param {Boolean} visibility for the object\n * @return {Void}\n */\n setVisibility: function(visibility /* name, fabricObject */) {\n this.visible = visibility;\n },\n\n\n positionHandler: function(dim, finalMatrix /*, fabricObject, currentControl */) {\n var point = fabric.util.transformPoint({\n x: this.x * dim.x + this.offsetX,\n y: this.y * dim.y + this.offsetY }, finalMatrix);\n return point;\n },\n\n /**\n * Render function for the control.\n * When this function runs the context is unscaled. unrotate. Just retina scaled.\n * all the functions will have to translate to the point left,top before starting Drawing\n * if they want to draw a control where the position is detected.\n * left and top are the result of the positionHandler function\n * @param {RenderingContext2D} ctx the context where the control will be drawn\n * @param {Number} left position of the canvas where we are about to render the control.\n * @param {Number} top position of the canvas where we are about to render the control.\n * @param {Object} styleOverride\n * @param {fabric.Object} fabricObject the object where the control is about to be rendered\n */\n render: function(ctx, left, top, styleOverride, fabricObject) {\n styleOverride = styleOverride || {};\n switch (styleOverride.cornerStyle || fabricObject.cornerStyle) {\n case 'circle':\n fabric.controlsUtils.renderCircleControl.call(this, ctx, left, top, styleOverride, fabricObject);\n break;\n default:\n fabric.controlsUtils.renderSquareControl.call(this, ctx, left, top, styleOverride, fabricObject);\n }\n },\n };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function() {\n\n /* _FROM_SVG_START_ */\n function getColorStop(el, multiplier) {\n var style = el.getAttribute('style'),\n offset = el.getAttribute('offset') || 0,\n color, colorAlpha, opacity, i;\n\n // convert percents to absolute values\n offset = parseFloat(offset) / (/%$/.test(offset) ? 100 : 1);\n offset = offset < 0 ? 0 : offset > 1 ? 1 : offset;\n if (style) {\n var keyValuePairs = style.split(/\\s*;\\s*/);\n\n if (keyValuePairs[keyValuePairs.length - 1] === '') {\n keyValuePairs.pop();\n }\n\n for (i = keyValuePairs.length; i--; ) {\n\n var split = keyValuePairs[i].split(/\\s*:\\s*/),\n key = split[0].trim(),\n value = split[1].trim();\n\n if (key === 'stop-color') {\n color = value;\n }\n else if (key === 'stop-opacity') {\n opacity = value;\n }\n }\n }\n\n if (!color) {\n color = el.getAttribute('stop-color') || 'rgb(0,0,0)';\n }\n if (!opacity) {\n opacity = el.getAttribute('stop-opacity');\n }\n\n color = new fabric.Color(color);\n colorAlpha = color.getAlpha();\n opacity = isNaN(parseFloat(opacity)) ? 1 : parseFloat(opacity);\n opacity *= colorAlpha * multiplier;\n\n return {\n offset: offset,\n color: color.toRgb(),\n opacity: opacity\n };\n }\n\n function getLinearCoords(el) {\n return {\n x1: el.getAttribute('x1') || 0,\n y1: el.getAttribute('y1') || 0,\n x2: el.getAttribute('x2') || '100%',\n y2: el.getAttribute('y2') || 0\n };\n }\n\n function getRadialCoords(el) {\n return {\n x1: el.getAttribute('fx') || el.getAttribute('cx') || '50%',\n y1: el.getAttribute('fy') || el.getAttribute('cy') || '50%',\n r1: 0,\n x2: el.getAttribute('cx') || '50%',\n y2: el.getAttribute('cy') || '50%',\n r2: el.getAttribute('r') || '50%'\n };\n }\n /* _FROM_SVG_END_ */\n\n var clone = fabric.util.object.clone;\n\n /**\n * Gradient class\n * @class fabric.Gradient\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#gradients}\n * @see {@link fabric.Gradient#initialize} for constructor definition\n */\n fabric.Gradient = fabric.util.createClass(/** @lends fabric.Gradient.prototype */ {\n\n /**\n * Horizontal offset for aligning gradients coming from SVG when outside pathgroups\n * @type Number\n * @default 0\n */\n offsetX: 0,\n\n /**\n * Vertical offset for aligning gradients coming from SVG when outside pathgroups\n * @type Number\n * @default 0\n */\n offsetY: 0,\n\n /**\n * A transform matrix to apply to the gradient before painting.\n * Imported from svg gradients, is not applied with the current transform in the center.\n * Before this transform is applied, the origin point is at the top left corner of the object\n * plus the addition of offsetY and offsetX.\n * @type Number[]\n * @default null\n */\n gradientTransform: null,\n\n /**\n * coordinates units for coords.\n * If `pixels`, the number of coords are in the same unit of width / height.\n * If set as `percentage` the coords are still a number, but 1 means 100% of width\n * for the X and 100% of the height for the y. It can be bigger than 1 and negative.\n * allowed values pixels or percentage.\n * @type String\n * @default 'pixels'\n */\n gradientUnits: 'pixels',\n\n /**\n * Gradient type linear or radial\n * @type String\n * @default 'pixels'\n */\n type: 'linear',\n\n /**\n * Constructor\n * @param {Object} options Options object with type, coords, gradientUnits and colorStops\n * @param {Object} [options.type] gradient type linear or radial\n * @param {Object} [options.gradientUnits] gradient units\n * @param {Object} [options.offsetX] SVG import compatibility\n * @param {Object} [options.offsetY] SVG import compatibility\n * @param {Object[]} options.colorStops contains the colorstops.\n * @param {Object} options.coords contains the coords of the gradient\n * @param {Number} [options.coords.x1] X coordiante of the first point for linear or of the focal point for radial\n * @param {Number} [options.coords.y1] Y coordiante of the first point for linear or of the focal point for radial\n * @param {Number} [options.coords.x2] X coordiante of the second point for linear or of the center point for radial\n * @param {Number} [options.coords.y2] Y coordiante of the second point for linear or of the center point for radial\n * @param {Number} [options.coords.r1] only for radial gradient, radius of the inner circle\n * @param {Number} [options.coords.r2] only for radial gradient, radius of the external circle\n * @return {fabric.Gradient} thisArg\n */\n initialize: function(options) {\n options || (options = { });\n options.coords || (options.coords = { });\n\n var coords, _this = this;\n\n // sets everything, then coords and colorstops get sets again\n Object.keys(options).forEach(function(option) {\n _this[option] = options[option];\n });\n\n if (this.id) {\n this.id += '_' + fabric.Object.__uid++;\n }\n else {\n this.id = fabric.Object.__uid++;\n }\n\n coords = {\n x1: options.coords.x1 || 0,\n y1: options.coords.y1 || 0,\n x2: options.coords.x2 || 0,\n y2: options.coords.y2 || 0\n };\n\n if (this.type === 'radial') {\n coords.r1 = options.coords.r1 || 0;\n coords.r2 = options.coords.r2 || 0;\n }\n\n this.coords = coords;\n this.colorStops = options.colorStops.slice();\n },\n\n /**\n * Adds another colorStop\n * @param {Object} colorStop Object with offset and color\n * @return {fabric.Gradient} thisArg\n */\n addColorStop: function(colorStops) {\n for (var position in colorStops) {\n var color = new fabric.Color(colorStops[position]);\n this.colorStops.push({\n offset: parseFloat(position),\n color: color.toRgb(),\n opacity: color.getAlpha()\n });\n }\n return this;\n },\n\n /**\n * Returns object representation of a gradient\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object}\n */\n toObject: function(propertiesToInclude) {\n var object = {\n type: this.type,\n coords: this.coords,\n colorStops: this.colorStops,\n offsetX: this.offsetX,\n offsetY: this.offsetY,\n gradientUnits: this.gradientUnits,\n gradientTransform: this.gradientTransform ? this.gradientTransform.concat() : this.gradientTransform\n };\n fabric.util.populateWithProperties(this, object, propertiesToInclude);\n\n return object;\n },\n\n /* _TO_SVG_START_ */\n /**\n * Returns SVG representation of an gradient\n * @param {Object} object Object to create a gradient for\n * @return {String} SVG representation of an gradient (linear/radial)\n */\n toSVG: function(object, options) {\n var coords = clone(this.coords, true), i, len, options = options || {},\n markup, commonAttributes, colorStops = clone(this.colorStops, true),\n needsSwap = coords.r1 > coords.r2,\n transform = this.gradientTransform ? this.gradientTransform.concat() : fabric.iMatrix.concat(),\n offsetX = -this.offsetX, offsetY = -this.offsetY,\n withViewport = !!options.additionalTransform,\n gradientUnits = this.gradientUnits === 'pixels' ? 'userSpaceOnUse' : 'objectBoundingBox';\n // colorStops must be sorted ascending\n colorStops.sort(function(a, b) {\n return a.offset - b.offset;\n });\n\n if (gradientUnits === 'objectBoundingBox') {\n offsetX /= object.width;\n offsetY /= object.height;\n }\n else {\n offsetX += object.width / 2;\n offsetY += object.height / 2;\n }\n if (object.type === 'path') {\n offsetX -= object.pathOffset.x;\n offsetY -= object.pathOffset.y;\n }\n\n\n transform[4] -= offsetX;\n transform[5] -= offsetY;\n\n commonAttributes = 'id=\"SVGID_' + this.id +\n '\" gradientUnits=\"' + gradientUnits + '\"';\n commonAttributes += ' gradientTransform=\"' + (withViewport ?\n options.additionalTransform + ' ' : '') + fabric.util.matrixToSVG(transform) + '\" ';\n\n if (this.type === 'linear') {\n markup = [\n '<linearGradient ',\n commonAttributes,\n ' x1=\"', coords.x1,\n '\" y1=\"', coords.y1,\n '\" x2=\"', coords.x2,\n '\" y2=\"', coords.y2,\n '\">\\n'\n ];\n }\n else if (this.type === 'radial') {\n // svg radial gradient has just 1 radius. the biggest.\n markup = [\n '<radialGradient ',\n commonAttributes,\n ' cx=\"', needsSwap ? coords.x1 : coords.x2,\n '\" cy=\"', needsSwap ? coords.y1 : coords.y2,\n '\" r=\"', needsSwap ? coords.r1 : coords.r2,\n '\" fx=\"', needsSwap ? coords.x2 : coords.x1,\n '\" fy=\"', needsSwap ? coords.y2 : coords.y1,\n '\">\\n'\n ];\n }\n\n if (this.type === 'radial') {\n if (needsSwap) {\n // svg goes from internal to external radius. if radius are inverted, swap color stops.\n colorStops = colorStops.concat();\n colorStops.reverse();\n for (i = 0, len = colorStops.length; i < len; i++) {\n colorStops[i].offset = 1 - colorStops[i].offset;\n }\n }\n var minRadius = Math.min(coords.r1, coords.r2);\n if (minRadius > 0) {\n // i have to shift all colorStops and add new one in 0.\n var maxRadius = Math.max(coords.r1, coords.r2),\n percentageShift = minRadius / maxRadius;\n for (i = 0, len = colorStops.length; i < len; i++) {\n colorStops[i].offset += percentageShift * (1 - colorStops[i].offset);\n }\n }\n }\n\n for (i = 0, len = colorStops.length; i < len; i++) {\n var colorStop = colorStops[i];\n markup.push(\n '<stop ',\n 'offset=\"', (colorStop.offset * 100) + '%',\n '\" style=\"stop-color:', colorStop.color,\n (typeof colorStop.opacity !== 'undefined' ? ';stop-opacity: ' + colorStop.opacity : ';'),\n '\"/>\\n'\n );\n }\n\n markup.push((this.type === 'linear' ? '</linearGradient>\\n' : '</radialGradient>\\n'));\n\n return markup.join('');\n },\n /* _TO_SVG_END_ */\n\n /**\n * Returns an instance of CanvasGradient\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @return {CanvasGradient}\n */\n toLive: function(ctx) {\n var gradient, coords = fabric.util.object.clone(this.coords), i, len;\n\n if (!this.type) {\n return;\n }\n\n if (this.type === 'linear') {\n gradient = ctx.createLinearGradient(\n coords.x1, coords.y1, coords.x2, coords.y2);\n }\n else if (this.type === 'radial') {\n gradient = ctx.createRadialGradient(\n coords.x1, coords.y1, coords.r1, coords.x2, coords.y2, coords.r2);\n }\n\n for (i = 0, len = this.colorStops.length; i < len; i++) {\n var color = this.colorStops[i].color,\n opacity = this.colorStops[i].opacity,\n offset = this.colorStops[i].offset;\n\n if (typeof opacity !== 'undefined') {\n color = new fabric.Color(color).setAlpha(opacity).toRgba();\n }\n gradient.addColorStop(offset, color);\n }\n\n return gradient;\n }\n });\n\n fabric.util.object.extend(fabric.Gradient, {\n\n /* _FROM_SVG_START_ */\n /**\n * Returns {@link fabric.Gradient} instance from an SVG element\n * @static\n * @memberOf fabric.Gradient\n * @param {SVGGradientElement} el SVG gradient element\n * @param {fabric.Object} instance\n * @param {String} opacityAttr A fill-opacity or stroke-opacity attribute to multiply to each stop's opacity.\n * @param {Object} svgOptions an object containing the size of the SVG in order to parse correctly graidents\n * that uses gradientUnits as 'userSpaceOnUse' and percentages.\n * @param {Object.number} viewBoxWidth width part of the viewBox attribute on svg\n * @param {Object.number} viewBoxHeight height part of the viewBox attribute on svg\n * @param {Object.number} width width part of the svg tag if viewBox is not specified\n * @param {Object.number} height height part of the svg tag if viewBox is not specified\n * @return {fabric.Gradient} Gradient instance\n * @see http://www.w3.org/TR/SVG/pservers.html#LinearGradientElement\n * @see http://www.w3.org/TR/SVG/pservers.html#RadialGradientElement\n */\n fromElement: function(el, instance, opacityAttr, svgOptions) {\n /**\n * @example:\n *\n * <linearGradient id=\"linearGrad1\">\n * <stop offset=\"0%\" stop-color=\"white\"/>\n * <stop offset=\"100%\" stop-color=\"black\"/>\n * </linearGradient>\n *\n * OR\n *\n * <linearGradient id=\"linearGrad2\">\n * <stop offset=\"0\" style=\"stop-color:rgb(255,255,255)\"/>\n * <stop offset=\"1\" style=\"stop-color:rgb(0,0,0)\"/>\n * </linearGradient>\n *\n * OR\n *\n * <radialGradient id=\"radialGrad1\">\n * <stop offset=\"0%\" stop-color=\"white\" stop-opacity=\"1\" />\n * <stop offset=\"50%\" stop-color=\"black\" stop-opacity=\"0.5\" />\n * <stop offset=\"100%\" stop-color=\"white\" stop-opacity=\"1\" />\n * </radialGradient>\n *\n * OR\n *\n * <radialGradient id=\"radialGrad2\">\n * <stop offset=\"0\" stop-color=\"rgb(255,255,255)\" />\n * <stop offset=\"0.5\" stop-color=\"rgb(0,0,0)\" />\n * <stop offset=\"1\" stop-color=\"rgb(255,255,255)\" />\n * </radialGradient>\n *\n */\n\n var multiplier = parseFloat(opacityAttr) / (/%$/.test(opacityAttr) ? 100 : 1);\n multiplier = multiplier < 0 ? 0 : multiplier > 1 ? 1 : multiplier;\n if (isNaN(multiplier)) {\n multiplier = 1;\n }\n\n var colorStopEls = el.getElementsByTagName('stop'),\n type,\n gradientUnits = el.getAttribute('gradientUnits') === 'userSpaceOnUse' ?\n 'pixels' : 'percentage',\n gradientTransform = el.getAttribute('gradientTransform') || '',\n colorStops = [],\n coords, i, offsetX = 0, offsetY = 0,\n transformMatrix;\n if (el.nodeName === 'linearGradient' || el.nodeName === 'LINEARGRADIENT') {\n type = 'linear';\n coords = getLinearCoords(el);\n }\n else {\n type = 'radial';\n coords = getRadialCoords(el);\n }\n\n for (i = colorStopEls.length; i--; ) {\n colorStops.push(getColorStop(colorStopEls[i], multiplier));\n }\n\n transformMatrix = fabric.parseTransformAttribute(gradientTransform);\n\n __convertPercentUnitsToValues(instance, coords, svgOptions, gradientUnits);\n\n if (gradientUnits === 'pixels') {\n offsetX = -instance.left;\n offsetY = -instance.top;\n }\n\n var gradient = new fabric.Gradient({\n id: el.getAttribute('id'),\n type: type,\n coords: coords,\n colorStops: colorStops,\n gradientUnits: gradientUnits,\n gradientTransform: transformMatrix,\n offsetX: offsetX,\n offsetY: offsetY,\n });\n\n return gradient;\n }\n /* _FROM_SVG_END_ */\n });\n\n /**\n * @private\n */\n function __convertPercentUnitsToValues(instance, options, svgOptions, gradientUnits) {\n var propValue, finalValue;\n Object.keys(options).forEach(function(prop) {\n propValue = options[prop];\n if (propValue === 'Infinity') {\n finalValue = 1;\n }\n else if (propValue === '-Infinity') {\n finalValue = 0;\n }\n else {\n finalValue = parseFloat(options[prop], 10);\n if (typeof propValue === 'string' && /^(\\d+\\.\\d+)%|(\\d+)%$/.test(propValue)) {\n finalValue *= 0.01;\n if (gradientUnits === 'pixels') {\n // then we need to fix those percentages here in svg parsing\n if (prop === 'x1' || prop === 'x2' || prop === 'r2') {\n finalValue *= svgOptions.viewBoxWidth || svgOptions.width;\n }\n if (prop === 'y1' || prop === 'y2') {\n finalValue *= svgOptions.viewBoxHeight || svgOptions.height;\n }\n }\n }\n }\n options[prop] = finalValue;\n });\n }\n})();\n\n\n(function() {\n\n 'use strict';\n\n var toFixed = fabric.util.toFixed;\n\n /**\n * Pattern class\n * @class fabric.Pattern\n * @see {@link http://fabricjs.com/patterns|Pattern demo}\n * @see {@link http://fabricjs.com/dynamic-patterns|DynamicPattern demo}\n * @see {@link fabric.Pattern#initialize} for constructor definition\n */\n\n\n fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ {\n\n /**\n * Repeat property of a pattern (one of repeat, repeat-x, repeat-y or no-repeat)\n * @type String\n * @default\n */\n repeat: 'repeat',\n\n /**\n * Pattern horizontal offset from object's left/top corner\n * @type Number\n * @default\n */\n offsetX: 0,\n\n /**\n * Pattern vertical offset from object's left/top corner\n * @type Number\n * @default\n */\n offsetY: 0,\n\n /**\n * crossOrigin value (one of \"\", \"anonymous\", \"use-credentials\")\n * @see https://developer.mozilla.org/en-US/docs/HTML/CORS_settings_attributes\n * @type String\n * @default\n */\n crossOrigin: '',\n\n /**\n * transform matrix to change the pattern, imported from svgs.\n * @type Array\n * @default\n */\n patternTransform: null,\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n * @param {Function} [callback] function to invoke after callback init.\n * @return {fabric.Pattern} thisArg\n */\n initialize: function(options, callback) {\n options || (options = { });\n\n this.id = fabric.Object.__uid++;\n this.setOptions(options);\n if (!options.source || (options.source && typeof options.source !== 'string')) {\n callback && callback(this);\n return;\n }\n else {\n // img src string\n var _this = this;\n this.source = fabric.util.createImage();\n fabric.util.loadImage(options.source, function(img, isError) {\n _this.source = img;\n callback && callback(_this, isError);\n }, null, this.crossOrigin);\n }\n },\n\n /**\n * Returns object representation of a pattern\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} Object representation of a pattern instance\n */\n toObject: function(propertiesToInclude) {\n var NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS,\n source, object;\n\n // <img> element\n if (typeof this.source.src === 'string') {\n source = this.source.src;\n }\n // <canvas> element\n else if (typeof this.source === 'object' && this.source.toDataURL) {\n source = this.source.toDataURL();\n }\n\n object = {\n type: 'pattern',\n source: source,\n repeat: this.repeat,\n crossOrigin: this.crossOrigin,\n offsetX: toFixed(this.offsetX, NUM_FRACTION_DIGITS),\n offsetY: toFixed(this.offsetY, NUM_FRACTION_DIGITS),\n patternTransform: this.patternTransform ? this.patternTransform.concat() : null\n };\n fabric.util.populateWithProperties(this, object, propertiesToInclude);\n\n return object;\n },\n\n /* _TO_SVG_START_ */\n /**\n * Returns SVG representation of a pattern\n * @param {fabric.Object} object\n * @return {String} SVG representation of a pattern\n */\n toSVG: function(object) {\n var patternSource = typeof this.source === 'function' ? this.source() : this.source,\n patternWidth = patternSource.width / object.width,\n patternHeight = patternSource.height / object.height,\n patternOffsetX = this.offsetX / object.width,\n patternOffsetY = this.offsetY / object.height,\n patternImgSrc = '';\n if (this.repeat === 'repeat-x' || this.repeat === 'no-repeat') {\n patternHeight = 1;\n if (patternOffsetY) {\n patternHeight += Math.abs(patternOffsetY);\n }\n }\n if (this.repeat === 'repeat-y' || this.repeat === 'no-repeat') {\n patternWidth = 1;\n if (patternOffsetX) {\n patternWidth += Math.abs(patternOffsetX);\n }\n\n }\n if (patternSource.src) {\n patternImgSrc = patternSource.src;\n }\n else if (patternSource.toDataURL) {\n patternImgSrc = patternSource.toDataURL();\n }\n\n return '<pattern id=\"SVGID_' + this.id +\n '\" x=\"' + patternOffsetX +\n '\" y=\"' + patternOffsetY +\n '\" width=\"' + patternWidth +\n '\" height=\"' + patternHeight + '\">\\n' +\n '<image x=\"0\" y=\"0\"' +\n ' width=\"' + patternSource.width +\n '\" height=\"' + patternSource.height +\n '\" xlink:href=\"' + patternImgSrc +\n '\"></image>\\n' +\n '</pattern>\\n';\n },\n /* _TO_SVG_END_ */\n\n setOptions: function(options) {\n for (var prop in options) {\n this[prop] = options[prop];\n }\n },\n\n /**\n * Returns an instance of CanvasPattern\n * @param {CanvasRenderingContext2D} ctx Context to create pattern\n * @return {CanvasPattern}\n */\n toLive: function(ctx) {\n var source = this.source;\n // if the image failed to load, return, and allow rest to continue loading\n if (!source) {\n return '';\n }\n\n // if an image\n if (typeof source.src !== 'undefined') {\n if (!source.complete) {\n return '';\n }\n if (source.naturalWidth === 0 || source.naturalHeight === 0) {\n return '';\n }\n }\n return ctx.createPattern(source, this.repeat);\n }\n });\n})();\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n toFixed = fabric.util.toFixed;\n\n if (fabric.Shadow) {\n fabric.warn('fabric.Shadow is already defined.');\n return;\n }\n\n /**\n * Shadow class\n * @class fabric.Shadow\n * @see {@link http://fabricjs.com/shadows|Shadow demo}\n * @see {@link fabric.Shadow#initialize} for constructor definition\n */\n fabric.Shadow = fabric.util.createClass(/** @lends fabric.Shadow.prototype */ {\n\n /**\n * Shadow color\n * @type String\n * @default\n */\n color: 'rgb(0,0,0)',\n\n /**\n * Shadow blur\n * @type Number\n */\n blur: 0,\n\n /**\n * Shadow horizontal offset\n * @type Number\n * @default\n */\n offsetX: 0,\n\n /**\n * Shadow vertical offset\n * @type Number\n * @default\n */\n offsetY: 0,\n\n /**\n * Whether the shadow should affect stroke operations\n * @type Boolean\n * @default\n */\n affectStroke: false,\n\n /**\n * Indicates whether toObject should include default values\n * @type Boolean\n * @default\n */\n includeDefaultValues: true,\n\n /**\n * When `false`, the shadow will scale with the object.\n * When `true`, the shadow's offsetX, offsetY, and blur will not be affected by the object's scale.\n * default to false\n * @type Boolean\n * @default\n */\n nonScaling: false,\n\n /**\n * Constructor\n * @param {Object|String} [options] Options object with any of color, blur, offsetX, offsetY properties or string (e.g. \"rgba(0,0,0,0.2) 2px 2px 10px\")\n * @return {fabric.Shadow} thisArg\n */\n initialize: function(options) {\n\n if (typeof options === 'string') {\n options = this._parseShadow(options);\n }\n\n for (var prop in options) {\n this[prop] = options[prop];\n }\n\n this.id = fabric.Object.__uid++;\n },\n\n /**\n * @private\n * @param {String} shadow Shadow value to parse\n * @return {Object} Shadow object with color, offsetX, offsetY and blur\n */\n _parseShadow: function(shadow) {\n var shadowStr = shadow.trim(),\n offsetsAndBlur = fabric.Shadow.reOffsetsAndBlur.exec(shadowStr) || [],\n color = shadowStr.replace(fabric.Shadow.reOffsetsAndBlur, '') || 'rgb(0,0,0)';\n\n return {\n color: color.trim(),\n offsetX: parseInt(offsetsAndBlur[1], 10) || 0,\n offsetY: parseInt(offsetsAndBlur[2], 10) || 0,\n blur: parseInt(offsetsAndBlur[3], 10) || 0\n };\n },\n\n /**\n * Returns a string representation of an instance\n * @see http://www.w3.org/TR/css-text-decor-3/#text-shadow\n * @return {String} Returns CSS3 text-shadow declaration\n */\n toString: function() {\n return [this.offsetX, this.offsetY, this.blur, this.color].join('px ');\n },\n\n /* _TO_SVG_START_ */\n /**\n * Returns SVG representation of a shadow\n * @param {fabric.Object} object\n * @return {String} SVG representation of a shadow\n */\n toSVG: function(object) {\n var fBoxX = 40, fBoxY = 40, NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS,\n offset = fabric.util.rotateVector(\n { x: this.offsetX, y: this.offsetY },\n fabric.util.degreesToRadians(-object.angle)),\n BLUR_BOX = 20, color = new fabric.Color(this.color);\n\n if (object.width && object.height) {\n //http://www.w3.org/TR/SVG/filters.html#FilterEffectsRegion\n // we add some extra space to filter box to contain the blur ( 20 )\n fBoxX = toFixed((Math.abs(offset.x) + this.blur) / object.width, NUM_FRACTION_DIGITS) * 100 + BLUR_BOX;\n fBoxY = toFixed((Math.abs(offset.y) + this.blur) / object.height, NUM_FRACTION_DIGITS) * 100 + BLUR_BOX;\n }\n if (object.flipX) {\n offset.x *= -1;\n }\n if (object.flipY) {\n offset.y *= -1;\n }\n\n return (\n '<filter id=\"SVGID_' + this.id + '\" y=\"-' + fBoxY + '%\" height=\"' + (100 + 2 * fBoxY) + '%\" ' +\n 'x=\"-' + fBoxX + '%\" width=\"' + (100 + 2 * fBoxX) + '%\" ' + '>\\n' +\n '\\t<feGaussianBlur in=\"SourceAlpha\" stdDeviation=\"' +\n toFixed(this.blur ? this.blur / 2 : 0, NUM_FRACTION_DIGITS) + '\"></feGaussianBlur>\\n' +\n '\\t<feOffset dx=\"' + toFixed(offset.x, NUM_FRACTION_DIGITS) +\n '\" dy=\"' + toFixed(offset.y, NUM_FRACTION_DIGITS) + '\" result=\"oBlur\" ></feOffset>\\n' +\n '\\t<feFlood flood-color=\"' + color.toRgb() + '\" flood-opacity=\"' + color.getAlpha() + '\"/>\\n' +\n '\\t<feComposite in2=\"oBlur\" operator=\"in\" />\\n' +\n '\\t<feMerge>\\n' +\n '\\t\\t<feMergeNode></feMergeNode>\\n' +\n '\\t\\t<feMergeNode in=\"SourceGraphic\"></feMergeNode>\\n' +\n '\\t</feMerge>\\n' +\n '</filter>\\n');\n },\n /* _TO_SVG_END_ */\n\n /**\n * Returns object representation of a shadow\n * @return {Object} Object representation of a shadow instance\n */\n toObject: function() {\n if (this.includeDefaultValues) {\n return {\n color: this.color,\n blur: this.blur,\n offsetX: this.offsetX,\n offsetY: this.offsetY,\n affectStroke: this.affectStroke,\n nonScaling: this.nonScaling\n };\n }\n var obj = { }, proto = fabric.Shadow.prototype;\n\n ['color', 'blur', 'offsetX', 'offsetY', 'affectStroke', 'nonScaling'].forEach(function(prop) {\n if (this[prop] !== proto[prop]) {\n obj[prop] = this[prop];\n }\n }, this);\n\n return obj;\n }\n });\n\n /**\n * Regex matching shadow offsetX, offsetY and blur (ex: \"2px 2px 10px rgba(0,0,0,0.2)\", \"rgb(0,255,0) 2px 2px\")\n * @static\n * @field\n * @memberOf fabric.Shadow\n */\n // eslint-disable-next-line max-len\n fabric.Shadow.reOffsetsAndBlur = /(?:\\s|^)(-?\\d+(?:px)?(?:\\s?|$))?(-?\\d+(?:px)?(?:\\s?|$))?(\\d+(?:px)?)?(?:\\s?|$)(?:$|\\s)/;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function () {\n\n 'use strict';\n\n if (fabric.StaticCanvas) {\n fabric.warn('fabric.StaticCanvas is already defined.');\n return;\n }\n\n // aliases for faster resolution\n var extend = fabric.util.object.extend,\n getElementOffset = fabric.util.getElementOffset,\n removeFromArray = fabric.util.removeFromArray,\n toFixed = fabric.util.toFixed,\n transformPoint = fabric.util.transformPoint,\n invertTransform = fabric.util.invertTransform,\n getNodeCanvas = fabric.util.getNodeCanvas,\n createCanvasElement = fabric.util.createCanvasElement,\n\n CANVAS_INIT_ERROR = new Error('Could not initialize `canvas` element');\n\n /**\n * Static canvas class\n * @class fabric.StaticCanvas\n * @mixes fabric.Collection\n * @mixes fabric.Observable\n * @see {@link http://fabricjs.com/static_canvas|StaticCanvas demo}\n * @see {@link fabric.StaticCanvas#initialize} for constructor definition\n * @fires before:render\n * @fires after:render\n * @fires canvas:cleared\n * @fires object:added\n * @fires object:removed\n */\n fabric.StaticCanvas = fabric.util.createClass(fabric.CommonMethods, /** @lends fabric.StaticCanvas.prototype */ {\n\n /**\n * Constructor\n * @param {HTMLElement | String} el <canvas> element to initialize instance on\n * @param {Object} [options] Options object\n * @return {Object} thisArg\n */\n initialize: function(el, options) {\n options || (options = { });\n this.renderAndResetBound = this.renderAndReset.bind(this);\n this.requestRenderAllBound = this.requestRenderAll.bind(this);\n this._initStatic(el, options);\n },\n\n /**\n * Background color of canvas instance.\n * Should be set via {@link fabric.StaticCanvas#setBackgroundColor}.\n * @type {(String|fabric.Pattern)}\n * @default\n */\n backgroundColor: '',\n\n /**\n * Background image of canvas instance.\n * since 2.4.0 image caching is active, please when putting an image as background, add to the\n * canvas property a reference to the canvas it is on. Otherwise the image cannot detect the zoom\n * vale. As an alternative you can disable image objectCaching\n * @type fabric.Image\n * @default\n */\n backgroundImage: null,\n\n /**\n * Overlay color of canvas instance.\n * Should be set via {@link fabric.StaticCanvas#setOverlayColor}\n * @since 1.3.9\n * @type {(String|fabric.Pattern)}\n * @default\n */\n overlayColor: '',\n\n /**\n * Overlay image of canvas instance.\n * since 2.4.0 image caching is active, please when putting an image as overlay, add to the\n * canvas property a reference to the canvas it is on. Otherwise the image cannot detect the zoom\n * vale. As an alternative you can disable image objectCaching\n * @type fabric.Image\n * @default\n */\n overlayImage: null,\n\n /**\n * Indicates whether toObject/toDatalessObject should include default values\n * if set to false, takes precedence over the object value.\n * @type Boolean\n * @default\n */\n includeDefaultValues: true,\n\n /**\n * Indicates whether objects' state should be saved\n * @type Boolean\n * @default\n */\n stateful: false,\n\n /**\n * Indicates whether {@link fabric.Collection.add}, {@link fabric.Collection.insertAt} and {@link fabric.Collection.remove},\n * {@link fabric.StaticCanvas.moveTo}, {@link fabric.StaticCanvas.clear} and many more, should also re-render canvas.\n * Disabling this option will not give a performance boost when adding/removing a lot of objects to/from canvas at once\n * since the renders are quequed and executed one per frame.\n * Disabling is suggested anyway and managing the renders of the app manually is not a big effort ( canvas.requestRenderAll() )\n * Left default to true to do not break documentation and old app, fiddles.\n * @type Boolean\n * @default\n */\n renderOnAddRemove: true,\n\n /**\n * Indicates whether object controls (borders/controls) are rendered above overlay image\n * @type Boolean\n * @default\n */\n controlsAboveOverlay: false,\n\n /**\n * Indicates whether the browser can be scrolled when using a touchscreen and dragging on the canvas\n * @type Boolean\n * @default\n */\n allowTouchScrolling: false,\n\n /**\n * Indicates whether this canvas will use image smoothing, this is on by default in browsers\n * @type Boolean\n * @default\n */\n imageSmoothingEnabled: true,\n\n /**\n * The transformation (in the format of Canvas transform) which focuses the viewport\n * @type Array\n * @default\n */\n viewportTransform: fabric.iMatrix.concat(),\n\n /**\n * if set to false background image is not affected by viewport transform\n * @since 1.6.3\n * @type Boolean\n * @default\n */\n backgroundVpt: true,\n\n /**\n * if set to false overlya image is not affected by viewport transform\n * @since 1.6.3\n * @type Boolean\n * @default\n */\n overlayVpt: true,\n\n /**\n * When true, canvas is scaled by devicePixelRatio for better rendering on retina screens\n * @type Boolean\n * @default\n */\n enableRetinaScaling: true,\n\n /**\n * Describe canvas element extension over design\n * properties are tl,tr,bl,br.\n * if canvas is not zoomed/panned those points are the four corner of canvas\n * if canvas is viewportTransformed you those points indicate the extension\n * of canvas element in plain untrasformed coordinates\n * The coordinates get updated with @method calcViewportBoundaries.\n * @memberOf fabric.StaticCanvas.prototype\n */\n vptCoords: { },\n\n /**\n * Based on vptCoords and object.aCoords, skip rendering of objects that\n * are not included in current viewport.\n * May greatly help in applications with crowded canvas and use of zoom/pan\n * If One of the corner of the bounding box of the object is on the canvas\n * the objects get rendered.\n * @memberOf fabric.StaticCanvas.prototype\n * @type Boolean\n * @default\n */\n skipOffscreen: true,\n\n /**\n * a fabricObject that, without stroke define a clipping area with their shape. filled in black\n * the clipPath object gets used when the canvas has rendered, and the context is placed in the\n * top left corner of the canvas.\n * clipPath will clip away controls, if you do not want this to happen use controlsAboveOverlay = true\n * @type fabric.Object\n */\n clipPath: undefined,\n\n /**\n * @private\n * @param {HTMLElement | String} el <canvas> element to initialize instance on\n * @param {Object} [options] Options object\n */\n _initStatic: function(el, options) {\n var cb = this.requestRenderAllBound;\n this._objects = [];\n this._createLowerCanvas(el);\n this._initOptions(options);\n // only initialize retina scaling once\n if (!this.interactive) {\n this._initRetinaScaling();\n }\n\n if (options.overlayImage) {\n this.setOverlayImage(options.overlayImage, cb);\n }\n if (options.backgroundImage) {\n this.setBackgroundImage(options.backgroundImage, cb);\n }\n if (options.backgroundColor) {\n this.setBackgroundColor(options.backgroundColor, cb);\n }\n if (options.overlayColor) {\n this.setOverlayColor(options.overlayColor, cb);\n }\n this.calcOffset();\n },\n\n /**\n * @private\n */\n _isRetinaScaling: function() {\n return (fabric.devicePixelRatio !== 1 && this.enableRetinaScaling);\n },\n\n /**\n * @private\n * @return {Number} retinaScaling if applied, otherwise 1;\n */\n getRetinaScaling: function() {\n return this._isRetinaScaling() ? fabric.devicePixelRatio : 1;\n },\n\n /**\n * @private\n */\n _initRetinaScaling: function() {\n if (!this._isRetinaScaling()) {\n return;\n }\n var scaleRatio = fabric.devicePixelRatio;\n this.__initRetinaScaling(scaleRatio, this.lowerCanvasEl, this.contextContainer);\n if (this.upperCanvasEl) {\n this.__initRetinaScaling(scaleRatio, this.upperCanvasEl, this.contextTop);\n }\n },\n\n __initRetinaScaling: function(scaleRatio, canvas, context) {\n canvas.setAttribute('width', this.width * scaleRatio);\n canvas.setAttribute('height', this.height * scaleRatio);\n context.scale(scaleRatio, scaleRatio);\n },\n\n\n /**\n * Calculates canvas element offset relative to the document\n * This method is also attached as \"resize\" event handler of window\n * @return {fabric.Canvas} instance\n * @chainable\n */\n calcOffset: function () {\n this._offset = getElementOffset(this.lowerCanvasEl);\n return this;\n },\n\n /**\n * Sets {@link fabric.StaticCanvas#overlayImage|overlay image} for this canvas\n * @param {(fabric.Image|String)} image fabric.Image instance or URL of an image to set overlay to\n * @param {Function} callback callback to invoke when image is loaded and set as an overlay\n * @param {Object} [options] Optional options to set for the {@link fabric.Image|overlay image}.\n * @return {fabric.Canvas} thisArg\n * @chainable\n * @see {@link http://jsfiddle.net/fabricjs/MnzHT/|jsFiddle demo}\n * @example <caption>Normal overlayImage with left/top = 0</caption>\n * canvas.setOverlayImage('http://fabricjs.com/assets/jail_cell_bars.png', canvas.renderAll.bind(canvas), {\n * // Needed to position overlayImage at 0/0\n * originX: 'left',\n * originY: 'top'\n * });\n * @example <caption>overlayImage with different properties</caption>\n * canvas.setOverlayImage('http://fabricjs.com/assets/jail_cell_bars.png', canvas.renderAll.bind(canvas), {\n * opacity: 0.5,\n * angle: 45,\n * left: 400,\n * top: 400,\n * originX: 'left',\n * originY: 'top'\n * });\n * @example <caption>Stretched overlayImage #1 - width/height correspond to canvas width/height</caption>\n * fabric.Image.fromURL('http://fabricjs.com/assets/jail_cell_bars.png', function(img, isError) {\n * img.set({width: canvas.width, height: canvas.height, originX: 'left', originY: 'top'});\n * canvas.setOverlayImage(img, canvas.renderAll.bind(canvas));\n * });\n * @example <caption>Stretched overlayImage #2 - width/height correspond to canvas width/height</caption>\n * canvas.setOverlayImage('http://fabricjs.com/assets/jail_cell_bars.png', canvas.renderAll.bind(canvas), {\n * width: canvas.width,\n * height: canvas.height,\n * // Needed to position overlayImage at 0/0\n * originX: 'left',\n * originY: 'top'\n * });\n * @example <caption>overlayImage loaded from cross-origin</caption>\n * canvas.setOverlayImage('http://fabricjs.com/assets/jail_cell_bars.png', canvas.renderAll.bind(canvas), {\n * opacity: 0.5,\n * angle: 45,\n * left: 400,\n * top: 400,\n * originX: 'left',\n * originY: 'top',\n * crossOrigin: 'anonymous'\n * });\n */\n setOverlayImage: function (image, callback, options) {\n return this.__setBgOverlayImage('overlayImage', image, callback, options);\n },\n\n /**\n * Sets {@link fabric.StaticCanvas#backgroundImage|background image} for this canvas\n * @param {(fabric.Image|String)} image fabric.Image instance or URL of an image to set background to\n * @param {Function} callback Callback to invoke when image is loaded and set as background\n * @param {Object} [options] Optional options to set for the {@link fabric.Image|background image}.\n * @return {fabric.Canvas} thisArg\n * @chainable\n * @see {@link http://jsfiddle.net/djnr8o7a/28/|jsFiddle demo}\n * @example <caption>Normal backgroundImage with left/top = 0</caption>\n * canvas.setBackgroundImage('http://fabricjs.com/assets/honey_im_subtle.png', canvas.renderAll.bind(canvas), {\n * // Needed to position backgroundImage at 0/0\n * originX: 'left',\n * originY: 'top'\n * });\n * @example <caption>backgroundImage with different properties</caption>\n * canvas.setBackgroundImage('http://fabricjs.com/assets/honey_im_subtle.png', canvas.renderAll.bind(canvas), {\n * opacity: 0.5,\n * angle: 45,\n * left: 400,\n * top: 400,\n * originX: 'left',\n * originY: 'top'\n * });\n * @example <caption>Stretched backgroundImage #1 - width/height correspond to canvas width/height</caption>\n * fabric.Image.fromURL('http://fabricjs.com/assets/honey_im_subtle.png', function(img, isError) {\n * img.set({width: canvas.width, height: canvas.height, originX: 'left', originY: 'top'});\n * canvas.setBackgroundImage(img, canvas.renderAll.bind(canvas));\n * });\n * @example <caption>Stretched backgroundImage #2 - width/height correspond to canvas width/height</caption>\n * canvas.setBackgroundImage('http://fabricjs.com/assets/honey_im_subtle.png', canvas.renderAll.bind(canvas), {\n * width: canvas.width,\n * height: canvas.height,\n * // Needed to position backgroundImage at 0/0\n * originX: 'left',\n * originY: 'top'\n * });\n * @example <caption>backgroundImage loaded from cross-origin</caption>\n * canvas.setBackgroundImage('http://fabricjs.com/assets/honey_im_subtle.png', canvas.renderAll.bind(canvas), {\n * opacity: 0.5,\n * angle: 45,\n * left: 400,\n * top: 400,\n * originX: 'left',\n * originY: 'top',\n * crossOrigin: 'anonymous'\n * });\n */\n // TODO: fix stretched examples\n setBackgroundImage: function (image, callback, options) {\n return this.__setBgOverlayImage('backgroundImage', image, callback, options);\n },\n\n /**\n * Sets {@link fabric.StaticCanvas#overlayColor|foreground color} for this canvas\n * @param {(String|fabric.Pattern)} overlayColor Color or pattern to set foreground color to\n * @param {Function} callback Callback to invoke when foreground color is set\n * @return {fabric.Canvas} thisArg\n * @chainable\n * @see {@link http://jsfiddle.net/fabricjs/pB55h/|jsFiddle demo}\n * @example <caption>Normal overlayColor - color value</caption>\n * canvas.setOverlayColor('rgba(255, 73, 64, 0.6)', canvas.renderAll.bind(canvas));\n * @example <caption>fabric.Pattern used as overlayColor</caption>\n * canvas.setOverlayColor({\n * source: 'http://fabricjs.com/assets/escheresque_ste.png'\n * }, canvas.renderAll.bind(canvas));\n * @example <caption>fabric.Pattern used as overlayColor with repeat and offset</caption>\n * canvas.setOverlayColor({\n * source: 'http://fabricjs.com/assets/escheresque_ste.png',\n * repeat: 'repeat',\n * offsetX: 200,\n * offsetY: 100\n * }, canvas.renderAll.bind(canvas));\n */\n setOverlayColor: function(overlayColor, callback) {\n return this.__setBgOverlayColor('overlayColor', overlayColor, callback);\n },\n\n /**\n * Sets {@link fabric.StaticCanvas#backgroundColor|background color} for this canvas\n * @param {(String|fabric.Pattern)} backgroundColor Color or pattern to set background color to\n * @param {Function} callback Callback to invoke when background color is set\n * @return {fabric.Canvas} thisArg\n * @chainable\n * @see {@link http://jsfiddle.net/fabricjs/hXzvk/|jsFiddle demo}\n * @example <caption>Normal backgroundColor - color value</caption>\n * canvas.setBackgroundColor('rgba(255, 73, 64, 0.6)', canvas.renderAll.bind(canvas));\n * @example <caption>fabric.Pattern used as backgroundColor</caption>\n * canvas.setBackgroundColor({\n * source: 'http://fabricjs.com/assets/escheresque_ste.png'\n * }, canvas.renderAll.bind(canvas));\n * @example <caption>fabric.Pattern used as backgroundColor with repeat and offset</caption>\n * canvas.setBackgroundColor({\n * source: 'http://fabricjs.com/assets/escheresque_ste.png',\n * repeat: 'repeat',\n * offsetX: 200,\n * offsetY: 100\n * }, canvas.renderAll.bind(canvas));\n */\n setBackgroundColor: function(backgroundColor, callback) {\n return this.__setBgOverlayColor('backgroundColor', backgroundColor, callback);\n },\n\n /**\n * @private\n * @param {String} property Property to set ({@link fabric.StaticCanvas#backgroundImage|backgroundImage}\n * or {@link fabric.StaticCanvas#overlayImage|overlayImage})\n * @param {(fabric.Image|String|null)} image fabric.Image instance, URL of an image or null to set background or overlay to\n * @param {Function} callback Callback to invoke when image is loaded and set as background or overlay. The first argument is the created image, the second argument is a flag indicating whether an error occured or not.\n * @param {Object} [options] Optional options to set for the {@link fabric.Image|image}.\n */\n __setBgOverlayImage: function(property, image, callback, options) {\n if (typeof image === 'string') {\n fabric.util.loadImage(image, function(img, isError) {\n if (img) {\n var instance = new fabric.Image(img, options);\n this[property] = instance;\n instance.canvas = this;\n }\n callback && callback(img, isError);\n }, this, options && options.crossOrigin);\n }\n else {\n options && image.setOptions(options);\n this[property] = image;\n image && (image.canvas = this);\n callback && callback(image, false);\n }\n\n return this;\n },\n\n /**\n * @private\n * @param {String} property Property to set ({@link fabric.StaticCanvas#backgroundColor|backgroundColor}\n * or {@link fabric.StaticCanvas#overlayColor|overlayColor})\n * @param {(Object|String|null)} color Object with pattern information, color value or null\n * @param {Function} [callback] Callback is invoked when color is set\n */\n __setBgOverlayColor: function(property, color, callback) {\n this[property] = color;\n this._initGradient(color, property);\n this._initPattern(color, property, callback);\n return this;\n },\n\n /**\n * @private\n */\n _createCanvasElement: function() {\n var element = createCanvasElement();\n if (!element) {\n throw CANVAS_INIT_ERROR;\n }\n if (!element.style) {\n element.style = { };\n }\n if (typeof element.getContext === 'undefined') {\n throw CANVAS_INIT_ERROR;\n }\n return element;\n },\n\n /**\n * @private\n * @param {Object} [options] Options object\n */\n _initOptions: function (options) {\n var lowerCanvasEl = this.lowerCanvasEl;\n this._setOptions(options);\n\n this.width = this.width || parseInt(lowerCanvasEl.width, 10) || 0;\n this.height = this.height || parseInt(lowerCanvasEl.height, 10) || 0;\n\n if (!this.lowerCanvasEl.style) {\n return;\n }\n\n lowerCanvasEl.width = this.width;\n lowerCanvasEl.height = this.height;\n\n lowerCanvasEl.style.width = this.width + 'px';\n lowerCanvasEl.style.height = this.height + 'px';\n\n this.viewportTransform = this.viewportTransform.slice();\n },\n\n /**\n * Creates a bottom canvas\n * @private\n * @param {HTMLElement} [canvasEl]\n */\n _createLowerCanvas: function (canvasEl) {\n // canvasEl === 'HTMLCanvasElement' does not work on jsdom/node\n if (canvasEl && canvasEl.getContext) {\n this.lowerCanvasEl = canvasEl;\n }\n else {\n this.lowerCanvasEl = fabric.util.getById(canvasEl) || this._createCanvasElement();\n }\n\n fabric.util.addClass(this.lowerCanvasEl, 'lower-canvas');\n\n if (this.interactive) {\n this._applyCanvasStyle(this.lowerCanvasEl);\n }\n\n this.contextContainer = this.lowerCanvasEl.getContext('2d');\n },\n\n /**\n * Returns canvas width (in px)\n * @return {Number}\n */\n getWidth: function () {\n return this.width;\n },\n\n /**\n * Returns canvas height (in px)\n * @return {Number}\n */\n getHeight: function () {\n return this.height;\n },\n\n /**\n * Sets width of this canvas instance\n * @param {Number|String} value Value to set width to\n * @param {Object} [options] Options object\n * @param {Boolean} [options.backstoreOnly=false] Set the given dimensions only as canvas backstore dimensions\n * @param {Boolean} [options.cssOnly=false] Set the given dimensions only as css dimensions\n * @return {fabric.Canvas} instance\n * @chainable true\n */\n setWidth: function (value, options) {\n return this.setDimensions({ width: value }, options);\n },\n\n /**\n * Sets height of this canvas instance\n * @param {Number|String} value Value to set height to\n * @param {Object} [options] Options object\n * @param {Boolean} [options.backstoreOnly=false] Set the given dimensions only as canvas backstore dimensions\n * @param {Boolean} [options.cssOnly=false] Set the given dimensions only as css dimensions\n * @return {fabric.Canvas} instance\n * @chainable true\n */\n setHeight: function (value, options) {\n return this.setDimensions({ height: value }, options);\n },\n\n /**\n * Sets dimensions (width, height) of this canvas instance. when options.cssOnly flag active you should also supply the unit of measure (px/%/em)\n * @param {Object} dimensions Object with width/height properties\n * @param {Number|String} [dimensions.width] Width of canvas element\n * @param {Number|String} [dimensions.height] Height of canvas element\n * @param {Object} [options] Options object\n * @param {Boolean} [options.backstoreOnly=false] Set the given dimensions only as canvas backstore dimensions\n * @param {Boolean} [options.cssOnly=false] Set the given dimensions only as css dimensions\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n setDimensions: function (dimensions, options) {\n var cssValue;\n\n options = options || {};\n\n for (var prop in dimensions) {\n cssValue = dimensions[prop];\n\n if (!options.cssOnly) {\n this._setBackstoreDimension(prop, dimensions[prop]);\n cssValue += 'px';\n this.hasLostContext = true;\n }\n\n if (!options.backstoreOnly) {\n this._setCssDimension(prop, cssValue);\n }\n }\n if (this._isCurrentlyDrawing) {\n this.freeDrawingBrush && this.freeDrawingBrush._setBrushStyles();\n }\n this._initRetinaScaling();\n this.calcOffset();\n\n if (!options.cssOnly) {\n this.requestRenderAll();\n }\n\n return this;\n },\n\n /**\n * Helper for setting width/height\n * @private\n * @param {String} prop property (width|height)\n * @param {Number} value value to set property to\n * @return {fabric.Canvas} instance\n * @chainable true\n */\n _setBackstoreDimension: function (prop, value) {\n this.lowerCanvasEl[prop] = value;\n\n if (this.upperCanvasEl) {\n this.upperCanvasEl[prop] = value;\n }\n\n if (this.cacheCanvasEl) {\n this.cacheCanvasEl[prop] = value;\n }\n\n this[prop] = value;\n\n return this;\n },\n\n /**\n * Helper for setting css width/height\n * @private\n * @param {String} prop property (width|height)\n * @param {String} value value to set property to\n * @return {fabric.Canvas} instance\n * @chainable true\n */\n _setCssDimension: function (prop, value) {\n this.lowerCanvasEl.style[prop] = value;\n\n if (this.upperCanvasEl) {\n this.upperCanvasEl.style[prop] = value;\n }\n\n if (this.wrapperEl) {\n this.wrapperEl.style[prop] = value;\n }\n\n return this;\n },\n\n /**\n * Returns canvas zoom level\n * @return {Number}\n */\n getZoom: function () {\n return this.viewportTransform[0];\n },\n\n /**\n * Sets viewport transform of this canvas instance\n * @param {Array} vpt the transform in the form of context.transform\n * @return {fabric.Canvas} instance\n * @chainable true\n */\n setViewportTransform: function (vpt) {\n var activeObject = this._activeObject, object, i, len;\n this.viewportTransform = vpt;\n for (i = 0, len = this._objects.length; i < len; i++) {\n object = this._objects[i];\n object.group || object.setCoords(true);\n }\n if (activeObject) {\n activeObject.setCoords();\n }\n this.calcViewportBoundaries();\n this.renderOnAddRemove && this.requestRenderAll();\n return this;\n },\n\n /**\n * Sets zoom level of this canvas instance, zoom centered around point\n * @param {fabric.Point} point to zoom with respect to\n * @param {Number} value to set zoom to, less than 1 zooms out\n * @return {fabric.Canvas} instance\n * @chainable true\n */\n zoomToPoint: function (point, value) {\n // TODO: just change the scale, preserve other transformations\n var before = point, vpt = this.viewportTransform.slice(0);\n point = transformPoint(point, invertTransform(this.viewportTransform));\n vpt[0] = value;\n vpt[3] = value;\n var after = transformPoint(point, vpt);\n vpt[4] += before.x - after.x;\n vpt[5] += before.y - after.y;\n return this.setViewportTransform(vpt);\n },\n\n /**\n * Sets zoom level of this canvas instance\n * @param {Number} value to set zoom to, less than 1 zooms out\n * @return {fabric.Canvas} instance\n * @chainable true\n */\n setZoom: function (value) {\n this.zoomToPoint(new fabric.Point(0, 0), value);\n return this;\n },\n\n /**\n * Pan viewport so as to place point at top left corner of canvas\n * @param {fabric.Point} point to move to\n * @return {fabric.Canvas} instance\n * @chainable true\n */\n absolutePan: function (point) {\n var vpt = this.viewportTransform.slice(0);\n vpt[4] = -point.x;\n vpt[5] = -point.y;\n return this.setViewportTransform(vpt);\n },\n\n /**\n * Pans viewpoint relatively\n * @param {fabric.Point} point (position vector) to move by\n * @return {fabric.Canvas} instance\n * @chainable true\n */\n relativePan: function (point) {\n return this.absolutePan(new fabric.Point(\n -point.x - this.viewportTransform[4],\n -point.y - this.viewportTransform[5]\n ));\n },\n\n /**\n * Returns <canvas> element corresponding to this instance\n * @return {HTMLCanvasElement}\n */\n getElement: function () {\n return this.lowerCanvasEl;\n },\n\n /**\n * @private\n * @param {fabric.Object} obj Object that was added\n */\n _onObjectAdded: function(obj) {\n this.stateful && obj.setupState();\n obj._set('canvas', this);\n obj.setCoords();\n this.fire('object:added', { target: obj });\n obj.fire('added');\n },\n\n /**\n * @private\n * @param {fabric.Object} obj Object that was removed\n */\n _onObjectRemoved: function(obj) {\n this.fire('object:removed', { target: obj });\n obj.fire('removed');\n delete obj.canvas;\n },\n\n /**\n * Clears specified context of canvas element\n * @param {CanvasRenderingContext2D} ctx Context to clear\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n clearContext: function(ctx) {\n ctx.clearRect(0, 0, this.width, this.height);\n return this;\n },\n\n /**\n * Returns context of canvas where objects are drawn\n * @return {CanvasRenderingContext2D}\n */\n getContext: function () {\n return this.contextContainer;\n },\n\n /**\n * Clears all contexts (background, main, top) of an instance\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n clear: function () {\n this._objects.length = 0;\n this.backgroundImage = null;\n this.overlayImage = null;\n this.backgroundColor = '';\n this.overlayColor = '';\n if (this._hasITextHandlers) {\n this.off('mouse:up', this._mouseUpITextHandler);\n this._iTextInstances = null;\n this._hasITextHandlers = false;\n }\n this.clearContext(this.contextContainer);\n this.fire('canvas:cleared');\n this.renderOnAddRemove && this.requestRenderAll();\n return this;\n },\n\n /**\n * Renders the canvas\n * @return {fabric.Canvas} instance\n * @chainable\n */\n renderAll: function () {\n var canvasToDrawOn = this.contextContainer;\n this.renderCanvas(canvasToDrawOn, this._objects);\n return this;\n },\n\n /**\n * Function created to be instance bound at initialization\n * used in requestAnimationFrame rendering\n * Let the fabricJS call it. If you call it manually you could have more\n * animationFrame stacking on to of each other\n * for an imperative rendering, use canvas.renderAll\n * @private\n * @return {fabric.Canvas} instance\n * @chainable\n */\n renderAndReset: function() {\n this.isRendering = 0;\n this.renderAll();\n },\n\n /**\n * Append a renderAll request to next animation frame.\n * unless one is already in progress, in that case nothing is done\n * a boolean flag will avoid appending more.\n * @return {fabric.Canvas} instance\n * @chainable\n */\n requestRenderAll: function () {\n if (!this.isRendering) {\n this.isRendering = fabric.util.requestAnimFrame(this.renderAndResetBound);\n }\n return this;\n },\n\n /**\n * Calculate the position of the 4 corner of canvas with current viewportTransform.\n * helps to determinate when an object is in the current rendering viewport using\n * object absolute coordinates ( aCoords )\n * @return {Object} points.tl\n * @chainable\n */\n calcViewportBoundaries: function() {\n var points = { }, width = this.width, height = this.height,\n iVpt = invertTransform(this.viewportTransform);\n points.tl = transformPoint({ x: 0, y: 0 }, iVpt);\n points.br = transformPoint({ x: width, y: height }, iVpt);\n points.tr = new fabric.Point(points.br.x, points.tl.y);\n points.bl = new fabric.Point(points.tl.x, points.br.y);\n this.vptCoords = points;\n return points;\n },\n\n cancelRequestedRender: function() {\n if (this.isRendering) {\n fabric.util.cancelAnimFrame(this.isRendering);\n this.isRendering = 0;\n }\n },\n\n /**\n * Renders background, objects, overlay and controls.\n * @param {CanvasRenderingContext2D} ctx\n * @param {Array} objects to render\n * @return {fabric.Canvas} instance\n * @chainable\n */\n renderCanvas: function(ctx, objects) {\n var v = this.viewportTransform, path = this.clipPath;\n this.cancelRequestedRender();\n this.calcViewportBoundaries();\n this.clearContext(ctx);\n fabric.util.setImageSmoothing(ctx, this.imageSmoothingEnabled);\n this.fire('before:render', { ctx: ctx, });\n this._renderBackground(ctx);\n\n ctx.save();\n //apply viewport transform once for all rendering process\n ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]);\n this._renderObjects(ctx, objects);\n ctx.restore();\n if (!this.controlsAboveOverlay && this.interactive) {\n this.drawControls(ctx);\n }\n if (path) {\n path.canvas = this;\n // needed to setup a couple of variables\n path.shouldCache();\n path._transformDone = true;\n path.renderCache({ forClipping: true });\n this.drawClipPathOnCanvas(ctx);\n }\n this._renderOverlay(ctx);\n if (this.controlsAboveOverlay && this.interactive) {\n this.drawControls(ctx);\n }\n this.fire('after:render', { ctx: ctx, });\n },\n\n /**\n * Paint the cached clipPath on the lowerCanvasEl\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n drawClipPathOnCanvas: function(ctx) {\n var v = this.viewportTransform, path = this.clipPath;\n ctx.save();\n ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]);\n // DEBUG: uncomment this line, comment the following\n // ctx.globalAlpha = 0.4;\n ctx.globalCompositeOperation = 'destination-in';\n path.transform(ctx);\n ctx.scale(1 / path.zoomX, 1 / path.zoomY);\n ctx.drawImage(path._cacheCanvas, -path.cacheTranslationX, -path.cacheTranslationY);\n ctx.restore();\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Array} objects to render\n */\n _renderObjects: function(ctx, objects) {\n var i, len;\n for (i = 0, len = objects.length; i < len; ++i) {\n objects[i] && objects[i].render(ctx);\n }\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {string} property 'background' or 'overlay'\n */\n _renderBackgroundOrOverlay: function(ctx, property) {\n var fill = this[property + 'Color'], object = this[property + 'Image'],\n v = this.viewportTransform, needsVpt = this[property + 'Vpt'];\n if (!fill && !object) {\n return;\n }\n if (fill) {\n ctx.save();\n ctx.beginPath();\n ctx.moveTo(0, 0);\n ctx.lineTo(this.width, 0);\n ctx.lineTo(this.width, this.height);\n ctx.lineTo(0, this.height);\n ctx.closePath();\n ctx.fillStyle = fill.toLive\n ? fill.toLive(ctx, this)\n : fill;\n if (needsVpt) {\n ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]);\n }\n ctx.transform(1, 0, 0, 1, fill.offsetX || 0, fill.offsetY || 0);\n var m = fill.gradientTransform || fill.patternTransform;\n m && ctx.transform(m[0], m[1], m[2], m[3], m[4], m[5]);\n ctx.fill();\n ctx.restore();\n }\n if (object) {\n ctx.save();\n if (needsVpt) {\n ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]);\n }\n object.render(ctx);\n ctx.restore();\n }\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderBackground: function(ctx) {\n this._renderBackgroundOrOverlay(ctx, 'background');\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderOverlay: function(ctx) {\n this._renderBackgroundOrOverlay(ctx, 'overlay');\n },\n\n /**\n * Returns coordinates of a center of canvas.\n * Returned value is an object with top and left properties\n * @return {Object} object with \"top\" and \"left\" number values\n */\n getCenter: function () {\n return {\n top: this.height / 2,\n left: this.width / 2\n };\n },\n\n /**\n * Centers object horizontally in the canvas\n * @param {fabric.Object} object Object to center horizontally\n * @return {fabric.Canvas} thisArg\n */\n centerObjectH: function (object) {\n return this._centerObject(object, new fabric.Point(this.getCenter().left, object.getCenterPoint().y));\n },\n\n /**\n * Centers object vertically in the canvas\n * @param {fabric.Object} object Object to center vertically\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n centerObjectV: function (object) {\n return this._centerObject(object, new fabric.Point(object.getCenterPoint().x, this.getCenter().top));\n },\n\n /**\n * Centers object vertically and horizontally in the canvas\n * @param {fabric.Object} object Object to center vertically and horizontally\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n centerObject: function(object) {\n var center = this.getCenter();\n\n return this._centerObject(object, new fabric.Point(center.left, center.top));\n },\n\n /**\n * Centers object vertically and horizontally in the viewport\n * @param {fabric.Object} object Object to center vertically and horizontally\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n viewportCenterObject: function(object) {\n var vpCenter = this.getVpCenter();\n\n return this._centerObject(object, vpCenter);\n },\n\n /**\n * Centers object horizontally in the viewport, object.top is unchanged\n * @param {fabric.Object} object Object to center vertically and horizontally\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n viewportCenterObjectH: function(object) {\n var vpCenter = this.getVpCenter();\n this._centerObject(object, new fabric.Point(vpCenter.x, object.getCenterPoint().y));\n return this;\n },\n\n /**\n * Centers object Vertically in the viewport, object.top is unchanged\n * @param {fabric.Object} object Object to center vertically and horizontally\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n viewportCenterObjectV: function(object) {\n var vpCenter = this.getVpCenter();\n\n return this._centerObject(object, new fabric.Point(object.getCenterPoint().x, vpCenter.y));\n },\n\n /**\n * Calculate the point in canvas that correspond to the center of actual viewport.\n * @return {fabric.Point} vpCenter, viewport center\n * @chainable\n */\n getVpCenter: function() {\n var center = this.getCenter(),\n iVpt = invertTransform(this.viewportTransform);\n return transformPoint({ x: center.left, y: center.top }, iVpt);\n },\n\n /**\n * @private\n * @param {fabric.Object} object Object to center\n * @param {fabric.Point} center Center point\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n _centerObject: function(object, center) {\n object.setPositionByOrigin(center, 'center', 'center');\n object.setCoords();\n this.renderOnAddRemove && this.requestRenderAll();\n return this;\n },\n\n /**\n * Returs dataless JSON representation of canvas\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {String} json string\n */\n toDatalessJSON: function (propertiesToInclude) {\n return this.toDatalessObject(propertiesToInclude);\n },\n\n /**\n * Returns object representation of canvas\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject: function (propertiesToInclude) {\n return this._toObjectMethod('toObject', propertiesToInclude);\n },\n\n /**\n * Returns dataless object representation of canvas\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toDatalessObject: function (propertiesToInclude) {\n return this._toObjectMethod('toDatalessObject', propertiesToInclude);\n },\n\n /**\n * @private\n */\n _toObjectMethod: function (methodName, propertiesToInclude) {\n\n var clipPath = this.clipPath, data = {\n version: fabric.version,\n objects: this._toObjects(methodName, propertiesToInclude),\n };\n if (clipPath) {\n data.clipPath = this._toObject(this.clipPath, methodName, propertiesToInclude);\n }\n extend(data, this.__serializeBgOverlay(methodName, propertiesToInclude));\n\n fabric.util.populateWithProperties(this, data, propertiesToInclude);\n\n return data;\n },\n\n /**\n * @private\n */\n _toObjects: function(methodName, propertiesToInclude) {\n return this._objects.filter(function(object) {\n return !object.excludeFromExport;\n }).map(function(instance) {\n return this._toObject(instance, methodName, propertiesToInclude);\n }, this);\n },\n\n /**\n * @private\n */\n _toObject: function(instance, methodName, propertiesToInclude) {\n var originalValue;\n\n if (!this.includeDefaultValues) {\n originalValue = instance.includeDefaultValues;\n instance.includeDefaultValues = false;\n }\n\n var object = instance[methodName](propertiesToInclude);\n if (!this.includeDefaultValues) {\n instance.includeDefaultValues = originalValue;\n }\n return object;\n },\n\n /**\n * @private\n */\n __serializeBgOverlay: function(methodName, propertiesToInclude) {\n var data = { }, bgImage = this.backgroundImage, overlay = this.overlayImage;\n\n if (this.backgroundColor) {\n data.background = this.backgroundColor.toObject\n ? this.backgroundColor.toObject(propertiesToInclude)\n : this.backgroundColor;\n }\n\n if (this.overlayColor) {\n data.overlay = this.overlayColor.toObject\n ? this.overlayColor.toObject(propertiesToInclude)\n : this.overlayColor;\n }\n if (bgImage && !bgImage.excludeFromExport) {\n data.backgroundImage = this._toObject(bgImage, methodName, propertiesToInclude);\n }\n if (overlay && !overlay.excludeFromExport) {\n data.overlayImage = this._toObject(overlay, methodName, propertiesToInclude);\n }\n\n return data;\n },\n\n /* _TO_SVG_START_ */\n /**\n * When true, getSvgTransform() will apply the StaticCanvas.viewportTransform to the SVG transformation. When true,\n * a zoomed canvas will then produce zoomed SVG output.\n * @type Boolean\n * @default\n */\n svgViewportTransformation: true,\n\n /**\n * Returns SVG representation of canvas\n * @function\n * @param {Object} [options] Options object for SVG output\n * @param {Boolean} [options.suppressPreamble=false] If true xml tag is not included\n * @param {Object} [options.viewBox] SVG viewbox object\n * @param {Number} [options.viewBox.x] x-cooridnate of viewbox\n * @param {Number} [options.viewBox.y] y-coordinate of viewbox\n * @param {Number} [options.viewBox.width] Width of viewbox\n * @param {Number} [options.viewBox.height] Height of viewbox\n * @param {String} [options.encoding=UTF-8] Encoding of SVG output\n * @param {String} [options.width] desired width of svg with or without units\n * @param {String} [options.height] desired height of svg with or without units\n * @param {Function} [reviver] Method for further parsing of svg elements, called after each fabric object converted into svg representation.\n * @return {String} SVG string\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#serialization}\n * @see {@link http://jsfiddle.net/fabricjs/jQ3ZZ/|jsFiddle demo}\n * @example <caption>Normal SVG output</caption>\n * var svg = canvas.toSVG();\n * @example <caption>SVG output without preamble (without <?xml ../>)</caption>\n * var svg = canvas.toSVG({suppressPreamble: true});\n * @example <caption>SVG output with viewBox attribute</caption>\n * var svg = canvas.toSVG({\n * viewBox: {\n * x: 100,\n * y: 100,\n * width: 200,\n * height: 300\n * }\n * });\n * @example <caption>SVG output with different encoding (default: UTF-8)</caption>\n * var svg = canvas.toSVG({encoding: 'ISO-8859-1'});\n * @example <caption>Modify SVG output with reviver function</caption>\n * var svg = canvas.toSVG(null, function(svg) {\n * return svg.replace('stroke-dasharray: ; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; ', '');\n * });\n */\n toSVG: function(options, reviver) {\n options || (options = { });\n options.reviver = reviver;\n var markup = [];\n\n this._setSVGPreamble(markup, options);\n this._setSVGHeader(markup, options);\n if (this.clipPath) {\n markup.push('<g clip-path=\"url(#' + this.clipPath.clipPathId + ')\" >\\n');\n }\n this._setSVGBgOverlayColor(markup, 'background');\n this._setSVGBgOverlayImage(markup, 'backgroundImage', reviver);\n this._setSVGObjects(markup, reviver);\n if (this.clipPath) {\n markup.push('</g>\\n');\n }\n this._setSVGBgOverlayColor(markup, 'overlay');\n this._setSVGBgOverlayImage(markup, 'overlayImage', reviver);\n\n markup.push('</svg>');\n\n return markup.join('');\n },\n\n /**\n * @private\n */\n _setSVGPreamble: function(markup, options) {\n if (options.suppressPreamble) {\n return;\n }\n markup.push(\n '<?xml version=\"1.0\" encoding=\"', (options.encoding || 'UTF-8'), '\" standalone=\"no\" ?>\\n',\n '<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" ',\n '\"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\\n'\n );\n },\n\n /**\n * @private\n */\n _setSVGHeader: function(markup, options) {\n var width = options.width || this.width,\n height = options.height || this.height,\n vpt, viewBox = 'viewBox=\"0 0 ' + this.width + ' ' + this.height + '\" ',\n NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS;\n\n if (options.viewBox) {\n viewBox = 'viewBox=\"' +\n options.viewBox.x + ' ' +\n options.viewBox.y + ' ' +\n options.viewBox.width + ' ' +\n options.viewBox.height + '\" ';\n }\n else {\n if (this.svgViewportTransformation) {\n vpt = this.viewportTransform;\n viewBox = 'viewBox=\"' +\n toFixed(-vpt[4] / vpt[0], NUM_FRACTION_DIGITS) + ' ' +\n toFixed(-vpt[5] / vpt[3], NUM_FRACTION_DIGITS) + ' ' +\n toFixed(this.width / vpt[0], NUM_FRACTION_DIGITS) + ' ' +\n toFixed(this.height / vpt[3], NUM_FRACTION_DIGITS) + '\" ';\n }\n }\n\n markup.push(\n '<svg ',\n 'xmlns=\"http://www.w3.org/2000/svg\" ',\n 'xmlns:xlink=\"http://www.w3.org/1999/xlink\" ',\n 'version=\"1.1\" ',\n 'width=\"', width, '\" ',\n 'height=\"', height, '\" ',\n viewBox,\n 'xml:space=\"preserve\">\\n',\n '<desc>Created with Fabric.js ', fabric.version, '</desc>\\n',\n '<defs>\\n',\n this.createSVGFontFacesMarkup(),\n this.createSVGRefElementsMarkup(),\n this.createSVGClipPathMarkup(options),\n '</defs>\\n'\n );\n },\n\n createSVGClipPathMarkup: function(options) {\n var clipPath = this.clipPath;\n if (clipPath) {\n clipPath.clipPathId = 'CLIPPATH_' + fabric.Object.__uid++;\n return '<clipPath id=\"' + clipPath.clipPathId + '\" >\\n' +\n this.clipPath.toClipPathSVG(options.reviver) +\n '</clipPath>\\n';\n }\n return '';\n },\n\n /**\n * Creates markup containing SVG referenced elements like patterns, gradients etc.\n * @return {String}\n */\n createSVGRefElementsMarkup: function() {\n var _this = this,\n markup = ['background', 'overlay'].map(function(prop) {\n var fill = _this[prop + 'Color'];\n if (fill && fill.toLive) {\n var shouldTransform = _this[prop + 'Vpt'], vpt = _this.viewportTransform,\n object = {\n width: _this.width / (shouldTransform ? vpt[0] : 1),\n height: _this.height / (shouldTransform ? vpt[3] : 1)\n };\n return fill.toSVG(\n object,\n { additionalTransform: shouldTransform ? fabric.util.matrixToSVG(vpt) : '' }\n );\n }\n });\n return markup.join('');\n },\n\n /**\n * Creates markup containing SVG font faces,\n * font URLs for font faces must be collected by developers\n * and are not extracted from the DOM by fabricjs\n * @param {Array} objects Array of fabric objects\n * @return {String}\n */\n createSVGFontFacesMarkup: function() {\n var markup = '', fontList = { }, obj, fontFamily,\n style, row, rowIndex, _char, charIndex, i, len,\n fontPaths = fabric.fontPaths, objects = [];\n\n this._objects.forEach(function add(object) {\n objects.push(object);\n if (object._objects) {\n object._objects.forEach(add);\n }\n });\n\n for (i = 0, len = objects.length; i < len; i++) {\n obj = objects[i];\n fontFamily = obj.fontFamily;\n if (obj.type.indexOf('text') === -1 || fontList[fontFamily] || !fontPaths[fontFamily]) {\n continue;\n }\n fontList[fontFamily] = true;\n if (!obj.styles) {\n continue;\n }\n style = obj.styles;\n for (rowIndex in style) {\n row = style[rowIndex];\n for (charIndex in row) {\n _char = row[charIndex];\n fontFamily = _char.fontFamily;\n if (!fontList[fontFamily] && fontPaths[fontFamily]) {\n fontList[fontFamily] = true;\n }\n }\n }\n }\n\n for (var j in fontList) {\n markup += [\n '\\t\\t@font-face {\\n',\n '\\t\\t\\tfont-family: \\'', j, '\\';\\n',\n '\\t\\t\\tsrc: url(\\'', fontPaths[j], '\\');\\n',\n '\\t\\t}\\n'\n ].join('');\n }\n\n if (markup) {\n markup = [\n '\\t<style type=\"text/css\">',\n '<![CDATA[\\n',\n markup,\n ']]>',\n '</style>\\n'\n ].join('');\n }\n\n return markup;\n },\n\n /**\n * @private\n */\n _setSVGObjects: function(markup, reviver) {\n var instance, i, len, objects = this._objects;\n for (i = 0, len = objects.length; i < len; i++) {\n instance = objects[i];\n if (instance.excludeFromExport) {\n continue;\n }\n this._setSVGObject(markup, instance, reviver);\n }\n },\n\n /**\n * @private\n */\n _setSVGObject: function(markup, instance, reviver) {\n markup.push(instance.toSVG(reviver));\n },\n\n /**\n * @private\n */\n _setSVGBgOverlayImage: function(markup, property, reviver) {\n if (this[property] && !this[property].excludeFromExport && this[property].toSVG) {\n markup.push(this[property].toSVG(reviver));\n }\n },\n\n /**\n * @private\n */\n _setSVGBgOverlayColor: function(markup, property) {\n var filler = this[property + 'Color'], vpt = this.viewportTransform, finalWidth = this.width,\n finalHeight = this.height;\n if (!filler) {\n return;\n }\n if (filler.toLive) {\n var repeat = filler.repeat, iVpt = fabric.util.invertTransform(vpt), shouldInvert = this[property + 'Vpt'],\n additionalTransform = shouldInvert ? fabric.util.matrixToSVG(iVpt) : '';\n markup.push(\n '<rect transform=\"' + additionalTransform + ' translate(', finalWidth / 2, ',', finalHeight / 2, ')\"',\n ' x=\"', filler.offsetX - finalWidth / 2,\n '\" y=\"', filler.offsetY - finalHeight / 2, '\" ',\n 'width=\"',\n (repeat === 'repeat-y' || repeat === 'no-repeat'\n ? filler.source.width\n : finalWidth ),\n '\" height=\"',\n (repeat === 'repeat-x' || repeat === 'no-repeat'\n ? filler.source.height\n : finalHeight),\n '\" fill=\"url(#SVGID_' + filler.id + ')\"',\n '></rect>\\n'\n );\n }\n else {\n markup.push(\n '<rect x=\"0\" y=\"0\" width=\"100%\" height=\"100%\" ',\n 'fill=\"', filler, '\"',\n '></rect>\\n'\n );\n }\n },\n /* _TO_SVG_END_ */\n\n /**\n * Moves an object or the objects of a multiple selection\n * to the bottom of the stack of drawn objects\n * @param {fabric.Object} object Object to send to back\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n sendToBack: function (object) {\n if (!object) {\n return this;\n }\n var activeSelection = this._activeObject,\n i, obj, objs;\n if (object === activeSelection && object.type === 'activeSelection') {\n objs = activeSelection._objects;\n for (i = objs.length; i--;) {\n obj = objs[i];\n removeFromArray(this._objects, obj);\n this._objects.unshift(obj);\n }\n }\n else {\n removeFromArray(this._objects, object);\n this._objects.unshift(object);\n }\n this.renderOnAddRemove && this.requestRenderAll();\n return this;\n },\n\n /**\n * Moves an object or the objects of a multiple selection\n * to the top of the stack of drawn objects\n * @param {fabric.Object} object Object to send\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n bringToFront: function (object) {\n if (!object) {\n return this;\n }\n var activeSelection = this._activeObject,\n i, obj, objs;\n if (object === activeSelection && object.type === 'activeSelection') {\n objs = activeSelection._objects;\n for (i = 0; i < objs.length; i++) {\n obj = objs[i];\n removeFromArray(this._objects, obj);\n this._objects.push(obj);\n }\n }\n else {\n removeFromArray(this._objects, object);\n this._objects.push(object);\n }\n this.renderOnAddRemove && this.requestRenderAll();\n return this;\n },\n\n /**\n * Moves an object or a selection down in stack of drawn objects\n * An optional paramter, intersecting allowes to move the object in behind\n * the first intersecting object. Where intersection is calculated with\n * bounding box. If no intersection is found, there will not be change in the\n * stack.\n * @param {fabric.Object} object Object to send\n * @param {Boolean} [intersecting] If `true`, send object behind next lower intersecting object\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n sendBackwards: function (object, intersecting) {\n if (!object) {\n return this;\n }\n var activeSelection = this._activeObject,\n i, obj, idx, newIdx, objs, objsMoved = 0;\n\n if (object === activeSelection && object.type === 'activeSelection') {\n objs = activeSelection._objects;\n for (i = 0; i < objs.length; i++) {\n obj = objs[i];\n idx = this._objects.indexOf(obj);\n if (idx > 0 + objsMoved) {\n newIdx = idx - 1;\n removeFromArray(this._objects, obj);\n this._objects.splice(newIdx, 0, obj);\n }\n objsMoved++;\n }\n }\n else {\n idx = this._objects.indexOf(object);\n if (idx !== 0) {\n // if object is not on the bottom of stack\n newIdx = this._findNewLowerIndex(object, idx, intersecting);\n removeFromArray(this._objects, object);\n this._objects.splice(newIdx, 0, object);\n }\n }\n this.renderOnAddRemove && this.requestRenderAll();\n return this;\n },\n\n /**\n * @private\n */\n _findNewLowerIndex: function(object, idx, intersecting) {\n var newIdx, i;\n\n if (intersecting) {\n newIdx = idx;\n\n // traverse down the stack looking for the nearest intersecting object\n for (i = idx - 1; i >= 0; --i) {\n\n var isIntersecting = object.intersectsWithObject(this._objects[i]) ||\n object.isContainedWithinObject(this._objects[i]) ||\n this._objects[i].isContainedWithinObject(object);\n\n if (isIntersecting) {\n newIdx = i;\n break;\n }\n }\n }\n else {\n newIdx = idx - 1;\n }\n\n return newIdx;\n },\n\n /**\n * Moves an object or a selection up in stack of drawn objects\n * An optional paramter, intersecting allowes to move the object in front\n * of the first intersecting object. Where intersection is calculated with\n * bounding box. If no intersection is found, there will not be change in the\n * stack.\n * @param {fabric.Object} object Object to send\n * @param {Boolean} [intersecting] If `true`, send object in front of next upper intersecting object\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n bringForward: function (object, intersecting) {\n if (!object) {\n return this;\n }\n var activeSelection = this._activeObject,\n i, obj, idx, newIdx, objs, objsMoved = 0;\n\n if (object === activeSelection && object.type === 'activeSelection') {\n objs = activeSelection._objects;\n for (i = objs.length; i--;) {\n obj = objs[i];\n idx = this._objects.indexOf(obj);\n if (idx < this._objects.length - 1 - objsMoved) {\n newIdx = idx + 1;\n removeFromArray(this._objects, obj);\n this._objects.splice(newIdx, 0, obj);\n }\n objsMoved++;\n }\n }\n else {\n idx = this._objects.indexOf(object);\n if (idx !== this._objects.length - 1) {\n // if object is not on top of stack (last item in an array)\n newIdx = this._findNewUpperIndex(object, idx, intersecting);\n removeFromArray(this._objects, object);\n this._objects.splice(newIdx, 0, object);\n }\n }\n this.renderOnAddRemove && this.requestRenderAll();\n return this;\n },\n\n /**\n * @private\n */\n _findNewUpperIndex: function(object, idx, intersecting) {\n var newIdx, i, len;\n\n if (intersecting) {\n newIdx = idx;\n\n // traverse up the stack looking for the nearest intersecting object\n for (i = idx + 1, len = this._objects.length; i < len; ++i) {\n\n var isIntersecting = object.intersectsWithObject(this._objects[i]) ||\n object.isContainedWithinObject(this._objects[i]) ||\n this._objects[i].isContainedWithinObject(object);\n\n if (isIntersecting) {\n newIdx = i;\n break;\n }\n }\n }\n else {\n newIdx = idx + 1;\n }\n\n return newIdx;\n },\n\n /**\n * Moves an object to specified level in stack of drawn objects\n * @param {fabric.Object} object Object to send\n * @param {Number} index Position to move to\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n moveTo: function (object, index) {\n removeFromArray(this._objects, object);\n this._objects.splice(index, 0, object);\n return this.renderOnAddRemove && this.requestRenderAll();\n },\n\n /**\n * Clears a canvas element and dispose objects\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n dispose: function () {\n // cancel eventually ongoing renders\n if (this.isRendering) {\n fabric.util.cancelAnimFrame(this.isRendering);\n this.isRendering = 0;\n }\n this.forEachObject(function(object) {\n object.dispose && object.dispose();\n });\n this._objects = [];\n if (this.backgroundImage && this.backgroundImage.dispose) {\n this.backgroundImage.dispose();\n }\n this.backgroundImage = null;\n if (this.overlayImage && this.overlayImage.dispose) {\n this.overlayImage.dispose();\n }\n this.overlayImage = null;\n this._iTextInstances = null;\n this.contextContainer = null;\n fabric.util.cleanUpJsdomNode(this.lowerCanvasEl);\n this.lowerCanvasEl = undefined;\n return this;\n },\n\n /**\n * Returns a string representation of an instance\n * @return {String} string representation of an instance\n */\n toString: function () {\n return '#<fabric.Canvas (' + this.complexity() + '): ' +\n '{ objects: ' + this._objects.length + ' }>';\n }\n });\n\n extend(fabric.StaticCanvas.prototype, fabric.Observable);\n extend(fabric.StaticCanvas.prototype, fabric.Collection);\n extend(fabric.StaticCanvas.prototype, fabric.DataURLExporter);\n\n extend(fabric.StaticCanvas, /** @lends fabric.StaticCanvas */ {\n\n /**\n * @static\n * @type String\n * @default\n */\n EMPTY_JSON: '{\"objects\": [], \"background\": \"white\"}',\n\n /**\n * Provides a way to check support of some of the canvas methods\n * (either those of HTMLCanvasElement itself, or rendering context)\n *\n * @param {String} methodName Method to check support for;\n * Could be one of \"setLineDash\"\n * @return {Boolean | null} `true` if method is supported (or at least exists),\n * `null` if canvas element or context can not be initialized\n */\n supports: function (methodName) {\n var el = createCanvasElement();\n\n if (!el || !el.getContext) {\n return null;\n }\n\n var ctx = el.getContext('2d');\n if (!ctx) {\n return null;\n }\n\n switch (methodName) {\n\n case 'setLineDash':\n return typeof ctx.setLineDash !== 'undefined';\n\n default:\n return null;\n }\n }\n });\n\n /**\n * Returns JSON representation of canvas\n * @function\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {String} JSON string\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#serialization}\n * @see {@link http://jsfiddle.net/fabricjs/pec86/|jsFiddle demo}\n * @example <caption>JSON without additional properties</caption>\n * var json = canvas.toJSON();\n * @example <caption>JSON with additional properties included</caption>\n * var json = canvas.toJSON(['lockMovementX', 'lockMovementY', 'lockRotation', 'lockScalingX', 'lockScalingY']);\n * @example <caption>JSON without default values</caption>\n * canvas.includeDefaultValues = false;\n * var json = canvas.toJSON();\n */\n fabric.StaticCanvas.prototype.toJSON = fabric.StaticCanvas.prototype.toObject;\n\n if (fabric.isLikelyNode) {\n fabric.StaticCanvas.prototype.createPNGStream = function() {\n var impl = getNodeCanvas(this.lowerCanvasEl);\n return impl && impl.createPNGStream();\n };\n fabric.StaticCanvas.prototype.createJPEGStream = function(opts) {\n var impl = getNodeCanvas(this.lowerCanvasEl);\n return impl && impl.createJPEGStream(opts);\n };\n }\n})();\n\n\n/**\n * BaseBrush class\n * @class fabric.BaseBrush\n * @see {@link http://fabricjs.com/freedrawing|Freedrawing demo}\n */\nfabric.BaseBrush = fabric.util.createClass(/** @lends fabric.BaseBrush.prototype */ {\n\n /**\n * Color of a brush\n * @type String\n * @default\n */\n color: 'rgb(0, 0, 0)',\n\n /**\n * Width of a brush, has to be a Number, no string literals\n * @type Number\n * @default\n */\n width: 1,\n\n /**\n * Shadow object representing shadow of this shape.\n * <b>Backwards incompatibility note:</b> This property replaces \"shadowColor\" (String), \"shadowOffsetX\" (Number),\n * \"shadowOffsetY\" (Number) and \"shadowBlur\" (Number) since v1.2.12\n * @type fabric.Shadow\n * @default\n */\n shadow: null,\n\n /**\n * Line endings style of a brush (one of \"butt\", \"round\", \"square\")\n * @type String\n * @default\n */\n strokeLineCap: 'round',\n\n /**\n * Corner style of a brush (one of \"bevel\", \"round\", \"miter\")\n * @type String\n * @default\n */\n strokeLineJoin: 'round',\n\n /**\n * Maximum miter length (used for strokeLineJoin = \"miter\") of a brush's\n * @type Number\n * @default\n */\n strokeMiterLimit: 10,\n\n /**\n * Stroke Dash Array.\n * @type Array\n * @default\n */\n strokeDashArray: null,\n\n /**\n * Sets brush styles\n * @private\n */\n _setBrushStyles: function() {\n var ctx = this.canvas.contextTop;\n ctx.strokeStyle = this.color;\n ctx.lineWidth = this.width;\n ctx.lineCap = this.strokeLineCap;\n ctx.miterLimit = this.strokeMiterLimit;\n ctx.lineJoin = this.strokeLineJoin;\n if (fabric.StaticCanvas.supports('setLineDash')) {\n ctx.setLineDash(this.strokeDashArray || []);\n }\n },\n\n /**\n * Sets the transformation on given context\n * @param {RenderingContext2d} ctx context to render on\n * @private\n */\n _saveAndTransform: function(ctx) {\n var v = this.canvas.viewportTransform;\n ctx.save();\n ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]);\n },\n\n /**\n * Sets brush shadow styles\n * @private\n */\n _setShadow: function() {\n if (!this.shadow) {\n return;\n }\n\n var canvas = this.canvas,\n shadow = this.shadow,\n ctx = canvas.contextTop,\n zoom = canvas.getZoom();\n if (canvas && canvas._isRetinaScaling()) {\n zoom *= fabric.devicePixelRatio;\n }\n\n ctx.shadowColor = shadow.color;\n ctx.shadowBlur = shadow.blur * zoom;\n ctx.shadowOffsetX = shadow.offsetX * zoom;\n ctx.shadowOffsetY = shadow.offsetY * zoom;\n },\n\n needsFullRender: function() {\n var color = new fabric.Color(this.color);\n return color.getAlpha() < 1 || !!this.shadow;\n },\n\n /**\n * Removes brush shadow styles\n * @private\n */\n _resetShadow: function() {\n var ctx = this.canvas.contextTop;\n\n ctx.shadowColor = '';\n ctx.shadowBlur = ctx.shadowOffsetX = ctx.shadowOffsetY = 0;\n }\n});\n\n\n(function() {\n /**\n * PencilBrush class\n * @class fabric.PencilBrush\n * @extends fabric.BaseBrush\n */\n fabric.PencilBrush = fabric.util.createClass(fabric.BaseBrush, /** @lends fabric.PencilBrush.prototype */ {\n\n /**\n * Discard points that are less than `decimate` pixel distant from each other\n * @type Number\n * @default 0.4\n */\n decimate: 0.4,\n\n /**\n * Constructor\n * @param {fabric.Canvas} canvas\n * @return {fabric.PencilBrush} Instance of a pencil brush\n */\n initialize: function(canvas) {\n this.canvas = canvas;\n this._points = [];\n },\n\n /**\n * Invoked inside on mouse down and mouse move\n * @param {Object} pointer\n */\n _drawSegment: function (ctx, p1, p2) {\n var midPoint = p1.midPointFrom(p2);\n ctx.quadraticCurveTo(p1.x, p1.y, midPoint.x, midPoint.y);\n return midPoint;\n },\n\n /**\n * Inovoked on mouse down\n * @param {Object} pointer\n */\n onMouseDown: function(pointer, options) {\n if (!this.canvas._isMainEvent(options.e)) {\n return;\n }\n this._prepareForDrawing(pointer);\n // capture coordinates immediately\n // this allows to draw dots (when movement never occurs)\n this._captureDrawingPath(pointer);\n this._render();\n },\n\n /**\n * Inovoked on mouse move\n * @param {Object} pointer\n */\n onMouseMove: function(pointer, options) {\n if (!this.canvas._isMainEvent(options.e)) {\n return;\n }\n if (this._captureDrawingPath(pointer) && this._points.length > 1) {\n if (this.needsFullRender()) {\n // redraw curve\n // clear top canvas\n this.canvas.clearContext(this.canvas.contextTop);\n this._render();\n }\n else {\n var points = this._points, length = points.length, ctx = this.canvas.contextTop;\n // draw the curve update\n this._saveAndTransform(ctx);\n if (this.oldEnd) {\n ctx.beginPath();\n ctx.moveTo(this.oldEnd.x, this.oldEnd.y);\n }\n this.oldEnd = this._drawSegment(ctx, points[length - 2], points[length - 1], true);\n ctx.stroke();\n ctx.restore();\n }\n }\n },\n\n /**\n * Invoked on mouse up\n */\n onMouseUp: function(options) {\n if (!this.canvas._isMainEvent(options.e)) {\n return true;\n }\n this.oldEnd = undefined;\n this._finalizeAndAddPath();\n return false;\n },\n\n /**\n * @private\n * @param {Object} pointer Actual mouse position related to the canvas.\n */\n _prepareForDrawing: function(pointer) {\n\n var p = new fabric.Point(pointer.x, pointer.y);\n\n this._reset();\n this._addPoint(p);\n this.canvas.contextTop.moveTo(p.x, p.y);\n },\n\n /**\n * @private\n * @param {fabric.Point} point Point to be added to points array\n */\n _addPoint: function(point) {\n if (this._points.length > 1 && point.eq(this._points[this._points.length - 1])) {\n return false;\n }\n this._points.push(point);\n return true;\n },\n\n /**\n * Clear points array and set contextTop canvas style.\n * @private\n */\n _reset: function() {\n this._points = [];\n this._setBrushStyles();\n this._setShadow();\n },\n\n /**\n * @private\n * @param {Object} pointer Actual mouse position related to the canvas.\n */\n _captureDrawingPath: function(pointer) {\n var pointerPoint = new fabric.Point(pointer.x, pointer.y);\n return this._addPoint(pointerPoint);\n },\n\n /**\n * Draw a smooth path on the topCanvas using quadraticCurveTo\n * @private\n */\n _render: function() {\n var ctx = this.canvas.contextTop, i, len,\n p1 = this._points[0],\n p2 = this._points[1];\n\n this._saveAndTransform(ctx);\n ctx.beginPath();\n //if we only have 2 points in the path and they are the same\n //it means that the user only clicked the canvas without moving the mouse\n //then we should be drawing a dot. A path isn't drawn between two identical dots\n //that's why we set them apart a bit\n if (this._points.length === 2 && p1.x === p2.x && p1.y === p2.y) {\n var width = this.width / 1000;\n p1 = new fabric.Point(p1.x, p1.y);\n p2 = new fabric.Point(p2.x, p2.y);\n p1.x -= width;\n p2.x += width;\n }\n ctx.moveTo(p1.x, p1.y);\n\n for (i = 1, len = this._points.length; i < len; i++) {\n // we pick the point between pi + 1 & pi + 2 as the\n // end point and p1 as our control point.\n this._drawSegment(ctx, p1, p2);\n p1 = this._points[i];\n p2 = this._points[i + 1];\n }\n // Draw last line as a straight line while\n // we wait for the next point to be able to calculate\n // the bezier control point\n ctx.lineTo(p1.x, p1.y);\n ctx.stroke();\n ctx.restore();\n },\n\n /**\n * Converts points to SVG path\n * @param {Array} points Array of points\n * @return {String} SVG path\n */\n convertPointsToSVGPath: function(points) {\n var path = [], i, width = this.width / 1000,\n p1 = new fabric.Point(points[0].x, points[0].y),\n p2 = new fabric.Point(points[1].x, points[1].y),\n len = points.length, multSignX = 1, multSignY = 0, manyPoints = len > 2;\n\n if (manyPoints) {\n multSignX = points[2].x < p2.x ? -1 : points[2].x === p2.x ? 0 : 1;\n multSignY = points[2].y < p2.y ? -1 : points[2].y === p2.y ? 0 : 1;\n }\n path.push('M ', p1.x - multSignX * width, ' ', p1.y - multSignY * width, ' ');\n for (i = 1; i < len; i++) {\n if (!p1.eq(p2)) {\n var midPoint = p1.midPointFrom(p2);\n // p1 is our bezier control point\n // midpoint is our endpoint\n // start point is p(i-1) value.\n path.push('Q ', p1.x, ' ', p1.y, ' ', midPoint.x, ' ', midPoint.y, ' ');\n }\n p1 = points[i];\n if ((i + 1) < points.length) {\n p2 = points[i + 1];\n }\n }\n if (manyPoints) {\n multSignX = p1.x > points[i - 2].x ? 1 : p1.x === points[i - 2].x ? 0 : -1;\n multSignY = p1.y > points[i - 2].y ? 1 : p1.y === points[i - 2].y ? 0 : -1;\n }\n path.push('L ', p1.x + multSignX * width, ' ', p1.y + multSignY * width);\n return path;\n },\n\n /**\n * Creates fabric.Path object to add on canvas\n * @param {String} pathData Path data\n * @return {fabric.Path} Path to add on canvas\n */\n createPath: function(pathData) {\n var path = new fabric.Path(pathData, {\n fill: null,\n stroke: this.color,\n strokeWidth: this.width,\n strokeLineCap: this.strokeLineCap,\n strokeMiterLimit: this.strokeMiterLimit,\n strokeLineJoin: this.strokeLineJoin,\n strokeDashArray: this.strokeDashArray,\n });\n if (this.shadow) {\n this.shadow.affectStroke = true;\n path.shadow = new fabric.Shadow(this.shadow);\n }\n\n return path;\n },\n\n /**\n * Decimate poins array with the decimate value\n */\n decimatePoints: function(points, distance) {\n if (points.length <= 2) {\n return points;\n }\n var zoom = this.canvas.getZoom(), adjustedDistance = Math.pow(distance / zoom, 2),\n i, l = points.length - 1, lastPoint = points[0], newPoints = [lastPoint],\n cDistance;\n for (i = 1; i < l; i++) {\n cDistance = Math.pow(lastPoint.x - points[i].x, 2) + Math.pow(lastPoint.y - points[i].y, 2);\n if (cDistance >= adjustedDistance) {\n lastPoint = points[i];\n newPoints.push(lastPoint);\n }\n }\n if (newPoints.length === 1) {\n newPoints.push(new fabric.Point(newPoints[0].x, newPoints[0].y));\n }\n return newPoints;\n },\n\n /**\n * On mouseup after drawing the path on contextTop canvas\n * we use the points captured to create an new fabric path object\n * and add it to the fabric canvas.\n */\n _finalizeAndAddPath: function() {\n var ctx = this.canvas.contextTop;\n ctx.closePath();\n if (this.decimate) {\n this._points = this.decimatePoints(this._points, this.decimate);\n }\n var pathData = this.convertPointsToSVGPath(this._points).join('');\n if (pathData === 'M 0 0 Q 0 0 0 0 L 0 0') {\n // do not create 0 width/height paths, as they are\n // rendered inconsistently across browsers\n // Firefox 4, for example, renders a dot,\n // whereas Chrome 10 renders nothing\n this.canvas.requestRenderAll();\n return;\n }\n\n var path = this.createPath(pathData);\n this.canvas.clearContext(this.canvas.contextTop);\n this.canvas.fire('before:path:created', { path: path });\n this.canvas.add(path);\n this.canvas.requestRenderAll();\n path.setCoords();\n this._resetShadow();\n\n\n // fire event 'path' created\n this.canvas.fire('path:created', { path: path });\n }\n });\n})();\n\n\n/**\n * CircleBrush class\n * @class fabric.CircleBrush\n */\nfabric.CircleBrush = fabric.util.createClass(fabric.BaseBrush, /** @lends fabric.CircleBrush.prototype */ {\n\n /**\n * Width of a brush\n * @type Number\n * @default\n */\n width: 10,\n\n /**\n * Constructor\n * @param {fabric.Canvas} canvas\n * @return {fabric.CircleBrush} Instance of a circle brush\n */\n initialize: function(canvas) {\n this.canvas = canvas;\n this.points = [];\n },\n\n /**\n * Invoked inside on mouse down and mouse move\n * @param {Object} pointer\n */\n drawDot: function(pointer) {\n var point = this.addPoint(pointer),\n ctx = this.canvas.contextTop;\n this._saveAndTransform(ctx);\n this.dot(ctx, point);\n ctx.restore();\n },\n\n dot: function(ctx, point) {\n ctx.fillStyle = point.fill;\n ctx.beginPath();\n ctx.arc(point.x, point.y, point.radius, 0, Math.PI * 2, false);\n ctx.closePath();\n ctx.fill();\n },\n\n /**\n * Invoked on mouse down\n */\n onMouseDown: function(pointer) {\n this.points.length = 0;\n this.canvas.clearContext(this.canvas.contextTop);\n this._setShadow();\n this.drawDot(pointer);\n },\n\n /**\n * Render the full state of the brush\n * @private\n */\n _render: function() {\n var ctx = this.canvas.contextTop, i, len,\n points = this.points;\n this._saveAndTransform(ctx);\n for (i = 0, len = points.length; i < len; i++) {\n this.dot(ctx, points[i]);\n }\n ctx.restore();\n },\n\n /**\n * Invoked on mouse move\n * @param {Object} pointer\n */\n onMouseMove: function(pointer) {\n if (this.needsFullRender()) {\n this.canvas.clearContext(this.canvas.contextTop);\n this.addPoint(pointer);\n this._render();\n }\n else {\n this.drawDot(pointer);\n }\n },\n\n /**\n * Invoked on mouse up\n */\n onMouseUp: function() {\n var originalRenderOnAddRemove = this.canvas.renderOnAddRemove, i, len;\n this.canvas.renderOnAddRemove = false;\n\n var circles = [];\n\n for (i = 0, len = this.points.length; i < len; i++) {\n var point = this.points[i],\n circle = new fabric.Circle({\n radius: point.radius,\n left: point.x,\n top: point.y,\n originX: 'center',\n originY: 'center',\n fill: point.fill\n });\n\n this.shadow && (circle.shadow = new fabric.Shadow(this.shadow));\n\n circles.push(circle);\n }\n var group = new fabric.Group(circles);\n group.canvas = this.canvas;\n\n this.canvas.fire('before:path:created', { path: group });\n this.canvas.add(group);\n this.canvas.fire('path:created', { path: group });\n\n this.canvas.clearContext(this.canvas.contextTop);\n this._resetShadow();\n this.canvas.renderOnAddRemove = originalRenderOnAddRemove;\n this.canvas.requestRenderAll();\n },\n\n /**\n * @param {Object} pointer\n * @return {fabric.Point} Just added pointer point\n */\n addPoint: function(pointer) {\n var pointerPoint = new fabric.Point(pointer.x, pointer.y),\n\n circleRadius = fabric.util.getRandomInt(\n Math.max(0, this.width - 20), this.width + 20) / 2,\n\n circleColor = new fabric.Color(this.color)\n .setAlpha(fabric.util.getRandomInt(0, 100) / 100)\n .toRgba();\n\n pointerPoint.radius = circleRadius;\n pointerPoint.fill = circleColor;\n\n this.points.push(pointerPoint);\n\n return pointerPoint;\n }\n});\n\n\n/**\n * SprayBrush class\n * @class fabric.SprayBrush\n */\nfabric.SprayBrush = fabric.util.createClass( fabric.BaseBrush, /** @lends fabric.SprayBrush.prototype */ {\n\n /**\n * Width of a spray\n * @type Number\n * @default\n */\n width: 10,\n\n /**\n * Density of a spray (number of dots per chunk)\n * @type Number\n * @default\n */\n density: 20,\n\n /**\n * Width of spray dots\n * @type Number\n * @default\n */\n dotWidth: 1,\n\n /**\n * Width variance of spray dots\n * @type Number\n * @default\n */\n dotWidthVariance: 1,\n\n /**\n * Whether opacity of a dot should be random\n * @type Boolean\n * @default\n */\n randomOpacity: false,\n\n /**\n * Whether overlapping dots (rectangles) should be removed (for performance reasons)\n * @type Boolean\n * @default\n */\n optimizeOverlapping: true,\n\n /**\n * Constructor\n * @param {fabric.Canvas} canvas\n * @return {fabric.SprayBrush} Instance of a spray brush\n */\n initialize: function(canvas) {\n this.canvas = canvas;\n this.sprayChunks = [];\n },\n\n /**\n * Invoked on mouse down\n * @param {Object} pointer\n */\n onMouseDown: function(pointer) {\n this.sprayChunks.length = 0;\n this.canvas.clearContext(this.canvas.contextTop);\n this._setShadow();\n\n this.addSprayChunk(pointer);\n this.render(this.sprayChunkPoints);\n },\n\n /**\n * Invoked on mouse move\n * @param {Object} pointer\n */\n onMouseMove: function(pointer) {\n this.addSprayChunk(pointer);\n this.render(this.sprayChunkPoints);\n },\n\n /**\n * Invoked on mouse up\n */\n onMouseUp: function() {\n var originalRenderOnAddRemove = this.canvas.renderOnAddRemove;\n this.canvas.renderOnAddRemove = false;\n\n var rects = [];\n\n for (var i = 0, ilen = this.sprayChunks.length; i < ilen; i++) {\n var sprayChunk = this.sprayChunks[i];\n\n for (var j = 0, jlen = sprayChunk.length; j < jlen; j++) {\n\n var rect = new fabric.Rect({\n width: sprayChunk[j].width,\n height: sprayChunk[j].width,\n left: sprayChunk[j].x + 1,\n top: sprayChunk[j].y + 1,\n originX: 'center',\n originY: 'center',\n fill: this.color\n });\n rects.push(rect);\n }\n }\n\n if (this.optimizeOverlapping) {\n rects = this._getOptimizedRects(rects);\n }\n\n var group = new fabric.Group(rects);\n this.shadow && group.set('shadow', new fabric.Shadow(this.shadow));\n this.canvas.fire('before:path:created', { path: group });\n this.canvas.add(group);\n this.canvas.fire('path:created', { path: group });\n\n this.canvas.clearContext(this.canvas.contextTop);\n this._resetShadow();\n this.canvas.renderOnAddRemove = originalRenderOnAddRemove;\n this.canvas.requestRenderAll();\n },\n\n /**\n * @private\n * @param {Array} rects\n */\n _getOptimizedRects: function(rects) {\n\n // avoid creating duplicate rects at the same coordinates\n var uniqueRects = { }, key, i, len;\n\n for (i = 0, len = rects.length; i < len; i++) {\n key = rects[i].left + '' + rects[i].top;\n if (!uniqueRects[key]) {\n uniqueRects[key] = rects[i];\n }\n }\n var uniqueRectsArray = [];\n for (key in uniqueRects) {\n uniqueRectsArray.push(uniqueRects[key]);\n }\n\n return uniqueRectsArray;\n },\n\n /**\n * Render new chunk of spray brush\n */\n render: function(sprayChunk) {\n var ctx = this.canvas.contextTop, i, len;\n ctx.fillStyle = this.color;\n\n this._saveAndTransform(ctx);\n\n for (i = 0, len = sprayChunk.length; i < len; i++) {\n var point = sprayChunk[i];\n if (typeof point.opacity !== 'undefined') {\n ctx.globalAlpha = point.opacity;\n }\n ctx.fillRect(point.x, point.y, point.width, point.width);\n }\n ctx.restore();\n },\n\n /**\n * Render all spray chunks\n */\n _render: function() {\n var ctx = this.canvas.contextTop, i, ilen;\n ctx.fillStyle = this.color;\n\n this._saveAndTransform(ctx);\n\n for (i = 0, ilen = this.sprayChunks.length; i < ilen; i++) {\n this.render(this.sprayChunks[i]);\n }\n ctx.restore();\n },\n\n /**\n * @param {Object} pointer\n */\n addSprayChunk: function(pointer) {\n this.sprayChunkPoints = [];\n\n var x, y, width, radius = this.width / 2, i;\n\n for (i = 0; i < this.density; i++) {\n\n x = fabric.util.getRandomInt(pointer.x - radius, pointer.x + radius);\n y = fabric.util.getRandomInt(pointer.y - radius, pointer.y + radius);\n\n if (this.dotWidthVariance) {\n width = fabric.util.getRandomInt(\n // bottom clamp width to 1\n Math.max(1, this.dotWidth - this.dotWidthVariance),\n this.dotWidth + this.dotWidthVariance);\n }\n else {\n width = this.dotWidth;\n }\n\n var point = new fabric.Point(x, y);\n point.width = width;\n\n if (this.randomOpacity) {\n point.opacity = fabric.util.getRandomInt(0, 100) / 100;\n }\n\n this.sprayChunkPoints.push(point);\n }\n\n this.sprayChunks.push(this.sprayChunkPoints);\n }\n});\n\n\n/**\n * PatternBrush class\n * @class fabric.PatternBrush\n * @extends fabric.BaseBrush\n */\nfabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fabric.PatternBrush.prototype */ {\n\n getPatternSrc: function() {\n\n var dotWidth = 20,\n dotDistance = 5,\n patternCanvas = fabric.util.createCanvasElement(),\n patternCtx = patternCanvas.getContext('2d');\n\n patternCanvas.width = patternCanvas.height = dotWidth + dotDistance;\n\n patternCtx.fillStyle = this.color;\n patternCtx.beginPath();\n patternCtx.arc(dotWidth / 2, dotWidth / 2, dotWidth / 2, 0, Math.PI * 2, false);\n patternCtx.closePath();\n patternCtx.fill();\n\n return patternCanvas;\n },\n\n getPatternSrcFunction: function() {\n return String(this.getPatternSrc).replace('this.color', '\"' + this.color + '\"');\n },\n\n /**\n * Creates \"pattern\" instance property\n */\n getPattern: function() {\n return this.canvas.contextTop.createPattern(this.source || this.getPatternSrc(), 'repeat');\n },\n\n /**\n * Sets brush styles\n */\n _setBrushStyles: function() {\n this.callSuper('_setBrushStyles');\n this.canvas.contextTop.strokeStyle = this.getPattern();\n },\n\n /**\n * Creates path\n */\n createPath: function(pathData) {\n var path = this.callSuper('createPath', pathData),\n topLeft = path._getLeftTopCoords().scalarAdd(path.strokeWidth / 2);\n\n path.stroke = new fabric.Pattern({\n source: this.source || this.getPatternSrcFunction(),\n offsetX: -topLeft.x,\n offsetY: -topLeft.y\n });\n return path;\n }\n});\n\n\n(function() {\n\n var getPointer = fabric.util.getPointer,\n degreesToRadians = fabric.util.degreesToRadians,\n abs = Math.abs,\n supportLineDash = fabric.StaticCanvas.supports('setLineDash'),\n isTouchEvent = fabric.util.isTouchEvent,\n STROKE_OFFSET = 0.5;\n\n /**\n * Canvas class\n * @class fabric.Canvas\n * @extends fabric.StaticCanvas\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#canvas}\n * @see {@link fabric.Canvas#initialize} for constructor definition\n *\n * @fires object:modified at the end of a transform or any change when statefull is true\n * @fires object:rotating while an object is being rotated from the control\n * @fires object:scaling while an object is being scaled by controls\n * @fires object:moving while an object is being dragged\n * @fires object:skewing while an object is being skewed from the controls\n *\n * @fires before:transform before a transform is is started\n * @fires before:selection:cleared\n * @fires selection:cleared\n * @fires selection:updated\n * @fires selection:created\n *\n * @fires path:created after a drawing operation ends and the path is added\n * @fires mouse:down\n * @fires mouse:move\n * @fires mouse:up\n * @fires mouse:down:before on mouse down, before the inner fabric logic runs\n * @fires mouse:move:before on mouse move, before the inner fabric logic runs\n * @fires mouse:up:before on mouse up, before the inner fabric logic runs\n * @fires mouse:over\n * @fires mouse:out\n * @fires mouse:dblclick whenever a native dbl click event fires on the canvas.\n *\n * @fires dragover\n * @fires dragenter\n * @fires dragleave\n * @fires drop\n * @fires after:render at the end of the render process, receives the context in the callback\n * @fires before:render at start the render process, receives the context in the callback\n *\n * the following events are deprecated:\n * @fires object:rotated at the end of a rotation transform\n * @fires object:scaled at the end of a scale transform\n * @fires object:moved at the end of translation transform\n * @fires object:skewed at the end of a skew transform\n */\n fabric.Canvas = fabric.util.createClass(fabric.StaticCanvas, /** @lends fabric.Canvas.prototype */ {\n\n /**\n * Constructor\n * @param {HTMLElement | String} el <canvas> element to initialize instance on\n * @param {Object} [options] Options object\n * @return {Object} thisArg\n */\n initialize: function(el, options) {\n options || (options = { });\n this.renderAndResetBound = this.renderAndReset.bind(this);\n this.requestRenderAllBound = this.requestRenderAll.bind(this);\n this._initStatic(el, options);\n this._initInteractive();\n this._createCacheCanvas();\n },\n\n /**\n * When true, objects can be transformed by one side (unproportionally)\n * when dragged on the corners that normally would not do that.\n * @type Boolean\n * @default\n * @since fabric 4.0 // changed name and default value\n */\n uniformScaling: true,\n\n /**\n * Indicates which key switches uniform scaling.\n * values: 'altKey', 'shiftKey', 'ctrlKey'.\n * If `null` or 'none' or any other string that is not a modifier key\n * feature is disabled.\n * totally wrong named. this sounds like `uniform scaling`\n * if Canvas.uniformScaling is true, pressing this will set it to false\n * and viceversa.\n * @since 1.6.2\n * @type String\n * @default\n */\n uniScaleKey: 'shiftKey',\n\n /**\n * When true, objects use center point as the origin of scale transformation.\n * <b>Backwards incompatibility note:</b> This property replaces \"centerTransform\" (Boolean).\n * @since 1.3.4\n * @type Boolean\n * @default\n */\n centeredScaling: false,\n\n /**\n * When true, objects use center point as the origin of rotate transformation.\n * <b>Backwards incompatibility note:</b> This property replaces \"centerTransform\" (Boolean).\n * @since 1.3.4\n * @type Boolean\n * @default\n */\n centeredRotation: false,\n\n /**\n * Indicates which key enable centered Transform\n * values: 'altKey', 'shiftKey', 'ctrlKey'.\n * If `null` or 'none' or any other string that is not a modifier key\n * feature is disabled feature disabled.\n * @since 1.6.2\n * @type String\n * @default\n */\n centeredKey: 'altKey',\n\n /**\n * Indicates which key enable alternate action on corner\n * values: 'altKey', 'shiftKey', 'ctrlKey'.\n * If `null` or 'none' or any other string that is not a modifier key\n * feature is disabled feature disabled.\n * @since 1.6.2\n * @type String\n * @default\n */\n altActionKey: 'shiftKey',\n\n /**\n * Indicates that canvas is interactive. This property should not be changed.\n * @type Boolean\n * @default\n */\n interactive: true,\n\n /**\n * Indicates whether group selection should be enabled\n * @type Boolean\n * @default\n */\n selection: true,\n\n /**\n * Indicates which key or keys enable multiple click selection\n * Pass value as a string or array of strings\n * values: 'altKey', 'shiftKey', 'ctrlKey'.\n * If `null` or empty or containing any other string that is not a modifier key\n * feature is disabled.\n * @since 1.6.2\n * @type String|Array\n * @default\n */\n selectionKey: 'shiftKey',\n\n /**\n * Indicates which key enable alternative selection\n * in case of target overlapping with active object\n * values: 'altKey', 'shiftKey', 'ctrlKey'.\n * For a series of reason that come from the general expectations on how\n * things should work, this feature works only for preserveObjectStacking true.\n * If `null` or 'none' or any other string that is not a modifier key\n * feature is disabled.\n * @since 1.6.5\n * @type null|String\n * @default\n */\n altSelectionKey: null,\n\n /**\n * Color of selection\n * @type String\n * @default\n */\n selectionColor: 'rgba(100, 100, 255, 0.3)', // blue\n\n /**\n * Default dash array pattern\n * If not empty the selection border is dashed\n * @type Array\n */\n selectionDashArray: [],\n\n /**\n * Color of the border of selection (usually slightly darker than color of selection itself)\n * @type String\n * @default\n */\n selectionBorderColor: 'rgba(255, 255, 255, 0.3)',\n\n /**\n * Width of a line used in object/group selection\n * @type Number\n * @default\n */\n selectionLineWidth: 1,\n\n /**\n * Select only shapes that are fully contained in the dragged selection rectangle.\n * @type Boolean\n * @default\n */\n selectionFullyContained: false,\n\n /**\n * Default cursor value used when hovering over an object on canvas\n * @type String\n * @default\n */\n hoverCursor: 'move',\n\n /**\n * Default cursor value used when moving an object on canvas\n * @type String\n * @default\n */\n moveCursor: 'move',\n\n /**\n * Default cursor value used for the entire canvas\n * @type String\n * @default\n */\n defaultCursor: 'default',\n\n /**\n * Cursor value used during free drawing\n * @type String\n * @default\n */\n freeDrawingCursor: 'crosshair',\n\n /**\n * Cursor value used for rotation point\n * @type String\n * @default\n */\n rotationCursor: 'crosshair',\n\n /**\n * Cursor value used for disabled elements ( corners with disabled action )\n * @type String\n * @since 2.0.0\n * @default\n */\n notAllowedCursor: 'not-allowed',\n\n /**\n * Default element class that's given to wrapper (div) element of canvas\n * @type String\n * @default\n */\n containerClass: 'canvas-container',\n\n /**\n * When true, object detection happens on per-pixel basis rather than on per-bounding-box\n * @type Boolean\n * @default\n */\n perPixelTargetFind: false,\n\n /**\n * Number of pixels around target pixel to tolerate (consider active) during object detection\n * @type Number\n * @default\n */\n targetFindTolerance: 0,\n\n /**\n * When true, target detection is skipped. Target detection will return always undefined.\n * click selection won't work anymore, events will fire with no targets.\n * if something is selected before setting it to true, it will be deselected at the first click.\n * area selection will still work. check the `selection` property too.\n * if you deactivate both, you should look into staticCanvas.\n * @type Boolean\n * @default\n */\n skipTargetFind: false,\n\n /**\n * When true, mouse events on canvas (mousedown/mousemove/mouseup) result in free drawing.\n * After mousedown, mousemove creates a shape,\n * and then mouseup finalizes it and adds an instance of `fabric.Path` onto canvas.\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-4#free_drawing}\n * @type Boolean\n * @default\n */\n isDrawingMode: false,\n\n /**\n * Indicates whether objects should remain in current stack position when selected.\n * When false objects are brought to top and rendered as part of the selection group\n * @type Boolean\n * @default\n */\n preserveObjectStacking: false,\n\n /**\n * Indicates the angle that an object will lock to while rotating.\n * @type Number\n * @since 1.6.7\n * @default\n */\n snapAngle: 0,\n\n /**\n * Indicates the distance from the snapAngle the rotation will lock to the snapAngle.\n * When `null`, the snapThreshold will default to the snapAngle.\n * @type null|Number\n * @since 1.6.7\n * @default\n */\n snapThreshold: null,\n\n /**\n * Indicates if the right click on canvas can output the context menu or not\n * @type Boolean\n * @since 1.6.5\n * @default\n */\n stopContextMenu: false,\n\n /**\n * Indicates if the canvas can fire right click events\n * @type Boolean\n * @since 1.6.5\n * @default\n */\n fireRightClick: false,\n\n /**\n * Indicates if the canvas can fire middle click events\n * @type Boolean\n * @since 1.7.8\n * @default\n */\n fireMiddleClick: false,\n\n /**\n * Keep track of the subTargets for Mouse Events\n * @type fabric.Object[]\n */\n targets: [],\n\n /**\n * Keep track of the hovered target\n * @type fabric.Object\n * @private\n */\n _hoveredTarget: null,\n\n /**\n * hold the list of nested targets hovered\n * @type fabric.Object[]\n * @private\n */\n _hoveredTargets: [],\n\n /**\n * @private\n */\n _initInteractive: function() {\n this._currentTransform = null;\n this._groupSelector = null;\n this._initWrapperElement();\n this._createUpperCanvas();\n this._initEventListeners();\n\n this._initRetinaScaling();\n\n this.freeDrawingBrush = fabric.PencilBrush && new fabric.PencilBrush(this);\n\n this.calcOffset();\n },\n\n /**\n * Divides objects in two groups, one to render immediately\n * and one to render as activeGroup.\n * @return {Array} objects to render immediately and pushes the other in the activeGroup.\n */\n _chooseObjectsToRender: function() {\n var activeObjects = this.getActiveObjects(),\n object, objsToRender, activeGroupObjects;\n\n if (activeObjects.length > 0 && !this.preserveObjectStacking) {\n objsToRender = [];\n activeGroupObjects = [];\n for (var i = 0, length = this._objects.length; i < length; i++) {\n object = this._objects[i];\n if (activeObjects.indexOf(object) === -1 ) {\n objsToRender.push(object);\n }\n else {\n activeGroupObjects.push(object);\n }\n }\n if (activeObjects.length > 1) {\n this._activeObject._objects = activeGroupObjects;\n }\n objsToRender.push.apply(objsToRender, activeGroupObjects);\n }\n else {\n objsToRender = this._objects;\n }\n return objsToRender;\n },\n\n /**\n * Renders both the top canvas and the secondary container canvas.\n * @return {fabric.Canvas} instance\n * @chainable\n */\n renderAll: function () {\n if (this.contextTopDirty && !this._groupSelector && !this.isDrawingMode) {\n this.clearContext(this.contextTop);\n this.contextTopDirty = false;\n }\n if (this.hasLostContext) {\n this.renderTopLayer(this.contextTop);\n }\n var canvasToDrawOn = this.contextContainer;\n this.renderCanvas(canvasToDrawOn, this._chooseObjectsToRender());\n return this;\n },\n\n renderTopLayer: function(ctx) {\n ctx.save();\n if (this.isDrawingMode && this._isCurrentlyDrawing) {\n this.freeDrawingBrush && this.freeDrawingBrush._render();\n this.contextTopDirty = true;\n }\n // we render the top context - last object\n if (this.selection && this._groupSelector) {\n this._drawSelection(ctx);\n this.contextTopDirty = true;\n }\n ctx.restore();\n },\n\n /**\n * Method to render only the top canvas.\n * Also used to render the group selection box.\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n renderTop: function () {\n var ctx = this.contextTop;\n this.clearContext(ctx);\n this.renderTopLayer(ctx);\n this.fire('after:render');\n return this;\n },\n\n /**\n * @private\n */\n _normalizePointer: function (object, pointer) {\n var m = object.calcTransformMatrix(),\n invertedM = fabric.util.invertTransform(m),\n vptPointer = this.restorePointerVpt(pointer);\n return fabric.util.transformPoint(vptPointer, invertedM);\n },\n\n /**\n * Returns true if object is transparent at a certain location\n * @param {fabric.Object} target Object to check\n * @param {Number} x Left coordinate\n * @param {Number} y Top coordinate\n * @return {Boolean}\n */\n isTargetTransparent: function (target, x, y) {\n // in case the target is the activeObject, we cannot execute this optimization\n // because we need to draw controls too.\n if (target.shouldCache() && target._cacheCanvas && target !== this._activeObject) {\n var normalizedPointer = this._normalizePointer(target, {x: x, y: y}),\n targetRelativeX = Math.max(target.cacheTranslationX + (normalizedPointer.x * target.zoomX), 0),\n targetRelativeY = Math.max(target.cacheTranslationY + (normalizedPointer.y * target.zoomY), 0);\n\n var isTransparent = fabric.util.isTransparent(\n target._cacheContext, Math.round(targetRelativeX), Math.round(targetRelativeY), this.targetFindTolerance);\n\n return isTransparent;\n }\n\n var ctx = this.contextCache,\n originalColor = target.selectionBackgroundColor, v = this.viewportTransform;\n\n target.selectionBackgroundColor = '';\n\n this.clearContext(ctx);\n\n ctx.save();\n ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]);\n target.render(ctx);\n ctx.restore();\n\n target === this._activeObject && target._renderControls(ctx, {\n hasBorders: false,\n transparentCorners: false\n }, {\n hasBorders: false,\n });\n\n target.selectionBackgroundColor = originalColor;\n\n var isTransparent = fabric.util.isTransparent(\n ctx, x, y, this.targetFindTolerance);\n\n return isTransparent;\n },\n\n /**\n * takes an event and determins if selection key has been pressed\n * @private\n * @param {Event} e Event object\n */\n _isSelectionKeyPressed: function(e) {\n var selectionKeyPressed = false;\n\n if (Object.prototype.toString.call(this.selectionKey) === '[object Array]') {\n selectionKeyPressed = !!this.selectionKey.find(function(key) { return e[key] === true; });\n }\n else {\n selectionKeyPressed = e[this.selectionKey];\n }\n\n return selectionKeyPressed;\n },\n\n /**\n * @private\n * @param {Event} e Event object\n * @param {fabric.Object} target\n */\n _shouldClearSelection: function (e, target) {\n var activeObjects = this.getActiveObjects(),\n activeObject = this._activeObject;\n\n return (\n !target\n ||\n (target &&\n activeObject &&\n activeObjects.length > 1 &&\n activeObjects.indexOf(target) === -1 &&\n activeObject !== target &&\n !this._isSelectionKeyPressed(e))\n ||\n (target && !target.evented)\n ||\n (target &&\n !target.selectable &&\n activeObject &&\n activeObject !== target)\n );\n },\n\n /**\n * centeredScaling from object can't override centeredScaling from canvas.\n * this should be fixed, since object setting should take precedence over canvas.\n * also this should be something that will be migrated in the control properties.\n * as ability to define the origin of the transformation that the control provide.\n * @private\n * @param {fabric.Object} target\n * @param {String} action\n * @param {Boolean} altKey\n */\n _shouldCenterTransform: function (target, action, altKey) {\n if (!target) {\n return;\n }\n\n var centerTransform;\n\n if (action === 'scale' || action === 'scaleX' || action === 'scaleY' || action === 'resizing') {\n centerTransform = this.centeredScaling || target.centeredScaling;\n }\n else if (action === 'rotate') {\n centerTransform = this.centeredRotation || target.centeredRotation;\n }\n\n return centerTransform ? !altKey : altKey;\n },\n\n /**\n * should disappear before release 4.0\n * @private\n */\n _getOriginFromCorner: function(target, corner) {\n var origin = {\n x: target.originX,\n y: target.originY\n };\n\n if (corner === 'ml' || corner === 'tl' || corner === 'bl') {\n origin.x = 'right';\n }\n else if (corner === 'mr' || corner === 'tr' || corner === 'br') {\n origin.x = 'left';\n }\n\n if (corner === 'tl' || corner === 'mt' || corner === 'tr') {\n origin.y = 'bottom';\n }\n else if (corner === 'bl' || corner === 'mb' || corner === 'br') {\n origin.y = 'top';\n }\n else if (corner === 'mtr') {\n origin.x = 'center';\n origin.y = 'center';\n }\n return origin;\n },\n\n /**\n * @private\n * @param {Boolean} alreadySelected true if target is already selected\n * @param {String} corner a string representing the corner ml, mr, tl ...\n * @param {Event} e Event object\n * @param {fabric.Object} [target] inserted back to help overriding. Unused\n */\n _getActionFromCorner: function(alreadySelected, corner, e, target) {\n if (!corner || !alreadySelected) {\n return 'drag';\n }\n var control = target.controls[corner];\n return control.getActionName(e, control, target);\n },\n\n /**\n * @private\n * @param {Event} e Event object\n * @param {fabric.Object} target\n */\n _setupCurrentTransform: function (e, target, alreadySelected) {\n if (!target) {\n return;\n }\n\n var pointer = this.getPointer(e), corner = target.__corner,\n actionHandler = (alreadySelected && corner) ?\n target.controls[corner].getActionHandler() : fabric.controlsUtils.dragHandler,\n action = this._getActionFromCorner(alreadySelected, corner, e, target),\n origin = this._getOriginFromCorner(target, corner),\n altKey = e[this.centeredKey],\n transform = {\n target: target,\n action: action,\n actionHandler: actionHandler,\n corner: corner,\n scaleX: target.scaleX,\n scaleY: target.scaleY,\n skewX: target.skewX,\n skewY: target.skewY,\n // used by transation\n offsetX: pointer.x - target.left,\n offsetY: pointer.y - target.top,\n originX: origin.x,\n originY: origin.y,\n ex: pointer.x,\n ey: pointer.y,\n lastX: pointer.x,\n lastY: pointer.y,\n // unsure they are useful anymore.\n // left: target.left,\n // top: target.top,\n theta: degreesToRadians(target.angle),\n // end of unsure\n width: target.width * target.scaleX,\n shiftKey: e.shiftKey,\n altKey: altKey,\n original: fabric.util.saveObjectTransform(target),\n };\n\n if (this._shouldCenterTransform(target, action, altKey)) {\n transform.originX = 'center';\n transform.originY = 'center';\n }\n transform.original.originX = origin.x;\n transform.original.originY = origin.y;\n this._currentTransform = transform;\n this._beforeTransform(e);\n },\n\n /**\n * Set the cursor type of the canvas element\n * @param {String} value Cursor type of the canvas element.\n * @see http://www.w3.org/TR/css3-ui/#cursor\n */\n setCursor: function (value) {\n this.upperCanvasEl.style.cursor = value;\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx to draw the selection on\n */\n _drawSelection: function (ctx) {\n var groupSelector = this._groupSelector,\n left = groupSelector.left,\n top = groupSelector.top,\n aleft = abs(left),\n atop = abs(top);\n\n if (this.selectionColor) {\n ctx.fillStyle = this.selectionColor;\n\n ctx.fillRect(\n groupSelector.ex - ((left > 0) ? 0 : -left),\n groupSelector.ey - ((top > 0) ? 0 : -top),\n aleft,\n atop\n );\n }\n\n if (!this.selectionLineWidth || !this.selectionBorderColor) {\n return;\n }\n ctx.lineWidth = this.selectionLineWidth;\n ctx.strokeStyle = this.selectionBorderColor;\n\n // selection border\n if (this.selectionDashArray.length > 1 && !supportLineDash) {\n\n var px = groupSelector.ex + STROKE_OFFSET - ((left > 0) ? 0 : aleft),\n py = groupSelector.ey + STROKE_OFFSET - ((top > 0) ? 0 : atop);\n\n ctx.beginPath();\n\n fabric.util.drawDashedLine(ctx, px, py, px + aleft, py, this.selectionDashArray);\n fabric.util.drawDashedLine(ctx, px, py + atop - 1, px + aleft, py + atop - 1, this.selectionDashArray);\n fabric.util.drawDashedLine(ctx, px, py, px, py + atop, this.selectionDashArray);\n fabric.util.drawDashedLine(ctx, px + aleft - 1, py, px + aleft - 1, py + atop, this.selectionDashArray);\n\n ctx.closePath();\n ctx.stroke();\n }\n else {\n fabric.Object.prototype._setLineDash.call(this, ctx, this.selectionDashArray);\n ctx.strokeRect(\n groupSelector.ex + STROKE_OFFSET - ((left > 0) ? 0 : aleft),\n groupSelector.ey + STROKE_OFFSET - ((top > 0) ? 0 : atop),\n aleft,\n atop\n );\n }\n },\n\n /**\n * Method that determines what object we are clicking on\n * the skipGroup parameter is for internal use, is needed for shift+click action\n * 11/09/2018 TODO: would be cool if findTarget could discern between being a full target\n * or the outside part of the corner.\n * @param {Event} e mouse event\n * @param {Boolean} skipGroup when true, activeGroup is skipped and only objects are traversed through\n * @return {fabric.Object} the target found\n */\n findTarget: function (e, skipGroup) {\n if (this.skipTargetFind) {\n return;\n }\n\n var ignoreZoom = true,\n pointer = this.getPointer(e, ignoreZoom),\n activeObject = this._activeObject,\n aObjects = this.getActiveObjects(),\n activeTarget, activeTargetSubs,\n isTouch = isTouchEvent(e);\n\n // first check current group (if one exists)\n // active group does not check sub targets like normal groups.\n // if active group just exits.\n this.targets = [];\n\n if (aObjects.length > 1 && !skipGroup && activeObject === this._searchPossibleTargets([activeObject], pointer)) {\n return activeObject;\n }\n // if we hit the corner of an activeObject, let's return that.\n if (aObjects.length === 1 && activeObject._findTargetCorner(pointer, isTouch)) {\n return activeObject;\n }\n if (aObjects.length === 1 &&\n activeObject === this._searchPossibleTargets([activeObject], pointer)) {\n if (!this.preserveObjectStacking) {\n return activeObject;\n }\n else {\n activeTarget = activeObject;\n activeTargetSubs = this.targets;\n this.targets = [];\n }\n }\n var target = this._searchPossibleTargets(this._objects, pointer);\n if (e[this.altSelectionKey] && target && activeTarget && target !== activeTarget) {\n target = activeTarget;\n this.targets = activeTargetSubs;\n }\n return target;\n },\n\n /**\n * Checks point is inside the object.\n * @param {Object} [pointer] x,y object of point coordinates we want to check.\n * @param {fabric.Object} obj Object to test against\n * @param {Object} [globalPointer] x,y object of point coordinates relative to canvas used to search per pixel target.\n * @return {Boolean} true if point is contained within an area of given object\n * @private\n */\n _checkTarget: function(pointer, obj, globalPointer) {\n if (obj &&\n obj.visible &&\n obj.evented &&\n // http://www.geog.ubc.ca/courses/klink/gis.notes/ncgia/u32.html\n // http://idav.ucdavis.edu/~okreylos/TAship/Spring2000/PointInPolygon.html\n (obj.containsPoint(pointer) || !!obj._findTargetCorner(pointer))\n ) {\n if ((this.perPixelTargetFind || obj.perPixelTargetFind) && !obj.isEditing) {\n var isTransparent = this.isTargetTransparent(obj, globalPointer.x, globalPointer.y);\n if (!isTransparent) {\n return true;\n }\n }\n else {\n return true;\n }\n }\n },\n\n /**\n * Function used to search inside objects an object that contains pointer in bounding box or that contains pointerOnCanvas when painted\n * @param {Array} [objects] objects array to look into\n * @param {Object} [pointer] x,y object of point coordinates we want to check.\n * @return {fabric.Object} object that contains pointer\n * @private\n */\n _searchPossibleTargets: function(objects, pointer) {\n // Cache all targets where their bounding box contains point.\n var target, i = objects.length, subTarget;\n // Do not check for currently grouped objects, since we check the parent group itself.\n // until we call this function specifically to search inside the activeGroup\n while (i--) {\n var objToCheck = objects[i];\n var pointerToUse = objToCheck.group ?\n this._normalizePointer(objToCheck.group, pointer) : pointer;\n if (this._checkTarget(pointerToUse, objToCheck, pointer)) {\n target = objects[i];\n if (target.subTargetCheck && target instanceof fabric.Group) {\n subTarget = this._searchPossibleTargets(target._objects, pointer);\n subTarget && this.targets.push(subTarget);\n }\n break;\n }\n }\n return target;\n },\n\n /**\n * Returns pointer coordinates without the effect of the viewport\n * @param {Object} pointer with \"x\" and \"y\" number values\n * @return {Object} object with \"x\" and \"y\" number values\n */\n restorePointerVpt: function(pointer) {\n return fabric.util.transformPoint(\n pointer,\n fabric.util.invertTransform(this.viewportTransform)\n );\n },\n\n /**\n * Returns pointer coordinates relative to canvas.\n * Can return coordinates with or without viewportTransform.\n * ignoreZoom false gives back coordinates that represent\n * the point clicked on canvas element.\n * ignoreZoom true gives back coordinates after being processed\n * by the viewportTransform ( sort of coordinates of what is displayed\n * on the canvas where you are clicking.\n * ignoreZoom true = HTMLElement coordinates relative to top,left\n * ignoreZoom false, default = fabric space coordinates, the same used for shape position\n * To interact with your shapes top and left you want to use ignoreZoom true\n * most of the time, while ignoreZoom false will give you coordinates\n * compatible with the object.oCoords system.\n * of the time.\n * @param {Event} e\n * @param {Boolean} ignoreZoom\n * @return {Object} object with \"x\" and \"y\" number values\n */\n getPointer: function (e, ignoreZoom) {\n // return cached values if we are in the event processing chain\n if (this._absolutePointer && !ignoreZoom) {\n return this._absolutePointer;\n }\n if (this._pointer && ignoreZoom) {\n return this._pointer;\n }\n\n var pointer = getPointer(e),\n upperCanvasEl = this.upperCanvasEl,\n bounds = upperCanvasEl.getBoundingClientRect(),\n boundsWidth = bounds.width || 0,\n boundsHeight = bounds.height || 0,\n cssScale;\n\n if (!boundsWidth || !boundsHeight ) {\n if ('top' in bounds && 'bottom' in bounds) {\n boundsHeight = Math.abs( bounds.top - bounds.bottom );\n }\n if ('right' in bounds && 'left' in bounds) {\n boundsWidth = Math.abs( bounds.right - bounds.left );\n }\n }\n\n this.calcOffset();\n pointer.x = pointer.x - this._offset.left;\n pointer.y = pointer.y - this._offset.top;\n if (!ignoreZoom) {\n pointer = this.restorePointerVpt(pointer);\n }\n\n var retinaScaling = this.getRetinaScaling();\n if (retinaScaling !== 1) {\n pointer.x /= retinaScaling;\n pointer.y /= retinaScaling;\n }\n\n if (boundsWidth === 0 || boundsHeight === 0) {\n // If bounds are not available (i.e. not visible), do not apply scale.\n cssScale = { width: 1, height: 1 };\n }\n else {\n cssScale = {\n width: upperCanvasEl.width / boundsWidth,\n height: upperCanvasEl.height / boundsHeight\n };\n }\n\n return {\n x: pointer.x * cssScale.width,\n y: pointer.y * cssScale.height\n };\n },\n\n /**\n * @private\n * @throws {CANVAS_INIT_ERROR} If canvas can not be initialized\n */\n _createUpperCanvas: function () {\n var lowerCanvasClass = this.lowerCanvasEl.className.replace(/\\s*lower-canvas\\s*/, ''),\n lowerCanvasEl = this.lowerCanvasEl, upperCanvasEl = this.upperCanvasEl;\n\n // there is no need to create a new upperCanvas element if we have already one.\n if (upperCanvasEl) {\n upperCanvasEl.className = '';\n }\n else {\n upperCanvasEl = this._createCanvasElement();\n this.upperCanvasEl = upperCanvasEl;\n }\n fabric.util.addClass(upperCanvasEl, 'upper-canvas ' + lowerCanvasClass);\n\n this.wrapperEl.appendChild(upperCanvasEl);\n\n this._copyCanvasStyle(lowerCanvasEl, upperCanvasEl);\n this._applyCanvasStyle(upperCanvasEl);\n this.contextTop = upperCanvasEl.getContext('2d');\n },\n\n /**\n * @private\n */\n _createCacheCanvas: function () {\n this.cacheCanvasEl = this._createCanvasElement();\n this.cacheCanvasEl.setAttribute('width', this.width);\n this.cacheCanvasEl.setAttribute('height', this.height);\n this.contextCache = this.cacheCanvasEl.getContext('2d');\n },\n\n /**\n * @private\n */\n _initWrapperElement: function () {\n this.wrapperEl = fabric.util.wrapElement(this.lowerCanvasEl, 'div', {\n 'class': this.containerClass\n });\n fabric.util.setStyle(this.wrapperEl, {\n width: this.width + 'px',\n height: this.height + 'px',\n position: 'relative'\n });\n fabric.util.makeElementUnselectable(this.wrapperEl);\n },\n\n /**\n * @private\n * @param {HTMLElement} element canvas element to apply styles on\n */\n _applyCanvasStyle: function (element) {\n var width = this.width || element.width,\n height = this.height || element.height;\n\n fabric.util.setStyle(element, {\n position: 'absolute',\n width: width + 'px',\n height: height + 'px',\n left: 0,\n top: 0,\n 'touch-action': this.allowTouchScrolling ? 'manipulation' : 'none',\n '-ms-touch-action': this.allowTouchScrolling ? 'manipulation' : 'none'\n });\n element.width = width;\n element.height = height;\n fabric.util.makeElementUnselectable(element);\n },\n\n /**\n * Copy the entire inline style from one element (fromEl) to another (toEl)\n * @private\n * @param {Element} fromEl Element style is copied from\n * @param {Element} toEl Element copied style is applied to\n */\n _copyCanvasStyle: function (fromEl, toEl) {\n toEl.style.cssText = fromEl.style.cssText;\n },\n\n /**\n * Returns context of canvas where object selection is drawn\n * @return {CanvasRenderingContext2D}\n */\n getSelectionContext: function() {\n return this.contextTop;\n },\n\n /**\n * Returns <canvas> element on which object selection is drawn\n * @return {HTMLCanvasElement}\n */\n getSelectionElement: function () {\n return this.upperCanvasEl;\n },\n\n /**\n * Returns currently active object\n * @return {fabric.Object} active object\n */\n getActiveObject: function () {\n return this._activeObject;\n },\n\n /**\n * Returns an array with the current selected objects\n * @return {fabric.Object} active object\n */\n getActiveObjects: function () {\n var active = this._activeObject;\n if (active) {\n if (active.type === 'activeSelection' && active._objects) {\n return active._objects.slice(0);\n }\n else {\n return [active];\n }\n }\n return [];\n },\n\n /**\n * @private\n * @param {fabric.Object} obj Object that was removed\n */\n _onObjectRemoved: function(obj) {\n // removing active object should fire \"selection:cleared\" events\n if (obj === this._activeObject) {\n this.fire('before:selection:cleared', { target: obj });\n this._discardActiveObject();\n this.fire('selection:cleared', { target: obj });\n obj.fire('deselected');\n }\n if (obj === this._hoveredTarget){\n this._hoveredTarget = null;\n this._hoveredTargets = [];\n }\n this.callSuper('_onObjectRemoved', obj);\n },\n\n /**\n * @private\n * Compares the old activeObject with the current one and fires correct events\n * @param {fabric.Object} obj old activeObject\n */\n _fireSelectionEvents: function(oldObjects, e) {\n var somethingChanged = false, objects = this.getActiveObjects(),\n added = [], removed = [], opt = { e: e };\n oldObjects.forEach(function(oldObject) {\n if (objects.indexOf(oldObject) === -1) {\n somethingChanged = true;\n oldObject.fire('deselected', opt);\n removed.push(oldObject);\n }\n });\n objects.forEach(function(object) {\n if (oldObjects.indexOf(object) === -1) {\n somethingChanged = true;\n object.fire('selected', opt);\n added.push(object);\n }\n });\n if (oldObjects.length > 0 && objects.length > 0) {\n opt.selected = added;\n opt.deselected = removed;\n // added for backward compatibility\n opt.updated = added[0] || removed[0];\n opt.target = this._activeObject;\n somethingChanged && this.fire('selection:updated', opt);\n }\n else if (objects.length > 0) {\n opt.selected = added;\n // added for backward compatibility\n opt.target = this._activeObject;\n this.fire('selection:created', opt);\n }\n else if (oldObjects.length > 0) {\n opt.deselected = removed;\n this.fire('selection:cleared', opt);\n }\n },\n\n /**\n * Sets given object as the only active object on canvas\n * @param {fabric.Object} object Object to set as an active one\n * @param {Event} [e] Event (passed along when firing \"object:selected\")\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n setActiveObject: function (object, e) {\n var currentActives = this.getActiveObjects();\n this._setActiveObject(object, e);\n this._fireSelectionEvents(currentActives, e);\n return this;\n },\n\n /**\n * @private\n * @param {Object} object to set as active\n * @param {Event} [e] Event (passed along when firing \"object:selected\")\n * @return {Boolean} true if the selection happened\n */\n _setActiveObject: function(object, e) {\n if (this._activeObject === object) {\n return false;\n }\n if (!this._discardActiveObject(e, object)) {\n return false;\n }\n if (object.onSelect({ e: e })) {\n return false;\n }\n this._activeObject = object;\n return true;\n },\n\n /**\n * @private\n */\n _discardActiveObject: function(e, object) {\n var obj = this._activeObject;\n if (obj) {\n // onDeselect return TRUE to cancel selection;\n if (obj.onDeselect({ e: e, object: object })) {\n return false;\n }\n this._activeObject = null;\n }\n return true;\n },\n\n /**\n * Discards currently active object and fire events. If the function is called by fabric\n * as a consequence of a mouse event, the event is passed as a parameter and\n * sent to the fire function for the custom events. When used as a method the\n * e param does not have any application.\n * @param {event} e\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n discardActiveObject: function (e) {\n var currentActives = this.getActiveObjects(), activeObject = this.getActiveObject();\n if (currentActives.length) {\n this.fire('before:selection:cleared', { target: activeObject, e: e });\n }\n this._discardActiveObject(e);\n this._fireSelectionEvents(currentActives, e);\n return this;\n },\n\n /**\n * Clears a canvas element and removes all event listeners\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n dispose: function () {\n var wrapper = this.wrapperEl;\n this.removeListeners();\n wrapper.removeChild(this.upperCanvasEl);\n wrapper.removeChild(this.lowerCanvasEl);\n this.contextCache = null;\n this.contextTop = null;\n ['upperCanvasEl', 'cacheCanvasEl'].forEach((function(element) {\n fabric.util.cleanUpJsdomNode(this[element]);\n this[element] = undefined;\n }).bind(this));\n if (wrapper.parentNode) {\n wrapper.parentNode.replaceChild(this.lowerCanvasEl, this.wrapperEl);\n }\n delete this.wrapperEl;\n fabric.StaticCanvas.prototype.dispose.call(this);\n return this;\n },\n\n /**\n * Clears all contexts (background, main, top) of an instance\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n clear: function () {\n // this.discardActiveGroup();\n this.discardActiveObject();\n this.clearContext(this.contextTop);\n return this.callSuper('clear');\n },\n\n /**\n * Draws objects' controls (borders/controls)\n * @param {CanvasRenderingContext2D} ctx Context to render controls on\n */\n drawControls: function(ctx) {\n var activeObject = this._activeObject;\n\n if (activeObject) {\n activeObject._renderControls(ctx);\n }\n },\n\n /**\n * @private\n */\n _toObject: function(instance, methodName, propertiesToInclude) {\n //If the object is part of the current selection group, it should\n //be transformed appropriately\n //i.e. it should be serialised as it would appear if the selection group\n //were to be destroyed.\n var originalProperties = this._realizeGroupTransformOnObject(instance),\n object = this.callSuper('_toObject', instance, methodName, propertiesToInclude);\n //Undo the damage we did by changing all of its properties\n this._unwindGroupTransformOnObject(instance, originalProperties);\n return object;\n },\n\n /**\n * Realises an object's group transformation on it\n * @private\n * @param {fabric.Object} [instance] the object to transform (gets mutated)\n * @returns the original values of instance which were changed\n */\n _realizeGroupTransformOnObject: function(instance) {\n if (instance.group && instance.group.type === 'activeSelection' && this._activeObject === instance.group) {\n var layoutProps = ['angle', 'flipX', 'flipY', 'left', 'scaleX', 'scaleY', 'skewX', 'skewY', 'top'];\n //Copy all the positionally relevant properties across now\n var originalValues = {};\n layoutProps.forEach(function(prop) {\n originalValues[prop] = instance[prop];\n });\n this._activeObject.realizeTransform(instance);\n return originalValues;\n }\n else {\n return null;\n }\n },\n\n /**\n * Restores the changed properties of instance\n * @private\n * @param {fabric.Object} [instance] the object to un-transform (gets mutated)\n * @param {Object} [originalValues] the original values of instance, as returned by _realizeGroupTransformOnObject\n */\n _unwindGroupTransformOnObject: function(instance, originalValues) {\n if (originalValues) {\n instance.set(originalValues);\n }\n },\n\n /**\n * @private\n */\n _setSVGObject: function(markup, instance, reviver) {\n //If the object is in a selection group, simulate what would happen to that\n //object when the group is deselected\n var originalProperties = this._realizeGroupTransformOnObject(instance);\n this.callSuper('_setSVGObject', markup, instance, reviver);\n this._unwindGroupTransformOnObject(instance, originalProperties);\n },\n\n setViewportTransform: function (vpt) {\n if (this.renderOnAddRemove && this._activeObject && this._activeObject.isEditing) {\n this._activeObject.clearContextTop();\n }\n fabric.StaticCanvas.prototype.setViewportTransform.call(this, vpt);\n }\n });\n\n // copying static properties manually to work around Opera's bug,\n // where \"prototype\" property is enumerable and overrides existing prototype\n for (var prop in fabric.StaticCanvas) {\n if (prop !== 'prototype') {\n fabric.Canvas[prop] = fabric.StaticCanvas[prop];\n }\n }\n})();\n\n\n(function() {\n\n var addListener = fabric.util.addListener,\n removeListener = fabric.util.removeListener,\n RIGHT_CLICK = 3, MIDDLE_CLICK = 2, LEFT_CLICK = 1,\n addEventOptions = { passive: false };\n\n function checkClick(e, value) {\n return e.button && (e.button === value - 1);\n }\n\n fabric.util.object.extend(fabric.Canvas.prototype, /** @lends fabric.Canvas.prototype */ {\n\n /**\n * Contains the id of the touch event that owns the fabric transform\n * @type Number\n * @private\n */\n mainTouchId: null,\n\n /**\n * Adds mouse listeners to canvas\n * @private\n */\n _initEventListeners: function () {\n // in case we initialized the class twice. This should not happen normally\n // but in some kind of applications where the canvas element may be changed\n // this is a workaround to having double listeners.\n this.removeListeners();\n this._bindEvents();\n this.addOrRemove(addListener, 'add');\n },\n\n /**\n * return an event prefix pointer or mouse.\n * @private\n */\n _getEventPrefix: function () {\n return this.enablePointerEvents ? 'pointer' : 'mouse';\n },\n\n addOrRemove: function(functor, eventjsFunctor) {\n var canvasElement = this.upperCanvasEl,\n eventTypePrefix = this._getEventPrefix();\n functor(fabric.window, 'resize', this._onResize);\n functor(canvasElement, eventTypePrefix + 'down', this._onMouseDown);\n functor(canvasElement, eventTypePrefix + 'move', this._onMouseMove, addEventOptions);\n functor(canvasElement, eventTypePrefix + 'out', this._onMouseOut);\n functor(canvasElement, eventTypePrefix + 'enter', this._onMouseEnter);\n functor(canvasElement, 'wheel', this._onMouseWheel);\n functor(canvasElement, 'contextmenu', this._onContextMenu);\n functor(canvasElement, 'dblclick', this._onDoubleClick);\n functor(canvasElement, 'dragover', this._onDragOver);\n functor(canvasElement, 'dragenter', this._onDragEnter);\n functor(canvasElement, 'dragleave', this._onDragLeave);\n functor(canvasElement, 'drop', this._onDrop);\n if (!this.enablePointerEvents) {\n functor(canvasElement, 'touchstart', this._onTouchStart, addEventOptions);\n }\n if (typeof eventjs !== 'undefined' && eventjsFunctor in eventjs) {\n eventjs[eventjsFunctor](canvasElement, 'gesture', this._onGesture);\n eventjs[eventjsFunctor](canvasElement, 'drag', this._onDrag);\n eventjs[eventjsFunctor](canvasElement, 'orientation', this._onOrientationChange);\n eventjs[eventjsFunctor](canvasElement, 'shake', this._onShake);\n eventjs[eventjsFunctor](canvasElement, 'longpress', this._onLongPress);\n }\n },\n\n /**\n * Removes all event listeners\n */\n removeListeners: function() {\n this.addOrRemove(removeListener, 'remove');\n // if you dispose on a mouseDown, before mouse up, you need to clean document to...\n var eventTypePrefix = this._getEventPrefix();\n removeListener(fabric.document, eventTypePrefix + 'up', this._onMouseUp);\n removeListener(fabric.document, 'touchend', this._onTouchEnd, addEventOptions);\n removeListener(fabric.document, eventTypePrefix + 'move', this._onMouseMove, addEventOptions);\n removeListener(fabric.document, 'touchmove', this._onMouseMove, addEventOptions);\n },\n\n /**\n * @private\n */\n _bindEvents: function() {\n if (this.eventsBound) {\n // for any reason we pass here twice we do not want to bind events twice.\n return;\n }\n this._onMouseDown = this._onMouseDown.bind(this);\n this._onTouchStart = this._onTouchStart.bind(this);\n this._onMouseMove = this._onMouseMove.bind(this);\n this._onMouseUp = this._onMouseUp.bind(this);\n this._onTouchEnd = this._onTouchEnd.bind(this);\n this._onResize = this._onResize.bind(this);\n this._onGesture = this._onGesture.bind(this);\n this._onDrag = this._onDrag.bind(this);\n this._onShake = this._onShake.bind(this);\n this._onLongPress = this._onLongPress.bind(this);\n this._onOrientationChange = this._onOrientationChange.bind(this);\n this._onMouseWheel = this._onMouseWheel.bind(this);\n this._onMouseOut = this._onMouseOut.bind(this);\n this._onMouseEnter = this._onMouseEnter.bind(this);\n this._onContextMenu = this._onContextMenu.bind(this);\n this._onDoubleClick = this._onDoubleClick.bind(this);\n this._onDragOver = this._onDragOver.bind(this);\n this._onDragEnter = this._simpleEventHandler.bind(this, 'dragenter');\n this._onDragLeave = this._simpleEventHandler.bind(this, 'dragleave');\n this._onDrop = this._simpleEventHandler.bind(this, 'drop');\n this.eventsBound = true;\n },\n\n /**\n * @private\n * @param {Event} [e] Event object fired on Event.js gesture\n * @param {Event} [self] Inner Event object\n */\n _onGesture: function(e, self) {\n this.__onTransformGesture && this.__onTransformGesture(e, self);\n },\n\n /**\n * @private\n * @param {Event} [e] Event object fired on Event.js drag\n * @param {Event} [self] Inner Event object\n */\n _onDrag: function(e, self) {\n this.__onDrag && this.__onDrag(e, self);\n },\n\n /**\n * @private\n * @param {Event} [e] Event object fired on wheel event\n */\n _onMouseWheel: function(e) {\n this.__onMouseWheel(e);\n },\n\n /**\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n _onMouseOut: function(e) {\n var target = this._hoveredTarget;\n this.fire('mouse:out', { target: target, e: e });\n this._hoveredTarget = null;\n target && target.fire('mouseout', { e: e });\n\n var _this = this;\n this._hoveredTargets.forEach(function(_target){\n _this.fire('mouse:out', { target: target, e: e });\n _target && target.fire('mouseout', { e: e });\n });\n this._hoveredTargets = [];\n\n if (this._iTextInstances) {\n this._iTextInstances.forEach(function(obj) {\n if (obj.isEditing) {\n obj.hiddenTextarea.focus();\n }\n });\n }\n },\n\n /**\n * @private\n * @param {Event} e Event object fired on mouseenter\n */\n _onMouseEnter: function(e) {\n // This find target and consequent 'mouse:over' is used to\n // clear old instances on hovered target.\n // calling findTarget has the side effect of killing target.__corner.\n // as a short term fix we are not firing this if we are currently transforming.\n // as a long term fix we need to separate the action of finding a target with the\n // side effects we added to it.\n if (!this._currentTransform && !this.findTarget(e)) {\n this.fire('mouse:over', { target: null, e: e });\n this._hoveredTarget = null;\n this._hoveredTargets = [];\n }\n },\n\n /**\n * @private\n * @param {Event} [e] Event object fired on Event.js orientation change\n * @param {Event} [self] Inner Event object\n */\n _onOrientationChange: function(e, self) {\n this.__onOrientationChange && this.__onOrientationChange(e, self);\n },\n\n /**\n * @private\n * @param {Event} [e] Event object fired on Event.js shake\n * @param {Event} [self] Inner Event object\n */\n _onShake: function(e, self) {\n this.__onShake && this.__onShake(e, self);\n },\n\n /**\n * @private\n * @param {Event} [e] Event object fired on Event.js shake\n * @param {Event} [self] Inner Event object\n */\n _onLongPress: function(e, self) {\n this.__onLongPress && this.__onLongPress(e, self);\n },\n\n /**\n * prevent default to allow drop event to be fired\n * @private\n * @param {Event} [e] Event object fired on Event.js shake\n */\n _onDragOver: function(e) {\n e.preventDefault();\n var target = this._simpleEventHandler('dragover', e);\n this._fireEnterLeaveEvents(target, e);\n },\n\n /**\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n _onContextMenu: function (e) {\n if (this.stopContextMenu) {\n e.stopPropagation();\n e.preventDefault();\n }\n return false;\n },\n\n /**\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n _onDoubleClick: function (e) {\n this._cacheTransformEventData(e);\n this._handleEvent(e, 'dblclick');\n this._resetTransformEventData(e);\n },\n\n /**\n * Return a the id of an event.\n * returns either the pointerId or the identifier or 0 for the mouse event\n * @private\n * @param {Event} evt Event object\n */\n getPointerId: function(evt) {\n var changedTouches = evt.changedTouches;\n\n if (changedTouches) {\n return changedTouches[0] && changedTouches[0].identifier;\n }\n\n if (this.enablePointerEvents) {\n return evt.pointerId;\n }\n\n return -1;\n },\n\n /**\n * Determines if an event has the id of the event that is considered main\n * @private\n * @param {evt} event Event object\n */\n _isMainEvent: function(evt) {\n if (evt.isPrimary === true) {\n return true;\n }\n if (evt.isPrimary === false) {\n return false;\n }\n if (evt.type === 'touchend' && evt.touches.length === 0) {\n return true;\n }\n if (evt.changedTouches) {\n return evt.changedTouches[0].identifier === this.mainTouchId;\n }\n return true;\n },\n\n /**\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n _onTouchStart: function(e) {\n e.preventDefault();\n if (this.mainTouchId === null) {\n this.mainTouchId = this.getPointerId(e);\n }\n this.__onMouseDown(e);\n this._resetTransformEventData();\n var canvasElement = this.upperCanvasEl,\n eventTypePrefix = this._getEventPrefix();\n addListener(fabric.document, 'touchend', this._onTouchEnd, addEventOptions);\n addListener(fabric.document, 'touchmove', this._onMouseMove, addEventOptions);\n // Unbind mousedown to prevent double triggers from touch devices\n removeListener(canvasElement, eventTypePrefix + 'down', this._onMouseDown);\n },\n\n /**\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n _onMouseDown: function (e) {\n this.__onMouseDown(e);\n this._resetTransformEventData();\n var canvasElement = this.upperCanvasEl,\n eventTypePrefix = this._getEventPrefix();\n removeListener(canvasElement, eventTypePrefix + 'move', this._onMouseMove, addEventOptions);\n addListener(fabric.document, eventTypePrefix + 'up', this._onMouseUp);\n addListener(fabric.document, eventTypePrefix + 'move', this._onMouseMove, addEventOptions);\n },\n\n /**\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n _onTouchEnd: function(e) {\n if (e.touches.length > 0) {\n // if there are still touches stop here\n return;\n }\n this.__onMouseUp(e);\n this._resetTransformEventData();\n this.mainTouchId = null;\n var eventTypePrefix = this._getEventPrefix();\n removeListener(fabric.document, 'touchend', this._onTouchEnd, addEventOptions);\n removeListener(fabric.document, 'touchmove', this._onMouseMove, addEventOptions);\n var _this = this;\n if (this._willAddMouseDown) {\n clearTimeout(this._willAddMouseDown);\n }\n this._willAddMouseDown = setTimeout(function() {\n // Wait 400ms before rebinding mousedown to prevent double triggers\n // from touch devices\n addListener(_this.upperCanvasEl, eventTypePrefix + 'down', _this._onMouseDown);\n _this._willAddMouseDown = 0;\n }, 400);\n },\n\n /**\n * @private\n * @param {Event} e Event object fired on mouseup\n */\n _onMouseUp: function (e) {\n this.__onMouseUp(e);\n this._resetTransformEventData();\n var canvasElement = this.upperCanvasEl,\n eventTypePrefix = this._getEventPrefix();\n if (this._isMainEvent(e)) {\n removeListener(fabric.document, eventTypePrefix + 'up', this._onMouseUp);\n removeListener(fabric.document, eventTypePrefix + 'move', this._onMouseMove, addEventOptions);\n addListener(canvasElement, eventTypePrefix + 'move', this._onMouseMove, addEventOptions);\n }\n },\n\n /**\n * @private\n * @param {Event} e Event object fired on mousemove\n */\n _onMouseMove: function (e) {\n !this.allowTouchScrolling && e.preventDefault && e.preventDefault();\n this.__onMouseMove(e);\n },\n\n /**\n * @private\n */\n _onResize: function () {\n this.calcOffset();\n },\n\n /**\n * Decides whether the canvas should be redrawn in mouseup and mousedown events.\n * @private\n * @param {Object} target\n */\n _shouldRender: function(target) {\n var activeObject = this._activeObject;\n\n if (\n !!activeObject !== !!target ||\n (activeObject && target && (activeObject !== target))\n ) {\n // this covers: switch of target, from target to no target, selection of target\n // multiSelection with key and mouse\n return true;\n }\n else if (activeObject && activeObject.isEditing) {\n // if we mouse up/down over a editing textbox a cursor change,\n // there is no need to re render\n return false;\n }\n return false;\n },\n\n /**\n * Method that defines the actions when mouse is released on canvas.\n * The method resets the currentTransform parameters, store the image corner\n * position in the image object and render the canvas on top.\n * @private\n * @param {Event} e Event object fired on mouseup\n */\n __onMouseUp: function (e) {\n var target, transform = this._currentTransform,\n groupSelector = this._groupSelector, shouldRender = false,\n isClick = (!groupSelector || (groupSelector.left === 0 && groupSelector.top === 0));\n this._cacheTransformEventData(e);\n target = this._target;\n this._handleEvent(e, 'up:before');\n // if right/middle click just fire events and return\n // target undefined will make the _handleEvent search the target\n if (checkClick(e, RIGHT_CLICK)) {\n if (this.fireRightClick) {\n this._handleEvent(e, 'up', RIGHT_CLICK, isClick);\n }\n return;\n }\n\n if (checkClick(e, MIDDLE_CLICK)) {\n if (this.fireMiddleClick) {\n this._handleEvent(e, 'up', MIDDLE_CLICK, isClick);\n }\n this._resetTransformEventData();\n return;\n }\n\n if (this.isDrawingMode && this._isCurrentlyDrawing) {\n this._onMouseUpInDrawingMode(e);\n return;\n }\n\n if (!this._isMainEvent(e)) {\n return;\n }\n if (transform) {\n this._finalizeCurrentTransform(e);\n shouldRender = transform.actionPerformed;\n }\n if (!isClick) {\n var targetWasActive = target === this._activeObject;\n this._maybeGroupObjects(e);\n if (!shouldRender) {\n shouldRender = (\n this._shouldRender(target) ||\n (!targetWasActive && target === this._activeObject)\n );\n }\n }\n if (target) {\n var corner = target._findTargetCorner(\n this.getPointer(e, true),\n fabric.util.isTouchEvent(e)\n );\n var control = target.controls[corner],\n mouseUpHandler = control && control.getMouseUpHandler(e, target, control);\n if (mouseUpHandler) {\n mouseUpHandler(e, target, control);\n }\n target.isMoving = false;\n }\n this._setCursorFromEvent(e, target);\n this._handleEvent(e, 'up', LEFT_CLICK, isClick);\n this._groupSelector = null;\n this._currentTransform = null;\n // reset the target information about which corner is selected\n target && (target.__corner = 0);\n if (shouldRender) {\n this.requestRenderAll();\n }\n else if (!isClick) {\n this.renderTop();\n }\n },\n\n /**\n * @private\n * Handle event firing for target and subtargets\n * @param {Event} e event from mouse\n * @param {String} eventType event to fire (up, down or move)\n * @return {Fabric.Object} target return the the target found, for internal reasons.\n */\n _simpleEventHandler: function(eventType, e) {\n var target = this.findTarget(e),\n targets = this.targets,\n options = {\n e: e,\n target: target,\n subTargets: targets,\n };\n this.fire(eventType, options);\n target && target.fire(eventType, options);\n if (!targets) {\n return target;\n }\n for (var i = 0; i < targets.length; i++) {\n targets[i].fire(eventType, options);\n }\n return target;\n },\n\n /**\n * @private\n * Handle event firing for target and subtargets\n * @param {Event} e event from mouse\n * @param {String} eventType event to fire (up, down or move)\n * @param {fabric.Object} targetObj receiving event\n * @param {Number} [button] button used in the event 1 = left, 2 = middle, 3 = right\n * @param {Boolean} isClick for left button only, indicates that the mouse up happened without move.\n */\n _handleEvent: function(e, eventType, button, isClick) {\n var target = this._target,\n targets = this.targets || [],\n options = {\n e: e,\n target: target,\n subTargets: targets,\n button: button || LEFT_CLICK,\n isClick: isClick || false,\n pointer: this._pointer,\n absolutePointer: this._absolutePointer,\n transform: this._currentTransform\n };\n if (eventType === 'up') {\n options.currentTarget = this.findTarget(e);\n options.currentSubTargets = this.targets;\n }\n this.fire('mouse:' + eventType, options);\n target && target.fire('mouse' + eventType, options);\n for (var i = 0; i < targets.length; i++) {\n targets[i].fire('mouse' + eventType, options);\n }\n },\n\n /**\n * @private\n * @param {Event} e send the mouse event that generate the finalize down, so it can be used in the event\n */\n _finalizeCurrentTransform: function(e) {\n\n var transform = this._currentTransform,\n target = transform.target,\n eventName,\n options = {\n e: e,\n target: target,\n transform: transform,\n action: transform.action,\n };\n\n if (target._scaling) {\n target._scaling = false;\n }\n\n target.setCoords();\n\n if (transform.actionPerformed || (this.stateful && target.hasStateChanged())) {\n if (transform.actionPerformed) {\n // this is not friendly to the new control api.\n // is deprecated.\n eventName = this._addEventOptions(options, transform);\n this._fire(eventName, options);\n }\n this._fire('modified', options);\n }\n },\n\n /**\n * Mutate option object in order to add by property and give back the event name.\n * @private\n * @deprecated since 4.2.0\n * @param {Object} options to mutate\n * @param {Object} transform to inspect action from\n */\n _addEventOptions: function(options, transform) {\n // we can probably add more details at low cost\n // scale change, rotation changes, translation changes\n var eventName, by;\n switch (transform.action) {\n case 'scaleX':\n eventName = 'scaled';\n by = 'x';\n break;\n case 'scaleY':\n eventName = 'scaled';\n by = 'y';\n break;\n case 'skewX':\n eventName = 'skewed';\n by = 'x';\n break;\n case 'skewY':\n eventName = 'skewed';\n by = 'y';\n break;\n case 'scale':\n eventName = 'scaled';\n by = 'equally';\n break;\n case 'rotate':\n eventName = 'rotated';\n break;\n case 'drag':\n eventName = 'moved';\n break;\n }\n options.by = by;\n return eventName;\n },\n\n /**\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n _onMouseDownInDrawingMode: function(e) {\n this._isCurrentlyDrawing = true;\n if (this.getActiveObject()) {\n this.discardActiveObject(e).requestRenderAll();\n }\n var pointer = this.getPointer(e);\n this.freeDrawingBrush.onMouseDown(pointer, { e: e, pointer: pointer });\n this._handleEvent(e, 'down');\n },\n\n /**\n * @private\n * @param {Event} e Event object fired on mousemove\n */\n _onMouseMoveInDrawingMode: function(e) {\n if (this._isCurrentlyDrawing) {\n var pointer = this.getPointer(e);\n this.freeDrawingBrush.onMouseMove(pointer, { e: e, pointer: pointer });\n }\n this.setCursor(this.freeDrawingCursor);\n this._handleEvent(e, 'move');\n },\n\n /**\n * @private\n * @param {Event} e Event object fired on mouseup\n */\n _onMouseUpInDrawingMode: function(e) {\n var pointer = this.getPointer(e);\n this._isCurrentlyDrawing = this.freeDrawingBrush.onMouseUp({ e: e, pointer: pointer });\n this._handleEvent(e, 'up');\n },\n\n /**\n * Method that defines the actions when mouse is clicked on canvas.\n * The method inits the currentTransform parameters and renders all the\n * canvas so the current image can be placed on the top canvas and the rest\n * in on the container one.\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n __onMouseDown: function (e) {\n this._cacheTransformEventData(e);\n this._handleEvent(e, 'down:before');\n var target = this._target;\n // if right click just fire events\n if (checkClick(e, RIGHT_CLICK)) {\n if (this.fireRightClick) {\n this._handleEvent(e, 'down', RIGHT_CLICK);\n }\n return;\n }\n\n if (checkClick(e, MIDDLE_CLICK)) {\n if (this.fireMiddleClick) {\n this._handleEvent(e, 'down', MIDDLE_CLICK);\n }\n return;\n }\n\n if (this.isDrawingMode) {\n this._onMouseDownInDrawingMode(e);\n return;\n }\n\n if (!this._isMainEvent(e)) {\n return;\n }\n\n // ignore if some object is being transformed at this moment\n if (this._currentTransform) {\n return;\n }\n\n var pointer = this._pointer;\n // save pointer for check in __onMouseUp event\n this._previousPointer = pointer;\n var shouldRender = this._shouldRender(target),\n shouldGroup = this._shouldGroup(e, target);\n if (this._shouldClearSelection(e, target)) {\n this.discardActiveObject(e);\n }\n else if (shouldGroup) {\n this._handleGrouping(e, target);\n target = this._activeObject;\n }\n\n if (this.selection && (!target ||\n (!target.selectable && !target.isEditing && target !== this._activeObject))) {\n this._groupSelector = {\n ex: pointer.x,\n ey: pointer.y,\n top: 0,\n left: 0\n };\n }\n\n if (target) {\n var alreadySelected = target === this._activeObject;\n if (target.selectable) {\n this.setActiveObject(target, e);\n }\n var corner = target._findTargetCorner(\n this.getPointer(e, true),\n fabric.util.isTouchEvent(e)\n );\n target.__corner = corner;\n if (target === this._activeObject && (corner || !shouldGroup)) {\n var control = target.controls[corner],\n mouseDownHandler = control && control.getMouseDownHandler(e, target, control);\n if (mouseDownHandler) {\n mouseDownHandler(e, target, control);\n }\n this._setupCurrentTransform(e, target, alreadySelected);\n }\n }\n this._handleEvent(e, 'down');\n // we must renderAll so that we update the visuals\n (shouldRender || shouldGroup) && this.requestRenderAll();\n },\n\n /**\n * reset cache form common information needed during event processing\n * @private\n */\n _resetTransformEventData: function() {\n this._target = null;\n this._pointer = null;\n this._absolutePointer = null;\n },\n\n /**\n * Cache common information needed during event processing\n * @private\n * @param {Event} e Event object fired on event\n */\n _cacheTransformEventData: function(e) {\n // reset in order to avoid stale caching\n this._resetTransformEventData();\n this._pointer = this.getPointer(e, true);\n this._absolutePointer = this.restorePointerVpt(this._pointer);\n this._target = this._currentTransform ? this._currentTransform.target : this.findTarget(e) || null;\n },\n\n /**\n * @private\n */\n _beforeTransform: function(e) {\n var t = this._currentTransform;\n this.stateful && t.target.saveState();\n this.fire('before:transform', {\n e: e,\n transform: t,\n });\n },\n\n /**\n * Method that defines the actions when mouse is hovering the canvas.\n * The currentTransform parameter will define whether the user is rotating/scaling/translating\n * an image or neither of them (only hovering). A group selection is also possible and would cancel\n * all any other type of action.\n * In case of an image transformation only the top canvas will be rendered.\n * @private\n * @param {Event} e Event object fired on mousemove\n */\n __onMouseMove: function (e) {\n this._handleEvent(e, 'move:before');\n this._cacheTransformEventData(e);\n var target, pointer;\n\n if (this.isDrawingMode) {\n this._onMouseMoveInDrawingMode(e);\n return;\n }\n\n if (!this._isMainEvent(e)) {\n return;\n }\n\n var groupSelector = this._groupSelector;\n\n // We initially clicked in an empty area, so we draw a box for multiple selection\n if (groupSelector) {\n pointer = this._pointer;\n\n groupSelector.left = pointer.x - groupSelector.ex;\n groupSelector.top = pointer.y - groupSelector.ey;\n\n this.renderTop();\n }\n else if (!this._currentTransform) {\n target = this.findTarget(e) || null;\n this._setCursorFromEvent(e, target);\n this._fireOverOutEvents(target, e);\n }\n else {\n this._transformObject(e);\n }\n this._handleEvent(e, 'move');\n this._resetTransformEventData();\n },\n\n /**\n * Manage the mouseout, mouseover events for the fabric object on the canvas\n * @param {Fabric.Object} target the target where the target from the mousemove event\n * @param {Event} e Event object fired on mousemove\n * @private\n */\n _fireOverOutEvents: function(target, e) {\n var _hoveredTarget = this._hoveredTarget,\n _hoveredTargets = this._hoveredTargets, targets = this.targets,\n length = Math.max(_hoveredTargets.length, targets.length);\n\n this.fireSyntheticInOutEvents(target, e, {\n oldTarget: _hoveredTarget,\n evtOut: 'mouseout',\n canvasEvtOut: 'mouse:out',\n evtIn: 'mouseover',\n canvasEvtIn: 'mouse:over',\n });\n for (var i = 0; i < length; i++){\n this.fireSyntheticInOutEvents(targets[i], e, {\n oldTarget: _hoveredTargets[i],\n evtOut: 'mouseout',\n evtIn: 'mouseover',\n });\n }\n this._hoveredTarget = target;\n this._hoveredTargets = this.targets.concat();\n },\n\n /**\n * Manage the dragEnter, dragLeave events for the fabric objects on the canvas\n * @param {Fabric.Object} target the target where the target from the onDrag event\n * @param {Event} e Event object fired on ondrag\n * @private\n */\n _fireEnterLeaveEvents: function(target, e) {\n var _draggedoverTarget = this._draggedoverTarget,\n _hoveredTargets = this._hoveredTargets, targets = this.targets,\n length = Math.max(_hoveredTargets.length, targets.length);\n\n this.fireSyntheticInOutEvents(target, e, {\n oldTarget: _draggedoverTarget,\n evtOut: 'dragleave',\n evtIn: 'dragenter',\n });\n for (var i = 0; i < length; i++) {\n this.fireSyntheticInOutEvents(targets[i], e, {\n oldTarget: _hoveredTargets[i],\n evtOut: 'dragleave',\n evtIn: 'dragenter',\n });\n }\n this._draggedoverTarget = target;\n },\n\n /**\n * Manage the synthetic in/out events for the fabric objects on the canvas\n * @param {Fabric.Object} target the target where the target from the supported events\n * @param {Event} e Event object fired\n * @param {Object} config configuration for the function to work\n * @param {String} config.targetName property on the canvas where the old target is stored\n * @param {String} [config.canvasEvtOut] name of the event to fire at canvas level for out\n * @param {String} config.evtOut name of the event to fire for out\n * @param {String} [config.canvasEvtIn] name of the event to fire at canvas level for in\n * @param {String} config.evtIn name of the event to fire for in\n * @private\n */\n fireSyntheticInOutEvents: function(target, e, config) {\n var inOpt, outOpt, oldTarget = config.oldTarget, outFires, inFires,\n targetChanged = oldTarget !== target, canvasEvtIn = config.canvasEvtIn, canvasEvtOut = config.canvasEvtOut;\n if (targetChanged) {\n inOpt = { e: e, target: target, previousTarget: oldTarget };\n outOpt = { e: e, target: oldTarget, nextTarget: target };\n }\n inFires = target && targetChanged;\n outFires = oldTarget && targetChanged;\n if (outFires) {\n canvasEvtOut && this.fire(canvasEvtOut, outOpt);\n oldTarget.fire(config.evtOut, outOpt);\n }\n if (inFires) {\n canvasEvtIn && this.fire(canvasEvtIn, inOpt);\n target.fire(config.evtIn, inOpt);\n }\n },\n\n /**\n * Method that defines actions when an Event Mouse Wheel\n * @param {Event} e Event object fired on mouseup\n */\n __onMouseWheel: function(e) {\n this._cacheTransformEventData(e);\n this._handleEvent(e, 'wheel');\n this._resetTransformEventData();\n },\n\n /**\n * @private\n * @param {Event} e Event fired on mousemove\n */\n _transformObject: function(e) {\n var pointer = this.getPointer(e),\n transform = this._currentTransform;\n\n transform.reset = false;\n transform.target.isMoving = true;\n transform.shiftKey = e.shiftKey;\n transform.altKey = e[this.centeredKey];\n\n this._performTransformAction(e, transform, pointer);\n transform.actionPerformed && this.requestRenderAll();\n },\n\n /**\n * @private\n */\n _performTransformAction: function(e, transform, pointer) {\n var x = pointer.x,\n y = pointer.y,\n action = transform.action,\n actionPerformed = false,\n actionHandler = transform.actionHandler;\n // this object could be created from the function in the control handlers\n\n\n if (actionHandler) {\n actionPerformed = actionHandler(e, transform, x, y);\n }\n if (action === 'drag' && actionPerformed) {\n this.setCursor(transform.target.moveCursor || this.moveCursor);\n }\n transform.actionPerformed = transform.actionPerformed || actionPerformed;\n },\n\n /**\n * @private\n */\n _fire: fabric.controlsUtils.fireEvent,\n\n /**\n * Sets the cursor depending on where the canvas is being hovered.\n * Note: very buggy in Opera\n * @param {Event} e Event object\n * @param {Object} target Object that the mouse is hovering, if so.\n */\n _setCursorFromEvent: function (e, target) {\n if (!target) {\n this.setCursor(this.defaultCursor);\n return false;\n }\n var hoverCursor = target.hoverCursor || this.hoverCursor,\n activeSelection = this._activeObject && this._activeObject.type === 'activeSelection' ?\n this._activeObject : null,\n // only show proper corner when group selection is not active\n corner = (!activeSelection || !activeSelection.contains(target))\n // here we call findTargetCorner always with undefined for the touch parameter.\n // we assume that if you are using a cursor you do not need to interact with\n // the bigger touch area.\n && target._findTargetCorner(this.getPointer(e, true));\n\n if (!corner) {\n if (target.subTargetCheck){\n // hoverCursor should come from top-most subTarget,\n // so we walk the array backwards\n this.targets.concat().reverse().map(function(_target){\n hoverCursor = _target.hoverCursor || hoverCursor;\n });\n }\n this.setCursor(hoverCursor);\n }\n else {\n this.setCursor(this.getCornerCursor(corner, target, e));\n }\n },\n\n /**\n * @private\n */\n getCornerCursor: function(corner, target, e) {\n var control = target.controls[corner];\n return control.cursorStyleHandler(e, control, target);\n }\n });\n})();\n\n\n(function() {\n\n var min = Math.min,\n max = Math.max;\n\n fabric.util.object.extend(fabric.Canvas.prototype, /** @lends fabric.Canvas.prototype */ {\n\n /**\n * @private\n * @param {Event} e Event object\n * @param {fabric.Object} target\n * @return {Boolean}\n */\n _shouldGroup: function(e, target) {\n var activeObject = this._activeObject;\n return activeObject && this._isSelectionKeyPressed(e) && target && target.selectable && this.selection &&\n (activeObject !== target || activeObject.type === 'activeSelection') && !target.onSelect({ e: e });\n },\n\n /**\n * @private\n * @param {Event} e Event object\n * @param {fabric.Object} target\n */\n _handleGrouping: function (e, target) {\n var activeObject = this._activeObject;\n // avoid multi select when shift click on a corner\n if (activeObject.__corner) {\n return;\n }\n if (target === activeObject) {\n // if it's a group, find target again, using activeGroup objects\n target = this.findTarget(e, true);\n // if even object is not found or we are on activeObjectCorner, bail out\n if (!target || !target.selectable) {\n return;\n }\n }\n if (activeObject && activeObject.type === 'activeSelection') {\n this._updateActiveSelection(target, e);\n }\n else {\n this._createActiveSelection(target, e);\n }\n },\n\n /**\n * @private\n */\n _updateActiveSelection: function(target, e) {\n var activeSelection = this._activeObject,\n currentActiveObjects = activeSelection._objects.slice(0);\n if (activeSelection.contains(target)) {\n activeSelection.removeWithUpdate(target);\n this._hoveredTarget = target;\n this._hoveredTargets = this.targets.concat();\n if (activeSelection.size() === 1) {\n // activate last remaining object\n this._setActiveObject(activeSelection.item(0), e);\n }\n }\n else {\n activeSelection.addWithUpdate(target);\n this._hoveredTarget = activeSelection;\n this._hoveredTargets = this.targets.concat();\n }\n this._fireSelectionEvents(currentActiveObjects, e);\n },\n\n /**\n * @private\n */\n _createActiveSelection: function(target, e) {\n var currentActives = this.getActiveObjects(), group = this._createGroup(target);\n this._hoveredTarget = group;\n // ISSUE 4115: should we consider subTargets here?\n // this._hoveredTargets = [];\n // this._hoveredTargets = this.targets.concat();\n this._setActiveObject(group, e);\n this._fireSelectionEvents(currentActives, e);\n },\n\n /**\n * @private\n * @param {Object} target\n */\n _createGroup: function(target) {\n var objects = this._objects,\n isActiveLower = objects.indexOf(this._activeObject) < objects.indexOf(target),\n groupObjects = isActiveLower\n ? [this._activeObject, target]\n : [target, this._activeObject];\n this._activeObject.isEditing && this._activeObject.exitEditing();\n return new fabric.ActiveSelection(groupObjects, {\n canvas: this\n });\n },\n\n /**\n * @private\n * @param {Event} e mouse event\n */\n _groupSelectedObjects: function (e) {\n\n var group = this._collectObjects(e),\n aGroup;\n\n // do not create group for 1 element only\n if (group.length === 1) {\n this.setActiveObject(group[0], e);\n }\n else if (group.length > 1) {\n aGroup = new fabric.ActiveSelection(group.reverse(), {\n canvas: this\n });\n this.setActiveObject(aGroup, e);\n }\n },\n\n /**\n * @private\n */\n _collectObjects: function(e) {\n var group = [],\n currentObject,\n x1 = this._groupSelector.ex,\n y1 = this._groupSelector.ey,\n x2 = x1 + this._groupSelector.left,\n y2 = y1 + this._groupSelector.top,\n selectionX1Y1 = new fabric.Point(min(x1, x2), min(y1, y2)),\n selectionX2Y2 = new fabric.Point(max(x1, x2), max(y1, y2)),\n allowIntersect = !this.selectionFullyContained,\n isClick = x1 === x2 && y1 === y2;\n // we iterate reverse order to collect top first in case of click.\n for (var i = this._objects.length; i--; ) {\n currentObject = this._objects[i];\n\n if (!currentObject || !currentObject.selectable || !currentObject.visible) {\n continue;\n }\n\n if ((allowIntersect && currentObject.intersectsWithRect(selectionX1Y1, selectionX2Y2)) ||\n currentObject.isContainedWithinRect(selectionX1Y1, selectionX2Y2) ||\n (allowIntersect && currentObject.containsPoint(selectionX1Y1)) ||\n (allowIntersect && currentObject.containsPoint(selectionX2Y2))\n ) {\n group.push(currentObject);\n // only add one object if it's a click\n if (isClick) {\n break;\n }\n }\n }\n\n if (group.length > 1) {\n group = group.filter(function(object) {\n return !object.onSelect({ e: e });\n });\n }\n\n return group;\n },\n\n /**\n * @private\n */\n _maybeGroupObjects: function(e) {\n if (this.selection && this._groupSelector) {\n this._groupSelectedObjects(e);\n }\n this.setCursor(this.defaultCursor);\n // clear selection and current transformation\n this._groupSelector = null;\n }\n });\n\n})();\n\n\n(function () {\n fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.StaticCanvas.prototype */ {\n\n /**\n * Exports canvas element to a dataurl image. Note that when multiplier is used, cropping is scaled appropriately\n * @param {Object} [options] Options object\n * @param {String} [options.format=png] The format of the output image. Either \"jpeg\" or \"png\"\n * @param {Number} [options.quality=1] Quality level (0..1). Only used for jpeg.\n * @param {Number} [options.multiplier=1] Multiplier to scale by, to have consistent\n * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14\n * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14\n * @param {Number} [options.width] Cropping width. Introduced in v1.2.14\n * @param {Number} [options.height] Cropping height. Introduced in v1.2.14\n * @param {Boolean} [options.enableRetinaScaling] Enable retina scaling for clone image. Introduce in 2.0.0\n * @return {String} Returns a data: URL containing a representation of the object in the format specified by options.format\n * @see {@link http://jsfiddle.net/fabricjs/NfZVb/|jsFiddle demo}\n * @example <caption>Generate jpeg dataURL with lower quality</caption>\n * var dataURL = canvas.toDataURL({\n * format: 'jpeg',\n * quality: 0.8\n * });\n * @example <caption>Generate cropped png dataURL (clipping of canvas)</caption>\n * var dataURL = canvas.toDataURL({\n * format: 'png',\n * left: 100,\n * top: 100,\n * width: 200,\n * height: 200\n * });\n * @example <caption>Generate double scaled png dataURL</caption>\n * var dataURL = canvas.toDataURL({\n * format: 'png',\n * multiplier: 2\n * });\n */\n toDataURL: function (options) {\n options || (options = { });\n\n var format = options.format || 'png',\n quality = options.quality || 1,\n multiplier = (options.multiplier || 1) * (options.enableRetinaScaling ? this.getRetinaScaling() : 1),\n canvasEl = this.toCanvasElement(multiplier, options);\n return fabric.util.toDataURL(canvasEl, format, quality);\n },\n\n /**\n * Create a new HTMLCanvas element painted with the current canvas content.\n * No need to resize the actual one or repaint it.\n * Will transfer object ownership to a new canvas, paint it, and set everything back.\n * This is an intermediary step used to get to a dataUrl but also it is useful to\n * create quick image copies of a canvas without passing for the dataUrl string\n * @param {Number} [multiplier] a zoom factor.\n * @param {Object} [cropping] Cropping informations\n * @param {Number} [cropping.left] Cropping left offset.\n * @param {Number} [cropping.top] Cropping top offset.\n * @param {Number} [cropping.width] Cropping width.\n * @param {Number} [cropping.height] Cropping height.\n */\n toCanvasElement: function(multiplier, cropping) {\n multiplier = multiplier || 1;\n cropping = cropping || { };\n var scaledWidth = (cropping.width || this.width) * multiplier,\n scaledHeight = (cropping.height || this.height) * multiplier,\n zoom = this.getZoom(),\n originalWidth = this.width,\n originalHeight = this.height,\n newZoom = zoom * multiplier,\n vp = this.viewportTransform,\n translateX = (vp[4] - (cropping.left || 0)) * multiplier,\n translateY = (vp[5] - (cropping.top || 0)) * multiplier,\n originalInteractive = this.interactive,\n newVp = [newZoom, 0, 0, newZoom, translateX, translateY],\n originalRetina = this.enableRetinaScaling,\n canvasEl = fabric.util.createCanvasElement(),\n originalContextTop = this.contextTop;\n canvasEl.width = scaledWidth;\n canvasEl.height = scaledHeight;\n this.contextTop = null;\n this.enableRetinaScaling = false;\n this.interactive = false;\n this.viewportTransform = newVp;\n this.width = scaledWidth;\n this.height = scaledHeight;\n this.calcViewportBoundaries();\n this.renderCanvas(canvasEl.getContext('2d'), this._objects);\n this.viewportTransform = vp;\n this.width = originalWidth;\n this.height = originalHeight;\n this.calcViewportBoundaries();\n this.interactive = originalInteractive;\n this.enableRetinaScaling = originalRetina;\n this.contextTop = originalContextTop;\n return canvasEl;\n },\n });\n\n})();\n\n\nfabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.StaticCanvas.prototype */ {\n /**\n * Populates canvas with data from the specified JSON.\n * JSON format must conform to the one of {@link fabric.Canvas#toJSON}\n * @param {String|Object} json JSON string or object\n * @param {Function} callback Callback, invoked when json is parsed\n * and corresponding objects (e.g: {@link fabric.Image})\n * are initialized\n * @param {Function} [reviver] Method for further parsing of JSON elements, called after each fabric object created.\n * @return {fabric.Canvas} instance\n * @chainable\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#deserialization}\n * @see {@link http://jsfiddle.net/fabricjs/fmgXt/|jsFiddle demo}\n * @example <caption>loadFromJSON</caption>\n * canvas.loadFromJSON(json, canvas.renderAll.bind(canvas));\n * @example <caption>loadFromJSON with reviver</caption>\n * canvas.loadFromJSON(json, canvas.renderAll.bind(canvas), function(o, object) {\n * // `o` = json object\n * // `object` = fabric.Object instance\n * // ... do some stuff ...\n * });\n */\n loadFromJSON: function (json, callback, reviver) {\n if (!json) {\n return;\n }\n\n // serialize if it wasn't already\n var serialized = (typeof json === 'string')\n ? JSON.parse(json)\n : fabric.util.object.clone(json);\n\n var _this = this,\n clipPath = serialized.clipPath,\n renderOnAddRemove = this.renderOnAddRemove;\n\n this.renderOnAddRemove = false;\n\n delete serialized.clipPath;\n\n this._enlivenObjects(serialized.objects, function (enlivenedObjects) {\n _this.clear();\n _this._setBgOverlay(serialized, function () {\n if (clipPath) {\n _this._enlivenObjects([clipPath], function (enlivenedCanvasClip) {\n _this.clipPath = enlivenedCanvasClip[0];\n _this.__setupCanvas.call(_this, serialized, enlivenedObjects, renderOnAddRemove, callback);\n });\n }\n else {\n _this.__setupCanvas.call(_this, serialized, enlivenedObjects, renderOnAddRemove, callback);\n }\n });\n }, reviver);\n return this;\n },\n\n /**\n * @private\n * @param {Object} serialized Object with background and overlay information\n * @param {Array} restored canvas objects\n * @param {Function} cached renderOnAddRemove callback\n * @param {Function} callback Invoked after all background and overlay images/patterns loaded\n */\n __setupCanvas: function(serialized, enlivenedObjects, renderOnAddRemove, callback) {\n var _this = this;\n enlivenedObjects.forEach(function(obj, index) {\n // we splice the array just in case some custom classes restored from JSON\n // will add more object to canvas at canvas init.\n _this.insertAt(obj, index);\n });\n this.renderOnAddRemove = renderOnAddRemove;\n // remove parts i cannot set as options\n delete serialized.objects;\n delete serialized.backgroundImage;\n delete serialized.overlayImage;\n delete serialized.background;\n delete serialized.overlay;\n // this._initOptions does too many things to just\n // call it. Normally loading an Object from JSON\n // create the Object instance. Here the Canvas is\n // already an instance and we are just loading things over it\n this._setOptions(serialized);\n this.renderAll();\n callback && callback();\n },\n\n /**\n * @private\n * @param {Object} serialized Object with background and overlay information\n * @param {Function} callback Invoked after all background and overlay images/patterns loaded\n */\n _setBgOverlay: function(serialized, callback) {\n var loaded = {\n backgroundColor: false,\n overlayColor: false,\n backgroundImage: false,\n overlayImage: false\n };\n\n if (!serialized.backgroundImage && !serialized.overlayImage && !serialized.background && !serialized.overlay) {\n callback && callback();\n return;\n }\n\n var cbIfLoaded = function () {\n if (loaded.backgroundImage && loaded.overlayImage && loaded.backgroundColor && loaded.overlayColor) {\n callback && callback();\n }\n };\n\n this.__setBgOverlay('backgroundImage', serialized.backgroundImage, loaded, cbIfLoaded);\n this.__setBgOverlay('overlayImage', serialized.overlayImage, loaded, cbIfLoaded);\n this.__setBgOverlay('backgroundColor', serialized.background, loaded, cbIfLoaded);\n this.__setBgOverlay('overlayColor', serialized.overlay, loaded, cbIfLoaded);\n },\n\n /**\n * @private\n * @param {String} property Property to set (backgroundImage, overlayImage, backgroundColor, overlayColor)\n * @param {(Object|String)} value Value to set\n * @param {Object} loaded Set loaded property to true if property is set\n * @param {Object} callback Callback function to invoke after property is set\n */\n __setBgOverlay: function(property, value, loaded, callback) {\n var _this = this;\n\n if (!value) {\n loaded[property] = true;\n callback && callback();\n return;\n }\n\n if (property === 'backgroundImage' || property === 'overlayImage') {\n fabric.util.enlivenObjects([value], function(enlivedObject){\n _this[property] = enlivedObject[0];\n loaded[property] = true;\n callback && callback();\n });\n }\n else {\n this['set' + fabric.util.string.capitalize(property, true)](value, function() {\n loaded[property] = true;\n callback && callback();\n });\n }\n },\n\n /**\n * @private\n * @param {Array} objects\n * @param {Function} callback\n * @param {Function} [reviver]\n */\n _enlivenObjects: function (objects, callback, reviver) {\n if (!objects || objects.length === 0) {\n callback && callback([]);\n return;\n }\n\n fabric.util.enlivenObjects(objects, function(enlivenedObjects) {\n callback && callback(enlivenedObjects);\n }, null, reviver);\n },\n\n /**\n * @private\n * @param {String} format\n * @param {Function} callback\n */\n _toDataURL: function (format, callback) {\n this.clone(function (clone) {\n callback(clone.toDataURL(format));\n });\n },\n\n /**\n * @private\n * @param {String} format\n * @param {Number} multiplier\n * @param {Function} callback\n */\n _toDataURLWithMultiplier: function (format, multiplier, callback) {\n this.clone(function (clone) {\n callback(clone.toDataURLWithMultiplier(format, multiplier));\n });\n },\n\n /**\n * Clones canvas instance\n * @param {Object} [callback] Receives cloned instance as a first argument\n * @param {Array} [properties] Array of properties to include in the cloned canvas and children\n */\n clone: function (callback, properties) {\n var data = JSON.stringify(this.toJSON(properties));\n this.cloneWithoutData(function(clone) {\n clone.loadFromJSON(data, function() {\n callback && callback(clone);\n });\n });\n },\n\n /**\n * Clones canvas instance without cloning existing data.\n * This essentially copies canvas dimensions, clipping properties, etc.\n * but leaves data empty (so that you can populate it with your own)\n * @param {Object} [callback] Receives cloned instance as a first argument\n */\n cloneWithoutData: function(callback) {\n var el = fabric.util.createCanvasElement();\n\n el.width = this.width;\n el.height = this.height;\n\n var clone = new fabric.Canvas(el);\n if (this.backgroundImage) {\n clone.setBackgroundImage(this.backgroundImage.src, function() {\n clone.renderAll();\n callback && callback(clone);\n });\n clone.backgroundImageOpacity = this.backgroundImageOpacity;\n clone.backgroundImageStretch = this.backgroundImageStretch;\n }\n else {\n callback && callback(clone);\n }\n }\n});\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n extend = fabric.util.object.extend,\n clone = fabric.util.object.clone,\n toFixed = fabric.util.toFixed,\n capitalize = fabric.util.string.capitalize,\n degreesToRadians = fabric.util.degreesToRadians,\n supportsLineDash = fabric.StaticCanvas.supports('setLineDash'),\n objectCaching = !fabric.isLikelyNode,\n ALIASING_LIMIT = 2;\n\n if (fabric.Object) {\n return;\n }\n\n /**\n * Root object class from which all 2d shape classes inherit from\n * @class fabric.Object\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#objects}\n * @see {@link fabric.Object#initialize} for constructor definition\n *\n * @fires added\n * @fires removed\n *\n * @fires selected\n * @fires deselected\n * @fires modified\n * @fires modified\n * @fires moved\n * @fires scaled\n * @fires rotated\n * @fires skewed\n *\n * @fires rotating\n * @fires scaling\n * @fires moving\n * @fires skewing\n *\n * @fires mousedown\n * @fires mouseup\n * @fires mouseover\n * @fires mouseout\n * @fires mousewheel\n * @fires mousedblclick\n *\n * @fires dragover\n * @fires dragenter\n * @fires dragleave\n * @fires drop\n */\n fabric.Object = fabric.util.createClass(fabric.CommonMethods, /** @lends fabric.Object.prototype */ {\n\n /**\n * Type of an object (rect, circle, path, etc.).\n * Note that this property is meant to be read-only and not meant to be modified.\n * If you modify, certain parts of Fabric (such as JSON loading) won't work correctly.\n * @type String\n * @default\n */\n type: 'object',\n\n /**\n * Horizontal origin of transformation of an object (one of \"left\", \"right\", \"center\")\n * See http://jsfiddle.net/1ow02gea/244/ on how originX/originY affect objects in groups\n * @type String\n * @default\n */\n originX: 'left',\n\n /**\n * Vertical origin of transformation of an object (one of \"top\", \"bottom\", \"center\")\n * See http://jsfiddle.net/1ow02gea/244/ on how originX/originY affect objects in groups\n * @type String\n * @default\n */\n originY: 'top',\n\n /**\n * Top position of an object. Note that by default it's relative to object top. You can change this by setting originY={top/center/bottom}\n * @type Number\n * @default\n */\n top: 0,\n\n /**\n * Left position of an object. Note that by default it's relative to object left. You can change this by setting originX={left/center/right}\n * @type Number\n * @default\n */\n left: 0,\n\n /**\n * Object width\n * @type Number\n * @default\n */\n width: 0,\n\n /**\n * Object height\n * @type Number\n * @default\n */\n height: 0,\n\n /**\n * Object scale factor (horizontal)\n * @type Number\n * @default\n */\n scaleX: 1,\n\n /**\n * Object scale factor (vertical)\n * @type Number\n * @default\n */\n scaleY: 1,\n\n /**\n * When true, an object is rendered as flipped horizontally\n * @type Boolean\n * @default\n */\n flipX: false,\n\n /**\n * When true, an object is rendered as flipped vertically\n * @type Boolean\n * @default\n */\n flipY: false,\n\n /**\n * Opacity of an object\n * @type Number\n * @default\n */\n opacity: 1,\n\n /**\n * Angle of rotation of an object (in degrees)\n * @type Number\n * @default\n */\n angle: 0,\n\n /**\n * Angle of skew on x axes of an object (in degrees)\n * @type Number\n * @default\n */\n skewX: 0,\n\n /**\n * Angle of skew on y axes of an object (in degrees)\n * @type Number\n * @default\n */\n skewY: 0,\n\n /**\n * Size of object's controlling corners (in pixels)\n * @type Number\n * @default\n */\n cornerSize: 13,\n\n /**\n * Size of object's controlling corners when touch interaction is detected\n * @type Number\n * @default\n */\n touchCornerSize: 24,\n\n /**\n * When true, object's controlling corners are rendered as transparent inside (i.e. stroke instead of fill)\n * @type Boolean\n * @default\n */\n transparentCorners: true,\n\n /**\n * Default cursor value used when hovering over this object on canvas\n * @type String\n * @default\n */\n hoverCursor: null,\n\n /**\n * Default cursor value used when moving this object on canvas\n * @type String\n * @default\n */\n moveCursor: null,\n\n /**\n * Padding between object and its controlling borders (in pixels)\n * @type Number\n * @default\n */\n padding: 0,\n\n /**\n * Color of controlling borders of an object (when it's active)\n * @type String\n * @default\n */\n borderColor: 'rgb(178,204,255)',\n\n /**\n * Array specifying dash pattern of an object's borders (hasBorder must be true)\n * @since 1.6.2\n * @type Array\n */\n borderDashArray: null,\n\n /**\n * Color of controlling corners of an object (when it's active)\n * @type String\n * @default\n */\n cornerColor: 'rgb(178,204,255)',\n\n /**\n * Color of controlling corners of an object (when it's active and transparentCorners false)\n * @since 1.6.2\n * @type String\n * @default\n */\n cornerStrokeColor: null,\n\n /**\n * Specify style of control, 'rect' or 'circle'\n * @since 1.6.2\n * @type String\n */\n cornerStyle: 'rect',\n\n /**\n * Array specifying dash pattern of an object's control (hasBorder must be true)\n * @since 1.6.2\n * @type Array\n */\n cornerDashArray: null,\n\n /**\n * When true, this object will use center point as the origin of transformation\n * when being scaled via the controls.\n * <b>Backwards incompatibility note:</b> This property replaces \"centerTransform\" (Boolean).\n * @since 1.3.4\n * @type Boolean\n * @default\n */\n centeredScaling: false,\n\n /**\n * When true, this object will use center point as the origin of transformation\n * when being rotated via the controls.\n * <b>Backwards incompatibility note:</b> This property replaces \"centerTransform\" (Boolean).\n * @since 1.3.4\n * @type Boolean\n * @default\n */\n centeredRotation: true,\n\n /**\n * Color of object's fill\n * takes css colors https://www.w3.org/TR/css-color-3/\n * @type String\n * @default\n */\n fill: 'rgb(0,0,0)',\n\n /**\n * Fill rule used to fill an object\n * accepted values are nonzero, evenodd\n * <b>Backwards incompatibility note:</b> This property was used for setting globalCompositeOperation until v1.4.12 (use `fabric.Object#globalCompositeOperation` instead)\n * @type String\n * @default\n */\n fillRule: 'nonzero',\n\n /**\n * Composite rule used for canvas globalCompositeOperation\n * @type String\n * @default\n */\n globalCompositeOperation: 'source-over',\n\n /**\n * Background color of an object.\n * takes css colors https://www.w3.org/TR/css-color-3/\n * @type String\n * @default\n */\n backgroundColor: '',\n\n /**\n * Selection Background color of an object. colored layer behind the object when it is active.\n * does not mix good with globalCompositeOperation methods.\n * @type String\n * @default\n */\n selectionBackgroundColor: '',\n\n /**\n * When defined, an object is rendered via stroke and this property specifies its color\n * takes css colors https://www.w3.org/TR/css-color-3/\n * @type String\n * @default\n */\n stroke: null,\n\n /**\n * Width of a stroke used to render this object\n * @type Number\n * @default\n */\n strokeWidth: 1,\n\n /**\n * Array specifying dash pattern of an object's stroke (stroke must be defined)\n * @type Array\n */\n strokeDashArray: null,\n\n /**\n * Line offset of an object's stroke\n * @type Number\n * @default\n */\n strokeDashOffset: 0,\n\n /**\n * Line endings style of an object's stroke (one of \"butt\", \"round\", \"square\")\n * @type String\n * @default\n */\n strokeLineCap: 'butt',\n\n /**\n * Corner style of an object's stroke (one of \"bevil\", \"round\", \"miter\")\n * @type String\n * @default\n */\n strokeLineJoin: 'miter',\n\n /**\n * Maximum miter length (used for strokeLineJoin = \"miter\") of an object's stroke\n * @type Number\n * @default\n */\n strokeMiterLimit: 4,\n\n /**\n * Shadow object representing shadow of this shape\n * @type fabric.Shadow\n * @default\n */\n shadow: null,\n\n /**\n * Opacity of object's controlling borders when object is active and moving\n * @type Number\n * @default\n */\n borderOpacityWhenMoving: 0.4,\n\n /**\n * Scale factor of object's controlling borders\n * bigger number will make a thicker border\n * border is 1, so this is basically a border tickness\n * since there is no way to change the border itself.\n * @type Number\n * @default\n */\n borderScaleFactor: 1,\n\n /**\n * Minimum allowed scale value of an object\n * @type Number\n * @default\n */\n minScaleLimit: 0,\n\n /**\n * When set to `false`, an object can not be selected for modification (using either point-click-based or group-based selection).\n * But events still fire on it.\n * @type Boolean\n * @default\n */\n selectable: true,\n\n /**\n * When set to `false`, an object can not be a target of events. All events propagate through it. Introduced in v1.3.4\n * @type Boolean\n * @default\n */\n evented: true,\n\n /**\n * When set to `false`, an object is not rendered on canvas\n * @type Boolean\n * @default\n */\n visible: true,\n\n /**\n * When set to `false`, object's controls are not displayed and can not be used to manipulate object\n * @type Boolean\n * @default\n */\n hasControls: true,\n\n /**\n * When set to `false`, object's controlling borders are not rendered\n * @type Boolean\n * @default\n */\n hasBorders: true,\n\n /**\n * When set to `true`, objects are \"found\" on canvas on per-pixel basis rather than according to bounding box\n * @type Boolean\n * @default\n */\n perPixelTargetFind: false,\n\n /**\n * When `false`, default object's values are not included in its serialization\n * @type Boolean\n * @default\n */\n includeDefaultValues: true,\n\n /**\n * When `true`, object horizontal movement is locked\n * @type Boolean\n * @default\n */\n lockMovementX: false,\n\n /**\n * When `true`, object vertical movement is locked\n * @type Boolean\n * @default\n */\n lockMovementY: false,\n\n /**\n * When `true`, object rotation is locked\n * @type Boolean\n * @default\n */\n lockRotation: false,\n\n /**\n * When `true`, object horizontal scaling is locked\n * @type Boolean\n * @default\n */\n lockScalingX: false,\n\n /**\n * When `true`, object vertical scaling is locked\n * @type Boolean\n * @default\n */\n lockScalingY: false,\n\n /**\n * When `true`, object horizontal skewing is locked\n * @type Boolean\n * @default\n */\n lockSkewingX: false,\n\n /**\n * When `true`, object vertical skewing is locked\n * @type Boolean\n * @default\n */\n lockSkewingY: false,\n\n /**\n * When `true`, object cannot be flipped by scaling into negative values\n * @type Boolean\n * @default\n */\n lockScalingFlip: false,\n\n /**\n * When `true`, object is not exported in OBJECT/JSON\n * @since 1.6.3\n * @type Boolean\n * @default\n */\n excludeFromExport: false,\n\n /**\n * When `true`, object is cached on an additional canvas.\n * When `false`, object is not cached unless necessary ( clipPath )\n * default to true\n * @since 1.7.0\n * @type Boolean\n * @default true\n */\n objectCaching: objectCaching,\n\n /**\n * When `true`, object properties are checked for cache invalidation. In some particular\n * situation you may want this to be disabled ( spray brush, very big, groups)\n * or if your application does not allow you to modify properties for groups child you want\n * to disable it for groups.\n * default to false\n * since 1.7.0\n * @type Boolean\n * @default false\n */\n statefullCache: false,\n\n /**\n * When `true`, cache does not get updated during scaling. The picture will get blocky if scaled\n * too much and will be redrawn with correct details at the end of scaling.\n * this setting is performance and application dependant.\n * default to true\n * since 1.7.0\n * @type Boolean\n * @default true\n */\n noScaleCache: true,\n\n /**\n * When `false`, the stoke width will scale with the object.\n * When `true`, the stroke will always match the exact pixel size entered for stroke width.\n * default to false\n * @since 2.6.0\n * @type Boolean\n * @default false\n * @type Boolean\n * @default false\n */\n strokeUniform: false,\n\n /**\n * When set to `true`, object's cache will be rerendered next render call.\n * since 1.7.0\n * @type Boolean\n * @default true\n */\n dirty: true,\n\n /**\n * keeps the value of the last hovered corner during mouse move.\n * 0 is no corner, or 'mt', 'ml', 'mtr' etc..\n * It should be private, but there is no harm in using it as\n * a read-only property.\n * @type number|string|any\n * @default 0\n */\n __corner: 0,\n\n /**\n * Determines if the fill or the stroke is drawn first (one of \"fill\" or \"stroke\")\n * @type String\n * @default\n */\n paintFirst: 'fill',\n\n /**\n * List of properties to consider when checking if state\n * of an object is changed (fabric.Object#hasStateChanged)\n * as well as for history (undo/redo) purposes\n * @type Array\n */\n stateProperties: (\n 'top left width height scaleX scaleY flipX flipY originX originY transformMatrix ' +\n 'stroke strokeWidth strokeDashArray strokeLineCap strokeDashOffset strokeLineJoin strokeMiterLimit ' +\n 'angle opacity fill globalCompositeOperation shadow visible backgroundColor ' +\n 'skewX skewY fillRule paintFirst clipPath strokeUniform'\n ).split(' '),\n\n /**\n * List of properties to consider when checking if cache needs refresh\n * Those properties are checked by statefullCache ON ( or lazy mode if we want ) or from single\n * calls to Object.set(key, value). If the key is in this list, the object is marked as dirty\n * and refreshed at the next render\n * @type Array\n */\n cacheProperties: (\n 'fill stroke strokeWidth strokeDashArray width height paintFirst strokeUniform' +\n ' strokeLineCap strokeDashOffset strokeLineJoin strokeMiterLimit backgroundColor clipPath'\n ).split(' '),\n\n /**\n * List of properties to consider for animating colors.\n * @type Array\n */\n colorProperties: (\n 'fill stroke backgroundColor'\n ).split(' '),\n\n /**\n * a fabricObject that, without stroke define a clipping area with their shape. filled in black\n * the clipPath object gets used when the object has rendered, and the context is placed in the center\n * of the object cacheCanvas.\n * If you want 0,0 of a clipPath to align with an object center, use clipPath.originX/Y to 'center'\n * @type fabric.Object\n */\n clipPath: undefined,\n\n /**\n * Meaningful ONLY when the object is used as clipPath.\n * if true, the clipPath will make the object clip to the outside of the clipPath\n * since 2.4.0\n * @type boolean\n * @default false\n */\n inverted: false,\n\n /**\n * Meaningful ONLY when the object is used as clipPath.\n * if true, the clipPath will have its top and left relative to canvas, and will\n * not be influenced by the object transform. This will make the clipPath relative\n * to the canvas, but clipping just a particular object.\n * WARNING this is beta, this feature may change or be renamed.\n * since 2.4.0\n * @type boolean\n * @default false\n */\n absolutePositioned: false,\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n */\n initialize: function(options) {\n if (options) {\n this.setOptions(options);\n }\n },\n\n /**\n * Create a the canvas used to keep the cached copy of the object\n * @private\n */\n _createCacheCanvas: function() {\n this._cacheProperties = {};\n this._cacheCanvas = fabric.util.createCanvasElement();\n this._cacheContext = this._cacheCanvas.getContext('2d');\n this._updateCacheCanvas();\n // if canvas gets created, is empty, so dirty.\n this.dirty = true;\n },\n\n /**\n * Limit the cache dimensions so that X * Y do not cross fabric.perfLimitSizeTotal\n * and each side do not cross fabric.cacheSideLimit\n * those numbers are configurable so that you can get as much detail as you want\n * making bargain with performances.\n * @param {Object} dims\n * @param {Object} dims.width width of canvas\n * @param {Object} dims.height height of canvas\n * @param {Object} dims.zoomX zoomX zoom value to unscale the canvas before drawing cache\n * @param {Object} dims.zoomY zoomY zoom value to unscale the canvas before drawing cache\n * @return {Object}.width width of canvas\n * @return {Object}.height height of canvas\n * @return {Object}.zoomX zoomX zoom value to unscale the canvas before drawing cache\n * @return {Object}.zoomY zoomY zoom value to unscale the canvas before drawing cache\n */\n _limitCacheSize: function(dims) {\n var perfLimitSizeTotal = fabric.perfLimitSizeTotal,\n width = dims.width, height = dims.height,\n max = fabric.maxCacheSideLimit, min = fabric.minCacheSideLimit;\n if (width <= max && height <= max && width * height <= perfLimitSizeTotal) {\n if (width < min) {\n dims.width = min;\n }\n if (height < min) {\n dims.height = min;\n }\n return dims;\n }\n var ar = width / height, limitedDims = fabric.util.limitDimsByArea(ar, perfLimitSizeTotal),\n capValue = fabric.util.capValue,\n x = capValue(min, limitedDims.x, max),\n y = capValue(min, limitedDims.y, max);\n if (width > x) {\n dims.zoomX /= width / x;\n dims.width = x;\n dims.capped = true;\n }\n if (height > y) {\n dims.zoomY /= height / y;\n dims.height = y;\n dims.capped = true;\n }\n return dims;\n },\n\n /**\n * Return the dimension and the zoom level needed to create a cache canvas\n * big enough to host the object to be cached.\n * @private\n * @return {Object}.x width of object to be cached\n * @return {Object}.y height of object to be cached\n * @return {Object}.width width of canvas\n * @return {Object}.height height of canvas\n * @return {Object}.zoomX zoomX zoom value to unscale the canvas before drawing cache\n * @return {Object}.zoomY zoomY zoom value to unscale the canvas before drawing cache\n */\n _getCacheCanvasDimensions: function() {\n var objectScale = this.getTotalObjectScaling(),\n // caculate dimensions without skewing\n dim = this._getTransformedDimensions(0, 0),\n neededX = dim.x * objectScale.scaleX / this.scaleX,\n neededY = dim.y * objectScale.scaleY / this.scaleY;\n return {\n // for sure this ALIASING_LIMIT is slightly creating problem\n // in situation in which the cache canvas gets an upper limit\n // also objectScale contains already scaleX and scaleY\n width: neededX + ALIASING_LIMIT,\n height: neededY + ALIASING_LIMIT,\n zoomX: objectScale.scaleX,\n zoomY: objectScale.scaleY,\n x: neededX,\n y: neededY\n };\n },\n\n /**\n * Update width and height of the canvas for cache\n * returns true or false if canvas needed resize.\n * @private\n * @return {Boolean} true if the canvas has been resized\n */\n _updateCacheCanvas: function() {\n var targetCanvas = this.canvas;\n if (this.noScaleCache && targetCanvas && targetCanvas._currentTransform) {\n var target = targetCanvas._currentTransform.target,\n action = targetCanvas._currentTransform.action;\n if (this === target && action.slice && action.slice(0, 5) === 'scale') {\n return false;\n }\n }\n var canvas = this._cacheCanvas,\n dims = this._limitCacheSize(this._getCacheCanvasDimensions()),\n minCacheSize = fabric.minCacheSideLimit,\n width = dims.width, height = dims.height, drawingWidth, drawingHeight,\n zoomX = dims.zoomX, zoomY = dims.zoomY,\n dimensionsChanged = width !== this.cacheWidth || height !== this.cacheHeight,\n zoomChanged = this.zoomX !== zoomX || this.zoomY !== zoomY,\n shouldRedraw = dimensionsChanged || zoomChanged,\n additionalWidth = 0, additionalHeight = 0, shouldResizeCanvas = false;\n if (dimensionsChanged) {\n var canvasWidth = this._cacheCanvas.width,\n canvasHeight = this._cacheCanvas.height,\n sizeGrowing = width > canvasWidth || height > canvasHeight,\n sizeShrinking = (width < canvasWidth * 0.9 || height < canvasHeight * 0.9) &&\n canvasWidth > minCacheSize && canvasHeight > minCacheSize;\n shouldResizeCanvas = sizeGrowing || sizeShrinking;\n if (sizeGrowing && !dims.capped && (width > minCacheSize || height > minCacheSize)) {\n additionalWidth = width * 0.1;\n additionalHeight = height * 0.1;\n }\n }\n if (shouldRedraw) {\n if (shouldResizeCanvas) {\n canvas.width = Math.ceil(width + additionalWidth);\n canvas.height = Math.ceil(height + additionalHeight);\n }\n else {\n this._cacheContext.setTransform(1, 0, 0, 1, 0, 0);\n this._cacheContext.clearRect(0, 0, canvas.width, canvas.height);\n }\n drawingWidth = dims.x / 2;\n drawingHeight = dims.y / 2;\n this.cacheTranslationX = Math.round(canvas.width / 2 - drawingWidth) + drawingWidth;\n this.cacheTranslationY = Math.round(canvas.height / 2 - drawingHeight) + drawingHeight;\n this.cacheWidth = width;\n this.cacheHeight = height;\n this._cacheContext.translate(this.cacheTranslationX, this.cacheTranslationY);\n this._cacheContext.scale(zoomX, zoomY);\n this.zoomX = zoomX;\n this.zoomY = zoomY;\n return true;\n }\n return false;\n },\n\n /**\n * Sets object's properties from options\n * @param {Object} [options] Options object\n */\n setOptions: function(options) {\n this._setOptions(options);\n this._initGradient(options.fill, 'fill');\n this._initGradient(options.stroke, 'stroke');\n this._initPattern(options.fill, 'fill');\n this._initPattern(options.stroke, 'stroke');\n },\n\n /**\n * Transforms context when rendering an object\n * @param {CanvasRenderingContext2D} ctx Context\n */\n transform: function(ctx) {\n var needFullTransform = (this.group && !this.group._transformDone) ||\n (this.group && this.canvas && ctx === this.canvas.contextTop);\n var m = this.calcTransformMatrix(!needFullTransform);\n ctx.transform(m[0], m[1], m[2], m[3], m[4], m[5]);\n },\n\n /**\n * Returns an object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} Object representation of an instance\n */\n toObject: function(propertiesToInclude) {\n var NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS,\n\n object = {\n type: this.type,\n version: fabric.version,\n originX: this.originX,\n originY: this.originY,\n left: toFixed(this.left, NUM_FRACTION_DIGITS),\n top: toFixed(this.top, NUM_FRACTION_DIGITS),\n width: toFixed(this.width, NUM_FRACTION_DIGITS),\n height: toFixed(this.height, NUM_FRACTION_DIGITS),\n fill: (this.fill && this.fill.toObject) ? this.fill.toObject() : this.fill,\n stroke: (this.stroke && this.stroke.toObject) ? this.stroke.toObject() : this.stroke,\n strokeWidth: toFixed(this.strokeWidth, NUM_FRACTION_DIGITS),\n strokeDashArray: this.strokeDashArray ? this.strokeDashArray.concat() : this.strokeDashArray,\n strokeLineCap: this.strokeLineCap,\n strokeDashOffset: this.strokeDashOffset,\n strokeLineJoin: this.strokeLineJoin,\n // strokeUniform: this.strokeUniform,\n strokeMiterLimit: toFixed(this.strokeMiterLimit, NUM_FRACTION_DIGITS),\n scaleX: toFixed(this.scaleX, NUM_FRACTION_DIGITS),\n scaleY: toFixed(this.scaleY, NUM_FRACTION_DIGITS),\n angle: toFixed(this.angle, NUM_FRACTION_DIGITS),\n flipX: this.flipX,\n flipY: this.flipY,\n opacity: toFixed(this.opacity, NUM_FRACTION_DIGITS),\n shadow: (this.shadow && this.shadow.toObject) ? this.shadow.toObject() : this.shadow,\n visible: this.visible,\n backgroundColor: this.backgroundColor,\n fillRule: this.fillRule,\n paintFirst: this.paintFirst,\n globalCompositeOperation: this.globalCompositeOperation,\n skewX: toFixed(this.skewX, NUM_FRACTION_DIGITS),\n skewY: toFixed(this.skewY, NUM_FRACTION_DIGITS),\n };\n\n if (this.clipPath) {\n object.clipPath = this.clipPath.toObject(propertiesToInclude);\n object.clipPath.inverted = this.clipPath.inverted;\n object.clipPath.absolutePositioned = this.clipPath.absolutePositioned;\n }\n\n fabric.util.populateWithProperties(this, object, propertiesToInclude);\n if (!this.includeDefaultValues) {\n object = this._removeDefaultValues(object);\n }\n\n return object;\n },\n\n /**\n * Returns (dataless) object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} Object representation of an instance\n */\n toDatalessObject: function(propertiesToInclude) {\n // will be overwritten by subclasses\n return this.toObject(propertiesToInclude);\n },\n\n /**\n * @private\n * @param {Object} object\n */\n _removeDefaultValues: function(object) {\n var prototype = fabric.util.getKlass(object.type).prototype,\n stateProperties = prototype.stateProperties;\n stateProperties.forEach(function(prop) {\n if (prop === 'left' || prop === 'top') {\n return;\n }\n if (object[prop] === prototype[prop]) {\n delete object[prop];\n }\n var isArray = Object.prototype.toString.call(object[prop]) === '[object Array]' &&\n Object.prototype.toString.call(prototype[prop]) === '[object Array]';\n\n // basically a check for [] === []\n if (isArray && object[prop].length === 0 && prototype[prop].length === 0) {\n delete object[prop];\n }\n });\n\n return object;\n },\n\n /**\n * Returns a string representation of an instance\n * @return {String}\n */\n toString: function() {\n return '#<fabric.' + capitalize(this.type) + '>';\n },\n\n /**\n * Return the object scale factor counting also the group scaling\n * @return {Object} object with scaleX and scaleY properties\n */\n getObjectScaling: function() {\n var options = fabric.util.qrDecompose(this.calcTransformMatrix());\n return { scaleX: Math.abs(options.scaleX), scaleY: Math.abs(options.scaleY) };\n },\n\n /**\n * Return the object scale factor counting also the group scaling, zoom and retina\n * @return {Object} object with scaleX and scaleY properties\n */\n getTotalObjectScaling: function() {\n var scale = this.getObjectScaling(), scaleX = scale.scaleX, scaleY = scale.scaleY;\n if (this.canvas) {\n var zoom = this.canvas.getZoom();\n var retina = this.canvas.getRetinaScaling();\n scaleX *= zoom * retina;\n scaleY *= zoom * retina;\n }\n return { scaleX: scaleX, scaleY: scaleY };\n },\n\n /**\n * Return the object opacity counting also the group property\n * @return {Number}\n */\n getObjectOpacity: function() {\n var opacity = this.opacity;\n if (this.group) {\n opacity *= this.group.getObjectOpacity();\n }\n return opacity;\n },\n\n /**\n * @private\n * @param {String} key\n * @param {*} value\n * @return {fabric.Object} thisArg\n */\n _set: function(key, value) {\n var shouldConstrainValue = (key === 'scaleX' || key === 'scaleY'),\n isChanged = this[key] !== value, groupNeedsUpdate = false;\n\n if (shouldConstrainValue) {\n value = this._constrainScale(value);\n }\n if (key === 'scaleX' && value < 0) {\n this.flipX = !this.flipX;\n value *= -1;\n }\n else if (key === 'scaleY' && value < 0) {\n this.flipY = !this.flipY;\n value *= -1;\n }\n else if (key === 'shadow' && value && !(value instanceof fabric.Shadow)) {\n value = new fabric.Shadow(value);\n }\n else if (key === 'dirty' && this.group) {\n this.group.set('dirty', value);\n }\n\n this[key] = value;\n\n if (isChanged) {\n groupNeedsUpdate = this.group && this.group.isOnACache();\n if (this.cacheProperties.indexOf(key) > -1) {\n this.dirty = true;\n groupNeedsUpdate && this.group.set('dirty', true);\n }\n else if (groupNeedsUpdate && this.stateProperties.indexOf(key) > -1) {\n this.group.set('dirty', true);\n }\n }\n\n return this;\n },\n\n /**\n * This callback function is called by the parent group of an object every\n * time a non-delegated property changes on the group. It is passed the key\n * and value as parameters. Not adding in this function's signature to avoid\n * Travis build error about unused variables.\n */\n setOnGroup: function() {\n // implemented by sub-classes, as needed.\n },\n\n /**\n * Retrieves viewportTransform from Object's canvas if possible\n * @method getViewportTransform\n * @memberOf fabric.Object.prototype\n * @return {Array}\n */\n getViewportTransform: function() {\n if (this.canvas && this.canvas.viewportTransform) {\n return this.canvas.viewportTransform;\n }\n return fabric.iMatrix.concat();\n },\n\n /*\n * @private\n * return if the object would be visible in rendering\n * @memberOf fabric.Object.prototype\n * @return {Boolean}\n */\n isNotVisible: function() {\n return this.opacity === 0 ||\n (!this.width && !this.height && this.strokeWidth === 0) ||\n !this.visible;\n },\n\n /**\n * Renders an object on a specified context\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n render: function(ctx) {\n // do not render if width/height are zeros or object is not visible\n if (this.isNotVisible()) {\n return;\n }\n if (this.canvas && this.canvas.skipOffscreen && !this.group && !this.isOnScreen()) {\n return;\n }\n ctx.save();\n this._setupCompositeOperation(ctx);\n this.drawSelectionBackground(ctx);\n this.transform(ctx);\n this._setOpacity(ctx);\n this._setShadow(ctx, this);\n if (this.shouldCache()) {\n this.renderCache();\n this.drawCacheOnCanvas(ctx);\n }\n else {\n this._removeCacheCanvas();\n this.dirty = false;\n this.drawObject(ctx);\n if (this.objectCaching && this.statefullCache) {\n this.saveState({ propertySet: 'cacheProperties' });\n }\n }\n ctx.restore();\n },\n\n renderCache: function(options) {\n options = options || {};\n if (!this._cacheCanvas) {\n this._createCacheCanvas();\n }\n if (this.isCacheDirty()) {\n this.statefullCache && this.saveState({ propertySet: 'cacheProperties' });\n this.drawObject(this._cacheContext, options.forClipping);\n this.dirty = false;\n }\n },\n\n /**\n * Remove cacheCanvas and its dimensions from the objects\n */\n _removeCacheCanvas: function() {\n this._cacheCanvas = null;\n this.cacheWidth = 0;\n this.cacheHeight = 0;\n },\n\n /**\n * return true if the object will draw a stroke\n * Does not consider text styles. This is just a shortcut used at rendering time\n * We want it to be an aproximation and be fast.\n * wrote to avoid extra caching, it has to return true when stroke happens,\n * can guess when it will not happen at 100% chance, does not matter if it misses\n * some use case where the stroke is invisible.\n * @since 3.0.0\n * @returns Boolean\n */\n hasStroke: function() {\n return this.stroke && this.stroke !== 'transparent' && this.strokeWidth !== 0;\n },\n\n /**\n * return true if the object will draw a fill\n * Does not consider text styles. This is just a shortcut used at rendering time\n * We want it to be an aproximation and be fast.\n * wrote to avoid extra caching, it has to return true when fill happens,\n * can guess when it will not happen at 100% chance, does not matter if it misses\n * some use case where the fill is invisible.\n * @since 3.0.0\n * @returns Boolean\n */\n hasFill: function() {\n return this.fill && this.fill !== 'transparent';\n },\n\n /**\n * When set to `true`, force the object to have its own cache, even if it is inside a group\n * it may be needed when your object behave in a particular way on the cache and always needs\n * its own isolated canvas to render correctly.\n * Created to be overridden\n * since 1.7.12\n * @returns Boolean\n */\n needsItsOwnCache: function() {\n if (this.paintFirst === 'stroke' &&\n this.hasFill() && this.hasStroke() && typeof this.shadow === 'object') {\n return true;\n }\n if (this.clipPath) {\n return true;\n }\n return false;\n },\n\n /**\n * Decide if the object should cache or not. Create its own cache level\n * objectCaching is a global flag, wins over everything\n * needsItsOwnCache should be used when the object drawing method requires\n * a cache step. None of the fabric classes requires it.\n * Generally you do not cache objects in groups because the group outside is cached.\n * Read as: cache if is needed, or if the feature is enabled but we are not already caching.\n * @return {Boolean}\n */\n shouldCache: function() {\n this.ownCaching = this.needsItsOwnCache() || (\n this.objectCaching &&\n (!this.group || !this.group.isOnACache())\n );\n return this.ownCaching;\n },\n\n /**\n * Check if this object or a child object will cast a shadow\n * used by Group.shouldCache to know if child has a shadow recursively\n * @return {Boolean}\n */\n willDrawShadow: function() {\n return !!this.shadow && (this.shadow.offsetX !== 0 || this.shadow.offsetY !== 0);\n },\n\n /**\n * Execute the drawing operation for an object clipPath\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n drawClipPathOnCache: function(ctx) {\n var path = this.clipPath;\n ctx.save();\n // DEBUG: uncomment this line, comment the following\n // ctx.globalAlpha = 0.4\n if (path.inverted) {\n ctx.globalCompositeOperation = 'destination-out';\n }\n else {\n ctx.globalCompositeOperation = 'destination-in';\n }\n //ctx.scale(1 / 2, 1 / 2);\n if (path.absolutePositioned) {\n var m = fabric.util.invertTransform(this.calcTransformMatrix());\n ctx.transform(m[0], m[1], m[2], m[3], m[4], m[5]);\n }\n path.transform(ctx);\n ctx.scale(1 / path.zoomX, 1 / path.zoomY);\n ctx.drawImage(path._cacheCanvas, -path.cacheTranslationX, -path.cacheTranslationY);\n ctx.restore();\n },\n\n /**\n * Execute the drawing operation for an object on a specified context\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n drawObject: function(ctx, forClipping) {\n var originalFill = this.fill, originalStroke = this.stroke;\n if (forClipping) {\n this.fill = 'black';\n this.stroke = '';\n this._setClippingProperties(ctx);\n }\n else {\n this._renderBackground(ctx);\n this._setStrokeStyles(ctx, this);\n this._setFillStyles(ctx, this);\n }\n this._render(ctx);\n this._drawClipPath(ctx);\n this.fill = originalFill;\n this.stroke = originalStroke;\n },\n\n _drawClipPath: function(ctx) {\n var path = this.clipPath;\n if (!path) { return; }\n // needed to setup a couple of variables\n // path canvas gets overridden with this one.\n // TODO find a better solution?\n path.canvas = this.canvas;\n path.shouldCache();\n path._transformDone = true;\n path.renderCache({ forClipping: true });\n this.drawClipPathOnCache(ctx);\n },\n\n /**\n * Paint the cached copy of the object on the target context.\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n drawCacheOnCanvas: function(ctx) {\n ctx.scale(1 / this.zoomX, 1 / this.zoomY);\n ctx.drawImage(this._cacheCanvas, -this.cacheTranslationX, -this.cacheTranslationY);\n },\n\n /**\n * Check if cache is dirty\n * @param {Boolean} skipCanvas skip canvas checks because this object is painted\n * on parent canvas.\n */\n isCacheDirty: function(skipCanvas) {\n if (this.isNotVisible()) {\n return false;\n }\n if (this._cacheCanvas && !skipCanvas && this._updateCacheCanvas()) {\n // in this case the context is already cleared.\n return true;\n }\n else {\n if (this.dirty ||\n (this.clipPath && this.clipPath.absolutePositioned) ||\n (this.statefullCache && this.hasStateChanged('cacheProperties'))\n ) {\n if (this._cacheCanvas && !skipCanvas) {\n var width = this.cacheWidth / this.zoomX;\n var height = this.cacheHeight / this.zoomY;\n this._cacheContext.clearRect(-width / 2, -height / 2, width, height);\n }\n return true;\n }\n }\n return false;\n },\n\n /**\n * Draws a background for the object big as its untransformed dimensions\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderBackground: function(ctx) {\n if (!this.backgroundColor) {\n return;\n }\n var dim = this._getNonTransformedDimensions();\n ctx.fillStyle = this.backgroundColor;\n\n ctx.fillRect(\n -dim.x / 2,\n -dim.y / 2,\n dim.x,\n dim.y\n );\n // if there is background color no other shadows\n // should be casted\n this._removeShadow(ctx);\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _setOpacity: function(ctx) {\n if (this.group && !this.group._transformDone) {\n ctx.globalAlpha = this.getObjectOpacity();\n }\n else {\n ctx.globalAlpha *= this.opacity;\n }\n },\n\n _setStrokeStyles: function(ctx, decl) {\n if (decl.stroke) {\n ctx.lineWidth = decl.strokeWidth;\n ctx.lineCap = decl.strokeLineCap;\n ctx.lineDashOffset = decl.strokeDashOffset;\n ctx.lineJoin = decl.strokeLineJoin;\n ctx.miterLimit = decl.strokeMiterLimit;\n ctx.strokeStyle = decl.stroke.toLive\n ? decl.stroke.toLive(ctx, this)\n : decl.stroke;\n }\n },\n\n _setFillStyles: function(ctx, decl) {\n if (decl.fill) {\n ctx.fillStyle = decl.fill.toLive\n ? decl.fill.toLive(ctx, this)\n : decl.fill;\n }\n },\n\n _setClippingProperties: function(ctx) {\n ctx.globalAlpha = 1;\n ctx.strokeStyle = 'transparent';\n ctx.fillStyle = '#000000';\n },\n\n /**\n * @private\n * Sets line dash\n * @param {CanvasRenderingContext2D} ctx Context to set the dash line on\n * @param {Array} dashArray array representing dashes\n * @param {Function} alternative function to call if browser does not support lineDash\n */\n _setLineDash: function(ctx, dashArray, alternative) {\n if (!dashArray || dashArray.length === 0) {\n return;\n }\n // Spec requires the concatenation of two copies the dash list when the number of elements is odd\n if (1 & dashArray.length) {\n dashArray.push.apply(dashArray, dashArray);\n }\n if (supportsLineDash) {\n ctx.setLineDash(dashArray);\n }\n else {\n alternative && alternative(ctx);\n }\n },\n\n /**\n * Renders controls and borders for the object\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Object} [styleOverride] properties to override the object style\n */\n _renderControls: function(ctx, styleOverride) {\n var vpt = this.getViewportTransform(),\n matrix = this.calcTransformMatrix(),\n options, drawBorders, drawControls;\n styleOverride = styleOverride || { };\n drawBorders = typeof styleOverride.hasBorders !== 'undefined' ? styleOverride.hasBorders : this.hasBorders;\n drawControls = typeof styleOverride.hasControls !== 'undefined' ? styleOverride.hasControls : this.hasControls;\n matrix = fabric.util.multiplyTransformMatrices(vpt, matrix);\n options = fabric.util.qrDecompose(matrix);\n ctx.save();\n ctx.translate(options.translateX, options.translateY);\n ctx.lineWidth = 1 * this.borderScaleFactor;\n if (!this.group) {\n ctx.globalAlpha = this.isMoving ? this.borderOpacityWhenMoving : 1;\n }\n if (styleOverride.forActiveSelection) {\n ctx.rotate(degreesToRadians(options.angle));\n drawBorders && this.drawBordersInGroup(ctx, options, styleOverride);\n }\n else {\n ctx.rotate(degreesToRadians(this.angle));\n drawBorders && this.drawBorders(ctx, styleOverride);\n }\n drawControls && this.drawControls(ctx, styleOverride);\n ctx.restore();\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _setShadow: function(ctx) {\n if (!this.shadow) {\n return;\n }\n\n var shadow = this.shadow, canvas = this.canvas, scaling,\n multX = (canvas && canvas.viewportTransform[0]) || 1,\n multY = (canvas && canvas.viewportTransform[3]) || 1;\n if (shadow.nonScaling) {\n scaling = { scaleX: 1, scaleY: 1 };\n }\n else {\n scaling = this.getObjectScaling();\n }\n if (canvas && canvas._isRetinaScaling()) {\n multX *= fabric.devicePixelRatio;\n multY *= fabric.devicePixelRatio;\n }\n ctx.shadowColor = shadow.color;\n ctx.shadowBlur = shadow.blur * fabric.browserShadowBlurConstant *\n (multX + multY) * (scaling.scaleX + scaling.scaleY) / 4;\n ctx.shadowOffsetX = shadow.offsetX * multX * scaling.scaleX;\n ctx.shadowOffsetY = shadow.offsetY * multY * scaling.scaleY;\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _removeShadow: function(ctx) {\n if (!this.shadow) {\n return;\n }\n\n ctx.shadowColor = '';\n ctx.shadowBlur = ctx.shadowOffsetX = ctx.shadowOffsetY = 0;\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Object} filler fabric.Pattern or fabric.Gradient\n * @return {Object} offset.offsetX offset for text rendering\n * @return {Object} offset.offsetY offset for text rendering\n */\n _applyPatternGradientTransform: function(ctx, filler) {\n if (!filler || !filler.toLive) {\n return { offsetX: 0, offsetY: 0 };\n }\n var t = filler.gradientTransform || filler.patternTransform;\n var offsetX = -this.width / 2 + filler.offsetX || 0,\n offsetY = -this.height / 2 + filler.offsetY || 0;\n\n if (filler.gradientUnits === 'percentage') {\n ctx.transform(this.width, 0, 0, this.height, offsetX, offsetY);\n }\n else {\n ctx.transform(1, 0, 0, 1, offsetX, offsetY);\n }\n if (t) {\n ctx.transform(t[0], t[1], t[2], t[3], t[4], t[5]);\n }\n return { offsetX: offsetX, offsetY: offsetY };\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderPaintInOrder: function(ctx) {\n if (this.paintFirst === 'stroke') {\n this._renderStroke(ctx);\n this._renderFill(ctx);\n }\n else {\n this._renderFill(ctx);\n this._renderStroke(ctx);\n }\n },\n\n /**\n * @private\n * function that actually render something on the context.\n * empty here to allow Obects to work on tests to benchmark fabric functionalites\n * not related to rendering\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _render: function(/* ctx */) {\n\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderFill: function(ctx) {\n if (!this.fill) {\n return;\n }\n\n ctx.save();\n this._applyPatternGradientTransform(ctx, this.fill);\n if (this.fillRule === 'evenodd') {\n ctx.fill('evenodd');\n }\n else {\n ctx.fill();\n }\n ctx.restore();\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderStroke: function(ctx) {\n if (!this.stroke || this.strokeWidth === 0) {\n return;\n }\n\n if (this.shadow && !this.shadow.affectStroke) {\n this._removeShadow(ctx);\n }\n\n ctx.save();\n if (this.strokeUniform && this.group) {\n var scaling = this.getObjectScaling();\n ctx.scale(1 / scaling.scaleX, 1 / scaling.scaleY);\n }\n else if (this.strokeUniform) {\n ctx.scale(1 / this.scaleX, 1 / this.scaleY);\n }\n this._setLineDash(ctx, this.strokeDashArray, this._renderDashedStroke);\n if (this.stroke.toLive && this.stroke.gradientUnits === 'percentage') {\n // need to transform gradient in a pattern.\n // this is a slow process. If you are hitting this codepath, and the object\n // is not using caching, you should consider switching it on.\n // we need a canvas as big as the current object caching canvas.\n this._applyPatternForTransformedGradient(ctx, this.stroke);\n }\n else {\n this._applyPatternGradientTransform(ctx, this.stroke);\n }\n ctx.stroke();\n ctx.restore();\n },\n\n /**\n * This function try to patch the missing gradientTransform on canvas gradients.\n * transforming a context to transform the gradient, is going to transform the stroke too.\n * we want to transform the gradient but not the stroke operation, so we create\n * a transformed gradient on a pattern and then we use the pattern instead of the gradient.\n * this method has drwabacks: is slow, is in low resolution, needs a patch for when the size\n * is limited.\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {fabric.Gradient} filler a fabric gradient instance\n */\n _applyPatternForTransformedGradient: function(ctx, filler) {\n var dims = this._limitCacheSize(this._getCacheCanvasDimensions()),\n pCanvas = fabric.util.createCanvasElement(), pCtx, retinaScaling = this.canvas.getRetinaScaling(),\n width = dims.x / this.scaleX / retinaScaling, height = dims.y / this.scaleY / retinaScaling;\n pCanvas.width = width;\n pCanvas.height = height;\n pCtx = pCanvas.getContext('2d');\n pCtx.beginPath(); pCtx.moveTo(0, 0); pCtx.lineTo(width, 0); pCtx.lineTo(width, height);\n pCtx.lineTo(0, height); pCtx.closePath();\n pCtx.translate(width / 2, height / 2);\n pCtx.scale(\n dims.zoomX / this.scaleX / retinaScaling,\n dims.zoomY / this.scaleY / retinaScaling\n );\n this._applyPatternGradientTransform(pCtx, filler);\n pCtx.fillStyle = filler.toLive(ctx);\n pCtx.fill();\n ctx.translate(-this.width / 2 - this.strokeWidth / 2, -this.height / 2 - this.strokeWidth / 2);\n ctx.scale(\n retinaScaling * this.scaleX / dims.zoomX,\n retinaScaling * this.scaleY / dims.zoomY\n );\n ctx.strokeStyle = pCtx.createPattern(pCanvas, 'no-repeat');\n },\n\n /**\n * This function is an helper for svg import. it returns the center of the object in the svg\n * untransformed coordinates\n * @private\n * @return {Object} center point from element coordinates\n */\n _findCenterFromElement: function() {\n return { x: this.left + this.width / 2, y: this.top + this.height / 2 };\n },\n\n /**\n * This function is an helper for svg import. it decompose the transformMatrix\n * and assign properties to object.\n * untransformed coordinates\n * @private\n * @chainable\n */\n _assignTransformMatrixProps: function() {\n if (this.transformMatrix) {\n var options = fabric.util.qrDecompose(this.transformMatrix);\n this.flipX = false;\n this.flipY = false;\n this.set('scaleX', options.scaleX);\n this.set('scaleY', options.scaleY);\n this.angle = options.angle;\n this.skewX = options.skewX;\n this.skewY = 0;\n }\n },\n\n /**\n * This function is an helper for svg import. it removes the transform matrix\n * and set to object properties that fabricjs can handle\n * @private\n * @param {Object} preserveAspectRatioOptions\n * @return {thisArg}\n */\n _removeTransformMatrix: function(preserveAspectRatioOptions) {\n var center = this._findCenterFromElement();\n if (this.transformMatrix) {\n this._assignTransformMatrixProps();\n center = fabric.util.transformPoint(center, this.transformMatrix);\n }\n this.transformMatrix = null;\n if (preserveAspectRatioOptions) {\n this.scaleX *= preserveAspectRatioOptions.scaleX;\n this.scaleY *= preserveAspectRatioOptions.scaleY;\n this.cropX = preserveAspectRatioOptions.cropX;\n this.cropY = preserveAspectRatioOptions.cropY;\n center.x += preserveAspectRatioOptions.offsetLeft;\n center.y += preserveAspectRatioOptions.offsetTop;\n this.width = preserveAspectRatioOptions.width;\n this.height = preserveAspectRatioOptions.height;\n }\n this.setPositionByOrigin(center, 'center', 'center');\n },\n\n /**\n * Clones an instance, using a callback method will work for every object.\n * @param {Function} callback Callback is invoked with a clone as a first argument\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n */\n clone: function(callback, propertiesToInclude) {\n var objectForm = this.toObject(propertiesToInclude);\n if (this.constructor.fromObject) {\n this.constructor.fromObject(objectForm, callback);\n }\n else {\n fabric.Object._fromObject('Object', objectForm, callback);\n }\n },\n\n /**\n * Creates an instance of fabric.Image out of an object\n * could make use of both toDataUrl or toCanvasElement.\n * @param {Function} callback callback, invoked with an instance as a first argument\n * @param {Object} [options] for clone as image, passed to toDataURL\n * @param {String} [options.format=png] The format of the output image. Either \"jpeg\" or \"png\"\n * @param {Number} [options.quality=1] Quality level (0..1). Only used for jpeg.\n * @param {Number} [options.multiplier=1] Multiplier to scale by\n * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14\n * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14\n * @param {Number} [options.width] Cropping width. Introduced in v1.2.14\n * @param {Number} [options.height] Cropping height. Introduced in v1.2.14\n * @param {Boolean} [options.enableRetinaScaling] Enable retina scaling for clone image. Introduce in 1.6.4\n * @param {Boolean} [options.withoutTransform] Remove current object transform ( no scale , no angle, no flip, no skew ). Introduced in 2.3.4\n * @param {Boolean} [options.withoutShadow] Remove current object shadow. Introduced in 2.4.2\n * @return {fabric.Object} thisArg\n */\n cloneAsImage: function(callback, options) {\n var canvasEl = this.toCanvasElement(options);\n if (callback) {\n callback(new fabric.Image(canvasEl));\n }\n return this;\n },\n\n /**\n * Converts an object into a HTMLCanvas element\n * @param {Object} options Options object\n * @param {Number} [options.multiplier=1] Multiplier to scale by\n * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14\n * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14\n * @param {Number} [options.width] Cropping width. Introduced in v1.2.14\n * @param {Number} [options.height] Cropping height. Introduced in v1.2.14\n * @param {Boolean} [options.enableRetinaScaling] Enable retina scaling for clone image. Introduce in 1.6.4\n * @param {Boolean} [options.withoutTransform] Remove current object transform ( no scale , no angle, no flip, no skew ). Introduced in 2.3.4\n * @param {Boolean} [options.withoutShadow] Remove current object shadow. Introduced in 2.4.2\n * @return {HTMLCanvasElement} Returns DOM element <canvas> with the fabric.Object\n */\n toCanvasElement: function(options) {\n options || (options = { });\n\n var utils = fabric.util, origParams = utils.saveObjectTransform(this),\n originalGroup = this.group,\n originalShadow = this.shadow, abs = Math.abs,\n multiplier = (options.multiplier || 1) * (options.enableRetinaScaling ? fabric.devicePixelRatio : 1);\n delete this.group;\n if (options.withoutTransform) {\n utils.resetObjectTransform(this);\n }\n if (options.withoutShadow) {\n this.shadow = null;\n }\n\n var el = fabric.util.createCanvasElement(),\n // skip canvas zoom and calculate with setCoords now.\n boundingRect = this.getBoundingRect(true, true),\n shadow = this.shadow, scaling,\n shadowOffset = { x: 0, y: 0 }, shadowBlur,\n width, height;\n\n if (shadow) {\n shadowBlur = shadow.blur;\n if (shadow.nonScaling) {\n scaling = { scaleX: 1, scaleY: 1 };\n }\n else {\n scaling = this.getObjectScaling();\n }\n // consider non scaling shadow.\n shadowOffset.x = 2 * Math.round(abs(shadow.offsetX) + shadowBlur) * (abs(scaling.scaleX));\n shadowOffset.y = 2 * Math.round(abs(shadow.offsetY) + shadowBlur) * (abs(scaling.scaleY));\n }\n width = boundingRect.width + shadowOffset.x;\n height = boundingRect.height + shadowOffset.y;\n // if the current width/height is not an integer\n // we need to make it so.\n el.width = Math.ceil(width);\n el.height = Math.ceil(height);\n var canvas = new fabric.StaticCanvas(el, {\n enableRetinaScaling: false,\n renderOnAddRemove: false,\n skipOffscreen: false,\n });\n if (options.format === 'jpeg') {\n canvas.backgroundColor = '#fff';\n }\n this.setPositionByOrigin(new fabric.Point(canvas.width / 2, canvas.height / 2), 'center', 'center');\n\n var originalCanvas = this.canvas;\n canvas.add(this);\n var canvasEl = canvas.toCanvasElement(multiplier || 1, options);\n this.shadow = originalShadow;\n this.set('canvas', originalCanvas);\n if (originalGroup) {\n this.group = originalGroup;\n }\n this.set(origParams).setCoords();\n // canvas.dispose will call image.dispose that will nullify the elements\n // since this canvas is a simple element for the process, we remove references\n // to objects in this way in order to avoid object trashing.\n canvas._objects = [];\n canvas.dispose();\n canvas = null;\n\n return canvasEl;\n },\n\n /**\n * Converts an object into a data-url-like string\n * @param {Object} options Options object\n * @param {String} [options.format=png] The format of the output image. Either \"jpeg\" or \"png\"\n * @param {Number} [options.quality=1] Quality level (0..1). Only used for jpeg.\n * @param {Number} [options.multiplier=1] Multiplier to scale by\n * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14\n * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14\n * @param {Number} [options.width] Cropping width. Introduced in v1.2.14\n * @param {Number} [options.height] Cropping height. Introduced in v1.2.14\n * @param {Boolean} [options.enableRetinaScaling] Enable retina scaling for clone image. Introduce in 1.6.4\n * @param {Boolean} [options.withoutTransform] Remove current object transform ( no scale , no angle, no flip, no skew ). Introduced in 2.3.4\n * @param {Boolean} [options.withoutShadow] Remove current object shadow. Introduced in 2.4.2\n * @return {String} Returns a data: URL containing a representation of the object in the format specified by options.format\n */\n toDataURL: function(options) {\n options || (options = { });\n return fabric.util.toDataURL(this.toCanvasElement(options), options.format || 'png', options.quality || 1);\n },\n\n /**\n * Returns true if specified type is identical to the type of an instance\n * @param {String} type Type to check against\n * @return {Boolean}\n */\n isType: function(type) {\n return this.type === type;\n },\n\n /**\n * Returns complexity of an instance\n * @return {Number} complexity of this instance (is 1 unless subclassed)\n */\n complexity: function() {\n return 1;\n },\n\n /**\n * Returns a JSON representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} JSON\n */\n toJSON: function(propertiesToInclude) {\n // delegate, not alias\n return this.toObject(propertiesToInclude);\n },\n\n /**\n * Sets \"angle\" of an instance with centered rotation\n * @param {Number} angle Angle value (in degrees)\n * @return {fabric.Object} thisArg\n * @chainable\n */\n rotate: function(angle) {\n var shouldCenterOrigin = (this.originX !== 'center' || this.originY !== 'center') && this.centeredRotation;\n\n if (shouldCenterOrigin) {\n this._setOriginToCenter();\n }\n\n this.set('angle', angle);\n\n if (shouldCenterOrigin) {\n this._resetOrigin();\n }\n\n return this;\n },\n\n /**\n * Centers object horizontally on canvas to which it was added last.\n * You might need to call `setCoords` on an object after centering, to update controls area.\n * @return {fabric.Object} thisArg\n * @chainable\n */\n centerH: function () {\n this.canvas && this.canvas.centerObjectH(this);\n return this;\n },\n\n /**\n * Centers object horizontally on current viewport of canvas to which it was added last.\n * You might need to call `setCoords` on an object after centering, to update controls area.\n * @return {fabric.Object} thisArg\n * @chainable\n */\n viewportCenterH: function () {\n this.canvas && this.canvas.viewportCenterObjectH(this);\n return this;\n },\n\n /**\n * Centers object vertically on canvas to which it was added last.\n * You might need to call `setCoords` on an object after centering, to update controls area.\n * @return {fabric.Object} thisArg\n * @chainable\n */\n centerV: function () {\n this.canvas && this.canvas.centerObjectV(this);\n return this;\n },\n\n /**\n * Centers object vertically on current viewport of canvas to which it was added last.\n * You might need to call `setCoords` on an object after centering, to update controls area.\n * @return {fabric.Object} thisArg\n * @chainable\n */\n viewportCenterV: function () {\n this.canvas && this.canvas.viewportCenterObjectV(this);\n return this;\n },\n\n /**\n * Centers object vertically and horizontally on canvas to which is was added last\n * You might need to call `setCoords` on an object after centering, to update controls area.\n * @return {fabric.Object} thisArg\n * @chainable\n */\n center: function () {\n this.canvas && this.canvas.centerObject(this);\n return this;\n },\n\n /**\n * Centers object on current viewport of canvas to which it was added last.\n * You might need to call `setCoords` on an object after centering, to update controls area.\n * @return {fabric.Object} thisArg\n * @chainable\n */\n viewportCenter: function () {\n this.canvas && this.canvas.viewportCenterObject(this);\n return this;\n },\n\n /**\n * Returns coordinates of a pointer relative to an object\n * @param {Event} e Event to operate upon\n * @param {Object} [pointer] Pointer to operate upon (instead of event)\n * @return {Object} Coordinates of a pointer (x, y)\n */\n getLocalPointer: function(e, pointer) {\n pointer = pointer || this.canvas.getPointer(e);\n var pClicked = new fabric.Point(pointer.x, pointer.y),\n objectLeftTop = this._getLeftTopCoords();\n if (this.angle) {\n pClicked = fabric.util.rotatePoint(\n pClicked, objectLeftTop, degreesToRadians(-this.angle));\n }\n return {\n x: pClicked.x - objectLeftTop.x,\n y: pClicked.y - objectLeftTop.y\n };\n },\n\n /**\n * Sets canvas globalCompositeOperation for specific object\n * custom composition operation for the particular object can be specified using globalCompositeOperation property\n * @param {CanvasRenderingContext2D} ctx Rendering canvas context\n */\n _setupCompositeOperation: function (ctx) {\n if (this.globalCompositeOperation) {\n ctx.globalCompositeOperation = this.globalCompositeOperation;\n }\n }\n });\n\n fabric.util.createAccessors && fabric.util.createAccessors(fabric.Object);\n\n extend(fabric.Object.prototype, fabric.Observable);\n\n /**\n * Defines the number of fraction digits to use when serializing object values.\n * You can use it to increase/decrease precision of such values like left, top, scaleX, scaleY, etc.\n * @static\n * @memberOf fabric.Object\n * @constant\n * @type Number\n */\n fabric.Object.NUM_FRACTION_DIGITS = 2;\n\n fabric.Object._fromObject = function(className, object, callback, extraParam) {\n var klass = fabric[className];\n object = clone(object, true);\n fabric.util.enlivenPatterns([object.fill, object.stroke], function(patterns) {\n if (typeof patterns[0] !== 'undefined') {\n object.fill = patterns[0];\n }\n if (typeof patterns[1] !== 'undefined') {\n object.stroke = patterns[1];\n }\n fabric.util.enlivenObjects([object.clipPath], function(enlivedProps) {\n object.clipPath = enlivedProps[0];\n var instance = extraParam ? new klass(object[extraParam], object) : new klass(object);\n callback && callback(instance);\n });\n });\n };\n\n /**\n * Unique id used internally when creating SVG elements\n * @static\n * @memberOf fabric.Object\n * @type Number\n */\n fabric.Object.__uid = 0;\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function() {\n\n var degreesToRadians = fabric.util.degreesToRadians,\n originXOffset = {\n left: -0.5,\n center: 0,\n right: 0.5\n },\n originYOffset = {\n top: -0.5,\n center: 0,\n bottom: 0.5\n };\n\n fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ {\n\n /**\n * Translates the coordinates from a set of origin to another (based on the object's dimensions)\n * @param {fabric.Point} point The point which corresponds to the originX and originY params\n * @param {String} fromOriginX Horizontal origin: 'left', 'center' or 'right'\n * @param {String} fromOriginY Vertical origin: 'top', 'center' or 'bottom'\n * @param {String} toOriginX Horizontal origin: 'left', 'center' or 'right'\n * @param {String} toOriginY Vertical origin: 'top', 'center' or 'bottom'\n * @return {fabric.Point}\n */\n translateToGivenOrigin: function(point, fromOriginX, fromOriginY, toOriginX, toOriginY) {\n var x = point.x,\n y = point.y,\n offsetX, offsetY, dim;\n\n if (typeof fromOriginX === 'string') {\n fromOriginX = originXOffset[fromOriginX];\n }\n else {\n fromOriginX -= 0.5;\n }\n\n if (typeof toOriginX === 'string') {\n toOriginX = originXOffset[toOriginX];\n }\n else {\n toOriginX -= 0.5;\n }\n\n offsetX = toOriginX - fromOriginX;\n\n if (typeof fromOriginY === 'string') {\n fromOriginY = originYOffset[fromOriginY];\n }\n else {\n fromOriginY -= 0.5;\n }\n\n if (typeof toOriginY === 'string') {\n toOriginY = originYOffset[toOriginY];\n }\n else {\n toOriginY -= 0.5;\n }\n\n offsetY = toOriginY - fromOriginY;\n\n if (offsetX || offsetY) {\n dim = this._getTransformedDimensions();\n x = point.x + offsetX * dim.x;\n y = point.y + offsetY * dim.y;\n }\n\n return new fabric.Point(x, y);\n },\n\n /**\n * Translates the coordinates from origin to center coordinates (based on the object's dimensions)\n * @param {fabric.Point} point The point which corresponds to the originX and originY params\n * @param {String} originX Horizontal origin: 'left', 'center' or 'right'\n * @param {String} originY Vertical origin: 'top', 'center' or 'bottom'\n * @return {fabric.Point}\n */\n translateToCenterPoint: function(point, originX, originY) {\n var p = this.translateToGivenOrigin(point, originX, originY, 'center', 'center');\n if (this.angle) {\n return fabric.util.rotatePoint(p, point, degreesToRadians(this.angle));\n }\n return p;\n },\n\n /**\n * Translates the coordinates from center to origin coordinates (based on the object's dimensions)\n * @param {fabric.Point} center The point which corresponds to center of the object\n * @param {String} originX Horizontal origin: 'left', 'center' or 'right'\n * @param {String} originY Vertical origin: 'top', 'center' or 'bottom'\n * @return {fabric.Point}\n */\n translateToOriginPoint: function(center, originX, originY) {\n var p = this.translateToGivenOrigin(center, 'center', 'center', originX, originY);\n if (this.angle) {\n return fabric.util.rotatePoint(p, center, degreesToRadians(this.angle));\n }\n return p;\n },\n\n /**\n * Returns the real center coordinates of the object\n * @return {fabric.Point}\n */\n getCenterPoint: function() {\n var leftTop = new fabric.Point(this.left, this.top);\n return this.translateToCenterPoint(leftTop, this.originX, this.originY);\n },\n\n /**\n * Returns the coordinates of the object based on center coordinates\n * @param {fabric.Point} point The point which corresponds to the originX and originY params\n * @return {fabric.Point}\n */\n // getOriginPoint: function(center) {\n // return this.translateToOriginPoint(center, this.originX, this.originY);\n // },\n\n /**\n * Returns the coordinates of the object as if it has a different origin\n * @param {String} originX Horizontal origin: 'left', 'center' or 'right'\n * @param {String} originY Vertical origin: 'top', 'center' or 'bottom'\n * @return {fabric.Point}\n */\n getPointByOrigin: function(originX, originY) {\n var center = this.getCenterPoint();\n return this.translateToOriginPoint(center, originX, originY);\n },\n\n /**\n * Returns the point in local coordinates\n * @param {fabric.Point} point The point relative to the global coordinate system\n * @param {String} originX Horizontal origin: 'left', 'center' or 'right'\n * @param {String} originY Vertical origin: 'top', 'center' or 'bottom'\n * @return {fabric.Point}\n */\n toLocalPoint: function(point, originX, originY) {\n var center = this.getCenterPoint(),\n p, p2;\n\n if (typeof originX !== 'undefined' && typeof originY !== 'undefined' ) {\n p = this.translateToGivenOrigin(center, 'center', 'center', originX, originY);\n }\n else {\n p = new fabric.Point(this.left, this.top);\n }\n\n p2 = new fabric.Point(point.x, point.y);\n if (this.angle) {\n p2 = fabric.util.rotatePoint(p2, center, -degreesToRadians(this.angle));\n }\n return p2.subtractEquals(p);\n },\n\n /**\n * Returns the point in global coordinates\n * @param {fabric.Point} The point relative to the local coordinate system\n * @return {fabric.Point}\n */\n // toGlobalPoint: function(point) {\n // return fabric.util.rotatePoint(point, this.getCenterPoint(), degreesToRadians(this.angle)).addEquals(new fabric.Point(this.left, this.top));\n // },\n\n /**\n * Sets the position of the object taking into consideration the object's origin\n * @param {fabric.Point} pos The new position of the object\n * @param {String} originX Horizontal origin: 'left', 'center' or 'right'\n * @param {String} originY Vertical origin: 'top', 'center' or 'bottom'\n * @return {void}\n */\n setPositionByOrigin: function(pos, originX, originY) {\n var center = this.translateToCenterPoint(pos, originX, originY),\n position = this.translateToOriginPoint(center, this.originX, this.originY);\n this.set('left', position.x);\n this.set('top', position.y);\n },\n\n /**\n * @param {String} to One of 'left', 'center', 'right'\n */\n adjustPosition: function(to) {\n var angle = degreesToRadians(this.angle),\n hypotFull = this.getScaledWidth(),\n xFull = fabric.util.cos(angle) * hypotFull,\n yFull = fabric.util.sin(angle) * hypotFull,\n offsetFrom, offsetTo;\n\n //TODO: this function does not consider mixed situation like top, center.\n if (typeof this.originX === 'string') {\n offsetFrom = originXOffset[this.originX];\n }\n else {\n offsetFrom = this.originX - 0.5;\n }\n if (typeof to === 'string') {\n offsetTo = originXOffset[to];\n }\n else {\n offsetTo = to - 0.5;\n }\n this.left += xFull * (offsetTo - offsetFrom);\n this.top += yFull * (offsetTo - offsetFrom);\n this.setCoords();\n this.originX = to;\n },\n\n /**\n * Sets the origin/position of the object to it's center point\n * @private\n * @return {void}\n */\n _setOriginToCenter: function() {\n this._originalOriginX = this.originX;\n this._originalOriginY = this.originY;\n\n var center = this.getCenterPoint();\n\n this.originX = 'center';\n this.originY = 'center';\n\n this.left = center.x;\n this.top = center.y;\n },\n\n /**\n * Resets the origin/position of the object to it's original origin\n * @private\n * @return {void}\n */\n _resetOrigin: function() {\n var originPoint = this.translateToOriginPoint(\n this.getCenterPoint(),\n this._originalOriginX,\n this._originalOriginY);\n\n this.originX = this._originalOriginX;\n this.originY = this._originalOriginY;\n\n this.left = originPoint.x;\n this.top = originPoint.y;\n\n this._originalOriginX = null;\n this._originalOriginY = null;\n },\n\n /**\n * @private\n */\n _getLeftTopCoords: function() {\n return this.translateToOriginPoint(this.getCenterPoint(), 'left', 'top');\n },\n });\n\n})();\n\n\n(function() {\n\n function arrayFromCoords(coords) {\n return [\n new fabric.Point(coords.tl.x, coords.tl.y),\n new fabric.Point(coords.tr.x, coords.tr.y),\n new fabric.Point(coords.br.x, coords.br.y),\n new fabric.Point(coords.bl.x, coords.bl.y)\n ];\n }\n\n var util = fabric.util,\n degreesToRadians = util.degreesToRadians,\n multiplyMatrices = util.multiplyTransformMatrices,\n transformPoint = util.transformPoint;\n\n util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ {\n\n /**\n * Describe object's corner position in canvas element coordinates.\n * properties are depending on control keys and padding the main controls.\n * each property is an object with x, y and corner.\n * The `corner` property contains in a similar manner the 4 points of the\n * interactive area of the corner.\n * The coordinates depends from the controls positionHandler and are used\n * to draw and locate controls\n * @memberOf fabric.Object.prototype\n */\n oCoords: null,\n\n /**\n * Describe object's corner position in canvas object absolute coordinates\n * properties are tl,tr,bl,br and describe the four main corner.\n * each property is an object with x, y, instance of Fabric.Point.\n * The coordinates depends from this properties: width, height, scaleX, scaleY\n * skewX, skewY, angle, strokeWidth, top, left.\n * Those coordinates are useful to understand where an object is. They get updated\n * with oCoords but they do not need to be updated when zoom or panning change.\n * The coordinates get updated with @method setCoords.\n * You can calculate them without updating with @method calcACoords();\n * @memberOf fabric.Object.prototype\n */\n aCoords: null,\n\n /**\n * Describe object's corner position in canvas element coordinates.\n * includes padding. Used of object detection.\n * set and refreshed with setCoords and calcCoords.\n * @memberOf fabric.Object.prototype\n */\n lineCoords: null,\n\n /**\n * storage for object transform matrix\n */\n ownMatrixCache: null,\n\n /**\n * storage for object full transform matrix\n */\n matrixCache: null,\n\n /**\n * custom controls interface\n * controls are added by default_controls.js\n */\n controls: { },\n\n /**\n * return correct set of coordinates for intersection\n * this will return either aCoords or lineCoords.\n * @param {Boolean} absolute will return aCoords if true or lineCoords\n * @return {Object} {tl, tr, br, bl} points\n */\n _getCoords: function(absolute, calculate) {\n if (calculate) {\n return (absolute ? this.calcACoords() : this.calcLineCoords());\n }\n if (!this.aCoords || !this.lineCoords) {\n this.setCoords(true);\n }\n return (absolute ? this.aCoords : this.lineCoords);\n },\n\n /**\n * return correct set of coordinates for intersection\n * this will return either aCoords or lineCoords.\n * The coords are returned in an array.\n * @return {Array} [tl, tr, br, bl] of points\n */\n getCoords: function(absolute, calculate) {\n return arrayFromCoords(this._getCoords(absolute, calculate));\n },\n\n /**\n * Checks if object intersects with an area formed by 2 points\n * @param {Object} pointTL top-left point of area\n * @param {Object} pointBR bottom-right point of area\n * @param {Boolean} [absolute] use coordinates without viewportTransform\n * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords\n * @return {Boolean} true if object intersects with an area formed by 2 points\n */\n intersectsWithRect: function(pointTL, pointBR, absolute, calculate) {\n var coords = this.getCoords(absolute, calculate),\n intersection = fabric.Intersection.intersectPolygonRectangle(\n coords,\n pointTL,\n pointBR\n );\n return intersection.status === 'Intersection';\n },\n\n /**\n * Checks if object intersects with another object\n * @param {Object} other Object to test\n * @param {Boolean} [absolute] use coordinates without viewportTransform\n * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords\n * @return {Boolean} true if object intersects with another object\n */\n intersectsWithObject: function(other, absolute, calculate) {\n var intersection = fabric.Intersection.intersectPolygonPolygon(\n this.getCoords(absolute, calculate),\n other.getCoords(absolute, calculate)\n );\n\n return intersection.status === 'Intersection'\n || other.isContainedWithinObject(this, absolute, calculate)\n || this.isContainedWithinObject(other, absolute, calculate);\n },\n\n /**\n * Checks if object is fully contained within area of another object\n * @param {Object} other Object to test\n * @param {Boolean} [absolute] use coordinates without viewportTransform\n * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords\n * @return {Boolean} true if object is fully contained within area of another object\n */\n isContainedWithinObject: function(other, absolute, calculate) {\n var points = this.getCoords(absolute, calculate),\n otherCoords = absolute ? other.aCoords : other.lineCoords,\n i = 0, lines = other._getImageLines(otherCoords);\n for (; i < 4; i++) {\n if (!other.containsPoint(points[i], lines)) {\n return false;\n }\n }\n return true;\n },\n\n /**\n * Checks if object is fully contained within area formed by 2 points\n * @param {Object} pointTL top-left point of area\n * @param {Object} pointBR bottom-right point of area\n * @param {Boolean} [absolute] use coordinates without viewportTransform\n * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords\n * @return {Boolean} true if object is fully contained within area formed by 2 points\n */\n isContainedWithinRect: function(pointTL, pointBR, absolute, calculate) {\n var boundingRect = this.getBoundingRect(absolute, calculate);\n\n return (\n boundingRect.left >= pointTL.x &&\n boundingRect.left + boundingRect.width <= pointBR.x &&\n boundingRect.top >= pointTL.y &&\n boundingRect.top + boundingRect.height <= pointBR.y\n );\n },\n\n /**\n * Checks if point is inside the object\n * @param {fabric.Point} point Point to check against\n * @param {Object} [lines] object returned from @method _getImageLines\n * @param {Boolean} [absolute] use coordinates without viewportTransform\n * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords\n * @return {Boolean} true if point is inside the object\n */\n containsPoint: function(point, lines, absolute, calculate) {\n var coords = this._getCoords(absolute, calculate),\n lines = lines || this._getImageLines(coords),\n xPoints = this._findCrossPoints(point, lines);\n // if xPoints is odd then point is inside the object\n return (xPoints !== 0 && xPoints % 2 === 1);\n },\n\n /**\n * Checks if object is contained within the canvas with current viewportTransform\n * the check is done stopping at first point that appears on screen\n * @param {Boolean} [calculate] use coordinates of current position instead of .aCoords\n * @return {Boolean} true if object is fully or partially contained within canvas\n */\n isOnScreen: function(calculate) {\n if (!this.canvas) {\n return false;\n }\n var pointTL = this.canvas.vptCoords.tl, pointBR = this.canvas.vptCoords.br;\n var points = this.getCoords(true, calculate);\n // if some point is on screen, the object is on screen.\n if (points.some(function(point) {\n return point.x <= pointBR.x && point.x >= pointTL.x &&\n point.y <= pointBR.y && point.y >= pointTL.y;\n })) {\n return true;\n }\n // no points on screen, check intersection with absolute coordinates\n if (this.intersectsWithRect(pointTL, pointBR, true, calculate)) {\n return true;\n }\n return this._containsCenterOfCanvas(pointTL, pointBR, calculate);\n },\n\n /**\n * Checks if the object contains the midpoint between canvas extremities\n * Does not make sense outside the context of isOnScreen and isPartiallyOnScreen\n * @private\n * @param {Fabric.Point} pointTL Top Left point\n * @param {Fabric.Point} pointBR Top Right point\n * @param {Boolean} calculate use coordinates of current position instead of .oCoords\n * @return {Boolean} true if the object contains the point\n */\n _containsCenterOfCanvas: function(pointTL, pointBR, calculate) {\n // worst case scenario the object is so big that contains the screen\n var centerPoint = { x: (pointTL.x + pointBR.x) / 2, y: (pointTL.y + pointBR.y) / 2 };\n if (this.containsPoint(centerPoint, null, true, calculate)) {\n return true;\n }\n return false;\n },\n\n /**\n * Checks if object is partially contained within the canvas with current viewportTransform\n * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords\n * @return {Boolean} true if object is partially contained within canvas\n */\n isPartiallyOnScreen: function(calculate) {\n if (!this.canvas) {\n return false;\n }\n var pointTL = this.canvas.vptCoords.tl, pointBR = this.canvas.vptCoords.br;\n if (this.intersectsWithRect(pointTL, pointBR, true, calculate)) {\n return true;\n }\n var allPointsAreOutside = this.getCoords(true, calculate).every(function(point) {\n return (point.x >= pointBR.x || point.x <= pointTL.x) &&\n (point.y >= pointBR.y || point.y <= pointTL.y);\n });\n return allPointsAreOutside && this._containsCenterOfCanvas(pointTL, pointBR, calculate);\n },\n\n /**\n * Method that returns an object with the object edges in it, given the coordinates of the corners\n * @private\n * @param {Object} oCoords Coordinates of the object corners\n */\n _getImageLines: function(oCoords) {\n\n var lines = {\n topline: {\n o: oCoords.tl,\n d: oCoords.tr\n },\n rightline: {\n o: oCoords.tr,\n d: oCoords.br\n },\n bottomline: {\n o: oCoords.br,\n d: oCoords.bl\n },\n leftline: {\n o: oCoords.bl,\n d: oCoords.tl\n }\n };\n\n // // debugging\n // if (this.canvas.contextTop) {\n // this.canvas.contextTop.fillRect(lines.bottomline.d.x, lines.bottomline.d.y, 2, 2);\n // this.canvas.contextTop.fillRect(lines.bottomline.o.x, lines.bottomline.o.y, 2, 2);\n //\n // this.canvas.contextTop.fillRect(lines.leftline.d.x, lines.leftline.d.y, 2, 2);\n // this.canvas.contextTop.fillRect(lines.leftline.o.x, lines.leftline.o.y, 2, 2);\n //\n // this.canvas.contextTop.fillRect(lines.topline.d.x, lines.topline.d.y, 2, 2);\n // this.canvas.contextTop.fillRect(lines.topline.o.x, lines.topline.o.y, 2, 2);\n //\n // this.canvas.contextTop.fillRect(lines.rightline.d.x, lines.rightline.d.y, 2, 2);\n // this.canvas.contextTop.fillRect(lines.rightline.o.x, lines.rightline.o.y, 2, 2);\n // }\n\n return lines;\n },\n\n /**\n * Helper method to determine how many cross points are between the 4 object edges\n * and the horizontal line determined by a point on canvas\n * @private\n * @param {fabric.Point} point Point to check\n * @param {Object} lines Coordinates of the object being evaluated\n */\n // remove yi, not used but left code here just in case.\n _findCrossPoints: function(point, lines) {\n var b1, b2, a1, a2, xi, // yi,\n xcount = 0,\n iLine;\n\n for (var lineKey in lines) {\n iLine = lines[lineKey];\n // optimisation 1: line below point. no cross\n if ((iLine.o.y < point.y) && (iLine.d.y < point.y)) {\n continue;\n }\n // optimisation 2: line above point. no cross\n if ((iLine.o.y >= point.y) && (iLine.d.y >= point.y)) {\n continue;\n }\n // optimisation 3: vertical line case\n if ((iLine.o.x === iLine.d.x) && (iLine.o.x >= point.x)) {\n xi = iLine.o.x;\n // yi = point.y;\n }\n // calculate the intersection point\n else {\n b1 = 0;\n b2 = (iLine.d.y - iLine.o.y) / (iLine.d.x - iLine.o.x);\n a1 = point.y - b1 * point.x;\n a2 = iLine.o.y - b2 * iLine.o.x;\n\n xi = -(a1 - a2) / (b1 - b2);\n // yi = a1 + b1 * xi;\n }\n // dont count xi < point.x cases\n if (xi >= point.x) {\n xcount += 1;\n }\n // optimisation 4: specific for square images\n if (xcount === 2) {\n break;\n }\n }\n return xcount;\n },\n\n /**\n * Returns coordinates of object's bounding rectangle (left, top, width, height)\n * the box is intended as aligned to axis of canvas.\n * @param {Boolean} [absolute] use coordinates without viewportTransform\n * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords / .aCoords\n * @return {Object} Object with left, top, width, height properties\n */\n getBoundingRect: function(absolute, calculate) {\n var coords = this.getCoords(absolute, calculate);\n return util.makeBoundingBoxFromPoints(coords);\n },\n\n /**\n * Returns width of an object's bounding box counting transformations\n * before 2.0 it was named getWidth();\n * @return {Number} width value\n */\n getScaledWidth: function() {\n return this._getTransformedDimensions().x;\n },\n\n /**\n * Returns height of an object bounding box counting transformations\n * before 2.0 it was named getHeight();\n * @return {Number} height value\n */\n getScaledHeight: function() {\n return this._getTransformedDimensions().y;\n },\n\n /**\n * Makes sure the scale is valid and modifies it if necessary\n * @private\n * @param {Number} value\n * @return {Number}\n */\n _constrainScale: function(value) {\n if (Math.abs(value) < this.minScaleLimit) {\n if (value < 0) {\n return -this.minScaleLimit;\n }\n else {\n return this.minScaleLimit;\n }\n }\n else if (value === 0) {\n return 0.0001;\n }\n return value;\n },\n\n /**\n * Scales an object (equally by x and y)\n * @param {Number} value Scale factor\n * @return {fabric.Object} thisArg\n * @chainable\n */\n scale: function(value) {\n this._set('scaleX', value);\n this._set('scaleY', value);\n return this.setCoords();\n },\n\n /**\n * Scales an object to a given width, with respect to bounding box (scaling by x/y equally)\n * @param {Number} value New width value\n * @param {Boolean} absolute ignore viewport\n * @return {fabric.Object} thisArg\n * @chainable\n */\n scaleToWidth: function(value, absolute) {\n // adjust to bounding rect factor so that rotated shapes would fit as well\n var boundingRectFactor = this.getBoundingRect(absolute).width / this.getScaledWidth();\n return this.scale(value / this.width / boundingRectFactor);\n },\n\n /**\n * Scales an object to a given height, with respect to bounding box (scaling by x/y equally)\n * @param {Number} value New height value\n * @param {Boolean} absolute ignore viewport\n * @return {fabric.Object} thisArg\n * @chainable\n */\n scaleToHeight: function(value, absolute) {\n // adjust to bounding rect factor so that rotated shapes would fit as well\n var boundingRectFactor = this.getBoundingRect(absolute).height / this.getScaledHeight();\n return this.scale(value / this.height / boundingRectFactor);\n },\n\n /**\n * Calculates and returns the .coords of an object.\n * unused by the library, only for the end dev.\n * @return {Object} Object with tl, tr, br, bl ....\n * @chainable\n * @deprecated\n */\n calcCoords: function(absolute) {\n // this is a compatibility function to avoid removing calcCoords now.\n if (absolute) {\n return this.calcACoords();\n }\n return this.calcOCoords();\n },\n\n calcLineCoords: function() {\n var vpt = this.getViewportTransform(),\n padding = this.padding, angle = degreesToRadians(this.angle),\n cos = util.cos(angle), sin = util.sin(angle),\n cosP = cos * padding, sinP = sin * padding, cosPSinP = cosP + sinP,\n cosPMinusSinP = cosP - sinP, aCoords = this.calcACoords();\n\n var lineCoords = {\n tl: transformPoint(aCoords.tl, vpt),\n tr: transformPoint(aCoords.tr, vpt),\n bl: transformPoint(aCoords.bl, vpt),\n br: transformPoint(aCoords.br, vpt),\n };\n\n if (padding) {\n lineCoords.tl.x -= cosPMinusSinP;\n lineCoords.tl.y -= cosPSinP;\n lineCoords.tr.x += cosPSinP;\n lineCoords.tr.y -= cosPMinusSinP;\n lineCoords.bl.x -= cosPSinP;\n lineCoords.bl.y += cosPMinusSinP;\n lineCoords.br.x += cosPMinusSinP;\n lineCoords.br.y += cosPSinP;\n }\n\n return lineCoords;\n },\n\n calcOCoords: function() {\n var rotateMatrix = this._calcRotateMatrix(),\n translateMatrix = this._calcTranslateMatrix(),\n vpt = this.getViewportTransform(),\n startMatrix = multiplyMatrices(vpt, translateMatrix),\n finalMatrix = multiplyMatrices(startMatrix, rotateMatrix),\n finalMatrix = multiplyMatrices(finalMatrix, [1 / vpt[0], 0, 0, 1 / vpt[3], 0, 0]),\n dim = this._calculateCurrentDimensions(),\n coords = {};\n this.forEachControl(function(control, key, fabricObject) {\n coords[key] = control.positionHandler(dim, finalMatrix, fabricObject);\n });\n\n // debug code\n // var canvas = this.canvas;\n // setTimeout(function() {\n // canvas.contextTop.clearRect(0, 0, 700, 700);\n // canvas.contextTop.fillStyle = 'green';\n // Object.keys(coords).forEach(function(key) {\n // var control = coords[key];\n // canvas.contextTop.fillRect(control.x, control.y, 3, 3);\n // });\n // }, 50);\n return coords;\n },\n\n calcACoords: function() {\n var rotateMatrix = this._calcRotateMatrix(),\n translateMatrix = this._calcTranslateMatrix(),\n finalMatrix = multiplyMatrices(translateMatrix, rotateMatrix),\n dim = this._getTransformedDimensions(),\n w = dim.x / 2, h = dim.y / 2;\n return {\n // corners\n tl: transformPoint({ x: -w, y: -h }, finalMatrix),\n tr: transformPoint({ x: w, y: -h }, finalMatrix),\n bl: transformPoint({ x: -w, y: h }, finalMatrix),\n br: transformPoint({ x: w, y: h }, finalMatrix)\n };\n },\n\n /**\n * Sets corner position coordinates based on current angle, width and height.\n * oCoords are used to find the corners\n * aCoords are used to quickly find an object on the canvas\n * lineCoords are used to quickly find object during pointer events.\n * See {@link https://github.com/kangax/fabric.js/wiki/When-to-call-setCoords|When-to-call-setCoords}\n * @param {Boolean} [skipCorners] skip calculation of oCoords.\n * @return {fabric.Object} thisArg\n * @chainable\n */\n setCoords: function(skipCorners) {\n this.aCoords = this.calcACoords();\n // in case we are in a group, for how the inner group target check works,\n // lineCoords are exactly aCoords. Since the vpt gets absorbed by the normalized pointer.\n this.lineCoords = this.group ? this.aCoords : this.calcLineCoords();\n if (skipCorners) {\n return this;\n }\n // set coordinates of the draggable boxes in the corners used to scale/rotate the image\n this.oCoords = this.calcOCoords();\n this._setCornerCoords && this._setCornerCoords();\n return this;\n },\n\n /**\n * calculate rotation matrix of an object\n * @return {Array} rotation matrix for the object\n */\n _calcRotateMatrix: function() {\n return util.calcRotateMatrix(this);\n },\n\n /**\n * calculate the translation matrix for an object transform\n * @return {Array} rotation matrix for the object\n */\n _calcTranslateMatrix: function() {\n var center = this.getCenterPoint();\n return [1, 0, 0, 1, center.x, center.y];\n },\n\n transformMatrixKey: function(skipGroup) {\n var sep = '_', prefix = '';\n if (!skipGroup && this.group) {\n prefix = this.group.transformMatrixKey(skipGroup) + sep;\n };\n return prefix + this.top + sep + this.left + sep + this.scaleX + sep + this.scaleY +\n sep + this.skewX + sep + this.skewY + sep + this.angle + sep + this.originX + sep + this.originY +\n sep + this.width + sep + this.height + sep + this.strokeWidth + this.flipX + this.flipY;\n },\n\n /**\n * calculate transform matrix that represents the current transformations from the\n * object's properties.\n * @param {Boolean} [skipGroup] return transform matrix for object not counting parent transformations\n * There are some situation in which this is useful to avoid the fake rotation.\n * @return {Array} transform matrix for the object\n */\n calcTransformMatrix: function(skipGroup) {\n var matrix = this.calcOwnMatrix();\n if (skipGroup || !this.group) {\n return matrix;\n }\n var key = this.transformMatrixKey(skipGroup), cache = this.matrixCache || (this.matrixCache = {});\n if (cache.key === key) {\n return cache.value;\n }\n if (this.group) {\n matrix = multiplyMatrices(this.group.calcTransformMatrix(false), matrix);\n }\n cache.key = key;\n cache.value = matrix;\n return matrix;\n },\n\n /**\n * calculate transform matrix that represents the current transformations from the\n * object's properties, this matrix does not include the group transformation\n * @return {Array} transform matrix for the object\n */\n calcOwnMatrix: function() {\n var key = this.transformMatrixKey(true), cache = this.ownMatrixCache || (this.ownMatrixCache = {});\n if (cache.key === key) {\n return cache.value;\n }\n var tMatrix = this._calcTranslateMatrix(),\n options = {\n angle: this.angle,\n translateX: tMatrix[4],\n translateY: tMatrix[5],\n scaleX: this.scaleX,\n scaleY: this.scaleY,\n skewX: this.skewX,\n skewY: this.skewY,\n flipX: this.flipX,\n flipY: this.flipY,\n };\n cache.key = key;\n cache.value = util.composeMatrix(options);\n return cache.value;\n },\n\n /*\n * Calculate object dimensions from its properties\n * @private\n * @deprecated since 3.4.0, please use fabric.util._calcDimensionsTransformMatrix\n * not including or including flipX, flipY to emulate the flipping boolean\n * @return {Object} .x width dimension\n * @return {Object} .y height dimension\n */\n _calcDimensionsTransformMatrix: function(skewX, skewY, flipping) {\n return util.calcDimensionsMatrix({\n skewX: skewX,\n skewY: skewY,\n scaleX: this.scaleX * (flipping && this.flipX ? -1 : 1),\n scaleY: this.scaleY * (flipping && this.flipY ? -1 : 1)\n });\n },\n\n /*\n * Calculate object dimensions from its properties\n * @private\n * @return {Object} .x width dimension\n * @return {Object} .y height dimension\n */\n _getNonTransformedDimensions: function() {\n var strokeWidth = this.strokeWidth,\n w = this.width + strokeWidth,\n h = this.height + strokeWidth;\n return { x: w, y: h };\n },\n\n /*\n * Calculate object bounding box dimensions from its properties scale, skew.\n * @param {Number} skewX, a value to override current skewX\n * @param {Number} skewY, a value to override current skewY\n * @private\n * @return {Object} .x width dimension\n * @return {Object} .y height dimension\n */\n _getTransformedDimensions: function(skewX, skewY) {\n if (typeof skewX === 'undefined') {\n skewX = this.skewX;\n }\n if (typeof skewY === 'undefined') {\n skewY = this.skewY;\n }\n var dimensions = this._getNonTransformedDimensions(), dimX, dimY,\n noSkew = skewX === 0 && skewY === 0;\n\n if (this.strokeUniform) {\n dimX = this.width;\n dimY = this.height;\n }\n else {\n dimX = dimensions.x;\n dimY = dimensions.y;\n }\n if (noSkew) {\n return this._finalizeDimensions(dimX * this.scaleX, dimY * this.scaleY);\n }\n var bbox = util.sizeAfterTransform(dimX, dimY, {\n scaleX: this.scaleX,\n scaleY: this.scaleY,\n skewX: skewX,\n skewY: skewY,\n });\n return this._finalizeDimensions(bbox.x, bbox.y);\n },\n\n /*\n * Calculate object bounding box dimensions from its properties scale, skew.\n * @param Number width width of the bbox\n * @param Number height height of the bbox\n * @private\n * @return {Object} .x finalized width dimension\n * @return {Object} .y finalized height dimension\n */\n _finalizeDimensions: function(width, height) {\n return this.strokeUniform ?\n { x: width + this.strokeWidth, y: height + this.strokeWidth }\n :\n { x: width, y: height };\n },\n\n /*\n * Calculate object dimensions for controls box, including padding and canvas zoom.\n * and active selection\n * private\n */\n _calculateCurrentDimensions: function() {\n var vpt = this.getViewportTransform(),\n dim = this._getTransformedDimensions(),\n p = transformPoint(dim, vpt, true);\n return p.scalarAdd(2 * this.padding);\n },\n });\n})();\n\n\nfabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ {\n\n /**\n * Moves an object to the bottom of the stack of drawn objects\n * @return {fabric.Object} thisArg\n * @chainable\n */\n sendToBack: function() {\n if (this.group) {\n fabric.StaticCanvas.prototype.sendToBack.call(this.group, this);\n }\n else if (this.canvas) {\n this.canvas.sendToBack(this);\n }\n return this;\n },\n\n /**\n * Moves an object to the top of the stack of drawn objects\n * @return {fabric.Object} thisArg\n * @chainable\n */\n bringToFront: function() {\n if (this.group) {\n fabric.StaticCanvas.prototype.bringToFront.call(this.group, this);\n }\n else if (this.canvas) {\n this.canvas.bringToFront(this);\n }\n return this;\n },\n\n /**\n * Moves an object down in stack of drawn objects\n * @param {Boolean} [intersecting] If `true`, send object behind next lower intersecting object\n * @return {fabric.Object} thisArg\n * @chainable\n */\n sendBackwards: function(intersecting) {\n if (this.group) {\n fabric.StaticCanvas.prototype.sendBackwards.call(this.group, this, intersecting);\n }\n else if (this.canvas) {\n this.canvas.sendBackwards(this, intersecting);\n }\n return this;\n },\n\n /**\n * Moves an object up in stack of drawn objects\n * @param {Boolean} [intersecting] If `true`, send object in front of next upper intersecting object\n * @return {fabric.Object} thisArg\n * @chainable\n */\n bringForward: function(intersecting) {\n if (this.group) {\n fabric.StaticCanvas.prototype.bringForward.call(this.group, this, intersecting);\n }\n else if (this.canvas) {\n this.canvas.bringForward(this, intersecting);\n }\n return this;\n },\n\n /**\n * Moves an object to specified level in stack of drawn objects\n * @param {Number} index New position of object\n * @return {fabric.Object} thisArg\n * @chainable\n */\n moveTo: function(index) {\n if (this.group && this.group.type !== 'activeSelection') {\n fabric.StaticCanvas.prototype.moveTo.call(this.group, this, index);\n }\n else if (this.canvas) {\n this.canvas.moveTo(this, index);\n }\n return this;\n }\n});\n\n\n/* _TO_SVG_START_ */\n(function() {\n function getSvgColorString(prop, value) {\n if (!value) {\n return prop + ': none; ';\n }\n else if (value.toLive) {\n return prop + ': url(#SVGID_' + value.id + '); ';\n }\n else {\n var color = new fabric.Color(value),\n str = prop + ': ' + color.toRgb() + '; ',\n opacity = color.getAlpha();\n if (opacity !== 1) {\n //change the color in rgb + opacity\n str += prop + '-opacity: ' + opacity.toString() + '; ';\n }\n return str;\n }\n }\n\n var toFixed = fabric.util.toFixed;\n\n fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ {\n /**\n * Returns styles-string for svg-export\n * @param {Boolean} skipShadow a boolean to skip shadow filter output\n * @return {String}\n */\n getSvgStyles: function(skipShadow) {\n\n var fillRule = this.fillRule ? this.fillRule : 'nonzero',\n strokeWidth = this.strokeWidth ? this.strokeWidth : '0',\n strokeDashArray = this.strokeDashArray ? this.strokeDashArray.join(' ') : 'none',\n strokeDashOffset = this.strokeDashOffset ? this.strokeDashOffset : '0',\n strokeLineCap = this.strokeLineCap ? this.strokeLineCap : 'butt',\n strokeLineJoin = this.strokeLineJoin ? this.strokeLineJoin : 'miter',\n strokeMiterLimit = this.strokeMiterLimit ? this.strokeMiterLimit : '4',\n opacity = typeof this.opacity !== 'undefined' ? this.opacity : '1',\n visibility = this.visible ? '' : ' visibility: hidden;',\n filter = skipShadow ? '' : this.getSvgFilter(),\n fill = getSvgColorString('fill', this.fill),\n stroke = getSvgColorString('stroke', this.stroke);\n\n return [\n stroke,\n 'stroke-width: ', strokeWidth, '; ',\n 'stroke-dasharray: ', strokeDashArray, '; ',\n 'stroke-linecap: ', strokeLineCap, '; ',\n 'stroke-dashoffset: ', strokeDashOffset, '; ',\n 'stroke-linejoin: ', strokeLineJoin, '; ',\n 'stroke-miterlimit: ', strokeMiterLimit, '; ',\n fill,\n 'fill-rule: ', fillRule, '; ',\n 'opacity: ', opacity, ';',\n filter,\n visibility\n ].join('');\n },\n\n /**\n * Returns styles-string for svg-export\n * @param {Object} style the object from which to retrieve style properties\n * @param {Boolean} useWhiteSpace a boolean to include an additional attribute in the style.\n * @return {String}\n */\n getSvgSpanStyles: function(style, useWhiteSpace) {\n var term = '; ';\n var fontFamily = style.fontFamily ?\n 'font-family: ' + (((style.fontFamily.indexOf('\\'') === -1 && style.fontFamily.indexOf('\"') === -1) ?\n '\\'' + style.fontFamily + '\\'' : style.fontFamily)) + term : '';\n var strokeWidth = style.strokeWidth ? 'stroke-width: ' + style.strokeWidth + term : '',\n fontFamily = fontFamily,\n fontSize = style.fontSize ? 'font-size: ' + style.fontSize + 'px' + term : '',\n fontStyle = style.fontStyle ? 'font-style: ' + style.fontStyle + term : '',\n fontWeight = style.fontWeight ? 'font-weight: ' + style.fontWeight + term : '',\n fill = style.fill ? getSvgColorString('fill', style.fill) : '',\n stroke = style.stroke ? getSvgColorString('stroke', style.stroke) : '',\n textDecoration = this.getSvgTextDecoration(style),\n deltaY = style.deltaY ? 'baseline-shift: ' + (-style.deltaY) + '; ' : '';\n if (textDecoration) {\n textDecoration = 'text-decoration: ' + textDecoration + term;\n }\n\n return [\n stroke,\n strokeWidth,\n fontFamily,\n fontSize,\n fontStyle,\n fontWeight,\n textDecoration,\n fill,\n deltaY,\n useWhiteSpace ? 'white-space: pre; ' : ''\n ].join('');\n },\n\n /**\n * Returns text-decoration property for svg-export\n * @param {Object} style the object from which to retrieve style properties\n * @return {String}\n */\n getSvgTextDecoration: function(style) {\n return ['overline', 'underline', 'line-through'].filter(function(decoration) {\n return style[decoration.replace('-', '')];\n }).join(' ');\n },\n\n /**\n * Returns filter for svg shadow\n * @return {String}\n */\n getSvgFilter: function() {\n return this.shadow ? 'filter: url(#SVGID_' + this.shadow.id + ');' : '';\n },\n\n /**\n * Returns id attribute for svg output\n * @return {String}\n */\n getSvgCommons: function() {\n return [\n this.id ? 'id=\"' + this.id + '\" ' : '',\n this.clipPath ? 'clip-path=\"url(#' + this.clipPath.clipPathId + ')\" ' : '',\n ].join('');\n },\n\n /**\n * Returns transform-string for svg-export\n * @param {Boolean} use the full transform or the single object one.\n * @return {String}\n */\n getSvgTransform: function(full, additionalTransform) {\n var transform = full ? this.calcTransformMatrix() : this.calcOwnMatrix(),\n svgTransform = 'transform=\"' + fabric.util.matrixToSVG(transform);\n return svgTransform +\n (additionalTransform || '') + '\" ';\n },\n\n _setSVGBg: function(textBgRects) {\n if (this.backgroundColor) {\n var NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS;\n textBgRects.push(\n '\\t\\t<rect ',\n this._getFillAttributes(this.backgroundColor),\n ' x=\"',\n toFixed(-this.width / 2, NUM_FRACTION_DIGITS),\n '\" y=\"',\n toFixed(-this.height / 2, NUM_FRACTION_DIGITS),\n '\" width=\"',\n toFixed(this.width, NUM_FRACTION_DIGITS),\n '\" height=\"',\n toFixed(this.height, NUM_FRACTION_DIGITS),\n '\"></rect>\\n');\n }\n },\n\n /**\n * Returns svg representation of an instance\n * @param {Function} [reviver] Method for further parsing of svg representation.\n * @return {String} svg representation of an instance\n */\n toSVG: function(reviver) {\n return this._createBaseSVGMarkup(this._toSVG(reviver), { reviver: reviver });\n },\n\n /**\n * Returns svg clipPath representation of an instance\n * @param {Function} [reviver] Method for further parsing of svg representation.\n * @return {String} svg representation of an instance\n */\n toClipPathSVG: function(reviver) {\n return '\\t' + this._createBaseClipPathSVGMarkup(this._toSVG(reviver), { reviver: reviver });\n },\n\n /**\n * @private\n */\n _createBaseClipPathSVGMarkup: function(objectMarkup, options) {\n options = options || {};\n var reviver = options.reviver,\n additionalTransform = options.additionalTransform || '',\n commonPieces = [\n this.getSvgTransform(true, additionalTransform),\n this.getSvgCommons(),\n ].join(''),\n // insert commons in the markup, style and svgCommons\n index = objectMarkup.indexOf('COMMON_PARTS');\n objectMarkup[index] = commonPieces;\n return reviver ? reviver(objectMarkup.join('')) : objectMarkup.join('');\n },\n\n /**\n * @private\n */\n _createBaseSVGMarkup: function(objectMarkup, options) {\n options = options || {};\n var noStyle = options.noStyle,\n reviver = options.reviver,\n styleInfo = noStyle ? '' : 'style=\"' + this.getSvgStyles() + '\" ',\n shadowInfo = options.withShadow ? 'style=\"' + this.getSvgFilter() + '\" ' : '',\n clipPath = this.clipPath,\n vectorEffect = this.strokeUniform ? 'vector-effect=\"non-scaling-stroke\" ' : '',\n absoluteClipPath = clipPath && clipPath.absolutePositioned,\n stroke = this.stroke, fill = this.fill, shadow = this.shadow,\n commonPieces, markup = [], clipPathMarkup,\n // insert commons in the markup, style and svgCommons\n index = objectMarkup.indexOf('COMMON_PARTS'),\n additionalTransform = options.additionalTransform;\n if (clipPath) {\n clipPath.clipPathId = 'CLIPPATH_' + fabric.Object.__uid++;\n clipPathMarkup = '<clipPath id=\"' + clipPath.clipPathId + '\" >\\n' +\n clipPath.toClipPathSVG(reviver) +\n '</clipPath>\\n';\n }\n if (absoluteClipPath) {\n markup.push(\n '<g ', shadowInfo, this.getSvgCommons(), ' >\\n'\n );\n }\n markup.push(\n '<g ',\n this.getSvgTransform(false),\n !absoluteClipPath ? shadowInfo + this.getSvgCommons() : '',\n ' >\\n'\n );\n commonPieces = [\n styleInfo,\n vectorEffect,\n noStyle ? '' : this.addPaintOrder(), ' ',\n additionalTransform ? 'transform=\"' + additionalTransform + '\" ' : '',\n ].join('');\n objectMarkup[index] = commonPieces;\n if (fill && fill.toLive) {\n markup.push(fill.toSVG(this));\n }\n if (stroke && stroke.toLive) {\n markup.push(stroke.toSVG(this));\n }\n if (shadow) {\n markup.push(shadow.toSVG(this));\n }\n if (clipPath) {\n markup.push(clipPathMarkup);\n }\n markup.push(objectMarkup.join(''));\n markup.push('</g>\\n');\n absoluteClipPath && markup.push('</g>\\n');\n return reviver ? reviver(markup.join('')) : markup.join('');\n },\n\n addPaintOrder: function() {\n return this.paintFirst !== 'fill' ? ' paint-order=\"' + this.paintFirst + '\" ' : '';\n }\n });\n})();\n/* _TO_SVG_END_ */\n\n\n(function() {\n\n var extend = fabric.util.object.extend,\n originalSet = 'stateProperties';\n\n /*\n Depends on `stateProperties`\n */\n function saveProps(origin, destination, props) {\n var tmpObj = { }, deep = true;\n props.forEach(function(prop) {\n tmpObj[prop] = origin[prop];\n });\n\n extend(origin[destination], tmpObj, deep);\n }\n\n function _isEqual(origValue, currentValue, firstPass) {\n if (origValue === currentValue) {\n // if the objects are identical, return\n return true;\n }\n else if (Array.isArray(origValue)) {\n if (!Array.isArray(currentValue) || origValue.length !== currentValue.length) {\n return false;\n }\n for (var i = 0, len = origValue.length; i < len; i++) {\n if (!_isEqual(origValue[i], currentValue[i])) {\n return false;\n }\n }\n return true;\n }\n else if (origValue && typeof origValue === 'object') {\n var keys = Object.keys(origValue), key;\n if (!currentValue ||\n typeof currentValue !== 'object' ||\n (!firstPass && keys.length !== Object.keys(currentValue).length)\n ) {\n return false;\n }\n for (var i = 0, len = keys.length; i < len; i++) {\n key = keys[i];\n // since clipPath is in the statefull cache list and the clipPath objects\n // would be iterated as an object, this would lead to possible infinite recursion\n // we do not want to compare those.\n if (key === 'canvas' || key === 'group') {\n continue;\n }\n if (!_isEqual(origValue[key], currentValue[key])) {\n return false;\n }\n }\n return true;\n }\n }\n\n\n fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ {\n\n /**\n * Returns true if object state (one of its state properties) was changed\n * @param {String} [propertySet] optional name for the set of property we want to save\n * @return {Boolean} true if instance' state has changed since `{@link fabric.Object#saveState}` was called\n */\n hasStateChanged: function(propertySet) {\n propertySet = propertySet || originalSet;\n var dashedPropertySet = '_' + propertySet;\n if (Object.keys(this[dashedPropertySet]).length < this[propertySet].length) {\n return true;\n }\n return !_isEqual(this[dashedPropertySet], this, true);\n },\n\n /**\n * Saves state of an object\n * @param {Object} [options] Object with additional `stateProperties` array to include when saving state\n * @return {fabric.Object} thisArg\n */\n saveState: function(options) {\n var propertySet = options && options.propertySet || originalSet,\n destination = '_' + propertySet;\n if (!this[destination]) {\n return this.setupState(options);\n }\n saveProps(this, destination, this[propertySet]);\n if (options && options.stateProperties) {\n saveProps(this, destination, options.stateProperties);\n }\n return this;\n },\n\n /**\n * Setups state of an object\n * @param {Object} [options] Object with additional `stateProperties` array to include when saving state\n * @return {fabric.Object} thisArg\n */\n setupState: function(options) {\n options = options || { };\n var propertySet = options.propertySet || originalSet;\n options.propertySet = propertySet;\n this['_' + propertySet] = { };\n this.saveState(options);\n return this;\n }\n });\n})();\n\n\n(function() {\n\n var degreesToRadians = fabric.util.degreesToRadians;\n\n fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ {\n /**\n * Determines which corner has been clicked\n * @private\n * @param {Object} pointer The pointer indicating the mouse position\n * @return {String|Boolean} corner code (tl, tr, bl, br, etc.), or false if nothing is found\n */\n _findTargetCorner: function(pointer, forTouch) {\n // objects in group, anykind, are not self modificable,\n // must not return an hovered corner.\n if (!this.hasControls || this.group || (!this.canvas || this.canvas._activeObject !== this)) {\n return false;\n }\n\n var ex = pointer.x,\n ey = pointer.y,\n xPoints,\n lines, keys = Object.keys(this.oCoords),\n j = keys.length - 1, i;\n this.__corner = 0;\n\n // cycle in reverse order so we pick first the one on top\n for (; j >= 0; j--) {\n i = keys[j];\n if (!this.isControlVisible(i)) {\n continue;\n }\n\n lines = this._getImageLines(forTouch ? this.oCoords[i].touchCorner : this.oCoords[i].corner);\n // debugging\n\n // this.canvas.contextTop.fillRect(lines.bottomline.d.x, lines.bottomline.d.y, 2, 2);\n // this.canvas.contextTop.fillRect(lines.bottomline.o.x, lines.bottomline.o.y, 2, 2);\n //\n // this.canvas.contextTop.fillRect(lines.leftline.d.x, lines.leftline.d.y, 2, 2);\n // this.canvas.contextTop.fillRect(lines.leftline.o.x, lines.leftline.o.y, 2, 2);\n //\n // this.canvas.contextTop.fillRect(lines.topline.d.x, lines.topline.d.y, 2, 2);\n // this.canvas.contextTop.fillRect(lines.topline.o.x, lines.topline.o.y, 2, 2);\n //\n // this.canvas.contextTop.fillRect(lines.rightline.d.x, lines.rightline.d.y, 2, 2);\n // this.canvas.contextTop.fillRect(lines.rightline.o.x, lines.rightline.o.y, 2, 2);\n\n xPoints = this._findCrossPoints({ x: ex, y: ey }, lines);\n if (xPoints !== 0 && xPoints % 2 === 1) {\n this.__corner = i;\n return i;\n }\n }\n return false;\n },\n\n /**\n * Calls a function for each control. The function gets called,\n * with the control, the object that is calling the iterator and the control's key\n * @param {Function} fn function to iterate over the controls over\n */\n forEachControl: function(fn) {\n for (var i in this.controls) {\n fn(this.controls[i], i, this);\n };\n },\n\n /**\n * Sets the coordinates of the draggable boxes in the corners of\n * the image used to scale/rotate it.\n * note: if we would switch to ROUND corner area, all of this would disappear.\n * everything would resolve to a single point and a pythagorean theorem for the distance\n * @private\n */\n _setCornerCoords: function() {\n var coords = this.oCoords,\n newTheta = degreesToRadians(45 - this.angle),\n cosTheta = fabric.util.cos(newTheta),\n sinTheta = fabric.util.sin(newTheta),\n /* Math.sqrt(2 * Math.pow(this.cornerSize, 2)) / 2, */\n /* 0.707106 stands for sqrt(2)/2 */\n cornerHypotenuse = this.cornerSize * 0.707106,\n touchHypotenuse = this.touchCornerSize * 0.707106,\n cosHalfOffset = cornerHypotenuse * cosTheta,\n sinHalfOffset = cornerHypotenuse * sinTheta,\n touchCosHalfOffset = touchHypotenuse * cosTheta,\n touchSinHalfOffset = touchHypotenuse * sinTheta,\n x, y;\n\n for (var control in coords) {\n x = coords[control].x;\n y = coords[control].y;\n coords[control].corner = {\n tl: {\n x: x - sinHalfOffset,\n y: y - cosHalfOffset\n },\n tr: {\n x: x + cosHalfOffset,\n y: y - sinHalfOffset\n },\n bl: {\n x: x - cosHalfOffset,\n y: y + sinHalfOffset\n },\n br: {\n x: x + sinHalfOffset,\n y: y + cosHalfOffset\n }\n };\n coords[control].touchCorner = {\n tl: {\n x: x - touchSinHalfOffset,\n y: y - touchCosHalfOffset\n },\n tr: {\n x: x + touchCosHalfOffset,\n y: y - touchSinHalfOffset\n },\n bl: {\n x: x - touchCosHalfOffset,\n y: y + touchSinHalfOffset\n },\n br: {\n x: x + touchSinHalfOffset,\n y: y + touchCosHalfOffset\n }\n };\n }\n },\n\n /**\n * Draws a colored layer behind the object, inside its selection borders.\n * Requires public options: padding, selectionBackgroundColor\n * this function is called when the context is transformed\n * has checks to be skipped when the object is on a staticCanvas\n * @param {CanvasRenderingContext2D} ctx Context to draw on\n * @return {fabric.Object} thisArg\n * @chainable\n */\n drawSelectionBackground: function(ctx) {\n if (!this.selectionBackgroundColor ||\n (this.canvas && !this.canvas.interactive) ||\n (this.canvas && this.canvas._activeObject !== this)\n ) {\n return this;\n }\n ctx.save();\n var center = this.getCenterPoint(), wh = this._calculateCurrentDimensions(),\n vpt = this.canvas.viewportTransform;\n ctx.translate(center.x, center.y);\n ctx.scale(1 / vpt[0], 1 / vpt[3]);\n ctx.rotate(degreesToRadians(this.angle));\n ctx.fillStyle = this.selectionBackgroundColor;\n ctx.fillRect(-wh.x / 2, -wh.y / 2, wh.x, wh.y);\n ctx.restore();\n return this;\n },\n\n /**\n * Draws borders of an object's bounding box.\n * Requires public properties: width, height\n * Requires public options: padding, borderColor\n * @param {CanvasRenderingContext2D} ctx Context to draw on\n * @param {Object} styleOverride object to override the object style\n * @return {fabric.Object} thisArg\n * @chainable\n */\n drawBorders: function(ctx, styleOverride) {\n styleOverride = styleOverride || {};\n var wh = this._calculateCurrentDimensions(),\n strokeWidth = this.borderScaleFactor,\n width = wh.x + strokeWidth,\n height = wh.y + strokeWidth,\n hasControls = typeof styleOverride.hasControls !== 'undefined' ?\n styleOverride.hasControls : this.hasControls,\n shouldStroke = false;\n\n ctx.save();\n ctx.strokeStyle = styleOverride.borderColor || this.borderColor;\n this._setLineDash(ctx, styleOverride.borderDashArray || this.borderDashArray, null);\n\n ctx.strokeRect(\n -width / 2,\n -height / 2,\n width,\n height\n );\n\n if (hasControls) {\n ctx.beginPath();\n this.forEachControl(function(control, key, fabricObject) {\n // in this moment, the ctx is centered on the object.\n // width and height of the above function are the size of the bbox.\n if (control.withConnection && control.getVisibility(fabricObject, key)) {\n // reset movement for each control\n shouldStroke = true;\n ctx.moveTo(control.x * width, control.y * height);\n ctx.lineTo(\n control.x * width + control.offsetX,\n control.y * height + control.offsetY\n );\n }\n });\n if (shouldStroke) {\n ctx.stroke();\n }\n }\n ctx.restore();\n return this;\n },\n\n /**\n * Draws borders of an object's bounding box when it is inside a group.\n * Requires public properties: width, height\n * Requires public options: padding, borderColor\n * @param {CanvasRenderingContext2D} ctx Context to draw on\n * @param {object} options object representing current object parameters\n * @param {Object} styleOverride object to override the object style\n * @return {fabric.Object} thisArg\n * @chainable\n */\n drawBordersInGroup: function(ctx, options, styleOverride) {\n styleOverride = styleOverride || {};\n var bbox = fabric.util.sizeAfterTransform(this.width, this.height, options),\n strokeWidth = this.strokeWidth,\n strokeUniform = this.strokeUniform,\n borderScaleFactor = this.borderScaleFactor,\n width =\n bbox.x + strokeWidth * (strokeUniform ? this.canvas.getZoom() : options.scaleX) + borderScaleFactor,\n height =\n bbox.y + strokeWidth * (strokeUniform ? this.canvas.getZoom() : options.scaleY) + borderScaleFactor;\n ctx.save();\n this._setLineDash(ctx, styleOverride.borderDashArray || this.borderDashArray, null);\n ctx.strokeStyle = styleOverride.borderColor || this.borderColor;\n ctx.strokeRect(\n -width / 2,\n -height / 2,\n width,\n height\n );\n\n ctx.restore();\n return this;\n },\n\n /**\n * Draws corners of an object's bounding box.\n * Requires public properties: width, height\n * Requires public options: cornerSize, padding\n * @param {CanvasRenderingContext2D} ctx Context to draw on\n * @param {Object} styleOverride object to override the object style\n * @return {fabric.Object} thisArg\n * @chainable\n */\n drawControls: function(ctx, styleOverride) {\n styleOverride = styleOverride || {};\n ctx.save();\n ctx.setTransform(this.canvas.getRetinaScaling(), 0, 0, this.canvas.getRetinaScaling(), 0, 0);\n ctx.strokeStyle = ctx.fillStyle = styleOverride.cornerColor || this.cornerColor;\n if (!this.transparentCorners) {\n ctx.strokeStyle = styleOverride.cornerStrokeColor || this.cornerStrokeColor;\n }\n this._setLineDash(ctx, styleOverride.cornerDashArray || this.cornerDashArray, null);\n this.setCoords();\n this.forEachControl(function(control, key, fabricObject) {\n if (control.getVisibility(fabricObject, key)) {\n control.render(ctx,\n fabricObject.oCoords[key].x,\n fabricObject.oCoords[key].y, styleOverride, fabricObject);\n }\n });\n ctx.restore();\n\n return this;\n },\n\n /**\n * Returns true if the specified control is visible, false otherwise.\n * @param {String} controlKey The key of the control. Possible values are 'tl', 'tr', 'br', 'bl', 'ml', 'mt', 'mr', 'mb', 'mtr'.\n * @returns {Boolean} true if the specified control is visible, false otherwise\n */\n isControlVisible: function(controlKey) {\n return this.controls[controlKey] && this.controls[controlKey].getVisibility(this, controlKey);\n },\n\n /**\n * Sets the visibility of the specified control.\n * @param {String} controlKey The key of the control. Possible values are 'tl', 'tr', 'br', 'bl', 'ml', 'mt', 'mr', 'mb', 'mtr'.\n * @param {Boolean} visible true to set the specified control visible, false otherwise\n * @return {fabric.Object} thisArg\n * @chainable\n */\n setControlVisible: function(controlKey, visible) {\n if (!this._controlsVisibility) {\n this._controlsVisibility = {};\n }\n this._controlsVisibility[controlKey] = visible;\n return this;\n },\n\n /**\n * Sets the visibility state of object controls.\n * @param {Object} [options] Options object\n * @param {Boolean} [options.bl] true to enable the bottom-left control, false to disable it\n * @param {Boolean} [options.br] true to enable the bottom-right control, false to disable it\n * @param {Boolean} [options.mb] true to enable the middle-bottom control, false to disable it\n * @param {Boolean} [options.ml] true to enable the middle-left control, false to disable it\n * @param {Boolean} [options.mr] true to enable the middle-right control, false to disable it\n * @param {Boolean} [options.mt] true to enable the middle-top control, false to disable it\n * @param {Boolean} [options.tl] true to enable the top-left control, false to disable it\n * @param {Boolean} [options.tr] true to enable the top-right control, false to disable it\n * @param {Boolean} [options.mtr] true to enable the middle-top-rotate control, false to disable it\n * @return {fabric.Object} thisArg\n * @chainable\n */\n setControlsVisibility: function(options) {\n options || (options = { });\n\n for (var p in options) {\n this.setControlVisible(p, options[p]);\n }\n return this;\n },\n\n\n /**\n * This callback function is called every time _discardActiveObject or _setActiveObject\n * try to to deselect this object. If the function returns true, the process is cancelled\n * @param {Object} [options] options sent from the upper functions\n * @param {Event} [options.e] event if the process is generated by an event\n */\n onDeselect: function() {\n // implemented by sub-classes, as needed.\n },\n\n\n /**\n * This callback function is called every time _discardActiveObject or _setActiveObject\n * try to to select this object. If the function returns true, the process is cancelled\n * @param {Object} [options] options sent from the upper functions\n * @param {Event} [options.e] event if the process is generated by an event\n */\n onSelect: function() {\n // implemented by sub-classes, as needed.\n }\n });\n})();\n\n\nfabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.StaticCanvas.prototype */ {\n\n /**\n * Animation duration (in ms) for fx* methods\n * @type Number\n * @default\n */\n FX_DURATION: 500,\n\n /**\n * Centers object horizontally with animation.\n * @param {fabric.Object} object Object to center\n * @param {Object} [callbacks] Callbacks object with optional \"onComplete\" and/or \"onChange\" properties\n * @param {Function} [callbacks.onComplete] Invoked on completion\n * @param {Function} [callbacks.onChange] Invoked on every step of animation\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n fxCenterObjectH: function (object, callbacks) {\n callbacks = callbacks || { };\n\n var empty = function() { },\n onComplete = callbacks.onComplete || empty,\n onChange = callbacks.onChange || empty,\n _this = this;\n\n fabric.util.animate({\n startValue: object.left,\n endValue: this.getCenter().left,\n duration: this.FX_DURATION,\n onChange: function(value) {\n object.set('left', value);\n _this.requestRenderAll();\n onChange();\n },\n onComplete: function() {\n object.setCoords();\n onComplete();\n }\n });\n\n return this;\n },\n\n /**\n * Centers object vertically with animation.\n * @param {fabric.Object} object Object to center\n * @param {Object} [callbacks] Callbacks object with optional \"onComplete\" and/or \"onChange\" properties\n * @param {Function} [callbacks.onComplete] Invoked on completion\n * @param {Function} [callbacks.onChange] Invoked on every step of animation\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n fxCenterObjectV: function (object, callbacks) {\n callbacks = callbacks || { };\n\n var empty = function() { },\n onComplete = callbacks.onComplete || empty,\n onChange = callbacks.onChange || empty,\n _this = this;\n\n fabric.util.animate({\n startValue: object.top,\n endValue: this.getCenter().top,\n duration: this.FX_DURATION,\n onChange: function(value) {\n object.set('top', value);\n _this.requestRenderAll();\n onChange();\n },\n onComplete: function() {\n object.setCoords();\n onComplete();\n }\n });\n\n return this;\n },\n\n /**\n * Same as `fabric.Canvas#remove` but animated\n * @param {fabric.Object} object Object to remove\n * @param {Object} [callbacks] Callbacks object with optional \"onComplete\" and/or \"onChange\" properties\n * @param {Function} [callbacks.onComplete] Invoked on completion\n * @param {Function} [callbacks.onChange] Invoked on every step of animation\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n fxRemove: function (object, callbacks) {\n callbacks = callbacks || { };\n\n var empty = function() { },\n onComplete = callbacks.onComplete || empty,\n onChange = callbacks.onChange || empty,\n _this = this;\n\n fabric.util.animate({\n startValue: object.opacity,\n endValue: 0,\n duration: this.FX_DURATION,\n onChange: function(value) {\n object.set('opacity', value);\n _this.requestRenderAll();\n onChange();\n },\n onComplete: function () {\n _this.remove(object);\n onComplete();\n }\n });\n\n return this;\n }\n});\n\nfabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ {\n /**\n * Animates object's properties\n * @param {String|Object} property Property to animate (if string) or properties to animate (if object)\n * @param {Number|Object} value Value to animate property to (if string was given first) or options object\n * @return {fabric.Object} thisArg\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#animation}\n * @chainable\n *\n * As object — multiple properties\n *\n * object.animate({ left: ..., top: ... });\n * object.animate({ left: ..., top: ... }, { duration: ... });\n *\n * As string — one property\n *\n * object.animate('left', ...);\n * object.animate('left', { duration: ... });\n *\n */\n animate: function() {\n if (arguments[0] && typeof arguments[0] === 'object') {\n var propsToAnimate = [], prop, skipCallbacks;\n for (prop in arguments[0]) {\n propsToAnimate.push(prop);\n }\n for (var i = 0, len = propsToAnimate.length; i < len; i++) {\n prop = propsToAnimate[i];\n skipCallbacks = i !== len - 1;\n this._animate(prop, arguments[0][prop], arguments[1], skipCallbacks);\n }\n }\n else {\n this._animate.apply(this, arguments);\n }\n return this;\n },\n\n /**\n * @private\n * @param {String} property Property to animate\n * @param {String} to Value to animate to\n * @param {Object} [options] Options object\n * @param {Boolean} [skipCallbacks] When true, callbacks like onchange and oncomplete are not invoked\n */\n _animate: function(property, to, options, skipCallbacks) {\n var _this = this, propPair;\n\n to = to.toString();\n\n if (!options) {\n options = { };\n }\n else {\n options = fabric.util.object.clone(options);\n }\n\n if (~property.indexOf('.')) {\n propPair = property.split('.');\n }\n\n var propIsColor =\n _this.colorProperties.indexOf(property) > -1 ||\n (propPair && _this.colorProperties.indexOf(propPair[1]) > -1);\n\n var currentValue = propPair\n ? this.get(propPair[0])[propPair[1]]\n : this.get(property);\n\n if (!('from' in options)) {\n options.from = currentValue;\n }\n\n if (!propIsColor) {\n if (~to.indexOf('=')) {\n to = currentValue + parseFloat(to.replace('=', ''));\n }\n else {\n to = parseFloat(to);\n }\n }\n\n var _options = {\n startValue: options.from,\n endValue: to,\n byValue: options.by,\n easing: options.easing,\n duration: options.duration,\n abort: options.abort && function () {\n return options.abort.call(_this);\n },\n onChange: function (value, valueProgress, timeProgress) {\n if (propPair) {\n _this[propPair[0]][propPair[1]] = value;\n }\n else {\n _this.set(property, value);\n }\n if (skipCallbacks) {\n return;\n }\n options.onChange && options.onChange(value, valueProgress, timeProgress);\n },\n onComplete: function (value, valueProgress, timeProgress) {\n if (skipCallbacks) {\n return;\n }\n\n _this.setCoords();\n options.onComplete && options.onComplete(value, valueProgress, timeProgress);\n }\n };\n\n if (propIsColor) {\n fabric.util.animateColor(_options.startValue, _options.endValue, _options.duration, _options);\n }\n else {\n fabric.util.animate(_options);\n }\n }\n});\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n extend = fabric.util.object.extend,\n clone = fabric.util.object.clone,\n coordProps = { x1: 1, x2: 1, y1: 1, y2: 1 },\n supportsLineDash = fabric.StaticCanvas.supports('setLineDash');\n\n if (fabric.Line) {\n fabric.warn('fabric.Line is already defined');\n return;\n }\n\n /**\n * Line class\n * @class fabric.Line\n * @extends fabric.Object\n * @see {@link fabric.Line#initialize} for constructor definition\n */\n fabric.Line = fabric.util.createClass(fabric.Object, /** @lends fabric.Line.prototype */ {\n\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'line',\n\n /**\n * x value or first line edge\n * @type Number\n * @default\n */\n x1: 0,\n\n /**\n * y value or first line edge\n * @type Number\n * @default\n */\n y1: 0,\n\n /**\n * x value or second line edge\n * @type Number\n * @default\n */\n x2: 0,\n\n /**\n * y value or second line edge\n * @type Number\n * @default\n */\n y2: 0,\n\n cacheProperties: fabric.Object.prototype.cacheProperties.concat('x1', 'x2', 'y1', 'y2'),\n\n /**\n * Constructor\n * @param {Array} [points] Array of points\n * @param {Object} [options] Options object\n * @return {fabric.Line} thisArg\n */\n initialize: function(points, options) {\n if (!points) {\n points = [0, 0, 0, 0];\n }\n\n this.callSuper('initialize', options);\n\n this.set('x1', points[0]);\n this.set('y1', points[1]);\n this.set('x2', points[2]);\n this.set('y2', points[3]);\n\n this._setWidthHeight(options);\n },\n\n /**\n * @private\n * @param {Object} [options] Options\n */\n _setWidthHeight: function(options) {\n options || (options = { });\n\n this.width = Math.abs(this.x2 - this.x1);\n this.height = Math.abs(this.y2 - this.y1);\n\n this.left = 'left' in options\n ? options.left\n : this._getLeftToOriginX();\n\n this.top = 'top' in options\n ? options.top\n : this._getTopToOriginY();\n },\n\n /**\n * @private\n * @param {String} key\n * @param {*} value\n */\n _set: function(key, value) {\n this.callSuper('_set', key, value);\n if (typeof coordProps[key] !== 'undefined') {\n this._setWidthHeight();\n }\n return this;\n },\n\n /**\n * @private\n * @return {Number} leftToOriginX Distance from left edge of canvas to originX of Line.\n */\n _getLeftToOriginX: makeEdgeToOriginGetter(\n { // property names\n origin: 'originX',\n axis1: 'x1',\n axis2: 'x2',\n dimension: 'width'\n },\n { // possible values of origin\n nearest: 'left',\n center: 'center',\n farthest: 'right'\n }\n ),\n\n /**\n * @private\n * @return {Number} topToOriginY Distance from top edge of canvas to originY of Line.\n */\n _getTopToOriginY: makeEdgeToOriginGetter(\n { // property names\n origin: 'originY',\n axis1: 'y1',\n axis2: 'y2',\n dimension: 'height'\n },\n { // possible values of origin\n nearest: 'top',\n center: 'center',\n farthest: 'bottom'\n }\n ),\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _render: function(ctx) {\n ctx.beginPath();\n\n if (!this.strokeDashArray || this.strokeDashArray && supportsLineDash) {\n // move from center (of virtual box) to its left/top corner\n // we can't assume x1, y1 is top left and x2, y2 is bottom right\n var p = this.calcLinePoints();\n ctx.moveTo(p.x1, p.y1);\n ctx.lineTo(p.x2, p.y2);\n }\n\n ctx.lineWidth = this.strokeWidth;\n\n // TODO: test this\n // make sure setting \"fill\" changes color of a line\n // (by copying fillStyle to strokeStyle, since line is stroked, not filled)\n var origStrokeStyle = ctx.strokeStyle;\n ctx.strokeStyle = this.stroke || ctx.fillStyle;\n this.stroke && this._renderStroke(ctx);\n ctx.strokeStyle = origStrokeStyle;\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderDashedStroke: function(ctx) {\n var p = this.calcLinePoints();\n\n ctx.beginPath();\n fabric.util.drawDashedLine(ctx, p.x1, p.y1, p.x2, p.y2, this.strokeDashArray);\n ctx.closePath();\n },\n\n /**\n * This function is an helper for svg import. it returns the center of the object in the svg\n * untransformed coordinates\n * @private\n * @return {Object} center point from element coordinates\n */\n _findCenterFromElement: function() {\n return {\n x: (this.x1 + this.x2) / 2,\n y: (this.y1 + this.y2) / 2,\n };\n },\n\n /**\n * Returns object representation of an instance\n * @methd toObject\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject: function(propertiesToInclude) {\n return extend(this.callSuper('toObject', propertiesToInclude), this.calcLinePoints());\n },\n\n /*\n * Calculate object dimensions from its properties\n * @private\n */\n _getNonTransformedDimensions: function() {\n var dim = this.callSuper('_getNonTransformedDimensions');\n if (this.strokeLineCap === 'butt') {\n if (this.width === 0) {\n dim.y -= this.strokeWidth;\n }\n if (this.height === 0) {\n dim.x -= this.strokeWidth;\n }\n }\n return dim;\n },\n\n /**\n * Recalculates line points given width and height\n * @private\n */\n calcLinePoints: function() {\n var xMult = this.x1 <= this.x2 ? -1 : 1,\n yMult = this.y1 <= this.y2 ? -1 : 1,\n x1 = (xMult * this.width * 0.5),\n y1 = (yMult * this.height * 0.5),\n x2 = (xMult * this.width * -0.5),\n y2 = (yMult * this.height * -0.5);\n\n return {\n x1: x1,\n x2: x2,\n y1: y1,\n y2: y2\n };\n },\n\n /* _TO_SVG_START_ */\n /**\n * Returns svg representation of an instance\n * @return {Array} an array of strings with the specific svg representation\n * of the instance\n */\n _toSVG: function() {\n var p = this.calcLinePoints();\n return [\n '<line ', 'COMMON_PARTS',\n 'x1=\"', p.x1,\n '\" y1=\"', p.y1,\n '\" x2=\"', p.x2,\n '\" y2=\"', p.y2,\n '\" />\\n'\n ];\n },\n /* _TO_SVG_END_ */\n });\n\n /* _FROM_SVG_START_ */\n /**\n * List of attribute names to account for when parsing SVG element (used by {@link fabric.Line.fromElement})\n * @static\n * @memberOf fabric.Line\n * @see http://www.w3.org/TR/SVG/shapes.html#LineElement\n */\n fabric.Line.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat('x1 y1 x2 y2'.split(' '));\n\n /**\n * Returns fabric.Line instance from an SVG element\n * @static\n * @memberOf fabric.Line\n * @param {SVGElement} element Element to parse\n * @param {Object} [options] Options object\n * @param {Function} [callback] callback function invoked after parsing\n */\n fabric.Line.fromElement = function(element, callback, options) {\n options = options || { };\n var parsedAttributes = fabric.parseAttributes(element, fabric.Line.ATTRIBUTE_NAMES),\n points = [\n parsedAttributes.x1 || 0,\n parsedAttributes.y1 || 0,\n parsedAttributes.x2 || 0,\n parsedAttributes.y2 || 0\n ];\n callback(new fabric.Line(points, extend(parsedAttributes, options)));\n };\n /* _FROM_SVG_END_ */\n\n /**\n * Returns fabric.Line instance from an object representation\n * @static\n * @memberOf fabric.Line\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] invoked with new instance as first argument\n */\n fabric.Line.fromObject = function(object, callback) {\n function _callback(instance) {\n delete instance.points;\n callback && callback(instance);\n };\n var options = clone(object, true);\n options.points = [object.x1, object.y1, object.x2, object.y2];\n fabric.Object._fromObject('Line', options, _callback, 'points');\n };\n\n /**\n * Produces a function that calculates distance from canvas edge to Line origin.\n */\n function makeEdgeToOriginGetter(propertyNames, originValues) {\n var origin = propertyNames.origin,\n axis1 = propertyNames.axis1,\n axis2 = propertyNames.axis2,\n dimension = propertyNames.dimension,\n nearest = originValues.nearest,\n center = originValues.center,\n farthest = originValues.farthest;\n\n return function() {\n switch (this.get(origin)) {\n case nearest:\n return Math.min(this.get(axis1), this.get(axis2));\n case center:\n return Math.min(this.get(axis1), this.get(axis2)) + (0.5 * this.get(dimension));\n case farthest:\n return Math.max(this.get(axis1), this.get(axis2));\n }\n };\n\n }\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n pi = Math.PI;\n\n if (fabric.Circle) {\n fabric.warn('fabric.Circle is already defined.');\n return;\n }\n\n /**\n * Circle class\n * @class fabric.Circle\n * @extends fabric.Object\n * @see {@link fabric.Circle#initialize} for constructor definition\n */\n fabric.Circle = fabric.util.createClass(fabric.Object, /** @lends fabric.Circle.prototype */ {\n\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'circle',\n\n /**\n * Radius of this circle\n * @type Number\n * @default\n */\n radius: 0,\n\n /**\n * Start angle of the circle, moving clockwise\n * deprectated type, this should be in degree, this was an oversight.\n * probably will change to degrees in next major version\n * @type Number\n * @default 0\n */\n startAngle: 0,\n\n /**\n * End angle of the circle\n * deprectated type, this should be in degree, this was an oversight.\n * probably will change to degrees in next major version\n * @type Number\n * @default 2Pi\n */\n endAngle: pi * 2,\n\n cacheProperties: fabric.Object.prototype.cacheProperties.concat('radius', 'startAngle', 'endAngle'),\n\n /**\n * @private\n * @param {String} key\n * @param {*} value\n * @return {fabric.Circle} thisArg\n */\n _set: function(key, value) {\n this.callSuper('_set', key, value);\n\n if (key === 'radius') {\n this.setRadius(value);\n }\n\n return this;\n },\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject: function(propertiesToInclude) {\n return this.callSuper('toObject', ['radius', 'startAngle', 'endAngle'].concat(propertiesToInclude));\n },\n\n /* _TO_SVG_START_ */\n\n /**\n * Returns svg representation of an instance\n * @return {Array} an array of strings with the specific svg representation\n * of the instance\n */\n _toSVG: function() {\n var svgString, x = 0, y = 0,\n angle = (this.endAngle - this.startAngle) % ( 2 * pi);\n\n if (angle === 0) {\n svgString = [\n '<circle ', 'COMMON_PARTS',\n 'cx=\"' + x + '\" cy=\"' + y + '\" ',\n 'r=\"', this.radius,\n '\" />\\n'\n ];\n }\n else {\n var startX = fabric.util.cos(this.startAngle) * this.radius,\n startY = fabric.util.sin(this.startAngle) * this.radius,\n endX = fabric.util.cos(this.endAngle) * this.radius,\n endY = fabric.util.sin(this.endAngle) * this.radius,\n largeFlag = angle > pi ? '1' : '0';\n svgString = [\n '<path d=\"M ' + startX + ' ' + startY,\n ' A ' + this.radius + ' ' + this.radius,\n ' 0 ', +largeFlag + ' 1', ' ' + endX + ' ' + endY,\n '\" ', 'COMMON_PARTS', ' />\\n'\n ];\n }\n return svgString;\n },\n /* _TO_SVG_END_ */\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx context to render on\n */\n _render: function(ctx) {\n ctx.beginPath();\n ctx.arc(\n 0,\n 0,\n this.radius,\n this.startAngle,\n this.endAngle, false);\n this._renderPaintInOrder(ctx);\n },\n\n /**\n * Returns horizontal radius of an object (according to how an object is scaled)\n * @return {Number}\n */\n getRadiusX: function() {\n return this.get('radius') * this.get('scaleX');\n },\n\n /**\n * Returns vertical radius of an object (according to how an object is scaled)\n * @return {Number}\n */\n getRadiusY: function() {\n return this.get('radius') * this.get('scaleY');\n },\n\n /**\n * Sets radius of an object (and updates width accordingly)\n * @return {fabric.Circle} thisArg\n */\n setRadius: function(value) {\n this.radius = value;\n return this.set('width', value * 2).set('height', value * 2);\n },\n });\n\n /* _FROM_SVG_START_ */\n /**\n * List of attribute names to account for when parsing SVG element (used by {@link fabric.Circle.fromElement})\n * @static\n * @memberOf fabric.Circle\n * @see: http://www.w3.org/TR/SVG/shapes.html#CircleElement\n */\n fabric.Circle.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat('cx cy r'.split(' '));\n\n /**\n * Returns {@link fabric.Circle} instance from an SVG element\n * @static\n * @memberOf fabric.Circle\n * @param {SVGElement} element Element to parse\n * @param {Function} [callback] Options callback invoked after parsing is finished\n * @param {Object} [options] Options object\n * @throws {Error} If value of `r` attribute is missing or invalid\n */\n fabric.Circle.fromElement = function(element, callback) {\n var parsedAttributes = fabric.parseAttributes(element, fabric.Circle.ATTRIBUTE_NAMES);\n\n if (!isValidRadius(parsedAttributes)) {\n throw new Error('value of `r` attribute is required and can not be negative');\n }\n\n parsedAttributes.left = (parsedAttributes.left || 0) - parsedAttributes.radius;\n parsedAttributes.top = (parsedAttributes.top || 0) - parsedAttributes.radius;\n callback(new fabric.Circle(parsedAttributes));\n };\n\n /**\n * @private\n */\n function isValidRadius(attributes) {\n return (('radius' in attributes) && (attributes.radius >= 0));\n }\n /* _FROM_SVG_END_ */\n\n /**\n * Returns {@link fabric.Circle} instance from an object representation\n * @static\n * @memberOf fabric.Circle\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] invoked with new instance as first argument\n * @return {Object} Instance of fabric.Circle\n */\n fabric.Circle.fromObject = function(object, callback) {\n return fabric.Object._fromObject('Circle', object, callback);\n };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { });\n\n if (fabric.Triangle) {\n fabric.warn('fabric.Triangle is already defined');\n return;\n }\n\n /**\n * Triangle class\n * @class fabric.Triangle\n * @extends fabric.Object\n * @return {fabric.Triangle} thisArg\n * @see {@link fabric.Triangle#initialize} for constructor definition\n */\n fabric.Triangle = fabric.util.createClass(fabric.Object, /** @lends fabric.Triangle.prototype */ {\n\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'triangle',\n\n /**\n * Width is set to 100 to compensate the old initialize code that was setting it to 100\n * @type Number\n * @default\n */\n width: 100,\n\n /**\n * Height is set to 100 to compensate the old initialize code that was setting it to 100\n * @type Number\n * @default\n */\n height: 100,\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _render: function(ctx) {\n var widthBy2 = this.width / 2,\n heightBy2 = this.height / 2;\n\n ctx.beginPath();\n ctx.moveTo(-widthBy2, heightBy2);\n ctx.lineTo(0, -heightBy2);\n ctx.lineTo(widthBy2, heightBy2);\n ctx.closePath();\n\n this._renderPaintInOrder(ctx);\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderDashedStroke: function(ctx) {\n var widthBy2 = this.width / 2,\n heightBy2 = this.height / 2;\n\n ctx.beginPath();\n fabric.util.drawDashedLine(ctx, -widthBy2, heightBy2, 0, -heightBy2, this.strokeDashArray);\n fabric.util.drawDashedLine(ctx, 0, -heightBy2, widthBy2, heightBy2, this.strokeDashArray);\n fabric.util.drawDashedLine(ctx, widthBy2, heightBy2, -widthBy2, heightBy2, this.strokeDashArray);\n ctx.closePath();\n },\n\n /* _TO_SVG_START_ */\n /**\n * Returns svg representation of an instance\n * @return {Array} an array of strings with the specific svg representation\n * of the instance\n */\n _toSVG: function() {\n var widthBy2 = this.width / 2,\n heightBy2 = this.height / 2,\n points = [\n -widthBy2 + ' ' + heightBy2,\n '0 ' + -heightBy2,\n widthBy2 + ' ' + heightBy2\n ].join(',');\n return [\n '<polygon ', 'COMMON_PARTS',\n 'points=\"', points,\n '\" />'\n ];\n },\n /* _TO_SVG_END_ */\n });\n\n /**\n * Returns {@link fabric.Triangle} instance from an object representation\n * @static\n * @memberOf fabric.Triangle\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] invoked with new instance as first argument\n */\n fabric.Triangle.fromObject = function(object, callback) {\n return fabric.Object._fromObject('Triangle', object, callback);\n };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n piBy2 = Math.PI * 2;\n\n if (fabric.Ellipse) {\n fabric.warn('fabric.Ellipse is already defined.');\n return;\n }\n\n /**\n * Ellipse class\n * @class fabric.Ellipse\n * @extends fabric.Object\n * @return {fabric.Ellipse} thisArg\n * @see {@link fabric.Ellipse#initialize} for constructor definition\n */\n fabric.Ellipse = fabric.util.createClass(fabric.Object, /** @lends fabric.Ellipse.prototype */ {\n\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'ellipse',\n\n /**\n * Horizontal radius\n * @type Number\n * @default\n */\n rx: 0,\n\n /**\n * Vertical radius\n * @type Number\n * @default\n */\n ry: 0,\n\n cacheProperties: fabric.Object.prototype.cacheProperties.concat('rx', 'ry'),\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n * @return {fabric.Ellipse} thisArg\n */\n initialize: function(options) {\n this.callSuper('initialize', options);\n this.set('rx', options && options.rx || 0);\n this.set('ry', options && options.ry || 0);\n },\n\n /**\n * @private\n * @param {String} key\n * @param {*} value\n * @return {fabric.Ellipse} thisArg\n */\n _set: function(key, value) {\n this.callSuper('_set', key, value);\n switch (key) {\n\n case 'rx':\n this.rx = value;\n this.set('width', value * 2);\n break;\n\n case 'ry':\n this.ry = value;\n this.set('height', value * 2);\n break;\n\n }\n return this;\n },\n\n /**\n * Returns horizontal radius of an object (according to how an object is scaled)\n * @return {Number}\n */\n getRx: function() {\n return this.get('rx') * this.get('scaleX');\n },\n\n /**\n * Returns Vertical radius of an object (according to how an object is scaled)\n * @return {Number}\n */\n getRy: function() {\n return this.get('ry') * this.get('scaleY');\n },\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject: function(propertiesToInclude) {\n return this.callSuper('toObject', ['rx', 'ry'].concat(propertiesToInclude));\n },\n\n /* _TO_SVG_START_ */\n /**\n * Returns svg representation of an instance\n * @return {Array} an array of strings with the specific svg representation\n * of the instance\n */\n _toSVG: function() {\n return [\n '<ellipse ', 'COMMON_PARTS',\n 'cx=\"0\" cy=\"0\" ',\n 'rx=\"', this.rx,\n '\" ry=\"', this.ry,\n '\" />\\n'\n ];\n },\n /* _TO_SVG_END_ */\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx context to render on\n */\n _render: function(ctx) {\n ctx.beginPath();\n ctx.save();\n ctx.transform(1, 0, 0, this.ry / this.rx, 0, 0);\n ctx.arc(\n 0,\n 0,\n this.rx,\n 0,\n piBy2,\n false);\n ctx.restore();\n this._renderPaintInOrder(ctx);\n },\n });\n\n /* _FROM_SVG_START_ */\n /**\n * List of attribute names to account for when parsing SVG element (used by {@link fabric.Ellipse.fromElement})\n * @static\n * @memberOf fabric.Ellipse\n * @see http://www.w3.org/TR/SVG/shapes.html#EllipseElement\n */\n fabric.Ellipse.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat('cx cy rx ry'.split(' '));\n\n /**\n * Returns {@link fabric.Ellipse} instance from an SVG element\n * @static\n * @memberOf fabric.Ellipse\n * @param {SVGElement} element Element to parse\n * @param {Function} [callback] Options callback invoked after parsing is finished\n * @return {fabric.Ellipse}\n */\n fabric.Ellipse.fromElement = function(element, callback) {\n\n var parsedAttributes = fabric.parseAttributes(element, fabric.Ellipse.ATTRIBUTE_NAMES);\n\n parsedAttributes.left = (parsedAttributes.left || 0) - parsedAttributes.rx;\n parsedAttributes.top = (parsedAttributes.top || 0) - parsedAttributes.ry;\n callback(new fabric.Ellipse(parsedAttributes));\n };\n /* _FROM_SVG_END_ */\n\n /**\n * Returns {@link fabric.Ellipse} instance from an object representation\n * @static\n * @memberOf fabric.Ellipse\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] invoked with new instance as first argument\n * @return {fabric.Ellipse}\n */\n fabric.Ellipse.fromObject = function(object, callback) {\n return fabric.Object._fromObject('Ellipse', object, callback);\n };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n extend = fabric.util.object.extend;\n\n if (fabric.Rect) {\n fabric.warn('fabric.Rect is already defined');\n return;\n }\n\n /**\n * Rectangle class\n * @class fabric.Rect\n * @extends fabric.Object\n * @return {fabric.Rect} thisArg\n * @see {@link fabric.Rect#initialize} for constructor definition\n */\n fabric.Rect = fabric.util.createClass(fabric.Object, /** @lends fabric.Rect.prototype */ {\n\n /**\n * List of properties to consider when checking if state of an object is changed ({@link fabric.Object#hasStateChanged})\n * as well as for history (undo/redo) purposes\n * @type Array\n */\n stateProperties: fabric.Object.prototype.stateProperties.concat('rx', 'ry'),\n\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'rect',\n\n /**\n * Horizontal border radius\n * @type Number\n * @default\n */\n rx: 0,\n\n /**\n * Vertical border radius\n * @type Number\n * @default\n */\n ry: 0,\n\n cacheProperties: fabric.Object.prototype.cacheProperties.concat('rx', 'ry'),\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n * @return {Object} thisArg\n */\n initialize: function(options) {\n this.callSuper('initialize', options);\n this._initRxRy();\n },\n\n /**\n * Initializes rx/ry attributes\n * @private\n */\n _initRxRy: function() {\n if (this.rx && !this.ry) {\n this.ry = this.rx;\n }\n else if (this.ry && !this.rx) {\n this.rx = this.ry;\n }\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _render: function(ctx) {\n\n // 1x1 case (used in spray brush) optimization was removed because\n // with caching and higher zoom level this makes more damage than help\n\n var rx = this.rx ? Math.min(this.rx, this.width / 2) : 0,\n ry = this.ry ? Math.min(this.ry, this.height / 2) : 0,\n w = this.width,\n h = this.height,\n x = -this.width / 2,\n y = -this.height / 2,\n isRounded = rx !== 0 || ry !== 0,\n /* \"magic number\" for bezier approximations of arcs (http://itc.ktu.lt/itc354/Riskus354.pdf) */\n k = 1 - 0.5522847498;\n ctx.beginPath();\n\n ctx.moveTo(x + rx, y);\n\n ctx.lineTo(x + w - rx, y);\n isRounded && ctx.bezierCurveTo(x + w - k * rx, y, x + w, y + k * ry, x + w, y + ry);\n\n ctx.lineTo(x + w, y + h - ry);\n isRounded && ctx.bezierCurveTo(x + w, y + h - k * ry, x + w - k * rx, y + h, x + w - rx, y + h);\n\n ctx.lineTo(x + rx, y + h);\n isRounded && ctx.bezierCurveTo(x + k * rx, y + h, x, y + h - k * ry, x, y + h - ry);\n\n ctx.lineTo(x, y + ry);\n isRounded && ctx.bezierCurveTo(x, y + k * ry, x + k * rx, y, x + rx, y);\n\n ctx.closePath();\n\n this._renderPaintInOrder(ctx);\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderDashedStroke: function(ctx) {\n var x = -this.width / 2,\n y = -this.height / 2,\n w = this.width,\n h = this.height;\n\n ctx.beginPath();\n fabric.util.drawDashedLine(ctx, x, y, x + w, y, this.strokeDashArray);\n fabric.util.drawDashedLine(ctx, x + w, y, x + w, y + h, this.strokeDashArray);\n fabric.util.drawDashedLine(ctx, x + w, y + h, x, y + h, this.strokeDashArray);\n fabric.util.drawDashedLine(ctx, x, y + h, x, y, this.strokeDashArray);\n ctx.closePath();\n },\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject: function(propertiesToInclude) {\n return this.callSuper('toObject', ['rx', 'ry'].concat(propertiesToInclude));\n },\n\n /* _TO_SVG_START_ */\n /**\n * Returns svg representation of an instance\n * @return {Array} an array of strings with the specific svg representation\n * of the instance\n */\n _toSVG: function() {\n var x = -this.width / 2, y = -this.height / 2;\n return [\n '<rect ', 'COMMON_PARTS',\n 'x=\"', x, '\" y=\"', y,\n '\" rx=\"', this.rx, '\" ry=\"', this.ry,\n '\" width=\"', this.width, '\" height=\"', this.height,\n '\" />\\n'\n ];\n },\n /* _TO_SVG_END_ */\n });\n\n /* _FROM_SVG_START_ */\n /**\n * List of attribute names to account for when parsing SVG element (used by `fabric.Rect.fromElement`)\n * @static\n * @memberOf fabric.Rect\n * @see: http://www.w3.org/TR/SVG/shapes.html#RectElement\n */\n fabric.Rect.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat('x y rx ry width height'.split(' '));\n\n /**\n * Returns {@link fabric.Rect} instance from an SVG element\n * @static\n * @memberOf fabric.Rect\n * @param {SVGElement} element Element to parse\n * @param {Function} callback callback function invoked after parsing\n * @param {Object} [options] Options object\n */\n fabric.Rect.fromElement = function(element, callback, options) {\n if (!element) {\n return callback(null);\n }\n options = options || { };\n\n var parsedAttributes = fabric.parseAttributes(element, fabric.Rect.ATTRIBUTE_NAMES);\n parsedAttributes.left = parsedAttributes.left || 0;\n parsedAttributes.top = parsedAttributes.top || 0;\n parsedAttributes.height = parsedAttributes.height || 0;\n parsedAttributes.width = parsedAttributes.width || 0;\n var rect = new fabric.Rect(extend((options ? fabric.util.object.clone(options) : { }), parsedAttributes));\n rect.visible = rect.visible && rect.width > 0 && rect.height > 0;\n callback(rect);\n };\n /* _FROM_SVG_END_ */\n\n /**\n * Returns {@link fabric.Rect} instance from an object representation\n * @static\n * @memberOf fabric.Rect\n * @param {Object} object Object to create an instance from\n * @param {Function} [callback] Callback to invoke when an fabric.Rect instance is created\n */\n fabric.Rect.fromObject = function(object, callback) {\n return fabric.Object._fromObject('Rect', object, callback);\n };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n extend = fabric.util.object.extend,\n min = fabric.util.array.min,\n max = fabric.util.array.max,\n toFixed = fabric.util.toFixed;\n\n if (fabric.Polyline) {\n fabric.warn('fabric.Polyline is already defined');\n return;\n }\n\n /**\n * Polyline class\n * @class fabric.Polyline\n * @extends fabric.Object\n * @see {@link fabric.Polyline#initialize} for constructor definition\n */\n fabric.Polyline = fabric.util.createClass(fabric.Object, /** @lends fabric.Polyline.prototype */ {\n\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'polyline',\n\n /**\n * Points array\n * @type Array\n * @default\n */\n points: null,\n\n cacheProperties: fabric.Object.prototype.cacheProperties.concat('points'),\n\n /**\n * Constructor\n * @param {Array} points Array of points (where each point is an object with x and y)\n * @param {Object} [options] Options object\n * @return {fabric.Polyline} thisArg\n * @example\n * var poly = new fabric.Polyline([\n * { x: 10, y: 10 },\n * { x: 50, y: 30 },\n * { x: 40, y: 70 },\n * { x: 60, y: 50 },\n * { x: 100, y: 150 },\n * { x: 40, y: 100 }\n * ], {\n * stroke: 'red',\n * left: 100,\n * top: 100\n * });\n */\n initialize: function(points, options) {\n options = options || {};\n this.points = points || [];\n this.callSuper('initialize', options);\n this._setPositionDimensions(options);\n },\n\n _setPositionDimensions: function(options) {\n var calcDim = this._calcDimensions(options), correctLeftTop;\n this.width = calcDim.width;\n this.height = calcDim.height;\n if (!options.fromSVG) {\n correctLeftTop = this.translateToGivenOrigin(\n { x: calcDim.left - this.strokeWidth / 2, y: calcDim.top - this.strokeWidth / 2 },\n 'left',\n 'top',\n this.originX,\n this.originY\n );\n }\n if (typeof options.left === 'undefined') {\n this.left = options.fromSVG ? calcDim.left : correctLeftTop.x;\n }\n if (typeof options.top === 'undefined') {\n this.top = options.fromSVG ? calcDim.top : correctLeftTop.y;\n }\n this.pathOffset = {\n x: calcDim.left + this.width / 2,\n y: calcDim.top + this.height / 2\n };\n },\n\n /**\n * Calculate the polygon min and max point from points array,\n * returning an object with left, top, widht, height to measure the\n * polygon size\n * @return {Object} object.left X coordinate of the polygon leftmost point\n * @return {Object} object.top Y coordinate of the polygon topmost point\n * @return {Object} object.width distance between X coordinates of the polygon leftmost and rightmost point\n * @return {Object} object.height distance between Y coordinates of the polygon topmost and bottommost point\n * @private\n */\n _calcDimensions: function() {\n\n var points = this.points,\n minX = min(points, 'x') || 0,\n minY = min(points, 'y') || 0,\n maxX = max(points, 'x') || 0,\n maxY = max(points, 'y') || 0,\n width = (maxX - minX),\n height = (maxY - minY);\n\n return {\n left: minX,\n top: minY,\n width: width,\n height: height\n };\n },\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} Object representation of an instance\n */\n toObject: function(propertiesToInclude) {\n return extend(this.callSuper('toObject', propertiesToInclude), {\n points: this.points.concat()\n });\n },\n\n /* _TO_SVG_START_ */\n /**\n * Returns svg representation of an instance\n * @return {Array} an array of strings with the specific svg representation\n * of the instance\n */\n _toSVG: function() {\n var points = [], diffX = this.pathOffset.x, diffY = this.pathOffset.y,\n NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS;\n\n for (var i = 0, len = this.points.length; i < len; i++) {\n points.push(\n toFixed(this.points[i].x - diffX, NUM_FRACTION_DIGITS), ',',\n toFixed(this.points[i].y - diffY, NUM_FRACTION_DIGITS), ' '\n );\n }\n return [\n '<' + this.type + ' ', 'COMMON_PARTS',\n 'points=\"', points.join(''),\n '\" />\\n'\n ];\n },\n /* _TO_SVG_END_ */\n\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n commonRender: function(ctx) {\n var point, len = this.points.length,\n x = this.pathOffset.x,\n y = this.pathOffset.y;\n\n if (!len || isNaN(this.points[len - 1].y)) {\n // do not draw if no points or odd points\n // NaN comes from parseFloat of a empty string in parser\n return false;\n }\n ctx.beginPath();\n ctx.moveTo(this.points[0].x - x, this.points[0].y - y);\n for (var i = 0; i < len; i++) {\n point = this.points[i];\n ctx.lineTo(point.x - x, point.y - y);\n }\n return true;\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _render: function(ctx) {\n if (!this.commonRender(ctx)) {\n return;\n }\n this._renderPaintInOrder(ctx);\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderDashedStroke: function(ctx) {\n var p1, p2;\n\n ctx.beginPath();\n for (var i = 0, len = this.points.length; i < len; i++) {\n p1 = this.points[i];\n p2 = this.points[i + 1] || p1;\n fabric.util.drawDashedLine(ctx, p1.x, p1.y, p2.x, p2.y, this.strokeDashArray);\n }\n },\n\n /**\n * Returns complexity of an instance\n * @return {Number} complexity of this instance\n */\n complexity: function() {\n return this.get('points').length;\n }\n });\n\n /* _FROM_SVG_START_ */\n /**\n * List of attribute names to account for when parsing SVG element (used by {@link fabric.Polyline.fromElement})\n * @static\n * @memberOf fabric.Polyline\n * @see: http://www.w3.org/TR/SVG/shapes.html#PolylineElement\n */\n fabric.Polyline.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat();\n\n /**\n * Returns fabric.Polyline instance from an SVG element\n * @static\n * @memberOf fabric.Polyline\n * @param {SVGElement} element Element to parser\n * @param {Function} callback callback function invoked after parsing\n * @param {Object} [options] Options object\n */\n fabric.Polyline.fromElementGenerator = function(_class) {\n return function(element, callback, options) {\n if (!element) {\n return callback(null);\n }\n options || (options = { });\n\n var points = fabric.parsePointsAttribute(element.getAttribute('points')),\n parsedAttributes = fabric.parseAttributes(element, fabric[_class].ATTRIBUTE_NAMES);\n parsedAttributes.fromSVG = true;\n callback(new fabric[_class](points, extend(parsedAttributes, options)));\n };\n };\n\n fabric.Polyline.fromElement = fabric.Polyline.fromElementGenerator('Polyline');\n\n /* _FROM_SVG_END_ */\n\n /**\n * Returns fabric.Polyline instance from an object representation\n * @static\n * @memberOf fabric.Polyline\n * @param {Object} object Object to create an instance from\n * @param {Function} [callback] Callback to invoke when an fabric.Path instance is created\n */\n fabric.Polyline.fromObject = function(object, callback) {\n return fabric.Object._fromObject('Polyline', object, callback, 'points');\n };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { });\n\n if (fabric.Polygon) {\n fabric.warn('fabric.Polygon is already defined');\n return;\n }\n\n /**\n * Polygon class\n * @class fabric.Polygon\n * @extends fabric.Polyline\n * @see {@link fabric.Polygon#initialize} for constructor definition\n */\n fabric.Polygon = fabric.util.createClass(fabric.Polyline, /** @lends fabric.Polygon.prototype */ {\n\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'polygon',\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _render: function(ctx) {\n if (!this.commonRender(ctx)) {\n return;\n }\n ctx.closePath();\n this._renderPaintInOrder(ctx);\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderDashedStroke: function(ctx) {\n this.callSuper('_renderDashedStroke', ctx);\n ctx.closePath();\n },\n });\n\n /* _FROM_SVG_START_ */\n /**\n * List of attribute names to account for when parsing SVG element (used by `fabric.Polygon.fromElement`)\n * @static\n * @memberOf fabric.Polygon\n * @see: http://www.w3.org/TR/SVG/shapes.html#PolygonElement\n */\n fabric.Polygon.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat();\n\n /**\n * Returns {@link fabric.Polygon} instance from an SVG element\n * @static\n * @memberOf fabric.Polygon\n * @param {SVGElement} element Element to parse\n * @param {Function} callback callback function invoked after parsing\n * @param {Object} [options] Options object\n */\n fabric.Polygon.fromElement = fabric.Polyline.fromElementGenerator('Polygon');\n /* _FROM_SVG_END_ */\n\n /**\n * Returns fabric.Polygon instance from an object representation\n * @static\n * @memberOf fabric.Polygon\n * @param {Object} object Object to create an instance from\n * @param {Function} [callback] Callback to invoke when an fabric.Path instance is created\n */\n fabric.Polygon.fromObject = function(object, callback) {\n return fabric.Object._fromObject('Polygon', object, callback, 'points');\n };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n min = fabric.util.array.min,\n max = fabric.util.array.max,\n extend = fabric.util.object.extend,\n _toString = Object.prototype.toString,\n toFixed = fabric.util.toFixed;\n\n if (fabric.Path) {\n fabric.warn('fabric.Path is already defined');\n return;\n }\n\n /**\n * Path class\n * @class fabric.Path\n * @extends fabric.Object\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#path_and_pathgroup}\n * @see {@link fabric.Path#initialize} for constructor definition\n */\n fabric.Path = fabric.util.createClass(fabric.Object, /** @lends fabric.Path.prototype */ {\n\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'path',\n\n /**\n * Array of path points\n * @type Array\n * @default\n */\n path: null,\n\n cacheProperties: fabric.Object.prototype.cacheProperties.concat('path', 'fillRule'),\n\n stateProperties: fabric.Object.prototype.stateProperties.concat('path'),\n\n /**\n * Constructor\n * @param {Array|String} path Path data (sequence of coordinates and corresponding \"command\" tokens)\n * @param {Object} [options] Options object\n * @return {fabric.Path} thisArg\n */\n initialize: function(path, options) {\n options = options || { };\n this.callSuper('initialize', options);\n if (!path) {\n path = [];\n }\n\n var fromArray = _toString.call(path) === '[object Array]';\n\n this.path = fromArray\n ? fabric.util.makePathSimpler(path)\n\n : fabric.util.makePathSimpler(\n fabric.util.parsePath(path)\n );\n\n if (!this.path) {\n return;\n }\n fabric.Polyline.prototype._setPositionDimensions.call(this, options);\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx context to render path on\n */\n _renderPathCommands: function(ctx) {\n var current, // current instruction\n subpathStartX = 0,\n subpathStartY = 0,\n x = 0, // current x\n y = 0, // current y\n controlX = 0, // current control point x\n controlY = 0, // current control point y\n l = -this.pathOffset.x,\n t = -this.pathOffset.y;\n\n ctx.beginPath();\n\n for (var i = 0, len = this.path.length; i < len; ++i) {\n\n current = this.path[i];\n\n switch (current[0]) { // first letter\n\n case 'L': // lineto, absolute\n x = current[1];\n y = current[2];\n ctx.lineTo(x + l, y + t);\n break;\n\n case 'M': // moveTo, absolute\n x = current[1];\n y = current[2];\n subpathStartX = x;\n subpathStartY = y;\n ctx.moveTo(x + l, y + t);\n break;\n\n case 'C': // bezierCurveTo, absolute\n x = current[5];\n y = current[6];\n controlX = current[3];\n controlY = current[4];\n ctx.bezierCurveTo(\n current[1] + l,\n current[2] + t,\n controlX + l,\n controlY + t,\n x + l,\n y + t\n );\n break;\n\n case 'Q': // quadraticCurveTo, absolute\n ctx.quadraticCurveTo(\n current[1] + l,\n current[2] + t,\n current[3] + l,\n current[4] + t\n );\n x = current[3];\n y = current[4];\n controlX = current[1];\n controlY = current[2];\n break;\n\n case 'z':\n case 'Z':\n x = subpathStartX;\n y = subpathStartY;\n ctx.closePath();\n break;\n }\n }\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx context to render path on\n */\n _render: function(ctx) {\n this._renderPathCommands(ctx);\n this._renderPaintInOrder(ctx);\n },\n\n /**\n * Returns string representation of an instance\n * @return {String} string representation of an instance\n */\n toString: function() {\n return '#<fabric.Path (' + this.complexity() +\n '): { \"top\": ' + this.top + ', \"left\": ' + this.left + ' }>';\n },\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject: function(propertiesToInclude) {\n return extend(this.callSuper('toObject', propertiesToInclude), {\n path: this.path.map(function(item) { return item.slice(); }),\n });\n },\n\n /**\n * Returns dataless object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toDatalessObject: function(propertiesToInclude) {\n var o = this.toObject(['sourcePath'].concat(propertiesToInclude));\n if (o.sourcePath) {\n delete o.path;\n }\n return o;\n },\n\n /* _TO_SVG_START_ */\n /**\n * Returns svg representation of an instance\n * @return {Array} an array of strings with the specific svg representation\n * of the instance\n */\n _toSVG: function() {\n var path = this.path.map(function(path) {\n return path.join(' ');\n }).join(' ');\n return [\n '<path ', 'COMMON_PARTS',\n 'd=\"', path,\n '\" stroke-linecap=\"round\" ',\n '/>\\n'\n ];\n },\n\n _getOffsetTransform: function() {\n var digits = fabric.Object.NUM_FRACTION_DIGITS;\n return ' translate(' + toFixed(-this.pathOffset.x, digits) + ', ' +\n toFixed(-this.pathOffset.y, digits) + ')';\n },\n\n /**\n * Returns svg clipPath representation of an instance\n * @param {Function} [reviver] Method for further parsing of svg representation.\n * @return {String} svg representation of an instance\n */\n toClipPathSVG: function(reviver) {\n var additionalTransform = this._getOffsetTransform();\n return '\\t' + this._createBaseClipPathSVGMarkup(\n this._toSVG(), { reviver: reviver, additionalTransform: additionalTransform }\n );\n },\n\n /**\n * Returns svg representation of an instance\n * @param {Function} [reviver] Method for further parsing of svg representation.\n * @return {String} svg representation of an instance\n */\n toSVG: function(reviver) {\n var additionalTransform = this._getOffsetTransform();\n return this._createBaseSVGMarkup(this._toSVG(), { reviver: reviver, additionalTransform: additionalTransform });\n },\n /* _TO_SVG_END_ */\n\n /**\n * Returns number representation of an instance complexity\n * @return {Number} complexity of this instance\n */\n complexity: function() {\n return this.path.length;\n },\n\n /**\n * @private\n */\n _calcDimensions: function() {\n\n var aX = [],\n aY = [],\n current, // current instruction\n subpathStartX = 0,\n subpathStartY = 0,\n x = 0, // current x\n y = 0, // current y\n bounds;\n\n for (var i = 0, len = this.path.length; i < len; ++i) {\n\n current = this.path[i];\n\n switch (current[0]) { // first letter\n\n case 'L': // lineto, absolute\n x = current[1];\n y = current[2];\n bounds = [];\n break;\n\n case 'M': // moveTo, absolute\n x = current[1];\n y = current[2];\n subpathStartX = x;\n subpathStartY = y;\n bounds = [];\n break;\n\n case 'C': // bezierCurveTo, absolute\n bounds = fabric.util.getBoundsOfCurve(x, y,\n current[1],\n current[2],\n current[3],\n current[4],\n current[5],\n current[6]\n );\n x = current[5];\n y = current[6];\n break;\n\n case 'Q': // quadraticCurveTo, absolute\n bounds = fabric.util.getBoundsOfCurve(x, y,\n current[1],\n current[2],\n current[1],\n current[2],\n current[3],\n current[4]\n );\n x = current[3];\n y = current[4];\n break;\n\n case 'z':\n case 'Z':\n x = subpathStartX;\n y = subpathStartY;\n break;\n }\n bounds.forEach(function (point) {\n aX.push(point.x);\n aY.push(point.y);\n });\n aX.push(x);\n aY.push(y);\n }\n\n var minX = min(aX) || 0,\n minY = min(aY) || 0,\n maxX = max(aX) || 0,\n maxY = max(aY) || 0,\n deltaX = maxX - minX,\n deltaY = maxY - minY;\n\n return {\n left: minX,\n top: minY,\n width: deltaX,\n height: deltaY\n };\n }\n });\n\n /**\n * Creates an instance of fabric.Path from an object\n * @static\n * @memberOf fabric.Path\n * @param {Object} object\n * @param {Function} [callback] Callback to invoke when an fabric.Path instance is created\n */\n fabric.Path.fromObject = function(object, callback) {\n if (typeof object.sourcePath === 'string') {\n var pathUrl = object.sourcePath;\n fabric.loadSVGFromURL(pathUrl, function (elements) {\n var path = elements[0];\n path.setOptions(object);\n callback && callback(path);\n });\n }\n else {\n fabric.Object._fromObject('Path', object, callback, 'path');\n }\n };\n\n /* _FROM_SVG_START_ */\n /**\n * List of attribute names to account for when parsing SVG element (used by `fabric.Path.fromElement`)\n * @static\n * @memberOf fabric.Path\n * @see http://www.w3.org/TR/SVG/paths.html#PathElement\n */\n fabric.Path.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat(['d']);\n\n /**\n * Creates an instance of fabric.Path from an SVG <path> element\n * @static\n * @memberOf fabric.Path\n * @param {SVGElement} element to parse\n * @param {Function} callback Callback to invoke when an fabric.Path instance is created\n * @param {Object} [options] Options object\n * @param {Function} [callback] Options callback invoked after parsing is finished\n */\n fabric.Path.fromElement = function(element, callback, options) {\n var parsedAttributes = fabric.parseAttributes(element, fabric.Path.ATTRIBUTE_NAMES);\n parsedAttributes.fromSVG = true;\n callback(new fabric.Path(parsedAttributes.d, extend(parsedAttributes, options)));\n };\n /* _FROM_SVG_END_ */\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n min = fabric.util.array.min,\n max = fabric.util.array.max;\n\n if (fabric.Group) {\n return;\n }\n\n /**\n * Group class\n * @class fabric.Group\n * @extends fabric.Object\n * @mixes fabric.Collection\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#groups}\n * @see {@link fabric.Group#initialize} for constructor definition\n */\n fabric.Group = fabric.util.createClass(fabric.Object, fabric.Collection, /** @lends fabric.Group.prototype */ {\n\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'group',\n\n /**\n * Width of stroke\n * @type Number\n * @default\n */\n strokeWidth: 0,\n\n /**\n * Indicates if click, mouseover, mouseout events & hoverCursor should also check for subtargets\n * @type Boolean\n * @default\n */\n subTargetCheck: false,\n\n /**\n * Groups are container, do not render anything on theyr own, ence no cache properties\n * @type Array\n * @default\n */\n cacheProperties: [],\n\n /**\n * setOnGroup is a method used for TextBox that is no more used since 2.0.0 The behavior is still\n * available setting this boolean to true.\n * @type Boolean\n * @since 2.0.0\n * @default\n */\n useSetOnGroup: false,\n\n /**\n * Constructor\n * @param {Object} objects Group objects\n * @param {Object} [options] Options object\n * @param {Boolean} [isAlreadyGrouped] if true, objects have been grouped already.\n * @return {Object} thisArg\n */\n initialize: function(objects, options, isAlreadyGrouped) {\n options = options || {};\n this._objects = [];\n // if objects enclosed in a group have been grouped already,\n // we cannot change properties of objects.\n // Thus we need to set options to group without objects,\n isAlreadyGrouped && this.callSuper('initialize', options);\n this._objects = objects || [];\n for (var i = this._objects.length; i--; ) {\n this._objects[i].group = this;\n }\n\n if (!isAlreadyGrouped) {\n var center = options && options.centerPoint;\n // we want to set origins before calculating the bounding box.\n // so that the topleft can be set with that in mind.\n // if specific top and left are passed, are overwritten later\n // with the callSuper('initialize', options)\n if (options.originX !== undefined) {\n this.originX = options.originX;\n }\n if (options.originY !== undefined) {\n this.originY = options.originY;\n }\n // if coming from svg i do not want to calc bounds.\n // i assume width and height are passed along options\n center || this._calcBounds();\n this._updateObjectsCoords(center);\n delete options.centerPoint;\n this.callSuper('initialize', options);\n }\n else {\n this._updateObjectsACoords();\n }\n\n this.setCoords();\n },\n\n /**\n * @private\n */\n _updateObjectsACoords: function() {\n var skipControls = true;\n for (var i = this._objects.length; i--; ){\n this._objects[i].setCoords(skipControls);\n }\n },\n\n /**\n * @private\n * @param {Boolean} [skipCoordsChange] if true, coordinates of objects enclosed in a group do not change\n */\n _updateObjectsCoords: function(center) {\n var center = center || this.getCenterPoint();\n for (var i = this._objects.length; i--; ){\n this._updateObjectCoords(this._objects[i], center);\n }\n },\n\n /**\n * @private\n * @param {Object} object\n * @param {fabric.Point} center, current center of group.\n */\n _updateObjectCoords: function(object, center) {\n var objectLeft = object.left,\n objectTop = object.top,\n skipControls = true;\n\n object.set({\n left: objectLeft - center.x,\n top: objectTop - center.y\n });\n object.group = this;\n object.setCoords(skipControls);\n },\n\n /**\n * Returns string represenation of a group\n * @return {String}\n */\n toString: function() {\n return '#<fabric.Group: (' + this.complexity() + ')>';\n },\n\n /**\n * Adds an object to a group; Then recalculates group's dimension, position.\n * @param {Object} object\n * @return {fabric.Group} thisArg\n * @chainable\n */\n addWithUpdate: function(object) {\n this._restoreObjectsState();\n fabric.util.resetObjectTransform(this);\n if (object) {\n this._objects.push(object);\n object.group = this;\n object._set('canvas', this.canvas);\n }\n this._calcBounds();\n this._updateObjectsCoords();\n this.setCoords();\n this.dirty = true;\n return this;\n },\n\n /**\n * Removes an object from a group; Then recalculates group's dimension, position.\n * @param {Object} object\n * @return {fabric.Group} thisArg\n * @chainable\n */\n removeWithUpdate: function(object) {\n this._restoreObjectsState();\n fabric.util.resetObjectTransform(this);\n\n this.remove(object);\n this._calcBounds();\n this._updateObjectsCoords();\n this.setCoords();\n this.dirty = true;\n return this;\n },\n\n /**\n * @private\n */\n _onObjectAdded: function(object) {\n this.dirty = true;\n object.group = this;\n object._set('canvas', this.canvas);\n },\n\n /**\n * @private\n */\n _onObjectRemoved: function(object) {\n this.dirty = true;\n delete object.group;\n },\n\n /**\n * @private\n */\n _set: function(key, value) {\n var i = this._objects.length;\n if (this.useSetOnGroup) {\n while (i--) {\n this._objects[i].setOnGroup(key, value);\n }\n }\n if (key === 'canvas') {\n while (i--) {\n this._objects[i]._set(key, value);\n }\n }\n fabric.Object.prototype._set.call(this, key, value);\n },\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject: function(propertiesToInclude) {\n var _includeDefaultValues = this.includeDefaultValues;\n var objsToObject = this._objects.map(function(obj) {\n var originalDefaults = obj.includeDefaultValues;\n obj.includeDefaultValues = _includeDefaultValues;\n var _obj = obj.toObject(propertiesToInclude);\n obj.includeDefaultValues = originalDefaults;\n return _obj;\n });\n var obj = fabric.Object.prototype.toObject.call(this, propertiesToInclude);\n obj.objects = objsToObject;\n return obj;\n },\n\n /**\n * Returns object representation of an instance, in dataless mode.\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toDatalessObject: function(propertiesToInclude) {\n var objsToObject, sourcePath = this.sourcePath;\n if (sourcePath) {\n objsToObject = sourcePath;\n }\n else {\n var _includeDefaultValues = this.includeDefaultValues;\n objsToObject = this._objects.map(function(obj) {\n var originalDefaults = obj.includeDefaultValues;\n obj.includeDefaultValues = _includeDefaultValues;\n var _obj = obj.toDatalessObject(propertiesToInclude);\n obj.includeDefaultValues = originalDefaults;\n return _obj;\n });\n }\n var obj = fabric.Object.prototype.toDatalessObject.call(this, propertiesToInclude);\n obj.objects = objsToObject;\n return obj;\n },\n\n /**\n * Renders instance on a given context\n * @param {CanvasRenderingContext2D} ctx context to render instance on\n */\n render: function(ctx) {\n this._transformDone = true;\n this.callSuper('render', ctx);\n this._transformDone = false;\n },\n\n /**\n * Decide if the object should cache or not. Create its own cache level\n * needsItsOwnCache should be used when the object drawing method requires\n * a cache step. None of the fabric classes requires it.\n * Generally you do not cache objects in groups because the group is already cached.\n * @return {Boolean}\n */\n shouldCache: function() {\n var ownCache = fabric.Object.prototype.shouldCache.call(this);\n if (ownCache) {\n for (var i = 0, len = this._objects.length; i < len; i++) {\n if (this._objects[i].willDrawShadow()) {\n this.ownCaching = false;\n return false;\n }\n }\n }\n return ownCache;\n },\n\n /**\n * Check if this object or a child object will cast a shadow\n * @return {Boolean}\n */\n willDrawShadow: function() {\n if (fabric.Object.prototype.willDrawShadow.call(this)) {\n return true;\n }\n for (var i = 0, len = this._objects.length; i < len; i++) {\n if (this._objects[i].willDrawShadow()) {\n return true;\n }\n }\n return false;\n },\n\n /**\n * Check if this group or its parent group are caching, recursively up\n * @return {Boolean}\n */\n isOnACache: function() {\n return this.ownCaching || (this.group && this.group.isOnACache());\n },\n\n /**\n * Execute the drawing operation for an object on a specified context\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n drawObject: function(ctx) {\n for (var i = 0, len = this._objects.length; i < len; i++) {\n this._objects[i].render(ctx);\n }\n this._drawClipPath(ctx);\n },\n\n /**\n * Check if cache is dirty\n */\n isCacheDirty: function(skipCanvas) {\n if (this.callSuper('isCacheDirty', skipCanvas)) {\n return true;\n }\n if (!this.statefullCache) {\n return false;\n }\n for (var i = 0, len = this._objects.length; i < len; i++) {\n if (this._objects[i].isCacheDirty(true)) {\n if (this._cacheCanvas) {\n // if this group has not a cache canvas there is nothing to clean\n var x = this.cacheWidth / this.zoomX, y = this.cacheHeight / this.zoomY;\n this._cacheContext.clearRect(-x / 2, -y / 2, x, y);\n }\n return true;\n }\n }\n return false;\n },\n\n /**\n * Retores original state of each of group objects (original state is that which was before group was created).\n * @private\n * @return {fabric.Group} thisArg\n * @chainable\n */\n _restoreObjectsState: function() {\n this._objects.forEach(this._restoreObjectState, this);\n return this;\n },\n\n /**\n * Realises the transform from this group onto the supplied object\n * i.e. it tells you what would happen if the supplied object was in\n * the group, and then the group was destroyed. It mutates the supplied\n * object.\n * @param {fabric.Object} object\n * @return {fabric.Object} transformedObject\n */\n realizeTransform: function(object) {\n var matrix = object.calcTransformMatrix(),\n options = fabric.util.qrDecompose(matrix),\n center = new fabric.Point(options.translateX, options.translateY);\n object.flipX = false;\n object.flipY = false;\n object.set('scaleX', options.scaleX);\n object.set('scaleY', options.scaleY);\n object.skewX = options.skewX;\n object.skewY = options.skewY;\n object.angle = options.angle;\n object.setPositionByOrigin(center, 'center', 'center');\n return object;\n },\n\n /**\n * Restores original state of a specified object in group\n * @private\n * @param {fabric.Object} object\n * @return {fabric.Group} thisArg\n */\n _restoreObjectState: function(object) {\n this.realizeTransform(object);\n delete object.group;\n object.setCoords();\n return this;\n },\n\n /**\n * Destroys a group (restoring state of its objects)\n * @return {fabric.Group} thisArg\n * @chainable\n */\n destroy: function() {\n // when group is destroyed objects needs to get a repaint to be eventually\n // displayed on canvas.\n this._objects.forEach(function(object) {\n object.set('dirty', true);\n });\n return this._restoreObjectsState();\n },\n\n /**\n * make a group an active selection, remove the group from canvas\n * the group has to be on canvas for this to work.\n * @return {fabric.ActiveSelection} thisArg\n * @chainable\n */\n toActiveSelection: function() {\n if (!this.canvas) {\n return;\n }\n var objects = this._objects, canvas = this.canvas;\n this._objects = [];\n var options = this.toObject();\n delete options.objects;\n var activeSelection = new fabric.ActiveSelection([]);\n activeSelection.set(options);\n activeSelection.type = 'activeSelection';\n canvas.remove(this);\n objects.forEach(function(object) {\n object.group = activeSelection;\n object.dirty = true;\n canvas.add(object);\n });\n activeSelection.canvas = canvas;\n activeSelection._objects = objects;\n canvas._activeObject = activeSelection;\n activeSelection.setCoords();\n return activeSelection;\n },\n\n /**\n * Destroys a group (restoring state of its objects)\n * @return {fabric.Group} thisArg\n * @chainable\n */\n ungroupOnCanvas: function() {\n return this._restoreObjectsState();\n },\n\n /**\n * Sets coordinates of all objects inside group\n * @return {fabric.Group} thisArg\n * @chainable\n */\n setObjectsCoords: function() {\n var skipControls = true;\n this.forEachObject(function(object) {\n object.setCoords(skipControls);\n });\n return this;\n },\n\n /**\n * @private\n */\n _calcBounds: function(onlyWidthHeight) {\n var aX = [],\n aY = [],\n o, prop,\n props = ['tr', 'br', 'bl', 'tl'],\n i = 0, iLen = this._objects.length,\n j, jLen = props.length;\n\n for ( ; i < iLen; ++i) {\n o = this._objects[i];\n o.aCoords = o.calcACoords();\n for (j = 0; j < jLen; j++) {\n prop = props[j];\n aX.push(o.aCoords[prop].x);\n aY.push(o.aCoords[prop].y);\n }\n }\n\n this._getBounds(aX, aY, onlyWidthHeight);\n },\n\n /**\n * @private\n */\n _getBounds: function(aX, aY, onlyWidthHeight) {\n var minXY = new fabric.Point(min(aX), min(aY)),\n maxXY = new fabric.Point(max(aX), max(aY)),\n top = minXY.y || 0, left = minXY.x || 0,\n width = (maxXY.x - minXY.x) || 0,\n height = (maxXY.y - minXY.y) || 0;\n this.width = width;\n this.height = height;\n if (!onlyWidthHeight) {\n // the bounding box always finds the topleft most corner.\n // whatever is the group origin, we set up here the left/top position.\n this.setPositionByOrigin({ x: left, y: top }, 'left', 'top');\n }\n },\n\n /* _TO_SVG_START_ */\n /**\n * Returns svg representation of an instance\n * @param {Function} [reviver] Method for further parsing of svg representation.\n * @return {String} svg representation of an instance\n */\n _toSVG: function(reviver) {\n var svgString = ['<g ', 'COMMON_PARTS', ' >\\n'];\n\n for (var i = 0, len = this._objects.length; i < len; i++) {\n svgString.push('\\t\\t', this._objects[i].toSVG(reviver));\n }\n svgString.push('</g>\\n');\n return svgString;\n },\n\n /**\n * Returns styles-string for svg-export, specific version for group\n * @return {String}\n */\n getSvgStyles: function() {\n var opacity = typeof this.opacity !== 'undefined' && this.opacity !== 1 ?\n 'opacity: ' + this.opacity + ';' : '',\n visibility = this.visible ? '' : ' visibility: hidden;';\n return [\n opacity,\n this.getSvgFilter(),\n visibility\n ].join('');\n },\n\n /**\n * Returns svg clipPath representation of an instance\n * @param {Function} [reviver] Method for further parsing of svg representation.\n * @return {String} svg representation of an instance\n */\n toClipPathSVG: function(reviver) {\n var svgString = [];\n\n for (var i = 0, len = this._objects.length; i < len; i++) {\n svgString.push('\\t', this._objects[i].toClipPathSVG(reviver));\n }\n\n return this._createBaseClipPathSVGMarkup(svgString, { reviver: reviver });\n },\n /* _TO_SVG_END_ */\n });\n\n /**\n * Returns {@link fabric.Group} instance from an object representation\n * @static\n * @memberOf fabric.Group\n * @param {Object} object Object to create a group from\n * @param {Function} [callback] Callback to invoke when an group instance is created\n */\n fabric.Group.fromObject = function(object, callback) {\n var objects = object.objects,\n options = fabric.util.object.clone(object, true);\n delete options.objects;\n if (typeof objects === 'string') {\n // it has to be an url or something went wrong.\n fabric.loadSVGFromURL(objects, function (elements) {\n var group = fabric.util.groupSVGElements(elements, object, objects);\n group.set(options);\n callback && callback(group);\n });\n return;\n }\n fabric.util.enlivenObjects(objects, function(enlivenedObjects) {\n fabric.util.enlivenObjects([object.clipPath], function(enlivedClipPath) {\n var options = fabric.util.object.clone(object, true);\n options.clipPath = enlivedClipPath[0];\n delete options.objects;\n callback && callback(new fabric.Group(enlivenedObjects, options, true));\n });\n });\n };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { });\n\n if (fabric.ActiveSelection) {\n return;\n }\n\n /**\n * Group class\n * @class fabric.ActiveSelection\n * @extends fabric.Group\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#groups}\n * @see {@link fabric.ActiveSelection#initialize} for constructor definition\n */\n fabric.ActiveSelection = fabric.util.createClass(fabric.Group, /** @lends fabric.ActiveSelection.prototype */ {\n\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'activeSelection',\n\n /**\n * Constructor\n * @param {Object} objects ActiveSelection objects\n * @param {Object} [options] Options object\n * @return {Object} thisArg\n */\n initialize: function(objects, options) {\n options = options || {};\n this._objects = objects || [];\n for (var i = this._objects.length; i--; ) {\n this._objects[i].group = this;\n }\n\n if (options.originX) {\n this.originX = options.originX;\n }\n if (options.originY) {\n this.originY = options.originY;\n }\n this._calcBounds();\n this._updateObjectsCoords();\n fabric.Object.prototype.initialize.call(this, options);\n this.setCoords();\n },\n\n /**\n * Change te activeSelection to a normal group,\n * High level function that automatically adds it to canvas as\n * active object. no events fired.\n * @since 2.0.0\n * @return {fabric.Group}\n */\n toGroup: function() {\n var objects = this._objects.concat();\n this._objects = [];\n var options = fabric.Object.prototype.toObject.call(this);\n var newGroup = new fabric.Group([]);\n delete options.type;\n newGroup.set(options);\n objects.forEach(function(object) {\n object.canvas.remove(object);\n object.group = newGroup;\n });\n newGroup._objects = objects;\n if (!this.canvas) {\n return newGroup;\n }\n var canvas = this.canvas;\n canvas.add(newGroup);\n canvas._activeObject = newGroup;\n newGroup.setCoords();\n return newGroup;\n },\n\n /**\n * If returns true, deselection is cancelled.\n * @since 2.0.0\n * @return {Boolean} [cancel]\n */\n onDeselect: function() {\n this.destroy();\n return false;\n },\n\n /**\n * Returns string representation of a group\n * @return {String}\n */\n toString: function() {\n return '#<fabric.ActiveSelection: (' + this.complexity() + ')>';\n },\n\n /**\n * Decide if the object should cache or not. Create its own cache level\n * objectCaching is a global flag, wins over everything\n * needsItsOwnCache should be used when the object drawing method requires\n * a cache step. None of the fabric classes requires it.\n * Generally you do not cache objects in groups because the group outside is cached.\n * @return {Boolean}\n */\n shouldCache: function() {\n return false;\n },\n\n /**\n * Check if this group or its parent group are caching, recursively up\n * @return {Boolean}\n */\n isOnACache: function() {\n return false;\n },\n\n /**\n * Renders controls and borders for the object\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Object} [styleOverride] properties to override the object style\n * @param {Object} [childrenOverride] properties to override the children overrides\n */\n _renderControls: function(ctx, styleOverride, childrenOverride) {\n ctx.save();\n ctx.globalAlpha = this.isMoving ? this.borderOpacityWhenMoving : 1;\n this.callSuper('_renderControls', ctx, styleOverride);\n childrenOverride = childrenOverride || { };\n if (typeof childrenOverride.hasControls === 'undefined') {\n childrenOverride.hasControls = false;\n }\n childrenOverride.forActiveSelection = true;\n for (var i = 0, len = this._objects.length; i < len; i++) {\n this._objects[i]._renderControls(ctx, childrenOverride);\n }\n ctx.restore();\n },\n });\n\n /**\n * Returns {@link fabric.ActiveSelection} instance from an object representation\n * @static\n * @memberOf fabric.ActiveSelection\n * @param {Object} object Object to create a group from\n * @param {Function} [callback] Callback to invoke when an ActiveSelection instance is created\n */\n fabric.ActiveSelection.fromObject = function(object, callback) {\n fabric.util.enlivenObjects(object.objects, function(enlivenedObjects) {\n delete object.objects;\n callback && callback(new fabric.ActiveSelection(enlivenedObjects, object, true));\n });\n };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var extend = fabric.util.object.extend;\n\n if (!global.fabric) {\n global.fabric = { };\n }\n\n if (global.fabric.Image) {\n fabric.warn('fabric.Image is already defined.');\n return;\n }\n\n /**\n * Image class\n * @class fabric.Image\n * @extends fabric.Object\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#images}\n * @see {@link fabric.Image#initialize} for constructor definition\n */\n fabric.Image = fabric.util.createClass(fabric.Object, /** @lends fabric.Image.prototype */ {\n\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'image',\n\n /**\n * Width of a stroke.\n * For image quality a stroke multiple of 2 gives better results.\n * @type Number\n * @default\n */\n strokeWidth: 0,\n\n /**\n * When calling {@link fabric.Image.getSrc}, return value from element src with `element.getAttribute('src')`.\n * This allows for relative urls as image src.\n * @since 2.7.0\n * @type Boolean\n * @default\n */\n srcFromAttribute: false,\n\n /**\n * private\n * contains last value of scaleX to detect\n * if the Image got resized after the last Render\n * @type Number\n */\n _lastScaleX: 1,\n\n /**\n * private\n * contains last value of scaleY to detect\n * if the Image got resized after the last Render\n * @type Number\n */\n _lastScaleY: 1,\n\n /**\n * private\n * contains last value of scaling applied by the apply filter chain\n * @type Number\n */\n _filterScalingX: 1,\n\n /**\n * private\n * contains last value of scaling applied by the apply filter chain\n * @type Number\n */\n _filterScalingY: 1,\n\n /**\n * minimum scale factor under which any resizeFilter is triggered to resize the image\n * 0 will disable the automatic resize. 1 will trigger automatically always.\n * number bigger than 1 are not implemented yet.\n * @type Number\n */\n minimumScaleTrigger: 0.5,\n\n /**\n * List of properties to consider when checking if\n * state of an object is changed ({@link fabric.Object#hasStateChanged})\n * as well as for history (undo/redo) purposes\n * @type Array\n */\n stateProperties: fabric.Object.prototype.stateProperties.concat('cropX', 'cropY'),\n\n /**\n * key used to retrieve the texture representing this image\n * @since 2.0.0\n * @type String\n * @default\n */\n cacheKey: '',\n\n /**\n * Image crop in pixels from original image size.\n * @since 2.0.0\n * @type Number\n * @default\n */\n cropX: 0,\n\n /**\n * Image crop in pixels from original image size.\n * @since 2.0.0\n * @type Number\n * @default\n */\n cropY: 0,\n\n /**\n * Indicates whether this canvas will use image smoothing when painting this image.\n * Also influence if the cacheCanvas for this image uses imageSmoothing\n * @since 4.0.0-beta.11\n * @type Boolean\n * @default\n */\n imageSmoothing: true,\n\n /**\n * Constructor\n * @param {HTMLImageElement | String} element Image element\n * @param {Object} [options] Options object\n * @param {function} [callback] callback function to call after eventual filters applied.\n * @return {fabric.Image} thisArg\n */\n initialize: function(element, options) {\n options || (options = { });\n this.filters = [];\n this.cacheKey = 'texture' + fabric.Object.__uid++;\n this.callSuper('initialize', options);\n this._initElement(element, options);\n },\n\n /**\n * Returns image element which this instance if based on\n * @return {HTMLImageElement} Image element\n */\n getElement: function() {\n return this._element || {};\n },\n\n /**\n * Sets image element for this instance to a specified one.\n * If filters defined they are applied to new image.\n * You might need to call `canvas.renderAll` and `object.setCoords` after replacing, to render new image and update controls area.\n * @param {HTMLImageElement} element\n * @param {Object} [options] Options object\n * @return {fabric.Image} thisArg\n * @chainable\n */\n setElement: function(element, options) {\n this.removeTexture(this.cacheKey);\n this.removeTexture(this.cacheKey + '_filtered');\n this._element = element;\n this._originalElement = element;\n this._initConfig(options);\n if (this.filters.length !== 0) {\n this.applyFilters();\n }\n // resizeFilters work on the already filtered copy.\n // we need to apply resizeFilters AFTER normal filters.\n // applyResizeFilters is run more often than normal fiters\n // and is triggered by user interactions rather than dev code\n if (this.resizeFilter) {\n this.applyResizeFilters();\n }\n return this;\n },\n\n /**\n * Delete a single texture if in webgl mode\n */\n removeTexture: function(key) {\n var backend = fabric.filterBackend;\n if (backend && backend.evictCachesForKey) {\n backend.evictCachesForKey(key);\n }\n },\n\n /**\n * Delete textures, reference to elements and eventually JSDOM cleanup\n */\n dispose: function() {\n this.removeTexture(this.cacheKey);\n this.removeTexture(this.cacheKey + '_filtered');\n this._cacheContext = undefined;\n ['_originalElement', '_element', '_filteredEl', '_cacheCanvas'].forEach((function(element) {\n fabric.util.cleanUpJsdomNode(this[element]);\n this[element] = undefined;\n }).bind(this));\n },\n\n /**\n * Get the crossOrigin value (of the corresponding image element)\n */\n getCrossOrigin: function() {\n return this._originalElement && (this._originalElement.crossOrigin || null);\n },\n\n /**\n * Returns original size of an image\n * @return {Object} Object with \"width\" and \"height\" properties\n */\n getOriginalSize: function() {\n var element = this.getElement();\n return {\n width: element.naturalWidth || element.width,\n height: element.naturalHeight || element.height\n };\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _stroke: function(ctx) {\n if (!this.stroke || this.strokeWidth === 0) {\n return;\n }\n var w = this.width / 2, h = this.height / 2;\n ctx.beginPath();\n ctx.moveTo(-w, -h);\n ctx.lineTo(w, -h);\n ctx.lineTo(w, h);\n ctx.lineTo(-w, h);\n ctx.lineTo(-w, -h);\n ctx.closePath();\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderDashedStroke: function(ctx) {\n var x = -this.width / 2,\n y = -this.height / 2,\n w = this.width,\n h = this.height;\n\n ctx.save();\n this._setStrokeStyles(ctx, this);\n\n ctx.beginPath();\n fabric.util.drawDashedLine(ctx, x, y, x + w, y, this.strokeDashArray);\n fabric.util.drawDashedLine(ctx, x + w, y, x + w, y + h, this.strokeDashArray);\n fabric.util.drawDashedLine(ctx, x + w, y + h, x, y + h, this.strokeDashArray);\n fabric.util.drawDashedLine(ctx, x, y + h, x, y, this.strokeDashArray);\n ctx.closePath();\n ctx.restore();\n },\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} Object representation of an instance\n */\n toObject: function(propertiesToInclude) {\n var filters = [];\n\n this.filters.forEach(function(filterObj) {\n if (filterObj) {\n filters.push(filterObj.toObject());\n }\n });\n var object = extend(\n this.callSuper(\n 'toObject',\n ['cropX', 'cropY'].concat(propertiesToInclude)\n ), {\n src: this.getSrc(),\n crossOrigin: this.getCrossOrigin(),\n filters: filters,\n });\n if (this.resizeFilter) {\n object.resizeFilter = this.resizeFilter.toObject();\n }\n return object;\n },\n\n /**\n * Returns true if an image has crop applied, inspecting values of cropX,cropY,width,hight.\n * @return {Boolean}\n */\n hasCrop: function() {\n return this.cropX || this.cropY || this.width < this._element.width || this.height < this._element.height;\n },\n\n /* _TO_SVG_START_ */\n /**\n * Returns svg representation of an instance\n * @return {Array} an array of strings with the specific svg representation\n * of the instance\n */\n _toSVG: function() {\n var svgString = [], imageMarkup = [], strokeSvg, element = this._element,\n x = -this.width / 2, y = -this.height / 2, clipPath = '', imageRendering = '';\n if (!element) {\n return [];\n }\n if (this.hasCrop()) {\n var clipPathId = fabric.Object.__uid++;\n svgString.push(\n '<clipPath id=\"imageCrop_' + clipPathId + '\">\\n',\n '\\t<rect x=\"' + x + '\" y=\"' + y + '\" width=\"' + this.width + '\" height=\"' + this.height + '\" />\\n',\n '</clipPath>\\n'\n );\n clipPath = ' clip-path=\"url(#imageCrop_' + clipPathId + ')\" ';\n }\n if (!this.imageSmoothing) {\n imageRendering = '\" image-rendering=\"optimizeSpeed';\n }\n imageMarkup.push('\\t<image ', 'COMMON_PARTS', 'xlink:href=\"', this.getSvgSrc(true),\n '\" x=\"', x - this.cropX, '\" y=\"', y - this.cropY,\n // we're essentially moving origin of transformation from top/left corner to the center of the shape\n // by wrapping it in container <g> element with actual transformation, then offsetting object to the top/left\n // so that object's center aligns with container's left/top\n '\" width=\"', element.width || element.naturalWidth,\n '\" height=\"', element.height || element.height,\n imageRendering,\n '\"', clipPath,\n '></image>\\n');\n\n if (this.stroke || this.strokeDashArray) {\n var origFill = this.fill;\n this.fill = null;\n strokeSvg = [\n '\\t<rect ',\n 'x=\"', x, '\" y=\"', y,\n '\" width=\"', this.width, '\" height=\"', this.height,\n '\" style=\"', this.getSvgStyles(),\n '\"/>\\n'\n ];\n this.fill = origFill;\n }\n if (this.paintFirst !== 'fill') {\n svgString = svgString.concat(strokeSvg, imageMarkup);\n }\n else {\n svgString = svgString.concat(imageMarkup, strokeSvg);\n }\n return svgString;\n },\n /* _TO_SVG_END_ */\n\n /**\n * Returns source of an image\n * @param {Boolean} filtered indicates if the src is needed for svg\n * @return {String} Source of an image\n */\n getSrc: function(filtered) {\n var element = filtered ? this._element : this._originalElement;\n if (element) {\n if (element.toDataURL) {\n return element.toDataURL();\n }\n\n if (this.srcFromAttribute) {\n return element.getAttribute('src');\n }\n else {\n return element.src;\n }\n }\n else {\n return this.src || '';\n }\n },\n\n /**\n * Sets source of an image\n * @param {String} src Source string (URL)\n * @param {Function} [callback] Callback is invoked when image has been loaded (and all filters have been applied)\n * @param {Object} [options] Options object\n * @param {String} [options.crossOrigin] crossOrigin value (one of \"\", \"anonymous\", \"use-credentials\")\n * @see https://developer.mozilla.org/en-US/docs/HTML/CORS_settings_attributes\n * @return {fabric.Image} thisArg\n * @chainable\n */\n setSrc: function(src, callback, options) {\n fabric.util.loadImage(src, function(img, isError) {\n this.setElement(img, options);\n this._setWidthHeight();\n callback && callback(this, isError);\n }, this, options && options.crossOrigin);\n return this;\n },\n\n /**\n * Returns string representation of an instance\n * @return {String} String representation of an instance\n */\n toString: function() {\n return '#<fabric.Image: { src: \"' + this.getSrc() + '\" }>';\n },\n\n applyResizeFilters: function() {\n var filter = this.resizeFilter,\n minimumScale = this.minimumScaleTrigger,\n objectScale = this.getTotalObjectScaling(),\n scaleX = objectScale.scaleX,\n scaleY = objectScale.scaleY,\n elementToFilter = this._filteredEl || this._originalElement;\n if (this.group) {\n this.set('dirty', true);\n }\n if (!filter || (scaleX > minimumScale && scaleY > minimumScale)) {\n this._element = elementToFilter;\n this._filterScalingX = 1;\n this._filterScalingY = 1;\n this._lastScaleX = scaleX;\n this._lastScaleY = scaleY;\n return;\n }\n if (!fabric.filterBackend) {\n fabric.filterBackend = fabric.initFilterBackend();\n }\n var canvasEl = fabric.util.createCanvasElement(),\n cacheKey = this._filteredEl ? (this.cacheKey + '_filtered') : this.cacheKey,\n sourceWidth = elementToFilter.width, sourceHeight = elementToFilter.height;\n canvasEl.width = sourceWidth;\n canvasEl.height = sourceHeight;\n this._element = canvasEl;\n this._lastScaleX = filter.scaleX = scaleX;\n this._lastScaleY = filter.scaleY = scaleY;\n fabric.filterBackend.applyFilters(\n [filter], elementToFilter, sourceWidth, sourceHeight, this._element, cacheKey);\n this._filterScalingX = canvasEl.width / this._originalElement.width;\n this._filterScalingY = canvasEl.height / this._originalElement.height;\n },\n\n /**\n * Applies filters assigned to this image (from \"filters\" array) or from filter param\n * @method applyFilters\n * @param {Array} filters to be applied\n * @param {Boolean} forResizing specify if the filter operation is a resize operation\n * @return {thisArg} return the fabric.Image object\n * @chainable\n */\n applyFilters: function(filters) {\n\n filters = filters || this.filters || [];\n filters = filters.filter(function(filter) { return filter && !filter.isNeutralState(); });\n this.set('dirty', true);\n\n // needs to clear out or WEBGL will not resize correctly\n this.removeTexture(this.cacheKey + '_filtered');\n\n if (filters.length === 0) {\n this._element = this._originalElement;\n this._filteredEl = null;\n this._filterScalingX = 1;\n this._filterScalingY = 1;\n return this;\n }\n\n var imgElement = this._originalElement,\n sourceWidth = imgElement.naturalWidth || imgElement.width,\n sourceHeight = imgElement.naturalHeight || imgElement.height;\n\n if (this._element === this._originalElement) {\n // if the element is the same we need to create a new element\n var canvasEl = fabric.util.createCanvasElement();\n canvasEl.width = sourceWidth;\n canvasEl.height = sourceHeight;\n this._element = canvasEl;\n this._filteredEl = canvasEl;\n }\n else {\n // clear the existing element to get new filter data\n // also dereference the eventual resized _element\n this._element = this._filteredEl;\n this._filteredEl.getContext('2d').clearRect(0, 0, sourceWidth, sourceHeight);\n // we also need to resize again at next renderAll, so remove saved _lastScaleX/Y\n this._lastScaleX = 1;\n this._lastScaleY = 1;\n }\n if (!fabric.filterBackend) {\n fabric.filterBackend = fabric.initFilterBackend();\n }\n fabric.filterBackend.applyFilters(\n filters, this._originalElement, sourceWidth, sourceHeight, this._element, this.cacheKey);\n if (this._originalElement.width !== this._element.width ||\n this._originalElement.height !== this._element.height) {\n this._filterScalingX = this._element.width / this._originalElement.width;\n this._filterScalingY = this._element.height / this._originalElement.height;\n }\n return this;\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _render: function(ctx) {\n fabric.util.setImageSmoothing(ctx, this.imageSmoothing);\n if (this.isMoving !== true && this.resizeFilter && this._needsResize()) {\n this.applyResizeFilters();\n }\n this._stroke(ctx);\n this._renderPaintInOrder(ctx);\n },\n\n /**\n * Paint the cached copy of the object on the target context.\n * it will set the imageSmoothing for the draw operation\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n drawCacheOnCanvas: function(ctx) {\n fabric.util.setImageSmoothing(ctx, this.imageSmoothing);\n fabric.Object.prototype.drawCacheOnCanvas.call(this, ctx);\n },\n\n /**\n * Decide if the object should cache or not. Create its own cache level\n * needsItsOwnCache should be used when the object drawing method requires\n * a cache step. None of the fabric classes requires it.\n * Generally you do not cache objects in groups because the group outside is cached.\n * This is the special image version where we would like to avoid caching where possible.\n * Essentially images do not benefit from caching. They may require caching, and in that\n * case we do it. Also caching an image usually ends in a loss of details.\n * A full performance audit should be done.\n * @return {Boolean}\n */\n shouldCache: function() {\n return this.needsItsOwnCache();\n },\n\n _renderFill: function(ctx) {\n var elementToDraw = this._element;\n if (!elementToDraw) {\n return;\n }\n var scaleX = this._filterScalingX, scaleY = this._filterScalingY,\n w = this.width, h = this.height, min = Math.min, max = Math.max,\n // crop values cannot be lesser than 0.\n cropX = max(this.cropX, 0), cropY = max(this.cropY, 0),\n elWidth = elementToDraw.naturalWidth || elementToDraw.width,\n elHeight = elementToDraw.naturalHeight || elementToDraw.height,\n sX = cropX * scaleX,\n sY = cropY * scaleY,\n // the width height cannot exceed element width/height, starting from the crop offset.\n sW = min(w * scaleX, elWidth - sX),\n sH = min(h * scaleY, elHeight - sY),\n x = -w / 2, y = -h / 2,\n maxDestW = min(w, elWidth / scaleX - cropX),\n maxDestH = min(h, elHeight / scaleX - cropY);\n\n elementToDraw && ctx.drawImage(elementToDraw, sX, sY, sW, sH, x, y, maxDestW, maxDestH);\n },\n\n /**\n * needed to check if image needs resize\n * @private\n */\n _needsResize: function() {\n var scale = this.getTotalObjectScaling();\n return (scale.scaleX !== this._lastScaleX || scale.scaleY !== this._lastScaleY);\n },\n\n /**\n * @private\n */\n _resetWidthHeight: function() {\n this.set(this.getOriginalSize());\n },\n\n /**\n * The Image class's initialization method. This method is automatically\n * called by the constructor.\n * @private\n * @param {HTMLImageElement|String} element The element representing the image\n * @param {Object} [options] Options object\n */\n _initElement: function(element, options) {\n this.setElement(fabric.util.getById(element), options);\n fabric.util.addClass(this.getElement(), fabric.Image.CSS_CANVAS);\n },\n\n /**\n * @private\n * @param {Object} [options] Options object\n */\n _initConfig: function(options) {\n options || (options = { });\n this.setOptions(options);\n this._setWidthHeight(options);\n },\n\n /**\n * @private\n * @param {Array} filters to be initialized\n * @param {Function} callback Callback to invoke when all fabric.Image.filters instances are created\n */\n _initFilters: function(filters, callback) {\n if (filters && filters.length) {\n fabric.util.enlivenObjects(filters, function(enlivenedObjects) {\n callback && callback(enlivenedObjects);\n }, 'fabric.Image.filters');\n }\n else {\n callback && callback();\n }\n },\n\n /**\n * @private\n * Set the width and the height of the image object, using the element or the\n * options.\n * @param {Object} [options] Object with width/height properties\n */\n _setWidthHeight: function(options) {\n options || (options = { });\n var el = this.getElement();\n this.width = options.width || el.naturalWidth || el.width || 0;\n this.height = options.height || el.naturalHeight || el.height || 0;\n },\n\n /**\n * Calculate offset for center and scale factor for the image in order to respect\n * the preserveAspectRatio attribute\n * @private\n * @return {Object}\n */\n parsePreserveAspectRatioAttribute: function() {\n var pAR = fabric.util.parsePreserveAspectRatioAttribute(this.preserveAspectRatio || ''),\n rWidth = this._element.width, rHeight = this._element.height,\n scaleX = 1, scaleY = 1, offsetLeft = 0, offsetTop = 0, cropX = 0, cropY = 0,\n offset, pWidth = this.width, pHeight = this.height, parsedAttributes = { width: pWidth, height: pHeight };\n if (pAR && (pAR.alignX !== 'none' || pAR.alignY !== 'none')) {\n if (pAR.meetOrSlice === 'meet') {\n scaleX = scaleY = fabric.util.findScaleToFit(this._element, parsedAttributes);\n offset = (pWidth - rWidth * scaleX) / 2;\n if (pAR.alignX === 'Min') {\n offsetLeft = -offset;\n }\n if (pAR.alignX === 'Max') {\n offsetLeft = offset;\n }\n offset = (pHeight - rHeight * scaleY) / 2;\n if (pAR.alignY === 'Min') {\n offsetTop = -offset;\n }\n if (pAR.alignY === 'Max') {\n offsetTop = offset;\n }\n }\n if (pAR.meetOrSlice === 'slice') {\n scaleX = scaleY = fabric.util.findScaleToCover(this._element, parsedAttributes);\n offset = rWidth - pWidth / scaleX;\n if (pAR.alignX === 'Mid') {\n cropX = offset / 2;\n }\n if (pAR.alignX === 'Max') {\n cropX = offset;\n }\n offset = rHeight - pHeight / scaleY;\n if (pAR.alignY === 'Mid') {\n cropY = offset / 2;\n }\n if (pAR.alignY === 'Max') {\n cropY = offset;\n }\n rWidth = pWidth / scaleX;\n rHeight = pHeight / scaleY;\n }\n }\n else {\n scaleX = pWidth / rWidth;\n scaleY = pHeight / rHeight;\n }\n return {\n width: rWidth,\n height: rHeight,\n scaleX: scaleX,\n scaleY: scaleY,\n offsetLeft: offsetLeft,\n offsetTop: offsetTop,\n cropX: cropX,\n cropY: cropY\n };\n }\n });\n\n /**\n * Default CSS class name for canvas\n * @static\n * @type String\n * @default\n */\n fabric.Image.CSS_CANVAS = 'canvas-img';\n\n /**\n * Alias for getSrc\n * @static\n */\n fabric.Image.prototype.getSvgSrc = fabric.Image.prototype.getSrc;\n\n /**\n * Creates an instance of fabric.Image from its object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {Function} callback Callback to invoke when an image instance is created\n */\n fabric.Image.fromObject = function(_object, callback) {\n var object = fabric.util.object.clone(_object);\n fabric.util.loadImage(object.src, function(img, isError) {\n if (isError) {\n callback && callback(null, true);\n return;\n }\n fabric.Image.prototype._initFilters.call(object, object.filters, function(filters) {\n object.filters = filters || [];\n fabric.Image.prototype._initFilters.call(object, [object.resizeFilter], function(resizeFilters) {\n object.resizeFilter = resizeFilters[0];\n fabric.util.enlivenObjects([object.clipPath], function(enlivedProps) {\n object.clipPath = enlivedProps[0];\n var image = new fabric.Image(img, object);\n callback(image, false);\n });\n });\n });\n }, null, object.crossOrigin);\n };\n\n /**\n * Creates an instance of fabric.Image from an URL string\n * @static\n * @param {String} url URL to create an image from\n * @param {Function} [callback] Callback to invoke when image is created (newly created image is passed as a first argument). Second argument is a boolean indicating if an error occured or not.\n * @param {Object} [imgOptions] Options object\n */\n fabric.Image.fromURL = function(url, callback, imgOptions) {\n fabric.util.loadImage(url, function(img, isError) {\n callback && callback(new fabric.Image(img, imgOptions), isError);\n }, null, imgOptions && imgOptions.crossOrigin);\n };\n\n /* _FROM_SVG_START_ */\n /**\n * List of attribute names to account for when parsing SVG element (used by {@link fabric.Image.fromElement})\n * @static\n * @see {@link http://www.w3.org/TR/SVG/struct.html#ImageElement}\n */\n fabric.Image.ATTRIBUTE_NAMES =\n fabric.SHARED_ATTRIBUTES.concat(\n 'x y width height preserveAspectRatio xlink:href crossOrigin image-rendering'.split(' ')\n );\n\n /**\n * Returns {@link fabric.Image} instance from an SVG element\n * @static\n * @param {SVGElement} element Element to parse\n * @param {Object} [options] Options object\n * @param {Function} callback Callback to execute when fabric.Image object is created\n * @return {fabric.Image} Instance of fabric.Image\n */\n fabric.Image.fromElement = function(element, callback, options) {\n var parsedAttributes = fabric.parseAttributes(element, fabric.Image.ATTRIBUTE_NAMES);\n fabric.Image.fromURL(parsedAttributes['xlink:href'], callback,\n extend((options ? fabric.util.object.clone(options) : { }), parsedAttributes));\n };\n /* _FROM_SVG_END_ */\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\nfabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ {\n\n /**\n * @private\n * @return {Number} angle value\n */\n _getAngleValueForStraighten: function() {\n var angle = this.angle % 360;\n if (angle > 0) {\n return Math.round((angle - 1) / 90) * 90;\n }\n return Math.round(angle / 90) * 90;\n },\n\n /**\n * Straightens an object (rotating it from current angle to one of 0, 90, 180, 270, etc. depending on which is closer)\n * @return {fabric.Object} thisArg\n * @chainable\n */\n straighten: function() {\n this.rotate(this._getAngleValueForStraighten());\n return this;\n },\n\n /**\n * Same as {@link fabric.Object.prototype.straighten} but with animation\n * @param {Object} callbacks Object with callback functions\n * @param {Function} [callbacks.onComplete] Invoked on completion\n * @param {Function} [callbacks.onChange] Invoked on every step of animation\n * @return {fabric.Object} thisArg\n * @chainable\n */\n fxStraighten: function(callbacks) {\n callbacks = callbacks || { };\n\n var empty = function() { },\n onComplete = callbacks.onComplete || empty,\n onChange = callbacks.onChange || empty,\n _this = this;\n\n fabric.util.animate({\n startValue: this.get('angle'),\n endValue: this._getAngleValueForStraighten(),\n duration: this.FX_DURATION,\n onChange: function(value) {\n _this.rotate(value);\n onChange();\n },\n onComplete: function() {\n _this.setCoords();\n onComplete();\n },\n });\n\n return this;\n }\n});\n\nfabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.StaticCanvas.prototype */ {\n\n /**\n * Straightens object, then rerenders canvas\n * @param {fabric.Object} object Object to straighten\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n straightenObject: function (object) {\n object.straighten();\n this.requestRenderAll();\n return this;\n },\n\n /**\n * Same as {@link fabric.Canvas.prototype.straightenObject}, but animated\n * @param {fabric.Object} object Object to straighten\n * @return {fabric.Canvas} thisArg\n * @chainable\n */\n fxStraightenObject: function (object) {\n object.fxStraighten({\n onChange: this.requestRenderAllBound\n });\n return this;\n }\n});\n\n\n(function() {\n\n 'use strict';\n\n /**\n * Tests if webgl supports certain precision\n * @param {WebGL} Canvas WebGL context to test on\n * @param {String} Precision to test can be any of following: 'lowp', 'mediump', 'highp'\n * @returns {Boolean} Whether the user's browser WebGL supports given precision.\n */\n function testPrecision(gl, precision){\n var fragmentSource = 'precision ' + precision + ' float;\\nvoid main(){}';\n var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);\n gl.shaderSource(fragmentShader, fragmentSource);\n gl.compileShader(fragmentShader);\n if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {\n return false;\n }\n return true;\n }\n\n /**\n * Indicate whether this filtering backend is supported by the user's browser.\n * @param {Number} tileSize check if the tileSize is supported\n * @returns {Boolean} Whether the user's browser supports WebGL.\n */\n fabric.isWebglSupported = function(tileSize) {\n if (fabric.isLikelyNode) {\n return false;\n }\n tileSize = tileSize || fabric.WebglFilterBackend.prototype.tileSize;\n var canvas = document.createElement('canvas');\n var gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');\n var isSupported = false;\n // eslint-disable-next-line\n if (gl) {\n fabric.maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE);\n isSupported = fabric.maxTextureSize >= tileSize;\n var precisions = ['highp', 'mediump', 'lowp'];\n for (var i = 0; i < 3; i++){\n if (testPrecision(gl, precisions[i])){\n fabric.webGlPrecision = precisions[i];\n break;\n };\n }\n }\n this.isSupported = isSupported;\n return isSupported;\n };\n\n fabric.WebglFilterBackend = WebglFilterBackend;\n\n /**\n * WebGL filter backend.\n */\n function WebglFilterBackend(options) {\n if (options && options.tileSize) {\n this.tileSize = options.tileSize;\n }\n this.setupGLContext(this.tileSize, this.tileSize);\n this.captureGPUInfo();\n };\n\n WebglFilterBackend.prototype = /** @lends fabric.WebglFilterBackend.prototype */ {\n\n tileSize: 2048,\n\n /**\n * Experimental. This object is a sort of repository of help layers used to avoid\n * of recreating them during frequent filtering. If you are previewing a filter with\n * a slider you problably do not want to create help layers every filter step.\n * in this object there will be appended some canvases, created once, resized sometimes\n * cleared never. Clearing is left to the developer.\n **/\n resources: {\n\n },\n\n /**\n * Setup a WebGL context suitable for filtering, and bind any needed event handlers.\n */\n setupGLContext: function(width, height) {\n this.dispose();\n this.createWebGLCanvas(width, height);\n // eslint-disable-next-line\n this.aPosition = new Float32Array([0, 0, 0, 1, 1, 0, 1, 1]);\n this.chooseFastestCopyGLTo2DMethod(width, height);\n },\n\n /**\n * Pick a method to copy data from GL context to 2d canvas. In some browsers using\n * putImageData is faster than drawImage for that specific operation.\n */\n chooseFastestCopyGLTo2DMethod: function(width, height) {\n var canMeasurePerf = typeof window.performance !== 'undefined', canUseImageData;\n try {\n new ImageData(1, 1);\n canUseImageData = true;\n }\n catch (e) {\n canUseImageData = false;\n }\n // eslint-disable-next-line no-undef\n var canUseArrayBuffer = typeof ArrayBuffer !== 'undefined';\n // eslint-disable-next-line no-undef\n var canUseUint8Clamped = typeof Uint8ClampedArray !== 'undefined';\n\n if (!(canMeasurePerf && canUseImageData && canUseArrayBuffer && canUseUint8Clamped)) {\n return;\n }\n\n var targetCanvas = fabric.util.createCanvasElement();\n // eslint-disable-next-line no-undef\n var imageBuffer = new ArrayBuffer(width * height * 4);\n if (fabric.forceGLPutImageData) {\n this.imageBuffer = imageBuffer;\n this.copyGLTo2D = copyGLTo2DPutImageData;\n return;\n }\n var testContext = {\n imageBuffer: imageBuffer,\n destinationWidth: width,\n destinationHeight: height,\n targetCanvas: targetCanvas\n };\n var startTime, drawImageTime, putImageDataTime;\n targetCanvas.width = width;\n targetCanvas.height = height;\n\n startTime = window.performance.now();\n copyGLTo2DDrawImage.call(testContext, this.gl, testContext);\n drawImageTime = window.performance.now() - startTime;\n\n startTime = window.performance.now();\n copyGLTo2DPutImageData.call(testContext, this.gl, testContext);\n putImageDataTime = window.performance.now() - startTime;\n\n if (drawImageTime > putImageDataTime) {\n this.imageBuffer = imageBuffer;\n this.copyGLTo2D = copyGLTo2DPutImageData;\n }\n else {\n this.copyGLTo2D = copyGLTo2DDrawImage;\n }\n },\n\n /**\n * Create a canvas element and associated WebGL context and attaches them as\n * class properties to the GLFilterBackend class.\n */\n createWebGLCanvas: function(width, height) {\n var canvas = fabric.util.createCanvasElement();\n canvas.width = width;\n canvas.height = height;\n var glOptions = {\n alpha: true,\n premultipliedAlpha: false,\n depth: false,\n stencil: false,\n antialias: false\n },\n gl = canvas.getContext('webgl', glOptions);\n if (!gl) {\n gl = canvas.getContext('experimental-webgl', glOptions);\n }\n if (!gl) {\n return;\n }\n gl.clearColor(0, 0, 0, 0);\n // this canvas can fire webglcontextlost and webglcontextrestored\n this.canvas = canvas;\n this.gl = gl;\n },\n\n /**\n * Attempts to apply the requested filters to the source provided, drawing the filtered output\n * to the provided target canvas.\n *\n * @param {Array} filters The filters to apply.\n * @param {HTMLImageElement|HTMLCanvasElement} source The source to be filtered.\n * @param {Number} width The width of the source input.\n * @param {Number} height The height of the source input.\n * @param {HTMLCanvasElement} targetCanvas The destination for filtered output to be drawn.\n * @param {String|undefined} cacheKey A key used to cache resources related to the source. If\n * omitted, caching will be skipped.\n */\n applyFilters: function(filters, source, width, height, targetCanvas, cacheKey) {\n var gl = this.gl;\n var cachedTexture;\n if (cacheKey) {\n cachedTexture = this.getCachedTexture(cacheKey, source);\n }\n var pipelineState = {\n originalWidth: source.width || source.originalWidth,\n originalHeight: source.height || source.originalHeight,\n sourceWidth: width,\n sourceHeight: height,\n destinationWidth: width,\n destinationHeight: height,\n context: gl,\n sourceTexture: this.createTexture(gl, width, height, !cachedTexture && source),\n targetTexture: this.createTexture(gl, width, height),\n originalTexture: cachedTexture ||\n this.createTexture(gl, width, height, !cachedTexture && source),\n passes: filters.length,\n webgl: true,\n aPosition: this.aPosition,\n programCache: this.programCache,\n pass: 0,\n filterBackend: this,\n targetCanvas: targetCanvas\n };\n var tempFbo = gl.createFramebuffer();\n gl.bindFramebuffer(gl.FRAMEBUFFER, tempFbo);\n filters.forEach(function(filter) { filter && filter.applyTo(pipelineState); });\n resizeCanvasIfNeeded(pipelineState);\n this.copyGLTo2D(gl, pipelineState);\n gl.bindTexture(gl.TEXTURE_2D, null);\n gl.deleteTexture(pipelineState.sourceTexture);\n gl.deleteTexture(pipelineState.targetTexture);\n gl.deleteFramebuffer(tempFbo);\n targetCanvas.getContext('2d').setTransform(1, 0, 0, 1, 0, 0);\n return pipelineState;\n },\n\n /**\n * Detach event listeners, remove references, and clean up caches.\n */\n dispose: function() {\n if (this.canvas) {\n this.canvas = null;\n this.gl = null;\n }\n this.clearWebGLCaches();\n },\n\n /**\n * Wipe out WebGL-related caches.\n */\n clearWebGLCaches: function() {\n this.programCache = {};\n this.textureCache = {};\n },\n\n /**\n * Create a WebGL texture object.\n *\n * Accepts specific dimensions to initialize the textuer to or a source image.\n *\n * @param {WebGLRenderingContext} gl The GL context to use for creating the texture.\n * @param {Number} width The width to initialize the texture at.\n * @param {Number} height The height to initialize the texture.\n * @param {HTMLImageElement|HTMLCanvasElement} textureImageSource A source for the texture data.\n * @returns {WebGLTexture}\n */\n createTexture: function(gl, width, height, textureImageSource) {\n var texture = gl.createTexture();\n gl.bindTexture(gl.TEXTURE_2D, texture);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n if (textureImageSource) {\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, textureImageSource);\n }\n else {\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);\n }\n return texture;\n },\n\n /**\n * Can be optionally used to get a texture from the cache array\n *\n * If an existing texture is not found, a new texture is created and cached.\n *\n * @param {String} uniqueId A cache key to use to find an existing texture.\n * @param {HTMLImageElement|HTMLCanvasElement} textureImageSource A source to use to create the\n * texture cache entry if one does not already exist.\n */\n getCachedTexture: function(uniqueId, textureImageSource) {\n if (this.textureCache[uniqueId]) {\n return this.textureCache[uniqueId];\n }\n else {\n var texture = this.createTexture(\n this.gl, textureImageSource.width, textureImageSource.height, textureImageSource);\n this.textureCache[uniqueId] = texture;\n return texture;\n }\n },\n\n /**\n * Clear out cached resources related to a source image that has been\n * filtered previously.\n *\n * @param {String} cacheKey The cache key provided when the source image was filtered.\n */\n evictCachesForKey: function(cacheKey) {\n if (this.textureCache[cacheKey]) {\n this.gl.deleteTexture(this.textureCache[cacheKey]);\n delete this.textureCache[cacheKey];\n }\n },\n\n copyGLTo2D: copyGLTo2DDrawImage,\n\n /**\n * Attempt to extract GPU information strings from a WebGL context.\n *\n * Useful information when debugging or blacklisting specific GPUs.\n *\n * @returns {Object} A GPU info object with renderer and vendor strings.\n */\n captureGPUInfo: function() {\n if (this.gpuInfo) {\n return this.gpuInfo;\n }\n var gl = this.gl, gpuInfo = { renderer: '', vendor: '' };\n if (!gl) {\n return gpuInfo;\n }\n var ext = gl.getExtension('WEBGL_debug_renderer_info');\n if (ext) {\n var renderer = gl.getParameter(ext.UNMASKED_RENDERER_WEBGL);\n var vendor = gl.getParameter(ext.UNMASKED_VENDOR_WEBGL);\n if (renderer) {\n gpuInfo.renderer = renderer.toLowerCase();\n }\n if (vendor) {\n gpuInfo.vendor = vendor.toLowerCase();\n }\n }\n this.gpuInfo = gpuInfo;\n return gpuInfo;\n },\n };\n})();\n\nfunction resizeCanvasIfNeeded(pipelineState) {\n var targetCanvas = pipelineState.targetCanvas,\n width = targetCanvas.width, height = targetCanvas.height,\n dWidth = pipelineState.destinationWidth,\n dHeight = pipelineState.destinationHeight;\n\n if (width !== dWidth || height !== dHeight) {\n targetCanvas.width = dWidth;\n targetCanvas.height = dHeight;\n }\n}\n\n/**\n * Copy an input WebGL canvas on to an output 2D canvas.\n *\n * The WebGL canvas is assumed to be upside down, with the top-left pixel of the\n * desired output image appearing in the bottom-left corner of the WebGL canvas.\n *\n * @param {WebGLRenderingContext} sourceContext The WebGL context to copy from.\n * @param {HTMLCanvasElement} targetCanvas The 2D target canvas to copy on to.\n * @param {Object} pipelineState The 2D target canvas to copy on to.\n */\nfunction copyGLTo2DDrawImage(gl, pipelineState) {\n var glCanvas = gl.canvas, targetCanvas = pipelineState.targetCanvas,\n ctx = targetCanvas.getContext('2d');\n ctx.translate(0, targetCanvas.height); // move it down again\n ctx.scale(1, -1); // vertical flip\n // where is my image on the big glcanvas?\n var sourceY = glCanvas.height - targetCanvas.height;\n ctx.drawImage(glCanvas, 0, sourceY, targetCanvas.width, targetCanvas.height, 0, 0,\n targetCanvas.width, targetCanvas.height);\n}\n\n/**\n * Copy an input WebGL canvas on to an output 2D canvas using 2d canvas' putImageData\n * API. Measurably faster than using ctx.drawImage in Firefox (version 54 on OSX Sierra).\n *\n * @param {WebGLRenderingContext} sourceContext The WebGL context to copy from.\n * @param {HTMLCanvasElement} targetCanvas The 2D target canvas to copy on to.\n * @param {Object} pipelineState The 2D target canvas to copy on to.\n */\nfunction copyGLTo2DPutImageData(gl, pipelineState) {\n var targetCanvas = pipelineState.targetCanvas, ctx = targetCanvas.getContext('2d'),\n dWidth = pipelineState.destinationWidth,\n dHeight = pipelineState.destinationHeight,\n numBytes = dWidth * dHeight * 4;\n\n // eslint-disable-next-line no-undef\n var u8 = new Uint8Array(this.imageBuffer, 0, numBytes);\n // eslint-disable-next-line no-undef\n var u8Clamped = new Uint8ClampedArray(this.imageBuffer, 0, numBytes);\n\n gl.readPixels(0, 0, dWidth, dHeight, gl.RGBA, gl.UNSIGNED_BYTE, u8);\n var imgData = new ImageData(u8Clamped, dWidth, dHeight);\n ctx.putImageData(imgData, 0, 0);\n}\n\n\n(function() {\n\n 'use strict';\n\n var noop = function() {};\n\n fabric.Canvas2dFilterBackend = Canvas2dFilterBackend;\n\n /**\n * Canvas 2D filter backend.\n */\n function Canvas2dFilterBackend() {};\n\n Canvas2dFilterBackend.prototype = /** @lends fabric.Canvas2dFilterBackend.prototype */ {\n evictCachesForKey: noop,\n dispose: noop,\n clearWebGLCaches: noop,\n\n /**\n * Experimental. This object is a sort of repository of help layers used to avoid\n * of recreating them during frequent filtering. If you are previewing a filter with\n * a slider you probably do not want to create help layers every filter step.\n * in this object there will be appended some canvases, created once, resized sometimes\n * cleared never. Clearing is left to the developer.\n **/\n resources: {\n\n },\n\n /**\n * Apply a set of filters against a source image and draw the filtered output\n * to the provided destination canvas.\n *\n * @param {EnhancedFilter} filters The filter to apply.\n * @param {HTMLImageElement|HTMLCanvasElement} sourceElement The source to be filtered.\n * @param {Number} sourceWidth The width of the source input.\n * @param {Number} sourceHeight The height of the source input.\n * @param {HTMLCanvasElement} targetCanvas The destination for filtered output to be drawn.\n */\n applyFilters: function(filters, sourceElement, sourceWidth, sourceHeight, targetCanvas) {\n var ctx = targetCanvas.getContext('2d');\n ctx.drawImage(sourceElement, 0, 0, sourceWidth, sourceHeight);\n var imageData = ctx.getImageData(0, 0, sourceWidth, sourceHeight);\n var originalImageData = ctx.getImageData(0, 0, sourceWidth, sourceHeight);\n var pipelineState = {\n sourceWidth: sourceWidth,\n sourceHeight: sourceHeight,\n imageData: imageData,\n originalEl: sourceElement,\n originalImageData: originalImageData,\n canvasEl: targetCanvas,\n ctx: ctx,\n filterBackend: this,\n };\n filters.forEach(function(filter) { filter.applyTo(pipelineState); });\n if (pipelineState.imageData.width !== sourceWidth || pipelineState.imageData.height !== sourceHeight) {\n targetCanvas.width = pipelineState.imageData.width;\n targetCanvas.height = pipelineState.imageData.height;\n }\n ctx.putImageData(pipelineState.imageData, 0, 0);\n return pipelineState;\n },\n\n };\n})();\n\n\n/**\n * @namespace fabric.Image.filters\n * @memberOf fabric.Image\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#image_filters}\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n */\nfabric.Image = fabric.Image || { };\nfabric.Image.filters = fabric.Image.filters || { };\n\n/**\n * Root filter class from which all filter classes inherit from\n * @class fabric.Image.filters.BaseFilter\n * @memberOf fabric.Image.filters\n */\nfabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Image.filters.BaseFilter.prototype */ {\n\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'BaseFilter',\n\n /**\n * Array of attributes to send with buffers. do not modify\n * @private\n */\n\n vertexSource: 'attribute vec2 aPosition;\\n' +\n 'varying vec2 vTexCoord;\\n' +\n 'void main() {\\n' +\n 'vTexCoord = aPosition;\\n' +\n 'gl_Position = vec4(aPosition * 2.0 - 1.0, 0.0, 1.0);\\n' +\n '}',\n\n fragmentSource: 'precision highp float;\\n' +\n 'varying vec2 vTexCoord;\\n' +\n 'uniform sampler2D uTexture;\\n' +\n 'void main() {\\n' +\n 'gl_FragColor = texture2D(uTexture, vTexCoord);\\n' +\n '}',\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n */\n initialize: function(options) {\n if (options) {\n this.setOptions(options);\n }\n },\n\n /**\n * Sets filter's properties from options\n * @param {Object} [options] Options object\n */\n setOptions: function(options) {\n for (var prop in options) {\n this[prop] = options[prop];\n }\n },\n\n /**\n * Compile this filter's shader program.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context to use for shader compilation.\n * @param {String} fragmentSource fragmentShader source for compilation\n * @param {String} vertexSource vertexShader source for compilation\n */\n createProgram: function(gl, fragmentSource, vertexSource) {\n fragmentSource = fragmentSource || this.fragmentSource;\n vertexSource = vertexSource || this.vertexSource;\n if (fabric.webGlPrecision !== 'highp'){\n fragmentSource = fragmentSource.replace(\n /precision highp float/g,\n 'precision ' + fabric.webGlPrecision + ' float'\n );\n }\n var vertexShader = gl.createShader(gl.VERTEX_SHADER);\n gl.shaderSource(vertexShader, vertexSource);\n gl.compileShader(vertexShader);\n if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {\n throw new Error(\n // eslint-disable-next-line prefer-template\n 'Vertex shader compile error for ' + this.type + ': ' +\n gl.getShaderInfoLog(vertexShader)\n );\n }\n\n var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);\n gl.shaderSource(fragmentShader, fragmentSource);\n gl.compileShader(fragmentShader);\n if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {\n throw new Error(\n // eslint-disable-next-line prefer-template\n 'Fragment shader compile error for ' + this.type + ': ' +\n gl.getShaderInfoLog(fragmentShader)\n );\n }\n\n var program = gl.createProgram();\n gl.attachShader(program, vertexShader);\n gl.attachShader(program, fragmentShader);\n gl.linkProgram(program);\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n throw new Error(\n // eslint-disable-next-line prefer-template\n 'Shader link error for \"${this.type}\" ' +\n gl.getProgramInfoLog(program)\n );\n }\n\n var attributeLocations = this.getAttributeLocations(gl, program);\n var uniformLocations = this.getUniformLocations(gl, program) || { };\n uniformLocations.uStepW = gl.getUniformLocation(program, 'uStepW');\n uniformLocations.uStepH = gl.getUniformLocation(program, 'uStepH');\n return {\n program: program,\n attributeLocations: attributeLocations,\n uniformLocations: uniformLocations\n };\n },\n\n /**\n * Return a map of attribute names to WebGLAttributeLocation objects.\n *\n * @param {WebGLRenderingContext} gl The canvas context used to compile the shader program.\n * @param {WebGLShaderProgram} program The shader program from which to take attribute locations.\n * @returns {Object} A map of attribute names to attribute locations.\n */\n getAttributeLocations: function(gl, program) {\n return {\n aPosition: gl.getAttribLocation(program, 'aPosition'),\n };\n },\n\n /**\n * Return a map of uniform names to WebGLUniformLocation objects.\n *\n * Intended to be overridden by subclasses.\n *\n * @param {WebGLRenderingContext} gl The canvas context used to compile the shader program.\n * @param {WebGLShaderProgram} program The shader program from which to take uniform locations.\n * @returns {Object} A map of uniform names to uniform locations.\n */\n getUniformLocations: function (/* gl, program */) {\n // in case i do not need any special uniform i need to return an empty object\n return { };\n },\n\n /**\n * Send attribute data from this filter to its shader program on the GPU.\n *\n * @param {WebGLRenderingContext} gl The canvas context used to compile the shader program.\n * @param {Object} attributeLocations A map of shader attribute names to their locations.\n */\n sendAttributeData: function(gl, attributeLocations, aPositionData) {\n var attributeLocation = attributeLocations.aPosition;\n var buffer = gl.createBuffer();\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer);\n gl.enableVertexAttribArray(attributeLocation);\n gl.vertexAttribPointer(attributeLocation, 2, gl.FLOAT, false, 0, 0);\n gl.bufferData(gl.ARRAY_BUFFER, aPositionData, gl.STATIC_DRAW);\n },\n\n _setupFrameBuffer: function(options) {\n var gl = options.context, width, height;\n if (options.passes > 1) {\n width = options.destinationWidth;\n height = options.destinationHeight;\n if (options.sourceWidth !== width || options.sourceHeight !== height) {\n gl.deleteTexture(options.targetTexture);\n options.targetTexture = options.filterBackend.createTexture(gl, width, height);\n }\n gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D,\n options.targetTexture, 0);\n }\n else {\n // draw last filter on canvas and not to framebuffer.\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n gl.finish();\n }\n },\n\n _swapTextures: function(options) {\n options.passes--;\n options.pass++;\n var temp = options.targetTexture;\n options.targetTexture = options.sourceTexture;\n options.sourceTexture = temp;\n },\n\n /**\n * Generic isNeutral implementation for one parameter based filters.\n * Used only in image applyFilters to discard filters that will not have an effect\n * on the image\n * Other filters may need their own verison ( ColorMatrix, HueRotation, gamma, ComposedFilter )\n * @param {Object} options\n **/\n isNeutralState: function(/* options */) {\n var main = this.mainParameter,\n _class = fabric.Image.filters[this.type].prototype;\n if (main) {\n if (Array.isArray(_class[main])) {\n for (var i = _class[main].length; i--;) {\n if (this[main][i] !== _class[main][i]) {\n return false;\n }\n }\n return true;\n }\n else {\n return _class[main] === this[main];\n }\n }\n else {\n return false;\n }\n },\n\n /**\n * Apply this filter to the input image data provided.\n *\n * Determines whether to use WebGL or Canvas2D based on the options.webgl flag.\n *\n * @param {Object} options\n * @param {Number} options.passes The number of filters remaining to be executed\n * @param {Boolean} options.webgl Whether to use webgl to render the filter.\n * @param {WebGLTexture} options.sourceTexture The texture setup as the source to be filtered.\n * @param {WebGLTexture} options.targetTexture The texture where filtered output should be drawn.\n * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n */\n applyTo: function(options) {\n if (options.webgl) {\n this._setupFrameBuffer(options);\n this.applyToWebGL(options);\n this._swapTextures(options);\n }\n else {\n this.applyTo2d(options);\n }\n },\n\n /**\n * Retrieves the cached shader.\n * @param {Object} options\n * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n */\n retrieveShader: function(options) {\n if (!options.programCache.hasOwnProperty(this.type)) {\n options.programCache[this.type] = this.createProgram(options.context);\n }\n return options.programCache[this.type];\n },\n\n /**\n * Apply this filter using webgl.\n *\n * @param {Object} options\n * @param {Number} options.passes The number of filters remaining to be executed\n * @param {Boolean} options.webgl Whether to use webgl to render the filter.\n * @param {WebGLTexture} options.originalTexture The texture of the original input image.\n * @param {WebGLTexture} options.sourceTexture The texture setup as the source to be filtered.\n * @param {WebGLTexture} options.targetTexture The texture where filtered output should be drawn.\n * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n */\n applyToWebGL: function(options) {\n var gl = options.context;\n var shader = this.retrieveShader(options);\n if (options.pass === 0 && options.originalTexture) {\n gl.bindTexture(gl.TEXTURE_2D, options.originalTexture);\n }\n else {\n gl.bindTexture(gl.TEXTURE_2D, options.sourceTexture);\n }\n gl.useProgram(shader.program);\n this.sendAttributeData(gl, shader.attributeLocations, options.aPosition);\n\n gl.uniform1f(shader.uniformLocations.uStepW, 1 / options.sourceWidth);\n gl.uniform1f(shader.uniformLocations.uStepH, 1 / options.sourceHeight);\n\n this.sendUniformData(gl, shader.uniformLocations);\n gl.viewport(0, 0, options.destinationWidth, options.destinationHeight);\n gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);\n },\n\n bindAdditionalTexture: function(gl, texture, textureUnit) {\n gl.activeTexture(textureUnit);\n gl.bindTexture(gl.TEXTURE_2D, texture);\n // reset active texture to 0 as usual\n gl.activeTexture(gl.TEXTURE0);\n },\n\n unbindAdditionalTexture: function(gl, textureUnit) {\n gl.activeTexture(textureUnit);\n gl.bindTexture(gl.TEXTURE_2D, null);\n gl.activeTexture(gl.TEXTURE0);\n },\n\n getMainParameter: function() {\n return this[this.mainParameter];\n },\n\n setMainParameter: function(value) {\n this[this.mainParameter] = value;\n },\n\n /**\n * Send uniform data from this filter to its shader program on the GPU.\n *\n * Intended to be overridden by subclasses.\n *\n * @param {WebGLRenderingContext} gl The canvas context used to compile the shader program.\n * @param {Object} uniformLocations A map of shader uniform names to their locations.\n */\n sendUniformData: function(/* gl, uniformLocations */) {\n // Intentionally left blank. Override me in subclasses.\n },\n\n /**\n * If needed by a 2d filter, this functions can create an helper canvas to be used\n * remember that options.targetCanvas is available for use till end of chain.\n */\n createHelpLayer: function(options) {\n if (!options.helpLayer) {\n var helpLayer = document.createElement('canvas');\n helpLayer.width = options.sourceWidth;\n helpLayer.height = options.sourceHeight;\n options.helpLayer = helpLayer;\n }\n },\n\n /**\n * Returns object representation of an instance\n * @return {Object} Object representation of an instance\n */\n toObject: function() {\n var object = { type: this.type }, mainP = this.mainParameter;\n if (mainP) {\n object[mainP] = this[mainP];\n }\n return object;\n },\n\n /**\n * Returns a JSON representation of an instance\n * @return {Object} JSON\n */\n toJSON: function() {\n // delegate, not alias\n return this.toObject();\n }\n});\n\nfabric.Image.filters.BaseFilter.fromObject = function(object, callback) {\n var filter = new fabric.Image.filters[object.type](object);\n callback && callback(filter);\n return filter;\n};\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * Color Matrix filter class\n * @class fabric.Image.filters.ColorMatrix\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link fabric.Image.filters.ColorMatrix#initialize} for constructor definition\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @see {@Link http://www.webwasp.co.uk/tutorials/219/Color_Matrix_Filter.php}\n * @see {@Link http://phoboslab.org/log/2013/11/fast-image-filters-with-webgl}\n * @example <caption>Kodachrome filter</caption>\n * var filter = new fabric.Image.filters.ColorMatrix({\n * matrix: [\n 1.1285582396593525, -0.3967382283601348, -0.03992559172921793, 0, 63.72958762196502,\n -0.16404339962244616, 1.0835251566291304, -0.05498805115633132, 0, 24.732407896706203,\n -0.16786010706155763, -0.5603416277695248, 1.6014850761964943, 0, 35.62982807460946,\n 0, 0, 0, 1, 0\n ]\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n */\n filters.ColorMatrix = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.ColorMatrix.prototype */ {\n\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'ColorMatrix',\n\n fragmentSource: 'precision highp float;\\n' +\n 'uniform sampler2D uTexture;\\n' +\n 'varying vec2 vTexCoord;\\n' +\n 'uniform mat4 uColorMatrix;\\n' +\n 'uniform vec4 uConstants;\\n' +\n 'void main() {\\n' +\n 'vec4 color = texture2D(uTexture, vTexCoord);\\n' +\n 'color *= uColorMatrix;\\n' +\n 'color += uConstants;\\n' +\n 'gl_FragColor = color;\\n' +\n '}',\n\n /**\n * Colormatrix for pixels.\n * array of 20 floats. Numbers in positions 4, 9, 14, 19 loose meaning\n * outside the -1, 1 range.\n * 0.0039215686 is the part of 1 that get translated to 1 in 2d\n * @param {Array} matrix array of 20 numbers.\n * @default\n */\n matrix: [\n 1, 0, 0, 0, 0,\n 0, 1, 0, 0, 0,\n 0, 0, 1, 0, 0,\n 0, 0, 0, 1, 0\n ],\n\n mainParameter: 'matrix',\n\n /**\n * Lock the colormatrix on the color part, skipping alpha, manly for non webgl scenario\n * to save some calculation\n */\n colorsOnly: true,\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n */\n initialize: function(options) {\n this.callSuper('initialize', options);\n // create a new array instead mutating the prototype with push\n this.matrix = this.matrix.slice(0);\n },\n\n /**\n * Apply the ColorMatrix operation to a Uint8Array representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8Array to be filtered.\n */\n applyTo2d: function(options) {\n var imageData = options.imageData,\n data = imageData.data,\n iLen = data.length,\n m = this.matrix,\n r, g, b, a, i, colorsOnly = this.colorsOnly;\n\n for (i = 0; i < iLen; i += 4) {\n r = data[i];\n g = data[i + 1];\n b = data[i + 2];\n if (colorsOnly) {\n data[i] = r * m[0] + g * m[1] + b * m[2] + m[4] * 255;\n data[i + 1] = r * m[5] + g * m[6] + b * m[7] + m[9] * 255;\n data[i + 2] = r * m[10] + g * m[11] + b * m[12] + m[14] * 255;\n }\n else {\n a = data[i + 3];\n data[i] = r * m[0] + g * m[1] + b * m[2] + a * m[3] + m[4] * 255;\n data[i + 1] = r * m[5] + g * m[6] + b * m[7] + a * m[8] + m[9] * 255;\n data[i + 2] = r * m[10] + g * m[11] + b * m[12] + a * m[13] + m[14] * 255;\n data[i + 3] = r * m[15] + g * m[16] + b * m[17] + a * m[18] + m[19] * 255;\n }\n }\n },\n\n /**\n * Return WebGL uniform locations for this filter's shader.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {WebGLShaderProgram} program This filter's compiled shader program.\n */\n getUniformLocations: function(gl, program) {\n return {\n uColorMatrix: gl.getUniformLocation(program, 'uColorMatrix'),\n uConstants: gl.getUniformLocation(program, 'uConstants'),\n };\n },\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData: function(gl, uniformLocations) {\n var m = this.matrix,\n matrix = [\n m[0], m[1], m[2], m[3],\n m[5], m[6], m[7], m[8],\n m[10], m[11], m[12], m[13],\n m[15], m[16], m[17], m[18]\n ],\n constants = [m[4], m[9], m[14], m[19]];\n gl.uniformMatrix4fv(uniformLocations.uColorMatrix, false, matrix);\n gl.uniform4fv(uniformLocations.uConstants, constants);\n },\n });\n\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] function to invoke after filter creation\n * @return {fabric.Image.filters.ColorMatrix} Instance of fabric.Image.filters.ColorMatrix\n */\n fabric.Image.filters.ColorMatrix.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * Brightness filter class\n * @class fabric.Image.filters.Brightness\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link fabric.Image.filters.Brightness#initialize} for constructor definition\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example\n * var filter = new fabric.Image.filters.Brightness({\n * brightness: 0.05\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n */\n filters.Brightness = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Brightness.prototype */ {\n\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'Brightness',\n\n /**\n * Fragment source for the brightness program\n */\n fragmentSource: 'precision highp float;\\n' +\n 'uniform sampler2D uTexture;\\n' +\n 'uniform float uBrightness;\\n' +\n 'varying vec2 vTexCoord;\\n' +\n 'void main() {\\n' +\n 'vec4 color = texture2D(uTexture, vTexCoord);\\n' +\n 'color.rgb += uBrightness;\\n' +\n 'gl_FragColor = color;\\n' +\n '}',\n\n /**\n * Brightness value, from -1 to 1.\n * translated to -255 to 255 for 2d\n * 0.0039215686 is the part of 1 that get translated to 1 in 2d\n * @param {Number} brightness\n * @default\n */\n brightness: 0,\n\n /**\n * Describe the property that is the filter parameter\n * @param {String} m\n * @default\n */\n mainParameter: 'brightness',\n\n /**\n * Apply the Brightness operation to a Uint8ClampedArray representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n */\n applyTo2d: function(options) {\n if (this.brightness === 0) {\n return;\n }\n var imageData = options.imageData,\n data = imageData.data, i, len = data.length,\n brightness = Math.round(this.brightness * 255);\n for (i = 0; i < len; i += 4) {\n data[i] = data[i] + brightness;\n data[i + 1] = data[i + 1] + brightness;\n data[i + 2] = data[i + 2] + brightness;\n }\n },\n\n /**\n * Return WebGL uniform locations for this filter's shader.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {WebGLShaderProgram} program This filter's compiled shader program.\n */\n getUniformLocations: function(gl, program) {\n return {\n uBrightness: gl.getUniformLocation(program, 'uBrightness'),\n };\n },\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData: function(gl, uniformLocations) {\n gl.uniform1f(uniformLocations.uBrightness, this.brightness);\n },\n });\n\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.Brightness} Instance of fabric.Image.filters.Brightness\n */\n fabric.Image.filters.Brightness.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n extend = fabric.util.object.extend,\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * Adapted from <a href=\"http://www.html5rocks.com/en/tutorials/canvas/imagefilters/\">html5rocks article</a>\n * @class fabric.Image.filters.Convolute\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link fabric.Image.filters.Convolute#initialize} for constructor definition\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example <caption>Sharpen filter</caption>\n * var filter = new fabric.Image.filters.Convolute({\n * matrix: [ 0, -1, 0,\n * -1, 5, -1,\n * 0, -1, 0 ]\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n * canvas.renderAll();\n * @example <caption>Blur filter</caption>\n * var filter = new fabric.Image.filters.Convolute({\n * matrix: [ 1/9, 1/9, 1/9,\n * 1/9, 1/9, 1/9,\n * 1/9, 1/9, 1/9 ]\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n * canvas.renderAll();\n * @example <caption>Emboss filter</caption>\n * var filter = new fabric.Image.filters.Convolute({\n * matrix: [ 1, 1, 1,\n * 1, 0.7, -1,\n * -1, -1, -1 ]\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n * canvas.renderAll();\n * @example <caption>Emboss filter with opaqueness</caption>\n * var filter = new fabric.Image.filters.Convolute({\n * opaque: true,\n * matrix: [ 1, 1, 1,\n * 1, 0.7, -1,\n * -1, -1, -1 ]\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n * canvas.renderAll();\n */\n filters.Convolute = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Convolute.prototype */ {\n\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'Convolute',\n\n /*\n * Opaque value (true/false)\n */\n opaque: false,\n\n /*\n * matrix for the filter, max 9x9\n */\n matrix: [0, 0, 0, 0, 1, 0, 0, 0, 0],\n\n /**\n * Fragment source for the brightness program\n */\n fragmentSource: {\n Convolute_3_1: 'precision highp float;\\n' +\n 'uniform sampler2D uTexture;\\n' +\n 'uniform float uMatrix[9];\\n' +\n 'uniform float uStepW;\\n' +\n 'uniform float uStepH;\\n' +\n 'varying vec2 vTexCoord;\\n' +\n 'void main() {\\n' +\n 'vec4 color = vec4(0, 0, 0, 0);\\n' +\n 'for (float h = 0.0; h < 3.0; h+=1.0) {\\n' +\n 'for (float w = 0.0; w < 3.0; w+=1.0) {\\n' +\n 'vec2 matrixPos = vec2(uStepW * (w - 1), uStepH * (h - 1));\\n' +\n 'color += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 3.0 + w)];\\n' +\n '}\\n' +\n '}\\n' +\n 'gl_FragColor = color;\\n' +\n '}',\n Convolute_3_0: 'precision highp float;\\n' +\n 'uniform sampler2D uTexture;\\n' +\n 'uniform float uMatrix[9];\\n' +\n 'uniform float uStepW;\\n' +\n 'uniform float uStepH;\\n' +\n 'varying vec2 vTexCoord;\\n' +\n 'void main() {\\n' +\n 'vec4 color = vec4(0, 0, 0, 1);\\n' +\n 'for (float h = 0.0; h < 3.0; h+=1.0) {\\n' +\n 'for (float w = 0.0; w < 3.0; w+=1.0) {\\n' +\n 'vec2 matrixPos = vec2(uStepW * (w - 1.0), uStepH * (h - 1.0));\\n' +\n 'color.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 3.0 + w)];\\n' +\n '}\\n' +\n '}\\n' +\n 'float alpha = texture2D(uTexture, vTexCoord).a;\\n' +\n 'gl_FragColor = color;\\n' +\n 'gl_FragColor.a = alpha;\\n' +\n '}',\n Convolute_5_1: 'precision highp float;\\n' +\n 'uniform sampler2D uTexture;\\n' +\n 'uniform float uMatrix[25];\\n' +\n 'uniform float uStepW;\\n' +\n 'uniform float uStepH;\\n' +\n 'varying vec2 vTexCoord;\\n' +\n 'void main() {\\n' +\n 'vec4 color = vec4(0, 0, 0, 0);\\n' +\n 'for (float h = 0.0; h < 5.0; h+=1.0) {\\n' +\n 'for (float w = 0.0; w < 5.0; w+=1.0) {\\n' +\n 'vec2 matrixPos = vec2(uStepW * (w - 2.0), uStepH * (h - 2.0));\\n' +\n 'color += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 5.0 + w)];\\n' +\n '}\\n' +\n '}\\n' +\n 'gl_FragColor = color;\\n' +\n '}',\n Convolute_5_0: 'precision highp float;\\n' +\n 'uniform sampler2D uTexture;\\n' +\n 'uniform float uMatrix[25];\\n' +\n 'uniform float uStepW;\\n' +\n 'uniform float uStepH;\\n' +\n 'varying vec2 vTexCoord;\\n' +\n 'void main() {\\n' +\n 'vec4 color = vec4(0, 0, 0, 1);\\n' +\n 'for (float h = 0.0; h < 5.0; h+=1.0) {\\n' +\n 'for (float w = 0.0; w < 5.0; w+=1.0) {\\n' +\n 'vec2 matrixPos = vec2(uStepW * (w - 2.0), uStepH * (h - 2.0));\\n' +\n 'color.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 5.0 + w)];\\n' +\n '}\\n' +\n '}\\n' +\n 'float alpha = texture2D(uTexture, vTexCoord).a;\\n' +\n 'gl_FragColor = color;\\n' +\n 'gl_FragColor.a = alpha;\\n' +\n '}',\n Convolute_7_1: 'precision highp float;\\n' +\n 'uniform sampler2D uTexture;\\n' +\n 'uniform float uMatrix[49];\\n' +\n 'uniform float uStepW;\\n' +\n 'uniform float uStepH;\\n' +\n 'varying vec2 vTexCoord;\\n' +\n 'void main() {\\n' +\n 'vec4 color = vec4(0, 0, 0, 0);\\n' +\n 'for (float h = 0.0; h < 7.0; h+=1.0) {\\n' +\n 'for (float w = 0.0; w < 7.0; w+=1.0) {\\n' +\n 'vec2 matrixPos = vec2(uStepW * (w - 3.0), uStepH * (h - 3.0));\\n' +\n 'color += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 7.0 + w)];\\n' +\n '}\\n' +\n '}\\n' +\n 'gl_FragColor = color;\\n' +\n '}',\n Convolute_7_0: 'precision highp float;\\n' +\n 'uniform sampler2D uTexture;\\n' +\n 'uniform float uMatrix[49];\\n' +\n 'uniform float uStepW;\\n' +\n 'uniform float uStepH;\\n' +\n 'varying vec2 vTexCoord;\\n' +\n 'void main() {\\n' +\n 'vec4 color = vec4(0, 0, 0, 1);\\n' +\n 'for (float h = 0.0; h < 7.0; h+=1.0) {\\n' +\n 'for (float w = 0.0; w < 7.0; w+=1.0) {\\n' +\n 'vec2 matrixPos = vec2(uStepW * (w - 3.0), uStepH * (h - 3.0));\\n' +\n 'color.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 7.0 + w)];\\n' +\n '}\\n' +\n '}\\n' +\n 'float alpha = texture2D(uTexture, vTexCoord).a;\\n' +\n 'gl_FragColor = color;\\n' +\n 'gl_FragColor.a = alpha;\\n' +\n '}',\n Convolute_9_1: 'precision highp float;\\n' +\n 'uniform sampler2D uTexture;\\n' +\n 'uniform float uMatrix[81];\\n' +\n 'uniform float uStepW;\\n' +\n 'uniform float uStepH;\\n' +\n 'varying vec2 vTexCoord;\\n' +\n 'void main() {\\n' +\n 'vec4 color = vec4(0, 0, 0, 0);\\n' +\n 'for (float h = 0.0; h < 9.0; h+=1.0) {\\n' +\n 'for (float w = 0.0; w < 9.0; w+=1.0) {\\n' +\n 'vec2 matrixPos = vec2(uStepW * (w - 4.0), uStepH * (h - 4.0));\\n' +\n 'color += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 9.0 + w)];\\n' +\n '}\\n' +\n '}\\n' +\n 'gl_FragColor = color;\\n' +\n '}',\n Convolute_9_0: 'precision highp float;\\n' +\n 'uniform sampler2D uTexture;\\n' +\n 'uniform float uMatrix[81];\\n' +\n 'uniform float uStepW;\\n' +\n 'uniform float uStepH;\\n' +\n 'varying vec2 vTexCoord;\\n' +\n 'void main() {\\n' +\n 'vec4 color = vec4(0, 0, 0, 1);\\n' +\n 'for (float h = 0.0; h < 9.0; h+=1.0) {\\n' +\n 'for (float w = 0.0; w < 9.0; w+=1.0) {\\n' +\n 'vec2 matrixPos = vec2(uStepW * (w - 4.0), uStepH * (h - 4.0));\\n' +\n 'color.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 9.0 + w)];\\n' +\n '}\\n' +\n '}\\n' +\n 'float alpha = texture2D(uTexture, vTexCoord).a;\\n' +\n 'gl_FragColor = color;\\n' +\n 'gl_FragColor.a = alpha;\\n' +\n '}',\n },\n\n /**\n * Constructor\n * @memberOf fabric.Image.filters.Convolute.prototype\n * @param {Object} [options] Options object\n * @param {Boolean} [options.opaque=false] Opaque value (true/false)\n * @param {Array} [options.matrix] Filter matrix\n */\n\n\n /**\n * Retrieves the cached shader.\n * @param {Object} options\n * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n */\n retrieveShader: function(options) {\n var size = Math.sqrt(this.matrix.length);\n var cacheKey = this.type + '_' + size + '_' + (this.opaque ? 1 : 0);\n var shaderSource = this.fragmentSource[cacheKey];\n if (!options.programCache.hasOwnProperty(cacheKey)) {\n options.programCache[cacheKey] = this.createProgram(options.context, shaderSource);\n }\n return options.programCache[cacheKey];\n },\n\n /**\n * Apply the Brightness operation to a Uint8ClampedArray representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n */\n applyTo2d: function(options) {\n var imageData = options.imageData,\n data = imageData.data,\n weights = this.matrix,\n side = Math.round(Math.sqrt(weights.length)),\n halfSide = Math.floor(side / 2),\n sw = imageData.width,\n sh = imageData.height,\n output = options.ctx.createImageData(sw, sh),\n dst = output.data,\n // go through the destination image pixels\n alphaFac = this.opaque ? 1 : 0,\n r, g, b, a, dstOff,\n scx, scy, srcOff, wt,\n x, y, cx, cy;\n\n for (y = 0; y < sh; y++) {\n for (x = 0; x < sw; x++) {\n dstOff = (y * sw + x) * 4;\n // calculate the weighed sum of the source image pixels that\n // fall under the convolution matrix\n r = 0; g = 0; b = 0; a = 0;\n\n for (cy = 0; cy < side; cy++) {\n for (cx = 0; cx < side; cx++) {\n scy = y + cy - halfSide;\n scx = x + cx - halfSide;\n\n // eslint-disable-next-line max-depth\n if (scy < 0 || scy >= sh || scx < 0 || scx >= sw) {\n continue;\n }\n\n srcOff = (scy * sw + scx) * 4;\n wt = weights[cy * side + cx];\n\n r += data[srcOff] * wt;\n g += data[srcOff + 1] * wt;\n b += data[srcOff + 2] * wt;\n // eslint-disable-next-line max-depth\n if (!alphaFac) {\n a += data[srcOff + 3] * wt;\n }\n }\n }\n dst[dstOff] = r;\n dst[dstOff + 1] = g;\n dst[dstOff + 2] = b;\n if (!alphaFac) {\n dst[dstOff + 3] = a;\n }\n else {\n dst[dstOff + 3] = data[dstOff + 3];\n }\n }\n }\n options.imageData = output;\n },\n\n /**\n * Return WebGL uniform locations for this filter's shader.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {WebGLShaderProgram} program This filter's compiled shader program.\n */\n getUniformLocations: function(gl, program) {\n return {\n uMatrix: gl.getUniformLocation(program, 'uMatrix'),\n uOpaque: gl.getUniformLocation(program, 'uOpaque'),\n uHalfSize: gl.getUniformLocation(program, 'uHalfSize'),\n uSize: gl.getUniformLocation(program, 'uSize'),\n };\n },\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData: function(gl, uniformLocations) {\n gl.uniform1fv(uniformLocations.uMatrix, this.matrix);\n },\n\n /**\n * Returns object representation of an instance\n * @return {Object} Object representation of an instance\n */\n toObject: function() {\n return extend(this.callSuper('toObject'), {\n opaque: this.opaque,\n matrix: this.matrix\n });\n }\n });\n\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.Convolute} Instance of fabric.Image.filters.Convolute\n */\n fabric.Image.filters.Convolute.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * Grayscale image filter class\n * @class fabric.Image.filters.Grayscale\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example\n * var filter = new fabric.Image.filters.Grayscale();\n * object.filters.push(filter);\n * object.applyFilters();\n */\n filters.Grayscale = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Grayscale.prototype */ {\n\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'Grayscale',\n\n fragmentSource: {\n average: 'precision highp float;\\n' +\n 'uniform sampler2D uTexture;\\n' +\n 'varying vec2 vTexCoord;\\n' +\n 'void main() {\\n' +\n 'vec4 color = texture2D(uTexture, vTexCoord);\\n' +\n 'float average = (color.r + color.b + color.g) / 3.0;\\n' +\n 'gl_FragColor = vec4(average, average, average, color.a);\\n' +\n '}',\n lightness: 'precision highp float;\\n' +\n 'uniform sampler2D uTexture;\\n' +\n 'uniform int uMode;\\n' +\n 'varying vec2 vTexCoord;\\n' +\n 'void main() {\\n' +\n 'vec4 col = texture2D(uTexture, vTexCoord);\\n' +\n 'float average = (max(max(col.r, col.g),col.b) + min(min(col.r, col.g),col.b)) / 2.0;\\n' +\n 'gl_FragColor = vec4(average, average, average, col.a);\\n' +\n '}',\n luminosity: 'precision highp float;\\n' +\n 'uniform sampler2D uTexture;\\n' +\n 'uniform int uMode;\\n' +\n 'varying vec2 vTexCoord;\\n' +\n 'void main() {\\n' +\n 'vec4 col = texture2D(uTexture, vTexCoord);\\n' +\n 'float average = 0.21 * col.r + 0.72 * col.g + 0.07 * col.b;\\n' +\n 'gl_FragColor = vec4(average, average, average, col.a);\\n' +\n '}',\n },\n\n\n /**\n * Grayscale mode, between 'average', 'lightness', 'luminosity'\n * @param {String} type\n * @default\n */\n mode: 'average',\n\n mainParameter: 'mode',\n\n /**\n * Apply the Grayscale operation to a Uint8Array representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8Array to be filtered.\n */\n applyTo2d: function(options) {\n var imageData = options.imageData,\n data = imageData.data, i,\n len = data.length, value,\n mode = this.mode;\n for (i = 0; i < len; i += 4) {\n if (mode === 'average') {\n value = (data[i] + data[i + 1] + data[i + 2]) / 3;\n }\n else if (mode === 'lightness') {\n value = (Math.min(data[i], data[i + 1], data[i + 2]) +\n Math.max(data[i], data[i + 1], data[i + 2])) / 2;\n }\n else if (mode === 'luminosity') {\n value = 0.21 * data[i] + 0.72 * data[i + 1] + 0.07 * data[i + 2];\n }\n data[i] = value;\n data[i + 1] = value;\n data[i + 2] = value;\n }\n },\n\n /**\n * Retrieves the cached shader.\n * @param {Object} options\n * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n */\n retrieveShader: function(options) {\n var cacheKey = this.type + '_' + this.mode;\n if (!options.programCache.hasOwnProperty(cacheKey)) {\n var shaderSource = this.fragmentSource[this.mode];\n options.programCache[cacheKey] = this.createProgram(options.context, shaderSource);\n }\n return options.programCache[cacheKey];\n },\n\n /**\n * Return WebGL uniform locations for this filter's shader.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {WebGLShaderProgram} program This filter's compiled shader program.\n */\n getUniformLocations: function(gl, program) {\n return {\n uMode: gl.getUniformLocation(program, 'uMode'),\n };\n },\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData: function(gl, uniformLocations) {\n // default average mode.\n var mode = 1;\n gl.uniform1i(uniformLocations.uMode, mode);\n },\n\n /**\n * Grayscale filter isNeutralState implementation\n * The filter is never neutral\n * on the image\n **/\n isNeutralState: function() {\n return false;\n },\n });\n\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.Grayscale} Instance of fabric.Image.filters.Grayscale\n */\n fabric.Image.filters.Grayscale.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * Invert filter class\n * @class fabric.Image.filters.Invert\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example\n * var filter = new fabric.Image.filters.Invert();\n * object.filters.push(filter);\n * object.applyFilters(canvas.renderAll.bind(canvas));\n */\n filters.Invert = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Invert.prototype */ {\n\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'Invert',\n\n fragmentSource: 'precision highp float;\\n' +\n 'uniform sampler2D uTexture;\\n' +\n 'uniform int uInvert;\\n' +\n 'varying vec2 vTexCoord;\\n' +\n 'void main() {\\n' +\n 'vec4 color = texture2D(uTexture, vTexCoord);\\n' +\n 'if (uInvert == 1) {\\n' +\n 'gl_FragColor = vec4(1.0 - color.r,1.0 -color.g,1.0 -color.b,color.a);\\n' +\n '} else {\\n' +\n 'gl_FragColor = color;\\n' +\n '}\\n' +\n '}',\n\n /**\n * Filter invert. if false, does nothing\n * @param {Boolean} invert\n * @default\n */\n invert: true,\n\n mainParameter: 'invert',\n\n /**\n * Apply the Invert operation to a Uint8Array representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8Array to be filtered.\n */\n applyTo2d: function(options) {\n var imageData = options.imageData,\n data = imageData.data, i,\n len = data.length;\n for (i = 0; i < len; i += 4) {\n data[i] = 255 - data[i];\n data[i + 1] = 255 - data[i + 1];\n data[i + 2] = 255 - data[i + 2];\n }\n },\n\n /**\n * Invert filter isNeutralState implementation\n * Used only in image applyFilters to discard filters that will not have an effect\n * on the image\n * @param {Object} options\n **/\n isNeutralState: function() {\n return !this.invert;\n },\n\n /**\n * Return WebGL uniform locations for this filter's shader.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {WebGLShaderProgram} program This filter's compiled shader program.\n */\n getUniformLocations: function(gl, program) {\n return {\n uInvert: gl.getUniformLocation(program, 'uInvert'),\n };\n },\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData: function(gl, uniformLocations) {\n gl.uniform1i(uniformLocations.uInvert, this.invert);\n },\n });\n\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.Invert} Instance of fabric.Image.filters.Invert\n */\n fabric.Image.filters.Invert.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n extend = fabric.util.object.extend,\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * Noise filter class\n * @class fabric.Image.filters.Noise\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link fabric.Image.filters.Noise#initialize} for constructor definition\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example\n * var filter = new fabric.Image.filters.Noise({\n * noise: 700\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n * canvas.renderAll();\n */\n filters.Noise = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Noise.prototype */ {\n\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'Noise',\n\n /**\n * Fragment source for the noise program\n */\n fragmentSource: 'precision highp float;\\n' +\n 'uniform sampler2D uTexture;\\n' +\n 'uniform float uStepH;\\n' +\n 'uniform float uNoise;\\n' +\n 'uniform float uSeed;\\n' +\n 'varying vec2 vTexCoord;\\n' +\n 'float rand(vec2 co, float seed, float vScale) {\\n' +\n 'return fract(sin(dot(co.xy * vScale ,vec2(12.9898 , 78.233))) * 43758.5453 * (seed + 0.01) / 2.0);\\n' +\n '}\\n' +\n 'void main() {\\n' +\n 'vec4 color = texture2D(uTexture, vTexCoord);\\n' +\n 'color.rgb += (0.5 - rand(vTexCoord, uSeed, 0.1 / uStepH)) * uNoise;\\n' +\n 'gl_FragColor = color;\\n' +\n '}',\n\n /**\n * Describe the property that is the filter parameter\n * @param {String} m\n * @default\n */\n mainParameter: 'noise',\n\n /**\n * Noise value, from\n * @param {Number} noise\n * @default\n */\n noise: 0,\n\n /**\n * Apply the Brightness operation to a Uint8ClampedArray representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n */\n applyTo2d: function(options) {\n if (this.noise === 0) {\n return;\n }\n var imageData = options.imageData,\n data = imageData.data, i, len = data.length,\n noise = this.noise, rand;\n\n for (i = 0, len = data.length; i < len; i += 4) {\n\n rand = (0.5 - Math.random()) * noise;\n\n data[i] += rand;\n data[i + 1] += rand;\n data[i + 2] += rand;\n }\n },\n\n /**\n * Return WebGL uniform locations for this filter's shader.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {WebGLShaderProgram} program This filter's compiled shader program.\n */\n getUniformLocations: function(gl, program) {\n return {\n uNoise: gl.getUniformLocation(program, 'uNoise'),\n uSeed: gl.getUniformLocation(program, 'uSeed'),\n };\n },\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData: function(gl, uniformLocations) {\n gl.uniform1f(uniformLocations.uNoise, this.noise / 255);\n gl.uniform1f(uniformLocations.uSeed, Math.random());\n },\n\n /**\n * Returns object representation of an instance\n * @return {Object} Object representation of an instance\n */\n toObject: function() {\n return extend(this.callSuper('toObject'), {\n noise: this.noise\n });\n }\n });\n\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {Function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.Noise} Instance of fabric.Image.filters.Noise\n */\n fabric.Image.filters.Noise.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * Pixelate filter class\n * @class fabric.Image.filters.Pixelate\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link fabric.Image.filters.Pixelate#initialize} for constructor definition\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example\n * var filter = new fabric.Image.filters.Pixelate({\n * blocksize: 8\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n */\n filters.Pixelate = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Pixelate.prototype */ {\n\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'Pixelate',\n\n blocksize: 4,\n\n mainParameter: 'blocksize',\n\n /**\n * Fragment source for the Pixelate program\n */\n fragmentSource: 'precision highp float;\\n' +\n 'uniform sampler2D uTexture;\\n' +\n 'uniform float uBlocksize;\\n' +\n 'uniform float uStepW;\\n' +\n 'uniform float uStepH;\\n' +\n 'varying vec2 vTexCoord;\\n' +\n 'void main() {\\n' +\n 'float blockW = uBlocksize * uStepW;\\n' +\n 'float blockH = uBlocksize * uStepW;\\n' +\n 'int posX = int(vTexCoord.x / blockW);\\n' +\n 'int posY = int(vTexCoord.y / blockH);\\n' +\n 'float fposX = float(posX);\\n' +\n 'float fposY = float(posY);\\n' +\n 'vec2 squareCoords = vec2(fposX * blockW, fposY * blockH);\\n' +\n 'vec4 color = texture2D(uTexture, squareCoords);\\n' +\n 'gl_FragColor = color;\\n' +\n '}',\n\n /**\n * Apply the Pixelate operation to a Uint8ClampedArray representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n */\n applyTo2d: function(options) {\n var imageData = options.imageData,\n data = imageData.data,\n iLen = imageData.height,\n jLen = imageData.width,\n index, i, j, r, g, b, a,\n _i, _j, _iLen, _jLen;\n\n for (i = 0; i < iLen; i += this.blocksize) {\n for (j = 0; j < jLen; j += this.blocksize) {\n\n index = (i * 4) * jLen + (j * 4);\n\n r = data[index];\n g = data[index + 1];\n b = data[index + 2];\n a = data[index + 3];\n\n _iLen = Math.min(i + this.blocksize, iLen);\n _jLen = Math.min(j + this.blocksize, jLen);\n for (_i = i; _i < _iLen; _i++) {\n for (_j = j; _j < _jLen; _j++) {\n index = (_i * 4) * jLen + (_j * 4);\n data[index] = r;\n data[index + 1] = g;\n data[index + 2] = b;\n data[index + 3] = a;\n }\n }\n }\n }\n },\n\n /**\n * Indicate when the filter is not gonna apply changes to the image\n **/\n isNeutralState: function() {\n return this.blocksize === 1;\n },\n\n /**\n * Return WebGL uniform locations for this filter's shader.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {WebGLShaderProgram} program This filter's compiled shader program.\n */\n getUniformLocations: function(gl, program) {\n return {\n uBlocksize: gl.getUniformLocation(program, 'uBlocksize'),\n uStepW: gl.getUniformLocation(program, 'uStepW'),\n uStepH: gl.getUniformLocation(program, 'uStepH'),\n };\n },\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData: function(gl, uniformLocations) {\n gl.uniform1f(uniformLocations.uBlocksize, this.blocksize);\n },\n });\n\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {Function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.Pixelate} Instance of fabric.Image.filters.Pixelate\n */\n fabric.Image.filters.Pixelate.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n extend = fabric.util.object.extend,\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * Remove white filter class\n * @class fabric.Image.filters.RemoveColor\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link fabric.Image.filters.RemoveColor#initialize} for constructor definition\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example\n * var filter = new fabric.Image.filters.RemoveColor({\n * threshold: 0.2,\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n * canvas.renderAll();\n */\n filters.RemoveColor = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.RemoveColor.prototype */ {\n\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'RemoveColor',\n\n /**\n * Color to remove, in any format understood by fabric.Color.\n * @param {String} type\n * @default\n */\n color: '#FFFFFF',\n\n /**\n * Fragment source for the brightness program\n */\n fragmentSource: 'precision highp float;\\n' +\n 'uniform sampler2D uTexture;\\n' +\n 'uniform vec4 uLow;\\n' +\n 'uniform vec4 uHigh;\\n' +\n 'varying vec2 vTexCoord;\\n' +\n 'void main() {\\n' +\n 'gl_FragColor = texture2D(uTexture, vTexCoord);\\n' +\n 'if(all(greaterThan(gl_FragColor.rgb,uLow.rgb)) && all(greaterThan(uHigh.rgb,gl_FragColor.rgb))) {\\n' +\n 'gl_FragColor.a = 0.0;\\n' +\n '}\\n' +\n '}',\n\n /**\n * distance to actual color, as value up or down from each r,g,b\n * between 0 and 1\n **/\n distance: 0.02,\n\n /**\n * For color to remove inside distance, use alpha channel for a smoother deletion\n * NOT IMPLEMENTED YET\n **/\n useAlpha: false,\n\n /**\n * Constructor\n * @memberOf fabric.Image.filters.RemoveWhite.prototype\n * @param {Object} [options] Options object\n * @param {Number} [options.color=#RRGGBB] Threshold value\n * @param {Number} [options.distance=10] Distance value\n */\n\n /**\n * Applies filter to canvas element\n * @param {Object} canvasEl Canvas element to apply filter to\n */\n applyTo2d: function(options) {\n var imageData = options.imageData,\n data = imageData.data, i,\n distance = this.distance * 255,\n r, g, b,\n source = new fabric.Color(this.color).getSource(),\n lowC = [\n source[0] - distance,\n source[1] - distance,\n source[2] - distance,\n ],\n highC = [\n source[0] + distance,\n source[1] + distance,\n source[2] + distance,\n ];\n\n\n for (i = 0; i < data.length; i += 4) {\n r = data[i];\n g = data[i + 1];\n b = data[i + 2];\n\n if (r > lowC[0] &&\n g > lowC[1] &&\n b > lowC[2] &&\n r < highC[0] &&\n g < highC[1] &&\n b < highC[2]) {\n data[i + 3] = 0;\n }\n }\n },\n\n /**\n * Return WebGL uniform locations for this filter's shader.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {WebGLShaderProgram} program This filter's compiled shader program.\n */\n getUniformLocations: function(gl, program) {\n return {\n uLow: gl.getUniformLocation(program, 'uLow'),\n uHigh: gl.getUniformLocation(program, 'uHigh'),\n };\n },\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData: function(gl, uniformLocations) {\n var source = new fabric.Color(this.color).getSource(),\n distance = parseFloat(this.distance),\n lowC = [\n 0 + source[0] / 255 - distance,\n 0 + source[1] / 255 - distance,\n 0 + source[2] / 255 - distance,\n 1\n ],\n highC = [\n source[0] / 255 + distance,\n source[1] / 255 + distance,\n source[2] / 255 + distance,\n 1\n ];\n gl.uniform4fv(uniformLocations.uLow, lowC);\n gl.uniform4fv(uniformLocations.uHigh, highC);\n },\n\n /**\n * Returns object representation of an instance\n * @return {Object} Object representation of an instance\n */\n toObject: function() {\n return extend(this.callSuper('toObject'), {\n color: this.color,\n distance: this.distance\n });\n }\n });\n\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {Function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.RemoveColor} Instance of fabric.Image.filters.RemoveWhite\n */\n fabric.Image.filters.RemoveColor.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n var matrices = {\n Brownie: [\n 0.59970,0.34553,-0.27082,0,0.186,\n -0.03770,0.86095,0.15059,0,-0.1449,\n 0.24113,-0.07441,0.44972,0,-0.02965,\n 0,0,0,1,0\n ],\n Vintage: [\n 0.62793,0.32021,-0.03965,0,0.03784,\n 0.02578,0.64411,0.03259,0,0.02926,\n 0.04660,-0.08512,0.52416,0,0.02023,\n 0,0,0,1,0\n ],\n Kodachrome: [\n 1.12855,-0.39673,-0.03992,0,0.24991,\n -0.16404,1.08352,-0.05498,0,0.09698,\n -0.16786,-0.56034,1.60148,0,0.13972,\n 0,0,0,1,0\n ],\n Technicolor: [\n 1.91252,-0.85453,-0.09155,0,0.04624,\n -0.30878,1.76589,-0.10601,0,-0.27589,\n -0.23110,-0.75018,1.84759,0,0.12137,\n 0,0,0,1,0\n ],\n Polaroid: [\n 1.438,-0.062,-0.062,0,0,\n -0.122,1.378,-0.122,0,0,\n -0.016,-0.016,1.483,0,0,\n 0,0,0,1,0\n ],\n Sepia: [\n 0.393, 0.769, 0.189, 0, 0,\n 0.349, 0.686, 0.168, 0, 0,\n 0.272, 0.534, 0.131, 0, 0,\n 0, 0, 0, 1, 0\n ],\n BlackWhite: [\n 1.5, 1.5, 1.5, 0, -1,\n 1.5, 1.5, 1.5, 0, -1,\n 1.5, 1.5, 1.5, 0, -1,\n 0, 0, 0, 1, 0,\n ]\n };\n\n for (var key in matrices) {\n filters[key] = createClass(filters.ColorMatrix, /** @lends fabric.Image.filters.Sepia.prototype */ {\n\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: key,\n\n /**\n * Colormatrix for the effect\n * array of 20 floats. Numbers in positions 4, 9, 14, 19 loose meaning\n * outside the -1, 1 range.\n * @param {Array} matrix array of 20 numbers.\n * @default\n */\n matrix: matrices[key],\n\n /**\n * Lock the matrix export for this kind of static, parameter less filters.\n */\n mainParameter: false,\n /**\n * Lock the colormatrix on the color part, skipping alpha\n */\n colorsOnly: true,\n\n });\n fabric.Image.filters[key].fromObject = fabric.Image.filters.BaseFilter.fromObject;\n }\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n 'use strict';\n\n var fabric = global.fabric,\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * Color Blend filter class\n * @class fabric.Image.filter.BlendColor\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @example\n * var filter = new fabric.Image.filters.BlendColor({\n * color: '#000',\n * mode: 'multiply'\n * });\n *\n * var filter = new fabric.Image.filters.BlendImage({\n * image: fabricImageObject,\n * mode: 'multiply',\n * alpha: 0.5\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n * canvas.renderAll();\n */\n\n filters.BlendColor = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Blend.prototype */ {\n type: 'BlendColor',\n\n /**\n * Color to make the blend operation with. default to a reddish color since black or white\n * gives always strong result.\n **/\n color: '#F95C63',\n\n /**\n * Blend mode for the filter: one of multiply, add, diff, screen, subtract,\n * darken, lighten, overlay, exclusion, tint.\n **/\n mode: 'multiply',\n\n /**\n * alpha value. represent the strength of the blend color operation.\n **/\n alpha: 1,\n\n /**\n * Fragment source for the Multiply program\n */\n fragmentSource: {\n multiply: 'gl_FragColor.rgb *= uColor.rgb;\\n',\n screen: 'gl_FragColor.rgb = 1.0 - (1.0 - gl_FragColor.rgb) * (1.0 - uColor.rgb);\\n',\n add: 'gl_FragColor.rgb += uColor.rgb;\\n',\n diff: 'gl_FragColor.rgb = abs(gl_FragColor.rgb - uColor.rgb);\\n',\n subtract: 'gl_FragColor.rgb -= uColor.rgb;\\n',\n lighten: 'gl_FragColor.rgb = max(gl_FragColor.rgb, uColor.rgb);\\n',\n darken: 'gl_FragColor.rgb = min(gl_FragColor.rgb, uColor.rgb);\\n',\n exclusion: 'gl_FragColor.rgb += uColor.rgb - 2.0 * (uColor.rgb * gl_FragColor.rgb);\\n',\n overlay: 'if (uColor.r < 0.5) {\\n' +\n 'gl_FragColor.r *= 2.0 * uColor.r;\\n' +\n '} else {\\n' +\n 'gl_FragColor.r = 1.0 - 2.0 * (1.0 - gl_FragColor.r) * (1.0 - uColor.r);\\n' +\n '}\\n' +\n 'if (uColor.g < 0.5) {\\n' +\n 'gl_FragColor.g *= 2.0 * uColor.g;\\n' +\n '} else {\\n' +\n 'gl_FragColor.g = 1.0 - 2.0 * (1.0 - gl_FragColor.g) * (1.0 - uColor.g);\\n' +\n '}\\n' +\n 'if (uColor.b < 0.5) {\\n' +\n 'gl_FragColor.b *= 2.0 * uColor.b;\\n' +\n '} else {\\n' +\n 'gl_FragColor.b = 1.0 - 2.0 * (1.0 - gl_FragColor.b) * (1.0 - uColor.b);\\n' +\n '}\\n',\n tint: 'gl_FragColor.rgb *= (1.0 - uColor.a);\\n' +\n 'gl_FragColor.rgb += uColor.rgb;\\n',\n },\n\n /**\n * build the fragment source for the filters, joining the common part with\n * the specific one.\n * @param {String} mode the mode of the filter, a key of this.fragmentSource\n * @return {String} the source to be compiled\n * @private\n */\n buildSource: function(mode) {\n return 'precision highp float;\\n' +\n 'uniform sampler2D uTexture;\\n' +\n 'uniform vec4 uColor;\\n' +\n 'varying vec2 vTexCoord;\\n' +\n 'void main() {\\n' +\n 'vec4 color = texture2D(uTexture, vTexCoord);\\n' +\n 'gl_FragColor = color;\\n' +\n 'if (color.a > 0.0) {\\n' +\n this.fragmentSource[mode] +\n '}\\n' +\n '}';\n },\n\n /**\n * Retrieves the cached shader.\n * @param {Object} options\n * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n */\n retrieveShader: function(options) {\n var cacheKey = this.type + '_' + this.mode, shaderSource;\n if (!options.programCache.hasOwnProperty(cacheKey)) {\n shaderSource = this.buildSource(this.mode);\n options.programCache[cacheKey] = this.createProgram(options.context, shaderSource);\n }\n return options.programCache[cacheKey];\n },\n\n /**\n * Apply the Blend operation to a Uint8ClampedArray representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n */\n applyTo2d: function(options) {\n var imageData = options.imageData,\n data = imageData.data, iLen = data.length,\n tr, tg, tb,\n r, g, b,\n source, alpha1 = 1 - this.alpha;\n\n source = new fabric.Color(this.color).getSource();\n tr = source[0] * this.alpha;\n tg = source[1] * this.alpha;\n tb = source[2] * this.alpha;\n\n for (var i = 0; i < iLen; i += 4) {\n\n r = data[i];\n g = data[i + 1];\n b = data[i + 2];\n\n switch (this.mode) {\n case 'multiply':\n data[i] = r * tr / 255;\n data[i + 1] = g * tg / 255;\n data[i + 2] = b * tb / 255;\n break;\n case 'screen':\n data[i] = 255 - (255 - r) * (255 - tr) / 255;\n data[i + 1] = 255 - (255 - g) * (255 - tg) / 255;\n data[i + 2] = 255 - (255 - b) * (255 - tb) / 255;\n break;\n case 'add':\n data[i] = r + tr;\n data[i + 1] = g + tg;\n data[i + 2] = b + tb;\n break;\n case 'diff':\n case 'difference':\n data[i] = Math.abs(r - tr);\n data[i + 1] = Math.abs(g - tg);\n data[i + 2] = Math.abs(b - tb);\n break;\n case 'subtract':\n data[i] = r - tr;\n data[i + 1] = g - tg;\n data[i + 2] = b - tb;\n break;\n case 'darken':\n data[i] = Math.min(r, tr);\n data[i + 1] = Math.min(g, tg);\n data[i + 2] = Math.min(b, tb);\n break;\n case 'lighten':\n data[i] = Math.max(r, tr);\n data[i + 1] = Math.max(g, tg);\n data[i + 2] = Math.max(b, tb);\n break;\n case 'overlay':\n data[i] = tr < 128 ? (2 * r * tr / 255) : (255 - 2 * (255 - r) * (255 - tr) / 255);\n data[i + 1] = tg < 128 ? (2 * g * tg / 255) : (255 - 2 * (255 - g) * (255 - tg) / 255);\n data[i + 2] = tb < 128 ? (2 * b * tb / 255) : (255 - 2 * (255 - b) * (255 - tb) / 255);\n break;\n case 'exclusion':\n data[i] = tr + r - ((2 * tr * r) / 255);\n data[i + 1] = tg + g - ((2 * tg * g) / 255);\n data[i + 2] = tb + b - ((2 * tb * b) / 255);\n break;\n case 'tint':\n data[i] = tr + r * alpha1;\n data[i + 1] = tg + g * alpha1;\n data[i + 2] = tb + b * alpha1;\n }\n }\n },\n\n /**\n * Return WebGL uniform locations for this filter's shader.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {WebGLShaderProgram} program This filter's compiled shader program.\n */\n getUniformLocations: function(gl, program) {\n return {\n uColor: gl.getUniformLocation(program, 'uColor'),\n };\n },\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData: function(gl, uniformLocations) {\n var source = new fabric.Color(this.color).getSource();\n source[0] = this.alpha * source[0] / 255;\n source[1] = this.alpha * source[1] / 255;\n source[2] = this.alpha * source[2] / 255;\n source[3] = this.alpha;\n gl.uniform4fv(uniformLocations.uColor, source);\n },\n\n /**\n * Returns object representation of an instance\n * @return {Object} Object representation of an instance\n */\n toObject: function() {\n return {\n type: this.type,\n color: this.color,\n mode: this.mode,\n alpha: this.alpha\n };\n }\n });\n\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.BlendColor} Instance of fabric.Image.filters.BlendColor\n */\n fabric.Image.filters.BlendColor.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n 'use strict';\n\n var fabric = global.fabric,\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * Image Blend filter class\n * @class fabric.Image.filter.BlendImage\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @example\n * var filter = new fabric.Image.filters.BlendColor({\n * color: '#000',\n * mode: 'multiply'\n * });\n *\n * var filter = new fabric.Image.filters.BlendImage({\n * image: fabricImageObject,\n * mode: 'multiply',\n * alpha: 0.5\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n * canvas.renderAll();\n */\n\n filters.BlendImage = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.BlendImage.prototype */ {\n type: 'BlendImage',\n\n /**\n * Color to make the blend operation with. default to a reddish color since black or white\n * gives always strong result.\n **/\n image: null,\n\n /**\n * Blend mode for the filter: one of multiply, add, diff, screen, subtract,\n * darken, lighten, overlay, exclusion, tint.\n **/\n mode: 'multiply',\n\n /**\n * alpha value. represent the strength of the blend image operation.\n * not implemented.\n **/\n alpha: 1,\n\n vertexSource: 'attribute vec2 aPosition;\\n' +\n 'varying vec2 vTexCoord;\\n' +\n 'varying vec2 vTexCoord2;\\n' +\n 'uniform mat3 uTransformMatrix;\\n' +\n 'void main() {\\n' +\n 'vTexCoord = aPosition;\\n' +\n 'vTexCoord2 = (uTransformMatrix * vec3(aPosition, 1.0)).xy;\\n' +\n 'gl_Position = vec4(aPosition * 2.0 - 1.0, 0.0, 1.0);\\n' +\n '}',\n\n /**\n * Fragment source for the Multiply program\n */\n fragmentSource: {\n multiply: 'precision highp float;\\n' +\n 'uniform sampler2D uTexture;\\n' +\n 'uniform sampler2D uImage;\\n' +\n 'uniform vec4 uColor;\\n' +\n 'varying vec2 vTexCoord;\\n' +\n 'varying vec2 vTexCoord2;\\n' +\n 'void main() {\\n' +\n 'vec4 color = texture2D(uTexture, vTexCoord);\\n' +\n 'vec4 color2 = texture2D(uImage, vTexCoord2);\\n' +\n 'color.rgba *= color2.rgba;\\n' +\n 'gl_FragColor = color;\\n' +\n '}',\n mask: 'precision highp float;\\n' +\n 'uniform sampler2D uTexture;\\n' +\n 'uniform sampler2D uImage;\\n' +\n 'uniform vec4 uColor;\\n' +\n 'varying vec2 vTexCoord;\\n' +\n 'varying vec2 vTexCoord2;\\n' +\n 'void main() {\\n' +\n 'vec4 color = texture2D(uTexture, vTexCoord);\\n' +\n 'vec4 color2 = texture2D(uImage, vTexCoord2);\\n' +\n 'color.a = color2.a;\\n' +\n 'gl_FragColor = color;\\n' +\n '}',\n },\n\n /**\n * Retrieves the cached shader.\n * @param {Object} options\n * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n */\n retrieveShader: function(options) {\n var cacheKey = this.type + '_' + this.mode;\n var shaderSource = this.fragmentSource[this.mode];\n if (!options.programCache.hasOwnProperty(cacheKey)) {\n options.programCache[cacheKey] = this.createProgram(options.context, shaderSource);\n }\n return options.programCache[cacheKey];\n },\n\n applyToWebGL: function(options) {\n // load texture to blend.\n var gl = options.context,\n texture = this.createTexture(options.filterBackend, this.image);\n this.bindAdditionalTexture(gl, texture, gl.TEXTURE1);\n this.callSuper('applyToWebGL', options);\n this.unbindAdditionalTexture(gl, gl.TEXTURE1);\n },\n\n createTexture: function(backend, image) {\n return backend.getCachedTexture(image.cacheKey, image._element);\n },\n\n /**\n * Calculate a transformMatrix to adapt the image to blend over\n * @param {Object} options\n * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n */\n calculateMatrix: function() {\n var image = this.image,\n width = image._element.width,\n height = image._element.height;\n return [\n 1 / image.scaleX, 0, 0,\n 0, 1 / image.scaleY, 0,\n -image.left / width, -image.top / height, 1\n ];\n },\n\n /**\n * Apply the Blend operation to a Uint8ClampedArray representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n */\n applyTo2d: function(options) {\n var imageData = options.imageData,\n resources = options.filterBackend.resources,\n data = imageData.data, iLen = data.length,\n width = imageData.width,\n height = imageData.height,\n tr, tg, tb, ta,\n r, g, b, a,\n canvas1, context, image = this.image, blendData;\n\n if (!resources.blendImage) {\n resources.blendImage = fabric.util.createCanvasElement();\n }\n canvas1 = resources.blendImage;\n context = canvas1.getContext('2d');\n if (canvas1.width !== width || canvas1.height !== height) {\n canvas1.width = width;\n canvas1.height = height;\n }\n else {\n context.clearRect(0, 0, width, height);\n }\n context.setTransform(image.scaleX, 0, 0, image.scaleY, image.left, image.top);\n context.drawImage(image._element, 0, 0, width, height);\n blendData = context.getImageData(0, 0, width, height).data;\n for (var i = 0; i < iLen; i += 4) {\n\n r = data[i];\n g = data[i + 1];\n b = data[i + 2];\n a = data[i + 3];\n\n tr = blendData[i];\n tg = blendData[i + 1];\n tb = blendData[i + 2];\n ta = blendData[i + 3];\n\n switch (this.mode) {\n case 'multiply':\n data[i] = r * tr / 255;\n data[i + 1] = g * tg / 255;\n data[i + 2] = b * tb / 255;\n data[i + 3] = a * ta / 255;\n break;\n case 'mask':\n data[i + 3] = ta;\n break;\n }\n }\n },\n\n /**\n * Return WebGL uniform locations for this filter's shader.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {WebGLShaderProgram} program This filter's compiled shader program.\n */\n getUniformLocations: function(gl, program) {\n return {\n uTransformMatrix: gl.getUniformLocation(program, 'uTransformMatrix'),\n uImage: gl.getUniformLocation(program, 'uImage'),\n };\n },\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData: function(gl, uniformLocations) {\n var matrix = this.calculateMatrix();\n gl.uniform1i(uniformLocations.uImage, 1); // texture unit 1.\n gl.uniformMatrix3fv(uniformLocations.uTransformMatrix, false, matrix);\n },\n\n /**\n * Returns object representation of an instance\n * @return {Object} Object representation of an instance\n */\n toObject: function() {\n return {\n type: this.type,\n image: this.image && this.image.toObject(),\n mode: this.mode,\n alpha: this.alpha\n };\n }\n });\n\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {function} callback to be invoked after filter creation\n * @return {fabric.Image.filters.BlendImage} Instance of fabric.Image.filters.BlendImage\n */\n fabric.Image.filters.BlendImage.fromObject = function(object, callback) {\n fabric.Image.fromObject(object.image, function(image) {\n var options = fabric.util.object.clone(object);\n options.image = image;\n callback(new fabric.Image.filters.BlendImage(options));\n });\n };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }), pow = Math.pow, floor = Math.floor,\n sqrt = Math.sqrt, abs = Math.abs, round = Math.round, sin = Math.sin,\n ceil = Math.ceil,\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * Resize image filter class\n * @class fabric.Image.filters.Resize\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example\n * var filter = new fabric.Image.filters.Resize();\n * object.filters.push(filter);\n * object.applyFilters(canvas.renderAll.bind(canvas));\n */\n filters.Resize = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Resize.prototype */ {\n\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'Resize',\n\n /**\n * Resize type\n * for webgl resizeType is just lanczos, for canvas2d can be:\n * bilinear, hermite, sliceHack, lanczos.\n * @param {String} resizeType\n * @default\n */\n resizeType: 'hermite',\n\n /**\n * Scale factor for resizing, x axis\n * @param {Number} scaleX\n * @default\n */\n scaleX: 1,\n\n /**\n * Scale factor for resizing, y axis\n * @param {Number} scaleY\n * @default\n */\n scaleY: 1,\n\n /**\n * LanczosLobes parameter for lanczos filter, valid for resizeType lanczos\n * @param {Number} lanczosLobes\n * @default\n */\n lanczosLobes: 3,\n\n\n /**\n * Return WebGL uniform locations for this filter's shader.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {WebGLShaderProgram} program This filter's compiled shader program.\n */\n getUniformLocations: function(gl, program) {\n return {\n uDelta: gl.getUniformLocation(program, 'uDelta'),\n uTaps: gl.getUniformLocation(program, 'uTaps'),\n };\n },\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData: function(gl, uniformLocations) {\n gl.uniform2fv(uniformLocations.uDelta, this.horizontal ? [1 / this.width, 0] : [0, 1 / this.height]);\n gl.uniform1fv(uniformLocations.uTaps, this.taps);\n },\n\n /**\n * Retrieves the cached shader.\n * @param {Object} options\n * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n */\n retrieveShader: function(options) {\n var filterWindow = this.getFilterWindow(), cacheKey = this.type + '_' + filterWindow;\n if (!options.programCache.hasOwnProperty(cacheKey)) {\n var fragmentShader = this.generateShader(filterWindow);\n options.programCache[cacheKey] = this.createProgram(options.context, fragmentShader);\n }\n return options.programCache[cacheKey];\n },\n\n getFilterWindow: function() {\n var scale = this.tempScale;\n return Math.ceil(this.lanczosLobes / scale);\n },\n\n getTaps: function() {\n var lobeFunction = this.lanczosCreate(this.lanczosLobes), scale = this.tempScale,\n filterWindow = this.getFilterWindow(), taps = new Array(filterWindow);\n for (var i = 1; i <= filterWindow; i++) {\n taps[i - 1] = lobeFunction(i * scale);\n }\n return taps;\n },\n\n /**\n * Generate vertex and shader sources from the necessary steps numbers\n * @param {Number} filterWindow\n */\n generateShader: function(filterWindow) {\n var offsets = new Array(filterWindow),\n fragmentShader = this.fragmentSourceTOP, filterWindow;\n\n for (var i = 1; i <= filterWindow; i++) {\n offsets[i - 1] = i + '.0 * uDelta';\n }\n\n fragmentShader += 'uniform float uTaps[' + filterWindow + '];\\n';\n fragmentShader += 'void main() {\\n';\n fragmentShader += ' vec4 color = texture2D(uTexture, vTexCoord);\\n';\n fragmentShader += ' float sum = 1.0;\\n';\n\n offsets.forEach(function(offset, i) {\n fragmentShader += ' color += texture2D(uTexture, vTexCoord + ' + offset + ') * uTaps[' + i + '];\\n';\n fragmentShader += ' color += texture2D(uTexture, vTexCoord - ' + offset + ') * uTaps[' + i + '];\\n';\n fragmentShader += ' sum += 2.0 * uTaps[' + i + '];\\n';\n });\n fragmentShader += ' gl_FragColor = color / sum;\\n';\n fragmentShader += '}';\n return fragmentShader;\n },\n\n fragmentSourceTOP: 'precision highp float;\\n' +\n 'uniform sampler2D uTexture;\\n' +\n 'uniform vec2 uDelta;\\n' +\n 'varying vec2 vTexCoord;\\n',\n\n /**\n * Apply the resize filter to the image\n * Determines whether to use WebGL or Canvas2D based on the options.webgl flag.\n *\n * @param {Object} options\n * @param {Number} options.passes The number of filters remaining to be executed\n * @param {Boolean} options.webgl Whether to use webgl to render the filter.\n * @param {WebGLTexture} options.sourceTexture The texture setup as the source to be filtered.\n * @param {WebGLTexture} options.targetTexture The texture where filtered output should be drawn.\n * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n */\n applyTo: function(options) {\n if (options.webgl) {\n options.passes++;\n this.width = options.sourceWidth;\n this.horizontal = true;\n this.dW = Math.round(this.width * this.scaleX);\n this.dH = options.sourceHeight;\n this.tempScale = this.dW / this.width;\n this.taps = this.getTaps();\n options.destinationWidth = this.dW;\n this._setupFrameBuffer(options);\n this.applyToWebGL(options);\n this._swapTextures(options);\n options.sourceWidth = options.destinationWidth;\n\n this.height = options.sourceHeight;\n this.horizontal = false;\n this.dH = Math.round(this.height * this.scaleY);\n this.tempScale = this.dH / this.height;\n this.taps = this.getTaps();\n options.destinationHeight = this.dH;\n this._setupFrameBuffer(options);\n this.applyToWebGL(options);\n this._swapTextures(options);\n options.sourceHeight = options.destinationHeight;\n }\n else {\n this.applyTo2d(options);\n }\n },\n\n isNeutralState: function() {\n return this.scaleX === 1 && this.scaleY === 1;\n },\n\n lanczosCreate: function(lobes) {\n return function(x) {\n if (x >= lobes || x <= -lobes) {\n return 0.0;\n }\n if (x < 1.19209290E-07 && x > -1.19209290E-07) {\n return 1.0;\n }\n x *= Math.PI;\n var xx = x / lobes;\n return (sin(x) / x) * sin(xx) / xx;\n };\n },\n\n /**\n * Applies filter to canvas element\n * @memberOf fabric.Image.filters.Resize.prototype\n * @param {Object} canvasEl Canvas element to apply filter to\n * @param {Number} scaleX\n * @param {Number} scaleY\n */\n applyTo2d: function(options) {\n var imageData = options.imageData,\n scaleX = this.scaleX,\n scaleY = this.scaleY;\n\n this.rcpScaleX = 1 / scaleX;\n this.rcpScaleY = 1 / scaleY;\n\n var oW = imageData.width, oH = imageData.height,\n dW = round(oW * scaleX), dH = round(oH * scaleY),\n newData;\n\n if (this.resizeType === 'sliceHack') {\n newData = this.sliceByTwo(options, oW, oH, dW, dH);\n }\n else if (this.resizeType === 'hermite') {\n newData = this.hermiteFastResize(options, oW, oH, dW, dH);\n }\n else if (this.resizeType === 'bilinear') {\n newData = this.bilinearFiltering(options, oW, oH, dW, dH);\n }\n else if (this.resizeType === 'lanczos') {\n newData = this.lanczosResize(options, oW, oH, dW, dH);\n }\n options.imageData = newData;\n },\n\n /**\n * Filter sliceByTwo\n * @param {Object} canvasEl Canvas element to apply filter to\n * @param {Number} oW Original Width\n * @param {Number} oH Original Height\n * @param {Number} dW Destination Width\n * @param {Number} dH Destination Height\n * @returns {ImageData}\n */\n sliceByTwo: function(options, oW, oH, dW, dH) {\n var imageData = options.imageData,\n mult = 0.5, doneW = false, doneH = false, stepW = oW * mult,\n stepH = oH * mult, resources = fabric.filterBackend.resources,\n tmpCanvas, ctx, sX = 0, sY = 0, dX = oW, dY = 0;\n if (!resources.sliceByTwo) {\n resources.sliceByTwo = document.createElement('canvas');\n }\n tmpCanvas = resources.sliceByTwo;\n if (tmpCanvas.width < oW * 1.5 || tmpCanvas.height < oH) {\n tmpCanvas.width = oW * 1.5;\n tmpCanvas.height = oH;\n }\n ctx = tmpCanvas.getContext('2d');\n ctx.clearRect(0, 0, oW * 1.5, oH);\n ctx.putImageData(imageData, 0, 0);\n\n dW = floor(dW);\n dH = floor(dH);\n\n while (!doneW || !doneH) {\n oW = stepW;\n oH = stepH;\n if (dW < floor(stepW * mult)) {\n stepW = floor(stepW * mult);\n }\n else {\n stepW = dW;\n doneW = true;\n }\n if (dH < floor(stepH * mult)) {\n stepH = floor(stepH * mult);\n }\n else {\n stepH = dH;\n doneH = true;\n }\n ctx.drawImage(tmpCanvas, sX, sY, oW, oH, dX, dY, stepW, stepH);\n sX = dX;\n sY = dY;\n dY += stepH;\n }\n return ctx.getImageData(sX, sY, dW, dH);\n },\n\n /**\n * Filter lanczosResize\n * @param {Object} canvasEl Canvas element to apply filter to\n * @param {Number} oW Original Width\n * @param {Number} oH Original Height\n * @param {Number} dW Destination Width\n * @param {Number} dH Destination Height\n * @returns {ImageData}\n */\n lanczosResize: function(options, oW, oH, dW, dH) {\n\n function process(u) {\n var v, i, weight, idx, a, red, green,\n blue, alpha, fX, fY;\n center.x = (u + 0.5) * ratioX;\n icenter.x = floor(center.x);\n for (v = 0; v < dH; v++) {\n center.y = (v + 0.5) * ratioY;\n icenter.y = floor(center.y);\n a = 0; red = 0; green = 0; blue = 0; alpha = 0;\n for (i = icenter.x - range2X; i <= icenter.x + range2X; i++) {\n if (i < 0 || i >= oW) {\n continue;\n }\n fX = floor(1000 * abs(i - center.x));\n if (!cacheLanc[fX]) {\n cacheLanc[fX] = { };\n }\n for (var j = icenter.y - range2Y; j <= icenter.y + range2Y; j++) {\n if (j < 0 || j >= oH) {\n continue;\n }\n fY = floor(1000 * abs(j - center.y));\n if (!cacheLanc[fX][fY]) {\n cacheLanc[fX][fY] = lanczos(sqrt(pow(fX * rcpRatioX, 2) + pow(fY * rcpRatioY, 2)) / 1000);\n }\n weight = cacheLanc[fX][fY];\n if (weight > 0) {\n idx = (j * oW + i) * 4;\n a += weight;\n red += weight * srcData[idx];\n green += weight * srcData[idx + 1];\n blue += weight * srcData[idx + 2];\n alpha += weight * srcData[idx + 3];\n }\n }\n }\n idx = (v * dW + u) * 4;\n destData[idx] = red / a;\n destData[idx + 1] = green / a;\n destData[idx + 2] = blue / a;\n destData[idx + 3] = alpha / a;\n }\n\n if (++u < dW) {\n return process(u);\n }\n else {\n return destImg;\n }\n }\n\n var srcData = options.imageData.data,\n destImg = options.ctx.createImageData(dW, dH),\n destData = destImg.data,\n lanczos = this.lanczosCreate(this.lanczosLobes),\n ratioX = this.rcpScaleX, ratioY = this.rcpScaleY,\n rcpRatioX = 2 / this.rcpScaleX, rcpRatioY = 2 / this.rcpScaleY,\n range2X = ceil(ratioX * this.lanczosLobes / 2),\n range2Y = ceil(ratioY * this.lanczosLobes / 2),\n cacheLanc = { }, center = { }, icenter = { };\n\n return process(0);\n },\n\n /**\n * bilinearFiltering\n * @param {Object} canvasEl Canvas element to apply filter to\n * @param {Number} oW Original Width\n * @param {Number} oH Original Height\n * @param {Number} dW Destination Width\n * @param {Number} dH Destination Height\n * @returns {ImageData}\n */\n bilinearFiltering: function(options, oW, oH, dW, dH) {\n var a, b, c, d, x, y, i, j, xDiff, yDiff, chnl,\n color, offset = 0, origPix, ratioX = this.rcpScaleX,\n ratioY = this.rcpScaleY,\n w4 = 4 * (oW - 1), img = options.imageData,\n pixels = img.data, destImage = options.ctx.createImageData(dW, dH),\n destPixels = destImage.data;\n for (i = 0; i < dH; i++) {\n for (j = 0; j < dW; j++) {\n x = floor(ratioX * j);\n y = floor(ratioY * i);\n xDiff = ratioX * j - x;\n yDiff = ratioY * i - y;\n origPix = 4 * (y * oW + x);\n\n for (chnl = 0; chnl < 4; chnl++) {\n a = pixels[origPix + chnl];\n b = pixels[origPix + 4 + chnl];\n c = pixels[origPix + w4 + chnl];\n d = pixels[origPix + w4 + 4 + chnl];\n color = a * (1 - xDiff) * (1 - yDiff) + b * xDiff * (1 - yDiff) +\n c * yDiff * (1 - xDiff) + d * xDiff * yDiff;\n destPixels[offset++] = color;\n }\n }\n }\n return destImage;\n },\n\n /**\n * hermiteFastResize\n * @param {Object} canvasEl Canvas element to apply filter to\n * @param {Number} oW Original Width\n * @param {Number} oH Original Height\n * @param {Number} dW Destination Width\n * @param {Number} dH Destination Height\n * @returns {ImageData}\n */\n hermiteFastResize: function(options, oW, oH, dW, dH) {\n var ratioW = this.rcpScaleX, ratioH = this.rcpScaleY,\n ratioWHalf = ceil(ratioW / 2),\n ratioHHalf = ceil(ratioH / 2),\n img = options.imageData, data = img.data,\n img2 = options.ctx.createImageData(dW, dH), data2 = img2.data;\n for (var j = 0; j < dH; j++) {\n for (var i = 0; i < dW; i++) {\n var x2 = (i + j * dW) * 4, weight = 0, weights = 0, weightsAlpha = 0,\n gxR = 0, gxG = 0, gxB = 0, gxA = 0, centerY = (j + 0.5) * ratioH;\n for (var yy = floor(j * ratioH); yy < (j + 1) * ratioH; yy++) {\n var dy = abs(centerY - (yy + 0.5)) / ratioHHalf,\n centerX = (i + 0.5) * ratioW, w0 = dy * dy;\n for (var xx = floor(i * ratioW); xx < (i + 1) * ratioW; xx++) {\n var dx = abs(centerX - (xx + 0.5)) / ratioWHalf,\n w = sqrt(w0 + dx * dx);\n /* eslint-disable max-depth */\n if (w > 1 && w < -1) {\n continue;\n }\n //hermite filter\n weight = 2 * w * w * w - 3 * w * w + 1;\n if (weight > 0) {\n dx = 4 * (xx + yy * oW);\n //alpha\n gxA += weight * data[dx + 3];\n weightsAlpha += weight;\n //colors\n if (data[dx + 3] < 255) {\n weight = weight * data[dx + 3] / 250;\n }\n gxR += weight * data[dx];\n gxG += weight * data[dx + 1];\n gxB += weight * data[dx + 2];\n weights += weight;\n }\n /* eslint-enable max-depth */\n }\n }\n data2[x2] = gxR / weights;\n data2[x2 + 1] = gxG / weights;\n data2[x2 + 2] = gxB / weights;\n data2[x2 + 3] = gxA / weightsAlpha;\n }\n }\n return img2;\n },\n\n /**\n * Returns object representation of an instance\n * @return {Object} Object representation of an instance\n */\n toObject: function() {\n return {\n type: this.type,\n scaleX: this.scaleX,\n scaleY: this.scaleY,\n resizeType: this.resizeType,\n lanczosLobes: this.lanczosLobes\n };\n }\n });\n\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {Function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.Resize} Instance of fabric.Image.filters.Resize\n */\n fabric.Image.filters.Resize.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * Contrast filter class\n * @class fabric.Image.filters.Contrast\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link fabric.Image.filters.Contrast#initialize} for constructor definition\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example\n * var filter = new fabric.Image.filters.Contrast({\n * contrast: 0.25\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n */\n filters.Contrast = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Contrast.prototype */ {\n\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'Contrast',\n\n fragmentSource: 'precision highp float;\\n' +\n 'uniform sampler2D uTexture;\\n' +\n 'uniform float uContrast;\\n' +\n 'varying vec2 vTexCoord;\\n' +\n 'void main() {\\n' +\n 'vec4 color = texture2D(uTexture, vTexCoord);\\n' +\n 'float contrastF = 1.015 * (uContrast + 1.0) / (1.0 * (1.015 - uContrast));\\n' +\n 'color.rgb = contrastF * (color.rgb - 0.5) + 0.5;\\n' +\n 'gl_FragColor = color;\\n' +\n '}',\n\n /**\n * contrast value, range from -1 to 1.\n * @param {Number} contrast\n * @default 0\n */\n contrast: 0,\n\n mainParameter: 'contrast',\n\n /**\n * Constructor\n * @memberOf fabric.Image.filters.Contrast.prototype\n * @param {Object} [options] Options object\n * @param {Number} [options.contrast=0] Value to contrast the image up (-1...1)\n */\n\n /**\n * Apply the Contrast operation to a Uint8Array representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8Array to be filtered.\n */\n applyTo2d: function(options) {\n if (this.contrast === 0) {\n return;\n }\n var imageData = options.imageData, i, len,\n data = imageData.data, len = data.length,\n contrast = Math.floor(this.contrast * 255),\n contrastF = 259 * (contrast + 255) / (255 * (259 - contrast));\n\n for (i = 0; i < len; i += 4) {\n data[i] = contrastF * (data[i] - 128) + 128;\n data[i + 1] = contrastF * (data[i + 1] - 128) + 128;\n data[i + 2] = contrastF * (data[i + 2] - 128) + 128;\n }\n },\n\n /**\n * Return WebGL uniform locations for this filter's shader.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {WebGLShaderProgram} program This filter's compiled shader program.\n */\n getUniformLocations: function(gl, program) {\n return {\n uContrast: gl.getUniformLocation(program, 'uContrast'),\n };\n },\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData: function(gl, uniformLocations) {\n gl.uniform1f(uniformLocations.uContrast, this.contrast);\n },\n });\n\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.Contrast} Instance of fabric.Image.filters.Contrast\n */\n fabric.Image.filters.Contrast.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * Saturate filter class\n * @class fabric.Image.filters.Saturation\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link fabric.Image.filters.Saturation#initialize} for constructor definition\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example\n * var filter = new fabric.Image.filters.Saturation({\n * saturation: 100\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n */\n filters.Saturation = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Saturation.prototype */ {\n\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'Saturation',\n\n fragmentSource: 'precision highp float;\\n' +\n 'uniform sampler2D uTexture;\\n' +\n 'uniform float uSaturation;\\n' +\n 'varying vec2 vTexCoord;\\n' +\n 'void main() {\\n' +\n 'vec4 color = texture2D(uTexture, vTexCoord);\\n' +\n 'float rgMax = max(color.r, color.g);\\n' +\n 'float rgbMax = max(rgMax, color.b);\\n' +\n 'color.r += rgbMax != color.r ? (rgbMax - color.r) * uSaturation : 0.00;\\n' +\n 'color.g += rgbMax != color.g ? (rgbMax - color.g) * uSaturation : 0.00;\\n' +\n 'color.b += rgbMax != color.b ? (rgbMax - color.b) * uSaturation : 0.00;\\n' +\n 'gl_FragColor = color;\\n' +\n '}',\n\n saturation: 0,\n\n mainParameter: 'saturation',\n\n /**\n * Constructor\n * @memberOf fabric.Image.filters.Saturate.prototype\n * @param {Object} [options] Options object\n * @param {Number} [options.saturate=0] Value to saturate the image (-1...1)\n */\n\n /**\n * Apply the Saturation operation to a Uint8ClampedArray representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n */\n applyTo2d: function(options) {\n if (this.saturation === 0) {\n return;\n }\n var imageData = options.imageData,\n data = imageData.data, len = data.length,\n adjust = -this.saturation, i, max;\n\n for (i = 0; i < len; i += 4) {\n max = Math.max(data[i], data[i + 1], data[i + 2]);\n data[i] += max !== data[i] ? (max - data[i]) * adjust : 0;\n data[i + 1] += max !== data[i + 1] ? (max - data[i + 1]) * adjust : 0;\n data[i + 2] += max !== data[i + 2] ? (max - data[i + 2]) * adjust : 0;\n }\n },\n\n /**\n * Return WebGL uniform locations for this filter's shader.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {WebGLShaderProgram} program This filter's compiled shader program.\n */\n getUniformLocations: function(gl, program) {\n return {\n uSaturation: gl.getUniformLocation(program, 'uSaturation'),\n };\n },\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData: function(gl, uniformLocations) {\n gl.uniform1f(uniformLocations.uSaturation, -this.saturation);\n },\n });\n\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {Function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.Saturation} Instance of fabric.Image.filters.Saturate\n */\n fabric.Image.filters.Saturation.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * Blur filter class\n * @class fabric.Image.filters.Blur\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link fabric.Image.filters.Blur#initialize} for constructor definition\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example\n * var filter = new fabric.Image.filters.Blur({\n * blur: 0.5\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n * canvas.renderAll();\n */\n filters.Blur = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Blur.prototype */ {\n\n type: 'Blur',\n\n /*\n'gl_FragColor = vec4(0.0);',\n'gl_FragColor += texture2D(texture, vTexCoord + -7 * uDelta)*0.0044299121055113265;',\n'gl_FragColor += texture2D(texture, vTexCoord + -6 * uDelta)*0.00895781211794;',\n'gl_FragColor += texture2D(texture, vTexCoord + -5 * uDelta)*0.0215963866053;',\n'gl_FragColor += texture2D(texture, vTexCoord + -4 * uDelta)*0.0443683338718;',\n'gl_FragColor += texture2D(texture, vTexCoord + -3 * uDelta)*0.0776744219933;',\n'gl_FragColor += texture2D(texture, vTexCoord + -2 * uDelta)*0.115876621105;',\n'gl_FragColor += texture2D(texture, vTexCoord + -1 * uDelta)*0.147308056121;',\n'gl_FragColor += texture2D(texture, vTexCoord )*0.159576912161;',\n'gl_FragColor += texture2D(texture, vTexCoord + 1 * uDelta)*0.147308056121;',\n'gl_FragColor += texture2D(texture, vTexCoord + 2 * uDelta)*0.115876621105;',\n'gl_FragColor += texture2D(texture, vTexCoord + 3 * uDelta)*0.0776744219933;',\n'gl_FragColor += texture2D(texture, vTexCoord + 4 * uDelta)*0.0443683338718;',\n'gl_FragColor += texture2D(texture, vTexCoord + 5 * uDelta)*0.0215963866053;',\n'gl_FragColor += texture2D(texture, vTexCoord + 6 * uDelta)*0.00895781211794;',\n'gl_FragColor += texture2D(texture, vTexCoord + 7 * uDelta)*0.0044299121055113265;',\n*/\n\n /* eslint-disable max-len */\n fragmentSource: 'precision highp float;\\n' +\n 'uniform sampler2D uTexture;\\n' +\n 'uniform vec2 uDelta;\\n' +\n 'varying vec2 vTexCoord;\\n' +\n 'const float nSamples = 15.0;\\n' +\n 'vec3 v3offset = vec3(12.9898, 78.233, 151.7182);\\n' +\n 'float random(vec3 scale) {\\n' +\n /* use the fragment position for a different seed per-pixel */\n 'return fract(sin(dot(gl_FragCoord.xyz, scale)) * 43758.5453);\\n' +\n '}\\n' +\n 'void main() {\\n' +\n 'vec4 color = vec4(0.0);\\n' +\n 'float total = 0.0;\\n' +\n 'float offset = random(v3offset);\\n' +\n 'for (float t = -nSamples; t <= nSamples; t++) {\\n' +\n 'float percent = (t + offset - 0.5) / nSamples;\\n' +\n 'float weight = 1.0 - abs(percent);\\n' +\n 'color += texture2D(uTexture, vTexCoord + uDelta * percent) * weight;\\n' +\n 'total += weight;\\n' +\n '}\\n' +\n 'gl_FragColor = color / total;\\n' +\n '}',\n /* eslint-enable max-len */\n\n /**\n * blur value, in percentage of image dimensions.\n * specific to keep the image blur constant at different resolutions\n * range bewteen 0 and 1.\n */\n blur: 0,\n\n mainParameter: 'blur',\n\n applyTo: function(options) {\n if (options.webgl) {\n // this aspectRatio is used to give the same blur to vertical and horizontal\n this.aspectRatio = options.sourceWidth / options.sourceHeight;\n options.passes++;\n this._setupFrameBuffer(options);\n this.horizontal = true;\n this.applyToWebGL(options);\n this._swapTextures(options);\n this._setupFrameBuffer(options);\n this.horizontal = false;\n this.applyToWebGL(options);\n this._swapTextures(options);\n }\n else {\n this.applyTo2d(options);\n }\n },\n\n applyTo2d: function(options) {\n // paint canvasEl with current image data.\n //options.ctx.putImageData(options.imageData, 0, 0);\n options.imageData = this.simpleBlur(options);\n },\n\n simpleBlur: function(options) {\n var resources = options.filterBackend.resources, canvas1, canvas2,\n width = options.imageData.width,\n height = options.imageData.height;\n\n if (!resources.blurLayer1) {\n resources.blurLayer1 = fabric.util.createCanvasElement();\n resources.blurLayer2 = fabric.util.createCanvasElement();\n }\n canvas1 = resources.blurLayer1;\n canvas2 = resources.blurLayer2;\n if (canvas1.width !== width || canvas1.height !== height) {\n canvas2.width = canvas1.width = width;\n canvas2.height = canvas1.height = height;\n }\n var ctx1 = canvas1.getContext('2d'),\n ctx2 = canvas2.getContext('2d'),\n nSamples = 15,\n random, percent, j, i,\n blur = this.blur * 0.06 * 0.5;\n\n // load first canvas\n ctx1.putImageData(options.imageData, 0, 0);\n ctx2.clearRect(0, 0, width, height);\n\n for (i = -nSamples; i <= nSamples; i++) {\n random = (Math.random() - 0.5) / 4;\n percent = i / nSamples;\n j = blur * percent * width + random;\n ctx2.globalAlpha = 1 - Math.abs(percent);\n ctx2.drawImage(canvas1, j, random);\n ctx1.drawImage(canvas2, 0, 0);\n ctx2.globalAlpha = 1;\n ctx2.clearRect(0, 0, canvas2.width, canvas2.height);\n }\n for (i = -nSamples; i <= nSamples; i++) {\n random = (Math.random() - 0.5) / 4;\n percent = i / nSamples;\n j = blur * percent * height + random;\n ctx2.globalAlpha = 1 - Math.abs(percent);\n ctx2.drawImage(canvas1, random, j);\n ctx1.drawImage(canvas2, 0, 0);\n ctx2.globalAlpha = 1;\n ctx2.clearRect(0, 0, canvas2.width, canvas2.height);\n }\n options.ctx.drawImage(canvas1, 0, 0);\n var newImageData = options.ctx.getImageData(0, 0, canvas1.width, canvas1.height);\n ctx1.globalAlpha = 1;\n ctx1.clearRect(0, 0, canvas1.width, canvas1.height);\n return newImageData;\n },\n\n /**\n * Return WebGL uniform locations for this filter's shader.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {WebGLShaderProgram} program This filter's compiled shader program.\n */\n getUniformLocations: function(gl, program) {\n return {\n delta: gl.getUniformLocation(program, 'uDelta'),\n };\n },\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData: function(gl, uniformLocations) {\n var delta = this.chooseRightDelta();\n gl.uniform2fv(uniformLocations.delta, delta);\n },\n\n /**\n * choose right value of image percentage to blur with\n * @returns {Array} a numeric array with delta values\n */\n chooseRightDelta: function() {\n var blurScale = 1, delta = [0, 0], blur;\n if (this.horizontal) {\n if (this.aspectRatio > 1) {\n // image is wide, i want to shrink radius horizontal\n blurScale = 1 / this.aspectRatio;\n }\n }\n else {\n if (this.aspectRatio < 1) {\n // image is tall, i want to shrink radius vertical\n blurScale = this.aspectRatio;\n }\n }\n blur = blurScale * this.blur * 0.12;\n if (this.horizontal) {\n delta[0] = blur;\n }\n else {\n delta[1] = blur;\n }\n return delta;\n },\n });\n\n /**\n * Deserialize a JSON definition of a BlurFilter into a concrete instance.\n */\n filters.Blur.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * Gamma filter class\n * @class fabric.Image.filters.Gamma\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link fabric.Image.filters.Gamma#initialize} for constructor definition\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example\n * var filter = new fabric.Image.filters.Gamma({\n * gamma: [1, 0.5, 2.1]\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n */\n filters.Gamma = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Gamma.prototype */ {\n\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'Gamma',\n\n fragmentSource: 'precision highp float;\\n' +\n 'uniform sampler2D uTexture;\\n' +\n 'uniform vec3 uGamma;\\n' +\n 'varying vec2 vTexCoord;\\n' +\n 'void main() {\\n' +\n 'vec4 color = texture2D(uTexture, vTexCoord);\\n' +\n 'vec3 correction = (1.0 / uGamma);\\n' +\n 'color.r = pow(color.r, correction.r);\\n' +\n 'color.g = pow(color.g, correction.g);\\n' +\n 'color.b = pow(color.b, correction.b);\\n' +\n 'gl_FragColor = color;\\n' +\n 'gl_FragColor.rgb *= color.a;\\n' +\n '}',\n\n /**\n * Gamma array value, from 0.01 to 2.2.\n * @param {Array} gamma\n * @default\n */\n gamma: [1, 1, 1],\n\n /**\n * Describe the property that is the filter parameter\n * @param {String} m\n * @default\n */\n mainParameter: 'gamma',\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n */\n initialize: function(options) {\n this.gamma = [1, 1, 1];\n filters.BaseFilter.prototype.initialize.call(this, options);\n },\n\n /**\n * Apply the Gamma operation to a Uint8Array representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8Array to be filtered.\n */\n applyTo2d: function(options) {\n var imageData = options.imageData, data = imageData.data,\n gamma = this.gamma, len = data.length,\n rInv = 1 / gamma[0], gInv = 1 / gamma[1],\n bInv = 1 / gamma[2], i;\n\n if (!this.rVals) {\n // eslint-disable-next-line\n this.rVals = new Uint8Array(256);\n // eslint-disable-next-line\n this.gVals = new Uint8Array(256);\n // eslint-disable-next-line\n this.bVals = new Uint8Array(256);\n }\n\n // This is an optimization - pre-compute a look-up table for each color channel\n // instead of performing these pow calls for each pixel in the image.\n for (i = 0, len = 256; i < len; i++) {\n this.rVals[i] = Math.pow(i / 255, rInv) * 255;\n this.gVals[i] = Math.pow(i / 255, gInv) * 255;\n this.bVals[i] = Math.pow(i / 255, bInv) * 255;\n }\n for (i = 0, len = data.length; i < len; i += 4) {\n data[i] = this.rVals[data[i]];\n data[i + 1] = this.gVals[data[i + 1]];\n data[i + 2] = this.bVals[data[i + 2]];\n }\n },\n\n /**\n * Return WebGL uniform locations for this filter's shader.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {WebGLShaderProgram} program This filter's compiled shader program.\n */\n getUniformLocations: function(gl, program) {\n return {\n uGamma: gl.getUniformLocation(program, 'uGamma'),\n };\n },\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData: function(gl, uniformLocations) {\n gl.uniform3fv(uniformLocations.uGamma, this.gamma);\n },\n });\n\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.Gamma} Instance of fabric.Image.filters.Gamma\n */\n fabric.Image.filters.Gamma.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * A container class that knows how to apply a sequence of filters to an input image.\n */\n filters.Composed = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Composed.prototype */ {\n\n type: 'Composed',\n\n /**\n * A non sparse array of filters to apply\n */\n subFilters: [],\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n */\n initialize: function(options) {\n this.callSuper('initialize', options);\n // create a new array instead mutating the prototype with push\n this.subFilters = this.subFilters.slice(0);\n },\n\n /**\n * Apply this container's filters to the input image provided.\n *\n * @param {Object} options\n * @param {Number} options.passes The number of filters remaining to be applied.\n */\n applyTo: function(options) {\n options.passes += this.subFilters.length - 1;\n this.subFilters.forEach(function(filter) {\n filter.applyTo(options);\n });\n },\n\n /**\n * Serialize this filter into JSON.\n *\n * @returns {Object} A JSON representation of this filter.\n */\n toObject: function() {\n return fabric.util.object.extend(this.callSuper('toObject'), {\n subFilters: this.subFilters.map(function(filter) { return filter.toObject(); }),\n });\n },\n\n isNeutralState: function() {\n return !this.subFilters.some(function(filter) { return !filter.isNeutralState(); });\n }\n });\n\n /**\n * Deserialize a JSON definition of a ComposedFilter into a concrete instance.\n */\n fabric.Image.filters.Composed.fromObject = function(object, callback) {\n var filters = object.subFilters || [],\n subFilters = filters.map(function(filter) {\n return new fabric.Image.filters[filter.type](filter);\n }),\n instance = new fabric.Image.filters.Composed({ subFilters: subFilters });\n callback && callback(instance);\n return instance;\n };\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n\n /**\n * HueRotation filter class\n * @class fabric.Image.filters.HueRotation\n * @memberOf fabric.Image.filters\n * @extends fabric.Image.filters.BaseFilter\n * @see {@link fabric.Image.filters.HueRotation#initialize} for constructor definition\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @example\n * var filter = new fabric.Image.filters.HueRotation({\n * rotation: -0.5\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n */\n filters.HueRotation = createClass(filters.ColorMatrix, /** @lends fabric.Image.filters.HueRotation.prototype */ {\n\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'HueRotation',\n\n /**\n * HueRotation value, from -1 to 1.\n * the unit is radians\n * @param {Number} myParameter\n * @default\n */\n rotation: 0,\n\n /**\n * Describe the property that is the filter parameter\n * @param {String} m\n * @default\n */\n mainParameter: 'rotation',\n\n calculateMatrix: function() {\n var rad = this.rotation * Math.PI, cos = fabric.util.cos(rad), sin = fabric.util.sin(rad),\n aThird = 1 / 3, aThirdSqtSin = Math.sqrt(aThird) * sin, OneMinusCos = 1 - cos;\n this.matrix = [\n 1, 0, 0, 0, 0,\n 0, 1, 0, 0, 0,\n 0, 0, 1, 0, 0,\n 0, 0, 0, 1, 0\n ];\n this.matrix[0] = cos + OneMinusCos / 3;\n this.matrix[1] = aThird * OneMinusCos - aThirdSqtSin;\n this.matrix[2] = aThird * OneMinusCos + aThirdSqtSin;\n this.matrix[5] = aThird * OneMinusCos + aThirdSqtSin;\n this.matrix[6] = cos + aThird * OneMinusCos;\n this.matrix[7] = aThird * OneMinusCos - aThirdSqtSin;\n this.matrix[10] = aThird * OneMinusCos - aThirdSqtSin;\n this.matrix[11] = aThird * OneMinusCos + aThirdSqtSin;\n this.matrix[12] = cos + aThird * OneMinusCos;\n },\n\n /**\n * HueRotation isNeutralState implementation\n * Used only in image applyFilters to discard filters that will not have an effect\n * on the image\n * @param {Object} options\n **/\n isNeutralState: function(options) {\n this.calculateMatrix();\n return filters.BaseFilter.prototype.isNeutralState.call(this, options);\n },\n\n /**\n * Apply this filter to the input image data provided.\n *\n * Determines whether to use WebGL or Canvas2D based on the options.webgl flag.\n *\n * @param {Object} options\n * @param {Number} options.passes The number of filters remaining to be executed\n * @param {Boolean} options.webgl Whether to use webgl to render the filter.\n * @param {WebGLTexture} options.sourceTexture The texture setup as the source to be filtered.\n * @param {WebGLTexture} options.targetTexture The texture where filtered output should be drawn.\n * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n */\n applyTo: function(options) {\n this.calculateMatrix();\n filters.BaseFilter.prototype.applyTo.call(this, options);\n },\n\n });\n\n /**\n * Returns filter instance from an object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] to be invoked after filter creation\n * @return {fabric.Image.filters.HueRotation} Instance of fabric.Image.filters.HueRotation\n */\n fabric.Image.filters.HueRotation.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = { }),\n clone = fabric.util.object.clone;\n\n if (fabric.Text) {\n fabric.warn('fabric.Text is already defined');\n return;\n }\n\n /**\n * Text class\n * @class fabric.Text\n * @extends fabric.Object\n * @return {fabric.Text} thisArg\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#text}\n * @see {@link fabric.Text#initialize} for constructor definition\n */\n fabric.Text = fabric.util.createClass(fabric.Object, /** @lends fabric.Text.prototype */ {\n\n /**\n * Properties which when set cause object to change dimensions\n * @type Array\n * @private\n */\n _dimensionAffectingProps: [\n 'fontSize',\n 'fontWeight',\n 'fontFamily',\n 'fontStyle',\n 'lineHeight',\n 'text',\n 'charSpacing',\n 'textAlign',\n 'styles',\n ],\n\n /**\n * @private\n */\n _reNewline: /\\r?\\n/,\n\n /**\n * Use this regular expression to filter for whitespaces that is not a new line.\n * Mostly used when text is 'justify' aligned.\n * @private\n */\n _reSpacesAndTabs: /[ \\t\\r]/g,\n\n /**\n * Use this regular expression to filter for whitespace that is not a new line.\n * Mostly used when text is 'justify' aligned.\n * @private\n */\n _reSpaceAndTab: /[ \\t\\r]/,\n\n /**\n * Use this regular expression to filter consecutive groups of non spaces.\n * Mostly used when text is 'justify' aligned.\n * @private\n */\n _reWords: /\\S+/g,\n\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'text',\n\n /**\n * Font size (in pixels)\n * @type Number\n * @default\n */\n fontSize: 40,\n\n /**\n * Font weight (e.g. bold, normal, 400, 600, 800)\n * @type {(Number|String)}\n * @default\n */\n fontWeight: 'normal',\n\n /**\n * Font family\n * @type String\n * @default\n */\n fontFamily: 'Times New Roman',\n\n /**\n * Text decoration underline.\n * @type Boolean\n * @default\n */\n underline: false,\n\n /**\n * Text decoration overline.\n * @type Boolean\n * @default\n */\n overline: false,\n\n /**\n * Text decoration linethrough.\n * @type Boolean\n * @default\n */\n linethrough: false,\n\n /**\n * Text alignment. Possible values: \"left\", \"center\", \"right\", \"justify\",\n * \"justify-left\", \"justify-center\" or \"justify-right\".\n * @type String\n * @default\n */\n textAlign: 'left',\n\n /**\n * Font style . Possible values: \"\", \"normal\", \"italic\" or \"oblique\".\n * @type String\n * @default\n */\n fontStyle: 'normal',\n\n /**\n * Line height\n * @type Number\n * @default\n */\n lineHeight: 1.16,\n\n /**\n * Superscript schema object (minimum overlap)\n * @type {Object}\n * @default\n */\n superscript: {\n size: 0.60, // fontSize factor\n baseline: -0.35 // baseline-shift factor (upwards)\n },\n\n /**\n * Subscript schema object (minimum overlap)\n * @type {Object}\n * @default\n */\n subscript: {\n size: 0.60, // fontSize factor\n baseline: 0.11 // baseline-shift factor (downwards)\n },\n\n /**\n * Background color of text lines\n * @type String\n * @default\n */\n textBackgroundColor: '',\n\n /**\n * List of properties to consider when checking if\n * state of an object is changed ({@link fabric.Object#hasStateChanged})\n * as well as for history (undo/redo) purposes\n * @type Array\n */\n stateProperties: fabric.Object.prototype.stateProperties.concat('fontFamily',\n 'fontWeight',\n 'fontSize',\n 'text',\n 'underline',\n 'overline',\n 'linethrough',\n 'textAlign',\n 'fontStyle',\n 'lineHeight',\n 'textBackgroundColor',\n 'charSpacing',\n 'styles'),\n\n /**\n * List of properties to consider when checking if cache needs refresh\n * @type Array\n */\n cacheProperties: fabric.Object.prototype.cacheProperties.concat('fontFamily',\n 'fontWeight',\n 'fontSize',\n 'text',\n 'underline',\n 'overline',\n 'linethrough',\n 'textAlign',\n 'fontStyle',\n 'lineHeight',\n 'textBackgroundColor',\n 'charSpacing',\n 'styles'),\n\n /**\n * When defined, an object is rendered via stroke and this property specifies its color.\n * <b>Backwards incompatibility note:</b> This property was named \"strokeStyle\" until v1.1.6\n * @type String\n * @default\n */\n stroke: null,\n\n /**\n * Shadow object representing shadow of this shape.\n * <b>Backwards incompatibility note:</b> This property was named \"textShadow\" (String) until v1.2.11\n * @type fabric.Shadow\n * @default\n */\n shadow: null,\n\n /**\n * @private\n */\n _fontSizeFraction: 0.222,\n\n /**\n * @private\n */\n offsets: {\n underline: 0.10,\n linethrough: -0.315,\n overline: -0.88\n },\n\n /**\n * Text Line proportion to font Size (in pixels)\n * @type Number\n * @default\n */\n _fontSizeMult: 1.13,\n\n /**\n * additional space between characters\n * expressed in thousands of em unit\n * @type Number\n * @default\n */\n charSpacing: 0,\n\n /**\n * Object containing character styles - top-level properties -> line numbers,\n * 2nd-level properties - charater numbers\n * @type Object\n * @default\n */\n styles: null,\n\n /**\n * Reference to a context to measure text char or couple of chars\n * the cacheContext of the canvas will be used or a freshly created one if the object is not on canvas\n * once created it will be referenced on fabric._measuringContext to avoide creating a canvas for every\n * text object created.\n * @type {CanvasRenderingContext2D}\n * @default\n */\n _measuringContext: null,\n\n /**\n * Baseline shift, stlyes only, keep at 0 for the main text object\n * @type {Number}\n * @default\n */\n deltaY: 0,\n\n /**\n * Array of properties that define a style unit (of 'styles').\n * @type {Array}\n * @default\n */\n _styleProperties: [\n 'stroke',\n 'strokeWidth',\n 'fill',\n 'fontFamily',\n 'fontSize',\n 'fontWeight',\n 'fontStyle',\n 'underline',\n 'overline',\n 'linethrough',\n 'deltaY',\n 'textBackgroundColor',\n ],\n\n /**\n * contains characters bounding boxes\n */\n __charBounds: [],\n\n /**\n * use this size when measuring text. To avoid IE11 rounding errors\n * @type {Number}\n * @default\n * @readonly\n * @private\n */\n CACHE_FONT_SIZE: 400,\n\n /**\n * contains the min text width to avoid getting 0\n * @type {Number}\n * @default\n */\n MIN_TEXT_WIDTH: 2,\n\n /**\n * Constructor\n * @param {String} text Text string\n * @param {Object} [options] Options object\n * @return {fabric.Text} thisArg\n */\n initialize: function(text, options) {\n this.styles = options ? (options.styles || { }) : { };\n this.text = text;\n this.__skipDimension = true;\n this.callSuper('initialize', options);\n this.__skipDimension = false;\n this.initDimensions();\n this.setCoords();\n this.setupState({ propertySet: '_dimensionAffectingProps' });\n },\n\n /**\n * Return a contex for measurement of text string.\n * if created it gets stored for reuse\n * @param {String} text Text string\n * @param {Object} [options] Options object\n * @return {fabric.Text} thisArg\n */\n getMeasuringContext: function() {\n // if we did not return we have to measure something.\n if (!fabric._measuringContext) {\n fabric._measuringContext = this.canvas && this.canvas.contextCache ||\n fabric.util.createCanvasElement().getContext('2d');\n }\n return fabric._measuringContext;\n },\n\n /**\n * @private\n * Divides text into lines of text and lines of graphemes.\n */\n _splitText: function() {\n var newLines = this._splitTextIntoLines(this.text);\n this.textLines = newLines.lines;\n this._textLines = newLines.graphemeLines;\n this._unwrappedTextLines = newLines._unwrappedLines;\n this._text = newLines.graphemeText;\n return newLines;\n },\n\n /**\n * Initialize or update text dimensions.\n * Updates this.width and this.height with the proper values.\n * Does not return dimensions.\n */\n initDimensions: function() {\n if (this.__skipDimension) {\n return;\n }\n this._splitText();\n this._clearCache();\n this.width = this.calcTextWidth() || this.cursorWidth || this.MIN_TEXT_WIDTH;\n if (this.textAlign.indexOf('justify') !== -1) {\n // once text is measured we need to make space fatter to make justified text.\n this.enlargeSpaces();\n }\n this.height = this.calcTextHeight();\n this.saveState({ propertySet: '_dimensionAffectingProps' });\n },\n\n /**\n * Enlarge space boxes and shift the others\n */\n enlargeSpaces: function() {\n var diffSpace, currentLineWidth, numberOfSpaces, accumulatedSpace, line, charBound, spaces;\n for (var i = 0, len = this._textLines.length; i < len; i++) {\n if (this.textAlign !== 'justify' && (i === len - 1 || this.isEndOfWrapping(i))) {\n continue;\n }\n accumulatedSpace = 0;\n line = this._textLines[i];\n currentLineWidth = this.getLineWidth(i);\n if (currentLineWidth < this.width && (spaces = this.textLines[i].match(this._reSpacesAndTabs))) {\n numberOfSpaces = spaces.length;\n diffSpace = (this.width - currentLineWidth) / numberOfSpaces;\n for (var j = 0, jlen = line.length; j <= jlen; j++) {\n charBound = this.__charBounds[i][j];\n if (this._reSpaceAndTab.test(line[j])) {\n charBound.width += diffSpace;\n charBound.kernedWidth += diffSpace;\n charBound.left += accumulatedSpace;\n accumulatedSpace += diffSpace;\n }\n else {\n charBound.left += accumulatedSpace;\n }\n }\n }\n }\n },\n\n /**\n * Detect if the text line is ended with an hard break\n * text and itext do not have wrapping, return false\n * @return {Boolean}\n */\n isEndOfWrapping: function(lineIndex) {\n return lineIndex === this._textLines.length - 1;\n },\n\n /**\n * Detect if a line has a linebreak and so we need to account for it when moving\n * and counting style.\n * It return always for text and Itext.\n * @return Number\n */\n missingNewlineOffset: function() {\n return 1;\n },\n\n /**\n * Returns string representation of an instance\n * @return {String} String representation of text object\n */\n toString: function() {\n return '#<fabric.Text (' + this.complexity() +\n '): { \"text\": \"' + this.text + '\", \"fontFamily\": \"' + this.fontFamily + '\" }>';\n },\n\n /**\n * Return the dimension and the zoom level needed to create a cache canvas\n * big enough to host the object to be cached.\n * @private\n * @param {Object} dim.x width of object to be cached\n * @param {Object} dim.y height of object to be cached\n * @return {Object}.width width of canvas\n * @return {Object}.height height of canvas\n * @return {Object}.zoomX zoomX zoom value to unscale the canvas before drawing cache\n * @return {Object}.zoomY zoomY zoom value to unscale the canvas before drawing cache\n */\n _getCacheCanvasDimensions: function() {\n var dims = this.callSuper('_getCacheCanvasDimensions');\n var fontSize = this.fontSize;\n dims.width += fontSize * dims.zoomX;\n dims.height += fontSize * dims.zoomY;\n return dims;\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _render: function(ctx) {\n this._setTextStyles(ctx);\n this._renderTextLinesBackground(ctx);\n this._renderTextDecoration(ctx, 'underline');\n this._renderText(ctx);\n this._renderTextDecoration(ctx, 'overline');\n this._renderTextDecoration(ctx, 'linethrough');\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderText: function(ctx) {\n if (this.paintFirst === 'stroke') {\n this._renderTextStroke(ctx);\n this._renderTextFill(ctx);\n }\n else {\n this._renderTextFill(ctx);\n this._renderTextStroke(ctx);\n }\n },\n\n /**\n * Set the font parameter of the context with the object properties or with charStyle\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Object} [charStyle] object with font style properties\n * @param {String} [charStyle.fontFamily] Font Family\n * @param {Number} [charStyle.fontSize] Font size in pixels. ( without px suffix )\n * @param {String} [charStyle.fontWeight] Font weight\n * @param {String} [charStyle.fontStyle] Font style (italic|normal)\n */\n _setTextStyles: function(ctx, charStyle, forMeasuring) {\n ctx.textBaseline = 'alphabetic';\n ctx.font = this._getFontDeclaration(charStyle, forMeasuring);\n },\n\n /**\n * calculate and return the text Width measuring each line.\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @return {Number} Maximum width of fabric.Text object\n */\n calcTextWidth: function() {\n var maxWidth = this.getLineWidth(0);\n\n for (var i = 1, len = this._textLines.length; i < len; i++) {\n var currentLineWidth = this.getLineWidth(i);\n if (currentLineWidth > maxWidth) {\n maxWidth = currentLineWidth;\n }\n }\n return maxWidth;\n },\n\n /**\n * @private\n * @param {String} method Method name (\"fillText\" or \"strokeText\")\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {String} line Text to render\n * @param {Number} left Left position of text\n * @param {Number} top Top position of text\n * @param {Number} lineIndex Index of a line in a text\n */\n _renderTextLine: function(method, ctx, line, left, top, lineIndex) {\n this._renderChars(method, ctx, line, left, top, lineIndex);\n },\n\n /**\n * Renders the text background for lines, taking care of style\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderTextLinesBackground: function(ctx) {\n if (!this.textBackgroundColor && !this.styleHas('textBackgroundColor')) {\n return;\n }\n var lineTopOffset = 0, heightOfLine,\n lineLeftOffset, originalFill = ctx.fillStyle,\n line, lastColor,\n leftOffset = this._getLeftOffset(),\n topOffset = this._getTopOffset(),\n boxStart = 0, boxWidth = 0, charBox, currentColor;\n\n for (var i = 0, len = this._textLines.length; i < len; i++) {\n heightOfLine = this.getHeightOfLine(i);\n if (!this.textBackgroundColor && !this.styleHas('textBackgroundColor', i)) {\n lineTopOffset += heightOfLine;\n continue;\n }\n line = this._textLines[i];\n lineLeftOffset = this._getLineLeftOffset(i);\n boxWidth = 0;\n boxStart = 0;\n lastColor = this.getValueOfPropertyAt(i, 0, 'textBackgroundColor');\n for (var j = 0, jlen = line.length; j < jlen; j++) {\n charBox = this.__charBounds[i][j];\n currentColor = this.getValueOfPropertyAt(i, j, 'textBackgroundColor');\n if (currentColor !== lastColor) {\n ctx.fillStyle = lastColor;\n lastColor && ctx.fillRect(\n leftOffset + lineLeftOffset + boxStart,\n topOffset + lineTopOffset,\n boxWidth,\n heightOfLine / this.lineHeight\n );\n boxStart = charBox.left;\n boxWidth = charBox.width;\n lastColor = currentColor;\n }\n else {\n boxWidth += charBox.kernedWidth;\n }\n }\n if (currentColor) {\n ctx.fillStyle = currentColor;\n ctx.fillRect(\n leftOffset + lineLeftOffset + boxStart,\n topOffset + lineTopOffset,\n boxWidth,\n heightOfLine / this.lineHeight\n );\n }\n lineTopOffset += heightOfLine;\n }\n ctx.fillStyle = originalFill;\n // if there is text background color no\n // other shadows should be casted\n this._removeShadow(ctx);\n },\n\n /**\n * @private\n * @param {Object} decl style declaration for cache\n * @param {String} decl.fontFamily fontFamily\n * @param {String} decl.fontStyle fontStyle\n * @param {String} decl.fontWeight fontWeight\n * @return {Object} reference to cache\n */\n getFontCache: function(decl) {\n var fontFamily = decl.fontFamily.toLowerCase();\n if (!fabric.charWidthsCache[fontFamily]) {\n fabric.charWidthsCache[fontFamily] = { };\n }\n var cache = fabric.charWidthsCache[fontFamily],\n cacheProp = decl.fontStyle.toLowerCase() + '_' + (decl.fontWeight + '').toLowerCase();\n if (!cache[cacheProp]) {\n cache[cacheProp] = { };\n }\n return cache[cacheProp];\n },\n\n /**\n * apply all the character style to canvas for rendering\n * @private\n * @param {String} _char\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @param {Object} [decl]\n */\n _applyCharStyles: function(method, ctx, lineIndex, charIndex, styleDeclaration) {\n\n this._setFillStyles(ctx, styleDeclaration);\n this._setStrokeStyles(ctx, styleDeclaration);\n\n ctx.font = this._getFontDeclaration(styleDeclaration);\n },\n\n /**\n * measure and return the width of a single character.\n * possibly overridden to accommodate different measure logic or\n * to hook some external lib for character measurement\n * @private\n * @param {String} _char, char to be measured\n * @param {Object} charStyle style of char to be measured\n * @param {String} [previousChar] previous char\n * @param {Object} [prevCharStyle] style of previous char\n */\n _measureChar: function(_char, charStyle, previousChar, prevCharStyle) {\n // first i try to return from cache\n var fontCache = this.getFontCache(charStyle), fontDeclaration = this._getFontDeclaration(charStyle),\n previousFontDeclaration = this._getFontDeclaration(prevCharStyle), couple = previousChar + _char,\n stylesAreEqual = fontDeclaration === previousFontDeclaration, width, coupleWidth, previousWidth,\n fontMultiplier = charStyle.fontSize / this.CACHE_FONT_SIZE, kernedWidth;\n\n if (previousChar && fontCache[previousChar] !== undefined) {\n previousWidth = fontCache[previousChar];\n }\n if (fontCache[_char] !== undefined) {\n kernedWidth = width = fontCache[_char];\n }\n if (stylesAreEqual && fontCache[couple] !== undefined) {\n coupleWidth = fontCache[couple];\n kernedWidth = coupleWidth - previousWidth;\n }\n if (width === undefined || previousWidth === undefined || coupleWidth === undefined) {\n var ctx = this.getMeasuringContext();\n // send a TRUE to specify measuring font size CACHE_FONT_SIZE\n this._setTextStyles(ctx, charStyle, true);\n }\n if (width === undefined) {\n kernedWidth = width = ctx.measureText(_char).width;\n fontCache[_char] = width;\n }\n if (previousWidth === undefined && stylesAreEqual && previousChar) {\n previousWidth = ctx.measureText(previousChar).width;\n fontCache[previousChar] = previousWidth;\n }\n if (stylesAreEqual && coupleWidth === undefined) {\n // we can measure the kerning couple and subtract the width of the previous character\n coupleWidth = ctx.measureText(couple).width;\n fontCache[couple] = coupleWidth;\n kernedWidth = coupleWidth - previousWidth;\n }\n return { width: width * fontMultiplier, kernedWidth: kernedWidth * fontMultiplier };\n },\n\n /**\n * Computes height of character at given position\n * @param {Number} line the line index number\n * @param {Number} _char the character index number\n * @return {Number} fontSize of the character\n */\n getHeightOfChar: function(line, _char) {\n return this.getValueOfPropertyAt(line, _char, 'fontSize');\n },\n\n /**\n * measure a text line measuring all characters.\n * @param {Number} lineIndex line number\n * @return {Number} Line width\n */\n measureLine: function(lineIndex) {\n var lineInfo = this._measureLine(lineIndex);\n if (this.charSpacing !== 0) {\n lineInfo.width -= this._getWidthOfCharSpacing();\n }\n if (lineInfo.width < 0) {\n lineInfo.width = 0;\n }\n return lineInfo;\n },\n\n /**\n * measure every grapheme of a line, populating __charBounds\n * @param {Number} lineIndex\n * @return {Object} object.width total width of characters\n * @return {Object} object.widthOfSpaces length of chars that match this._reSpacesAndTabs\n */\n _measureLine: function(lineIndex) {\n var width = 0, i, grapheme, line = this._textLines[lineIndex], prevGrapheme,\n graphemeInfo, numOfSpaces = 0, lineBounds = new Array(line.length);\n\n this.__charBounds[lineIndex] = lineBounds;\n for (i = 0; i < line.length; i++) {\n grapheme = line[i];\n graphemeInfo = this._getGraphemeBox(grapheme, lineIndex, i, prevGrapheme);\n lineBounds[i] = graphemeInfo;\n width += graphemeInfo.kernedWidth;\n prevGrapheme = grapheme;\n }\n // this latest bound box represent the last character of the line\n // to simplify cursor handling in interactive mode.\n lineBounds[i] = {\n left: graphemeInfo ? graphemeInfo.left + graphemeInfo.width : 0,\n width: 0,\n kernedWidth: 0,\n height: this.fontSize\n };\n return { width: width, numOfSpaces: numOfSpaces };\n },\n\n /**\n * Measure and return the info of a single grapheme.\n * needs the the info of previous graphemes already filled\n * @private\n * @param {String} grapheme to be measured\n * @param {Number} lineIndex index of the line where the char is\n * @param {Number} charIndex position in the line\n * @param {String} [prevGrapheme] character preceding the one to be measured\n */\n _getGraphemeBox: function(grapheme, lineIndex, charIndex, prevGrapheme, skipLeft) {\n var style = this.getCompleteStyleDeclaration(lineIndex, charIndex),\n prevStyle = prevGrapheme ? this.getCompleteStyleDeclaration(lineIndex, charIndex - 1) : { },\n info = this._measureChar(grapheme, style, prevGrapheme, prevStyle),\n kernedWidth = info.kernedWidth,\n width = info.width, charSpacing;\n\n if (this.charSpacing !== 0) {\n charSpacing = this._getWidthOfCharSpacing();\n width += charSpacing;\n kernedWidth += charSpacing;\n }\n\n var box = {\n width: width,\n left: 0,\n height: style.fontSize,\n kernedWidth: kernedWidth,\n deltaY: style.deltaY,\n };\n if (charIndex > 0 && !skipLeft) {\n var previousBox = this.__charBounds[lineIndex][charIndex - 1];\n box.left = previousBox.left + previousBox.width + info.kernedWidth - info.width;\n }\n return box;\n },\n\n /**\n * Calculate height of line at 'lineIndex'\n * @param {Number} lineIndex index of line to calculate\n * @return {Number}\n */\n getHeightOfLine: function(lineIndex) {\n if (this.__lineHeights[lineIndex]) {\n return this.__lineHeights[lineIndex];\n }\n\n var line = this._textLines[lineIndex],\n // char 0 is measured before the line cycle because it nneds to char\n // emptylines\n maxHeight = this.getHeightOfChar(lineIndex, 0);\n for (var i = 1, len = line.length; i < len; i++) {\n maxHeight = Math.max(this.getHeightOfChar(lineIndex, i), maxHeight);\n }\n\n return this.__lineHeights[lineIndex] = maxHeight * this.lineHeight * this._fontSizeMult;\n },\n\n /**\n * Calculate text box height\n */\n calcTextHeight: function() {\n var lineHeight, height = 0;\n for (var i = 0, len = this._textLines.length; i < len; i++) {\n lineHeight = this.getHeightOfLine(i);\n height += (i === len - 1 ? lineHeight / this.lineHeight : lineHeight);\n }\n return height;\n },\n\n /**\n * @private\n * @return {Number} Left offset\n */\n _getLeftOffset: function() {\n return -this.width / 2;\n },\n\n /**\n * @private\n * @return {Number} Top offset\n */\n _getTopOffset: function() {\n return -this.height / 2;\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {String} method Method name (\"fillText\" or \"strokeText\")\n */\n _renderTextCommon: function(ctx, method) {\n ctx.save();\n var lineHeights = 0, left = this._getLeftOffset(), top = this._getTopOffset(),\n offsets = this._applyPatternGradientTransform(ctx, method === 'fillText' ? this.fill : this.stroke);\n for (var i = 0, len = this._textLines.length; i < len; i++) {\n var heightOfLine = this.getHeightOfLine(i),\n maxHeight = heightOfLine / this.lineHeight,\n leftOffset = this._getLineLeftOffset(i);\n this._renderTextLine(\n method,\n ctx,\n this._textLines[i],\n left + leftOffset - offsets.offsetX,\n top + lineHeights + maxHeight - offsets.offsetY,\n i\n );\n lineHeights += heightOfLine;\n }\n ctx.restore();\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderTextFill: function(ctx) {\n if (!this.fill && !this.styleHas('fill')) {\n return;\n }\n\n this._renderTextCommon(ctx, 'fillText');\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderTextStroke: function(ctx) {\n if ((!this.stroke || this.strokeWidth === 0) && this.isEmptyStyles()) {\n return;\n }\n\n if (this.shadow && !this.shadow.affectStroke) {\n this._removeShadow(ctx);\n }\n\n ctx.save();\n this._setLineDash(ctx, this.strokeDashArray);\n ctx.beginPath();\n this._renderTextCommon(ctx, 'strokeText');\n ctx.closePath();\n ctx.restore();\n },\n\n /**\n * @private\n * @param {String} method fillText or strokeText.\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Array} line Content of the line, splitted in an array by grapheme\n * @param {Number} left\n * @param {Number} top\n * @param {Number} lineIndex\n */\n _renderChars: function(method, ctx, line, left, top, lineIndex) {\n // set proper line offset\n var lineHeight = this.getHeightOfLine(lineIndex),\n isJustify = this.textAlign.indexOf('justify') !== -1,\n actualStyle,\n nextStyle,\n charsToRender = '',\n charBox,\n boxWidth = 0,\n timeToRender,\n shortCut = !isJustify && this.charSpacing === 0 && this.isEmptyStyles(lineIndex);\n\n ctx.save();\n top -= lineHeight * this._fontSizeFraction / this.lineHeight;\n if (shortCut) {\n // render all the line in one pass without checking\n this._renderChar(method, ctx, lineIndex, 0, line.join(''), left, top, lineHeight);\n ctx.restore();\n return;\n }\n for (var i = 0, len = line.length - 1; i <= len; i++) {\n timeToRender = i === len || this.charSpacing;\n charsToRender += line[i];\n charBox = this.__charBounds[lineIndex][i];\n if (boxWidth === 0) {\n left += charBox.kernedWidth - charBox.width;\n boxWidth += charBox.width;\n }\n else {\n boxWidth += charBox.kernedWidth;\n }\n if (isJustify && !timeToRender) {\n if (this._reSpaceAndTab.test(line[i])) {\n timeToRender = true;\n }\n }\n if (!timeToRender) {\n // if we have charSpacing, we render char by char\n actualStyle = actualStyle || this.getCompleteStyleDeclaration(lineIndex, i);\n nextStyle = this.getCompleteStyleDeclaration(lineIndex, i + 1);\n timeToRender = this._hasStyleChanged(actualStyle, nextStyle);\n }\n if (timeToRender) {\n this._renderChar(method, ctx, lineIndex, i, charsToRender, left, top, lineHeight);\n charsToRender = '';\n actualStyle = nextStyle;\n left += boxWidth;\n boxWidth = 0;\n }\n }\n ctx.restore();\n },\n\n /**\n * @private\n * @param {String} method\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @param {String} _char\n * @param {Number} left Left coordinate\n * @param {Number} top Top coordinate\n * @param {Number} lineHeight Height of the line\n */\n _renderChar: function(method, ctx, lineIndex, charIndex, _char, left, top) {\n var decl = this._getStyleDeclaration(lineIndex, charIndex),\n fullDecl = this.getCompleteStyleDeclaration(lineIndex, charIndex),\n shouldFill = method === 'fillText' && fullDecl.fill,\n shouldStroke = method === 'strokeText' && fullDecl.stroke && fullDecl.strokeWidth;\n\n if (!shouldStroke && !shouldFill) {\n return;\n }\n decl && ctx.save();\n\n this._applyCharStyles(method, ctx, lineIndex, charIndex, fullDecl);\n\n if (decl && decl.textBackgroundColor) {\n this._removeShadow(ctx);\n }\n if (decl && decl.deltaY) {\n top += decl.deltaY;\n }\n\n shouldFill && ctx.fillText(_char, left, top);\n shouldStroke && ctx.strokeText(_char, left, top);\n decl && ctx.restore();\n },\n\n /**\n * Turns the character into a 'superior figure' (i.e. 'superscript')\n * @param {Number} start selection start\n * @param {Number} end selection end\n * @returns {fabric.Text} thisArg\n * @chainable\n */\n setSuperscript: function(start, end) {\n return this._setScript(start, end, this.superscript);\n },\n\n /**\n * Turns the character into an 'inferior figure' (i.e. 'subscript')\n * @param {Number} start selection start\n * @param {Number} end selection end\n * @returns {fabric.Text} thisArg\n * @chainable\n */\n setSubscript: function(start, end) {\n return this._setScript(start, end, this.subscript);\n },\n\n /**\n * Applies 'schema' at given position\n * @private\n * @param {Number} start selection start\n * @param {Number} end selection end\n * @param {Number} schema\n * @returns {fabric.Text} thisArg\n * @chainable\n */\n _setScript: function(start, end, schema) {\n var loc = this.get2DCursorLocation(start, true),\n fontSize = this.getValueOfPropertyAt(loc.lineIndex, loc.charIndex, 'fontSize'),\n dy = this.getValueOfPropertyAt(loc.lineIndex, loc.charIndex, 'deltaY'),\n style = { fontSize: fontSize * schema.size, deltaY: dy + fontSize * schema.baseline };\n this.setSelectionStyles(style, start, end);\n return this;\n },\n\n /**\n * @private\n * @param {Object} prevStyle\n * @param {Object} thisStyle\n */\n _hasStyleChanged: function(prevStyle, thisStyle) {\n return prevStyle.fill !== thisStyle.fill ||\n prevStyle.stroke !== thisStyle.stroke ||\n prevStyle.strokeWidth !== thisStyle.strokeWidth ||\n prevStyle.fontSize !== thisStyle.fontSize ||\n prevStyle.fontFamily !== thisStyle.fontFamily ||\n prevStyle.fontWeight !== thisStyle.fontWeight ||\n prevStyle.fontStyle !== thisStyle.fontStyle ||\n prevStyle.deltaY !== thisStyle.deltaY;\n },\n\n /**\n * @private\n * @param {Object} prevStyle\n * @param {Object} thisStyle\n */\n _hasStyleChangedForSvg: function(prevStyle, thisStyle) {\n return this._hasStyleChanged(prevStyle, thisStyle) ||\n prevStyle.overline !== thisStyle.overline ||\n prevStyle.underline !== thisStyle.underline ||\n prevStyle.linethrough !== thisStyle.linethrough;\n },\n\n /**\n * @private\n * @param {Number} lineIndex index text line\n * @return {Number} Line left offset\n */\n _getLineLeftOffset: function(lineIndex) {\n var lineWidth = this.getLineWidth(lineIndex);\n if (this.textAlign === 'center') {\n return (this.width - lineWidth) / 2;\n }\n if (this.textAlign === 'right') {\n return this.width - lineWidth;\n }\n if (this.textAlign === 'justify-center' && this.isEndOfWrapping(lineIndex)) {\n return (this.width - lineWidth) / 2;\n }\n if (this.textAlign === 'justify-right' && this.isEndOfWrapping(lineIndex)) {\n return this.width - lineWidth;\n }\n return 0;\n },\n\n /**\n * @private\n */\n _clearCache: function() {\n this.__lineWidths = [];\n this.__lineHeights = [];\n this.__charBounds = [];\n },\n\n /**\n * @private\n */\n _shouldClearDimensionCache: function() {\n var shouldClear = this._forceClearCache;\n shouldClear || (shouldClear = this.hasStateChanged('_dimensionAffectingProps'));\n if (shouldClear) {\n this.dirty = true;\n this._forceClearCache = false;\n }\n return shouldClear;\n },\n\n /**\n * Measure a single line given its index. Used to calculate the initial\n * text bounding box. The values are calculated and stored in __lineWidths cache.\n * @private\n * @param {Number} lineIndex line number\n * @return {Number} Line width\n */\n getLineWidth: function(lineIndex) {\n if (this.__lineWidths[lineIndex]) {\n return this.__lineWidths[lineIndex];\n }\n\n var width, line = this._textLines[lineIndex], lineInfo;\n\n if (line === '') {\n width = 0;\n }\n else {\n lineInfo = this.measureLine(lineIndex);\n width = lineInfo.width;\n }\n this.__lineWidths[lineIndex] = width;\n return width;\n },\n\n _getWidthOfCharSpacing: function() {\n if (this.charSpacing !== 0) {\n return this.fontSize * this.charSpacing / 1000;\n }\n return 0;\n },\n\n /**\n * Retrieves the value of property at given character position\n * @param {Number} lineIndex the line number\n * @param {Number} charIndex the charater number\n * @param {String} property the property name\n * @returns the value of 'property'\n */\n getValueOfPropertyAt: function(lineIndex, charIndex, property) {\n var charStyle = this._getStyleDeclaration(lineIndex, charIndex);\n if (charStyle && typeof charStyle[property] !== 'undefined') {\n return charStyle[property];\n }\n return this[property];\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderTextDecoration: function(ctx, type) {\n if (!this[type] && !this.styleHas(type)) {\n return;\n }\n var heightOfLine, size, _size,\n lineLeftOffset, dy, _dy,\n line, lastDecoration,\n leftOffset = this._getLeftOffset(),\n topOffset = this._getTopOffset(), top,\n boxStart, boxWidth, charBox, currentDecoration,\n maxHeight, currentFill, lastFill,\n charSpacing = this._getWidthOfCharSpacing();\n\n for (var i = 0, len = this._textLines.length; i < len; i++) {\n heightOfLine = this.getHeightOfLine(i);\n if (!this[type] && !this.styleHas(type, i)) {\n topOffset += heightOfLine;\n continue;\n }\n line = this._textLines[i];\n maxHeight = heightOfLine / this.lineHeight;\n lineLeftOffset = this._getLineLeftOffset(i);\n boxStart = 0;\n boxWidth = 0;\n lastDecoration = this.getValueOfPropertyAt(i, 0, type);\n lastFill = this.getValueOfPropertyAt(i, 0, 'fill');\n top = topOffset + maxHeight * (1 - this._fontSizeFraction);\n size = this.getHeightOfChar(i, 0);\n dy = this.getValueOfPropertyAt(i, 0, 'deltaY');\n for (var j = 0, jlen = line.length; j < jlen; j++) {\n charBox = this.__charBounds[i][j];\n currentDecoration = this.getValueOfPropertyAt(i, j, type);\n currentFill = this.getValueOfPropertyAt(i, j, 'fill');\n _size = this.getHeightOfChar(i, j);\n _dy = this.getValueOfPropertyAt(i, j, 'deltaY');\n if ((currentDecoration !== lastDecoration || currentFill !== lastFill || _size !== size || _dy !== dy) &&\n boxWidth > 0) {\n ctx.fillStyle = lastFill;\n lastDecoration && lastFill && ctx.fillRect(\n leftOffset + lineLeftOffset + boxStart,\n top + this.offsets[type] * size + dy,\n boxWidth,\n this.fontSize / 15\n );\n boxStart = charBox.left;\n boxWidth = charBox.width;\n lastDecoration = currentDecoration;\n lastFill = currentFill;\n size = _size;\n dy = _dy;\n }\n else {\n boxWidth += charBox.kernedWidth;\n }\n }\n ctx.fillStyle = currentFill;\n currentDecoration && currentFill && ctx.fillRect(\n leftOffset + lineLeftOffset + boxStart,\n top + this.offsets[type] * size + dy,\n boxWidth - charSpacing,\n this.fontSize / 15\n );\n topOffset += heightOfLine;\n }\n // if there is text background color no\n // other shadows should be casted\n this._removeShadow(ctx);\n },\n\n /**\n * return font declaration string for canvas context\n * @param {Object} [styleObject] object\n * @returns {String} font declaration formatted for canvas context.\n */\n _getFontDeclaration: function(styleObject, forMeasuring) {\n var style = styleObject || this, family = this.fontFamily,\n fontIsGeneric = fabric.Text.genericFonts.indexOf(family.toLowerCase()) > -1;\n var fontFamily = family === undefined ||\n family.indexOf('\\'') > -1 || family.indexOf(',') > -1 ||\n family.indexOf('\"') > -1 || fontIsGeneric\n ? style.fontFamily : '\"' + style.fontFamily + '\"';\n return [\n // node-canvas needs \"weight style\", while browsers need \"style weight\"\n // verify if this can be fixed in JSDOM\n (fabric.isLikelyNode ? style.fontWeight : style.fontStyle),\n (fabric.isLikelyNode ? style.fontStyle : style.fontWeight),\n forMeasuring ? this.CACHE_FONT_SIZE + 'px' : style.fontSize + 'px',\n fontFamily\n ].join(' ');\n },\n\n /**\n * Renders text instance on a specified context\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n render: function(ctx) {\n // do not render if object is not visible\n if (!this.visible) {\n return;\n }\n if (this.canvas && this.canvas.skipOffscreen && !this.group && !this.isOnScreen()) {\n return;\n }\n if (this._shouldClearDimensionCache()) {\n this.initDimensions();\n }\n this.callSuper('render', ctx);\n },\n\n /**\n * Returns the text as an array of lines.\n * @param {String} text text to split\n * @returns {Array} Lines in the text\n */\n _splitTextIntoLines: function(text) {\n var lines = text.split(this._reNewline),\n newLines = new Array(lines.length),\n newLine = ['\\n'],\n newText = [];\n for (var i = 0; i < lines.length; i++) {\n newLines[i] = fabric.util.string.graphemeSplit(lines[i]);\n newText = newText.concat(newLines[i], newLine);\n }\n newText.pop();\n return { _unwrappedLines: newLines, lines: lines, graphemeText: newText, graphemeLines: newLines };\n },\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} Object representation of an instance\n */\n toObject: function(propertiesToInclude) {\n var additionalProperties = [\n 'text',\n 'fontSize',\n 'fontWeight',\n 'fontFamily',\n 'fontStyle',\n 'lineHeight',\n 'underline',\n 'overline',\n 'linethrough',\n 'textAlign',\n 'textBackgroundColor',\n 'charSpacing',\n ].concat(propertiesToInclude);\n var obj = this.callSuper('toObject', additionalProperties);\n obj.styles = clone(this.styles, true);\n return obj;\n },\n\n /**\n * Sets property to a given value. When changing position/dimension -related properties (left, top, scale, angle, etc.) `set` does not update position of object's borders/controls. If you need to update those, call `setCoords()`.\n * @param {String|Object} key Property name or object (if object, iterate over the object properties)\n * @param {Object|Function} value Property value (if function, the value is passed into it and its return value is used as a new one)\n * @return {fabric.Object} thisArg\n * @chainable\n */\n set: function(key, value) {\n this.callSuper('set', key, value);\n var needsDims = false;\n if (typeof key === 'object') {\n for (var _key in key) {\n needsDims = needsDims || this._dimensionAffectingProps.indexOf(_key) !== -1;\n }\n }\n else {\n needsDims = this._dimensionAffectingProps.indexOf(key) !== -1;\n }\n if (needsDims) {\n this.initDimensions();\n this.setCoords();\n }\n return this;\n },\n\n /**\n * Returns complexity of an instance\n * @return {Number} complexity\n */\n complexity: function() {\n return 1;\n }\n });\n\n /* _FROM_SVG_START_ */\n /**\n * List of attribute names to account for when parsing SVG element (used by {@link fabric.Text.fromElement})\n * @static\n * @memberOf fabric.Text\n * @see: http://www.w3.org/TR/SVG/text.html#TextElement\n */\n fabric.Text.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat(\n 'x y dx dy font-family font-style font-weight font-size letter-spacing text-decoration text-anchor'.split(' '));\n\n /**\n * Default SVG font size\n * @static\n * @memberOf fabric.Text\n */\n fabric.Text.DEFAULT_SVG_FONT_SIZE = 16;\n\n /**\n * Returns fabric.Text instance from an SVG element (<b>not yet implemented</b>)\n * @static\n * @memberOf fabric.Text\n * @param {SVGElement} element Element to parse\n * @param {Function} callback callback function invoked after parsing\n * @param {Object} [options] Options object\n */\n fabric.Text.fromElement = function(element, callback, options) {\n if (!element) {\n return callback(null);\n }\n\n var parsedAttributes = fabric.parseAttributes(element, fabric.Text.ATTRIBUTE_NAMES),\n parsedAnchor = parsedAttributes.textAnchor || 'left';\n options = fabric.util.object.extend((options ? clone(options) : { }), parsedAttributes);\n\n options.top = options.top || 0;\n options.left = options.left || 0;\n if (parsedAttributes.textDecoration) {\n var textDecoration = parsedAttributes.textDecoration;\n if (textDecoration.indexOf('underline') !== -1) {\n options.underline = true;\n }\n if (textDecoration.indexOf('overline') !== -1) {\n options.overline = true;\n }\n if (textDecoration.indexOf('line-through') !== -1) {\n options.linethrough = true;\n }\n delete options.textDecoration;\n }\n if ('dx' in parsedAttributes) {\n options.left += parsedAttributes.dx;\n }\n if ('dy' in parsedAttributes) {\n options.top += parsedAttributes.dy;\n }\n if (!('fontSize' in options)) {\n options.fontSize = fabric.Text.DEFAULT_SVG_FONT_SIZE;\n }\n\n var textContent = '';\n\n // The XML is not properly parsed in IE9 so a workaround to get\n // textContent is through firstChild.data. Another workaround would be\n // to convert XML loaded from a file to be converted using DOMParser (same way loadSVGFromString() does)\n if (!('textContent' in element)) {\n if ('firstChild' in element && element.firstChild !== null) {\n if ('data' in element.firstChild && element.firstChild.data !== null) {\n textContent = element.firstChild.data;\n }\n }\n }\n else {\n textContent = element.textContent;\n }\n\n textContent = textContent.replace(/^\\s+|\\s+$|\\n+/g, '').replace(/\\s+/g, ' ');\n var originalStrokeWidth = options.strokeWidth;\n options.strokeWidth = 0;\n\n var text = new fabric.Text(textContent, options),\n textHeightScaleFactor = text.getScaledHeight() / text.height,\n lineHeightDiff = (text.height + text.strokeWidth) * text.lineHeight - text.height,\n scaledDiff = lineHeightDiff * textHeightScaleFactor,\n textHeight = text.getScaledHeight() + scaledDiff,\n offX = 0;\n /*\n Adjust positioning:\n x/y attributes in SVG correspond to the bottom-left corner of text bounding box\n fabric output by default at top, left.\n */\n if (parsedAnchor === 'center') {\n offX = text.getScaledWidth() / 2;\n }\n if (parsedAnchor === 'right') {\n offX = text.getScaledWidth();\n }\n text.set({\n left: text.left - offX,\n top: text.top - (textHeight - text.fontSize * (0.07 + text._fontSizeFraction)) / text.lineHeight,\n strokeWidth: typeof originalStrokeWidth !== 'undefined' ? originalStrokeWidth : 1,\n });\n callback(text);\n };\n /* _FROM_SVG_END_ */\n\n /**\n * Returns fabric.Text instance from an object representation\n * @static\n * @memberOf fabric.Text\n * @param {Object} object Object to create an instance from\n * @param {Function} [callback] Callback to invoke when an fabric.Text instance is created\n */\n fabric.Text.fromObject = function(object, callback) {\n return fabric.Object._fromObject('Text', object, callback, 'text');\n };\n\n fabric.Text.genericFonts = ['sans-serif', 'serif', 'cursive', 'fantasy', 'monospace'];\n\n fabric.util.createAccessors && fabric.util.createAccessors(fabric.Text);\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function() {\n fabric.util.object.extend(fabric.Text.prototype, /** @lends fabric.Text.prototype */ {\n /**\n * Returns true if object has no styling or no styling in a line\n * @param {Number} lineIndex , lineIndex is on wrapped lines.\n * @return {Boolean}\n */\n isEmptyStyles: function(lineIndex) {\n if (!this.styles) {\n return true;\n }\n if (typeof lineIndex !== 'undefined' && !this.styles[lineIndex]) {\n return true;\n }\n var obj = typeof lineIndex === 'undefined' ? this.styles : { line: this.styles[lineIndex] };\n for (var p1 in obj) {\n for (var p2 in obj[p1]) {\n // eslint-disable-next-line no-unused-vars\n for (var p3 in obj[p1][p2]) {\n return false;\n }\n }\n }\n return true;\n },\n\n /**\n * Returns true if object has a style property or has it ina specified line\n * This function is used to detect if a text will use a particular property or not.\n * @param {String} property to check for\n * @param {Number} lineIndex to check the style on\n * @return {Boolean}\n */\n styleHas: function(property, lineIndex) {\n if (!this.styles || !property || property === '') {\n return false;\n }\n if (typeof lineIndex !== 'undefined' && !this.styles[lineIndex]) {\n return false;\n }\n var obj = typeof lineIndex === 'undefined' ? this.styles : { 0: this.styles[lineIndex] };\n // eslint-disable-next-line\n for (var p1 in obj) {\n // eslint-disable-next-line\n for (var p2 in obj[p1]) {\n if (typeof obj[p1][p2][property] !== 'undefined') {\n return true;\n }\n }\n }\n return false;\n },\n\n /**\n * Check if characters in a text have a value for a property\n * whose value matches the textbox's value for that property. If so,\n * the character-level property is deleted. If the character\n * has no other properties, then it is also deleted. Finally,\n * if the line containing that character has no other characters\n * then it also is deleted.\n *\n * @param {string} property The property to compare between characters and text.\n */\n cleanStyle: function(property) {\n if (!this.styles || !property || property === '') {\n return false;\n }\n var obj = this.styles, stylesCount = 0, letterCount, stylePropertyValue,\n allStyleObjectPropertiesMatch = true, graphemeCount = 0, styleObject;\n // eslint-disable-next-line\n for (var p1 in obj) {\n letterCount = 0;\n // eslint-disable-next-line\n for (var p2 in obj[p1]) {\n var styleObject = obj[p1][p2],\n stylePropertyHasBeenSet = styleObject.hasOwnProperty(property);\n\n stylesCount++;\n\n if (stylePropertyHasBeenSet) {\n if (!stylePropertyValue) {\n stylePropertyValue = styleObject[property];\n }\n else if (styleObject[property] !== stylePropertyValue) {\n allStyleObjectPropertiesMatch = false;\n }\n\n if (styleObject[property] === this[property]) {\n delete styleObject[property];\n }\n }\n else {\n allStyleObjectPropertiesMatch = false;\n }\n\n if (Object.keys(styleObject).length !== 0) {\n letterCount++;\n }\n else {\n delete obj[p1][p2];\n }\n }\n\n if (letterCount === 0) {\n delete obj[p1];\n }\n }\n // if every grapheme has the same style set then\n // delete those styles and set it on the parent\n for (var i = 0; i < this._textLines.length; i++) {\n graphemeCount += this._textLines[i].length;\n }\n if (allStyleObjectPropertiesMatch && stylesCount === graphemeCount) {\n this[property] = stylePropertyValue;\n this.removeStyle(property);\n }\n },\n\n /**\n * Remove a style property or properties from all individual character styles\n * in a text object. Deletes the character style object if it contains no other style\n * props. Deletes a line style object if it contains no other character styles.\n *\n * @param {String} props The property to remove from character styles.\n */\n removeStyle: function(property) {\n if (!this.styles || !property || property === '') {\n return;\n }\n var obj = this.styles, line, lineNum, charNum;\n for (lineNum in obj) {\n line = obj[lineNum];\n for (charNum in line) {\n delete line[charNum][property];\n if (Object.keys(line[charNum]).length === 0) {\n delete line[charNum];\n }\n }\n if (Object.keys(line).length === 0) {\n delete obj[lineNum];\n }\n }\n },\n\n /**\n * @private\n */\n _extendStyles: function(index, styles) {\n var loc = this.get2DCursorLocation(index);\n\n if (!this._getLineStyle(loc.lineIndex)) {\n this._setLineStyle(loc.lineIndex);\n }\n\n if (!this._getStyleDeclaration(loc.lineIndex, loc.charIndex)) {\n this._setStyleDeclaration(loc.lineIndex, loc.charIndex, {});\n }\n\n fabric.util.object.extend(this._getStyleDeclaration(loc.lineIndex, loc.charIndex), styles);\n },\n\n /**\n * Returns 2d representation (lineIndex and charIndex) of cursor (or selection start)\n * @param {Number} [selectionStart] Optional index. When not given, current selectionStart is used.\n * @param {Boolean} [skipWrapping] consider the location for unwrapped lines. useful to manage styles.\n */\n get2DCursorLocation: function(selectionStart, skipWrapping) {\n if (typeof selectionStart === 'undefined') {\n selectionStart = this.selectionStart;\n }\n var lines = skipWrapping ? this._unwrappedTextLines : this._textLines,\n len = lines.length;\n for (var i = 0; i < len; i++) {\n if (selectionStart <= lines[i].length) {\n return {\n lineIndex: i,\n charIndex: selectionStart\n };\n }\n selectionStart -= lines[i].length + this.missingNewlineOffset(i);\n }\n return {\n lineIndex: i - 1,\n charIndex: lines[i - 1].length < selectionStart ? lines[i - 1].length : selectionStart\n };\n },\n\n /**\n * Gets style of a current selection/cursor (at the start position)\n * if startIndex or endIndex are not provided, slectionStart or selectionEnd will be used.\n * @param {Number} [startIndex] Start index to get styles at\n * @param {Number} [endIndex] End index to get styles at, if not specified selectionEnd or startIndex + 1\n * @param {Boolean} [complete] get full style or not\n * @return {Array} styles an array with one, zero or more Style objects\n */\n getSelectionStyles: function(startIndex, endIndex, complete) {\n if (typeof startIndex === 'undefined') {\n startIndex = this.selectionStart || 0;\n }\n if (typeof endIndex === 'undefined') {\n endIndex = this.selectionEnd || startIndex;\n }\n var styles = [];\n for (var i = startIndex; i < endIndex; i++) {\n styles.push(this.getStyleAtPosition(i, complete));\n }\n return styles;\n },\n\n /**\n * Gets style of a current selection/cursor position\n * @param {Number} position to get styles at\n * @param {Boolean} [complete] full style if true\n * @return {Object} style Style object at a specified index\n * @private\n */\n getStyleAtPosition: function(position, complete) {\n var loc = this.get2DCursorLocation(position),\n style = complete ? this.getCompleteStyleDeclaration(loc.lineIndex, loc.charIndex) :\n this._getStyleDeclaration(loc.lineIndex, loc.charIndex);\n return style || {};\n },\n\n /**\n * Sets style of a current selection, if no selection exist, do not set anything.\n * @param {Object} [styles] Styles object\n * @param {Number} [startIndex] Start index to get styles at\n * @param {Number} [endIndex] End index to get styles at, if not specified selectionEnd or startIndex + 1\n * @return {fabric.IText} thisArg\n * @chainable\n */\n setSelectionStyles: function(styles, startIndex, endIndex) {\n if (typeof startIndex === 'undefined') {\n startIndex = this.selectionStart || 0;\n }\n if (typeof endIndex === 'undefined') {\n endIndex = this.selectionEnd || startIndex;\n }\n for (var i = startIndex; i < endIndex; i++) {\n this._extendStyles(i, styles);\n }\n /* not included in _extendStyles to avoid clearing cache more than once */\n this._forceClearCache = true;\n return this;\n },\n\n /**\n * get the reference, not a clone, of the style object for a given character\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @return {Object} style object\n */\n _getStyleDeclaration: function(lineIndex, charIndex) {\n var lineStyle = this.styles && this.styles[lineIndex];\n if (!lineStyle) {\n return null;\n }\n return lineStyle[charIndex];\n },\n\n /**\n * return a new object that contains all the style property for a character\n * the object returned is newly created\n * @param {Number} lineIndex of the line where the character is\n * @param {Number} charIndex position of the character on the line\n * @return {Object} style object\n */\n getCompleteStyleDeclaration: function(lineIndex, charIndex) {\n var style = this._getStyleDeclaration(lineIndex, charIndex) || { },\n styleObject = { }, prop;\n for (var i = 0; i < this._styleProperties.length; i++) {\n prop = this._styleProperties[i];\n styleObject[prop] = typeof style[prop] === 'undefined' ? this[prop] : style[prop];\n }\n return styleObject;\n },\n\n /**\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @param {Object} style\n * @private\n */\n _setStyleDeclaration: function(lineIndex, charIndex, style) {\n this.styles[lineIndex][charIndex] = style;\n },\n\n /**\n *\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @private\n */\n _deleteStyleDeclaration: function(lineIndex, charIndex) {\n delete this.styles[lineIndex][charIndex];\n },\n\n /**\n * @param {Number} lineIndex\n * @return {Boolean} if the line exists or not\n * @private\n */\n _getLineStyle: function(lineIndex) {\n return !!this.styles[lineIndex];\n },\n\n /**\n * Set the line style to an empty object so that is initialized\n * @param {Number} lineIndex\n * @private\n */\n _setLineStyle: function(lineIndex) {\n this.styles[lineIndex] = {};\n },\n\n /**\n * @param {Number} lineIndex\n * @private\n */\n _deleteLineStyle: function(lineIndex) {\n delete this.styles[lineIndex];\n }\n });\n})();\n\n\n(function() {\n\n function parseDecoration(object) {\n if (object.textDecoration) {\n object.textDecoration.indexOf('underline') > -1 && (object.underline = true);\n object.textDecoration.indexOf('line-through') > -1 && (object.linethrough = true);\n object.textDecoration.indexOf('overline') > -1 && (object.overline = true);\n delete object.textDecoration;\n }\n }\n\n /**\n * IText class (introduced in <b>v1.4</b>) Events are also fired with \"text:\"\n * prefix when observing canvas.\n * @class fabric.IText\n * @extends fabric.Text\n * @mixes fabric.Observable\n *\n * @fires changed\n * @fires selection:changed\n * @fires editing:entered\n * @fires editing:exited\n *\n * @return {fabric.IText} thisArg\n * @see {@link fabric.IText#initialize} for constructor definition\n *\n * <p>Supported key combinations:</p>\n * <pre>\n * Move cursor: left, right, up, down\n * Select character: shift + left, shift + right\n * Select text vertically: shift + up, shift + down\n * Move cursor by word: alt + left, alt + right\n * Select words: shift + alt + left, shift + alt + right\n * Move cursor to line start/end: cmd + left, cmd + right or home, end\n * Select till start/end of line: cmd + shift + left, cmd + shift + right or shift + home, shift + end\n * Jump to start/end of text: cmd + up, cmd + down\n * Select till start/end of text: cmd + shift + up, cmd + shift + down or shift + pgUp, shift + pgDown\n * Delete character: backspace\n * Delete word: alt + backspace\n * Delete line: cmd + backspace\n * Forward delete: delete\n * Copy text: ctrl/cmd + c\n * Paste text: ctrl/cmd + v\n * Cut text: ctrl/cmd + x\n * Select entire text: ctrl/cmd + a\n * Quit editing tab or esc\n * </pre>\n *\n * <p>Supported mouse/touch combination</p>\n * <pre>\n * Position cursor: click/touch\n * Create selection: click/touch & drag\n * Create selection: click & shift + click\n * Select word: double click\n * Select line: triple click\n * </pre>\n */\n fabric.IText = fabric.util.createClass(fabric.Text, fabric.Observable, /** @lends fabric.IText.prototype */ {\n\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'i-text',\n\n /**\n * Index where text selection starts (or where cursor is when there is no selection)\n * @type Number\n * @default\n */\n selectionStart: 0,\n\n /**\n * Index where text selection ends\n * @type Number\n * @default\n */\n selectionEnd: 0,\n\n /**\n * Color of text selection\n * @type String\n * @default\n */\n selectionColor: 'rgba(17,119,255,0.3)',\n\n /**\n * Indicates whether text is in editing mode\n * @type Boolean\n * @default\n */\n isEditing: false,\n\n /**\n * Indicates whether a text can be edited\n * @type Boolean\n * @default\n */\n editable: true,\n\n /**\n * Border color of text object while it's in editing mode\n * @type String\n * @default\n */\n editingBorderColor: 'rgba(102,153,255,0.25)',\n\n /**\n * Width of cursor (in px)\n * @type Number\n * @default\n */\n cursorWidth: 2,\n\n /**\n * Color of text cursor color in editing mode.\n * if not set (default) will take color from the text.\n * if set to a color value that fabric can understand, it will\n * be used instead of the color of the text at the current position.\n * @type String\n * @default\n */\n cursorColor: '',\n\n /**\n * Delay between cursor blink (in ms)\n * @type Number\n * @default\n */\n cursorDelay: 1000,\n\n /**\n * Duration of cursor fadein (in ms)\n * @type Number\n * @default\n */\n cursorDuration: 600,\n\n /**\n * Indicates whether internal text char widths can be cached\n * @type Boolean\n * @default\n */\n caching: true,\n\n /**\n * @private\n */\n _reSpace: /\\s|\\n/,\n\n /**\n * @private\n */\n _currentCursorOpacity: 0,\n\n /**\n * @private\n */\n _selectionDirection: null,\n\n /**\n * @private\n */\n _abortCursorAnimation: false,\n\n /**\n * @private\n */\n __widthOfSpace: [],\n\n /**\n * Helps determining when the text is in composition, so that the cursor\n * rendering is altered.\n */\n inCompositionMode: false,\n\n /**\n * Constructor\n * @param {String} text Text string\n * @param {Object} [options] Options object\n * @return {fabric.IText} thisArg\n */\n initialize: function(text, options) {\n this.callSuper('initialize', text, options);\n this.initBehavior();\n },\n\n /**\n * Sets selection start (left boundary of a selection)\n * @param {Number} index Index to set selection start to\n */\n setSelectionStart: function(index) {\n index = Math.max(index, 0);\n this._updateAndFire('selectionStart', index);\n },\n\n /**\n * Sets selection end (right boundary of a selection)\n * @param {Number} index Index to set selection end to\n */\n setSelectionEnd: function(index) {\n index = Math.min(index, this.text.length);\n this._updateAndFire('selectionEnd', index);\n },\n\n /**\n * @private\n * @param {String} property 'selectionStart' or 'selectionEnd'\n * @param {Number} index new position of property\n */\n _updateAndFire: function(property, index) {\n if (this[property] !== index) {\n this._fireSelectionChanged();\n this[property] = index;\n }\n this._updateTextarea();\n },\n\n /**\n * Fires the even of selection changed\n * @private\n */\n _fireSelectionChanged: function() {\n this.fire('selection:changed');\n this.canvas && this.canvas.fire('text:selection:changed', { target: this });\n },\n\n /**\n * Initialize text dimensions. Render all text on given context\n * or on a offscreen canvas to get the text width with measureText.\n * Updates this.width and this.height with the proper values.\n * Does not return dimensions.\n * @private\n */\n initDimensions: function() {\n this.isEditing && this.initDelayedCursor();\n this.clearContextTop();\n this.callSuper('initDimensions');\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n render: function(ctx) {\n this.clearContextTop();\n this.callSuper('render', ctx);\n // clear the cursorOffsetCache, so we ensure to calculate once per renderCursor\n // the correct position but not at every cursor animation.\n this.cursorOffsetCache = { };\n this.renderCursorOrSelection();\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _render: function(ctx) {\n this.callSuper('_render', ctx);\n },\n\n /**\n * Prepare and clean the contextTop\n */\n clearContextTop: function(skipRestore) {\n if (!this.isEditing || !this.canvas || !this.canvas.contextTop) {\n return;\n }\n var ctx = this.canvas.contextTop, v = this.canvas.viewportTransform;\n ctx.save();\n ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]);\n this.transform(ctx);\n this._clearTextArea(ctx);\n skipRestore || ctx.restore();\n },\n /**\n * Renders cursor or selection (depending on what exists)\n * it does on the contextTop. If contextTop is not available, do nothing.\n */\n renderCursorOrSelection: function() {\n if (!this.isEditing || !this.canvas || !this.canvas.contextTop) {\n return;\n }\n var boundaries = this._getCursorBoundaries(),\n ctx = this.canvas.contextTop;\n this.clearContextTop(true);\n if (this.selectionStart === this.selectionEnd) {\n this.renderCursor(boundaries, ctx);\n }\n else {\n this.renderSelection(boundaries, ctx);\n }\n ctx.restore();\n },\n\n _clearTextArea: function(ctx) {\n // we add 4 pixel, to be sure to do not leave any pixel out\n var width = this.width + 4, height = this.height + 4;\n ctx.clearRect(-width / 2, -height / 2, width, height);\n },\n\n /**\n * Returns cursor boundaries (left, top, leftOffset, topOffset)\n * @private\n * @param {Array} chars Array of characters\n * @param {String} typeOfBoundaries\n */\n _getCursorBoundaries: function(position) {\n\n // left/top are left/top of entire text box\n // leftOffset/topOffset are offset from that left/top point of a text box\n\n if (typeof position === 'undefined') {\n position = this.selectionStart;\n }\n\n var left = this._getLeftOffset(),\n top = this._getTopOffset(),\n offsets = this._getCursorBoundariesOffsets(position);\n\n return {\n left: left,\n top: top,\n leftOffset: offsets.left,\n topOffset: offsets.top\n };\n },\n\n /**\n * @private\n */\n _getCursorBoundariesOffsets: function(position) {\n if (this.cursorOffsetCache && 'top' in this.cursorOffsetCache) {\n return this.cursorOffsetCache;\n }\n var lineLeftOffset,\n lineIndex,\n charIndex,\n topOffset = 0,\n leftOffset = 0,\n boundaries,\n cursorPosition = this.get2DCursorLocation(position);\n charIndex = cursorPosition.charIndex;\n lineIndex = cursorPosition.lineIndex;\n for (var i = 0; i < lineIndex; i++) {\n topOffset += this.getHeightOfLine(i);\n }\n lineLeftOffset = this._getLineLeftOffset(lineIndex);\n var bound = this.__charBounds[lineIndex][charIndex];\n bound && (leftOffset = bound.left);\n if (this.charSpacing !== 0 && charIndex === this._textLines[lineIndex].length) {\n leftOffset -= this._getWidthOfCharSpacing();\n }\n boundaries = {\n top: topOffset,\n left: lineLeftOffset + (leftOffset > 0 ? leftOffset : 0),\n };\n this.cursorOffsetCache = boundaries;\n return this.cursorOffsetCache;\n },\n\n /**\n * Renders cursor\n * @param {Object} boundaries\n * @param {CanvasRenderingContext2D} ctx transformed context to draw on\n */\n renderCursor: function(boundaries, ctx) {\n var cursorLocation = this.get2DCursorLocation(),\n lineIndex = cursorLocation.lineIndex,\n charIndex = cursorLocation.charIndex > 0 ? cursorLocation.charIndex - 1 : 0,\n charHeight = this.getValueOfPropertyAt(lineIndex, charIndex, 'fontSize'),\n multiplier = this.scaleX * this.canvas.getZoom(),\n cursorWidth = this.cursorWidth / multiplier,\n topOffset = boundaries.topOffset,\n dy = this.getValueOfPropertyAt(lineIndex, charIndex, 'deltaY');\n\n topOffset += (1 - this._fontSizeFraction) * this.getHeightOfLine(lineIndex) / this.lineHeight\n - charHeight * (1 - this._fontSizeFraction);\n\n if (this.inCompositionMode) {\n this.renderSelection(boundaries, ctx);\n }\n\n ctx.fillStyle = this.cursorColor || this.getValueOfPropertyAt(lineIndex, charIndex, 'fill');\n ctx.globalAlpha = this.__isMousedown ? 1 : this._currentCursorOpacity;\n ctx.fillRect(\n boundaries.left + boundaries.leftOffset - cursorWidth / 2,\n topOffset + boundaries.top + dy,\n cursorWidth,\n charHeight);\n },\n\n /**\n * Renders text selection\n * @param {Object} boundaries Object with left/top/leftOffset/topOffset\n * @param {CanvasRenderingContext2D} ctx transformed context to draw on\n */\n renderSelection: function(boundaries, ctx) {\n\n var selectionStart = this.inCompositionMode ? this.hiddenTextarea.selectionStart : this.selectionStart,\n selectionEnd = this.inCompositionMode ? this.hiddenTextarea.selectionEnd : this.selectionEnd,\n isJustify = this.textAlign.indexOf('justify') !== -1,\n start = this.get2DCursorLocation(selectionStart),\n end = this.get2DCursorLocation(selectionEnd),\n startLine = start.lineIndex,\n endLine = end.lineIndex,\n startChar = start.charIndex < 0 ? 0 : start.charIndex,\n endChar = end.charIndex < 0 ? 0 : end.charIndex;\n\n for (var i = startLine; i <= endLine; i++) {\n var lineOffset = this._getLineLeftOffset(i) || 0,\n lineHeight = this.getHeightOfLine(i),\n realLineHeight = 0, boxStart = 0, boxEnd = 0;\n\n if (i === startLine) {\n boxStart = this.__charBounds[startLine][startChar].left;\n }\n if (i >= startLine && i < endLine) {\n boxEnd = isJustify && !this.isEndOfWrapping(i) ? this.width : this.getLineWidth(i) || 5; // WTF is this 5?\n }\n else if (i === endLine) {\n if (endChar === 0) {\n boxEnd = this.__charBounds[endLine][endChar].left;\n }\n else {\n var charSpacing = this._getWidthOfCharSpacing();\n boxEnd = this.__charBounds[endLine][endChar - 1].left\n + this.__charBounds[endLine][endChar - 1].width - charSpacing;\n }\n }\n realLineHeight = lineHeight;\n if (this.lineHeight < 1 || (i === endLine && this.lineHeight > 1)) {\n lineHeight /= this.lineHeight;\n }\n if (this.inCompositionMode) {\n ctx.fillStyle = this.compositionColor || 'black';\n ctx.fillRect(\n boundaries.left + lineOffset + boxStart,\n boundaries.top + boundaries.topOffset + lineHeight,\n boxEnd - boxStart,\n 1);\n }\n else {\n ctx.fillStyle = this.selectionColor;\n ctx.fillRect(\n boundaries.left + lineOffset + boxStart,\n boundaries.top + boundaries.topOffset,\n boxEnd - boxStart,\n lineHeight);\n }\n\n\n boundaries.topOffset += realLineHeight;\n }\n },\n\n /**\n * High level function to know the height of the cursor.\n * the currentChar is the one that precedes the cursor\n * Returns fontSize of char at the current cursor\n * Unused from the library, is for the end user\n * @return {Number} Character font size\n */\n getCurrentCharFontSize: function() {\n var cp = this._getCurrentCharIndex();\n return this.getValueOfPropertyAt(cp.l, cp.c, 'fontSize');\n },\n\n /**\n * High level function to know the color of the cursor.\n * the currentChar is the one that precedes the cursor\n * Returns color (fill) of char at the current cursor\n * Unused from the library, is for the end user\n * @return {String} Character color (fill)\n */\n getCurrentCharColor: function() {\n var cp = this._getCurrentCharIndex();\n return this.getValueOfPropertyAt(cp.l, cp.c, 'fill');\n },\n\n /**\n * Returns the cursor position for the getCurrent.. functions\n * @private\n */\n _getCurrentCharIndex: function() {\n var cursorPosition = this.get2DCursorLocation(this.selectionStart, true),\n charIndex = cursorPosition.charIndex > 0 ? cursorPosition.charIndex - 1 : 0;\n return { l: cursorPosition.lineIndex, c: charIndex };\n }\n });\n\n /**\n * Returns fabric.IText instance from an object representation\n * @static\n * @memberOf fabric.IText\n * @param {Object} object Object to create an instance from\n * @param {function} [callback] invoked with new instance as argument\n */\n fabric.IText.fromObject = function(object, callback) {\n parseDecoration(object);\n if (object.styles) {\n for (var i in object.styles) {\n for (var j in object.styles[i]) {\n parseDecoration(object.styles[i][j]);\n }\n }\n }\n fabric.Object._fromObject('IText', object, callback, 'text');\n };\n})();\n\n\n(function() {\n\n var clone = fabric.util.object.clone;\n\n fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.prototype */ {\n\n /**\n * Initializes all the interactive behavior of IText\n */\n initBehavior: function() {\n this.initAddedHandler();\n this.initRemovedHandler();\n this.initCursorSelectionHandlers();\n this.initDoubleClickSimulation();\n this.mouseMoveHandler = this.mouseMoveHandler.bind(this);\n },\n\n onDeselect: function() {\n this.isEditing && this.exitEditing();\n this.selected = false;\n },\n\n /**\n * Initializes \"added\" event handler\n */\n initAddedHandler: function() {\n var _this = this;\n this.on('added', function() {\n var canvas = _this.canvas;\n if (canvas) {\n if (!canvas._hasITextHandlers) {\n canvas._hasITextHandlers = true;\n _this._initCanvasHandlers(canvas);\n }\n canvas._iTextInstances = canvas._iTextInstances || [];\n canvas._iTextInstances.push(_this);\n }\n });\n },\n\n initRemovedHandler: function() {\n var _this = this;\n this.on('removed', function() {\n var canvas = _this.canvas;\n if (canvas) {\n canvas._iTextInstances = canvas._iTextInstances || [];\n fabric.util.removeFromArray(canvas._iTextInstances, _this);\n if (canvas._iTextInstances.length === 0) {\n canvas._hasITextHandlers = false;\n _this._removeCanvasHandlers(canvas);\n }\n }\n });\n },\n\n /**\n * register canvas event to manage exiting on other instances\n * @private\n */\n _initCanvasHandlers: function(canvas) {\n canvas._mouseUpITextHandler = function() {\n if (canvas._iTextInstances) {\n canvas._iTextInstances.forEach(function(obj) {\n obj.__isMousedown = false;\n });\n }\n };\n canvas.on('mouse:up', canvas._mouseUpITextHandler);\n },\n\n /**\n * remove canvas event to manage exiting on other instances\n * @private\n */\n _removeCanvasHandlers: function(canvas) {\n canvas.off('mouse:up', canvas._mouseUpITextHandler);\n },\n\n /**\n * @private\n */\n _tick: function() {\n this._currentTickState = this._animateCursor(this, 1, this.cursorDuration, '_onTickComplete');\n },\n\n /**\n * @private\n */\n _animateCursor: function(obj, targetOpacity, duration, completeMethod) {\n\n var tickState;\n\n tickState = {\n isAborted: false,\n abort: function() {\n this.isAborted = true;\n },\n };\n\n obj.animate('_currentCursorOpacity', targetOpacity, {\n duration: duration,\n onComplete: function() {\n if (!tickState.isAborted) {\n obj[completeMethod]();\n }\n },\n onChange: function() {\n // we do not want to animate a selection, only cursor\n if (obj.canvas && obj.selectionStart === obj.selectionEnd) {\n obj.renderCursorOrSelection();\n }\n },\n abort: function() {\n return tickState.isAborted;\n }\n });\n return tickState;\n },\n\n /**\n * @private\n */\n _onTickComplete: function() {\n\n var _this = this;\n\n if (this._cursorTimeout1) {\n clearTimeout(this._cursorTimeout1);\n }\n this._cursorTimeout1 = setTimeout(function() {\n _this._currentTickCompleteState = _this._animateCursor(_this, 0, this.cursorDuration / 2, '_tick');\n }, 100);\n },\n\n /**\n * Initializes delayed cursor\n */\n initDelayedCursor: function(restart) {\n var _this = this,\n delay = restart ? 0 : this.cursorDelay;\n\n this.abortCursorAnimation();\n this._currentCursorOpacity = 1;\n this._cursorTimeout2 = setTimeout(function() {\n _this._tick();\n }, delay);\n },\n\n /**\n * Aborts cursor animation and clears all timeouts\n */\n abortCursorAnimation: function() {\n var shouldClear = this._currentTickState || this._currentTickCompleteState,\n canvas = this.canvas;\n this._currentTickState && this._currentTickState.abort();\n this._currentTickCompleteState && this._currentTickCompleteState.abort();\n\n clearTimeout(this._cursorTimeout1);\n clearTimeout(this._cursorTimeout2);\n\n this._currentCursorOpacity = 0;\n // to clear just itext area we need to transform the context\n // it may not be worth it\n if (shouldClear && canvas) {\n canvas.clearContext(canvas.contextTop || canvas.contextContainer);\n }\n\n },\n\n /**\n * Selects entire text\n * @return {fabric.IText} thisArg\n * @chainable\n */\n selectAll: function() {\n this.selectionStart = 0;\n this.selectionEnd = this._text.length;\n this._fireSelectionChanged();\n this._updateTextarea();\n return this;\n },\n\n /**\n * Returns selected text\n * @return {String}\n */\n getSelectedText: function() {\n return this._text.slice(this.selectionStart, this.selectionEnd).join('');\n },\n\n /**\n * Find new selection index representing start of current word according to current selection index\n * @param {Number} startFrom Current selection index\n * @return {Number} New selection index\n */\n findWordBoundaryLeft: function(startFrom) {\n var offset = 0, index = startFrom - 1;\n\n // remove space before cursor first\n if (this._reSpace.test(this._text[index])) {\n while (this._reSpace.test(this._text[index])) {\n offset++;\n index--;\n }\n }\n while (/\\S/.test(this._text[index]) && index > -1) {\n offset++;\n index--;\n }\n\n return startFrom - offset;\n },\n\n /**\n * Find new selection index representing end of current word according to current selection index\n * @param {Number} startFrom Current selection index\n * @return {Number} New selection index\n */\n findWordBoundaryRight: function(startFrom) {\n var offset = 0, index = startFrom;\n\n // remove space after cursor first\n if (this._reSpace.test(this._text[index])) {\n while (this._reSpace.test(this._text[index])) {\n offset++;\n index++;\n }\n }\n while (/\\S/.test(this._text[index]) && index < this._text.length) {\n offset++;\n index++;\n }\n\n return startFrom + offset;\n },\n\n /**\n * Find new selection index representing start of current line according to current selection index\n * @param {Number} startFrom Current selection index\n * @return {Number} New selection index\n */\n findLineBoundaryLeft: function(startFrom) {\n var offset = 0, index = startFrom - 1;\n\n while (!/\\n/.test(this._text[index]) && index > -1) {\n offset++;\n index--;\n }\n\n return startFrom - offset;\n },\n\n /**\n * Find new selection index representing end of current line according to current selection index\n * @param {Number} startFrom Current selection index\n * @return {Number} New selection index\n */\n findLineBoundaryRight: function(startFrom) {\n var offset = 0, index = startFrom;\n\n while (!/\\n/.test(this._text[index]) && index < this._text.length) {\n offset++;\n index++;\n }\n\n return startFrom + offset;\n },\n\n /**\n * Finds index corresponding to beginning or end of a word\n * @param {Number} selectionStart Index of a character\n * @param {Number} direction 1 or -1\n * @return {Number} Index of the beginning or end of a word\n */\n searchWordBoundary: function(selectionStart, direction) {\n var text = this._text,\n index = this._reSpace.test(text[selectionStart]) ? selectionStart - 1 : selectionStart,\n _char = text[index],\n // wrong\n reNonWord = fabric.reNonWord;\n\n while (!reNonWord.test(_char) && index > 0 && index < text.length) {\n index += direction;\n _char = text[index];\n }\n if (reNonWord.test(_char)) {\n index += direction === 1 ? 0 : 1;\n }\n return index;\n },\n\n /**\n * Selects a word based on the index\n * @param {Number} selectionStart Index of a character\n */\n selectWord: function(selectionStart) {\n selectionStart = selectionStart || this.selectionStart;\n var newSelectionStart = this.searchWordBoundary(selectionStart, -1), /* search backwards */\n newSelectionEnd = this.searchWordBoundary(selectionStart, 1); /* search forward */\n\n this.selectionStart = newSelectionStart;\n this.selectionEnd = newSelectionEnd;\n this._fireSelectionChanged();\n this._updateTextarea();\n this.renderCursorOrSelection();\n },\n\n /**\n * Selects a line based on the index\n * @param {Number} selectionStart Index of a character\n * @return {fabric.IText} thisArg\n * @chainable\n */\n selectLine: function(selectionStart) {\n selectionStart = selectionStart || this.selectionStart;\n var newSelectionStart = this.findLineBoundaryLeft(selectionStart),\n newSelectionEnd = this.findLineBoundaryRight(selectionStart);\n\n this.selectionStart = newSelectionStart;\n this.selectionEnd = newSelectionEnd;\n this._fireSelectionChanged();\n this._updateTextarea();\n return this;\n },\n\n /**\n * Enters editing state\n * @return {fabric.IText} thisArg\n * @chainable\n */\n enterEditing: function(e) {\n if (this.isEditing || !this.editable) {\n return;\n }\n\n if (this.canvas) {\n this.canvas.calcOffset();\n this.exitEditingOnOthers(this.canvas);\n }\n\n this.isEditing = true;\n\n this.initHiddenTextarea(e);\n this.hiddenTextarea.focus();\n this.hiddenTextarea.value = this.text;\n this._updateTextarea();\n this._saveEditingProps();\n this._setEditingProps();\n this._textBeforeEdit = this.text;\n\n this._tick();\n this.fire('editing:entered');\n this._fireSelectionChanged();\n if (!this.canvas) {\n return this;\n }\n this.canvas.fire('text:editing:entered', { target: this });\n this.initMouseMoveHandler();\n this.canvas.requestRenderAll();\n return this;\n },\n\n exitEditingOnOthers: function(canvas) {\n if (canvas._iTextInstances) {\n canvas._iTextInstances.forEach(function(obj) {\n obj.selected = false;\n if (obj.isEditing) {\n obj.exitEditing();\n }\n });\n }\n },\n\n /**\n * Initializes \"mousemove\" event handler\n */\n initMouseMoveHandler: function() {\n this.canvas.on('mouse:move', this.mouseMoveHandler);\n },\n\n /**\n * @private\n */\n mouseMoveHandler: function(options) {\n if (!this.__isMousedown || !this.isEditing) {\n return;\n }\n\n var newSelectionStart = this.getSelectionStartFromPointer(options.e),\n currentStart = this.selectionStart,\n currentEnd = this.selectionEnd;\n if (\n (newSelectionStart !== this.__selectionStartOnMouseDown || currentStart === currentEnd)\n &&\n (currentStart === newSelectionStart || currentEnd === newSelectionStart)\n ) {\n return;\n }\n if (newSelectionStart > this.__selectionStartOnMouseDown) {\n this.selectionStart = this.__selectionStartOnMouseDown;\n this.selectionEnd = newSelectionStart;\n }\n else {\n this.selectionStart = newSelectionStart;\n this.selectionEnd = this.__selectionStartOnMouseDown;\n }\n if (this.selectionStart !== currentStart || this.selectionEnd !== currentEnd) {\n this.restartCursorIfNeeded();\n this._fireSelectionChanged();\n this._updateTextarea();\n this.renderCursorOrSelection();\n }\n },\n\n /**\n * @private\n */\n _setEditingProps: function() {\n this.hoverCursor = 'text';\n\n if (this.canvas) {\n this.canvas.defaultCursor = this.canvas.moveCursor = 'text';\n }\n\n this.borderColor = this.editingBorderColor;\n this.hasControls = this.selectable = false;\n this.lockMovementX = this.lockMovementY = true;\n },\n\n /**\n * convert from textarea to grapheme indexes\n */\n fromStringToGraphemeSelection: function(start, end, text) {\n var smallerTextStart = text.slice(0, start),\n graphemeStart = fabric.util.string.graphemeSplit(smallerTextStart).length;\n if (start === end) {\n return { selectionStart: graphemeStart, selectionEnd: graphemeStart };\n }\n var smallerTextEnd = text.slice(start, end),\n graphemeEnd = fabric.util.string.graphemeSplit(smallerTextEnd).length;\n return { selectionStart: graphemeStart, selectionEnd: graphemeStart + graphemeEnd };\n },\n\n /**\n * convert from fabric to textarea values\n */\n fromGraphemeToStringSelection: function(start, end, _text) {\n var smallerTextStart = _text.slice(0, start),\n graphemeStart = smallerTextStart.join('').length;\n if (start === end) {\n return { selectionStart: graphemeStart, selectionEnd: graphemeStart };\n }\n var smallerTextEnd = _text.slice(start, end),\n graphemeEnd = smallerTextEnd.join('').length;\n return { selectionStart: graphemeStart, selectionEnd: graphemeStart + graphemeEnd };\n },\n\n /**\n * @private\n */\n _updateTextarea: function() {\n this.cursorOffsetCache = { };\n if (!this.hiddenTextarea) {\n return;\n }\n if (!this.inCompositionMode) {\n var newSelection = this.fromGraphemeToStringSelection(this.selectionStart, this.selectionEnd, this._text);\n this.hiddenTextarea.selectionStart = newSelection.selectionStart;\n this.hiddenTextarea.selectionEnd = newSelection.selectionEnd;\n }\n this.updateTextareaPosition();\n },\n\n /**\n * @private\n */\n updateFromTextArea: function() {\n if (!this.hiddenTextarea) {\n return;\n }\n this.cursorOffsetCache = { };\n this.text = this.hiddenTextarea.value;\n if (this._shouldClearDimensionCache()) {\n this.initDimensions();\n this.setCoords();\n }\n var newSelection = this.fromStringToGraphemeSelection(\n this.hiddenTextarea.selectionStart, this.hiddenTextarea.selectionEnd, this.hiddenTextarea.value);\n this.selectionEnd = this.selectionStart = newSelection.selectionEnd;\n if (!this.inCompositionMode) {\n this.selectionStart = newSelection.selectionStart;\n }\n this.updateTextareaPosition();\n },\n\n /**\n * @private\n */\n updateTextareaPosition: function() {\n if (this.selectionStart === this.selectionEnd) {\n var style = this._calcTextareaPosition();\n this.hiddenTextarea.style.left = style.left;\n this.hiddenTextarea.style.top = style.top;\n }\n },\n\n /**\n * @private\n * @return {Object} style contains style for hiddenTextarea\n */\n _calcTextareaPosition: function() {\n if (!this.canvas) {\n return { x: 1, y: 1 };\n }\n var desiredPosition = this.inCompositionMode ? this.compositionStart : this.selectionStart,\n boundaries = this._getCursorBoundaries(desiredPosition),\n cursorLocation = this.get2DCursorLocation(desiredPosition),\n lineIndex = cursorLocation.lineIndex,\n charIndex = cursorLocation.charIndex,\n charHeight = this.getValueOfPropertyAt(lineIndex, charIndex, 'fontSize') * this.lineHeight,\n leftOffset = boundaries.leftOffset,\n m = this.calcTransformMatrix(),\n p = {\n x: boundaries.left + leftOffset,\n y: boundaries.top + boundaries.topOffset + charHeight\n },\n retinaScaling = this.canvas.getRetinaScaling(),\n upperCanvas = this.canvas.upperCanvasEl,\n upperCanvasWidth = upperCanvas.width / retinaScaling,\n upperCanvasHeight = upperCanvas.height / retinaScaling,\n maxWidth = upperCanvasWidth - charHeight,\n maxHeight = upperCanvasHeight - charHeight,\n scaleX = upperCanvas.clientWidth / upperCanvasWidth,\n scaleY = upperCanvas.clientHeight / upperCanvasHeight;\n\n p = fabric.util.transformPoint(p, m);\n p = fabric.util.transformPoint(p, this.canvas.viewportTransform);\n p.x *= scaleX;\n p.y *= scaleY;\n if (p.x < 0) {\n p.x = 0;\n }\n if (p.x > maxWidth) {\n p.x = maxWidth;\n }\n if (p.y < 0) {\n p.y = 0;\n }\n if (p.y > maxHeight) {\n p.y = maxHeight;\n }\n\n // add canvas offset on document\n p.x += this.canvas._offset.left;\n p.y += this.canvas._offset.top;\n\n return { left: p.x + 'px', top: p.y + 'px', fontSize: charHeight + 'px', charHeight: charHeight };\n },\n\n /**\n * @private\n */\n _saveEditingProps: function() {\n this._savedProps = {\n hasControls: this.hasControls,\n borderColor: this.borderColor,\n lockMovementX: this.lockMovementX,\n lockMovementY: this.lockMovementY,\n hoverCursor: this.hoverCursor,\n selectable: this.selectable,\n defaultCursor: this.canvas && this.canvas.defaultCursor,\n moveCursor: this.canvas && this.canvas.moveCursor\n };\n },\n\n /**\n * @private\n */\n _restoreEditingProps: function() {\n if (!this._savedProps) {\n return;\n }\n\n this.hoverCursor = this._savedProps.hoverCursor;\n this.hasControls = this._savedProps.hasControls;\n this.borderColor = this._savedProps.borderColor;\n this.selectable = this._savedProps.selectable;\n this.lockMovementX = this._savedProps.lockMovementX;\n this.lockMovementY = this._savedProps.lockMovementY;\n\n if (this.canvas) {\n this.canvas.defaultCursor = this._savedProps.defaultCursor;\n this.canvas.moveCursor = this._savedProps.moveCursor;\n }\n },\n\n /**\n * Exits from editing state\n * @return {fabric.IText} thisArg\n * @chainable\n */\n exitEditing: function() {\n var isTextChanged = (this._textBeforeEdit !== this.text);\n var hiddenTextarea = this.hiddenTextarea;\n this.selected = false;\n this.isEditing = false;\n\n this.selectionEnd = this.selectionStart;\n\n if (hiddenTextarea) {\n hiddenTextarea.blur && hiddenTextarea.blur();\n hiddenTextarea.parentNode && hiddenTextarea.parentNode.removeChild(hiddenTextarea);\n }\n this.hiddenTextarea = null;\n this.abortCursorAnimation();\n this._restoreEditingProps();\n this._currentCursorOpacity = 0;\n if (this._shouldClearDimensionCache()) {\n this.initDimensions();\n this.setCoords();\n }\n this.fire('editing:exited');\n isTextChanged && this.fire('modified');\n if (this.canvas) {\n this.canvas.off('mouse:move', this.mouseMoveHandler);\n this.canvas.fire('text:editing:exited', { target: this });\n isTextChanged && this.canvas.fire('object:modified', { target: this });\n }\n return this;\n },\n\n /**\n * @private\n */\n _removeExtraneousStyles: function() {\n for (var prop in this.styles) {\n if (!this._textLines[prop]) {\n delete this.styles[prop];\n }\n }\n },\n\n /**\n * remove and reflow a style block from start to end.\n * @param {Number} start linear start position for removal (included in removal)\n * @param {Number} end linear end position for removal ( excluded from removal )\n */\n removeStyleFromTo: function(start, end) {\n var cursorStart = this.get2DCursorLocation(start, true),\n cursorEnd = this.get2DCursorLocation(end, true),\n lineStart = cursorStart.lineIndex,\n charStart = cursorStart.charIndex,\n lineEnd = cursorEnd.lineIndex,\n charEnd = cursorEnd.charIndex,\n i, styleObj;\n if (lineStart !== lineEnd) {\n // step1 remove the trailing of lineStart\n if (this.styles[lineStart]) {\n for (i = charStart; i < this._unwrappedTextLines[lineStart].length; i++) {\n delete this.styles[lineStart][i];\n }\n }\n // step2 move the trailing of lineEnd to lineStart if needed\n if (this.styles[lineEnd]) {\n for (i = charEnd; i < this._unwrappedTextLines[lineEnd].length; i++) {\n styleObj = this.styles[lineEnd][i];\n if (styleObj) {\n this.styles[lineStart] || (this.styles[lineStart] = { });\n this.styles[lineStart][charStart + i - charEnd] = styleObj;\n }\n }\n }\n // step3 detects lines will be completely removed.\n for (i = lineStart + 1; i <= lineEnd; i++) {\n delete this.styles[i];\n }\n // step4 shift remaining lines.\n this.shiftLineStyles(lineEnd, lineStart - lineEnd);\n }\n else {\n // remove and shift left on the same line\n if (this.styles[lineStart]) {\n styleObj = this.styles[lineStart];\n var diff = charEnd - charStart, numericChar, _char;\n for (i = charStart; i < charEnd; i++) {\n delete styleObj[i];\n }\n for (_char in this.styles[lineStart]) {\n numericChar = parseInt(_char, 10);\n if (numericChar >= charEnd) {\n styleObj[numericChar - diff] = styleObj[_char];\n delete styleObj[_char];\n }\n }\n }\n }\n },\n\n /**\n * Shifts line styles up or down\n * @param {Number} lineIndex Index of a line\n * @param {Number} offset Can any number?\n */\n shiftLineStyles: function(lineIndex, offset) {\n // shift all line styles by offset upward or downward\n // do not clone deep. we need new array, not new style objects\n var clonedStyles = clone(this.styles);\n for (var line in this.styles) {\n var numericLine = parseInt(line, 10);\n if (numericLine > lineIndex) {\n this.styles[numericLine + offset] = clonedStyles[numericLine];\n if (!clonedStyles[numericLine - offset]) {\n delete this.styles[numericLine];\n }\n }\n }\n },\n\n restartCursorIfNeeded: function() {\n if (!this._currentTickState || this._currentTickState.isAborted\n || !this._currentTickCompleteState || this._currentTickCompleteState.isAborted\n ) {\n this.initDelayedCursor();\n }\n },\n\n /**\n * Handle insertion of more consecutive style lines for when one or more\n * newlines gets added to the text. Since current style needs to be shifted\n * first we shift the current style of the number lines needed, then we add\n * new lines from the last to the first.\n * @param {Number} lineIndex Index of a line\n * @param {Number} charIndex Index of a char\n * @param {Number} qty number of lines to add\n * @param {Array} copiedStyle Array of objects styles\n */\n insertNewlineStyleObject: function(lineIndex, charIndex, qty, copiedStyle) {\n var currentCharStyle,\n newLineStyles = {},\n somethingAdded = false,\n isEndOfLine = this._unwrappedTextLines[lineIndex].length === charIndex;\n\n qty || (qty = 1);\n this.shiftLineStyles(lineIndex, qty);\n if (this.styles[lineIndex]) {\n currentCharStyle = this.styles[lineIndex][charIndex === 0 ? charIndex : charIndex - 1];\n }\n // we clone styles of all chars\n // after cursor onto the current line\n for (var index in this.styles[lineIndex]) {\n var numIndex = parseInt(index, 10);\n if (numIndex >= charIndex) {\n somethingAdded = true;\n newLineStyles[numIndex - charIndex] = this.styles[lineIndex][index];\n // remove lines from the previous line since they're on a new line now\n if (!(isEndOfLine && charIndex === 0)) {\n delete this.styles[lineIndex][index];\n }\n }\n }\n var styleCarriedOver = false;\n if (somethingAdded && !isEndOfLine) {\n // if is end of line, the extra style we copied\n // is probably not something we want\n this.styles[lineIndex + qty] = newLineStyles;\n styleCarriedOver = true;\n }\n if (styleCarriedOver) {\n // skip the last line of since we already prepared it.\n qty--;\n }\n // for the all the lines or all the other lines\n // we clone current char style onto the next (otherwise empty) line\n while (qty > 0) {\n if (copiedStyle && copiedStyle[qty - 1]) {\n this.styles[lineIndex + qty] = { 0: clone(copiedStyle[qty - 1]) };\n }\n else if (currentCharStyle) {\n this.styles[lineIndex + qty] = { 0: clone(currentCharStyle) };\n }\n else {\n delete this.styles[lineIndex + qty];\n }\n qty--;\n }\n this._forceClearCache = true;\n },\n\n /**\n * Inserts style object for a given line/char index\n * @param {Number} lineIndex Index of a line\n * @param {Number} charIndex Index of a char\n * @param {Number} quantity number Style object to insert, if given\n * @param {Array} copiedStyle array of style objects\n */\n insertCharStyleObject: function(lineIndex, charIndex, quantity, copiedStyle) {\n if (!this.styles) {\n this.styles = {};\n }\n var currentLineStyles = this.styles[lineIndex],\n currentLineStylesCloned = currentLineStyles ? clone(currentLineStyles) : {};\n\n quantity || (quantity = 1);\n // shift all char styles by quantity forward\n // 0,1,2,3 -> (charIndex=2) -> 0,1,3,4 -> (insert 2) -> 0,1,2,3,4\n for (var index in currentLineStylesCloned) {\n var numericIndex = parseInt(index, 10);\n if (numericIndex >= charIndex) {\n currentLineStyles[numericIndex + quantity] = currentLineStylesCloned[numericIndex];\n // only delete the style if there was nothing moved there\n if (!currentLineStylesCloned[numericIndex - quantity]) {\n delete currentLineStyles[numericIndex];\n }\n }\n }\n this._forceClearCache = true;\n if (copiedStyle) {\n while (quantity--) {\n if (!Object.keys(copiedStyle[quantity]).length) {\n continue;\n }\n if (!this.styles[lineIndex]) {\n this.styles[lineIndex] = {};\n }\n this.styles[lineIndex][charIndex + quantity] = clone(copiedStyle[quantity]);\n }\n return;\n }\n if (!currentLineStyles) {\n return;\n }\n var newStyle = currentLineStyles[charIndex ? charIndex - 1 : 1];\n while (newStyle && quantity--) {\n this.styles[lineIndex][charIndex + quantity] = clone(newStyle);\n }\n },\n\n /**\n * Inserts style object(s)\n * @param {Array} insertedText Characters at the location where style is inserted\n * @param {Number} start cursor index for inserting style\n * @param {Array} [copiedStyle] array of style objects to insert.\n */\n insertNewStyleBlock: function(insertedText, start, copiedStyle) {\n var cursorLoc = this.get2DCursorLocation(start, true),\n addedLines = [0], linesLength = 0;\n // get an array of how many char per lines are being added.\n for (var i = 0; i < insertedText.length; i++) {\n if (insertedText[i] === '\\n') {\n linesLength++;\n addedLines[linesLength] = 0;\n }\n else {\n addedLines[linesLength]++;\n }\n }\n // for the first line copy the style from the current char position.\n if (addedLines[0] > 0) {\n this.insertCharStyleObject(cursorLoc.lineIndex, cursorLoc.charIndex, addedLines[0], copiedStyle);\n copiedStyle = copiedStyle && copiedStyle.slice(addedLines[0] + 1);\n }\n linesLength && this.insertNewlineStyleObject(\n cursorLoc.lineIndex, cursorLoc.charIndex + addedLines[0], linesLength);\n for (var i = 1; i < linesLength; i++) {\n if (addedLines[i] > 0) {\n this.insertCharStyleObject(cursorLoc.lineIndex + i, 0, addedLines[i], copiedStyle);\n }\n else if (copiedStyle) {\n this.styles[cursorLoc.lineIndex + i][0] = copiedStyle[0];\n }\n copiedStyle = copiedStyle && copiedStyle.slice(addedLines[i] + 1);\n }\n // we use i outside the loop to get it like linesLength\n if (addedLines[i] > 0) {\n this.insertCharStyleObject(cursorLoc.lineIndex + i, 0, addedLines[i], copiedStyle);\n }\n },\n\n /**\n * Set the selectionStart and selectionEnd according to the new position of cursor\n * mimic the key - mouse navigation when shift is pressed.\n */\n setSelectionStartEndWithShift: function(start, end, newSelection) {\n if (newSelection <= start) {\n if (end === start) {\n this._selectionDirection = 'left';\n }\n else if (this._selectionDirection === 'right') {\n this._selectionDirection = 'left';\n this.selectionEnd = start;\n }\n this.selectionStart = newSelection;\n }\n else if (newSelection > start && newSelection < end) {\n if (this._selectionDirection === 'right') {\n this.selectionEnd = newSelection;\n }\n else {\n this.selectionStart = newSelection;\n }\n }\n else {\n // newSelection is > selection start and end\n if (end === start) {\n this._selectionDirection = 'right';\n }\n else if (this._selectionDirection === 'left') {\n this._selectionDirection = 'right';\n this.selectionStart = end;\n }\n this.selectionEnd = newSelection;\n }\n },\n\n setSelectionInBoundaries: function() {\n var length = this.text.length;\n if (this.selectionStart > length) {\n this.selectionStart = length;\n }\n else if (this.selectionStart < 0) {\n this.selectionStart = 0;\n }\n if (this.selectionEnd > length) {\n this.selectionEnd = length;\n }\n else if (this.selectionEnd < 0) {\n this.selectionEnd = 0;\n }\n }\n });\n})();\n\n\nfabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.prototype */ {\n /**\n * Initializes \"dbclick\" event handler\n */\n initDoubleClickSimulation: function() {\n\n // for double click\n this.__lastClickTime = +new Date();\n\n // for triple click\n this.__lastLastClickTime = +new Date();\n\n this.__lastPointer = { };\n\n this.on('mousedown', this.onMouseDown);\n },\n\n /**\n * Default event handler to simulate triple click\n * @private\n */\n onMouseDown: function(options) {\n if (!this.canvas) {\n return;\n }\n this.__newClickTime = +new Date();\n var newPointer = options.pointer;\n if (this.isTripleClick(newPointer)) {\n this.fire('tripleclick', options);\n this._stopEvent(options.e);\n }\n this.__lastLastClickTime = this.__lastClickTime;\n this.__lastClickTime = this.__newClickTime;\n this.__lastPointer = newPointer;\n this.__lastIsEditing = this.isEditing;\n this.__lastSelected = this.selected;\n },\n\n isTripleClick: function(newPointer) {\n return this.__newClickTime - this.__lastClickTime < 500 &&\n this.__lastClickTime - this.__lastLastClickTime < 500 &&\n this.__lastPointer.x === newPointer.x &&\n this.__lastPointer.y === newPointer.y;\n },\n\n /**\n * @private\n */\n _stopEvent: function(e) {\n e.preventDefault && e.preventDefault();\n e.stopPropagation && e.stopPropagation();\n },\n\n /**\n * Initializes event handlers related to cursor or selection\n */\n initCursorSelectionHandlers: function() {\n this.initMousedownHandler();\n this.initMouseupHandler();\n this.initClicks();\n },\n\n /**\n * Default handler for double click, select a word\n */\n doubleClickHandler: function(options) {\n if (!this.isEditing) {\n return;\n }\n this.selectWord(this.getSelectionStartFromPointer(options.e));\n },\n\n /**\n * Default handler for triple click, select a line\n */\n tripleClickHandler: function(options) {\n if (!this.isEditing) {\n return;\n }\n this.selectLine(this.getSelectionStartFromPointer(options.e));\n },\n\n /**\n * Initializes double and triple click event handlers\n */\n initClicks: function() {\n this.on('mousedblclick', this.doubleClickHandler);\n this.on('tripleclick', this.tripleClickHandler);\n },\n\n /**\n * Default event handler for the basic functionalities needed on _mouseDown\n * can be overridden to do something different.\n * Scope of this implementation is: find the click position, set selectionStart\n * find selectionEnd, initialize the drawing of either cursor or selection area\n * initializing a mousedDown on a text area will cancel fabricjs knowledge of\n * current compositionMode. It will be set to false.\n */\n _mouseDownHandler: function(options) {\n if (!this.canvas || !this.editable || (options.e.button && options.e.button !== 1)) {\n return;\n }\n\n this.__isMousedown = true;\n\n if (this.selected) {\n this.inCompositionMode = false;\n this.setCursorByClick(options.e);\n }\n\n if (this.isEditing) {\n this.__selectionStartOnMouseDown = this.selectionStart;\n if (this.selectionStart === this.selectionEnd) {\n this.abortCursorAnimation();\n }\n this.renderCursorOrSelection();\n }\n },\n\n /**\n * Default event handler for the basic functionalities needed on mousedown:before\n * can be overridden to do something different.\n * Scope of this implementation is: verify the object is already selected when mousing down\n */\n _mouseDownHandlerBefore: function(options) {\n if (!this.canvas || !this.editable || (options.e.button && options.e.button !== 1)) {\n return;\n }\n // we want to avoid that an object that was selected and then becomes unselectable,\n // may trigger editing mode in some way.\n this.selected = this === this.canvas._activeObject;\n },\n\n /**\n * Initializes \"mousedown\" event handler\n */\n initMousedownHandler: function() {\n this.on('mousedown', this._mouseDownHandler);\n this.on('mousedown:before', this._mouseDownHandlerBefore);\n },\n\n /**\n * Initializes \"mouseup\" event handler\n */\n initMouseupHandler: function() {\n this.on('mouseup', this.mouseUpHandler);\n },\n\n /**\n * standard hander for mouse up, overridable\n * @private\n */\n mouseUpHandler: function(options) {\n this.__isMousedown = false;\n if (!this.editable || this.group ||\n (options.transform && options.transform.actionPerformed) ||\n (options.e.button && options.e.button !== 1)) {\n return;\n }\n\n if (this.canvas) {\n var currentActive = this.canvas._activeObject;\n if (currentActive && currentActive !== this) {\n // avoid running this logic when there is an active object\n // this because is possible with shift click and fast clicks,\n // to rapidly deselect and reselect this object and trigger an enterEdit\n return;\n }\n }\n\n if (this.__lastSelected && !this.__corner) {\n this.selected = false;\n this.__lastSelected = false;\n this.enterEditing(options.e);\n if (this.selectionStart === this.selectionEnd) {\n this.initDelayedCursor(true);\n }\n else {\n this.renderCursorOrSelection();\n }\n }\n else {\n this.selected = true;\n }\n },\n\n /**\n * Changes cursor location in a text depending on passed pointer (x/y) object\n * @param {Event} e Event object\n */\n setCursorByClick: function(e) {\n var newSelection = this.getSelectionStartFromPointer(e),\n start = this.selectionStart, end = this.selectionEnd;\n if (e.shiftKey) {\n this.setSelectionStartEndWithShift(start, end, newSelection);\n }\n else {\n this.selectionStart = newSelection;\n this.selectionEnd = newSelection;\n }\n if (this.isEditing) {\n this._fireSelectionChanged();\n this._updateTextarea();\n }\n },\n\n /**\n * Returns index of a character corresponding to where an object was clicked\n * @param {Event} e Event object\n * @return {Number} Index of a character\n */\n getSelectionStartFromPointer: function(e) {\n var mouseOffset = this.getLocalPointer(e),\n prevWidth = 0,\n width = 0,\n height = 0,\n charIndex = 0,\n lineIndex = 0,\n lineLeftOffset,\n line;\n\n for (var i = 0, len = this._textLines.length; i < len; i++) {\n if (height <= mouseOffset.y) {\n height += this.getHeightOfLine(i) * this.scaleY;\n lineIndex = i;\n if (i > 0) {\n charIndex += this._textLines[i - 1].length + this.missingNewlineOffset(i - 1);\n }\n }\n else {\n break;\n }\n }\n lineLeftOffset = this._getLineLeftOffset(lineIndex);\n width = lineLeftOffset * this.scaleX;\n line = this._textLines[lineIndex];\n for (var j = 0, jlen = line.length; j < jlen; j++) {\n prevWidth = width;\n // i removed something about flipX here, check.\n width += this.__charBounds[lineIndex][j].kernedWidth * this.scaleX;\n if (width <= mouseOffset.x) {\n charIndex++;\n }\n else {\n break;\n }\n }\n return this._getNewSelectionStartFromOffset(mouseOffset, prevWidth, width, charIndex, jlen);\n },\n\n /**\n * @private\n */\n _getNewSelectionStartFromOffset: function(mouseOffset, prevWidth, width, index, jlen) {\n // we need Math.abs because when width is after the last char, the offset is given as 1, while is 0\n var distanceBtwLastCharAndCursor = mouseOffset.x - prevWidth,\n distanceBtwNextCharAndCursor = width - mouseOffset.x,\n offset = distanceBtwNextCharAndCursor > distanceBtwLastCharAndCursor ||\n distanceBtwNextCharAndCursor < 0 ? 0 : 1,\n newSelectionStart = index + offset;\n // if object is horizontally flipped, mirror cursor location from the end\n if (this.flipX) {\n newSelectionStart = jlen - newSelectionStart;\n }\n\n if (newSelectionStart > this._text.length) {\n newSelectionStart = this._text.length;\n }\n\n return newSelectionStart;\n }\n});\n\n\nfabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.prototype */ {\n\n /**\n * Initializes hidden textarea (needed to bring up keyboard in iOS)\n */\n initHiddenTextarea: function() {\n this.hiddenTextarea = fabric.document.createElement('textarea');\n this.hiddenTextarea.setAttribute('autocapitalize', 'off');\n this.hiddenTextarea.setAttribute('autocorrect', 'off');\n this.hiddenTextarea.setAttribute('autocomplete', 'off');\n this.hiddenTextarea.setAttribute('spellcheck', 'false');\n this.hiddenTextarea.setAttribute('data-fabric-hiddentextarea', '');\n this.hiddenTextarea.setAttribute('wrap', 'off');\n var style = this._calcTextareaPosition();\n // line-height: 1px; was removed from the style to fix this:\n // https://bugs.chromium.org/p/chromium/issues/detail?id=870966\n this.hiddenTextarea.style.cssText = 'position: absolute; top: ' + style.top +\n '; left: ' + style.left + '; z-index: -999; opacity: 0; width: 1px; height: 1px; font-size: 1px;' +\n ' paddingーtop: ' + style.fontSize + ';';\n fabric.document.body.appendChild(this.hiddenTextarea);\n\n fabric.util.addListener(this.hiddenTextarea, 'keydown', this.onKeyDown.bind(this));\n fabric.util.addListener(this.hiddenTextarea, 'keyup', this.onKeyUp.bind(this));\n fabric.util.addListener(this.hiddenTextarea, 'input', this.onInput.bind(this));\n fabric.util.addListener(this.hiddenTextarea, 'copy', this.copy.bind(this));\n fabric.util.addListener(this.hiddenTextarea, 'cut', this.copy.bind(this));\n fabric.util.addListener(this.hiddenTextarea, 'paste', this.paste.bind(this));\n fabric.util.addListener(this.hiddenTextarea, 'compositionstart', this.onCompositionStart.bind(this));\n fabric.util.addListener(this.hiddenTextarea, 'compositionupdate', this.onCompositionUpdate.bind(this));\n fabric.util.addListener(this.hiddenTextarea, 'compositionend', this.onCompositionEnd.bind(this));\n\n if (!this._clickHandlerInitialized && this.canvas) {\n fabric.util.addListener(this.canvas.upperCanvasEl, 'click', this.onClick.bind(this));\n this._clickHandlerInitialized = true;\n }\n },\n\n /**\n * For functionalities on keyDown\n * Map a special key to a function of the instance/prototype\n * If you need different behaviour for ESC or TAB or arrows, you have to change\n * this map setting the name of a function that you build on the fabric.Itext or\n * your prototype.\n * the map change will affect all Instances unless you need for only some text Instances\n * in that case you have to clone this object and assign your Instance.\n * this.keysMap = fabric.util.object.clone(this.keysMap);\n * The function must be in fabric.Itext.prototype.myFunction And will receive event as args[0]\n */\n keysMap: {\n 9: 'exitEditing',\n 27: 'exitEditing',\n 33: 'moveCursorUp',\n 34: 'moveCursorDown',\n 35: 'moveCursorRight',\n 36: 'moveCursorLeft',\n 37: 'moveCursorLeft',\n 38: 'moveCursorUp',\n 39: 'moveCursorRight',\n 40: 'moveCursorDown',\n },\n\n /**\n * For functionalities on keyUp + ctrl || cmd\n */\n ctrlKeysMapUp: {\n 67: 'copy',\n 88: 'cut'\n },\n\n /**\n * For functionalities on keyDown + ctrl || cmd\n */\n ctrlKeysMapDown: {\n 65: 'selectAll'\n },\n\n onClick: function() {\n // No need to trigger click event here, focus is enough to have the keyboard appear on Android\n this.hiddenTextarea && this.hiddenTextarea.focus();\n },\n\n /**\n * Handles keydown event\n * only used for arrows and combination of modifier keys.\n * @param {Event} e Event object\n */\n onKeyDown: function(e) {\n if (!this.isEditing) {\n return;\n }\n if (e.keyCode in this.keysMap) {\n this[this.keysMap[e.keyCode]](e);\n }\n else if ((e.keyCode in this.ctrlKeysMapDown) && (e.ctrlKey || e.metaKey)) {\n this[this.ctrlKeysMapDown[e.keyCode]](e);\n }\n else {\n return;\n }\n e.stopImmediatePropagation();\n e.preventDefault();\n if (e.keyCode >= 33 && e.keyCode <= 40) {\n // if i press an arrow key just update selection\n this.inCompositionMode = false;\n this.clearContextTop();\n this.renderCursorOrSelection();\n }\n else {\n this.canvas && this.canvas.requestRenderAll();\n }\n },\n\n /**\n * Handles keyup event\n * We handle KeyUp because ie11 and edge have difficulties copy/pasting\n * if a copy/cut event fired, keyup is dismissed\n * @param {Event} e Event object\n */\n onKeyUp: function(e) {\n if (!this.isEditing || this._copyDone || this.inCompositionMode) {\n this._copyDone = false;\n return;\n }\n if ((e.keyCode in this.ctrlKeysMapUp) && (e.ctrlKey || e.metaKey)) {\n this[this.ctrlKeysMapUp[e.keyCode]](e);\n }\n else {\n return;\n }\n e.stopImmediatePropagation();\n e.preventDefault();\n this.canvas && this.canvas.requestRenderAll();\n },\n\n /**\n * Handles onInput event\n * @param {Event} e Event object\n */\n onInput: function(e) {\n var fromPaste = this.fromPaste;\n this.fromPaste = false;\n e && e.stopPropagation();\n if (!this.isEditing) {\n return;\n }\n // decisions about style changes.\n var nextText = this._splitTextIntoLines(this.hiddenTextarea.value).graphemeText,\n charCount = this._text.length,\n nextCharCount = nextText.length,\n removedText, insertedText,\n charDiff = nextCharCount - charCount,\n selectionStart = this.selectionStart, selectionEnd = this.selectionEnd,\n selection = selectionStart !== selectionEnd,\n copiedStyle, removeFrom, removeTo;\n if (this.hiddenTextarea.value === '') {\n this.styles = { };\n this.updateFromTextArea();\n this.fire('changed');\n if (this.canvas) {\n this.canvas.fire('text:changed', { target: this });\n this.canvas.requestRenderAll();\n }\n return;\n }\n\n var textareaSelection = this.fromStringToGraphemeSelection(\n this.hiddenTextarea.selectionStart,\n this.hiddenTextarea.selectionEnd,\n this.hiddenTextarea.value\n );\n var backDelete = selectionStart > textareaSelection.selectionStart;\n\n if (selection) {\n removedText = this._text.slice(selectionStart, selectionEnd);\n charDiff += selectionEnd - selectionStart;\n }\n else if (nextCharCount < charCount) {\n if (backDelete) {\n removedText = this._text.slice(selectionEnd + charDiff, selectionEnd);\n }\n else {\n removedText = this._text.slice(selectionStart, selectionStart - charDiff);\n }\n }\n insertedText = nextText.slice(textareaSelection.selectionEnd - charDiff, textareaSelection.selectionEnd);\n if (removedText && removedText.length) {\n if (insertedText.length) {\n // let's copy some style before deleting.\n // we want to copy the style before the cursor OR the style at the cursor if selection\n // is bigger than 0.\n copiedStyle = this.getSelectionStyles(selectionStart, selectionStart + 1, false);\n // now duplicate the style one for each inserted text.\n copiedStyle = insertedText.map(function() {\n // this return an array of references, but that is fine since we are\n // copying the style later.\n return copiedStyle[0];\n });\n }\n if (selection) {\n removeFrom = selectionStart;\n removeTo = selectionEnd;\n }\n else if (backDelete) {\n // detect differencies between forwardDelete and backDelete\n removeFrom = selectionEnd - removedText.length;\n removeTo = selectionEnd;\n }\n else {\n removeFrom = selectionEnd;\n removeTo = selectionEnd + removedText.length;\n }\n this.removeStyleFromTo(removeFrom, removeTo);\n }\n if (insertedText.length) {\n if (fromPaste && insertedText.join('') === fabric.copiedText && !fabric.disableStyleCopyPaste) {\n copiedStyle = fabric.copiedTextStyle;\n }\n this.insertNewStyleBlock(insertedText, selectionStart, copiedStyle);\n }\n this.updateFromTextArea();\n this.fire('changed');\n if (this.canvas) {\n this.canvas.fire('text:changed', { target: this });\n this.canvas.requestRenderAll();\n }\n },\n /**\n * Composition start\n */\n onCompositionStart: function() {\n this.inCompositionMode = true;\n },\n\n /**\n * Composition end\n */\n onCompositionEnd: function() {\n this.inCompositionMode = false;\n },\n\n // /**\n // * Composition update\n // */\n onCompositionUpdate: function(e) {\n this.compositionStart = e.target.selectionStart;\n this.compositionEnd = e.target.selectionEnd;\n this.updateTextareaPosition();\n },\n\n /**\n * Copies selected text\n * @param {Event} e Event object\n */\n copy: function() {\n if (this.selectionStart === this.selectionEnd) {\n //do not cut-copy if no selection\n return;\n }\n\n fabric.copiedText = this.getSelectedText();\n if (!fabric.disableStyleCopyPaste) {\n fabric.copiedTextStyle = this.getSelectionStyles(this.selectionStart, this.selectionEnd, true);\n }\n else {\n fabric.copiedTextStyle = null;\n }\n this._copyDone = true;\n },\n\n /**\n * Pastes text\n * @param {Event} e Event object\n */\n paste: function() {\n this.fromPaste = true;\n },\n\n /**\n * @private\n * @param {Event} e Event object\n * @return {Object} Clipboard data object\n */\n _getClipboardData: function(e) {\n return (e && e.clipboardData) || fabric.window.clipboardData;\n },\n\n /**\n * Finds the width in pixels before the cursor on the same line\n * @private\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @return {Number} widthBeforeCursor width before cursor\n */\n _getWidthBeforeCursor: function(lineIndex, charIndex) {\n var widthBeforeCursor = this._getLineLeftOffset(lineIndex), bound;\n\n if (charIndex > 0) {\n bound = this.__charBounds[lineIndex][charIndex - 1];\n widthBeforeCursor += bound.left + bound.width;\n }\n return widthBeforeCursor;\n },\n\n /**\n * Gets start offset of a selection\n * @param {Event} e Event object\n * @param {Boolean} isRight\n * @return {Number}\n */\n getDownCursorOffset: function(e, isRight) {\n var selectionProp = this._getSelectionForOffset(e, isRight),\n cursorLocation = this.get2DCursorLocation(selectionProp),\n lineIndex = cursorLocation.lineIndex;\n // if on last line, down cursor goes to end of line\n if (lineIndex === this._textLines.length - 1 || e.metaKey || e.keyCode === 34) {\n // move to the end of a text\n return this._text.length - selectionProp;\n }\n var charIndex = cursorLocation.charIndex,\n widthBeforeCursor = this._getWidthBeforeCursor(lineIndex, charIndex),\n indexOnOtherLine = this._getIndexOnLine(lineIndex + 1, widthBeforeCursor),\n textAfterCursor = this._textLines[lineIndex].slice(charIndex);\n return textAfterCursor.length + indexOnOtherLine + 1 + this.missingNewlineOffset(lineIndex);\n },\n\n /**\n * private\n * Helps finding if the offset should be counted from Start or End\n * @param {Event} e Event object\n * @param {Boolean} isRight\n * @return {Number}\n */\n _getSelectionForOffset: function(e, isRight) {\n if (e.shiftKey && this.selectionStart !== this.selectionEnd && isRight) {\n return this.selectionEnd;\n }\n else {\n return this.selectionStart;\n }\n },\n\n /**\n * @param {Event} e Event object\n * @param {Boolean} isRight\n * @return {Number}\n */\n getUpCursorOffset: function(e, isRight) {\n var selectionProp = this._getSelectionForOffset(e, isRight),\n cursorLocation = this.get2DCursorLocation(selectionProp),\n lineIndex = cursorLocation.lineIndex;\n if (lineIndex === 0 || e.metaKey || e.keyCode === 33) {\n // if on first line, up cursor goes to start of line\n return -selectionProp;\n }\n var charIndex = cursorLocation.charIndex,\n widthBeforeCursor = this._getWidthBeforeCursor(lineIndex, charIndex),\n indexOnOtherLine = this._getIndexOnLine(lineIndex - 1, widthBeforeCursor),\n textBeforeCursor = this._textLines[lineIndex].slice(0, charIndex),\n missingNewlineOffset = this.missingNewlineOffset(lineIndex - 1);\n // return a negative offset\n return -this._textLines[lineIndex - 1].length\n + indexOnOtherLine - textBeforeCursor.length + (1 - missingNewlineOffset);\n },\n\n /**\n * for a given width it founds the matching character.\n * @private\n */\n _getIndexOnLine: function(lineIndex, width) {\n\n var line = this._textLines[lineIndex],\n lineLeftOffset = this._getLineLeftOffset(lineIndex),\n widthOfCharsOnLine = lineLeftOffset,\n indexOnLine = 0, charWidth, foundMatch;\n\n for (var j = 0, jlen = line.length; j < jlen; j++) {\n charWidth = this.__charBounds[lineIndex][j].width;\n widthOfCharsOnLine += charWidth;\n if (widthOfCharsOnLine > width) {\n foundMatch = true;\n var leftEdge = widthOfCharsOnLine - charWidth,\n rightEdge = widthOfCharsOnLine,\n offsetFromLeftEdge = Math.abs(leftEdge - width),\n offsetFromRightEdge = Math.abs(rightEdge - width);\n\n indexOnLine = offsetFromRightEdge < offsetFromLeftEdge ? j : (j - 1);\n break;\n }\n }\n\n // reached end\n if (!foundMatch) {\n indexOnLine = line.length - 1;\n }\n\n return indexOnLine;\n },\n\n\n /**\n * Moves cursor down\n * @param {Event} e Event object\n */\n moveCursorDown: function(e) {\n if (this.selectionStart >= this._text.length && this.selectionEnd >= this._text.length) {\n return;\n }\n this._moveCursorUpOrDown('Down', e);\n },\n\n /**\n * Moves cursor up\n * @param {Event} e Event object\n */\n moveCursorUp: function(e) {\n if (this.selectionStart === 0 && this.selectionEnd === 0) {\n return;\n }\n this._moveCursorUpOrDown('Up', e);\n },\n\n /**\n * Moves cursor up or down, fires the events\n * @param {String} direction 'Up' or 'Down'\n * @param {Event} e Event object\n */\n _moveCursorUpOrDown: function(direction, e) {\n // getUpCursorOffset\n // getDownCursorOffset\n var action = 'get' + direction + 'CursorOffset',\n offset = this[action](e, this._selectionDirection === 'right');\n if (e.shiftKey) {\n this.moveCursorWithShift(offset);\n }\n else {\n this.moveCursorWithoutShift(offset);\n }\n if (offset !== 0) {\n this.setSelectionInBoundaries();\n this.abortCursorAnimation();\n this._currentCursorOpacity = 1;\n this.initDelayedCursor();\n this._fireSelectionChanged();\n this._updateTextarea();\n }\n },\n\n /**\n * Moves cursor with shift\n * @param {Number} offset\n */\n moveCursorWithShift: function(offset) {\n var newSelection = this._selectionDirection === 'left'\n ? this.selectionStart + offset\n : this.selectionEnd + offset;\n this.setSelectionStartEndWithShift(this.selectionStart, this.selectionEnd, newSelection);\n return offset !== 0;\n },\n\n /**\n * Moves cursor up without shift\n * @param {Number} offset\n */\n moveCursorWithoutShift: function(offset) {\n if (offset < 0) {\n this.selectionStart += offset;\n this.selectionEnd = this.selectionStart;\n }\n else {\n this.selectionEnd += offset;\n this.selectionStart = this.selectionEnd;\n }\n return offset !== 0;\n },\n\n /**\n * Moves cursor left\n * @param {Event} e Event object\n */\n moveCursorLeft: function(e) {\n if (this.selectionStart === 0 && this.selectionEnd === 0) {\n return;\n }\n this._moveCursorLeftOrRight('Left', e);\n },\n\n /**\n * @private\n * @return {Boolean} true if a change happened\n */\n _move: function(e, prop, direction) {\n var newValue;\n if (e.altKey) {\n newValue = this['findWordBoundary' + direction](this[prop]);\n }\n else if (e.metaKey || e.keyCode === 35 || e.keyCode === 36 ) {\n newValue = this['findLineBoundary' + direction](this[prop]);\n }\n else {\n this[prop] += direction === 'Left' ? -1 : 1;\n return true;\n }\n if (typeof newValue !== undefined && this[prop] !== newValue) {\n this[prop] = newValue;\n return true;\n }\n },\n\n /**\n * @private\n */\n _moveLeft: function(e, prop) {\n return this._move(e, prop, 'Left');\n },\n\n /**\n * @private\n */\n _moveRight: function(e, prop) {\n return this._move(e, prop, 'Right');\n },\n\n /**\n * Moves cursor left without keeping selection\n * @param {Event} e\n */\n moveCursorLeftWithoutShift: function(e) {\n var change = true;\n this._selectionDirection = 'left';\n\n // only move cursor when there is no selection,\n // otherwise we discard it, and leave cursor on same place\n if (this.selectionEnd === this.selectionStart && this.selectionStart !== 0) {\n change = this._moveLeft(e, 'selectionStart');\n\n }\n this.selectionEnd = this.selectionStart;\n return change;\n },\n\n /**\n * Moves cursor left while keeping selection\n * @param {Event} e\n */\n moveCursorLeftWithShift: function(e) {\n if (this._selectionDirection === 'right' && this.selectionStart !== this.selectionEnd) {\n return this._moveLeft(e, 'selectionEnd');\n }\n else if (this.selectionStart !== 0){\n this._selectionDirection = 'left';\n return this._moveLeft(e, 'selectionStart');\n }\n },\n\n /**\n * Moves cursor right\n * @param {Event} e Event object\n */\n moveCursorRight: function(e) {\n if (this.selectionStart >= this._text.length && this.selectionEnd >= this._text.length) {\n return;\n }\n this._moveCursorLeftOrRight('Right', e);\n },\n\n /**\n * Moves cursor right or Left, fires event\n * @param {String} direction 'Left', 'Right'\n * @param {Event} e Event object\n */\n _moveCursorLeftOrRight: function(direction, e) {\n var actionName = 'moveCursor' + direction + 'With';\n this._currentCursorOpacity = 1;\n\n if (e.shiftKey) {\n actionName += 'Shift';\n }\n else {\n actionName += 'outShift';\n }\n if (this[actionName](e)) {\n this.abortCursorAnimation();\n this.initDelayedCursor();\n this._fireSelectionChanged();\n this._updateTextarea();\n }\n },\n\n /**\n * Moves cursor right while keeping selection\n * @param {Event} e\n */\n moveCursorRightWithShift: function(e) {\n if (this._selectionDirection === 'left' && this.selectionStart !== this.selectionEnd) {\n return this._moveRight(e, 'selectionStart');\n }\n else if (this.selectionEnd !== this._text.length) {\n this._selectionDirection = 'right';\n return this._moveRight(e, 'selectionEnd');\n }\n },\n\n /**\n * Moves cursor right without keeping selection\n * @param {Event} e Event object\n */\n moveCursorRightWithoutShift: function(e) {\n var changed = true;\n this._selectionDirection = 'right';\n\n if (this.selectionStart === this.selectionEnd) {\n changed = this._moveRight(e, 'selectionStart');\n this.selectionEnd = this.selectionStart;\n }\n else {\n this.selectionStart = this.selectionEnd;\n }\n return changed;\n },\n\n /**\n * Removes characters from start/end\n * start/end ar per grapheme position in _text array.\n *\n * @param {Number} start\n * @param {Number} end default to start + 1\n */\n removeChars: function(start, end) {\n if (typeof end === 'undefined') {\n end = start + 1;\n }\n this.removeStyleFromTo(start, end);\n this._text.splice(start, end - start);\n this.text = this._text.join('');\n this.set('dirty', true);\n if (this._shouldClearDimensionCache()) {\n this.initDimensions();\n this.setCoords();\n }\n this._removeExtraneousStyles();\n },\n\n /**\n * insert characters at start position, before start position.\n * start equal 1 it means the text get inserted between actual grapheme 0 and 1\n * if style array is provided, it must be as the same length of text in graphemes\n * if end is provided and is bigger than start, old text is replaced.\n * start/end ar per grapheme position in _text array.\n *\n * @param {String} text text to insert\n * @param {Array} style array of style objects\n * @param {Number} start\n * @param {Number} end default to start + 1\n */\n insertChars: function(text, style, start, end) {\n if (typeof end === 'undefined') {\n end = start;\n }\n if (end > start) {\n this.removeStyleFromTo(start, end);\n }\n var graphemes = fabric.util.string.graphemeSplit(text);\n this.insertNewStyleBlock(graphemes, start, style);\n this._text = [].concat(this._text.slice(0, start), graphemes, this._text.slice(end));\n this.text = this._text.join('');\n this.set('dirty', true);\n if (this._shouldClearDimensionCache()) {\n this.initDimensions();\n this.setCoords();\n }\n this._removeExtraneousStyles();\n },\n\n});\n\n\n/* _TO_SVG_START_ */\n(function() {\n var toFixed = fabric.util.toFixed,\n multipleSpacesRegex = / +/g;\n\n fabric.util.object.extend(fabric.Text.prototype, /** @lends fabric.Text.prototype */ {\n\n /**\n * Returns SVG representation of an instance\n * @param {Function} [reviver] Method for further parsing of svg representation.\n * @return {String} svg representation of an instance\n */\n _toSVG: function() {\n var offsets = this._getSVGLeftTopOffsets(),\n textAndBg = this._getSVGTextAndBg(offsets.textTop, offsets.textLeft);\n return this._wrapSVGTextAndBg(textAndBg);\n },\n\n /**\n * Returns svg representation of an instance\n * @param {Function} [reviver] Method for further parsing of svg representation.\n * @return {String} svg representation of an instance\n */\n toSVG: function(reviver) {\n return this._createBaseSVGMarkup(\n this._toSVG(),\n { reviver: reviver, noStyle: true, withShadow: true }\n );\n },\n\n /**\n * @private\n */\n _getSVGLeftTopOffsets: function() {\n return {\n textLeft: -this.width / 2,\n textTop: -this.height / 2,\n lineTop: this.getHeightOfLine(0)\n };\n },\n\n /**\n * @private\n */\n _wrapSVGTextAndBg: function(textAndBg) {\n var noShadow = true,\n textDecoration = this.getSvgTextDecoration(this);\n return [\n textAndBg.textBgRects.join(''),\n '\\t\\t<text xml:space=\"preserve\" ',\n (this.fontFamily ? 'font-family=\"' + this.fontFamily.replace(/\"/g, '\\'') + '\" ' : ''),\n (this.fontSize ? 'font-size=\"' + this.fontSize + '\" ' : ''),\n (this.fontStyle ? 'font-style=\"' + this.fontStyle + '\" ' : ''),\n (this.fontWeight ? 'font-weight=\"' + this.fontWeight + '\" ' : ''),\n (textDecoration ? 'text-decoration=\"' + textDecoration + '\" ' : ''),\n 'style=\"', this.getSvgStyles(noShadow), '\"', this.addPaintOrder(), ' >',\n textAndBg.textSpans.join(''),\n '</text>\\n'\n ];\n },\n\n /**\n * @private\n * @param {Number} textTopOffset Text top offset\n * @param {Number} textLeftOffset Text left offset\n * @return {Object}\n */\n _getSVGTextAndBg: function(textTopOffset, textLeftOffset) {\n var textSpans = [],\n textBgRects = [],\n height = textTopOffset, lineOffset;\n // bounding-box background\n this._setSVGBg(textBgRects);\n\n // text and text-background\n for (var i = 0, len = this._textLines.length; i < len; i++) {\n lineOffset = this._getLineLeftOffset(i);\n if (this.textBackgroundColor || this.styleHas('textBackgroundColor', i)) {\n this._setSVGTextLineBg(textBgRects, i, textLeftOffset + lineOffset, height);\n }\n this._setSVGTextLineText(textSpans, i, textLeftOffset + lineOffset, height);\n height += this.getHeightOfLine(i);\n }\n\n return {\n textSpans: textSpans,\n textBgRects: textBgRects\n };\n },\n\n /**\n * @private\n */\n _createTextCharSpan: function(_char, styleDecl, left, top) {\n var shouldUseWhitespace = _char !== _char.trim() || _char.match(multipleSpacesRegex),\n styleProps = this.getSvgSpanStyles(styleDecl, shouldUseWhitespace),\n fillStyles = styleProps ? 'style=\"' + styleProps + '\"' : '',\n dy = styleDecl.deltaY, dySpan = '',\n NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS;\n if (dy) {\n dySpan = ' dy=\"' + toFixed(dy, NUM_FRACTION_DIGITS) + '\" ';\n }\n return [\n '<tspan x=\"', toFixed(left, NUM_FRACTION_DIGITS), '\" y=\"',\n toFixed(top, NUM_FRACTION_DIGITS), '\" ', dySpan,\n fillStyles, '>',\n fabric.util.string.escapeXml(_char),\n '</tspan>'\n ].join('');\n },\n\n _setSVGTextLineText: function(textSpans, lineIndex, textLeftOffset, textTopOffset) {\n // set proper line offset\n var lineHeight = this.getHeightOfLine(lineIndex),\n isJustify = this.textAlign.indexOf('justify') !== -1,\n actualStyle,\n nextStyle,\n charsToRender = '',\n charBox, style,\n boxWidth = 0,\n line = this._textLines[lineIndex],\n timeToRender;\n\n textTopOffset += lineHeight * (1 - this._fontSizeFraction) / this.lineHeight;\n for (var i = 0, len = line.length - 1; i <= len; i++) {\n timeToRender = i === len || this.charSpacing;\n charsToRender += line[i];\n charBox = this.__charBounds[lineIndex][i];\n if (boxWidth === 0) {\n textLeftOffset += charBox.kernedWidth - charBox.width;\n boxWidth += charBox.width;\n }\n else {\n boxWidth += charBox.kernedWidth;\n }\n if (isJustify && !timeToRender) {\n if (this._reSpaceAndTab.test(line[i])) {\n timeToRender = true;\n }\n }\n if (!timeToRender) {\n // if we have charSpacing, we render char by char\n actualStyle = actualStyle || this.getCompleteStyleDeclaration(lineIndex, i);\n nextStyle = this.getCompleteStyleDeclaration(lineIndex, i + 1);\n timeToRender = this._hasStyleChangedForSvg(actualStyle, nextStyle);\n }\n if (timeToRender) {\n style = this._getStyleDeclaration(lineIndex, i) || { };\n textSpans.push(this._createTextCharSpan(charsToRender, style, textLeftOffset, textTopOffset));\n charsToRender = '';\n actualStyle = nextStyle;\n textLeftOffset += boxWidth;\n boxWidth = 0;\n }\n }\n },\n\n _pushTextBgRect: function(textBgRects, color, left, top, width, height) {\n var NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS;\n textBgRects.push(\n '\\t\\t<rect ',\n this._getFillAttributes(color),\n ' x=\"',\n toFixed(left, NUM_FRACTION_DIGITS),\n '\" y=\"',\n toFixed(top, NUM_FRACTION_DIGITS),\n '\" width=\"',\n toFixed(width, NUM_FRACTION_DIGITS),\n '\" height=\"',\n toFixed(height, NUM_FRACTION_DIGITS),\n '\"></rect>\\n');\n },\n\n _setSVGTextLineBg: function(textBgRects, i, leftOffset, textTopOffset) {\n var line = this._textLines[i],\n heightOfLine = this.getHeightOfLine(i) / this.lineHeight,\n boxWidth = 0,\n boxStart = 0,\n charBox, currentColor,\n lastColor = this.getValueOfPropertyAt(i, 0, 'textBackgroundColor');\n for (var j = 0, jlen = line.length; j < jlen; j++) {\n charBox = this.__charBounds[i][j];\n currentColor = this.getValueOfPropertyAt(i, j, 'textBackgroundColor');\n if (currentColor !== lastColor) {\n lastColor && this._pushTextBgRect(textBgRects, lastColor, leftOffset + boxStart,\n textTopOffset, boxWidth, heightOfLine);\n boxStart = charBox.left;\n boxWidth = charBox.width;\n lastColor = currentColor;\n }\n else {\n boxWidth += charBox.kernedWidth;\n }\n }\n currentColor && this._pushTextBgRect(textBgRects, currentColor, leftOffset + boxStart,\n textTopOffset, boxWidth, heightOfLine);\n },\n\n /**\n * Adobe Illustrator (at least CS5) is unable to render rgba()-based fill values\n * we work around it by \"moving\" alpha channel into opacity attribute and setting fill's alpha to 1\n *\n * @private\n * @param {*} value\n * @return {String}\n */\n _getFillAttributes: function(value) {\n var fillColor = (value && typeof value === 'string') ? new fabric.Color(value) : '';\n if (!fillColor || !fillColor.getSource() || fillColor.getAlpha() === 1) {\n return 'fill=\"' + value + '\"';\n }\n return 'opacity=\"' + fillColor.getAlpha() + '\" fill=\"' + fillColor.setAlpha(1).toRgb() + '\"';\n },\n\n /**\n * @private\n */\n _getSVGLineTopOffset: function(lineIndex) {\n var lineTopOffset = 0, lastHeight = 0;\n for (var j = 0; j < lineIndex; j++) {\n lineTopOffset += this.getHeightOfLine(j);\n }\n lastHeight = this.getHeightOfLine(j);\n return {\n lineTop: lineTopOffset,\n offset: (this._fontSizeMult - this._fontSizeFraction) * lastHeight / (this.lineHeight * this._fontSizeMult)\n };\n },\n\n /**\n * Returns styles-string for svg-export\n * @param {Boolean} skipShadow a boolean to skip shadow filter output\n * @return {String}\n */\n getSvgStyles: function(skipShadow) {\n var svgStyle = fabric.Object.prototype.getSvgStyles.call(this, skipShadow);\n return svgStyle + ' white-space: pre;';\n },\n });\n})();\n/* _TO_SVG_END_ */\n\n\n(function(global) {\n\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = {});\n\n /**\n * Textbox class, based on IText, allows the user to resize the text rectangle\n * and wraps lines automatically. Textboxes have their Y scaling locked, the\n * user can only change width. Height is adjusted automatically based on the\n * wrapping of lines.\n * @class fabric.Textbox\n * @extends fabric.IText\n * @mixes fabric.Observable\n * @return {fabric.Textbox} thisArg\n * @see {@link fabric.Textbox#initialize} for constructor definition\n */\n fabric.Textbox = fabric.util.createClass(fabric.IText, fabric.Observable, {\n\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'textbox',\n\n /**\n * Minimum width of textbox, in pixels.\n * @type Number\n * @default\n */\n minWidth: 20,\n\n /**\n * Minimum calculated width of a textbox, in pixels.\n * fixed to 2 so that an empty textbox cannot go to 0\n * and is still selectable without text.\n * @type Number\n * @default\n */\n dynamicMinWidth: 2,\n\n /**\n * Cached array of text wrapping.\n * @type Array\n */\n __cachedLines: null,\n\n /**\n * Override standard Object class values\n */\n lockScalingFlip: true,\n\n /**\n * Override standard Object class values\n * Textbox needs this on false\n */\n noScaleCache: false,\n\n /**\n * Properties which when set cause object to change dimensions\n * @type Object\n * @private\n */\n _dimensionAffectingProps: fabric.Text.prototype._dimensionAffectingProps.concat('width'),\n\n /**\n * Use this regular expression to split strings in breakable lines\n * @private\n */\n _wordJoiners: /[ \\t\\r]/,\n\n /**\n * Use this boolean property in order to split strings that have no white space concept.\n * this is a cheap way to help with chinese/japaense\n * @type Boolean\n * @since 2.6.0\n */\n splitByGrapheme: false,\n\n /**\n * Unlike superclass's version of this function, Textbox does not update\n * its width.\n * @private\n * @override\n */\n initDimensions: function() {\n if (this.__skipDimension) {\n return;\n }\n this.isEditing && this.initDelayedCursor();\n this.clearContextTop();\n this._clearCache();\n // clear dynamicMinWidth as it will be different after we re-wrap line\n this.dynamicMinWidth = 0;\n // wrap lines\n this._styleMap = this._generateStyleMap(this._splitText());\n // if after wrapping, the width is smaller than dynamicMinWidth, change the width and re-wrap\n if (this.dynamicMinWidth > this.width) {\n this._set('width', this.dynamicMinWidth);\n }\n if (this.textAlign.indexOf('justify') !== -1) {\n // once text is measured we need to make space fatter to make justified text.\n this.enlargeSpaces();\n }\n // clear cache and re-calculate height\n this.height = this.calcTextHeight();\n this.saveState({ propertySet: '_dimensionAffectingProps' });\n },\n\n /**\n * Generate an object that translates the style object so that it is\n * broken up by visual lines (new lines and automatic wrapping).\n * The original text styles object is broken up by actual lines (new lines only),\n * which is only sufficient for Text / IText\n * @private\n */\n _generateStyleMap: function(textInfo) {\n var realLineCount = 0,\n realLineCharCount = 0,\n charCount = 0,\n map = {};\n\n for (var i = 0; i < textInfo.graphemeLines.length; i++) {\n if (textInfo.graphemeText[charCount] === '\\n' && i > 0) {\n realLineCharCount = 0;\n charCount++;\n realLineCount++;\n }\n else if (!this.splitByGrapheme && this._reSpaceAndTab.test(textInfo.graphemeText[charCount]) && i > 0) {\n // this case deals with space's that are removed from end of lines when wrapping\n realLineCharCount++;\n charCount++;\n }\n\n map[i] = { line: realLineCount, offset: realLineCharCount };\n\n charCount += textInfo.graphemeLines[i].length;\n realLineCharCount += textInfo.graphemeLines[i].length;\n }\n\n return map;\n },\n\n /**\n * Returns true if object has a style property or has it on a specified line\n * @param {Number} lineIndex\n * @return {Boolean}\n */\n styleHas: function(property, lineIndex) {\n if (this._styleMap && !this.isWrapping) {\n var map = this._styleMap[lineIndex];\n if (map) {\n lineIndex = map.line;\n }\n }\n return fabric.Text.prototype.styleHas.call(this, property, lineIndex);\n },\n\n /**\n * Returns true if object has no styling or no styling in a line\n * @param {Number} lineIndex , lineIndex is on wrapped lines.\n * @return {Boolean}\n */\n isEmptyStyles: function(lineIndex) {\n if (!this.styles) {\n return true;\n }\n var offset = 0, nextLineIndex = lineIndex + 1, nextOffset, obj, shouldLimit = false,\n map = this._styleMap[lineIndex], mapNextLine = this._styleMap[lineIndex + 1];\n if (map) {\n lineIndex = map.line;\n offset = map.offset;\n }\n if (mapNextLine) {\n nextLineIndex = mapNextLine.line;\n shouldLimit = nextLineIndex === lineIndex;\n nextOffset = mapNextLine.offset;\n }\n obj = typeof lineIndex === 'undefined' ? this.styles : { line: this.styles[lineIndex] };\n for (var p1 in obj) {\n for (var p2 in obj[p1]) {\n if (p2 >= offset && (!shouldLimit || p2 < nextOffset)) {\n // eslint-disable-next-line no-unused-vars\n for (var p3 in obj[p1][p2]) {\n return false;\n }\n }\n }\n }\n return true;\n },\n\n /**\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @private\n */\n _getStyleDeclaration: function(lineIndex, charIndex) {\n if (this._styleMap && !this.isWrapping) {\n var map = this._styleMap[lineIndex];\n if (!map) {\n return null;\n }\n lineIndex = map.line;\n charIndex = map.offset + charIndex;\n }\n return this.callSuper('_getStyleDeclaration', lineIndex, charIndex);\n },\n\n /**\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @param {Object} style\n * @private\n */\n _setStyleDeclaration: function(lineIndex, charIndex, style) {\n var map = this._styleMap[lineIndex];\n lineIndex = map.line;\n charIndex = map.offset + charIndex;\n\n this.styles[lineIndex][charIndex] = style;\n },\n\n /**\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @private\n */\n _deleteStyleDeclaration: function(lineIndex, charIndex) {\n var map = this._styleMap[lineIndex];\n lineIndex = map.line;\n charIndex = map.offset + charIndex;\n delete this.styles[lineIndex][charIndex];\n },\n\n /**\n * probably broken need a fix\n * Returns the real style line that correspond to the wrapped lineIndex line\n * Used just to verify if the line does exist or not.\n * @param {Number} lineIndex\n * @returns {Boolean} if the line exists or not\n * @private\n */\n _getLineStyle: function(lineIndex) {\n var map = this._styleMap[lineIndex];\n return !!this.styles[map.line];\n },\n\n /**\n * Set the line style to an empty object so that is initialized\n * @param {Number} lineIndex\n * @param {Object} style\n * @private\n */\n _setLineStyle: function(lineIndex) {\n var map = this._styleMap[lineIndex];\n this.styles[map.line] = {};\n },\n\n /**\n * Wraps text using the 'width' property of Textbox. First this function\n * splits text on newlines, so we preserve newlines entered by the user.\n * Then it wraps each line using the width of the Textbox by calling\n * _wrapLine().\n * @param {Array} lines The string array of text that is split into lines\n * @param {Number} desiredWidth width you want to wrap to\n * @returns {Array} Array of lines\n */\n _wrapText: function(lines, desiredWidth) {\n var wrapped = [], i;\n this.isWrapping = true;\n for (i = 0; i < lines.length; i++) {\n wrapped = wrapped.concat(this._wrapLine(lines[i], i, desiredWidth));\n }\n this.isWrapping = false;\n return wrapped;\n },\n\n /**\n * Helper function to measure a string of text, given its lineIndex and charIndex offset\n * it gets called when charBounds are not available yet.\n * @param {CanvasRenderingContext2D} ctx\n * @param {String} text\n * @param {number} lineIndex\n * @param {number} charOffset\n * @returns {number}\n * @private\n */\n _measureWord: function(word, lineIndex, charOffset) {\n var width = 0, prevGrapheme, skipLeft = true;\n charOffset = charOffset || 0;\n for (var i = 0, len = word.length; i < len; i++) {\n var box = this._getGraphemeBox(word[i], lineIndex, i + charOffset, prevGrapheme, skipLeft);\n width += box.kernedWidth;\n prevGrapheme = word[i];\n }\n return width;\n },\n\n /**\n * Wraps a line of text using the width of the Textbox and a context.\n * @param {Array} line The grapheme array that represent the line\n * @param {Number} lineIndex\n * @param {Number} desiredWidth width you want to wrap the line to\n * @param {Number} reservedSpace space to remove from wrapping for custom functionalities\n * @returns {Array} Array of line(s) into which the given text is wrapped\n * to.\n */\n _wrapLine: function(_line, lineIndex, desiredWidth, reservedSpace) {\n var lineWidth = 0,\n splitByGrapheme = this.splitByGrapheme,\n graphemeLines = [],\n line = [],\n // spaces in different languges?\n words = splitByGrapheme ? fabric.util.string.graphemeSplit(_line) : _line.split(this._wordJoiners),\n word = '',\n offset = 0,\n infix = splitByGrapheme ? '' : ' ',\n wordWidth = 0,\n infixWidth = 0,\n largestWordWidth = 0,\n lineJustStarted = true,\n additionalSpace = this._getWidthOfCharSpacing(),\n reservedSpace = reservedSpace || 0;\n // fix a difference between split and graphemeSplit\n if (words.length === 0) {\n words.push([]);\n }\n desiredWidth -= reservedSpace;\n for (var i = 0; i < words.length; i++) {\n // if using splitByGrapheme words are already in graphemes.\n word = splitByGrapheme ? words[i] : fabric.util.string.graphemeSplit(words[i]);\n wordWidth = this._measureWord(word, lineIndex, offset);\n offset += word.length;\n\n lineWidth += infixWidth + wordWidth - additionalSpace;\n if (lineWidth >= desiredWidth && !lineJustStarted) {\n graphemeLines.push(line);\n line = [];\n lineWidth = wordWidth;\n lineJustStarted = true;\n }\n else {\n lineWidth += additionalSpace;\n }\n\n if (!lineJustStarted && !splitByGrapheme) {\n line.push(infix);\n }\n line = line.concat(word);\n\n infixWidth = splitByGrapheme ? 0 : this._measureWord([infix], lineIndex, offset);\n offset++;\n lineJustStarted = false;\n // keep track of largest word\n if (wordWidth > largestWordWidth) {\n largestWordWidth = wordWidth;\n }\n }\n\n i && graphemeLines.push(line);\n\n if (largestWordWidth + reservedSpace > this.dynamicMinWidth) {\n this.dynamicMinWidth = largestWordWidth - additionalSpace + reservedSpace;\n }\n return graphemeLines;\n },\n\n /**\n * Detect if the text line is ended with an hard break\n * text and itext do not have wrapping, return false\n * @param {Number} lineIndex text to split\n * @return {Boolean}\n */\n isEndOfWrapping: function(lineIndex) {\n if (!this._styleMap[lineIndex + 1]) {\n // is last line, return true;\n return true;\n }\n if (this._styleMap[lineIndex + 1].line !== this._styleMap[lineIndex].line) {\n // this is last line before a line break, return true;\n return true;\n }\n return false;\n },\n\n /**\n * Detect if a line has a linebreak and so we need to account for it when moving\n * and counting style.\n * @return Number\n */\n missingNewlineOffset: function(lineIndex) {\n if (this.splitByGrapheme) {\n return this.isEndOfWrapping(lineIndex) ? 1 : 0;\n }\n return 1;\n },\n\n /**\n * Gets lines of text to render in the Textbox. This function calculates\n * text wrapping on the fly every time it is called.\n * @param {String} text text to split\n * @returns {Array} Array of lines in the Textbox.\n * @override\n */\n _splitTextIntoLines: function(text) {\n var newText = fabric.Text.prototype._splitTextIntoLines.call(this, text),\n graphemeLines = this._wrapText(newText.lines, this.width),\n lines = new Array(graphemeLines.length);\n for (var i = 0; i < graphemeLines.length; i++) {\n lines[i] = graphemeLines[i].join('');\n }\n newText.lines = lines;\n newText.graphemeLines = graphemeLines;\n return newText;\n },\n\n getMinWidth: function() {\n return Math.max(this.minWidth, this.dynamicMinWidth);\n },\n\n _removeExtraneousStyles: function() {\n var linesToKeep = {};\n for (var prop in this._styleMap) {\n if (this._textLines[prop]) {\n linesToKeep[this._styleMap[prop].line] = 1;\n }\n }\n for (var prop in this.styles) {\n if (!linesToKeep[prop]) {\n delete this.styles[prop];\n }\n }\n },\n\n /**\n * Returns object representation of an instance\n * @method toObject\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject: function(propertiesToInclude) {\n return this.callSuper('toObject', ['minWidth', 'splitByGrapheme'].concat(propertiesToInclude));\n }\n });\n\n /**\n * Returns fabric.Textbox instance from an object representation\n * @static\n * @memberOf fabric.Textbox\n * @param {Object} object Object to create an instance from\n * @param {Function} [callback] Callback to invoke when an fabric.Textbox instance is created\n */\n fabric.Textbox.fromObject = function(object, callback) {\n return fabric.Object._fromObject('Textbox', object, callback, 'text');\n };\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function() {\n\n var controlsUtils = fabric.controlsUtils,\n scaleSkewStyleHandler = controlsUtils.scaleSkewCursorStyleHandler,\n scaleStyleHandler = controlsUtils.scaleCursorStyleHandler,\n scalingEqually = controlsUtils.scalingEqually,\n scalingYOrSkewingX = controlsUtils.scalingYOrSkewingX,\n scalingXOrSkewingY = controlsUtils.scalingXOrSkewingY,\n scaleOrSkewActionName = controlsUtils.scaleOrSkewActionName,\n objectControls = fabric.Object.prototype.controls;\n\n objectControls.ml = new fabric.Control({\n x: -0.5,\n y: 0,\n cursorStyleHandler: scaleSkewStyleHandler,\n actionHandler: scalingXOrSkewingY,\n getActionName: scaleOrSkewActionName,\n });\n\n objectControls.mr = new fabric.Control({\n x: 0.5,\n y: 0,\n cursorStyleHandler: scaleSkewStyleHandler,\n actionHandler: scalingXOrSkewingY,\n getActionName: scaleOrSkewActionName,\n });\n\n objectControls.mb = new fabric.Control({\n x: 0,\n y: 0.5,\n cursorStyleHandler: scaleSkewStyleHandler,\n actionHandler: scalingYOrSkewingX,\n getActionName: scaleOrSkewActionName,\n });\n\n objectControls.mt = new fabric.Control({\n x: 0,\n y: -0.5,\n cursorStyleHandler: scaleSkewStyleHandler,\n actionHandler: scalingYOrSkewingX,\n getActionName: scaleOrSkewActionName,\n });\n\n objectControls.tl = new fabric.Control({\n x: -0.5,\n y: -0.5,\n cursorStyleHandler: scaleStyleHandler,\n actionHandler: scalingEqually\n });\n\n objectControls.tr = new fabric.Control({\n x: 0.5,\n y: -0.5,\n cursorStyleHandler: scaleStyleHandler,\n actionHandler: scalingEqually\n });\n\n objectControls.bl = new fabric.Control({\n x: -0.5,\n y: 0.5,\n cursorStyleHandler: scaleStyleHandler,\n actionHandler: scalingEqually\n });\n\n objectControls.br = new fabric.Control({\n x: 0.5,\n y: 0.5,\n cursorStyleHandler: scaleStyleHandler,\n actionHandler: scalingEqually\n });\n\n objectControls.mtr = new fabric.Control({\n x: 0,\n y: -0.5,\n actionHandler: controlsUtils.rotationWithSnapping,\n cursorStyleHandler: controlsUtils.rotationStyleHandler,\n offsetY: -40,\n withConnection: true,\n actionName: 'rotate',\n });\n\n if (fabric.Textbox) {\n // this is breaking the prototype inheritance, no time / ideas to fix it.\n // is important to document that if you want to have all objects to have a\n // specific custom control, you have to add it to Object prototype and to Textbox\n // prototype. The controls are shared as references. So changes to control `tr`\n // can still apply to all objects if needed.\n var textBoxControls = fabric.Textbox.prototype.controls = { };\n\n textBoxControls.mtr = objectControls.mtr;\n textBoxControls.tr = objectControls.tr;\n textBoxControls.br = objectControls.br;\n textBoxControls.tl = objectControls.tl;\n textBoxControls.bl = objectControls.bl;\n textBoxControls.mt = objectControls.mt;\n textBoxControls.mb = objectControls.mb;\n\n textBoxControls.mr = new fabric.Control({\n x: 0.5,\n y: 0,\n actionHandler: controlsUtils.changeWidth,\n cursorStyleHandler: scaleSkewStyleHandler,\n actionName: 'resizing',\n });\n\n textBoxControls.ml = new fabric.Control({\n x: -0.5,\n y: 0,\n actionHandler: controlsUtils.changeWidth,\n cursorStyleHandler: scaleSkewStyleHandler,\n actionName: 'resizing',\n });\n }\n})();\n\n"]},"metadata":{},"sourceType":"script"}