From 9d552db8366384da92c49de5e4fc7f621b0fda6e Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Sun, 19 Nov 2017 23:55:41 +0100 Subject: [PATCH] Update to 2.0 rc1 (#4472) * rc1 * removed beta from issue template --- CHANGELOG.md | 24 +- HEADER.js | 2 +- ISSUE_TEMPLATE.md | 2 +- dist/fabric.js | 1769 +++++++++++++++++++++++----------------- dist/fabric.min.js | 2 +- dist/fabric.min.js.gz | Bin 77542 -> 78630 bytes dist/fabric.require.js | 1209 +++++++++++++++------------ package.json | 2 +- 8 files changed, 1713 insertions(+), 1297 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 710e0dbf..44021974 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,27 @@ **Version 2.0.0** - + - rc1 + - Remove node specific code [#4470](https://github.com/kangax/fabric.js/pull/4470) + - Improved Canvas.dispose code to leak less memory [#4471](https://github.com/kangax/fabric.js/pull/4471) + - Remove extra padding of cache when upper limited [#4467](https://github.com/kangax/fabric.js/pull/4467) + - Solved 2 perfomances problems with textbox [#4466](https://github.com/kangax/fabric.js/pull/4466) [#4465](https://github.com/kangax/fabric.js/pull/4465) + - Added justify-left justify-right and justify-center [#4437](https://github.com/kangax/fabric.js/pull/4437) + - Fix Group fromObject and subTargetCheck [#4454](https://github.com/kangax/fabric.js/pull/4454) + - Fix regression on IMG from SVG [#4450](https://github.com/kangax/fabric.js/pull/4450) + - Remove cache dimensions together with canvas [#4453](https://github.com/kangax/fabric.js/pull/4453) + - Fixed some fuzzyness cases for cache [#4452](https://github.com/kangax/fabric.js/pull/4452) + - Fixed resize filter for webgl [#4426](https://github.com/kangax/fabric.js/pull/4426) + - Stop searching target during a mouse move with a transform [#4442](https://github.com/kangax/fabric.js/pull/4442) + - safeguard shaders for non supported precisions [#4433](https://github.com/kangax/fabric.js/pull/4433) + - fix insert and remove style for edge cases [#4420](https://github.com/kangax/fabric.js/pull/4420) + - Fix object.move when in active selection [#4394](https://github.com/kangax/fabric.js/pull/4394) + - Memoize calcTransformMatrix function [#4418](https://github.com/kangax/fabric.js/pull/4418) + - Make _set flag object as dirty just when a real change happen[#4415](https://github.com/kangax/fabric.js/pull/4415) + - Add browserShadowBlurConstant to adjust shadowBlur value [#4413](https://github.com/kangax/fabric.js/pull/4413) + - Fix set element not clearing the cacheTexture. [#4410](https://github.com/kangax/fabric.js/pull/4410) + - Multi selection key can be configured with an array of keys. [#4363](https://github.com/kangax/fabric.js/pull/4363) + - fix fast type in text loosing some style. [#4339](https://github.com/kangax/fabric.js/pull/4339) + - fixed division by zero with lockscaling flip. + - added paintFirst ( paint-order with svg support ) [#4303](https://github.com/kangax/fabric.js/pull/4303) - beta7 - added a build flag for not attaching fabric to window [#4199](https://github.com/kangax/fabric.js/pull/4199) - removed .active property from objects [#4200](https://github.com/kangax/fabric.js/pull/4200) diff --git a/HEADER.js b/HEADER.js index 190f52db..a69e069d 100644 --- a/HEADER.js +++ b/HEADER.js @@ -1,6 +1,6 @@ /*! Fabric.js Copyright 2008-2015, Printio (Juriy Zaytsev, Maxim Chernyak) */ -var fabric = fabric || { version: '2.0.0-beta7' }; +var fabric = fabric || { version: '2.0.0-rc.1' }; if (typeof exports !== 'undefined') { exports.fabric = fabric; } diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md index a085dc71..e2fd0127 100644 --- a/ISSUE_TEMPLATE.md +++ b/ISSUE_TEMPLATE.md @@ -25,7 +25,7 @@ Remove the template from below and provide thoughtful commentary *and code sampl ## Version -2.0 beta +2.0 ## Test Case http://jsfiddle.net/fabricjs/Da7SP/ diff --git a/dist/fabric.js b/dist/fabric.js index bc1d60e1..3c10a68b 100644 --- a/dist/fabric.js +++ b/dist/fabric.js @@ -1,7 +1,7 @@ /* build: `node build.js modules=ALL exclude=gestures,accessors minifier=uglifyjs` */ /*! Fabric.js Copyright 2008-2015, Printio (Juriy Zaytsev, Maxim Chernyak) */ -var fabric = fabric || { version: '2.0.0-beta7' }; +var fabric = fabric || { version: '2.0.0-rc.1' }; if (typeof exports !== 'undefined') { exports.fabric = fabric; } @@ -18,9 +18,9 @@ else { { features: { FetchExternalResources: ['img'] } - }); - + }); fabric.window = fabric.document.defaultView; + DOMParser = require('xmldom').DOMParser; } /** @@ -49,7 +49,7 @@ fabric.SHARED_ATTRIBUTES = [ "stroke", "stroke-dasharray", "stroke-linecap", "stroke-linejoin", "stroke-miterlimit", "stroke-opacity", "stroke-width", - "id", + "id", "paint-order", "instantiated_by_use" ]; /* _FROM_SVG_END_ */ @@ -119,6 +119,21 @@ fabric.devicePixelRatio = fabric.window.devicePixelRatio || fabric.window.webkitDevicePixelRatio || fabric.window.mozDevicePixelRatio || 1; +/** + * Browser-specific constant to adjust CanvasRenderingContext2D.shadowBlur value, + * which is unitless and not rendered equally across browsers. + * + * Values that work quite well (as of October 2017) are: + * - Chrome: 1.5 + * - Edge: 1.75 + * - Firefox: 0.9 + * - Safari: 0.95 + * + * @since 2.0.0 + * @type Number + * @default 1 + */ +fabric.browserShadowBlurConstant = 1; fabric.initFilterBackend = function() { if (fabric.enableGLFiltering && fabric.isWebglSupported && fabric.isWebglSupported(fabric.textureSize)) { @@ -673,11 +688,11 @@ fabric.CommonMethods = { var xPoints = [points[0].x, points[1].x, points[2].x, points[3].x], minX = fabric.util.array.min(xPoints), maxX = fabric.util.array.max(xPoints), - width = Math.abs(minX - maxX), + width = maxX - minX, yPoints = [points[0].y, points[1].y, points[2].y, points[3].y], minY = fabric.util.array.min(yPoints), maxY = fabric.util.array.max(yPoints), - height = Math.abs(minY - maxY); + height = maxY - minY; return { left: minX, @@ -841,11 +856,12 @@ fabric.CommonMethods = { var img = fabric.util.createImage(); /** @ignore */ - img.onload = function () { + var onLoadCallback = function () { callback && callback.call(context, img); img = img.onload = img.onerror = null; }; + img.onload = onLoadCallback; /** @ignore */ img.onerror = function() { fabric.log('Error loading ' + img.src); @@ -861,9 +877,43 @@ fabric.CommonMethods = { img.crossOrigin = crossOrigin; } + // IE10 / IE11-Fix: SVG contents from data: URI + // will only be available if the IMG is present + // in the DOM (and visible) + if (url.substring(0,14) === 'data:image/svg') { + img.onload = null; + fabric.util.loadImageInDom(img, onLoadCallback); + } + img.src = url; }, + /** + * Attaches SVG image with data: URL to the dom + * @memberOf fabric.util + * @param {Object} img Image object with data:image/svg src + * @param {Function} callback Callback; invoked with loaded image + * @return {Object} DOM element (div containing the SVG image) + */ + loadImageInDom: function(img, onLoadCallback) { + var div = fabric.document.createElement('div'); + div.style.width = div.style.height = '1px'; + div.style.left = div.style.top = '-100%'; + div.style.position = 'absolute'; + div.appendChild(img); + fabric.document.querySelector('body').appendChild(div); + /** + * Wrap in function to: + * 1. Call existing callback + * 2. Cleanup DOM + */ + img.onload = function () { + onLoadCallback(); + div.parentNode.removeChild(div); + div = null; + }; + }, + /** * Creates corresponding fabric instances from their object representations * @static @@ -3200,6 +3250,7 @@ if (typeof console !== 'undefined') { 'font-size': 'fontSize', 'font-style': 'fontStyle', 'font-weight': 'fontWeight', + 'paint-order': 'paintFirst', 'stroke-dasharray': 'strokeDashArray', 'stroke-linecap': 'strokeLineCap', 'stroke-linejoin': 'strokeLineJoin', @@ -3274,6 +3325,17 @@ if (typeof console !== 'undefined') { else if (attr === 'textAnchor' /* text-anchor */) { value = value === 'start' ? 'left' : value === 'end' ? 'right' : 'center'; } + else if (attr === 'paintFirst') { + var fillIndex = value.indexOf('fill'); + var strokeIndex = value.indexOf('stroke'); + var value = 'fill'; + if (fillIndex > -1 && strokeIndex > -1 && strokeIndex < fillIndex) { + value = 'stroke'; + } + else if (fillIndex === -1 && strokeIndex > -1) { + value = 'stroke'; + } + } else { parsed = isArray ? value.map(parseUnit) : parseUnit(value, fontSize); } @@ -4216,12 +4278,13 @@ fabric.ElementsParser.prototype._createObject = function(klass, el, index) { fabric.ElementsParser.prototype.createCallback = function(index, el) { var _this = this; return function(obj) { + var _options; _this.resolveGradient(obj, 'fill'); _this.resolveGradient(obj, 'stroke'); - obj._removeTransformMatrix(); if (obj instanceof fabric.Image) { - obj.parsePreserveAspectRatioAttribute(el); + _options = obj.parsePreserveAspectRatioAttribute(el); } + obj._removeTransformMatrix(_options); _this.reviver && _this.reviver(el, obj); _this.instances[index] = obj; _this.checkIfDone(); @@ -6591,9 +6654,9 @@ fabric.ElementsParser.prototype.checkIfDone = function() { }, /** - * Sets {@link fabric.StaticCanvas#overlayColor|background color} for this canvas - * @param {(String|fabric.Pattern)} overlayColor Color or pattern to set background color to - * @param {Function} callback Callback to invoke when background color is set + * Sets {@link fabric.StaticCanvas#overlayColor|foreground color} for this canvas + * @param {(String|fabric.Pattern)} overlayColor Color or pattern to set foreground color to + * @param {Function} callback Callback to invoke when foreground color is set * @return {fabric.Canvas} thisArg * @chainable * @see {@link http://jsfiddle.net/fabricjs/pB55h/|jsFiddle demo} @@ -7097,6 +7160,7 @@ fabric.ElementsParser.prototype.checkIfDone = function() { * @chainable */ renderCanvas: function(ctx, objects) { + var v = this.viewportTransform; if (this.isRendering) { fabric.util.cancelAnimFrame(this.isRendering); this.isRendering = 0; @@ -7111,7 +7175,7 @@ fabric.ElementsParser.prototype.checkIfDone = function() { ctx.save(); //apply viewport transform once for all rendering process - ctx.transform.apply(ctx, this.viewportTransform); + ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]); this._renderObjects(ctx, objects); ctx.restore(); if (!this.controlsAboveOverlay && this.interactive) { @@ -7145,7 +7209,7 @@ fabric.ElementsParser.prototype.checkIfDone = function() { * @param {string} property 'background' or 'overlay' */ _renderBackgroundOrOverlay: function(ctx, property) { - var object = this[property + 'Color']; + var object = this[property + 'Color'], v; if (object) { ctx.fillStyle = object.toLive ? object.toLive(ctx, this) @@ -7160,8 +7224,9 @@ fabric.ElementsParser.prototype.checkIfDone = function() { object = this[property + 'Image']; if (object) { if (this[property + 'Vpt']) { + v = this.viewportTransform; ctx.save(); - ctx.transform.apply(ctx, this.viewportTransform); + ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]); } object.render(ctx); this[property + 'Vpt'] && ctx.restore(); @@ -7880,7 +7945,12 @@ fabric.ElementsParser.prototype.checkIfDone = function() { * @chainable */ dispose: function () { - this.clear(); + this._objects.length = 0; + this.backgroundImage = null; + this.overlayImage = null; + this._iTextInstances = null; + this.lowerCanvasEl = null; + this.cacheCanvasEl = null; return this; }, @@ -8011,12 +8081,19 @@ fabric.BaseBrush = fabric.util.createClass(/** @lends fabric.BaseBrush.prototype strokeLineCap: 'round', /** - * Corner style of a brush (one of "bevil", "round", "miter") + * Corner style of a brush (one of "bevel", "round", "miter") * @type String * @default */ strokeLineJoin: 'round', + /** + * Maximum miter length (used for strokeLineJoin = "miter") of a brush's + * @type Number + * @default + */ + strokeMiterLimit: 10, + /** * Stroke Dash Array. * @type Array @@ -8041,10 +8118,10 @@ fabric.BaseBrush = fabric.util.createClass(/** @lends fabric.BaseBrush.prototype */ _setBrushStyles: function() { var ctx = this.canvas.contextTop; - ctx.strokeStyle = this.color; ctx.lineWidth = this.width; ctx.lineCap = this.strokeLineCap; + ctx.miterLimit = this.strokeMiterLimit; ctx.lineJoin = this.strokeLineJoin; if (this.strokeDashArray && fabric.StaticCanvas.supports('setLineDash')) { ctx.setLineDash(this.strokeDashArray); @@ -8151,6 +8228,9 @@ fabric.BaseBrush = fabric.util.createClass(/** @lends fabric.BaseBrush.prototype * @param {fabric.Point} point Point to be added to points array */ _addPoint: function(point) { + if (this._points.length > 1 && point.eq(this._points[this._points.length - 1])) { + return; + } this._points.push(point); }, @@ -8187,7 +8267,6 @@ fabric.BaseBrush = fabric.util.createClass(/** @lends fabric.BaseBrush.prototype ctx.save(); ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]); ctx.beginPath(); - //if we only have 2 points in the path and they are the same //it means that the user only clicked the canvas without moving the mouse //then we should be drawing a dot. A path isn't drawn between two identical dots @@ -8227,9 +8306,13 @@ fabric.BaseBrush = fabric.util.createClass(/** @lends fabric.BaseBrush.prototype var path = [], i, width = this.width / 1000, p1 = new fabric.Point(points[0].x, points[0].y), p2 = new fabric.Point(points[1].x, points[1].y), - len = points.length; + len = points.length, multSignX, multSignY, manyPoints = len > 2; - path.push('M ', p1.x - width, ' ', p1.y, ' '); + if (manyPoints) { + multSignX = points[2].x < p2.x ? -1 : points[2].x === p2.x ? 0 : 1; + multSignY = points[2].y < p2.y ? -1 : points[2].y === p2.y ? 0 : 1; + } + path.push('M ', p1.x - multSignX * width, ' ', p1.y - multSignY * width, ' '); for (i = 1; i < len; i++) { if (!p1.eq(p2)) { var midPoint = p1.midPointFrom(p2); @@ -8243,7 +8326,11 @@ fabric.BaseBrush = fabric.util.createClass(/** @lends fabric.BaseBrush.prototype p2 = points[i + 1]; } } - path.push('L ', p1.x + width, ' ', p1.y, ' '); + if (manyPoints) { + multSignX = p1.x > points[i - 2].x ? 1 : p1.x === points[i - 2].x ? 0 : -1; + multSignY = p1.y > points[i - 2].y ? 1 : p1.y === points[i - 2].y ? 0 : -1; + } + path.push('L ', p1.x + multSignX * width, ' ', p1.y + multSignY * width); return path; }, @@ -8258,6 +8345,7 @@ fabric.BaseBrush = fabric.util.createClass(/** @lends fabric.BaseBrush.prototype stroke: this.color, strokeWidth: this.width, strokeLineCap: this.strokeLineCap, + strokeMiterLimit: this.strokeMiterLimit, strokeLineJoin: this.strokeLineJoin, strokeDashArray: this.strokeDashArray, }); @@ -8293,13 +8381,12 @@ fabric.BaseBrush = fabric.util.createClass(/** @lends fabric.BaseBrush.prototype } var path = this.createPath(pathData); - - this.canvas.add(path); - path.setCoords(); - this.canvas.clearContext(this.canvas.contextTop); + this.canvas.add(path); + this.canvas.renderAll(); + path.setCoords(); this._resetShadow(); - this.canvas.requestRenderAll(); + // fire event 'path' created this.canvas.fire('path:created', { path: path }); @@ -8716,11 +8803,12 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab * @see {@link fabric.Canvas#initialize} for constructor definition * * @fires object:added + * @fires object:removed * @fires object:modified * @fires object:rotating * @fires object:scaling * @fires object:moving - * @fires object:selected + * @fires object:selected this event is deprecated. use selection:created * * @fires before:selection:cleared * @fires selection:cleared @@ -8825,12 +8913,13 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab selection: true, /** - * Indicates which key enable multiple click selection + * Indicates which key or keys enable multiple click selection + * Pass value as a string or array of strings * values: 'altKey', 'shiftKey', 'ctrlKey'. - * If `null` or 'none' or any other string that is not a modifier key - * feature is disabled feature disabled. + * If `null` or empty or containing any other string that is not a modifier key + * feature is disabled. * @since 1.6.2 - * @type String + * @type String|Array * @default */ selectionKey: 'shiftKey', @@ -9179,19 +9268,22 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab */ isTargetTransparent: function (target, x, y) { var ctx = this.contextCache, - originalColor = target.selectionBackgroundColor; + originalColor = target.selectionBackgroundColor, v = this.viewportTransform; - target.hasBorders = target.transparentCorners = false; target.selectionBackgroundColor = ''; + this.clearContext(ctx); + ctx.save(); - ctx.transform.apply(ctx, this.viewportTransform); + ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]); target.render(ctx); ctx.restore(); target === this._activeObject && target._renderControls(ctx, { hasBorders: false, transparentCorners: false + }, { + hasBorders: false, }); target.selectionBackgroundColor = originalColor; @@ -9199,11 +9291,27 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab var isTransparent = fabric.util.isTransparent( ctx, x, y, this.targetFindTolerance); - this.clearContext(ctx); - return isTransparent; }, + /** + * takes an event and determins if selection key has been pressed + * @private + * @param {Event} e Event object + */ + _isSelectionKeyPressed: function(e) { + var selectionKeyPressed = false; + + if (Object.prototype.toString.call(this.selectionKey) === '[object Array]') { + selectionKeyPressed = !!this.selectionKey.find(function(key) { return e[key] === true; }); + } + else { + selectionKeyPressed = e[this.selectionKey]; + } + + return selectionKeyPressed; + }, + /** * @private * @param {Event} e Event object @@ -9212,6 +9320,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab _shouldClearSelection: function (e, target) { var activeObjects = this.getActiveObjects(), activeObject = this._activeObject; + return ( !target || @@ -9220,7 +9329,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab activeObjects.length > 1 && activeObjects.indexOf(target) === -1 && activeObject !== target && - !e[this.selectionKey]) + !this._isSelectionKeyPressed(e)) || (target && !target.evented) || @@ -9578,8 +9687,8 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab var dist = localMouse.y + localMouse.x, lastDist = _dim.y * transform.original.scaleY / target.scaleY + _dim.x * transform.original.scaleX / target.scaleX, - scaled, signX = localMouse.x / Math.abs(localMouse.x), - signY = localMouse.y / Math.abs(localMouse.y); + scaled, signX = localMouse.x < 0 ? -1 : 1, + signY = localMouse.y < 0 ? -1 : 1; // We use transform.scaleX/Y instead of target.scaleX/Y // because the object may have a min scale and we'll loose the proportions @@ -9685,7 +9794,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab var lastAngle = atan2(t.ey - t.top, t.ex - t.left), curAngle = atan2(y - t.top, x - t.left), angle = radiansToDegrees(curAngle - lastAngle + t.theta), - hasRoated = true; + hasRotated = true; if (t.target.snapAngle > 0) { var snapAngle = t.target.snapAngle, @@ -9708,13 +9817,13 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab angle %= 360; if (t.target.angle === angle) { - hasRoated = false; + hasRotated = false; } else { t.target.angle = angle; } - return hasRoated; + return hasRotated; }, /** @@ -10094,6 +10203,53 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab this.callSuper('_onObjectRemoved', obj); }, + /** + * @private + * Compares the old activeObject with the current one and fires correct events + * @param {fabric.Object} obj old activeObject + */ + _fireSelectionEvents: function(oldObjects, e) { + var somethingChanged = false, objects = this.getActiveObjects(), + added = [], removed = [], opt = { e: e }; + oldObjects.forEach(function(oldObject) { + if (objects.indexOf(oldObject) === -1) { + somethingChanged = true; + oldObject.fire('deselected', opt); + removed.push(oldObject); + } + }); + objects.forEach(function(object) { + if (oldObjects.indexOf(object) === -1) { + somethingChanged = true; + object.fire('selected', opt); + added.push(object); + } + }); + if (oldObjects.length > 0 && objects.length > 0) { + opt.selected = added; + opt.deselected = removed; + // added for backward compatibility + opt.updated = added[0] || removed[0]; + opt.target = this._activeObject; + somethingChanged && this.fire('selection:updated', opt); + } + else if (objects.length > 0) { + // deprecated event + if (objects.length === 1) { + opt.target = added[0]; + this.fire('object:selected', opt); + } + opt.selected = added; + // added for backward compatibility + opt.target = this._activeObject; + this.fire('selection:created', opt); + } + else if (oldObjects.length > 0) { + opt.deselected = removed; + this.fire('selection:cleared', opt); + } + }, + /** * Sets given object as the only active object on canvas * @param {fabric.Object} object Object to set as an active one @@ -10102,15 +10258,9 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab * @chainable */ setActiveObject: function (object, e) { - var currentActiveObject = this._activeObject; - if (object === currentActiveObject) { - return this; - } - if (this._setActiveObject(object, e)) { - currentActiveObject && currentActiveObject.fire('deselected', { e: e }); - this.fire('object:selected', { target: object, e: e }); - object.fire('selected', { e: e }); - } + var currentActives = this.getActiveObjects(); + this._setActiveObject(object, e); + this._fireSelectionEvents(currentActives, e); return this; }, @@ -10159,14 +10309,12 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab * @chainable */ discardActiveObject: function (e) { - var activeObject = this._activeObject; - if (activeObject) { - this.fire('before:selection:cleared', { target: activeObject, e: e }); - if (this._discardActiveObject(e)) { - this.fire('selection:cleared', { e: e, target: activeObject }); - activeObject.fire('deselected', { e: e }); - } + var currentActives = this.getActiveObjects(); + if (currentActives.length) { + this.fire('before:selection:cleared', { target: currentActives[0], e: e }); } + this._discardActiveObject(e); + this._fireSelectionEvents(currentActives, e); return this; }, @@ -10176,7 +10324,6 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab * @chainable */ dispose: function () { - fabric.StaticCanvas.prototype.dispose.call(this); var wrapper = this.wrapperEl; this.removeListeners(); wrapper.removeChild(this.upperCanvasEl); @@ -10186,6 +10333,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab wrapper.parentNode.replaceChild(this.lowerCanvasEl, this.wrapperEl); } delete this.wrapperEl; + fabric.StaticCanvas.prototype.dispose.call(this); return this; }, @@ -10949,7 +11097,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab else { this._transformObject(e); } - this._handleEvent(e, 'move', target ? target : null); + this._handleEvent(e, 'move', this._currentTransform ? null : target); }, /** @@ -11202,7 +11350,8 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab */ _shouldGroup: function(e, target) { var activeObject = this._activeObject; - return activeObject && e[this.selectionKey] && target && target.selectable && this.selection && + + return activeObject && this._isSelectionKeyPressed(e) && target && target.selectable && this.selection && (activeObject !== target || activeObject.type === 'activeSelection'); }, @@ -11236,33 +11385,31 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab * @private */ _updateActiveSelection: function(target, e) { - var activeSelection = this._activeObject; + var activeSelection = this._activeObject, + currentActiveObjects = activeSelection._objects.slice(0); if (activeSelection.contains(target)) { activeSelection.removeWithUpdate(target); - target.fire('deselected', { e: e }); this._hoveredTarget = target; if (activeSelection.size() === 1) { // activate last remaining object - this.setActiveObject(activeSelection.item(0), e); - return; + this._setActiveObject(activeSelection.item(0), e); } } else { activeSelection.addWithUpdate(target); - target.fire('selected', { e: e }); this._hoveredTarget = activeSelection; } - this.fire('selection:updated', { target: activeSelection, e: e, updated: target }); + this._fireSelectionEvents(currentActiveObjects, e); }, /** * @private */ _createActiveSelection: function(target, e) { - var group = this._createGroup(target); - this.setActiveObject(group, e); - target.fire('selected', { e: e }); - this.fire('selection:created', { target: group, e: e }); + var currentActives = this.getActiveObjects(), group = this._createGroup(target); + this._hoveredTarget = group; + this._setActiveObject(group, e); + this._fireSelectionEvents(currentActives, e); }, /** @@ -11298,11 +11445,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab aGroup = new fabric.ActiveSelection(group.reverse(), { canvas: this }); - group.forEach(function(object) { - object.fire('selected', { e: e }); - }); this.setActiveObject(aGroup, e); - this.fire('selection:created', { target: aGroup, e: e }); } }, @@ -12259,6 +12402,13 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati */ __corner: 0, + /** + * Determins if the fill or the stroke is drawn first (one of "fill" or "stroke") + * @type String + * @default + */ + paintFirst: 'fill', + /** * List of properties to consider when checking if state * of an object is changed (fabric.Object#hasStateChanged) @@ -12269,7 +12419,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati 'top left width height scaleX scaleY flipX flipY originX originY transformMatrix ' + 'stroke strokeWidth strokeDashArray strokeLineCap strokeLineJoin strokeMiterLimit ' + 'angle opacity fill globalCompositeOperation shadow clipTo visible backgroundColor ' + - 'skewX skewY fillRule' + 'skewX skewY fillRule paintFirst' ).split(' '), /** @@ -12277,7 +12427,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati * @type Array */ cacheProperties: ( - 'fill stroke strokeWidth strokeDashArray width height' + + 'fill stroke strokeWidth strokeDashArray width height paintFirst' + ' strokeLineCap strokeLineJoin strokeMiterLimit backgroundColor' ).split(' '), @@ -12319,25 +12469,30 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati */ _limitCacheSize: function(dims) { var perfLimitSizeTotal = fabric.perfLimitSizeTotal, - maximumSide = fabric.cacheSideLimit, width = dims.width, height = dims.height, - ar = width / height, limitedDims = fabric.util.limitDimsByArea(ar, perfLimitSizeTotal, maximumSide), - capValue = fabric.util.capValue, max = fabric.maxCacheSideLimit, min = fabric.minCacheSideLimit, + max = fabric.maxCacheSideLimit, min = fabric.minCacheSideLimit; + if (width <= max && height <= max && width * height <= perfLimitSizeTotal) { + if (width < min) { + dims.width = min; + } + if (height < min) { + dims.height = min; + } + return dims; + } + var ar = width / height, limitedDims = fabric.util.limitDimsByArea(ar, perfLimitSizeTotal), + capValue = fabric.util.capValue, x = capValue(min, limitedDims.x, max), y = capValue(min, limitedDims.y, max); if (width > x) { dims.zoomX /= width / x; dims.width = x; - } - else if (width < min) { - dims.width = min; + dims.capped = true; } if (height > y) { dims.zoomY /= height / y; dims.height = y; - } - else if (height < min) { - dims.height = min; + dims.capped = true; } return dims; }, @@ -12346,6 +12501,8 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati * Return the dimension and the zoom level needed to create a cache canvas * big enough to host the object to be cached. * @private + * @param {Object} dim.x width of object to be cached + * @param {Object} dim.y height of object to be cached * @return {Object}.width width of canvas * @return {Object}.height height of canvas * @return {Object}.zoomX zoomX zoom value to unscale the canvas before drawing cache @@ -12354,17 +12511,21 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati _getCacheCanvasDimensions: function() { var zoom = this.canvas && this.canvas.getZoom() || 1, objectScale = this.getObjectScaling(), - dim = this._getNonTransformedDimensions(), retina = this.canvas && this.canvas._isRetinaScaling() ? fabric.devicePixelRatio : 1, + dim = this._getNonTransformedDimensions(), zoomX = objectScale.scaleX * zoom * retina, zoomY = objectScale.scaleY * zoom * retina, width = dim.x * zoomX, height = dim.y * zoomY; return { + // for sure this ALIASING_LIMIT is slightly crating problem + // in situation in wich the cache canvas gets an upper limit width: width + ALIASING_LIMIT, height: height + ALIASING_LIMIT, zoomX: zoomX, - zoomY: zoomY + zoomY: zoomY, + x: dim.x, + y: dim.y }; }, @@ -12376,14 +12537,16 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati */ _updateCacheCanvas: function() { if (this.noScaleCache && this.canvas && this.canvas._currentTransform) { - var action = this.canvas._currentTransform.action; - if (action.slice && action.slice(0, 5) === 'scale') { + var target = this.canvas._currentTransform.target, + action = this.canvas._currentTransform.action; + if (this === target && action.slice && action.slice(0, 5) === 'scale') { return false; } } - var dims = this._limitCacheSize(this._getCacheCanvasDimensions()), + var canvas = this._cacheCanvas, + dims = this._limitCacheSize(this._getCacheCanvasDimensions()), minCacheSize = fabric.minCacheSideLimit, - width = dims.width, height = dims.height, + width = dims.width, height = dims.height, drawingWidth, drawingHeight, zoomX = dims.zoomX, zoomY = dims.zoomY, dimensionsChanged = width !== this.cacheWidth || height !== this.cacheHeight, zoomChanged = this.zoomX !== zoomX || this.zoomY !== zoomY, @@ -12396,22 +12559,24 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati sizeShrinking = (width < canvasWidth * 0.9 || height < canvasHeight * 0.9) && canvasWidth > minCacheSize && canvasHeight > minCacheSize; shouldResizeCanvas = sizeGrowing || sizeShrinking; - if (sizeGrowing) { - additionalWidth = (width * 0.1) & ~1; - additionalHeight = (height * 0.1) & ~1; + if (sizeGrowing && !dims.capped && (width > minCacheSize || height > minCacheSize)) { + additionalWidth = width * 0.1; + additionalHeight = height * 0.1; } } if (shouldRedraw) { if (shouldResizeCanvas) { - this._cacheCanvas.width = Math.max(Math.ceil(width) + additionalWidth, minCacheSize); - this._cacheCanvas.height = Math.max(Math.ceil(height) + additionalHeight, minCacheSize); - this.cacheTranslationX = (width + additionalWidth) / 2; - this.cacheTranslationY = (height + additionalHeight) / 2; + canvas.width = Math.ceil(width + additionalWidth); + canvas.height = Math.ceil(height + additionalHeight); } else { this._cacheContext.setTransform(1, 0, 0, 1, 0, 0); - this._cacheContext.clearRect(0, 0, this._cacheCanvas.width, this._cacheCanvas.height); + this._cacheContext.clearRect(0, 0, canvas.width, canvas.height); } + drawingWidth = dims.x * zoomX / 2; + drawingHeight = dims.y * zoomY / 2; + this.cacheTranslationX = Math.round(canvas.width / 2 - drawingWidth) + drawingWidth; + this.cacheTranslationY = Math.round(canvas.height / 2 - drawingHeight) + drawingHeight; this.cacheWidth = width; this.cacheHeight = height; this._cacheContext.translate(this.cacheTranslationX, this.cacheTranslationY); @@ -12439,21 +12604,16 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati /** * Transforms context when rendering an object * @param {CanvasRenderingContext2D} ctx Context - * @param {Boolean} fromLeft When true, context is transformed to object's top/left corner. This is used when rendering text on Node */ - transform: function(ctx, fromLeft) { + transform: function(ctx) { + var m; if (this.group && !this.group._transformDone) { - this.group.transform(ctx); + m = this.calcTransformMatrix(); } - var center = fromLeft ? this._getLeftTopCoords() : this.getCenterPoint(); - ctx.translate(center.x, center.y); - this.angle && ctx.rotate(degreesToRadians(this.angle)); - ctx.scale( - this.scaleX * (this.flipX ? -1 : 1), - this.scaleY * (this.flipY ? -1 : 1) - ); - this.skewX && ctx.transform(1, 0, Math.tan(degreesToRadians(this.skewX)), 1, 0, 0); - this.skewY && ctx.transform(1, Math.tan(degreesToRadians(this.skewY)), 0, 1, 0, 0); + else { + m = this.calcOwnMatrix(); + } + ctx.transform(m[0], m[1], m[2], m[3], m[4], m[5]); }, /** @@ -12491,6 +12651,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati clipTo: this.clipTo && String(this.clipTo), backgroundColor: this.backgroundColor, fillRule: this.fillRule, + paintFirst: this.paintFirst, globalCompositeOperation: this.globalCompositeOperation, transformMatrix: this.transformMatrix ? this.transformMatrix.concat() : null, skewX: toFixed(this.skewX, NUM_FRACTION_DIGITS), @@ -12579,7 +12740,8 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati * @return {fabric.Object} thisArg */ _set: function(key, value) { - var shouldConstrainValue = (key === 'scaleX' || key === 'scaleY'); + var shouldConstrainValue = (key === 'scaleX' || key === 'scaleY'), + isChanged = this[key] !== value, groupNeedsUpdate = false; if (shouldConstrainValue) { value = this._constrainScale(value); @@ -12601,15 +12763,15 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati this[key] = value; - if (this.cacheProperties.indexOf(key) > -1) { - if (this.group) { + if (isChanged) { + groupNeedsUpdate = this.group && this.group.isOnACache(); + if (this.cacheProperties.indexOf(key) > -1) { + this.dirty = true; + groupNeedsUpdate && this.group.set('dirty', true); + } + else if (groupNeedsUpdate && this.stateProperties.indexOf(key) > -1) { this.group.set('dirty', true); } - this.dirty = true; - } - - if (this.group && this.stateProperties.indexOf(key) > -1 && this.group.isOnACache()) { - this.group.set('dirty', true); } return this; @@ -12682,6 +12844,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati this.drawCacheOnCanvas(ctx); } else { + this._removeCacheCanvas(); this.dirty = false; this.drawObject(ctx); if (this.objectCaching && this.statefullCache) { @@ -12692,6 +12855,15 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati ctx.restore(); }, + /** + * Remove cacheCanvas and its dimensions from the objects + */ + _removeCacheCanvas: function() { + this._cacheCanvas = null; + this.cacheWidth = 0; + this.cacheHeight = 0; + }, + /** * When set to `true`, force the object to have its own cache, even if it is inside a group * it may be needed when your object behave in a particular way on the cache and always needs @@ -12701,6 +12873,9 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati * @returns false */ needsItsOwnCache: function() { + if (this.paintFirst === 'stroke' && typeof this.shadow === 'object') { + return true; + } return false; }, @@ -12901,7 +13076,8 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati multY *= fabric.devicePixelRatio; } ctx.shadowColor = this.shadow.color; - ctx.shadowBlur = this.shadow.blur * (multX + multY) * (scaling.scaleX + scaling.scaleY) / 4; + ctx.shadowBlur = this.shadow.blur * fabric.browserShadowBlurConstant * + (multX + multY) * (scaling.scaleX + scaling.scaleY) / 4; ctx.shadowOffsetX = this.shadow.offsetX * multX * scaling.scaleX; ctx.shadowOffsetY = this.shadow.offsetY * multY * scaling.scaleY; }, @@ -12928,16 +13104,31 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati if (!filler || !filler.toLive) { return { offsetX: 0, offsetY: 0 }; } - var transform = filler.gradientTransform || filler.patternTransform; + var t = filler.gradientTransform || filler.patternTransform; var offsetX = -this.width / 2 + filler.offsetX || 0, offsetY = -this.height / 2 + filler.offsetY || 0; ctx.translate(offsetX, offsetY); - if (transform) { - ctx.transform.apply(ctx, transform); + if (t) { + ctx.transform(t[0], t[1], t[2], t[3], t[4], t[5]); } return { offsetX: offsetX, offsetY: offsetY }; }, + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _renderPaintInOrder: function(ctx) { + if (this.paintFirst === 'stroke') { + this._renderStroke(ctx); + this._renderFill(ctx); + } + else { + this._renderFill(ctx); + this._renderStroke(ctx); + } + }, + /** * @private * @param {CanvasRenderingContext2D} ctx Context to render on @@ -13008,16 +13199,26 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati * This function is an helper for svg import. it removes the transform matrix * and set to object properties that fabricjs can handle * @private - * @chainable + * @param {Object} preserveAspectRatioOptions * @return {thisArg} */ - _removeTransformMatrix: function() { + _removeTransformMatrix: function(preserveAspectRatioOptions) { var center = this._findCenterFromElement(); if (this.transformMatrix) { this._assignTransformMatrixProps(); center = fabric.util.transformPoint(center, this.transformMatrix); } this.transformMatrix = null; + if (preserveAspectRatioOptions) { + this.scaleX *= preserveAspectRatioOptions.scaleX; + this.scaleY *= preserveAspectRatioOptions.scaleY; + this.cropX = preserveAspectRatioOptions.cropX; + this.cropY = preserveAspectRatioOptions.cropY; + center.x += preserveAspectRatioOptions.offsetLeft; + center.y += preserveAspectRatioOptions.offsetTop; + this.width = preserveAspectRatioOptions.width; + this.height = preserveAspectRatioOptions.height; + } this.setPositionByOrigin(center, 'center', 'center'); }, @@ -13732,6 +13933,16 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati */ aCoords: null, + /** + * storage for object transform matrix + */ + ownMatrixCache: null, + + /** + * storage for object full transform matrix + */ + matrixCache: null, + /** * return correct set of coordinates for intersection */ @@ -13942,24 +14153,6 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati return xcount; }, - /** - * Returns width of an object's bounding rectangle - * @deprecated since 1.0.4 - * @return {Number} width value - */ - getBoundingRectWidth: function() { - return this.getBoundingRect().width; - }, - - /** - * Returns height of an object's bounding rectangle - * @deprecated since 1.0.4 - * @return {Number} height value - */ - getBoundingRectHeight: function() { - return this.getBoundingRect().height; - }, - /** * Returns coordinates of object's bounding rectangle (left, top, width, height) * the box is intented as aligned to axis of canvas. @@ -14024,24 +14217,26 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati /** * Scales an object to a given width, with respect to bounding box (scaling by x/y equally) * @param {Number} value New width value + * @param {Boolean} absolute ignore viewport * @return {fabric.Object} thisArg * @chainable */ - scaleToWidth: function(value) { + scaleToWidth: function(value, absolute) { // adjust to bounding rect factor so that rotated shapes would fit as well - var boundingRectFactor = this.getBoundingRect().width / this.getScaledWidth(); + var boundingRectFactor = this.getBoundingRect(absolute).width / this.getScaledWidth(); return this.scale(value / this.width / boundingRectFactor); }, /** * Scales an object to a given height, with respect to bounding box (scaling by x/y equally) * @param {Number} value New height value + * @param {Boolean} absolute ignore viewport * @return {fabric.Object} thisArg * @chainable */ - scaleToHeight: function(value) { + scaleToHeight: function(value, absolute) { // adjust to bounding rect factor so that rotated shapes would fit as well - var boundingRectFactor = this.getBoundingRect().height / this.getScaledHeight(); + var boundingRectFactor = this.getBoundingRect(absolute).height / this.getScaledHeight(); return this.scale(value / this.height / boundingRectFactor); }, @@ -14055,8 +14250,8 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati vpt = this.getViewportTransform(), dim = absolute ? this._getTransformedDimensions() : this._calculateCurrentDimensions(), currentWidth = dim.x, currentHeight = dim.y, - sinTh = Math.sin(theta), - cosTh = Math.cos(theta), + sinTh = theta ? Math.sin(theta) : 0, + cosTh = theta ? Math.cos(theta) : 1, _angle = currentWidth > 0 ? Math.atan(currentHeight / currentWidth) : 0, _hypotenuse = (currentWidth / Math.cos(_angle)) / 2, offsetX = Math.cos(_angle + theta) * _hypotenuse, @@ -14143,6 +14338,15 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati return fabric.iMatrix.concat(); }, + transformMatrixKey: function(skipGroup) { + var sep = '_', prefix = ''; + if (!skipGroup && this.group) { + prefix = this.group.transformMatrixKey(skipGroup) + sep; + }; + return prefix + this.top + sep + this.left + sep + this.scaleX + sep + this.scaleY + + sep + this.skewX + sep + this.skewY + sep + this.angle + sep + this.flipX + sep + this.flipY; + }, + /** * calculate trasform Matrix that represent current transformation from * object properties. @@ -14150,22 +14354,38 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati * @return {Array} matrix Transform Matrix for the object */ calcTransformMatrix: function(skipGroup) { + if (skipGroup) { + return this.calcOwnMatrix(); + } + var key = this.transformMatrixKey(), cache = this.matrixCache || (this.matrixCache = {}); + if (cache.key === key) { + return cache.value; + } + var matrix = this.calcOwnMatrix(); + if (this.group) { + matrix = multiplyMatrices(this.group.calcTransformMatrix(), matrix); + } + cache.key = key; + cache.value = matrix; + return matrix; + }, + + calcOwnMatrix: function() { + var key = this.transformMatrixKey(true), cache = this.ownMatrixCache || (this.ownMatrixCache = {}); + if (cache.key === key) { + return cache.value; + } var center = this.getCenterPoint(), - translateMatrix = [1, 0, 0, 1, center.x, center.y], + matrix = [1, 0, 0, 1, center.x, center.y], rotateMatrix, - dimensionMatrix = this._calcDimensionsTransformMatrix(this.skewX, this.skewY, true), - matrix; - if (this.group && !skipGroup) { - matrix = multiplyMatrices(this.group.calcTransformMatrix(), translateMatrix); - } - else { - matrix = translateMatrix; - } + dimensionMatrix = this._calcDimensionsTransformMatrix(this.skewX, this.skewY, true); if (this.angle) { rotateMatrix = this._calcRotateMatrix(); matrix = multiplyMatrices(matrix, rotateMatrix); } matrix = multiplyMatrices(matrix, dimensionMatrix); + cache.key = key; + cache.value = matrix; return matrix; }, @@ -14326,7 +14546,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot * @chainable */ moveTo: function(index) { - if (this.group) { + if (this.group && this.group.type !== 'activeSelection') { fabric.StaticCanvas.prototype.moveTo.call(this.group, this, index); } else { @@ -14404,15 +14624,18 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot * @return {String} */ getSvgSpanStyles: function(style, useWhiteSpace) { - var strokeWidth = style.strokeWidth ? 'stroke-width: ' + style.strokeWidth + '; ' : '', - fontFamily = style.fontFamily ? 'font-family: ' + style.fontFamily.replace(/"/g, '\'') + '; ' : '', - fontSize = style.fontSize ? 'font-size: ' + style.fontSize + '; ' : '', - fontStyle = style.fontStyle ? 'font-style: ' + style.fontStyle + '; ' : '', - fontWeight = style.fontWeight ? 'font-weight: ' + style.fontWeight + '; ' : '', + var term = '; ', + strokeWidth = style.strokeWidth ? 'stroke-width: ' + style.strokeWidth + term : '', + fontFamily = style.fontFamily ? 'font-family: ' + style.fontFamily.replace(/"/g, '\'') + term : '', + fontSize = style.fontSize ? 'font-size: ' + style.fontSize + term : '', + fontStyle = style.fontStyle ? 'font-style: ' + style.fontStyle + term : '', + fontWeight = style.fontWeight ? 'font-weight: ' + style.fontWeight + term : '', fill = style.fill ? getSvgColorString('fill', style.fill) : '', stroke = style.stroke ? getSvgColorString('stroke', style.stroke) : '', textDecoration = this.getSvgTextDecoration(style); - + if (textDecoration) { + textDecoration = 'text-decoration: ' + textDecoration + term; + } return [ stroke, strokeWidth, @@ -14428,8 +14651,8 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot getSvgTextDecoration: function(style) { if ('overline' in style || 'underline' in style || 'linethrough' in style) { - return 'text-decoration: ' + (style.overline ? 'overline ' : '') + - (style.underline ? 'underline ' : '') + (style.linethrough ? 'line-through ' : '') + ';'; + return (style.overline ? 'overline ' : '') + + (style.underline ? 'underline ' : '') + (style.linethrough ? 'line-through ' : ''); } return ''; }, @@ -14534,6 +14757,10 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot markup.push(this.shadow.toSVG(this)); } return markup; + }, + + addPaintOrder: function() { + return this.paintFirst !== 'fill' ? ' paint-order="' + this.paintFirst + '" ' : ''; } }); })(); @@ -15301,14 +15528,6 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot return; } - var cacheProperties = fabric.Object.prototype.cacheProperties.concat(); - cacheProperties.push( - 'x1', - 'x2', - 'y1', - 'y2' - ); - /** * Line class * @class fabric.Line @@ -15352,7 +15571,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot */ y2: 0, - cacheProperties: cacheProperties, + cacheProperties: fabric.Object.prototype.cacheProperties.concat('x1', 'x2', 'y1', 'y2'), /** * Constructor @@ -15655,11 +15874,6 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot return; } - var cacheProperties = fabric.Object.prototype.cacheProperties.concat(); - cacheProperties.push( - 'radius' - ); - /** * Circle class * @class fabric.Circle @@ -15696,7 +15910,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot */ endAngle: pi * 2, - cacheProperties: cacheProperties, + cacheProperties: fabric.Object.prototype.cacheProperties.concat('radius'), /** * Constructor @@ -15750,8 +15964,9 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot 'r="', this.radius, '" style="', this.getSvgStyles(), '" transform="', this.getSvgTransform(), - ' ', this.getSvgTransformMatrix(), - '"/>\n' + ' ', this.getSvgTransformMatrix(), '"', + this.addPaintOrder(), + '/>\n' ); } else { @@ -15767,7 +15982,8 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot ' 0 ', +largeFlag + ' 1', ' ' + endX + ' ' + endY, '" style="', this.getSvgStyles(), '" transform="', this.getSvgTransform(), - ' ', this.getSvgTransformMatrix(), + ' ', this.getSvgTransformMatrix(), '"', + this.addPaintOrder(), '"/>\n' ); } @@ -15782,13 +15998,13 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot */ _render: function(ctx) { ctx.beginPath(); - ctx.arc(0, + ctx.arc( + 0, 0, this.radius, this.startAngle, this.endAngle, false); - this._renderFill(ctx); - this._renderStroke(ctx); + this._renderPaintInOrder(ctx); }, /** @@ -15924,8 +16140,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot ctx.lineTo(widthBy2, heightBy2); ctx.closePath(); - this._renderFill(ctx); - this._renderStroke(ctx); + this._renderPaintInOrder(ctx); }, /** @@ -15964,8 +16179,9 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot '' + '" transform="', this.getSvgTransform(), '"', + this.addPaintOrder(), + '/>' ); return reviver ? reviver(markup.join('')) : markup.join(''); @@ -16000,12 +16216,6 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot return; } - var cacheProperties = fabric.Object.prototype.cacheProperties.concat(); - cacheProperties.push( - 'rx', - 'ry' - ); - /** * Ellipse class * @class fabric.Ellipse @@ -16036,7 +16246,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot */ ry: 0, - cacheProperties: cacheProperties, + cacheProperties: fabric.Object.prototype.cacheProperties.concat('rx', 'ry'), /** * Constructor @@ -16113,8 +16323,9 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot '" ry="', this.ry, '" style="', this.getSvgStyles(), '" transform="', this.getSvgTransform(), - this.getSvgTransformMatrix(), - '"/>\n' + this.getSvgTransformMatrix(), '"', + this.addPaintOrder(), + '/>\n' ); return reviver ? reviver(markup.join('')) : markup.join(''); @@ -16137,8 +16348,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot piBy2, false); ctx.restore(); - this._renderFill(ctx); - this._renderStroke(ctx); + this._renderPaintInOrder(ctx); }, }); @@ -16198,12 +16408,6 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot return; } - var stateProperties = fabric.Object.prototype.stateProperties.concat(); - stateProperties.push('rx', 'ry'); - - var cacheProperties = fabric.Object.prototype.cacheProperties.concat(); - cacheProperties.push('rx', 'ry'); - /** * Rectangle class * @class fabric.Rect @@ -16218,7 +16422,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot * as well as for history (undo/redo) purposes * @type Array */ - stateProperties: stateProperties, + stateProperties: fabric.Object.prototype.stateProperties.concat('rx', 'ry'), /** * Type of an object @@ -16241,7 +16445,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot */ ry: 0, - cacheProperties: cacheProperties, + cacheProperties: fabric.Object.prototype.cacheProperties.concat('rx', 'ry'), /** * Constructor @@ -16305,8 +16509,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot ctx.closePath(); - this._renderFill(ctx); - this._renderStroke(ctx); + this._renderPaintInOrder(ctx); }, /** @@ -16351,8 +16554,9 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot '" width="', this.width, '" height="', this.height, '" style="', this.getSvgStyles(), '" transform="', this.getSvgTransform(), - this.getSvgTransformMatrix(), - '"/>\n'); + this.getSvgTransformMatrix(), '"', + this.addPaintOrder(), + '/>\n'); return reviver ? reviver(markup.join('')) : markup.join(''); }, @@ -16422,9 +16626,6 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot return; } - var cacheProperties = fabric.Object.prototype.cacheProperties.concat(); - cacheProperties.push('points'); - /** * Polyline class * @class fabric.Polyline @@ -16447,7 +16648,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot */ points: null, - cacheProperties: cacheProperties, + cacheProperties: fabric.Object.prototype.cacheProperties.concat('points'), /** * Constructor @@ -16547,8 +16748,9 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot 'points="', points.join(''), '" style="', this.getSvgStyles(), '" transform="', this.getSvgTransform(), - ' ', this.getSvgTransformMatrix(), - '"/>\n' + ' ', this.getSvgTransformMatrix(), '"', + this.addPaintOrder(), + '/>\n' ); return reviver ? reviver(markup.join('')) : markup.join(''); @@ -16587,8 +16789,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot if (!this.commonRender(ctx)) { return; } - this._renderFill(ctx); - this._renderStroke(ctx); + this._renderPaintInOrder(ctx); }, /** @@ -16695,8 +16896,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot return; } ctx.closePath(); - this._renderFill(ctx); - this._renderStroke(ctx); + this._renderPaintInOrder(ctx); }, /** @@ -16785,12 +16985,6 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot return; } - var stateProperties = fabric.Object.prototype.stateProperties.concat(); - stateProperties.push('path'); - - var cacheProperties = fabric.Object.prototype.cacheProperties.concat(); - cacheProperties.push('path', 'fillRule'); - /** * Path class * @class fabric.Path @@ -16814,9 +17008,9 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot */ path: null, - cacheProperties: cacheProperties, + cacheProperties: fabric.Object.prototype.cacheProperties.concat('path', 'fillRule'), - stateProperties: stateProperties, + stateProperties: fabric.Object.prototype.stateProperties.concat('path'), /** * Constructor @@ -17186,8 +17380,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot */ _render: function(ctx) { this._renderPathCommands(ctx); - this._renderFill(ctx); - this._renderStroke(ctx); + this._renderPaintInOrder(ctx); }, /** @@ -17247,6 +17440,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot '" style="', this.getSvgStyles(), '" transform="', this.getSvgTransform(), addTransform, this.getSvgTransformMatrix(), '" stroke-linecap="round" ', + this.addPaintOrder(), '/>\n' ); @@ -17779,10 +17973,24 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot delete options.centerPoint; this.callSuper('initialize', options); } + else { + this._updateObjectsACoords(); + } this.setCoords(); }, + /** + * @private + * @param {Boolean} [skipCoordsChange] if true, coordinates of objects enclosed in a group do not change + */ + _updateObjectsACoords: function() { + var ignoreZoom = true, skipAbsolute = true; + for (var i = this._objects.length; i--; ){ + this._objects[i].setCoords(ignoreZoom, skipAbsolute); + } + }, + /** * @private * @param {Boolean} [skipCoordsChange] if true, coordinates of objects enclosed in a group do not change @@ -18601,6 +18809,11 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot * @chainable */ setElement: function(element, options) { + var backend = fabric.filterBackend; + if (backend && backend.evictCachesForKey) { + backend.evictCachesForKey(this.cacheKey); + backend.evictCachesForKey(this.cacheKey + '_filtered'); + } this._element = element; this._originalElement = element; this._initConfig(options); @@ -18701,9 +18914,6 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot if (this.resizeFilter) { object.resizeFilter = this.resizeFilter.toObject(); } - object.width /= this._filterScalingX; - object.height /= this._filterScalingY; - return object; }, @@ -18715,9 +18925,8 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot */ toSVG: function(reviver) { var markup = this._createBaseSVGMarkup(), x = -this.width / 2, y = -this.height / 2; - markup.push( - '\n', - '\t\n'); + var imageMarkup = ['\t\n' - ); - + '">\n']; + if (this.paintFirst === 'fill') { + Array.prototype.push.apply(markup, imageMarkup); + } if (this.stroke || this.strokeDashArray) { var origFill = this.fill; this.fill = null; markup.push( - ' -1) { + set: function(key, value) { + this.callSuper('set', key, value); + var needsDims = false; + if (typeof key === 'object') { + for (var _key in key) { + needsDims = needsDims || this._dimensionAffectingProps.indexOf(_key) !== -1; + } + } + else { + needsDims = this._dimensionAffectingProps.indexOf(key) !== -1; + } + if (needsDims) { this.initDimensions(); this.setCoords(); } + return this; }, /** @@ -24929,7 +25358,6 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) { */ _render: function(ctx) { this.callSuper('_render', ctx); - this.ctx = ctx; }, /** @@ -24940,9 +25368,9 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) { return; } if (this.canvas && this.canvas.contextTop) { - var ctx = this.canvas.contextTop; + var ctx = this.canvas.contextTop, v = this.canvas.viewportTransform; ctx.save(); - ctx.transform.apply(ctx, this.canvas.viewportTransform); + ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]); this.transform(ctx); this.transformMatrix && ctx.transform.apply(ctx, this.transformMatrix); this._clearTextArea(ctx); @@ -24954,7 +25382,7 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) { * Renders cursor or selection (depending on what exists) */ renderCursorOrSelection: function() { - if (!this.isEditing) { + if (!this.isEditing || !this.canvas) { return; } var boundaries = this._getCursorBoundaries(), ctx; @@ -24963,7 +25391,7 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) { this.clearContextTop(true); } else { - ctx = this.ctx; + ctx = this.canvas.contextContainer; ctx.save(); } if (this.selectionStart === this.selectionEnd) { @@ -25079,6 +25507,7 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) { var selectionStart = this.inCompositionMode ? this.hiddenTextarea.selectionStart : this.selectionStart, selectionEnd = this.inCompositionMode ? this.hiddenTextarea.selectionEnd : this.selectionEnd, + isJustify = this.textAlign.indexOf('justify') !== -1, start = this.get2DCursorLocation(selectionStart), end = this.get2DCursorLocation(selectionEnd), startLine = start.lineIndex, @@ -25095,7 +25524,7 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) { boxStart = this.__charBounds[startLine][startChar].left; } if (i >= startLine && i < endLine) { - boxEnd = this.getLineWidth(i) || 5; // WTF is this 5? + boxEnd = isJustify && !this.isEndOfWrapping(i) ? this.width : this.getLineWidth(i) || 5; // WTF is this 5? } else if (i === endLine) { if (endChar === 0) { @@ -25338,7 +25767,8 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) { * Aborts cursor animation and clears all timeouts */ abortCursorAnimation: function() { - var shouldClear = this._currentTickState || this._currentTickCompleteState; + var shouldClear = this._currentTickState || this._currentTickCompleteState, + canvas = this.canvas; this._currentTickState && this._currentTickState.abort(); this._currentTickCompleteState && this._currentTickCompleteState.abort(); @@ -25348,8 +25778,8 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) { this._currentCursorOpacity = 0; // to clear just itext area we need to transform the context // it may not be worth it - if (shouldClear) { - this.canvas && this.canvas.clearContext(this.canvas.contextTop || this.ctx); + if (shouldClear && canvas) { + canvas.clearContext(canvas.contextTop || canvas.contextContainer); } }, @@ -25665,6 +26095,10 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) { } this.cursorOffsetCache = { }; this.text = this.hiddenTextarea.value; + if (this._shouldClearDimensionCache()) { + this.initDimensions(); + this.setCoords(); + } var newSelection = this.fromStringToGraphemeSelection( this.hiddenTextarea.selectionStart, this.hiddenTextarea.selectionEnd, this.hiddenTextarea.value); this.selectionEnd = this.selectionStart = newSelection.selectionEnd; @@ -25788,7 +26222,10 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) { this.abortCursorAnimation(); this._restoreEditingProps(); this._currentCursorOpacity = 0; - + if (this._shouldClearDimensionCache()) { + this.initDimensions(); + this.setCoords(); + } this.fire('editing:exited'); isTextChanged && this.fire('modified'); if (this.canvas) { @@ -26019,10 +26456,14 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) { } linesLenght && this.insertNewlineStyleObject( cursorLoc.lineIndex, cursorLoc.charIndex + addedLines[0], linesLenght); - for (var i = 1; i <= linesLenght; i++) { + for (var i = 1; i < linesLenght; i++) { this.insertCharStyleObject(cursorLoc.lineIndex + i, 0, addedLines[i], copiedStyle); copiedStyle = copiedStyle && copiedStyle.slice(addedLines[i] + 1); } + // we use i outside the loop to get it like linesLength + if (addedLines[i] > 0) { + this.insertCharStyleObject(cursorLoc.lineIndex + i, 0, addedLines[i], copiedStyle); + } }, /** @@ -26445,7 +26886,6 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot nextCharCount = nextText.length, removedText, insertedText, charDiff = nextCharCount - charCount; - if (this.hiddenTextarea.value === '') { this.styles = { }; this.updateFromTextArea(); @@ -26454,26 +26894,34 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot this.canvas.fire('text:changed', { target: this }); this.canvas.requestRenderAll(); } + return; } + var textareaSelection = this.fromStringToGraphemeSelection( + this.hiddenTextarea.selectionStart, + this.hiddenTextarea.selectionEnd, + this.hiddenTextarea.value + ); + var backDelete = this.selectionStart > textareaSelection.selectionStart; + if (this.selectionStart !== this.selectionEnd) { removedText = this._text.slice(this.selectionStart, this.selectionEnd); charDiff += this.selectionEnd - this.selectionStart; } else if (nextCharCount < charCount) { - removedText = this._text.slice(this.selectionEnd + charDiff, this.selectionEnd); + if (backDelete) { + removedText = this._text.slice(this.selectionEnd + charDiff, this.selectionEnd); + } + else { + removedText = this._text.slice(this.selectionStart, this.selectionStart - charDiff); + } } - var textareaSelection = this.fromStringToGraphemeSelection( - this.hiddenTextarea.selectionStart, - this.hiddenTextarea.selectionEnd, - this.hiddenTextarea.value - ); insertedText = nextText.slice(textareaSelection.selectionEnd - charDiff, textareaSelection.selectionEnd); if (removedText && removedText.length) { if (this.selectionStart !== this.selectionEnd) { this.removeStyleFromTo(this.selectionStart, this.selectionEnd); } - else if (this.selectionStart > textareaSelection.selectionStart) { + else if (backDelete) { // detect differencies between forwardDelete and backDelete this.removeStyleFromTo(this.selectionEnd - removedText.length, this.selectionEnd); } @@ -26899,10 +27347,11 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot this.setSelectionEnd(this.selectionStart); this._removeExtraneousStyles(); - + if (this._shouldClearDimensionCache()) { + this.initDimensions(); + this.setCoords(); + } this.canvas && this.canvas.requestRenderAll(); - - this.setCoords(); this.fire('changed'); this.canvas && this.canvas.fire('text:changed', { target: this }); }, @@ -26974,8 +27423,8 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot */ _wrapSVGTextAndBg: function(markup, textAndBg) { var noShadow = true, filter = this.getSvgFilter(), - style = filter === '' ? '' : ' style="' + filter + '"'; - + style = filter === '' ? '' : ' style="' + filter + '"', + textDecoration = this.getSvgTextDecoration(this); markup.push( '\t\n', @@ -26985,8 +27434,8 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot (this.fontSize ? 'font-size="' + this.fontSize + '" ' : ''), (this.fontStyle ? 'font-style="' + this.fontStyle + '" ' : ''), (this.fontWeight ? 'font-weight="' + this.fontWeight + '" ' : ''), - (this.textDecoration ? 'text-decoration="' + this.textDecoration + '" ' : ''), - 'style="', this.getSvgStyles(noShadow), '" >\n', + (textDecoration ? 'text-decoration="' + textDecoration + '" ' : ''), + 'style="', this.getSvgStyles(noShadow), '"', this.addPaintOrder(), ' >\n', textAndBg.textSpans.join(''), '\t\t\n', '\t\n' @@ -27041,6 +27490,7 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot _setSVGTextLineText: function(textSpans, lineIndex, textLeftOffset, textTopOffset) { // set proper line offset var lineHeight = this.getHeightOfLine(lineIndex), + isJustify = this.textAlign.indexOf('justify') !== -1, actualStyle, nextStyle, charsToRender = '', @@ -27056,9 +27506,12 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot charBox = this.__charBounds[lineIndex][i]; if (boxWidth === 0) { textLeftOffset += charBox.kernedWidth - charBox.width; + boxWidth += charBox.width; } - boxWidth += charBox.kernedWidth; - if (this.textAlign === 'justify' && !timeToRender) { + else { + boxWidth += charBox.kernedWidth; + } + if (isJustify && !timeToRender) { if (this._reSpaceAndTab.test(line[i])) { timeToRender = true; } @@ -27067,7 +27520,7 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot // if we have charSpacing, we render char by char actualStyle = actualStyle || this.getCompleteStyleDeclaration(lineIndex, i); nextStyle = this.getCompleteStyleDeclaration(lineIndex, i + 1); - timeToRender = this._hasStyleChanged(actualStyle, nextStyle); + timeToRender = this._hasStyleChangedForSvg(actualStyle, nextStyle); } if (timeToRender) { style = this._getStyleDeclaration(lineIndex, i) || { }; @@ -27224,6 +27677,13 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot */ noScaleCache: false, + /** + * Properties which when set cause object to change dimensions + * @type Object + * @private + */ + _dimensionAffectingProps: fabric.Text.prototype._dimensionAffectingProps.concat('width'), + /** * Constructor. Some scaling related property values are forced. Visibility * of controls is also fixed; only the rotation and width controls are @@ -27233,11 +27693,7 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot * @return {fabric.Textbox} thisArg */ initialize: function(text, options) { - this.callSuper('initialize', text, options); - this.ctx = this.objectCaching ? this._cacheContext : fabric.util.createCanvasElement().getContext('2d'); - // add width to this list of props that effect line wrapping. - this._dimensionAffectingProps.push('width'); }, /** @@ -27256,22 +27712,18 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot // clear dynamicMinWidth as it will be different after we re-wrap line this.dynamicMinWidth = 0; // wrap lines - var newText = this._splitTextIntoLines(this.text); - this.textLines = newText.lines; - this._textLines = newText.graphemeLines; - this._unwrappedTextLines = newText._unwrappedLines; - this._text = newText.graphemeText; - this._styleMap = this._generateStyleMap(newText); + this._styleMap = this._generateStyleMap(this._splitText()); // if after wrapping, the width is smaller than dynamicMinWidth, change the width and re-wrap if (this.dynamicMinWidth > this.width) { this._set('width', this.dynamicMinWidth); } - if (this.textAlign === 'justify') { + if (this.textAlign.indexOf('justify') !== -1) { // once text is measured we need to make space fatter to make justified text. this.enlargeSpaces(); } // clear cache and re-calculate height this.height = this.calcTextHeight(); + this.saveState({ propertySet: '_dimensionAffectingProps' }); }, /** @@ -27495,6 +27947,24 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot return graphemeLines; }, + /** + * Detect if the text line is ended with an hard break + * text and itext do not have wrapping, return false + * @param {Number} lineIndex text to split + * @return {Boolean} + */ + isEndOfWrapping: function(lineIndex) { + if (!this._styleMap[lineIndex + 1]) { + // is last line, return true; + return true; + } + if (this._styleMap[lineIndex + 1].line !== this._styleMap[lineIndex].line) { + // this is last line before a line break, return true; + return true; + } + return false; + }, + /** * Gets lines of text to render in the Textbox. This function calculates * text wrapping on the fly every time it is called. @@ -27584,216 +28054,3 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot }); })(); - -(function() { - - if (typeof document !== 'undefined' && typeof window !== 'undefined') { - return; - } - - var DOMParser = require('xmldom').DOMParser, - URL = require('url'), - HTTP = require('http'), - HTTPS = require('https'), - - Canvas = require(fabric.canvasModule), - Image = require(fabric.canvasModule).Image; - - /** @private */ - function request(url, encoding, callback) { - var oURL = URL.parse(url); - - // detect if http or https is used - if ( !oURL.port ) { - oURL.port = ( oURL.protocol.indexOf('https:') === 0 ) ? 443 : 80; - } - - // assign request handler based on protocol - var reqHandler = (oURL.protocol.indexOf('https:') === 0 ) ? HTTPS : HTTP, - req = reqHandler.request({ - hostname: oURL.hostname, - port: oURL.port, - path: oURL.path, - method: 'GET' - }, function(response) { - var body = ''; - if (encoding) { - response.setEncoding(encoding); - } - response.on('end', function () { - callback(body); - }); - response.on('data', function (chunk) { - if (response.statusCode === 200) { - body += chunk; - } - }); - }); - - req.on('error', function(err) { - if (err.errno === process.ECONNREFUSED) { - fabric.log('ECONNREFUSED: connection refused to ' + oURL.hostname + ':' + oURL.port); - } - else { - fabric.log(err.message); - } - callback(null); - }); - - req.end(); - } - - /** @private */ - function requestFs(path, callback) { - var fs = require('fs'); - fs.readFile(path, function (err, data) { - if (err) { - fabric.log(err); - throw err; - } - else { - callback(data); - } - }); - } - - fabric.util.loadImage = function(url, callback, context) { - function createImageAndCallBack(data) { - if (data) { - img.src = new Buffer(data, 'binary'); - // preserving original url, which seems to be lost in node-canvas - img._src = url; - callback && callback.call(context, img); - } - else { - img = null; - callback && callback.call(context, null, true); - } - } - var img = new Image(); - if (url && (url instanceof Buffer || url.indexOf('data') === 0)) { - img.src = img._src = url; - callback && callback.call(context, img); - } - else if (url && url.indexOf('http') !== 0) { - requestFs(url, createImageAndCallBack); - } - else if (url) { - request(url, 'binary', createImageAndCallBack); - } - else { - callback && callback.call(context, url); - } - }; - - fabric.loadSVGFromURL = function(url, callback, reviver) { - url = url.replace(/^\n\s*/, '').replace(/\?.*$/, '').trim(); - if (url.indexOf('http') !== 0) { - requestFs(url, function(body) { - fabric.loadSVGFromString(body.toString(), callback, reviver); - }); - } - else { - request(url, '', function(body) { - fabric.loadSVGFromString(body, callback, reviver); - }); - } - }; - - fabric.loadSVGFromString = function(string, callback, reviver) { - var doc = new DOMParser().parseFromString(string); - fabric.parseSVGDocument(doc.documentElement, function(results, options) { - callback && callback(results, options); - }, reviver); - }; - - fabric.util.getScript = function(url, callback) { - request(url, '', function(body) { - // eslint-disable-next-line no-eval - eval(body); - callback && callback(); - }); - }; - - // fabric.util.createCanvasElement = function(_, width, height) { - // return new Canvas(width, height); - // } - - /** - * Only available when running fabric on node.js - * @param {Number} width Canvas width - * @param {Number} height Canvas height - * @param {Object} [options] Options to pass to FabricCanvas. - * @param {Object} [nodeCanvasOptions] Options to pass to NodeCanvas. - * @return {Object} wrapped canvas instance - */ - fabric.createCanvasForNode = function(width, height, options, nodeCanvasOptions) { - nodeCanvasOptions = nodeCanvasOptions || options; - - var canvasEl = fabric.document.createElement('canvas'), - nodeCanvas = new Canvas(width || 600, height || 600, nodeCanvasOptions), - nodeCacheCanvas = new Canvas(width || 600, height || 600, nodeCanvasOptions); - - canvasEl.width = nodeCanvas.width; - canvasEl.height = nodeCanvas.height; - options = options || { }; - options.nodeCanvas = nodeCanvas; - options.nodeCacheCanvas = nodeCacheCanvas; - var FabricCanvas = fabric.Canvas || fabric.StaticCanvas, - fabricCanvas = new FabricCanvas(canvasEl, options); - fabricCanvas.nodeCanvas = nodeCanvas; - fabricCanvas.nodeCacheCanvas = nodeCacheCanvas; - fabricCanvas.contextContainer = nodeCanvas.getContext('2d'); - fabricCanvas.contextCache = nodeCacheCanvas.getContext('2d'); - fabricCanvas.Font = Canvas.Font; - return fabricCanvas; - }; - - var originaInitStatic = fabric.StaticCanvas.prototype._initStatic; - fabric.StaticCanvas.prototype._initStatic = function(el, options) { - el = el || fabric.document.createElement('canvas'); - this.nodeCanvas = new Canvas(el.width, el.height); - this.nodeCacheCanvas = new Canvas(el.width, el.height); - originaInitStatic.call(this, el, options); - this.contextContainer = this.nodeCanvas.getContext('2d'); - this.contextCache = this.nodeCacheCanvas.getContext('2d'); - this.Font = Canvas.Font; - }; - - /** @ignore */ - fabric.StaticCanvas.prototype.createPNGStream = function() { - return this.nodeCanvas.createPNGStream(); - }; - - fabric.StaticCanvas.prototype.createJPEGStream = function(opts) { - return this.nodeCanvas.createJPEGStream(opts); - }; - - fabric.StaticCanvas.prototype._initRetinaScaling = function() { - if (!this._isRetinaScaling()) { - return; - } - - this.lowerCanvasEl.setAttribute('width', this.width * fabric.devicePixelRatio); - this.lowerCanvasEl.setAttribute('height', this.height * fabric.devicePixelRatio); - this.nodeCanvas.width = this.width * fabric.devicePixelRatio; - this.nodeCanvas.height = this.height * fabric.devicePixelRatio; - this.contextContainer.scale(fabric.devicePixelRatio, fabric.devicePixelRatio); - return this; - }; - if (fabric.Canvas) { - fabric.Canvas.prototype._initRetinaScaling = fabric.StaticCanvas.prototype._initRetinaScaling; - } - - var origSetBackstoreDimension = fabric.StaticCanvas.prototype._setBackstoreDimension; - fabric.StaticCanvas.prototype._setBackstoreDimension = function(prop, value) { - origSetBackstoreDimension.call(this, prop, value); - this.nodeCanvas[prop] = value; - return this; - }; - if (fabric.Canvas) { - fabric.Canvas.prototype._setBackstoreDimension = fabric.StaticCanvas.prototype._setBackstoreDimension; - } - -})(); - diff --git a/dist/fabric.min.js b/dist/fabric.min.js index 5c294bb3..7f484ee2 100644 --- a/dist/fabric.min.js +++ b/dist/fabric.min.js @@ -1 +1 @@ -function copyGLTo2DDrawImage(t,e){var i=t.canvas,r=e.getContext("2d");r.translate(0,e.height),r.scale(1,-1);var n=i.height-e.height;r.drawImage(i,0,n,e.width,e.height,0,0,e.width,e.height)}function copyGLTo2DPutImageData(t,e){var i=e.getContext("2d"),r=e.width,n=e.height,s=r*n*4,o=new Uint8Array(this.imageBuffer,0,s),a=new Uint8ClampedArray(this.imageBuffer,0,s);t.readPixels(0,0,r,n,t.RGBA,t.UNSIGNED_BYTE,o);var c=new ImageData(a,r);i.putImageData(c,0,0)}var fabric=fabric||{version:"2.0.0-beta7"};"undefined"!=typeof exports&&(exports.fabric=fabric),"undefined"!=typeof document&&"undefined"!=typeof window?(fabric.document=document,fabric.window=window):(fabric.document=require("jsdom").jsdom(decodeURIComponent("%3C!DOCTYPE%20html%3E%3Chtml%3E%3Chead%3E%3C%2Fhead%3E%3Cbody%3E%3C%2Fbody%3E%3C%2Fhtml%3E"),{features:{FetchExternalResources:["img"]}}),fabric.window=fabric.document.defaultView),fabric.isTouchSupported="ontouchstart"in fabric.window,fabric.isLikelyNode="undefined"!=typeof Buffer&&"undefined"==typeof window,fabric.SHARED_ATTRIBUTES=["display","transform","fill","fill-opacity","fill-rule","opacity","stroke","stroke-dasharray","stroke-linecap","stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke-width","id","instantiated_by_use"],fabric.DPI=96,fabric.reNum="(?:[-+]?(?:\\d+|\\d*\\.\\d+)(?:e[-+]?\\d+)?)",fabric.fontPaths={},fabric.iMatrix=[1,0,0,1,0,0],fabric.canvasModule="canvas",fabric.perfLimitSizeTotal=2097152,fabric.maxCacheSideLimit=4096,fabric.minCacheSideLimit=256,fabric.charWidthsCache={},fabric.textureSize=2048,fabric.enableGLFiltering=!0,fabric.devicePixelRatio=fabric.window.devicePixelRatio||fabric.window.webkitDevicePixelRatio||fabric.window.mozDevicePixelRatio||1,fabric.initFilterBackend=function(){return fabric.enableGLFiltering&&fabric.isWebglSupported&&fabric.isWebglSupported(fabric.textureSize)?(console.log("max texture size: "+fabric.maxTextureSize),new fabric.WebglFilterBackend({tileSize:fabric.textureSize})):fabric.Canvas2dFilterBackend?new fabric.Canvas2dFilterBackend:void 0},"undefined"!=typeof document&&"undefined"!=typeof window&&(window.fabric=fabric),function(){function t(t,e){if(this.__eventListeners[t]){var i=this.__eventListeners[t];e?i[i.indexOf(e)]=!1:fabric.util.array.fill(i,!1)}}function e(t,e){if(this.__eventListeners||(this.__eventListeners={}),1===arguments.length)for(var i in t)this.on(i,t[i]);else this.__eventListeners[t]||(this.__eventListeners[t]=[]),this.__eventListeners[t].push(e);return this}function i(e,i){if(this.__eventListeners){if(0===arguments.length)for(e in this.__eventListeners)t.call(this,e);else if(1===arguments.length&&"object"==typeof arguments[0])for(var r in e)t.call(this,r,e[r]);else t.call(this,e,i);return this}}function r(t,e){if(this.__eventListeners){var i=this.__eventListeners[t];if(i){for(var r=0,n=i.length;r-1},complexity:function(){return this.getObjects().reduce(function(t,e){return t+=e.complexity?e.complexity():0},0)}},fabric.CommonMethods={_setOptions:function(t){for(var e in t)this.set(e,t[e])},_initGradient:function(t,e){!t||!t.colorStops||t instanceof fabric.Gradient||this.set(e,new fabric.Gradient(t))},_initPattern:function(t,e,i){!t||!t.source||t instanceof fabric.Pattern?i&&i():this.set(e,new fabric.Pattern(t,i))},_initClipping:function(t){if(t.clipTo&&"string"==typeof t.clipTo){var e=fabric.util.getFunctionBody(t.clipTo);void 0!==e&&(this.clipTo=new Function("ctx",e))}},_setObject:function(t){for(var e in t)this._set(e,t[e])},set:function(t,e){return"object"==typeof t?this._setObject(t):"function"==typeof e&&"clipTo"!==t?this._set(t,e(this.get(t))):this._set(t,e),this},_set:function(t,e){this[t]=e},toggle:function(t){var e=this.get(t);return"boolean"==typeof e&&this.set(t,!e),this},get:function(t){return this[t]}},function(t){var e=Math.sqrt,i=Math.atan2,r=Math.pow,n=Math.abs,s=Math.PI/180;fabric.util={removeFromArray:function(t,e){var i=t.indexOf(e);return-1!==i&&t.splice(i,1),t},getRandomInt:function(t,e){return Math.floor(Math.random()*(e-t+1))+t},degreesToRadians:function(t){return t*s},radiansToDegrees:function(t){return t/s},rotatePoint:function(t,e,i){t.subtractEquals(e);var r=fabric.util.rotateVector(t,i);return new fabric.Point(r.x,r.y).addEquals(e)},rotateVector:function(t,e){var i=Math.sin(e),r=Math.cos(e);return{x:t.x*r-t.y*i,y:t.x*i+t.y*r}},transformPoint:function(t,e,i){return i?new fabric.Point(e[0]*t.x+e[2]*t.y,e[1]*t.x+e[3]*t.y):new fabric.Point(e[0]*t.x+e[2]*t.y+e[4],e[1]*t.x+e[3]*t.y+e[5])},makeBoundingBoxFromPoints:function(t){var e=[t[0].x,t[1].x,t[2].x,t[3].x],i=fabric.util.array.min(e),r=fabric.util.array.max(e),n=Math.abs(i-r),s=[t[0].y,t[1].y,t[2].y,t[3].y],o=fabric.util.array.min(s),a=fabric.util.array.max(s);return{left:i,top:o,width:n,height:Math.abs(o-a)}},invertTransform:function(t){var e=1/(t[0]*t[3]-t[1]*t[2]),i=[e*t[3],-e*t[1],-e*t[2],e*t[0]],r=fabric.util.transformPoint({x:t[4],y:t[5]},i,!0);return i[4]=-r.x,i[5]=-r.y,i},toFixed:function(t,e){return parseFloat(Number(t).toFixed(e))},parseUnit:function(t,e){var i=/\D{0,2}$/.exec(t),r=parseFloat(t);switch(e||(e=fabric.Text.DEFAULT_SVG_FONT_SIZE),i[0]){case"mm":return r*fabric.DPI/25.4;case"cm":return r*fabric.DPI/2.54;case"in":return r*fabric.DPI;case"pt":return r*fabric.DPI/72;case"pc":return r*fabric.DPI/72*12;case"em":return r*e;default:return r}},falseFunction:function(){return!1},getKlass:function(t,e){return t=fabric.util.string.camelize(t.charAt(0).toUpperCase()+t.slice(1)),fabric.util.resolveNamespace(e)[t]},getSvgAttributes:function(t){var e=["instantiated_by_use","style","id","class"];switch(t){case"linearGradient":e=e.concat(["x1","y1","x2","y2","gradientUnits","gradientTransform"]);break;case"radialGradient":e=e.concat(["gradientUnits","gradientTransform","cx","cy","r","fx","fy","fr"]);break;case"stop":e=e.concat(["offset","stop-color","stop-opacity"])}return e},resolveNamespace:function(e){if(!e)return fabric;var i,r=e.split("."),n=r.length,s=t||fabric.window;for(i=0;ir;)(r+=a[d++%f])>l&&(r=l),t[g?"lineTo":"moveTo"](r,0),g=!g;t.restore()},createCanvasElement:function(){return fabric.document.createElement("canvas")},createImage:function(){return fabric.document.createElement("img")},clipContext:function(t,e){e.save(),e.beginPath(),t.clipTo(e),e.clip()},multiplyTransformMatrices:function(t,e,i){return[t[0]*e[0]+t[2]*e[1],t[1]*e[0]+t[3]*e[1],t[0]*e[2]+t[2]*e[3],t[1]*e[2]+t[3]*e[3],i?0:t[0]*e[4]+t[2]*e[5]+t[4],i?0:t[1]*e[4]+t[3]*e[5]+t[5]]},qrDecompose:function(t){var n=i(t[1],t[0]),o=r(t[0],2)+r(t[1],2),a=e(o),c=(t[0]*t[3]-t[2]*t[1])/a,h=i(t[0]*t[2]+t[1]*t[3],o);return{angle:n/s,scaleX:a,scaleY:c,skewX:h/s,skewY:0,translateX:t[4],translateY:t[5]}},customTransformMatrix:function(t,e,i){var r=[1,0,n(Math.tan(i*s)),1],o=[n(t),0,0,n(e)];return fabric.util.multiplyTransformMatrices(o,r,!0)},resetObjectTransform:function(t){t.scaleX=1,t.scaleY=1,t.skewX=0,t.skewY=0,t.flipX=!1,t.flipY=!1,t.rotate(0)},getFunctionBody:function(t){return(String(t).match(/function[^{]*\{([\s\S]*)\}/)||{})[1]},isTransparent:function(t,e,i,r){r>0&&(e>r?e-=r:e=0,i>r?i-=r:i=0);var n,s,o=!0,a=t.getImageData(e,i,2*r||1,2*r||1),c=a.data.length;for(n=3;n0?P-=2*f:1===h&&P<0&&(P+=2*f);for(var M=Math.ceil(Math.abs(P/f*2)),F=[],L=P/M,I=8/3*Math.sin(L/4)*Math.sin(L/4)/Math.sin(L/2),R=A+L,B=0;B=n?s-n:2*Math.PI-(n-s)}function r(t,e,i,r,n,s,c,h){var l=a.call(arguments);if(o[l])return o[l];var u,f,d,g,p,v,m,b,_=Math.sqrt,y=Math.min,x=Math.max,C=Math.abs,S=[],w=[[],[]];f=6*t-12*i+6*n,u=-3*t+9*i-9*n+3*c,d=3*i-3*t;for(var T=0;T<2;++T)if(T>0&&(f=6*e-12*r+6*s,u=-3*e+9*r-9*s+3*h,d=3*r-3*e),C(u)<1e-12){if(C(f)<1e-12)continue;0<(g=-d/f)&&g<1&&S.push(g)}else(m=f*f-4*d*u)<0||(0<(p=(-f+(b=_(m)))/(2*u))&&p<1&&S.push(p),0<(v=(-f-b)/(2*u))&&v<1&&S.push(v));for(var O,k,D,E=S.length,j=E;E--;)O=(D=1-(g=S[E]))*D*D*t+3*D*D*g*i+3*D*g*g*n+g*g*g*c,w[0][E]=O,k=D*D*D*e+3*D*D*g*r+3*D*g*g*s+g*g*g*h,w[1][E]=k;w[0][j]=t,w[1][j]=e,w[0][j+1]=c,w[1][j+1]=h;var A=[{x:y.apply(null,w[0]),y:y.apply(null,w[1])},{x:x.apply(null,w[0]),y:x.apply(null,w[1])}];return o[l]=A,A}var n={},s={},o={},a=Array.prototype.join;fabric.util.drawArc=function(e,i,r,n){for(var s=n[0],o=n[1],a=n[2],c=n[3],h=n[4],l=[[],[],[],[]],u=t(n[5]-i,n[6]-r,s,o,c,h,a),f=0,d=u.length;f=e})}}}(),function(){function t(e,i,r){if(r)if(!fabric.isLikelyNode&&i instanceof Element)e=i;else if(i instanceof Array){e=[];for(var n=0,s=i.length;n57343)return t.charAt(e);if(55296<=i&&i<=56319){if(t.length<=e+1)throw"High surrogate without following low surrogate";var r=t.charCodeAt(e+1);if(56320>r||r>57343)throw"High surrogate without following low surrogate";return t.charAt(e)+t.charAt(e+1)}if(0===e)throw"Low surrogate without preceding high surrogate";var n=t.charCodeAt(e-1);if(55296>n||n>56319)throw"Low surrogate without preceding high surrogate";return!1}fabric.util.string={camelize:function(t){return t.replace(/-+(.)?/g,function(t,e){return e?e.toUpperCase():""})},capitalize:function(t,e){return t.charAt(0).toUpperCase()+(e?t.slice(1):t.slice(1).toLowerCase())},escapeXml:function(t){return t.replace(/&/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(//g,">")},graphemeSplit:function(e){var i,r=0,n=[];for(r=0,i;r1?e.apply(this,i.call(arguments,1)):e.call(this):console.log("tried to callSuper "+t+", method not found in prototype chain",this)}var i=Array.prototype.slice,r=function(){},n=function(){for(var t in{toString:1})if("toString"===t)return!1;return!0}(),s=function(t,e,i){for(var r in e)r in t.prototype&&"function"==typeof t.prototype[r]&&(e[r]+"").indexOf("callSuper")>-1?t.prototype[r]=function(t){return function(){var r=this.constructor.superclass;this.constructor.superclass=i;var n=e[t].apply(this,arguments);if(this.constructor.superclass=r,"initialize"!==t)return n}}(r):t.prototype[r]=e[r],n&&(e.toString!==Object.prototype.toString&&(t.prototype.toString=e.toString),e.valueOf!==Object.prototype.valueOf&&(t.prototype.valueOf=e.valueOf))};fabric.util.createClass=function(){function n(){this.initialize.apply(this,arguments)}var o=null,a=i.call(arguments,0);"function"==typeof a[0]&&(o=a.shift()),n.superclass=o,n.subclasses=[],o&&(t.prototype=o.prototype,n.prototype=new t,o.subclasses.push(n));for(var c=0,h=a.length;c=.9999?"":"alpha(opacity="+100*e+")",i.filter=i.filter.replace(r,e)):i.filter+=" alpha(opacity="+100*e+")",t}),fabric.util.setStyle=function(t,e){var i=t.style;if(!i)return t;if("string"==typeof e)return t.style.cssText+=";"+e,e.indexOf("opacity")>-1?n(t,e.match(/opacity:\s*(\d?\.?\d*)/)[1]):t;for(var r in e)"opacity"===r?n(t,e[r]):i["float"===r||"cssFloat"===r?void 0===i.styleFloat?"cssFloat":"styleFloat":r]=e[r];return t}}(),function(){function t(t,e){var i=fabric.document.createElement(t);for(var r in e)"class"===r?i.className=e[r]:"for"===r?i.htmlFor=e[r]:i.setAttribute(r,e[r]);return i}function e(t){for(var e=0,i=0,r=fabric.document.documentElement,n=fabric.document.body||{scrollLeft:0,scrollTop:0};t&&(t.parentNode||t.host)&&((t=t.parentNode||t.host)===fabric.document?(e=n.scrollLeft||r.scrollLeft||0,i=n.scrollTop||r.scrollTop||0):(e+=t.scrollLeft||0,i+=t.scrollTop||0),1!==t.nodeType||"fixed"!==fabric.util.getElementStyle(t,"position")););return{left:e,top:i}}var i,r=Array.prototype.slice,n=function(t){return r.call(t,0)};try{i=n(fabric.document.childNodes)instanceof Array}catch(t){}i||(n=function(t){for(var e=new Array(t.length),i=t.length;i--;)e[i]=t[i];return e});var s;s=fabric.document.defaultView&&fabric.document.defaultView.getComputedStyle?function(t,e){var i=fabric.document.defaultView.getComputedStyle(t,null);return i?i[e]:void 0}:function(t,e){var i=t.style[e];return!i&&t.currentStyle&&(i=t.currentStyle[e]),i},function(){var t=fabric.document.documentElement.style,e="userSelect"in t?"userSelect":"MozUserSelect"in t?"MozUserSelect":"WebkitUserSelect"in t?"WebkitUserSelect":"KhtmlUserSelect"in t?"KhtmlUserSelect":"";fabric.util.makeElementUnselectable=function(t){return void 0!==t.onselectstart&&(t.onselectstart=fabric.util.falseFunction),e?t.style[e]="none":"string"==typeof t.unselectable&&(t.unselectable="on"),t},fabric.util.makeElementSelectable=function(t){return void 0!==t.onselectstart&&(t.onselectstart=null),e?t.style[e]="":"string"==typeof t.unselectable&&(t.unselectable=""),t}}(),function(){fabric.util.getScript=function(t,e){var i=fabric.document.getElementsByTagName("head")[0],r=fabric.document.createElement("script"),n=!0;r.onload=r.onreadystatechange=function(t){if(n){if("string"==typeof this.readyState&&"loaded"!==this.readyState&&"complete"!==this.readyState)return;n=!1,e(t||fabric.window.event),r=r.onload=r.onreadystatechange=null}},r.src=t,i.appendChild(r)}}(),fabric.util.getById=function(t){return"string"==typeof t?fabric.document.getElementById(t):t},fabric.util.toArray=n,fabric.util.makeElement=t,fabric.util.addClass=function(t,e){t&&-1===(" "+t.className+" ").indexOf(" "+e+" ")&&(t.className+=(t.className?" ":"")+e)},fabric.util.wrapElement=function(e,i,r){return"string"==typeof i&&(i=t(i,r)),e.parentNode&&e.parentNode.replaceChild(i,e),i.appendChild(e),i},fabric.util.getScrollLeftTop=e,fabric.util.getElementOffset=function(t){var i,r,n=t&&t.ownerDocument,o={left:0,top:0},a={left:0,top:0},c={borderLeftWidth:"left",borderTopWidth:"top",paddingLeft:"left",paddingTop:"top"};if(!n)return a;for(var h in c)a[c[h]]+=parseInt(s(t,h),10)||0;return i=n.documentElement,void 0!==t.getBoundingClientRect&&(o=t.getBoundingClientRect()),r=e(t),{left:o.left+r.left-(i.clientLeft||0)+a.left,top:o.top+r.top-(i.clientTop||0)+a.top}},fabric.util.getElementStyle=s}(),function(){function t(t,e){return t+(/\?/.test(t)?"&":"?")+e}function e(){}var i=function(){for(var t=[function(){return new ActiveXObject("Microsoft.XMLHTTP")},function(){return new ActiveXObject("Msxml2.XMLHTTP")},function(){return new ActiveXObject("Msxml2.XMLHTTP.3.0")},function(){return new XMLHttpRequest}],e=t.length;e--;)try{if(t[e]())return t[e]}catch(t){}}();fabric.util.request=function(r,n){n||(n={});var s=n.method?n.method.toUpperCase():"GET",o=n.onComplete||function(){},a=i(),c=n.body||n.parameters;return a.onreadystatechange=function(){4===a.readyState&&(o(a),a.onreadystatechange=e)},"GET"===s&&(c=null,"string"==typeof n.parameters&&(r=t(r,n.parameters))),a.open(s,r,!0),"POST"!==s&&"PUT"!==s||a.setRequestHeader("Content-Type","application/x-www-form-urlencoded"),a.send(c),a}}(),fabric.log=function(){},fabric.warn=function(){},"undefined"!=typeof console&&["log","warn"].forEach(function(t){void 0!==console[t]&&"function"==typeof console[t].apply&&(fabric[t]=function(){return console[t].apply(console,arguments)})}),function(){function t(){return!1}function e(){return i.apply(fabric.window,arguments)}var i=fabric.window.requestAnimationFrame||fabric.window.webkitRequestAnimationFrame||fabric.window.mozRequestAnimationFrame||fabric.window.oRequestAnimationFrame||fabric.window.msRequestAnimationFrame||function(t){return fabric.window.setTimeout(t,1e3/60)},r=fabric.window.cancelAnimationFrame||fabric.window.clearTimeout;fabric.util.animate=function(i){e(function(r){i||(i={});var n,s=r||+new Date,o=i.duration||500,a=s+o,c=i.onChange||t,h=i.abort||t,l=i.onComplete||t,u=i.easing||function(t,e,i,r){return-i*Math.cos(t/r*(Math.PI/2))+i+e},f="startValue"in i?i.startValue:0,d="endValue"in i?i.endValue:100,g=i.byValue||d-f;i.onStart&&i.onStart(),function t(r){if(h())l(d,1,1);else{var p=(n=r||+new Date)>a?o:n-s,v=p/o,m=u(p,f,g,o),b=Math.abs((m-f)/g);c(m,b,v),n>a?i.onComplete&&i.onComplete():e(t)}}(s)})},fabric.util.requestAnimFrame=e,fabric.util.cancelAnimFrame=function(){return r.apply(fabric.window,arguments)}}(),function(){function t(t,e,i){var r="rgba("+parseInt(t[0]+i*(e[0]-t[0]),10)+","+parseInt(t[1]+i*(e[1]-t[1]),10)+","+parseInt(t[2]+i*(e[2]-t[2]),10);return r+=","+(t&&e?parseFloat(t[3]+i*(e[3]-t[3])):1),r+=")"}fabric.util.animateColor=function(e,i,r,n){var s=new fabric.Color(e).getSource(),o=new fabric.Color(i).getSource();n=n||{},fabric.util.animate(fabric.util.object.extend(n,{duration:r||500,startValue:s,endValue:o,byValue:o,easing:function(e,i,r,s){return t(i,r,n.colorEasing?n.colorEasing(e,s):1-Math.cos(e/s*(Math.PI/2)))}}))}}(),function(){function t(t,e,i,r){return ta?a:o),1===o&&1===a&&0===c&&0===h&&0===f&&0===d)return _;if((f||d)&&(x=" translate("+y(f)+" "+y(d)+") "),r=x+" matrix("+o+" 0 0 "+a+" "+c*o+" "+h*a+") ","svg"===t.nodeName){for(n=t.ownerDocument.createElement("g");t.firstChild;)n.appendChild(t.firstChild);t.appendChild(n)}else r=(n=t).getAttribute("transform")+r;return n.setAttribute("transform",r),_}function p(t,e){for(;t&&(t=t.parentNode);)if(t.nodeName&&e.test(t.nodeName.replace("svg:",""))&&!t.getAttribute("instantiated_by_use"))return!0;return!1}var v=t.fabric||(t.fabric={}),m=v.util.object.extend,b=v.util.object.clone,_=v.util.toFixed,y=v.util.parseUnit,x=v.util.multiplyTransformMatrices,C=["path","circle","polygon","polyline","ellipse","rect","line","image","text","linearGradient","radialGradient","stop"],S=["symbol","image","marker","pattern","view","svg"],w=["pattern","defs","symbol","metadata","clipPath","mask","desc"],T=["symbol","g","a","svg"],O={cx:"left",x:"left",r:"radius",cy:"top",y:"top",display:"visible",visibility:"visible",transform:"transformMatrix","fill-opacity":"fillOpacity","fill-rule":"fillRule","font-family":"fontFamily","font-size":"fontSize","font-style":"fontStyle","font-weight":"fontWeight","stroke-dasharray":"strokeDashArray","stroke-linecap":"strokeLineCap","stroke-linejoin":"strokeLineJoin","stroke-miterlimit":"strokeMiterLimit","stroke-opacity":"strokeOpacity","stroke-width":"strokeWidth","text-decoration":"textDecoration","text-anchor":"textAnchor",opacity:"opacity"},k={stroke:"strokeOpacity",fill:"fillOpacity"};v.svgValidTagNamesRegEx=r(C),v.svgViewBoxElementsRegEx=r(S),v.svgInvalidAncestorsRegEx=r(w),v.svgValidParentsRegEx=r(T),v.cssRules={},v.gradientDefs={},v.parseTransformAttribute=function(){function t(t,e){var i=Math.cos(e[0]),r=Math.sin(e[0]),n=0,s=0;3===e.length&&(n=e[1],s=e[2]),t[0]=i,t[1]=r,t[2]=-r,t[3]=i,t[4]=n-(i*n-r*s),t[5]=s-(r*n+i*s)}function e(t,e){var i=e[0],r=2===e.length?e[1]:e[0];t[0]=i,t[3]=r}function i(t,e,i){t[i]=Math.tan(v.util.degreesToRadians(e[0]))}function r(t,e){t[4]=e[0],2===e.length&&(t[5]=e[1])}var n=[1,0,0,1,0,0],s=v.reNum,o="(?:\\s+,?\\s*|,\\s*)",a="(?:"+("(?:(matrix)\\s*\\(\\s*("+s+")"+o+"("+s+")"+o+"("+s+")"+o+"("+s+")"+o+"("+s+")"+o+"("+s+")\\s*\\))")+"|"+("(?:(translate)\\s*\\(\\s*("+s+")(?:"+o+"("+s+"))?\\s*\\))")+"|"+("(?:(scale)\\s*\\(\\s*("+s+")(?:"+o+"("+s+"))?\\s*\\))")+"|"+("(?:(rotate)\\s*\\(\\s*("+s+")(?:"+o+"("+s+")"+o+"("+s+"))?\\s*\\))")+"|"+("(?:(skewX)\\s*\\(\\s*("+s+")\\s*\\))")+"|"+("(?:(skewY)\\s*\\(\\s*("+s+")\\s*\\))")+")",c="^\\s*(?:"+("(?:"+a+"(?:"+o+"*"+a+")*)")+"?)\\s*$",h=new RegExp(c),l=new RegExp(a,"g");return function(s){var o=n.concat(),c=[];if(!s||s&&!h.test(s))return o;s.replace(l,function(s){var h=new RegExp(a).exec(s).filter(function(t){return!!t}),l=h[1],u=h.slice(2).map(parseFloat);switch(l){case"translate":r(o,u);break;case"rotate":u[0]=v.util.degreesToRadians(u[0]),t(o,u);break;case"scale":e(o,u);break;case"skewX":i(o,u,2);break;case"skewY":i(o,u,1);break;case"matrix":o=u}c.push(o.concat()),o=n.concat()});for(var u=c[0];c.length>1;)c.shift(),u=v.util.multiplyTransformMatrices(u,c[0]);return u}}();var D=new RegExp("^\\s*("+v.reNum+"+)\\s*,?\\s*("+v.reNum+"+)\\s*,?\\s*("+v.reNum+"+)\\s*,?\\s*("+v.reNum+"+)\\s*$");v.parseSVGDocument=function(t,e,i,r){if(t){d(t);var n,s,o=v.Object.__uid++,a=g(t),c=v.util.toArray(t.getElementsByTagName("*"));if(a.crossOrigin=r&&r.crossOrigin,a.svgUid=o,0===c.length&&v.isLikelyNode){var h=[];for(n=0,s=(c=t.selectNodes('//*[name(.)!="svg"]')).length;n/i,""))),n&&n.documentElement||e&&e(null),v.parseSVGDocument(n.documentElement,function(t,i,r,n){e&&e(t,i,r,n)},i,r)}})},loadSVGFromString:function(t,e,i,r){t=t.trim();var n;if("undefined"!=typeof DOMParser){var s=new DOMParser;s&&s.parseFromString&&(n=s.parseFromString(t,"text/xml"))}else v.window.ActiveXObject&&((n=new ActiveXObject("Microsoft.XMLDOM")).async="false",n.loadXML(t.replace(//i,"")));v.parseSVGDocument(n.documentElement,function(t,i,r,n){e(t,i,r,n)},i,r)}})}("undefined"!=typeof exports?exports:this),fabric.ElementsParser=function(t,e,i,r,n){this.elements=t,this.callback=e,this.options=i,this.reviver=r,this.svgUid=i&&i.svgUid||0,this.parsingOptions=n},fabric.ElementsParser.prototype.parse=function(){this.instances=new Array(this.elements.length),this.numElements=this.elements.length,this.createObjects()},fabric.ElementsParser.prototype.createObjects=function(){for(var t=0,e=this.elements.length;tt.x&&this.y>t.y},gte:function(t){return this.x>=t.x&&this.y>=t.y},lerp:function(t,i){return void 0===i&&(i=.5),i=Math.max(Math.min(1,i),0),new e(this.x+(t.x-this.x)*i,this.y+(t.y-this.y)*i)},distanceFrom:function(t){var e=this.x-t.x,i=this.y-t.y;return Math.sqrt(e*e+i*i)},midPointFrom:function(t){return this.lerp(t)},min:function(t){return new e(Math.min(this.x,t.x),Math.min(this.y,t.y))},max:function(t){return new e(Math.max(this.x,t.x),Math.max(this.y,t.y))},toString:function(){return this.x+","+this.y},setXY:function(t,e){return this.x=t,this.y=e,this},setX:function(t){return this.x=t,this},setY:function(t){return this.y=t,this},setFromPoint:function(t){return this.x=t.x,this.y=t.y,this},swap:function(t){var e=this.x,i=this.y;this.x=t.x,this.y=t.y,t.x=e,t.y=i},clone:function(){return new e(this.x,this.y)}})}("undefined"!=typeof exports?exports:this),function(t){"use strict";function e(t){this.status=t,this.points=[]}var i=t.fabric||(t.fabric={});i.Intersection?i.warn("fabric.Intersection is already defined"):(i.Intersection=e,i.Intersection.prototype={constructor:e,appendPoint:function(t){return this.points.push(t),this},appendPoints:function(t){return this.points=this.points.concat(t),this}},i.Intersection.intersectLineLine=function(t,r,n,s){var o,a=(s.x-n.x)*(t.y-n.y)-(s.y-n.y)*(t.x-n.x),c=(r.x-t.x)*(t.y-n.y)-(r.y-t.y)*(t.x-n.x),h=(s.y-n.y)*(r.x-t.x)-(s.x-n.x)*(r.y-t.y);if(0!==h){var l=a/h,u=c/h;0<=l&&l<=1&&0<=u&&u<=1?(o=new e("Intersection")).appendPoint(new i.Point(t.x+l*(r.x-t.x),t.y+l*(r.y-t.y))):o=new e}else o=new e(0===a||0===c?"Coincident":"Parallel");return o},i.Intersection.intersectLinePolygon=function(t,i,r){var n,s,o,a,c=new e,h=r.length;for(a=0;a0&&(c.status="Intersection"),c},i.Intersection.intersectPolygonPolygon=function(t,i){var r,n=new e,s=t.length;for(r=0;r0&&(n.status="Intersection"),n},i.Intersection.intersectPolygonRectangle=function(t,r,n){var s=r.min(n),o=r.max(n),a=new i.Point(o.x,s.y),c=new i.Point(s.x,o.y),h=e.intersectLinePolygon(s,a,t),l=e.intersectLinePolygon(a,o,t),u=e.intersectLinePolygon(o,c,t),f=e.intersectLinePolygon(c,s,t),d=new e;return d.appendPoints(h.points),d.appendPoints(l.points),d.appendPoints(u.points),d.appendPoints(f.points),d.points.length>0&&(d.status="Intersection"),d})}("undefined"!=typeof exports?exports:this),function(t){"use strict";function e(t){t?this._tryParsingColor(t):this.setSource([0,0,0,1])}function i(t,e,i){return i<0&&(i+=1),i>1&&(i-=1),i<1/6?t+6*(e-t)*i:i<.5?e:i<2/3?t+(e-t)*(2/3-i)*6:t}var r=t.fabric||(t.fabric={});r.Color?r.warn("fabric.Color is already defined."):(r.Color=e,r.Color.prototype={_tryParsingColor:function(t){var i;t in e.colorNameMap&&(t=e.colorNameMap[t]),"transparent"===t&&(i=[255,255,255,0]),i||(i=e.sourceFromHex(t)),i||(i=e.sourceFromRgb(t)),i||(i=e.sourceFromHsl(t)),i||(i=[0,0,0,1]),i&&this.setSource(i)},_rgbToHsl:function(t,e,i){t/=255,e/=255,i/=255;var n,s,o,a=r.util.array.max([t,e,i]),c=r.util.array.min([t,e,i]);if(o=(a+c)/2,a===c)n=s=0;else{var h=a-c;switch(s=o>.5?h/(2-a-c):h/(a+c),a){case t:n=(e-i)/h+(e1?1:o,s){var a=s.split(/\s*;\s*/);for(""===a[a.length-1]&&a.pop(),n=a.length;n--;){var c=a[n].split(/\s*:\s*/),h=c[0].trim(),l=c[1].trim();"stop-color"===h?e=l:"stop-opacity"===h&&(r=l)}}return e||(e=t.getAttribute("stop-color")||"rgb(0,0,0)"),r||(r=t.getAttribute("stop-opacity")),e=new fabric.Color(e),i=e.getAlpha(),r=isNaN(parseFloat(r))?1:parseFloat(r),r*=i,{offset:o,color:e.toRgb(),opacity:r}}function e(t){return{x1:t.getAttribute("x1")||0,y1:t.getAttribute("y1")||0,x2:t.getAttribute("x2")||"100%",y2:t.getAttribute("y2")||0}}function i(t){return{x1:t.getAttribute("fx")||t.getAttribute("cx")||"50%",y1:t.getAttribute("fy")||t.getAttribute("cy")||"50%",r1:0,x2:t.getAttribute("cx")||"50%",y2:t.getAttribute("cy")||"50%",r2:t.getAttribute("r")||"50%"}}function r(t,e,i){var r,n=0,s=1,o="";for(var a in e)"Infinity"===e[a]?e[a]=1:"-Infinity"===e[a]&&(e[a]=0),r=parseFloat(e[a],10),s="string"==typeof e[a]&&/^\d+%$/.test(e[a])?.01:1,"x1"===a||"x2"===a||"r2"===a?(s*="objectBoundingBox"===i?t.width:1,n="objectBoundingBox"===i?t.left||0:0):"y1"!==a&&"y2"!==a||(s*="objectBoundingBox"===i?t.height:1,n="objectBoundingBox"===i?t.top||0:0),e[a]=r*s+n;if("ellipse"===t.type&&null!==e.r2&&"objectBoundingBox"===i&&t.rx!==t.ry){var c=t.ry/t.rx;o=" scale(1, "+c+")",e.y1&&(e.y1/=c),e.y2&&(e.y2/=c)}return o}var n=fabric.util.object.clone;fabric.Gradient=fabric.util.createClass({offsetX:0,offsetY:0,initialize:function(t){t||(t={});var e={};this.id=fabric.Object.__uid++,this.type=t.type||"linear",e={x1:t.coords.x1||0,y1:t.coords.y1||0,x2:t.coords.x2||0,y2:t.coords.y2||0},"radial"===this.type&&(e.r1=t.coords.r1||0,e.r2=t.coords.r2||0),this.coords=e,this.colorStops=t.colorStops.slice(),t.gradientTransform&&(this.gradientTransform=t.gradientTransform),this.offsetX=t.offsetX||this.offsetX,this.offsetY=t.offsetY||this.offsetY},addColorStop:function(t){for(var e in t){var i=new fabric.Color(t[e]);this.colorStops.push({offset:parseFloat(e),color:i.toRgb(),opacity:i.getAlpha()})}return this},toObject:function(t){var e={type:this.type,coords:this.coords,colorStops:this.colorStops,offsetX:this.offsetX,offsetY:this.offsetY,gradientTransform:this.gradientTransform?this.gradientTransform.concat():this.gradientTransform};return fabric.util.populateWithProperties(this,e,t),e},toSVG:function(t){var e,i,r,s,o=n(this.coords,!0),a=n(this.colorStops,!0),c=o.r1>o.r2,h=t.width/2,l=t.height/2;a.sort(function(t,e){return t.offset-e.offset}),"path"===t.type&&(h-=t.pathOffset.x,l-=t.pathOffset.y);for(var u in o)"x1"===u||"x2"===u?o[u]+=this.offsetX-h:"y1"!==u&&"y2"!==u||(o[u]+=this.offsetY-l);if(s='id="SVGID_'+this.id+'" gradientUnits="userSpaceOnUse"',this.gradientTransform&&(s+=' gradientTransform="matrix('+this.gradientTransform.join(" ")+')" '),"linear"===this.type?r=["\n']:"radial"===this.type&&(r=["\n']),"radial"===this.type){if(c)for((a=a.concat()).reverse(),e=0,i=a.length;e0){var d=f/Math.max(o.r1,o.r2);for(e=0,i=a.length;e\n')}return r.push("linear"===this.type?"\n":"\n"),r.join("")},toLive:function(t){var e,i,r,n=fabric.util.object.clone(this.coords);if(this.type){for("linear"===this.type?e=t.createLinearGradient(n.x1,n.y1,n.x2,n.y2):"radial"===this.type&&(e=t.createRadialGradient(n.x1,n.y1,n.r1,n.x2,n.y2,n.r2)),i=0,r=this.colorStops.length;i\n\n\n'},setOptions:function(t){for(var e in t)this[e]=t[e]},toLive:function(t){var e="function"==typeof this.source?this.source():this.source;if(!e)return"";if(void 0!==e.src){if(!e.complete)return"";if(0===e.naturalWidth||0===e.naturalHeight)return""}return t.createPattern(e,this.repeat)}})}(),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=e.util.toFixed;e.Shadow?e.warn("fabric.Shadow is already defined."):(e.Shadow=e.util.createClass({color:"rgb(0,0,0)",blur:0,offsetX:0,offsetY:0,affectStroke:!1,includeDefaultValues:!0,initialize:function(t){"string"==typeof t&&(t=this._parseShadow(t));for(var i in t)this[i]=t[i];this.id=e.Object.__uid++},_parseShadow:function(t){var i=t.trim(),r=e.Shadow.reOffsetsAndBlur.exec(i)||[];return{color:(i.replace(e.Shadow.reOffsetsAndBlur,"")||"rgb(0,0,0)").trim(),offsetX:parseInt(r[1],10)||0,offsetY:parseInt(r[2],10)||0,blur:parseInt(r[3],10)||0}},toString:function(){return[this.offsetX,this.offsetY,this.blur,this.color].join("px ")},toSVG:function(t){var r=40,n=40,s=e.Object.NUM_FRACTION_DIGITS,o=e.util.rotateVector({x:this.offsetX,y:this.offsetY},e.util.degreesToRadians(-t.angle));return t.width&&t.height&&(r=100*i((Math.abs(o.x)+this.blur)/t.width,s)+20,n=100*i((Math.abs(o.y)+this.blur)/t.height,s)+20),t.flipX&&(o.x*=-1),t.flipY&&(o.y*=-1),'\n\t\n\t\n\t\n\t\n\t\n\t\t\n\t\t\n\t\n\n'},toObject:function(){if(this.includeDefaultValues)return{color:this.color,blur:this.blur,offsetX:this.offsetX,offsetY:this.offsetY,affectStroke:this.affectStroke};var t={},i=e.Shadow.prototype;return["color","blur","offsetX","offsetY","affectStroke"].forEach(function(e){this[e]!==i[e]&&(t[e]=this[e])},this),t}}),e.Shadow.reOffsetsAndBlur=/(?:\s|^)(-?\d+(?:px)?(?:\s?|$))?(-?\d+(?:px)?(?:\s?|$))?(\d+(?:px)?)?(?:\s?|$)(?:$|\s)/)}("undefined"!=typeof exports?exports:this),function(){"use strict";if(fabric.StaticCanvas)fabric.warn("fabric.StaticCanvas is already defined.");else{var t=fabric.util.object.extend,e=fabric.util.getElementOffset,i=fabric.util.removeFromArray,r=fabric.util.toFixed,n=fabric.util.transformPoint,s=fabric.util.invertTransform,o=new Error("Could not initialize `canvas` element");fabric.StaticCanvas=fabric.util.createClass(fabric.CommonMethods,{initialize:function(t,e){e||(e={}),this.renderAndResetBound=this.renderAndReset.bind(this),this.requestRenderAllBound=this.requestRenderAll.bind(this),this._initStatic(t,e)},backgroundColor:"",backgroundImage:null,overlayColor:"",overlayImage:null,includeDefaultValues:!0,stateful:!1,renderOnAddRemove:!0,clipTo:null,controlsAboveOverlay:!1,allowTouchScrolling:!1,imageSmoothingEnabled:!0,viewportTransform:fabric.iMatrix.concat(),backgroundVpt:!0,overlayVpt:!0,onBeforeScaleRotate:function(){},enableRetinaScaling:!0,vptCoords:{},skipOffscreen:!0,_initStatic:function(t,e){var i=this.requestRenderAllBound;this._objects=[],this._createLowerCanvas(t),this._initOptions(e),this._setImageSmoothing(),this.interactive||this._initRetinaScaling(),e.overlayImage&&this.setOverlayImage(e.overlayImage,i),e.backgroundImage&&this.setBackgroundImage(e.backgroundImage,i),e.backgroundColor&&this.setBackgroundColor(e.backgroundColor,i),e.overlayColor&&this.setOverlayColor(e.overlayColor,i),this.calcOffset()},_isRetinaScaling:function(){return 1!==fabric.devicePixelRatio&&this.enableRetinaScaling},getRetinaScaling:function(){return this._isRetinaScaling()?fabric.devicePixelRatio:1},_initRetinaScaling:function(){this._isRetinaScaling()&&(this.lowerCanvasEl.setAttribute("width",this.width*fabric.devicePixelRatio),this.lowerCanvasEl.setAttribute("height",this.height*fabric.devicePixelRatio),this.contextContainer.scale(fabric.devicePixelRatio,fabric.devicePixelRatio))},calcOffset:function(){return this._offset=e(this.lowerCanvasEl),this},setOverlayImage:function(t,e,i){return this.__setBgOverlayImage("overlayImage",t,e,i)},setBackgroundImage:function(t,e,i){return this.__setBgOverlayImage("backgroundImage",t,e,i)},setOverlayColor:function(t,e){return this.__setBgOverlayColor("overlayColor",t,e)},setBackgroundColor:function(t,e){return this.__setBgOverlayColor("backgroundColor",t,e)},_setImageSmoothing:function(){var t=this.getContext();t.imageSmoothingEnabled=t.imageSmoothingEnabled||t.webkitImageSmoothingEnabled||t.mozImageSmoothingEnabled||t.msImageSmoothingEnabled||t.oImageSmoothingEnabled,t.imageSmoothingEnabled=this.imageSmoothingEnabled},__setBgOverlayImage:function(t,e,i,r){return"string"==typeof e?fabric.util.loadImage(e,function(e){e&&(this[t]=new fabric.Image(e,r)),i&&i(e)},this,r&&r.crossOrigin):(r&&e.setOptions(r),this[t]=e,i&&i(e)),this},__setBgOverlayColor:function(t,e,i){return this[t]=e,this._initGradient(e,t),this._initPattern(e,t,i),this},_createCanvasElement:function(){var t=fabric.util.createCanvasElement();if(!t)throw o;if(t.style||(t.style={}),void 0===t.getContext)throw o;return t},_initOptions:function(t){this._setOptions(t),this.width=this.width||parseInt(this.lowerCanvasEl.width,10)||0,this.height=this.height||parseInt(this.lowerCanvasEl.height,10)||0,this.lowerCanvasEl.style&&(this.lowerCanvasEl.width=this.width,this.lowerCanvasEl.height=this.height,this.lowerCanvasEl.style.width=this.width+"px",this.lowerCanvasEl.style.height=this.height+"px",this.viewportTransform=this.viewportTransform.slice())},_createLowerCanvas:function(t){t&&t.getContext?this.lowerCanvasEl=t:this.lowerCanvasEl=fabric.util.getById(t)||this._createCanvasElement(),fabric.util.addClass(this.lowerCanvasEl,"lower-canvas"),this.interactive&&this._applyCanvasStyle(this.lowerCanvasEl),this.contextContainer=this.lowerCanvasEl.getContext("2d")},getWidth:function(){return this.width},getHeight:function(){return this.height},setWidth:function(t,e){return this.setDimensions({width:t},e)},setHeight:function(t,e){return this.setDimensions({height:t},e)},setDimensions:function(t,e){var i;e=e||{};for(var r in t)i=t[r],e.cssOnly||(this._setBackstoreDimension(r,t[r]),i+="px"),e.backstoreOnly||this._setCssDimension(r,i);return this._initRetinaScaling(),this._setImageSmoothing(),this.calcOffset(),e.cssOnly||this.requestRenderAll(),this},_setBackstoreDimension:function(t,e){return this.lowerCanvasEl[t]=e,this.upperCanvasEl&&(this.upperCanvasEl[t]=e),this.cacheCanvasEl&&(this.cacheCanvasEl[t]=e),this[t]=e,this},_setCssDimension:function(t,e){return this.lowerCanvasEl.style[t]=e,this.upperCanvasEl&&(this.upperCanvasEl.style[t]=e),this.wrapperEl&&(this.wrapperEl.style[t]=e),this},getZoom:function(){return this.viewportTransform[0]},setViewportTransform:function(t){var e,i,r,n=this._activeObject;for(this.viewportTransform=t,i=0,r=this._objects.length;i"),i.join("")},_setSVGPreamble:function(t,e){e.suppressPreamble||t.push('\n','\n')},_setSVGHeader:function(t,e){var i,n=e.width||this.width,s=e.height||this.height,o='viewBox="0 0 '+this.width+" "+this.height+'" ',a=fabric.Object.NUM_FRACTION_DIGITS;e.viewBox?o='viewBox="'+e.viewBox.x+" "+e.viewBox.y+" "+e.viewBox.width+" "+e.viewBox.height+'" ':this.svgViewportTransformation&&(i=this.viewportTransform,o='viewBox="'+r(-i[4]/i[0],a)+" "+r(-i[5]/i[3],a)+" "+r(this.width/i[0],a)+" "+r(this.height/i[3],a)+'" '),t.push("\n',"Created with Fabric.js ",fabric.version,"\n","\n",this.createSVGFontFacesMarkup(),this.createSVGRefElementsMarkup(),"\n")},createSVGRefElementsMarkup:function(){var t=this;return["backgroundColor","overlayColor"].map(function(e){var i=t[e];if(i&&i.toLive)return i.toSVG(t,!1)}).join("")},createSVGFontFacesMarkup:function(){var t,e,i,r,n,s,o,a,c="",h={},l=fabric.fontPaths,u=this.getObjects();for(o=0,a=u.length;o',"\n",c,"","\n"].join("")),c},_setSVGObjects:function(t,e){var i,r,n,s=this.getObjects();for(r=0,n=s.length;r\n")}else t.push('\n")},sendToBack:function(t){if(!t)return this;var e,r,n,s=this._activeObject;if(t===s&&"activeSelection"===t.type)for(e=(n=s._objects).length;e--;)r=n[e],i(this._objects,r),this._objects.unshift(r);else i(this._objects,t),this._objects.unshift(t);return this.renderOnAddRemove&&this.requestRenderAll(),this},bringToFront:function(t){if(!t)return this;var e,r,n,s=this._activeObject;if(t===s&&"activeSelection"===t.type)for(n=s._objects,e=0;e0+h&&(o=s-1,i(this._objects,n),this._objects.splice(o,0,n)),h++;else 0!==(s=this._objects.indexOf(t))&&(o=this._findNewLowerIndex(t,s,e),i(this._objects,t),this._objects.splice(o,0,t));return this.renderOnAddRemove&&this.requestRenderAll(),this},_findNewLowerIndex:function(t,e,i){var r,n;if(i){for(r=e,n=e-1;n>=0;--n)if(t.intersectsWithObject(this._objects[n])||t.isContainedWithinObject(this._objects[n])||this._objects[n].isContainedWithinObject(t)){r=n;break}}else r=e-1;return r},bringForward:function(t,e){if(!t)return this;var r,n,s,o,a,c=this._activeObject,h=0;if(t===c&&"activeSelection"===t.type)for(r=(a=c._objects).length;r--;)n=a[r],(s=this._objects.indexOf(n))"}}),t(fabric.StaticCanvas.prototype,fabric.Observable),t(fabric.StaticCanvas.prototype,fabric.Collection),t(fabric.StaticCanvas.prototype,fabric.DataURLExporter),t(fabric.StaticCanvas,{EMPTY_JSON:'{"objects": [], "background": "white"}',supports:function(t){var e=fabric.util.createCanvasElement();if(!e||!e.getContext)return null;var i=e.getContext("2d");if(!i)return null;switch(t){case"getImageData":return void 0!==i.getImageData;case"setLineDash":return void 0!==i.setLineDash;case"toDataURL":return void 0!==e.toDataURL;case"toDataURLWithQuality":try{return e.toDataURL("image/jpeg",0),!0}catch(t){}return!1;default:return null}}}),fabric.StaticCanvas.prototype.toJSON=fabric.StaticCanvas.prototype.toObject}}(),fabric.BaseBrush=fabric.util.createClass({color:"rgb(0, 0, 0)",width:1,shadow:null,strokeLineCap:"round",strokeLineJoin:"round",strokeDashArray:null,setShadow:function(t){return this.shadow=new fabric.Shadow(t),this},_setBrushStyles:function(){var t=this.canvas.contextTop;t.strokeStyle=this.color,t.lineWidth=this.width,t.lineCap=this.strokeLineCap,t.lineJoin=this.strokeLineJoin,this.strokeDashArray&&fabric.StaticCanvas.supports("setLineDash")&&t.setLineDash(this.strokeDashArray)},_setShadow:function(){if(this.shadow){var t=this.canvas.contextTop,e=this.canvas.getZoom();t.shadowColor=this.shadow.color,t.shadowBlur=this.shadow.blur*e,t.shadowOffsetX=this.shadow.offsetX*e,t.shadowOffsetY=this.shadow.offsetY*e}},_resetShadow:function(){var t=this.canvas.contextTop;t.shadowColor="",t.shadowBlur=t.shadowOffsetX=t.shadowOffsetY=0}}),fabric.PencilBrush=fabric.util.createClass(fabric.BaseBrush,{initialize:function(t){this.canvas=t,this._points=[]},onMouseDown:function(t){this._prepareForDrawing(t),this._captureDrawingPath(t),this._render()},onMouseMove:function(t){this._captureDrawingPath(t),this.canvas.clearContext(this.canvas.contextTop),this._render()},onMouseUp:function(){this._finalizeAndAddPath()},_prepareForDrawing:function(t){var e=new fabric.Point(t.x,t.y);this._reset(),this._addPoint(e),this.canvas.contextTop.moveTo(e.x,e.y)},_addPoint:function(t){this._points.push(t)},_reset:function(){this._points.length=0,this._setBrushStyles(),this._setShadow()},_captureDrawingPath:function(t){var e=new fabric.Point(t.x,t.y);this._addPoint(e)},_render:function(){var t,e,i=this.canvas.contextTop,r=this.canvas.viewportTransform,n=this._points[0],s=this._points[1];if(i.save(),i.transform(r[0],r[1],r[2],r[3],r[4],r[5]),i.beginPath(),2===this._points.length&&n.x===s.x&&n.y===s.y){var o=this.width/1e3;n=new fabric.Point(n.x,n.y),s=new fabric.Point(s.x,s.y),n.x-=o,s.x+=o}for(i.moveTo(n.x,n.y),t=1,e=this._points.length;t0&&!this.preserveObjectStacking){e=[],i=[];for(var n=0,s=this._objects.length;n1&&(this._activeObject._objects=i),e.push.apply(e,i)}else e=this._objects;return e},renderAll:function(){!this.contextTopDirty||this._groupSelector||this.isDrawingMode||(this.clearContext(this.contextTop),this.contextTopDirty=!1);var t=this.contextContainer;return this.renderCanvas(t,this._chooseObjectsToRender()),this},renderTop:function(){var t=this.contextTop;return this.clearContext(t),this.selection&&this._groupSelector&&this._drawSelection(t),this.fire("after:render"),this.contextTopDirty=!0,this},_resetCurrentTransform:function(){var t=this._currentTransform;t.target.set({scaleX:t.original.scaleX,scaleY:t.original.scaleY,skewX:t.original.skewX,skewY:t.original.skewY,left:t.original.left,top:t.original.top}),this._shouldCenterTransform(t.target)?"rotate"===t.action?this._setOriginToCenter(t.target):("center"!==t.originX&&("right"===t.originX?t.mouseXSign=-1:t.mouseXSign=1),"center"!==t.originY&&("bottom"===t.originY?t.mouseYSign=-1:t.mouseYSign=1),t.originX="center",t.originY="center"):(t.originX=t.original.originX,t.originY=t.original.originY)},containsPoint:function(t,e,i){var r,n=i||this.getPointer(t,!0);return r=e.group&&e.group===this._activeObject&&"activeSelection"===e.group.type?this._normalizePointer(e.group,n):{x:n.x,y:n.y},e.containsPoint(r)||e._findTargetCorner(n)},_normalizePointer:function(t,e){var i=t.calcTransformMatrix(),r=fabric.util.invertTransform(i),n=this.restorePointerVpt(e);return fabric.util.transformPoint(n,r)},isTargetTransparent:function(t,e,i){var r=this.contextCache,n=t.selectionBackgroundColor;t.hasBorders=t.transparentCorners=!1,t.selectionBackgroundColor="",r.save(),r.transform.apply(r,this.viewportTransform),t.render(r),r.restore(),t===this._activeObject&&t._renderControls(r,{hasBorders:!1,transparentCorners:!1}),t.selectionBackgroundColor=n;var s=fabric.util.isTransparent(r,e,i,this.targetFindTolerance);return this.clearContext(r),s},_shouldClearSelection:function(t,e){var i=this.getActiveObjects(),r=this._activeObject;return!e||e&&r&&i.length>1&&-1===i.indexOf(e)&&r!==e&&!t[this.selectionKey]||e&&!e.evented||e&&!e.selectable&&r&&r!==e},_shouldCenterTransform:function(t){if(t){var e,i=this._currentTransform;return"scale"===i.action||"scaleX"===i.action||"scaleY"===i.action?e=this.centeredScaling||t.centeredScaling:"rotate"===i.action&&(e=this.centeredRotation||t.centeredRotation),e?!i.altKey:i.altKey}},_getOriginFromCorner:function(t,e){var i={x:t.originX,y:t.originY};return"ml"===e||"tl"===e||"bl"===e?i.x="right":"mr"!==e&&"tr"!==e&&"br"!==e||(i.x="left"),"tl"===e||"mt"===e||"tr"===e?i.y="bottom":"bl"!==e&&"mb"!==e&&"br"!==e||(i.y="top"),i},_getActionFromCorner:function(t,e,i){if(!e)return"drag";switch(e){case"mtr":return"rotate";case"ml":case"mr":return i[this.altActionKey]?"skewY":"scaleX";case"mt":case"mb":return i[this.altActionKey]?"skewX":"scaleY";default:return"scale"}},_setupCurrentTransform:function(t,i){if(i){var r=this.getPointer(t),n=i._findTargetCorner(this.getPointer(t,!0)),s=this._getActionFromCorner(i,n,t),o=this._getOriginFromCorner(i,n);this._currentTransform={target:i,action:s,corner:n,scaleX:i.scaleX,scaleY:i.scaleY,skewX:i.skewX,skewY:i.skewY,offsetX:r.x-i.left,offsetY:r.y-i.top,originX:o.x,originY:o.y,ex:r.x,ey:r.y,lastX:r.x,lastY:r.y,left:i.left,top:i.top,theta:e(i.angle),width:i.width*i.scaleX,mouseXSign:1,mouseYSign:1,shiftKey:t.shiftKey,altKey:t[this.centeredKey]},this._currentTransform.original={left:i.left,top:i.top,scaleX:i.scaleX,scaleY:i.scaleY,skewX:i.skewX,skewY:i.skewY,originX:o.x,originY:o.y},this._resetCurrentTransform()}},_translateObject:function(t,e){var i=this._currentTransform,r=i.target,n=t-i.offsetX,s=e-i.offsetY,o=!r.get("lockMovementX")&&r.left!==n,a=!r.get("lockMovementY")&&r.top!==s;return o&&r.set("left",n),a&&r.set("top",s),o||a},_changeSkewTransformOrigin:function(t,e,i){var r="originX",n={0:"center"},s=e.target.skewX,o="left",a="right",c="mt"===e.corner||"ml"===e.corner?1:-1,h=1;t=t>0?1:-1,"y"===i&&(s=e.target.skewY,o="top",a="bottom",r="originY"),n[-1]=o,n[1]=a,e.target.flipX&&(h*=-1),e.target.flipY&&(h*=-1),0===s?(e.skewSign=-c*t*h,e[r]=n[-t]):(s=s>0?1:-1,e.skewSign=s,e[r]=n[s*c*h])},_skewObject:function(t,e,i){var r=this._currentTransform,n=r.target,s=!1,o=n.get("lockSkewingX"),a=n.get("lockSkewingY");if(o&&"x"===i||a&&"y"===i)return!1;var c,h,l=n.getCenterPoint(),u=n.toLocalPoint(new fabric.Point(t,e),"center","center")[i],f=n.toLocalPoint(new fabric.Point(r.lastX,r.lastY),"center","center")[i],d=n._getTransformedDimensions();return this._changeSkewTransformOrigin(u-f,r,i),c=n.toLocalPoint(new fabric.Point(t,e),r.originX,r.originY)[i],h=n.translateToOriginPoint(l,r.originX,r.originY),s=this._setObjectSkew(c,r,i,d),r.lastX=t,r.lastY=e,n.setPositionByOrigin(h,r.originX,r.originY),s},_setObjectSkew:function(t,e,i,r){var n,s,o,a,c,h,l,u,f,d=e.target,g=!1,p=e.skewSign;return"x"===i?(a="y",c="Y",h="X",u=0,f=d.skewY):(a="x",c="X",h="Y",u=d.skewX,f=0),o=d._getTransformedDimensions(u,f),(l=2*Math.abs(t)-o[i])<=2?n=0:(n=p*Math.atan(l/d["scale"+h]/(o[a]/d["scale"+c])),n=fabric.util.radiansToDegrees(n)),g=d["skew"+h]!==n,d.set("skew"+h,n),0!==d["skew"+c]&&(s=d._getTransformedDimensions(),n=r[a]/s[a]*d["scale"+c],d.set("scale"+c,n)),g},_scaleObject:function(t,e,i){var r=this._currentTransform,n=r.target,s=n.get("lockScalingX"),o=n.get("lockScalingY"),a=n.get("lockScalingFlip");if(s&&o)return!1;var c=n.translateToOriginPoint(n.getCenterPoint(),r.originX,r.originY),h=n.toLocalPoint(new fabric.Point(t,e),r.originX,r.originY),l=n._getTransformedDimensions(),u=!1;return this._setLocalMouse(h,r),u=this._setObjectScale(h,r,s,o,i,a,l),n.setPositionByOrigin(c,r.originX,r.originY),u},_setObjectScale:function(t,e,i,r,n,s,o){var a,c,h,l,u=e.target,f=!1,d=!1,g=!1;return h=t.x*u.scaleX/o.x,l=t.y*u.scaleY/o.y,a=u.scaleX!==h,c=u.scaleY!==l,s&&h<=0&&hs?t.x<0?t.x+=s:t.x-=s:t.x=0,n(t.y)>s?t.y<0?t.y+=s:t.y-=s:t.y=0},_rotateObject:function(t,e){var n=this._currentTransform;if(n.target.get("lockRotation"))return!1;var s=r(n.ey-n.top,n.ex-n.left),o=r(e-n.top,t-n.left),a=i(o-s+n.theta),c=!0;if(n.target.snapAngle>0){var h=n.target.snapAngle,l=n.target.snapThreshold||h,u=Math.ceil(a/h)*h,f=Math.floor(a/h)*h;Math.abs(a-f)0?0:-i),e.ey-(r>0?0:-r),o,a)),this.selectionLineWidth&&this.selectionBorderColor)if(t.lineWidth=this.selectionLineWidth,t.strokeStyle=this.selectionBorderColor,this.selectionDashArray.length>1&&!s){var c=e.ex+.5-(i>0?0:o),h=e.ey+.5-(r>0?0:a);t.beginPath(),fabric.util.drawDashedLine(t,c,h,c+o,h,this.selectionDashArray),fabric.util.drawDashedLine(t,c,h+a-1,c+o,h+a-1,this.selectionDashArray),fabric.util.drawDashedLine(t,c,h,c,h+a,this.selectionDashArray),fabric.util.drawDashedLine(t,c+o-1,h,c+o-1,h+a,this.selectionDashArray),t.closePath(),t.stroke()}else fabric.Object.prototype._setLineDash.call(this,t,this.selectionDashArray),t.strokeRect(e.ex+.5-(i>0?0:o),e.ey+.5-(r>0?0:a),o,a)},findTarget:function(t,e){if(!this.skipTargetFind){var i,r,n=this.getPointer(t,!0),s=this._activeObject,o=this.getActiveObjects();if(this.targets=[],o.length>1&&!e&&s===this._searchPossibleTargets([s],n))return s;if(1===o.length&&s._findTargetCorner(n))return s;if(1===o.length&&s===this._searchPossibleTargets([s],n)){if(!this.preserveObjectStacking)return s;i=s,r=this.targets,this.targets=[]}var a=this._searchPossibleTargets(this._objects,n);return t[this.altSelectionKey]&&a&&i&&a!==i&&(a=i,this.targets=r),a}},_checkTarget:function(t,e){if(e&&e.visible&&e.evented&&this.containsPoint(null,e,t)){if(!this.perPixelTargetFind&&!e.perPixelTargetFind||e.isEditing)return!0;if(!this.isTargetTransparent(e,t.x,t.y))return!0}},_searchPossibleTargets:function(t,e){for(var i,r,n,s=t.length;s--;)if(this._checkTarget(e,t[s])){"group"===(i=t[s]).type&&i.subTargetCheck&&(r=this._normalizePointer(i,e),(n=this._searchPossibleTargets(i._objects,r))&&this.targets.push(n));break}return i},restorePointerVpt:function(t){return fabric.util.transformPoint(t,fabric.util.invertTransform(this.viewportTransform))},getPointer:function(e,i,r){r||(r=this.upperCanvasEl);var n,s=t(e),o=r.getBoundingClientRect(),a=o.width||0,c=o.height||0;return a&&c||("top"in o&&"bottom"in o&&(c=Math.abs(o.top-o.bottom)),"right"in o&&"left"in o&&(a=Math.abs(o.right-o.left))),this.calcOffset(),s.x=s.x-this._offset.left,s.y=s.y-this._offset.top,i||(s=this.restorePointerVpt(s)),n=0===a||0===c?{width:1,height:1}:{width:r.width/a,height:r.height/c},{x:s.x*n.width,y:s.y*n.height}},_createUpperCanvas:function(){var t=this.lowerCanvasEl.className.replace(/\s*lower-canvas\s*/,"");this.upperCanvasEl?this.upperCanvasEl.className="":this.upperCanvasEl=this._createCanvasElement(),fabric.util.addClass(this.upperCanvasEl,"upper-canvas "+t),this.wrapperEl.appendChild(this.upperCanvasEl),this._copyCanvasStyle(this.lowerCanvasEl,this.upperCanvasEl),this._applyCanvasStyle(this.upperCanvasEl),this.contextTop=this.upperCanvasEl.getContext("2d")},_createCacheCanvas:function(){this.cacheCanvasEl=this._createCanvasElement(),this.cacheCanvasEl.setAttribute("width",this.width),this.cacheCanvasEl.setAttribute("height",this.height),this.contextCache=this.cacheCanvasEl.getContext("2d")},_initWrapperElement:function(){this.wrapperEl=fabric.util.wrapElement(this.lowerCanvasEl,"div",{class:this.containerClass}),fabric.util.setStyle(this.wrapperEl,{width:this.width+"px",height:this.height+"px",position:"relative"}),fabric.util.makeElementUnselectable(this.wrapperEl)},_applyCanvasStyle:function(t){var e=this.width||t.width,i=this.height||t.height;fabric.util.setStyle(t,{position:"absolute",width:e+"px",height:i+"px",left:0,top:0,"touch-action":"none"}),t.width=e,t.height=i,fabric.util.makeElementUnselectable(t)},_copyCanvasStyle:function(t,e){e.style.cssText=t.style.cssText},getSelectionContext:function(){return this.contextTop},getSelectionElement:function(){return this.upperCanvasEl},getActiveObject:function(){return this._activeObject},getActiveObjects:function(){var t=this._activeObject;return t?"activeSelection"===t.type&&t._objects?t._objects.slice(0):[t]:[]},_onObjectRemoved:function(t){t===this._activeObject&&(this.fire("before:selection:cleared",{target:t}),this._discardActiveObject(),this.fire("selection:cleared",{target:t}),t.fire("deselected")),this._hoveredTarget===t&&(this._hoveredTarget=null),this.callSuper("_onObjectRemoved",t)},setActiveObject:function(t,e){var i=this._activeObject;return t===i?this:(this._setActiveObject(t,e)&&(i&&i.fire("deselected",{e:e}),this.fire("object:selected",{target:t,e:e}),t.fire("selected",{e:e})),this)},_setActiveObject:function(t,e){return this._activeObject!==t&&(!!this._discardActiveObject(e,t)&&(!t.onSelect({e:e})&&(this._activeObject=t,!0)))},_discardActiveObject:function(t,e){var i=this._activeObject;if(i){if(i.onDeselect({e:t,object:e}))return!1;this._activeObject=null}return!0},discardActiveObject:function(t){var e=this._activeObject;return e&&(this.fire("before:selection:cleared",{target:e,e:t}),this._discardActiveObject(t)&&(this.fire("selection:cleared",{e:t,target:e}),e.fire("deselected",{e:t}))),this},dispose:function(){fabric.StaticCanvas.prototype.dispose.call(this);var t=this.wrapperEl;return this.removeListeners(),t.removeChild(this.upperCanvasEl),t.removeChild(this.lowerCanvasEl),delete this.upperCanvasEl,t.parentNode&&t.parentNode.replaceChild(this.lowerCanvasEl,this.wrapperEl),delete this.wrapperEl,this},clear:function(){return this.discardActiveObject(),this.clearContext(this.contextTop),this.callSuper("clear")},drawControls:function(t){var e=this._activeObject;e&&e._renderControls(t)},_toObject:function(t,e,i){var r=this._realizeGroupTransformOnObject(t),n=this.callSuper("_toObject",t,e,i);return this._unwindGroupTransformOnObject(t,r),n},_realizeGroupTransformOnObject:function(t){if(t.group&&"activeSelection"===t.group.type&&this._activeObject===t.group){var e={};return["angle","flipX","flipY","left","scaleX","scaleY","skewX","skewY","top"].forEach(function(i){e[i]=t[i]}),this._activeObject.realizeTransform(t),e}return null},_unwindGroupTransformOnObject:function(t,e){e&&t.set(e)},_setSVGObject:function(t,e,i){var r=this._realizeGroupTransformOnObject(e);this.callSuper("_setSVGObject",t,e,i),this._unwindGroupTransformOnObject(e,r)}});for(var o in fabric.StaticCanvas)"prototype"!==o&&(fabric.Canvas[o]=fabric.StaticCanvas[o]);fabric.isTouchSupported&&(fabric.Canvas.prototype._setCursorFromEvent=function(){})}(),function(){function t(t,e){return"which"in t?t.which===e:t.button===e-1}var e={mt:0,tr:1,mr:2,br:3,mb:4,bl:5,ml:6,tl:7},i=fabric.util.addListener,r=fabric.util.removeListener;fabric.util.object.extend(fabric.Canvas.prototype,{cursorMap:["n-resize","ne-resize","e-resize","se-resize","s-resize","sw-resize","w-resize","nw-resize"],_initEventListeners:function(){this.removeListeners(),this._bindEvents(),i(fabric.window,"resize",this._onResize),i(this.upperCanvasEl,"mousedown",this._onMouseDown),i(this.upperCanvasEl,"dblclick",this._onDoubleClick),i(this.upperCanvasEl,"mousemove",this._onMouseMove),i(this.upperCanvasEl,"mouseout",this._onMouseOut),i(this.upperCanvasEl,"mouseenter",this._onMouseEnter),i(this.upperCanvasEl,"wheel",this._onMouseWheel),i(this.upperCanvasEl,"contextmenu",this._onContextMenu),i(this.upperCanvasEl,"touchstart",this._onMouseDown,{passive:!1}),i(this.upperCanvasEl,"touchmove",this._onMouseMove,{passive:!1}),"undefined"!=typeof eventjs&&"add"in eventjs&&(eventjs.add(this.upperCanvasEl,"gesture",this._onGesture),eventjs.add(this.upperCanvasEl,"drag",this._onDrag),eventjs.add(this.upperCanvasEl,"orientation",this._onOrientationChange),eventjs.add(this.upperCanvasEl,"shake",this._onShake),eventjs.add(this.upperCanvasEl,"longpress",this._onLongPress))},_bindEvents:function(){this.eventsBinded||(this._onMouseDown=this._onMouseDown.bind(this),this._onMouseMove=this._onMouseMove.bind(this),this._onMouseUp=this._onMouseUp.bind(this),this._onResize=this._onResize.bind(this),this._onGesture=this._onGesture.bind(this),this._onDrag=this._onDrag.bind(this),this._onShake=this._onShake.bind(this),this._onLongPress=this._onLongPress.bind(this),this._onOrientationChange=this._onOrientationChange.bind(this),this._onMouseWheel=this._onMouseWheel.bind(this),this._onMouseOut=this._onMouseOut.bind(this),this._onMouseEnter=this._onMouseEnter.bind(this),this._onContextMenu=this._onContextMenu.bind(this),this._onDoubleClick=this._onDoubleClick.bind(this),this.eventsBinded=!0)},removeListeners:function(){r(fabric.window,"resize",this._onResize),r(this.upperCanvasEl,"mousedown",this._onMouseDown),r(this.upperCanvasEl,"mousemove",this._onMouseMove),r(this.upperCanvasEl,"mouseout",this._onMouseOut),r(this.upperCanvasEl,"mouseenter",this._onMouseEnter),r(this.upperCanvasEl,"wheel",this._onMouseWheel),r(this.upperCanvasEl,"contextmenu",this._onContextMenu),r(this.upperCanvasEl,"doubleclick",this._onDoubleClick),r(this.upperCanvasEl,"touchstart",this._onMouseDown),r(this.upperCanvasEl,"touchmove",this._onMouseMove),"undefined"!=typeof eventjs&&"remove"in eventjs&&(eventjs.remove(this.upperCanvasEl,"gesture",this._onGesture),eventjs.remove(this.upperCanvasEl,"drag",this._onDrag),eventjs.remove(this.upperCanvasEl,"orientation",this._onOrientationChange),eventjs.remove(this.upperCanvasEl,"shake",this._onShake),eventjs.remove(this.upperCanvasEl,"longpress",this._onLongPress))},_onGesture:function(t,e){this.__onTransformGesture&&this.__onTransformGesture(t,e)},_onDrag:function(t,e){this.__onDrag&&this.__onDrag(t,e)},_onMouseWheel:function(t){this.__onMouseWheel(t)},_onMouseOut:function(t){var e=this._hoveredTarget;this.fire("mouse:out",{target:e,e:t}),this._hoveredTarget=null,e&&e.fire("mouseout",{e:t}),this._iTextInstances&&this._iTextInstances.forEach(function(t){t.isEditing&&t.hiddenTextarea.focus()})},_onMouseEnter:function(t){this.findTarget(t)||(this.fire("mouse:over",{target:null,e:t}),this._hoveredTarget=null)},_onOrientationChange:function(t,e){this.__onOrientationChange&&this.__onOrientationChange(t,e)},_onShake:function(t,e){this.__onShake&&this.__onShake(t,e)},_onLongPress:function(t,e){this.__onLongPress&&this.__onLongPress(t,e)},_onContextMenu:function(t){return this.stopContextMenu&&(t.stopPropagation(),t.preventDefault()),!1},_onDoubleClick:function(t){this._handleEvent(t,"dblclick",void 0)},_onMouseDown:function(t){this.__onMouseDown(t),i(fabric.document,"touchend",this._onMouseUp,{passive:!1}),i(fabric.document,"touchmove",this._onMouseMove,{passive:!1}),r(this.upperCanvasEl,"mousemove",this._onMouseMove),r(this.upperCanvasEl,"touchmove",this._onMouseMove),"touchstart"===t.type?r(this.upperCanvasEl,"mousedown",this._onMouseDown):(i(fabric.document,"mouseup",this._onMouseUp),i(fabric.document,"mousemove",this._onMouseMove))},_onMouseUp:function(t){if(this.__onMouseUp(t),r(fabric.document,"mouseup",this._onMouseUp),r(fabric.document,"touchend",this._onMouseUp),r(fabric.document,"mousemove",this._onMouseMove),r(fabric.document,"touchmove",this._onMouseMove),i(this.upperCanvasEl,"mousemove",this._onMouseMove),i(this.upperCanvasEl,"touchmove",this._onMouseMove,{passive:!1}),"touchend"===t.type){var e=this;setTimeout(function(){i(e.upperCanvasEl,"mousedown",e._onMouseDown)},400)}},_onMouseMove:function(t){!this.allowTouchScrolling&&t.preventDefault&&t.preventDefault(),this.__onMouseMove(t)},_onResize:function(){this.calcOffset()},_shouldRender:function(t,e){var i=this._activeObject;return(!i||!i.isEditing||t!==i)&&!!(t&&(t.isMoving||t!==i)||!t&&i||!t&&!i&&!this._groupSelector||e&&this._previousPointer&&this.selection&&(e.x!==this._previousPointer.x||e.y!==this._previousPointer.y))},__onMouseUp:function(e){var i,r=!0,n=this._currentTransform,s=this._groupSelector,o=!s||0===s.left&&0===s.top;if(t(e,3))this.fireRightClick&&this._handleEvent(e,"up",i,3,o);else if(t(e,2))this.fireMiddleClick&&this._handleEvent(e,"up",i,2,o);else if(this.isDrawingMode&&this._isCurrentlyDrawing)this._onMouseUpInDrawingMode(e);else{n&&(this._finalizeCurrentTransform(e),r=!n.actionPerformed),i=r?this.findTarget(e,!0):n.target;var a=this._shouldRender(i,this.getPointer(e));i||!o?this._maybeGroupObjects(e):(this._groupSelector=null,this._currentTransform=null),i&&(i.isMoving=!1),this._setCursorFromEvent(e,i),this._handleEvent(e,"up",i||null,1,o),i&&(i.__corner=0),a&&this.requestRenderAll()}},_handleEvent:function(t,e,i,r,n){var s=void 0===i?this.findTarget(t):i,o=this.targets||[],a={e:t,target:s,subTargets:o,button:r||1,isClick:n||!1};this.fire("mouse:"+e,a),s&&s.fire("mouse"+e,a);for(var c=0;c1)){var r=this._groupSelector;r?(i=this.getPointer(t,!0),r.left=i.x-r.ex,r.top=i.y-r.ey,this.renderTop()):this._currentTransform?this._transformObject(t):(e=this.findTarget(t),this._setCursorFromEvent(t,e),this._fireOverOutEvents(e,t)),this._handleEvent(t,"move",e||null)}},_fireOverOutEvents:function(t,e){var i,r,n=this._hoveredTarget;n!==t&&(i={e:e,target:t,previousTarget:this._hoveredTarget},r={e:e,target:this._hoveredTarget,nextTarget:t},this._hoveredTarget=t),t?n!==t&&(n&&(this.fire("mouse:out",r),n.fire("mouseout",r)),this.fire("mouse:over",i),t.fire("mouseover",i)):n&&(this.fire("mouse:out",r),n.fire("mouseout",r))},__onMouseWheel:function(t){this._handleEvent(t,"wheel")},_transformObject:function(t){var e=this.getPointer(t),i=this._currentTransform;i.reset=!1,i.target.isMoving=!0,i.shiftKey=t.shiftKey,i.altKey=t[this.centeredKey],this._beforeScaleTransform(t,i),this._performTransformAction(t,i,e),i.actionPerformed&&this.requestRenderAll()},_performTransformAction:function(t,e,i){var r=i.x,n=i.y,s=e.target,o=e.action,a=!1;"rotate"===o?(a=this._rotateObject(r,n))&&this._fire("rotating",s,t):"scale"===o?(a=this._onScale(t,e,r,n))&&this._fire("scaling",s,t):"scaleX"===o?(a=this._scaleObject(r,n,"x"))&&this._fire("scaling",s,t):"scaleY"===o?(a=this._scaleObject(r,n,"y"))&&this._fire("scaling",s,t):"skewX"===o?(a=this._skewObject(r,n,"x"))&&this._fire("skewing",s,t):"skewY"===o?(a=this._skewObject(r,n,"y"))&&this._fire("skewing",s,t):(a=this._translateObject(r,n))&&(this._fire("moving",s,t),this.setCursor(s.moveCursor||this.moveCursor)),e.actionPerformed=e.actionPerformed||a},_fire:function(t,e,i){this.fire("object:"+t,{target:e,e:i}),e.fire(t,{e:i})},_beforeScaleTransform:function(t,e){if("scale"===e.action||"scaleX"===e.action||"scaleY"===e.action){var i=this._shouldCenterTransform(e.target);(i&&("center"!==e.originX||"center"!==e.originY)||!i&&"center"===e.originX&&"center"===e.originY)&&(this._resetCurrentTransform(),e.reset=!0)}},_onScale:function(t,e,i,r){return this._isUniscalePossible(t,e.target)?(e.currentAction="scale",this._scaleObject(i,r)):(e.reset||"scale"!==e.currentAction||this._resetCurrentTransform(),e.currentAction="scaleEqually",this._scaleObject(i,r,"equally"))},_isUniscalePossible:function(t,e){return(t[this.uniScaleKey]||this.uniScaleTransform)&&!e.get("lockUniScaling")},_setCursorFromEvent:function(t,e){if(!e)return this.setCursor(this.defaultCursor),!1;var i=e.hoverCursor||this.hoverCursor,r=this._activeObject&&"activeSelection"===this._activeObject.type?this._activeObject:null,n=(!r||!r.contains(e))&&e._findTargetCorner(this.getPointer(t,!0));n?this.setCursor(this.getCornerCursor(n,e,t)):this.setCursor(i)},getCornerCursor:function(t,i,r){return this.actionIsDisabled(t,i,r)?this.notAllowedCursor:t in e?this._getRotatedCornerCursor(t,i,r):"mtr"===t&&i.hasRotatingPoint?this.rotationCursor:this.defaultCursor},actionIsDisabled:function(t,e,i){return"mt"===t||"mb"===t?i[this.altActionKey]?e.lockSkewingX:e.lockScalingY:"ml"===t||"mr"===t?i[this.altActionKey]?e.lockSkewingY:e.lockScalingX:"mtr"===t?e.lockRotation:this._isUniscalePossible(i,e)?e.lockScalingX&&e.lockScalingY:e.lockScalingX||e.lockScalingY},_getRotatedCornerCursor:function(t,i,r){var n=Math.round(i.angle%360/45);return n<0&&(n+=8),n+=e[t],r[this.altActionKey]&&e[t]%2==0&&(n+=2),n%=8,this.cursorMap[n]}})}(),function(){var t=Math.min,e=Math.max;fabric.util.object.extend(fabric.Canvas.prototype,{_shouldGroup:function(t,e){var i=this._activeObject;return i&&t[this.selectionKey]&&e&&e.selectable&&this.selection&&(i!==e||"activeSelection"===i.type)},_handleGrouping:function(t,e){var i=this._activeObject;i.__corner||(e!==i||(e=this.findTarget(t,!0)))&&(i&&"activeSelection"===i.type?this._updateActiveSelection(e,t):this._createActiveSelection(e,t))},_updateActiveSelection:function(t,e){var i=this._activeObject;if(i.contains(t)){if(i.removeWithUpdate(t),t.fire("deselected",{e:e}),this._hoveredTarget=t,1===i.size())return void this.setActiveObject(i.item(0),e)}else i.addWithUpdate(t),t.fire("selected",{e:e}),this._hoveredTarget=i;this.fire("selection:updated",{target:i,e:e,updated:t})},_createActiveSelection:function(t,e){var i=this._createGroup(t);this.setActiveObject(i,e),t.fire("selected",{e:e}),this.fire("selection:created",{target:i,e:e})},_createGroup:function(t){var e=this.getObjects(),i=e.indexOf(this._activeObject)1&&(e=new fabric.ActiveSelection(i.reverse(),{canvas:this}),i.forEach(function(e){e.fire("selected",{e:t})}),this.setActiveObject(e,t),this.fire("selection:created",{target:e,e:t}))},_collectObjects:function(){for(var i,r=[],n=this._groupSelector.ex,s=this._groupSelector.ey,o=n+this._groupSelector.left,a=s+this._groupSelector.top,c=new fabric.Point(t(n,o),t(s,a)),h=new fabric.Point(e(n,o),e(s,a)),l=n===o&&s===a,u=this._objects.length;u--&&!((i=this._objects[u])&&i.selectable&&i.visible&&(i.intersectsWithRect(c,h)||i.isContainedWithinRect(c,h)||i.containsPoint(c)||i.containsPoint(h))&&(r.push(i),l)););return r},_maybeGroupObjects:function(t){this.selection&&this._groupSelector&&this._groupSelectedObjects(t),this.setCursor(this.defaultCursor),this._groupSelector=null,this._currentTransform=null}})}(),function(){var t=fabric.StaticCanvas.supports("toDataURLWithQuality");fabric.util.object.extend(fabric.StaticCanvas.prototype,{toDataURL:function(t){t||(t={});var e=t.format||"png",i=t.quality||1,r=t.multiplier||1,n={left:t.left||0,top:t.top||0,width:t.width||0,height:t.height||0};return this.__toDataURLWithMultiplier(e,i,n,r)},__toDataURLWithMultiplier:function(t,e,i,r){var n=this.width,s=this.height,o=(i.width||this.width)*r,a=(i.height||this.height)*r,c=this.getZoom()*r,h=this.viewportTransform,l=[c,0,0,c,(h[4]-i.left)*r,(h[5]-i.top)*r],u=this.interactive,f=this.skipOffscreen,d=n!==o||s!==a;this.viewportTransform=l,this.skipOffscreen=!1,this.interactive=!1,d&&this.setDimensions({width:o,height:a},{backstoreOnly:!0}),this.renderAll();var g=this.__toDataURL(t,e,i);return this.interactive=u,this.skipOffscreen=f,this.viewportTransform=h,d&&this.setDimensions({width:n,height:s},{backstoreOnly:!0}),this.renderAll(),g},__toDataURL:function(e,i){var r=this.contextContainer.canvas;return"jpg"===e&&(e="jpeg"),t?r.toDataURL("image/"+e,i):r.toDataURL("image/"+e)}})}(),fabric.util.object.extend(fabric.StaticCanvas.prototype,{loadFromDatalessJSON:function(t,e,i){return this.loadFromJSON(t,e,i)},loadFromJSON:function(t,e,i){if(t){var r="string"==typeof t?JSON.parse(t):fabric.util.object.clone(t),n=this,s=this.renderOnAddRemove;return this.renderOnAddRemove=!1,this._enlivenObjects(r.objects,function(t){n.clear(),n._setBgOverlay(r,function(){t.forEach(function(t,e){n.insertAt(t,e)}),n.renderOnAddRemove=s,delete r.objects,delete r.backgroundImage,delete r.overlayImage,delete r.background,delete r.overlay,n._setOptions(r),n.renderAll(),e&&e()})},i),this}},_setBgOverlay:function(t,e){var i={backgroundColor:!1,overlayColor:!1,backgroundImage:!1,overlayImage:!1};if(t.backgroundImage||t.overlayImage||t.background||t.overlay){var r=function(){i.backgroundImage&&i.overlayImage&&i.backgroundColor&&i.overlayColor&&e&&e()};this.__setBgOverlay("backgroundImage",t.backgroundImage,i,r),this.__setBgOverlay("overlayImage",t.overlayImage,i,r),this.__setBgOverlay("backgroundColor",t.background,i,r),this.__setBgOverlay("overlayColor",t.overlay,i,r)}else e&&e()},__setBgOverlay:function(t,e,i,r){var n=this;if(!e)return i[t]=!0,void(r&&r());"backgroundImage"===t||"overlayImage"===t?fabric.util.enlivenObjects([e],function(e){n[t]=e[0],i[t]=!0,r&&r()}):this["set"+fabric.util.string.capitalize(t,!0)](e,function(){i[t]=!0,r&&r()})},_enlivenObjects:function(t,e,i){t&&0!==t.length?fabric.util.enlivenObjects(t,function(t){e&&e(t)},null,i):e&&e([])},_toDataURL:function(t,e){this.clone(function(i){e(i.toDataURL(t))})},_toDataURLWithMultiplier:function(t,e,i){this.clone(function(r){i(r.toDataURLWithMultiplier(t,e))})},clone:function(t,e){var i=JSON.stringify(this.toJSON(e));this.cloneWithoutData(function(e){e.loadFromJSON(i,function(){t&&t(e)})})},cloneWithoutData:function(t){var e=fabric.document.createElement("canvas");e.width=this.width,e.height=this.height;var i=new fabric.Canvas(e);i.clipTo=this.clipTo,this.backgroundImage?(i.setBackgroundImage(this.backgroundImage.src,function(){i.renderAll(),t&&t(i)}),i.backgroundImageOpacity=this.backgroundImageOpacity,i.backgroundImageStretch=this.backgroundImageStretch):t&&t(i)}}),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=e.util.object.extend,r=e.util.object.clone,n=e.util.toFixed,s=e.util.string.capitalize,o=e.util.degreesToRadians,a=e.StaticCanvas.supports("setLineDash"),c=!e.isLikelyNode;e.Object||(e.Object=e.util.createClass(e.CommonMethods,{type:"object",originX:"left",originY:"top",top:0,left:0,width:0,height:0,scaleX:1,scaleY:1,flipX:!1,flipY:!1,opacity:1,angle:0,skewX:0,skewY:0,cornerSize:13,transparentCorners:!0,hoverCursor:null,moveCursor:null,padding:0,borderColor:"rgba(102,153,255,0.75)",borderDashArray:null,cornerColor:"rgba(102,153,255,0.5)",cornerStrokeColor:null,cornerStyle:"rect",cornerDashArray:null,centeredScaling:!1,centeredRotation:!0,fill:"rgb(0,0,0)",fillRule:"nonzero",globalCompositeOperation:"source-over",backgroundColor:"",selectionBackgroundColor:"",stroke:null,strokeWidth:1,strokeDashArray:null,strokeLineCap:"butt",strokeLineJoin:"miter",strokeMiterLimit:10,shadow:null,borderOpacityWhenMoving:.4,borderScaleFactor:1,transformMatrix:null,minScaleLimit:0,selectable:!0,evented:!0,visible:!0,hasControls:!0,hasBorders:!0,hasRotatingPoint:!0,rotatingPointOffset:40,perPixelTargetFind:!1,includeDefaultValues:!0,clipTo:null,lockMovementX:!1,lockMovementY:!1,lockRotation:!1,lockScalingX:!1,lockScalingY:!1,lockUniScaling:!1,lockSkewingX:!1,lockSkewingY:!1,lockScalingFlip:!1,excludeFromExport:!1,objectCaching:c,statefullCache:!1,noScaleCache:!0,dirty:!0,__corner:0,stateProperties:"top left width height scaleX scaleY flipX flipY originX originY transformMatrix stroke strokeWidth strokeDashArray strokeLineCap strokeLineJoin strokeMiterLimit angle opacity fill globalCompositeOperation shadow clipTo visible backgroundColor skewX skewY fillRule".split(" "),cacheProperties:"fill stroke strokeWidth strokeDashArray width height strokeLineCap strokeLineJoin strokeMiterLimit backgroundColor".split(" "),initialize:function(t){t&&this.setOptions(t)},_createCacheCanvas:function(){this._cacheProperties={},this._cacheCanvas=e.document.createElement("canvas"),this._cacheContext=this._cacheCanvas.getContext("2d"),this._updateCacheCanvas()},_limitCacheSize:function(t){var i=e.perfLimitSizeTotal,r=e.cacheSideLimit,n=t.width,s=t.height,o=n/s,a=e.util.limitDimsByArea(o,i,r),c=e.util.capValue,h=e.maxCacheSideLimit,l=e.minCacheSideLimit,u=c(l,a.x,h),f=c(l,a.y,h);return n>u?(t.zoomX/=n/u,t.width=u):nf?(t.zoomY/=s/f,t.height=f):sg||s>p,m=(n<.9*g||s<.9*p)&&g>r&&p>r;d=v||m,v&&(u=.1*n&-2,f=.1*s&-2)}return!!l&&(d?(this._cacheCanvas.width=Math.max(Math.ceil(n)+u,r),this._cacheCanvas.height=Math.max(Math.ceil(s)+f,r),this.cacheTranslationX=(n+u)/2,this.cacheTranslationY=(s+f)/2):(this._cacheContext.setTransform(1,0,0,1,0,0),this._cacheContext.clearRect(0,0,this._cacheCanvas.width,this._cacheCanvas.height)),this.cacheWidth=n,this.cacheHeight=s,this._cacheContext.translate(this.cacheTranslationX,this.cacheTranslationY),this._cacheContext.scale(o,a),this.zoomX=o,this.zoomY=a,!0)},setOptions:function(t){this._setOptions(t),this._initGradient(t.fill,"fill"),this._initGradient(t.stroke,"stroke"),this._initClipping(t),this._initPattern(t.fill,"fill"),this._initPattern(t.stroke,"stroke")},transform:function(t,e){this.group&&!this.group._transformDone&&this.group.transform(t);var i=e?this._getLeftTopCoords():this.getCenterPoint();t.translate(i.x,i.y),this.angle&&t.rotate(o(this.angle)),t.scale(this.scaleX*(this.flipX?-1:1),this.scaleY*(this.flipY?-1:1)),this.skewX&&t.transform(1,0,Math.tan(o(this.skewX)),1,0,0),this.skewY&&t.transform(1,Math.tan(o(this.skewY)),0,1,0,0)},toObject:function(t){var i=e.Object.NUM_FRACTION_DIGITS,r={type:this.type,version:e.version,originX:this.originX,originY:this.originY,left:n(this.left,i),top:n(this.top,i),width:n(this.width,i),height:n(this.height,i),fill:this.fill&&this.fill.toObject?this.fill.toObject():this.fill,stroke:this.stroke&&this.stroke.toObject?this.stroke.toObject():this.stroke,strokeWidth:n(this.strokeWidth,i),strokeDashArray:this.strokeDashArray?this.strokeDashArray.concat():this.strokeDashArray,strokeLineCap:this.strokeLineCap,strokeLineJoin:this.strokeLineJoin,strokeMiterLimit:n(this.strokeMiterLimit,i),scaleX:n(this.scaleX,i),scaleY:n(this.scaleY,i),angle:n(this.angle,i),flipX:this.flipX,flipY:this.flipY,opacity:n(this.opacity,i),shadow:this.shadow&&this.shadow.toObject?this.shadow.toObject():this.shadow,visible:this.visible,clipTo:this.clipTo&&String(this.clipTo),backgroundColor:this.backgroundColor,fillRule:this.fillRule,globalCompositeOperation:this.globalCompositeOperation,transformMatrix:this.transformMatrix?this.transformMatrix.concat():null,skewX:n(this.skewX,i),skewY:n(this.skewY,i)};return e.util.populateWithProperties(this,r,t),this.includeDefaultValues||(r=this._removeDefaultValues(r)),r},toDatalessObject:function(t){return this.toObject(t)},_removeDefaultValues:function(t){var i=e.util.getKlass(t.type).prototype;return i.stateProperties.forEach(function(e){t[e]===i[e]&&delete t[e],"[object Array]"===Object.prototype.toString.call(t[e])&&"[object Array]"===Object.prototype.toString.call(i[e])&&0===t[e].length&&0===i[e].length&&delete t[e]}),t},toString:function(){return"#"},getObjectScaling:function(){var t=this.scaleX,e=this.scaleY;if(this.group){var i=this.group.getObjectScaling();t*=i.scaleX,e*=i.scaleY}return{scaleX:t,scaleY:e}},getObjectOpacity:function(){var t=this.opacity;return this.group&&(t*=this.group.getObjectOpacity()),t},_set:function(t,i){return("scaleX"===t||"scaleY"===t)&&(i=this._constrainScale(i)),"scaleX"===t&&i<0?(this.flipX=!this.flipX,i*=-1):"scaleY"===t&&i<0?(this.flipY=!this.flipY,i*=-1):"shadow"!==t||!i||i instanceof e.Shadow?"dirty"===t&&this.group&&this.group.set("dirty",i):i=new e.Shadow(i),this[t]=i,this.cacheProperties.indexOf(t)>-1&&(this.group&&this.group.set("dirty",!0),this.dirty=!0),this.group&&this.stateProperties.indexOf(t)>-1&&this.group.isOnACache()&&this.group.set("dirty",!0),this},setOnGroup:function(){},getViewportTransform:function(){return this.canvas&&this.canvas.viewportTransform?this.canvas.viewportTransform:e.iMatrix.concat()},isNotVisible:function(){return 0===this.opacity||0===this.width&&0===this.height||!this.visible},render:function(t){this.isNotVisible()||this.canvas&&this.canvas.skipOffscreen&&!this.group&&!this.isOnScreen()||(t.save(),this._setupCompositeOperation(t),this.drawSelectionBackground(t),this.transform(t),this._setOpacity(t),this._setShadow(t,this),this.transformMatrix&&t.transform.apply(t,this.transformMatrix),this.clipTo&&e.util.clipContext(this,t),this.shouldCache()?(this._cacheCanvas||this._createCacheCanvas(),this.isCacheDirty()&&(this.statefullCache&&this.saveState({propertySet:"cacheProperties"}),this.drawObject(this._cacheContext),this.dirty=!1),this.drawCacheOnCanvas(t)):(this.dirty=!1,this.drawObject(t),this.objectCaching&&this.statefullCache&&this.saveState({propertySet:"cacheProperties"})),this.clipTo&&t.restore(),t.restore())},needsItsOwnCache:function(){return!1},shouldCache:function(){return this.ownCaching=this.objectCaching&&(!this.group||this.needsItsOwnCache()||!this.group.isOnACache()),this.ownCaching},willDrawShadow:function(){return!!this.shadow&&(0!==this.shadow.offsetX||0!==this.shadow.offsetY)},drawObject:function(t){this._renderBackground(t),this._setStrokeStyles(t,this),this._setFillStyles(t,this),this._render(t)},drawCacheOnCanvas:function(t){t.scale(1/this.zoomX,1/this.zoomY),t.drawImage(this._cacheCanvas,-this.cacheTranslationX,-this.cacheTranslationY)},isCacheDirty:function(t){if(this.isNotVisible())return!1;if(this._cacheCanvas&&!t&&this._updateCacheCanvas())return!0;if(this.dirty||this.statefullCache&&this.hasStateChanged("cacheProperties")){if(this._cacheCanvas&&!t){var e=this.cacheWidth/this.zoomX,i=this.cacheHeight/this.zoomY;this._cacheContext.clearRect(-e/2,-i/2,e,i)}return!0}return!1},_renderBackground:function(t){if(this.backgroundColor){var e=this._getNonTransformedDimensions();t.fillStyle=this.backgroundColor,t.fillRect(-e.x/2,-e.y/2,e.x,e.y),this._removeShadow(t)}},_setOpacity:function(t){this.group&&!this.group._transformDone?t.globalAlpha=this.getObjectOpacity():t.globalAlpha*=this.opacity},_setStrokeStyles:function(t,e){e.stroke&&(t.lineWidth=e.strokeWidth,t.lineCap=e.strokeLineCap,t.lineJoin=e.strokeLineJoin,t.miterLimit=e.strokeMiterLimit,t.strokeStyle=e.stroke.toLive?e.stroke.toLive(t,this):e.stroke)},_setFillStyles:function(t,e){e.fill&&(t.fillStyle=e.fill.toLive?e.fill.toLive(t,this):e.fill)},_setLineDash:function(t,e,i){e&&(1&e.length&&e.push.apply(e,e),a?t.setLineDash(e):i&&i(t))},_renderControls:function(t,i){var r,n,s,a=this.getViewportTransform(),c=this.calcTransformMatrix();n=void 0!==(i=i||{}).hasBorders?i.hasBorders:this.hasBorders,s=void 0!==i.hasControls?i.hasControls:this.hasControls,c=e.util.multiplyTransformMatrices(a,c),r=e.util.qrDecompose(c),t.save(),t.translate(r.translateX,r.translateY),t.lineWidth=1*this.borderScaleFactor,this.group||(t.globalAlpha=this.isMoving?this.borderOpacityWhenMoving:1),i.forActiveSelection?(t.rotate(o(r.angle)),n&&this.drawBordersInGroup(t,r,i)):(t.rotate(o(this.angle)),n&&this.drawBorders(t,i)),s&&this.drawControls(t,i),t.restore()},_setShadow:function(t){if(this.shadow){var i=this.canvas&&this.canvas.viewportTransform[0]||1,r=this.canvas&&this.canvas.viewportTransform[3]||1,n=this.getObjectScaling();this.canvas&&this.canvas._isRetinaScaling()&&(i*=e.devicePixelRatio,r*=e.devicePixelRatio),t.shadowColor=this.shadow.color,t.shadowBlur=this.shadow.blur*(i+r)*(n.scaleX+n.scaleY)/4,t.shadowOffsetX=this.shadow.offsetX*i*n.scaleX,t.shadowOffsetY=this.shadow.offsetY*r*n.scaleY}},_removeShadow:function(t){this.shadow&&(t.shadowColor="",t.shadowBlur=t.shadowOffsetX=t.shadowOffsetY=0)},_applyPatternGradientTransform:function(t,e){if(!e||!e.toLive)return{offsetX:0,offsetY:0};var i=e.gradientTransform||e.patternTransform,r=-this.width/2+e.offsetX||0,n=-this.height/2+e.offsetY||0;return t.translate(r,n),i&&t.transform.apply(t,i),{offsetX:r,offsetY:n}},_renderFill:function(t){this.fill&&(t.save(),this._applyPatternGradientTransform(t,this.fill),"evenodd"===this.fillRule?t.fill("evenodd"):t.fill(),t.restore())},_renderStroke:function(t){this.stroke&&0!==this.strokeWidth&&(this.shadow&&!this.shadow.affectStroke&&this._removeShadow(t),t.save(),this._setLineDash(t,this.strokeDashArray,this._renderDashedStroke),this._applyPatternGradientTransform(t,this.stroke),t.stroke(),t.restore())},_findCenterFromElement:function(){return{x:this.left+this.width/2,y:this.top+this.height/2}},_assignTransformMatrixProps:function(){if(this.transformMatrix){var t=e.util.qrDecompose(this.transformMatrix);this.flipX=!1,this.flipY=!1,this.set("scaleX",t.scaleX),this.set("scaleY",t.scaleY),this.angle=t.angle,this.skewX=t.skewX,this.skewY=0}},_removeTransformMatrix:function(){var t=this._findCenterFromElement();this.transformMatrix&&(this._assignTransformMatrixProps(),t=e.util.transformPoint(t,this.transformMatrix)),this.transformMatrix=null,this.setPositionByOrigin(t,"center","center")},clone:function(t,i){var r=this.toObject(i);this.constructor.fromObject?this.constructor.fromObject(r,t):e.Object._fromObject("Object",r,t)},cloneAsImage:function(t,i){var r=this.toDataURL(i);return e.util.loadImage(r,function(i){t&&t(new e.Image(i))}),this},toDataURL:function(t){t||(t={});var i=e.util.createCanvasElement(),r=this.getBoundingRect();i.width=r.width,i.height=r.height,e.util.wrapElement(i,"div");var n=new e.StaticCanvas(i,{enableRetinaScaling:t.enableRetinaScaling});"jpg"===t.format&&(t.format="jpeg"),"jpeg"===t.format&&(n.backgroundColor="#fff");var s={left:this.left,top:this.top};this.setPositionByOrigin(new e.Point(n.width/2,n.height/2),"center","center");var o=this.canvas;n.add(this);var a=n.toDataURL(t);return this.set(s).setCoords(),this.canvas=o,n.dispose(),n=null,a},isType:function(t){return this.type===t},complexity:function(){return 1},toJSON:function(t){return this.toObject(t)},setGradient:function(t,i){i||(i={});var r={colorStops:[]};return r.type=i.type||(i.r1||i.r2?"radial":"linear"),r.coords={x1:i.x1,y1:i.y1,x2:i.x2,y2:i.y2},(i.r1||i.r2)&&(r.coords.r1=i.r1,r.coords.r2=i.r2),r.gradientTransform=i.gradientTransform,e.Gradient.prototype.addColorStop.call(r,i.colorStops),this.set(t,e.Gradient.forObject(this,r))},setPatternFill:function(t){return this.set("fill",new e.Pattern(t))},setShadow:function(t){return this.set("shadow",t?new e.Shadow(t):null)},setColor:function(t){return this.set("fill",t),this},rotate:function(t){var e=("center"!==this.originX||"center"!==this.originY)&&this.centeredRotation;return e&&this._setOriginToCenter(),this.set("angle",t),e&&this._resetOrigin(),this},centerH:function(){return this.canvas&&this.canvas.centerObjectH(this),this},viewportCenterH:function(){return this.canvas&&this.canvas.viewportCenterObjectH(this),this},centerV:function(){return this.canvas&&this.canvas.centerObjectV(this),this},viewportCenterV:function(){return this.canvas&&this.canvas.viewportCenterObjectV(this),this},center:function(){return this.canvas&&this.canvas.centerObject(this),this},viewportCenter:function(){return this.canvas&&this.canvas.viewportCenterObject(this),this},getLocalPointer:function(t,i){i=i||this.canvas.getPointer(t);var r=new e.Point(i.x,i.y),n=this._getLeftTopCoords();return this.angle&&(r=e.util.rotatePoint(r,n,o(-this.angle))),{x:r.x-n.x,y:r.y-n.y}},_setupCompositeOperation:function(t){this.globalCompositeOperation&&(t.globalCompositeOperation=this.globalCompositeOperation)}}),e.util.createAccessors&&e.util.createAccessors(e.Object),i(e.Object.prototype,e.Observable),e.Object.NUM_FRACTION_DIGITS=2,e.Object._fromObject=function(t,i,n,s){var o=e[t];i=r(i,!0),e.util.enlivenPatterns([i.fill,i.stroke],function(t){void 0!==t[0]&&(i.fill=t[0]),void 0!==t[1]&&(i.stroke=t[1]);var e=s?new o(i[s],i):new o(i);n&&n(e)})},e.Object.__uid=0)}("undefined"!=typeof exports?exports:this),function(){var t=fabric.util.degreesToRadians,e={left:-.5,center:0,right:.5},i={top:-.5,center:0,bottom:.5};fabric.util.object.extend(fabric.Object.prototype,{translateToGivenOrigin:function(t,r,n,s,o){var a,c,h,l=t.x,u=t.y;return"string"==typeof r?r=e[r]:r-=.5,"string"==typeof s?s=e[s]:s-=.5,a=s-r,"string"==typeof n?n=i[n]:n-=.5,"string"==typeof o?o=i[o]:o-=.5,c=o-n,(a||c)&&(h=this._getTransformedDimensions(),l=t.x+a*h.x,u=t.y+c*h.y),new fabric.Point(l,u)},translateToCenterPoint:function(e,i,r){var n=this.translateToGivenOrigin(e,i,r,"center","center");return this.angle?fabric.util.rotatePoint(n,e,t(this.angle)):n},translateToOriginPoint:function(e,i,r){var n=this.translateToGivenOrigin(e,"center","center",i,r);return this.angle?fabric.util.rotatePoint(n,e,t(this.angle)):n},getCenterPoint:function(){var t=new fabric.Point(this.left,this.top);return this.translateToCenterPoint(t,this.originX,this.originY)},getPointByOrigin:function(t,e){var i=this.getCenterPoint();return this.translateToOriginPoint(i,t,e)},toLocalPoint:function(e,i,r){var n,s,o=this.getCenterPoint();return n=void 0!==i&&void 0!==r?this.translateToGivenOrigin(o,"center","center",i,r):new fabric.Point(this.left,this.top),s=new fabric.Point(e.x,e.y),this.angle&&(s=fabric.util.rotatePoint(s,o,-t(this.angle))),s.subtractEquals(n)},setPositionByOrigin:function(t,e,i){var r=this.translateToCenterPoint(t,e,i),n=this.translateToOriginPoint(r,this.originX,this.originY);this.set("left",n.x),this.set("top",n.y)},adjustPosition:function(i){var r,n,s=t(this.angle),o=this.getScaledWidth(),a=Math.cos(s)*o,c=Math.sin(s)*o;r="string"==typeof this.originX?e[this.originX]:this.originX-.5,n="string"==typeof i?e[i]:i-.5,this.left+=a*(n-r),this.top+=c*(n-r),this.setCoords(),this.originX=i},_setOriginToCenter:function(){this._originalOriginX=this.originX,this._originalOriginY=this.originY;var t=this.getCenterPoint();this.originX="center",this.originY="center",this.left=t.x,this.top=t.y},_resetOrigin:function(){var t=this.translateToOriginPoint(this.getCenterPoint(),this._originalOriginX,this._originalOriginY);this.originX=this._originalOriginX,this.originY=this._originalOriginY,this.left=t.x,this.top=t.y,this._originalOriginX=null,this._originalOriginY=null},_getLeftTopCoords:function(){return this.translateToOriginPoint(this.getCenterPoint(),"left","top")},onDeselect:function(){}})}(),function(){function t(t){return[new fabric.Point(t.tl.x,t.tl.y),new fabric.Point(t.tr.x,t.tr.y),new fabric.Point(t.br.x,t.br.y),new fabric.Point(t.bl.x,t.bl.y)]}var e=fabric.util.degreesToRadians,i=fabric.util.multiplyTransformMatrices;fabric.util.object.extend(fabric.Object.prototype,{oCoords:null,aCoords:null,getCoords:function(e,i){this.oCoords||this.setCoords();var r=e?this.aCoords:this.oCoords;return t(i?this.calcCoords(e):r)},intersectsWithRect:function(t,e,i,r){var n=this.getCoords(i,r);return"Intersection"===fabric.Intersection.intersectPolygonRectangle(n,t,e).status},intersectsWithObject:function(t,e,i){return"Intersection"===fabric.Intersection.intersectPolygonPolygon(this.getCoords(e,i),t.getCoords(e,i)).status||t.isContainedWithinObject(this,e,i)||this.isContainedWithinObject(t,e,i)},isContainedWithinObject:function(t,e,i){for(var r=this.getCoords(e,i),n=0,s=t._getImageLines(i?t.calcCoords(e):e?t.aCoords:t.oCoords);n<4;n++)if(!t.containsPoint(r[n],s))return!1;return!0},isContainedWithinRect:function(t,e,i,r){var n=this.getBoundingRect(i,r);return n.left>=t.x&&n.left+n.width<=e.x&&n.top>=t.y&&n.top+n.height<=e.y},containsPoint:function(t,e,i,r){var e=e||this._getImageLines(r?this.calcCoords(i):i?this.aCoords:this.oCoords),n=this._findCrossPoints(t,e);return 0!==n&&n%2==1},isOnScreen:function(t){if(!this.canvas)return!1;for(var e,i=this.canvas.vptCoords.tl,r=this.canvas.vptCoords.br,n=this.getCoords(!0,t),s=0;s<4;s++)if((e=n[s]).x<=r.x&&e.x>=i.x&&e.y<=r.y&&e.y>=i.y)return!0;if(this.intersectsWithRect(i,r,!0))return!0;var o={x:(i.x+r.x)/2,y:(i.y+r.y)/2};return!!this.containsPoint(o,null,!0)},_getImageLines:function(t){return{topline:{o:t.tl,d:t.tr},rightline:{o:t.tr,d:t.br},bottomline:{o:t.br,d:t.bl},leftline:{o:t.bl,d:t.tl}}},_findCrossPoints:function(t,e){var i,r,n,s,o=0;for(var a in e)if(!((s=e[a]).o.y=t.y&&s.d.y>=t.y||(s.o.x===s.d.x&&s.o.x>=t.x?n=s.o.x:(i=0,r=(s.d.y-s.o.y)/(s.d.x-s.o.x),n=-(t.y-i*t.x-(s.o.y-r*s.o.x))/(i-r)),n>=t.x&&(o+=1),2!==o)))break;return o},getBoundingRectWidth:function(){return this.getBoundingRect().width},getBoundingRectHeight:function(){return this.getBoundingRect().height},getBoundingRect:function(t,e){var i=this.getCoords(t,e);return fabric.util.makeBoundingBoxFromPoints(i)},getScaledWidth:function(){return this._getTransformedDimensions().x},getScaledHeight:function(){return this._getTransformedDimensions().y},_constrainScale:function(t){return Math.abs(t)0?Math.atan(o/s):0,l=s/Math.cos(h)/2,u=Math.cos(h+i)*l,f=Math.sin(h+i)*l,d=this.getCenterPoint(),g=t?d:fabric.util.transformPoint(d,r),p=new fabric.Point(g.x-u,g.y-f),v=new fabric.Point(p.x+s*c,p.y+s*a),m=new fabric.Point(p.x-o*a,p.y+o*c),b=new fabric.Point(g.x+u,g.y+f);if(!t)var _=new fabric.Point((p.x+m.x)/2,(p.y+m.y)/2),y=new fabric.Point((v.x+p.x)/2,(v.y+p.y)/2),x=new fabric.Point((b.x+v.x)/2,(b.y+v.y)/2),C=new fabric.Point((b.x+m.x)/2,(b.y+m.y)/2),S=new fabric.Point(y.x+a*this.rotatingPointOffset,y.y-c*this.rotatingPointOffset);g={tl:p,tr:v,br:b,bl:m};return t||(g.ml=_,g.mt=y,g.mr=x,g.mb=C,g.mtr=S),g},setCoords:function(t,e){return this.oCoords=this.calcCoords(t),e||(this.aCoords=this.calcCoords(!0)),t||this._setCornerCoords&&this._setCornerCoords(),this},_calcRotateMatrix:function(){if(this.angle){var t=e(this.angle),i=Math.cos(t),r=Math.sin(t);return 6.123233995736766e-17!==i&&-1.8369701987210297e-16!==i||(i=0),[i,r,-r,i,0,0]}return fabric.iMatrix.concat()},calcTransformMatrix:function(t){var e,r,n=this.getCenterPoint(),s=[1,0,0,1,n.x,n.y],o=this._calcDimensionsTransformMatrix(this.skewX,this.skewY,!0);return r=this.group&&!t?i(this.group.calcTransformMatrix(),s):s,this.angle&&(e=this._calcRotateMatrix(),r=i(r,e)),r=i(r,o)},_calcDimensionsTransformMatrix:function(t,r,n){var s,o=[this.scaleX*(n&&this.flipX?-1:1),0,0,this.scaleY*(n&&this.flipY?-1:1),0,0];return t&&(s=[1,0,Math.tan(e(t)),1],o=i(o,s,!0)),r&&(s=[1,Math.tan(e(r)),0,1],o=i(o,s,!0)),o},_getNonTransformedDimensions:function(){var t=this.strokeWidth;return{x:this.width+t,y:this.height+t}},_getTransformedDimensions:function(t,e){void 0===t&&(t=this.skewX),void 0===e&&(e=this.skewY);var i,r,n=this._getNonTransformedDimensions(),s=n.x/2,o=n.y/2,a=[{x:-s,y:-o},{x:s,y:-o},{x:-s,y:o},{x:s,y:o}],c=this._calcDimensionsTransformMatrix(t,e,!1);for(i=0;i\n')},_createBaseSVGMarkup:function(){var t=[];return this.fill&&this.fill.toLive&&t.push(this.fill.toSVG(this,!1)),this.stroke&&this.stroke.toLive&&t.push(this.stroke.toSVG(this,!1)),this.shadow&&t.push(this.shadow.toSVG(this)),t}})}(),function(){function t(t,e,r){var n={};r.forEach(function(e){n[e]=t[e]}),i(t[e],n,!0)}function e(t,i,r){if(t===i)return!0;if(Array.isArray(t)){if(t.length!==i.length)return!1;for(var n=0,s=t.length;n\n'),t?t(e.join("")):e.join("")}}),i.Line.ATTRIBUTE_NAMES=i.SHARED_ATTRIBUTES.concat("x1 y1 x2 y2".split(" ")),i.Line.fromElement=function(t,e,n){n=n||{};var s=i.parseAttributes(t,i.Line.ATTRIBUTE_NAMES),o=[s.x1||0,s.y1||0,s.x2||0,s.y2||0];e(new i.Line(o,r(s,n)))},i.Line.fromObject=function(t,e){var r=n(t,!0);r.points=[t.x1,t.y1,t.x2,t.y2],i.Object._fromObject("Line",r,function(t){delete t.points,e&&e(t)},"points")}}}("undefined"!=typeof exports?exports:this),function(t){"use strict";function e(t){return"radius"in t&&t.radius>=0}var i=t.fabric||(t.fabric={}),r=Math.PI,n=i.util.object.extend;if(i.Circle)i.warn("fabric.Circle is already defined.");else{var s=i.Object.prototype.cacheProperties.concat();s.push("radius"),i.Circle=i.util.createClass(i.Object,{type:"circle",radius:0,startAngle:0,endAngle:2*r,cacheProperties:s,initialize:function(t){this.callSuper("initialize",t),this.set("radius",t&&t.radius||0)},_set:function(t,e){return this.callSuper("_set",t,e),"radius"===t&&this.setRadius(e),this},toObject:function(t){return this.callSuper("toObject",["radius","startAngle","endAngle"].concat(t))},toSVG:function(t){var e=this._createBaseSVGMarkup(),i=(this.endAngle-this.startAngle)%(2*r);if(0===i)e.push("\n');else{var n=Math.cos(this.startAngle)*this.radius,s=Math.sin(this.startAngle)*this.radius,o=Math.cos(this.endAngle)*this.radius,a=Math.sin(this.endAngle)*this.radius,c=i>r?"1":"0";e.push('\n')}return t?t(e.join("")):e.join("")},_render:function(t){t.beginPath(),t.arc(0,0,this.radius,this.startAngle,this.endAngle,!1),this._renderFill(t),this._renderStroke(t)},getRadiusX:function(){return this.get("radius")*this.get("scaleX")},getRadiusY:function(){return this.get("radius")*this.get("scaleY")},setRadius:function(t){return this.radius=t,this.set("width",2*t).set("height",2*t)}}),i.Circle.ATTRIBUTE_NAMES=i.SHARED_ATTRIBUTES.concat("cx cy r".split(" ")),i.Circle.fromElement=function(t,r,s){s||(s={});var o=i.parseAttributes(t,i.Circle.ATTRIBUTE_NAMES);if(!e(o))throw new Error("value of `r` attribute is required and can not be negative");o.left=(o.left||0)-o.radius,o.top=(o.top||0)-o.radius,r(new i.Circle(n(o,s)))},i.Circle.fromObject=function(t,e){return i.Object._fromObject("Circle",t,e)}}}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={});e.Triangle?e.warn("fabric.Triangle is already defined"):(e.Triangle=e.util.createClass(e.Object,{type:"triangle",initialize:function(t){this.callSuper("initialize",t),this.set("width",t&&t.width||100).set("height",t&&t.height||100)},_render:function(t){var e=this.width/2,i=this.height/2;t.beginPath(),t.moveTo(-e,i),t.lineTo(0,-i),t.lineTo(e,i),t.closePath(),this._renderFill(t),this._renderStroke(t)},_renderDashedStroke:function(t){var i=this.width/2,r=this.height/2;t.beginPath(),e.util.drawDashedLine(t,-i,r,0,-r,this.strokeDashArray),e.util.drawDashedLine(t,0,-r,i,r,this.strokeDashArray),e.util.drawDashedLine(t,i,r,-i,r,this.strokeDashArray),t.closePath()},toSVG:function(t){var e=this._createBaseSVGMarkup(),i=this.width/2,r=this.height/2,n=[-i+" "+r,"0 "+-r,i+" "+r].join(",");return e.push("'),t?t(e.join("")):e.join("")}}),e.Triangle.fromObject=function(t,i){return e.Object._fromObject("Triangle",t,i)})}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=2*Math.PI,r=e.util.object.extend;if(e.Ellipse)e.warn("fabric.Ellipse is already defined.");else{var n=e.Object.prototype.cacheProperties.concat();n.push("rx","ry"),e.Ellipse=e.util.createClass(e.Object,{type:"ellipse",rx:0,ry:0,cacheProperties:n,initialize:function(t){this.callSuper("initialize",t),this.set("rx",t&&t.rx||0),this.set("ry",t&&t.ry||0)},_set:function(t,e){switch(this.callSuper("_set",t,e),t){case"rx":this.rx=e,this.set("width",2*e);break;case"ry":this.ry=e,this.set("height",2*e)}return this},getRx:function(){return this.get("rx")*this.get("scaleX")},getRy:function(){return this.get("ry")*this.get("scaleY")},toObject:function(t){return this.callSuper("toObject",["rx","ry"].concat(t))},toSVG:function(t){var e=this._createBaseSVGMarkup();return e.push("\n'),t?t(e.join("")):e.join("")},_render:function(t){t.beginPath(),t.save(),t.transform(1,0,0,this.ry/this.rx,0,0),t.arc(0,0,this.rx,0,i,!1),t.restore(),this._renderFill(t),this._renderStroke(t)}}),e.Ellipse.ATTRIBUTE_NAMES=e.SHARED_ATTRIBUTES.concat("cx cy rx ry".split(" ")),e.Ellipse.fromElement=function(t,i,n){n||(n={});var s=e.parseAttributes(t,e.Ellipse.ATTRIBUTE_NAMES);s.left=(s.left||0)-s.rx,s.top=(s.top||0)-s.ry,i(new e.Ellipse(r(s,n)))},e.Ellipse.fromObject=function(t,i){return e.Object._fromObject("Ellipse",t,i)}}}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=e.util.object.extend;if(e.Rect)e.warn("fabric.Rect is already defined");else{var r=e.Object.prototype.stateProperties.concat();r.push("rx","ry");var n=e.Object.prototype.cacheProperties.concat();n.push("rx","ry"),e.Rect=e.util.createClass(e.Object,{stateProperties:r,type:"rect",rx:0,ry:0,cacheProperties:n,initialize:function(t){this.callSuper("initialize",t),this._initRxRy()},_initRxRy:function(){this.rx&&!this.ry?this.ry=this.rx:this.ry&&!this.rx&&(this.rx=this.ry)},_render:function(t){if(1!==this.width||1!==this.height){var e=this.rx?Math.min(this.rx,this.width/2):0,i=this.ry?Math.min(this.ry,this.height/2):0,r=this.width,n=this.height,s=-this.width/2,o=-this.height/2,a=0!==e||0!==i,c=.4477152502;t.beginPath(),t.moveTo(s+e,o),t.lineTo(s+r-e,o),a&&t.bezierCurveTo(s+r-c*e,o,s+r,o+c*i,s+r,o+i),t.lineTo(s+r,o+n-i),a&&t.bezierCurveTo(s+r,o+n-c*i,s+r-c*e,o+n,s+r-e,o+n),t.lineTo(s+e,o+n),a&&t.bezierCurveTo(s+c*e,o+n,s,o+n-c*i,s,o+n-i),t.lineTo(s,o+i),a&&t.bezierCurveTo(s,o+c*i,s+c*e,o,s+e,o),t.closePath(),this._renderFill(t),this._renderStroke(t)}else t.fillRect(-.5,-.5,1,1)},_renderDashedStroke:function(t){var i=-this.width/2,r=-this.height/2,n=this.width,s=this.height;t.beginPath(),e.util.drawDashedLine(t,i,r,i+n,r,this.strokeDashArray),e.util.drawDashedLine(t,i+n,r,i+n,r+s,this.strokeDashArray),e.util.drawDashedLine(t,i+n,r+s,i,r+s,this.strokeDashArray),e.util.drawDashedLine(t,i,r+s,i,r,this.strokeDashArray),t.closePath()},toObject:function(t){return this.callSuper("toObject",["rx","ry"].concat(t))},toSVG:function(t){var e=this._createBaseSVGMarkup(),i=-this.width/2,r=-this.height/2;return e.push("\n'),t?t(e.join("")):e.join("")}}),e.Rect.ATTRIBUTE_NAMES=e.SHARED_ATTRIBUTES.concat("x y rx ry width height".split(" ")),e.Rect.fromElement=function(t,r,n){if(!t)return r(null);n=n||{};var s=e.parseAttributes(t,e.Rect.ATTRIBUTE_NAMES);s.left=s.left||0,s.top=s.top||0;var o=new e.Rect(i(n?e.util.object.clone(n):{},s));o.visible=o.visible&&o.width>0&&o.height>0,r(o)},e.Rect.fromObject=function(t,i){return e.Object._fromObject("Rect",t,i)}}}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=e.util.object.extend,r=e.util.array.min,n=e.util.array.max,s=e.util.toFixed,o=e.Object.NUM_FRACTION_DIGITS;if(e.Polyline)e.warn("fabric.Polyline is already defined");else{var a=e.Object.prototype.cacheProperties.concat();a.push("points"),e.Polyline=e.util.createClass(e.Object,{type:"polyline",points:null,cacheProperties:a,initialize:function(t,e){e=e||{},this.points=t||[],this.callSuper("initialize",e);var i=this._calcDimensions();void 0===e.left&&(this.left=i.left),void 0===e.top&&(this.top=i.top),this.width=i.width,this.height=i.height,this.pathOffset={x:i.left+this.width/2,y:i.top+this.height/2}},_calcDimensions:function(){var t=this.points,e=r(t,"x")||0,i=r(t,"y")||0;return{left:e,top:i,width:(n(t,"x")||0)-e,height:(n(t,"y")||0)-i}},toObject:function(t){return i(this.callSuper("toObject",t),{points:this.points.concat()})},toSVG:function(t){for(var e=[],i=this.pathOffset.x,r=this.pathOffset.y,n=this._createBaseSVGMarkup(),a=0,c=this.points.length;a\n'),t?t(n.join("")):n.join("")},commonRender:function(t){var e,i=this.points.length,r=this.pathOffset.x,n=this.pathOffset.y;if(!i||isNaN(this.points[i-1].y))return!1;t.beginPath(),t.moveTo(this.points[0].x-r,this.points[0].y-n);for(var s=0;s"},toObject:function(t){return n(this.callSuper("toObject",t),{path:this.path.map(function(t){return t.slice()}),top:this.top,left:this.left})},toDatalessObject:function(t){var e=this.toObject(["sourcePath"].concat(t));return e.sourcePath&&delete e.path,e},toSVG:function(t){for(var e=[],i=this._createBaseSVGMarkup(),r="",n=0,s=this.path.length;n\n"),t?t(i.join("")):i.join("")},complexity:function(){return this.path.length},_parsePath:function(){for(var t,e,i,r,n,s=[],o=[],h=/([-+]?((\d+\.\d+)|((\d+)|(\.\d+)))(?:e[-+]?\d+)?)/gi,l=0,u=this.path.length;lp)for(var m=1,b=n.length;m"},addWithUpdate:function(t){return this._restoreObjectsState(),e.util.resetObjectTransform(this),t&&(this._objects.push(t),t.group=this,t._set("canvas",this.canvas)),this._calcBounds(),this._updateObjectsCoords(),this.setCoords(),this.dirty=!0,this},removeWithUpdate:function(t){return this._restoreObjectsState(),e.util.resetObjectTransform(this),this.remove(t),this._calcBounds(),this._updateObjectsCoords(),this.setCoords(),this.dirty=!0,this},_onObjectAdded:function(t){this.dirty=!0,t.group=this,t._set("canvas",this.canvas)},_onObjectRemoved:function(t){this.dirty=!0,delete t.group},_set:function(t,e){var i=this._objects.length;if(this.useSetOnGroup)for(;i--;)this._objects[i].setOnGroup(t,e);if("canvas"===t)for(i=this._objects.length;i--;)this._objects[i]._set(t,e);this.callSuper("_set",t,e)},toObject:function(t){var e=this.getObjects().map(function(e){var i=e.includeDefaultValues;e.includeDefaultValues=e.group.includeDefaultValues;var r=e.toObject(t);return e.includeDefaultValues=i,r});return i(this.callSuper("toObject",t),{objects:e})},toDatalessObject:function(t){var e,r=this.sourcePath;return e=r||this.getObjects().map(function(e){var i=e.includeDefaultValues;e.includeDefaultValues=e.group.includeDefaultValues;var r=e.toDatalessObject(t);return e.includeDefaultValues=i,r}),i(this.callSuper("toDatalessObject",t),{objects:e})},render:function(t){this._transformDone=!0,this.callSuper("render",t),this._transformDone=!1},shouldCache:function(){var t=this.objectCaching&&(!this.group||this.needsItsOwnCache()||!this.group.isOnACache());if(this.ownCaching=t,t)for(var e=0,i=this._objects.length;e\n');for(var i=0,r=this._objects.length;i\n"),t?t(e.join("")):e.join("")}}),e.Group.fromObject=function(t,i){e.util.enlivenObjects(t.objects,function(r){var n=e.util.object.clone(t,!0);delete n.objects,i&&i(new e.Group(r,n,!0))})})}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={});e.ActiveSelection||(e.ActiveSelection=e.util.createClass(e.Group,{type:"activeSelection",initialize:function(t,i){i=i||{},this._objects=t||[];for(var r=this._objects.length;r--;)this._objects[r].group=this;i.originX&&(this.originX=i.originX),i.originY&&(this.originY=i.originY),this._calcBounds(),this._updateObjectsCoords(),e.Object.prototype.initialize.call(this,i),this.setCoords()},toGroup:function(){var t=this._objects;this._objects=[];var i=this.toObject(),r=new e.Group([]);if(delete i.objects,r.set(i),r.type="group",t.forEach(function(t){t.group=r,t.canvas.remove(t)}),r._objects=t,!this.canvas)return r;var n=this.canvas;return n.add(r),n._activeObject=r,r.setCoords(),r},onDeselect:function(){return this.destroy(),!1},toString:function(){return"#"},_set:function(t,i){var r=this._objects.length;if("canvas"===t)for(;r--;)this._objects[r].set(t,i);if(this.useSetOnGroup)for(;r--;)this._objects[r].setOnGroup(t,i);e.Object.prototype._set.call(this,t,i)},shouldCache:function(){return!1},willDrawShadow:function(){if(this.shadow)return this.callSuper("willDrawShadow");for(var t=0,e=this._objects.length;t\n',"\t\n'),this.stroke||this.strokeDashArray){var n=this.fill;this.fill=null,e.push("\n'),this.fill=n}return e.push("\n"),t?t(e.join("")):e.join("")},getSrc:function(t){var e=t?this._element:this._originalElement;return e?e.toDataURL?e.toDataURL():fabric.isLikelyNode?e._src:e.src:this.src||""},setSrc:function(t,e,i){return fabric.util.loadImage(t,function(t){this.setElement(t,i),e(this)},this,i&&i.crossOrigin),this},toString:function(){return'#'},applyResizeFilters:function(){var t=this.resizeFilter,e=this.canvas?this.canvas.getRetinaScaling():1,i=this.minimumScaleTrigger,r=this.scaleX=1&&n>=1)this._element=this._filteredEl;else{fabric.filterBackend||(fabric.filterBackend=fabric.initFilterBackend());var s,o=this._filteredEl||this._originalElement;if(this._element===this._originalElement){var a=fabric.util.createCanvasElement();a.width=o.width,a.height=o.height,this._element=a}var c=this._element.getContext("2d");o.getContext?s=o.getContext("2d").getImageData(0,0,o.width,o.height):(c.drawImage(o,0,0),s=c.getImageData(0,0,o.width,o.height));var h={imageData:s,scaleX:r,scaleY:n};t.applyTo2d(h),this.width=this._element.width=h.imageData.width,this.height=this._element.height=h.imageData.height,c.putImageData(h.imageData,0,0)}},applyFilters:function(t){if(t=t||this.filters||[],0===(t=t.filter(function(t){return t})).length)return this._element=this._originalElement,this._filterScalingX=1,this._filterScalingY=1,this;var e=this._originalElement,i=e.naturalWidth||e.width,r=e.naturalHeight||e.height;if(this._element===this._originalElement){var n=fabric.util.createCanvasElement();n.width=e.width,n.height=e.height,this._element=n}else this._element.getContext("2d").clearRect(0,0,i,r);return fabric.filterBackend||(fabric.filterBackend=fabric.initFilterBackend()),fabric.filterBackend.applyFilters(t,this._originalElement,i,r,this._element,this.cacheKey),this.width===this._element.width&&this.height===this._element.height||(this._filterScalingX=this._element.width/this.width,this._filterScalingY=this._element.height/this.height,this.width=this._element.width,this.height=this._element.height),this},_render:function(t){var e,i=-this.width/2,r=-this.height/2;!1===this.isMoving&&this.resizeFilter&&this._needsResize()&&(this._lastScaleX=this.scaleX,this._lastScaleY=this.scaleY,this.applyResizeFilters()),(e=this._element)&&t.drawImage(e,this.cropX,this.cropY,this.width,this.height,i,r,this.width,this.height),this._stroke(t),this._renderStroke(t)},_needsResize:function(){return this.scaleX!==this._lastScaleX||this.scaleY!==this._lastScaleY},_resetWidthHeight:function(){var t=this.getElement();this.set("width",t.width),this.set("height",t.height)},_initElement:function(t,e){this.setElement(fabric.util.getById(t),e),fabric.util.addClass(this.getElement(),fabric.Image.CSS_CANVAS)},_initConfig:function(t){t||(t={}),this.setOptions(t),this._setWidthHeight(t),this._element&&this.crossOrigin&&(this._element.crossOrigin=this.crossOrigin)},_initFilters:function(t,e){t&&t.length?fabric.util.enlivenObjects(t,function(t){e&&e(t)},"fabric.Image.filters"):e&&e()},_setWidthHeight:function(t){this.width="width"in t?t.width:this.getElement()?this.getElement().width||0:0,this.height="height"in t?t.height:this.getElement()?this.getElement().height||0:0},parsePreserveAspectRatioAttribute:function(){if(this.preserveAspectRatio){var t,e=fabric.util.parsePreserveAspectRatioAttribute(this.preserveAspectRatio),i=this._element.width,r=this._element.height,n=this.width,s=this.height,o={width:n,height:s};!e||"none"===e.alignX&&"none"===e.alignY?(this.scaleX=n/i,this.scaleY=s/r):("meet"===e.meetOrSlice&&(this.width=i,this.height=r,this.scaleX=this.scaleY=t=fabric.util.findScaleToFit(this._element,o),"Mid"===e.alignX&&(this.left+=(n-i*t)/2),"Max"===e.alignX&&(this.left+=n-i*t),"Mid"===e.alignY&&(this.top+=(s-r*t)/2),"Max"===e.alignY&&(this.top+=s-r*t)),"slice"===e.meetOrSlice&&(this.scaleX=this.scaleY=t=fabric.util.findScaleToCover(this._element,o),this.width=n/t,this.height=s/t,"Mid"===e.alignX&&(this.cropX=(i-this.width)/2),"Max"===e.alignX&&(this.cropX=i-this.width),"Mid"===e.alignY&&(this.cropY=(r-this.height)/2),"Max"===e.alignY&&(this.cropY=r-this.height)))}}}),fabric.Image.CSS_CANVAS="canvas-img",fabric.Image.prototype.getSvgSrc=fabric.Image.prototype.getSrc,fabric.Image.fromObject=function(t,e){fabric.util.loadImage(t.src,function(i,r){r?e&&e(null,r):fabric.Image.prototype._initFilters.call(t,t.filters,function(r){t.filters=r||[],fabric.Image.prototype._initFilters.call(t,[t.resizeFilter],function(r){t.resizeFilter=r[0];var n=new fabric.Image(i,t);e(n)})})},null,t.crossOrigin)},fabric.Image.fromURL=function(t,e,i){fabric.util.loadImage(t,function(t){e&&e(new fabric.Image(t,i))},null,i&&i.crossOrigin)},fabric.Image.ATTRIBUTE_NAMES=fabric.SHARED_ATTRIBUTES.concat("x y width height preserveAspectRatio xlink:href crossOrigin".split(" ")),fabric.Image.fromElement=function(t,i,r){var n=fabric.parseAttributes(t,fabric.Image.ATTRIBUTE_NAMES);fabric.Image.fromURL(n["xlink:href"],i,e(r?fabric.util.object.clone(r):{},n))}}}("undefined"!=typeof exports?exports:this),fabric.util.object.extend(fabric.Object.prototype,{_getAngleValueForStraighten:function(){var t=this.angle%360;return t>0?90*Math.round((t-1)/90):90*Math.round(t/90)},straighten:function(){return this.rotate(this._getAngleValueForStraighten()),this},fxStraighten:function(t){var e=function(){},i=(t=t||{}).onComplete||e,r=t.onChange||e,n=this;return fabric.util.animate({startValue:this.get("angle"),endValue:this._getAngleValueForStraighten(),duration:this.FX_DURATION,onChange:function(t){n.rotate(t),r()},onComplete:function(){n.setCoords(),i()}}),this}}),fabric.util.object.extend(fabric.StaticCanvas.prototype,{straightenObject:function(t){return t.straighten(),this.requestRenderAll(),this},fxStraightenObject:function(t){return t.fxStraighten({onChange:this.requestRenderAllBound}),this}}),function(){"use strict";function t(t){t&&t.tileSize&&(this.tileSize=t.tileSize),this.setupGLContext(this.tileSize,this.tileSize),this.captureGPUInfo()}fabric.isWebglSupported=function(t){if(fabric.isLikelyNode)return!1;t=t||fabric.WebglFilterBackend.prototype.tileSize;var e=document.createElement("canvas"),i=e.getContext("webgl")||e.getContext("experimental-webgl"),r=!1;return i&&(fabric.maxTextureSize=i.getParameter(i.MAX_TEXTURE_SIZE),r=fabric.maxTextureSize>=t),this.isSupported=r,r},fabric.WebglFilterBackend=t,t.prototype={tileSize:2048,resources:{},setupGLContext:function(t,e){this.dispose(),this.createWebGLCanvas(t,e),this.squareVertices=new Float32Array([0,0,0,1,1,0,1,1]),this.chooseFastestCopyGLTo2DMethod(t,e)},chooseFastestCopyGLTo2DMethod:function(t,e){var i,r=void 0!==window.performance;try{new ImageData(1,1),i=!0}catch(t){i=!1}var n="undefined"!=typeof ArrayBuffer,s="undefined"!=typeof Uint8ClampedArray;if(r&&i&&n&&s){var o,a,c=fabric.util.createCanvasElement(),h=new ArrayBuffer(t*e*4),l={imageBuffer:h};c.width=t,c.height=e,o=window.performance.now(),copyGLTo2DDrawImage.call(l,this.gl,c),a=window.performance.now()-o,o=window.performance.now(),copyGLTo2DPutImageData.call(l,this.gl,c),a>window.performance.now()-o?(this.imageBuffer=h,this.copyGLTo2D=copyGLTo2DPutImageData):this.copyGLTo2D=copyGLTo2DDrawImage}},createWebGLCanvas:function(t,e){var i=fabric.util.createCanvasElement();i.width=t,i.height=e;var r={premultipliedAlpha:!1},n=i.getContext("webgl",r);n||(n=i.getContext("experimental-webgl",r)),n&&(n.clearColor(0,0,0,0),this.canvas=i,this.gl=n)},applyFilters:function(t,e,i,r,n,s){var o,a=this.gl;s&&(o=this.getCachedTexture(s,e));var c={originalWidth:e.width||e.originalWidth,originalHeight:e.height||e.originalHeight,sourceWidth:i,sourceHeight:r,context:a,sourceTexture:this.createTexture(a,i,r,!o&&e),targetTexture:this.createTexture(a,i,r),originalTexture:o||this.createTexture(a,i,r,!o&&e),passes:t.length,webgl:!0,squareVertices:this.squareVertices,programCache:this.programCache,pass:0,filterBackend:this},h=a.createFramebuffer();return a.bindFramebuffer(a.FRAMEBUFFER,h),t.forEach(function(t){t&&t.applyTo(c)}),this.copyGLTo2D(a,n),a.bindTexture(a.TEXTURE_2D,null),a.deleteTexture(c.sourceTexture),a.deleteTexture(c.targetTexture),a.deleteFramebuffer(h),n.getContext("2d").setTransform(1,0,0,1,0,0),c},applyFiltersDebug:function(t,e,i,r,n,s){var o=this.gl,a=this.applyFilters(t,e,i,r,n,s),c=o.getError();if(c!==o.NO_ERROR){var h=this.glErrorToString(o,c),l=new Error("WebGL Error "+h);throw l.glErrorCode=c,l}return a},glErrorToString:function(t,e){if(!t)return"Context undefined for error code: "+e;if("number"!=typeof e)return"Error code is not a number";switch(e){case t.NO_ERROR:return"NO_ERROR";case t.INVALID_ENUM:return"INVALID_ENUM";case t.INVALID_VALUE:return"INVALID_VALUE";case t.INVALID_OPERATION:return"INVALID_OPERATION";case t.INVALID_FRAMEBUFFER_OPERATION:return"INVALID_FRAMEBUFFER_OPERATION";case t.OUT_OF_MEMORY:return"OUT_OF_MEMORY";case t.CONTEXT_LOST_WEBGL:return"CONTEXT_LOST_WEBGL";default:return"UNKNOWN_ERROR"}},dispose:function(){this.canvas&&(this.canvas=null,this.gl=null),this.clearWebGLCaches()},clearWebGLCaches:function(){this.programCache={},this.textureCache={}},createTexture:function(t,e,i,r){var n=t.createTexture();return t.bindTexture(t.TEXTURE_2D,n),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.LINEAR),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.LINEAR),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),r?t.texImage2D(t.TEXTURE_2D,0,t.RGBA,t.RGBA,t.UNSIGNED_BYTE,r):t.texImage2D(t.TEXTURE_2D,0,t.RGBA,e,i,0,t.RGBA,t.UNSIGNED_BYTE,null),n},getCachedTexture:function(t,e){if(this.textureCache[t])return this.textureCache[t];var i=this.createTexture(this.gl,e.width,e.height,e);return this.textureCache[t]=i,i},evictCachesForKey:function(t){this.textureCache[t]&&(this.gl.deleteTexture(this.textureCache[t]),delete this.textureCache[t])},copyGLTo2D:copyGLTo2DDrawImage,captureGPUInfo:function(){if(this.gpuInfo)return this.gpuInfo;var t=this.gl,e=t.getExtension("WEBGL_debug_renderer_info"),i={renderer:"",vendor:""};if(e){var r=t.getParameter(e.UNMASKED_RENDERER_WEBGL),n=t.getParameter(e.UNMASKED_VENDOR_WEBGL);r&&(i.renderer=r.toLowerCase()),n&&(i.vendor=n.toLowerCase())}return this.gpuInfo=i,i}}}(),function(){"use strict";function t(){}var e=function(){};fabric.Canvas2dFilterBackend=t,t.prototype={evictCachesForKey:e,dispose:e,clearWebGLCaches:e,resources:{},applyFilters:function(t,e,i,r,n){var s=n.getContext("2d");s.drawImage(e,0,0,i,r);var o={sourceWidth:i,sourceHeight:r,imageData:s.getImageData(0,0,i,r),originalEl:e,originalImageData:s.getImageData(0,0,i,r),canvasEl:n,ctx:s,filterBackend:this};return t.forEach(function(t){t.applyTo(o)}),o.imageData.width===i&&o.imageData.height===r||(n.width=o.imageData.width,n.height=o.imageData.height),s.putImageData(o.imageData,0,0),o}}}(),fabric.Image.filters=fabric.Image.filters||{},fabric.Image.filters.BaseFilter=fabric.util.createClass({type:"BaseFilter",vertexSource:"attribute vec2 aPosition;\nattribute vec2 aTexCoord;\nvarying vec2 vTexCoord;\nvoid main() {\nvTexCoord = aTexCoord;\ngl_Position = vec4(aPosition * 2.0 - 1.0, 0.0, 1.0);\n}",fragmentSource:"precision highp float;\nvarying vec2 vTexCoord;\nuniform sampler2D uTexture;\nvoid main() {\ngl_FragColor = texture2D(uTexture, vTexCoord);\n}",initialize:function(t){t&&this.setOptions(t)},setOptions:function(t){for(var e in t)this[e]=t[e]},createProgram:function(t,e,i){if(this.vertexSource&&this.fragmentSource){var r=t.createShader(t.VERTEX_SHADER);if(t.shaderSource(r,i||this.vertexSource),t.compileShader(r),!t.getShaderParameter(r,t.COMPILE_STATUS))throw new Error('Vertex shader compile error for "${this.type}": '+t.getShaderInfoLog(r));var n=t.createShader(t.FRAGMENT_SHADER);if(t.shaderSource(n,e||this.fragmentSource),t.compileShader(n),!t.getShaderParameter(n,t.COMPILE_STATUS))throw new Error('Fragment shader compile error for "${this.type}": '+t.getShaderInfoLog(n));var s=t.createProgram();if(t.attachShader(s,r),t.attachShader(s,n),t.linkProgram(s),!t.getProgramParameter(s,t.LINK_STATUS))throw new Error('Shader link error for "${this.type}" '+t.getProgramInfoLog(s));var o=this.getAttributeLocations(t,s),a=this.getUniformLocations(t,s)||{};return a.uStepW=t.getUniformLocation(s,"uStepW"),a.uStepH=t.getUniformLocation(s,"uStepH"),{program:s,attributeLocations:o,uniformLocations:a}}},getAttributeLocations:function(t,e){return{aPosition:t.getAttribLocation(e,"aPosition"),aTexCoord:t.getAttribLocation(e,"aTexCoord")}},getUniformLocations:function(){},sendAttributeData:function(t,e,i){["aPosition","aTexCoord"].forEach(function(r){var n=e[r],s=t.createBuffer();t.bindBuffer(t.ARRAY_BUFFER,s),t.enableVertexAttribArray(n),t.vertexAttribPointer(n,2,t.FLOAT,!1,0,0),t.bufferData(t.ARRAY_BUFFER,i,t.STATIC_DRAW)})},_setupFrameBuffer:function(t){var e=t.context;t.passes>1?e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,t.targetTexture,0):(e.bindFramebuffer(e.FRAMEBUFFER,null),e.finish())},_swapTextures:function(t){t.passes--,t.pass++;var e=t.targetTexture;t.targetTexture=t.sourceTexture,t.sourceTexture=e},isNeutralState:function(){return!1},applyTo:function(t){if(t.webgl){if(t.passes>1&&this.isNeutralState(t))return;this._setupFrameBuffer(t),this.applyToWebGL(t),this._swapTextures(t)}else this.applyTo2d(t)},retrieveShader:function(t){return t.programCache.hasOwnProperty(this.type)||(t.programCache[this.type]=this.createProgram(t.context)),t.programCache[this.type]},applyToWebGL:function(t){var e=t.context,i=this.retrieveShader(t);0===t.pass&&t.originalTexture?e.bindTexture(e.TEXTURE_2D,t.originalTexture):e.bindTexture(e.TEXTURE_2D,t.sourceTexture),e.useProgram(i.program),this.sendAttributeData(e,i.attributeLocations,t.squareVertices),e.uniform1f(i.uniformLocations.uStepW,1/t.sourceWidth),e.uniform1f(i.uniformLocations.uStepH,1/t.sourceHeight),this.sendUniformData(e,i.uniformLocations),e.viewport(0,0,t.sourceWidth,t.sourceHeight),e.drawArrays(e.TRIANGLE_STRIP,0,4)},bindAdditionalTexture:function(t,e,i){t.activeTexture(i),t.bindTexture(t.TEXTURE_2D,e),t.activeTexture(t.TEXTURE0)},unbindAdditionalTexture:function(t,e){t.activeTexture(e),t.bindTexture(t.TEXTURE_2D,null),t.activeTexture(t.TEXTURE0)},getMainParameter:function(){return this[this.mainParameter]},setMainParameter:function(t){this[this.mainParameter]=t},sendUniformData:function(){},createHelpLayer:function(t){if(!t.helpLayer){var e=document.createElement("canvas");e.width=t.sourceWidth,e.height=t.sourceHeight,t.helpLayer=e}},toObject:function(){var t={type:this.type},e=this.mainParameter;return e&&(t[e]=this[e]),t},toJSON:function(){return this.toObject()}}),fabric.Image.filters.BaseFilter.fromObject=function(t,e){var i=new fabric.Image.filters[t.type](t);return e&&e(i),i},function(t){"use strict";var e=t.fabric||(t.fabric={}),i=e.Image.filters,r=e.util.createClass;i.ColorMatrix=r(i.BaseFilter,{type:"ColorMatrix",fragmentSource:"precision highp float;\nuniform sampler2D uTexture;\nvarying vec2 vTexCoord;\nuniform mat4 uColorMatrix;\nuniform vec4 uConstants;\nvoid main() {\nvec4 color = texture2D(uTexture, vTexCoord);\ncolor *= uColorMatrix;\ncolor += uConstants;\ngl_FragColor = color;\n}",matrix:[1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0],mainParameter:"matrix",colorsOnly:!0,initialize:function(t){this.callSuper("initialize",t),this.matrix=this.matrix.slice(0)},applyTo2d:function(t){var e,i,r,n,s,o=t.imageData.data,a=o.length,c=this.matrix,h=this.colorsOnly;for(s=0;sy||o<0||o>_||(c=4*(a*_+o),h=v[d*m+f],e+=p[c]*h,i+=p[c+1]*h,r+=p[c+2]*h,S||(n+=p[c+3]*h));C[s]=e,C[s+1]=i,C[s+2]=r,C[s+3]=S?p[s+3]:n}t.imageData=x},getUniformLocations:function(t,e){return{uMatrix:t.getUniformLocation(e,"uMatrix"),uOpaque:t.getUniformLocation(e,"uOpaque"),uHalfSize:t.getUniformLocation(e,"uHalfSize"),uSize:t.getUniformLocation(e,"uSize")}},sendUniformData:function(t,e){t.uniform1fv(e.uMatrix,this.matrix)},toObject:function(){return i(this.callSuper("toObject"),{opaque:this.opaque,matrix:this.matrix})}}),e.Image.filters.Convolute.fromObject=e.Image.filters.BaseFilter.fromObject}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=e.Image.filters,r=e.util.createClass;i.Grayscale=r(i.BaseFilter,{type:"Grayscale",fragmentSource:{average:"precision highp float;\nuniform sampler2D uTexture;\nvarying vec2 vTexCoord;\nvoid main() {\nvec4 color = texture2D(uTexture, vTexCoord);\nfloat average = (color.r + color.b + color.g) / 3.0;\ngl_FragColor = vec4(average, average, average, color.a);\n}",lightness:"precision highp float;\nuniform sampler2D uTexture;\nuniform int uMode;\nvarying vec2 vTexCoord;\nvoid main() {\nvec4 col = texture2D(uTexture, vTexCoord);\nfloat average = (max(max(col.r, col.g),col.b) + min(min(col.r, col.g),col.b)) / 2.0;\ngl_FragColor = vec4(average, average, average, col.a);\n}",luminosity:"precision highp float;\nuniform sampler2D uTexture;\nuniform int uMode;\nvarying vec2 vTexCoord;\nvoid main() {\nvec4 col = texture2D(uTexture, vTexCoord);\nfloat average = 0.21 * col.r + 0.72 * col.g + 0.07 * col.b;\ngl_FragColor = vec4(average, average, average, col.a);\n}"},mode:"average",mainParameter:"mode",applyTo2d:function(t){var e,i,r=t.imageData.data,n=r.length,s=this.mode;for(e=0;eh[0]&&n>h[1]&&s>h[2]&&r=e)){P=r(1e3*s(c-S.x)),C[P]||(C[P]={});for(var F=w.y-x;F<=w.y+x;F++)F<0||F>=o||(M=r(1e3*s(F-S.y)),C[P][M]||(C[P][M]=p(n(i(P*b,2)+i(M*_,2))/1e3)),(T=C[P][M])>0&&(k+=T,D+=T*f[O=4*(F*e+c)],E+=T*f[O+1],j+=T*f[O+2],A+=T*f[O+3]))}g[O=4*(a*h+t)]=D/k,g[O+1]=E/k,g[O+2]=j/k,g[O+3]=A/k}return++tt)return 0;if(e*=Math.PI,s(e)<1e-16)return 1;var i=e/t;return a(e)*a(i)/e/i}}(this.lanczosLobes),v=this.rcpScaleX,m=this.rcpScaleY,b=2/this.rcpScaleX,_=2/this.rcpScaleY,y=c(v*this.lanczosLobes/2),x=c(m*this.lanczosLobes/2),C={},S={},w={};return u(0)},bilinearFiltering:function(t,e,i,n,s){var o,a,c,h,l,u,f,d,g,p=0,v=this.rcpScaleX,m=this.rcpScaleY,b=4*(e-1),_=t.imageData.data,y=t.ctx.createImageData(n,s),x=y.data;for(c=0;c1&&M<-1||(_=2*M*M*M-3*M*M+1)>0&&(T+=_*d[(P=4*(A+k*e))+3],x+=_,d[P+3]<255&&(_=_*d[P+3]/250),C+=_*d[P],S+=_*d[P+1],w+=_*d[P+2],y+=_)}p[b]=C/y,p[b+1]=S/y,p[b+2]=w/y,p[b+3]=T/x}return g},toObject:function(){return{type:this.type,scaleX:this.scaleX,scaleY:this.scaleY,resizeType:this.resizeType,lanczosLobes:this.lanczosLobes}}}),e.Image.filters.Resize.fromObject=e.Image.filters.BaseFilter.fromObject}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=e.Image.filters,r=e.util.createClass;i.Contrast=r(i.BaseFilter,{type:"Contrast",fragmentSource:"precision highp float;\nuniform sampler2D uTexture;\nuniform float uContrast;\nvarying vec2 vTexCoord;\nvoid main() {\nvec4 color = texture2D(uTexture, vTexCoord);\nfloat contrastF = 1.015 * (uContrast + 1.0) / (1.0 * (1.015 - uContrast));\ncolor.rgb = contrastF * (color.rgb - 0.5) + 0.5;\ngl_FragColor = color;\n}",contrast:0,mainParameter:"contrast",applyTo2d:function(t){if(0!==this.contrast){var e,i=t.imageData.data,r=i.length,n=Math.floor(255*this.contrast),s=259*(n+255)/(255*(259-n));for(e=0;e1&&(e=1/this.aspectRatio):this.aspectRatio<1&&(e=this.aspectRatio),t=e*this.blur*.12,this.horizontal?i[0]=t:i[1]=t,i}}),i.Blur.fromObject=e.Image.filters.BaseFilter.fromObject}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=e.Image.filters,r=e.util.createClass;i.Gamma=r(i.BaseFilter,{type:"Gamma",fragmentSource:"precision highp float;\nuniform sampler2D uTexture;\nuniform vec3 uGamma;\nvarying vec2 vTexCoord;\nvoid main() {\nvec4 color = texture2D(uTexture, vTexCoord);\nvec3 correction = (1.0 / uGamma);\ncolor.r = pow(color.r, correction.r);\ncolor.g = pow(color.g, correction.g);\ncolor.b = pow(color.b, correction.b);\ngl_FragColor = color;\ngl_FragColor.rgb *= color.a;\n}",gamma:[1,1,1],mainParameter:"gamma",applyTo2d:function(t){var e,i=t.imageData.data,r=this.gamma,n=i.length,s=1/r[0],o=1/r[1],a=1/r[2];for(this.rVals||(this.rVals=new Uint8Array(256),this.gVals=new Uint8Array(256),this.bVals=new Uint8Array(256)),e=0,n=256;e'},_getCacheCanvasDimensions:function(){var t=this.callSuper("_getCacheCanvasDimensions"),e=this.fontSize;return t.width+=e*t.zoomX,t.height+=e*t.zoomY,t},_render:function(t){this._setTextStyles(t),this._renderTextLinesBackground(t),this._renderTextDecoration(t,"underline"),this._renderText(t),this._renderTextDecoration(t,"overline"),this._renderTextDecoration(t,"linethrough")},_renderText:function(t){this._renderTextFill(t),this._renderTextStroke(t)},_setTextStyles:function(t,e,i){t.textBaseline="alphabetic",t.font=this._getFontDeclaration(e,i)},calcTextWidth:function(){for(var t=this.getLineWidth(0),e=1,i=this._textLines.length;et&&(t=r)}return t},_renderTextLine:function(t,e,i,r,n,s){this._renderChars(t,e,i,r,n,s)},_renderTextLinesBackground:function(t){if(this.textBackgroundColor||this.styleHas("textBackgroundColor")){for(var e,i,r,n,s,o,a=0,c=t.fillStyle,h=this._getLeftOffset(),l=this._getTopOffset(),u=0,f=0,d=0,g=this._textLines.length;dn)){var d=a-n;c[t]=a,c[h]+=d,n=a}return{width:n*u,kernedWidth:a*u}},getHeightOfChar:function(t,e){return this.getValueOfPropertyAt(t,e,"fontSize")},measureLine:function(t){var e=this._measureLine(t);return 0!==this.charSpacing&&(e.width-=this._getWidthOfCharSpacing()),e.width<0&&(e.width=0),e},_measureLine:function(t){var e,i,r,n,s=0,o=this._textLines[t],a=new Array(o.length);for(this.__charBounds[t]=a,e=0;e0&&!n){var u=this.__charBounds[e][i-1];l.left=u.left+u.width+a.kernedWidth-a.width}return l},getHeightOfLine:function(t){if(this.__lineHeights[t])return this.__lineHeights[t];for(var e=this._textLines[t],i=this.getHeightOfChar(t,0),r=1,n=e.length;ri&&(i=s)}return this.__lineHeights[t]=i*this.lineHeight*this._fontSizeMult,this.__lineHeights[t]},calcTextHeight:function(){for(var t,e=0,i=0,r=this._textLines.length;i0?(t.fillStyle=f,s&&f&&t.fillRect(d+r+o,g+l*(1-this._fontSizeFraction)+this.offsets[e]*this.fontSize,a,this.fontSize/15),o=c.left,a=c.width,s=h,f=u):a+=c.kernedWidth;t.fillStyle=u,h&&u&&t.fillRect(d+r+o,g+l*(1-this._fontSizeFraction)+this.offsets[e]*this.fontSize,a,this.fontSize/15),g+=i}else g+=i;this._removeShadow(t)}},_getFontDeclaration:function(t,i){var r=t||this;return[e.isLikelyNode?r.fontWeight:r.fontStyle,e.isLikelyNode?r.fontStyle:r.fontWeight,i?"200px":r.fontSize+"px",e.isLikelyNode?'"'+r.fontFamily+'"':r.fontFamily].join(" ")},render:function(t){this.visible&&(this.canvas&&this.canvas.skipOffscreen&&!this.group&&!this.isOnScreen()||(this._shouldClearDimensionCache()&&this.initDimensions(),this.callSuper("render",t)))},_splitTextIntoLines:function(t){for(var i=t.split(this._reNewline),r=new Array(i.length),n=["\n"],s=[],o=0;o-1&&(this.initDimensions(),this.setCoords())},complexity:function(){return 1}}),e.Text.ATTRIBUTE_NAMES=e.SHARED_ATTRIBUTES.concat("x y dx dy font-family font-style font-weight font-size text-decoration text-anchor".split(" ")),e.Text.DEFAULT_SVG_FONT_SIZE=16,e.Text.fromElement=function(t,r,n){if(!t)return r(null);var s=e.parseAttributes(t,e.Text.ATTRIBUTE_NAMES),o=s.textAnchor||"left";if(n=e.util.object.extend(n?i(n):{},s),n.top=n.top||0,n.left=n.left||0,s.textDecoration){var a=s.textDecoration;-1!==a.indexOf("underline")&&(n.underline=!0),-1!==a.indexOf("overline")&&(n.overline=!0),-1!==a.indexOf("line-through")&&(n.linethrough=!0),delete n.textDecoration}"dx"in s&&(n.left+=s.dx),"dy"in s&&(n.top+=s.dy),"fontSize"in n||(n.fontSize=e.Text.DEFAULT_SVG_FONT_SIZE);var c="";"textContent"in t?c=t.textContent:"firstChild"in t&&null!==t.firstChild&&"data"in t.firstChild&&null!==t.firstChild.data&&(c=t.firstChild.data),c=c.replace(/^\s+|\s+$|\n+/g,"").replace(/\s+/g," ");var h=new e.Text(c,n),l=h.getScaledHeight()/h.height,u=((h.height+h.strokeWidth)*h.lineHeight-h.height)*l,f=h.getScaledHeight()+u,d=0;"center"===o&&(d=h.getScaledWidth()/2),"right"===o&&(d=h.getScaledWidth()),h.set({left:h.left-d,top:h.top-(f-h.fontSize*(.18+h._fontSizeFraction))/h.lineHeight}),r(h)},e.Text.fromObject=function(t,i){return e.Object._fromObject("Text",t,i,"text")},e.util.createAccessors&&e.util.createAccessors(e.Text)}}("undefined"!=typeof exports?exports:this),fabric.util.object.extend(fabric.Text.prototype,{isEmptyStyles:function(t){if(!this.styles)return!0;if(void 0!==t&&!this.styles[t])return!0;var e=void 0===t?this.styles:{line:this.styles[t]};for(var i in e)for(var r in e[i])for(var n in e[i][r])return!1;return!0},styleHas:function(t,e){if(!this.styles||!t||""===t)return!1;if(void 0!==e&&!this.styles[e])return!1;var i=void 0===e?this.styles:{line:this.styles[e]};for(var r in i)for(var n in i[r])if(void 0!==i[r][n][t])return!0;return!1},cleanStyle:function(t){if(!this.styles||!t||""===t)return!1;var e,i,r=this.styles,n=0,s=!1,o=!0,a=0;for(var c in r){e=0;for(var h in r[c])n++,s?r[c][h][t]!==i&&(o=!1):(i=r[c][h][t],s=!0),r[c][h][t]===this[t]&&delete r[c][h][t],0!==Object.keys(r[c][h]).length?e++:delete r[c][h];0===e&&delete r[c]}for(var l=0;l-1&&(t.underline=!0),t.textDecoration.indexOf("line-through")>-1&&(t.linethrough=!0),t.textDecoration.indexOf("overline")>-1&&(t.overline=!0),delete t.textDecoration)}fabric.IText=fabric.util.createClass(fabric.Text,fabric.Observable,{type:"i-text",selectionStart:0,selectionEnd:0,selectionColor:"rgba(17,119,255,0.3)",isEditing:!1,editable:!0,editingBorderColor:"rgba(102,153,255,0.25)",cursorWidth:2,cursorColor:"#333",cursorDelay:1e3,cursorDuration:600,caching:!0,_reSpace:/\s|\n/,_currentCursorOpacity:0,_selectionDirection:null,_abortCursorAnimation:!1,__widthOfSpace:[],inCompositionMode:!1,initialize:function(t,e){this.callSuper("initialize",t,e),this.initBehavior()},setSelectionStart:function(t){t=Math.max(t,0),this._updateAndFire("selectionStart",t)},setSelectionEnd:function(t){t=Math.min(t,this.text.length),this._updateAndFire("selectionEnd",t)},_updateAndFire:function(t,e){this[t]!==e&&(this._fireSelectionChanged(),this[t]=e),this._updateTextarea()},_fireSelectionChanged:function(){this.fire("selection:changed"),this.canvas&&this.canvas.fire("text:selection:changed",{target:this})},initDimensions:function(){this.isEditing&&this.initDelayedCursor(),this.clearContextTop(),this.callSuper("initDimensions")},render:function(t){this.clearContextTop(),this.callSuper("render",t),this.cursorOffsetCache={},this.renderCursorOrSelection()},_render:function(t){this.callSuper("_render",t),this.ctx=t},clearContextTop:function(t){if(this.isEditing&&this.canvas&&this.canvas.contextTop){var e=this.canvas.contextTop;e.save(),e.transform.apply(e,this.canvas.viewportTransform),this.transform(e),this.transformMatrix&&e.transform.apply(e,this.transformMatrix),this._clearTextArea(e),t||e.restore()}},renderCursorOrSelection:function(){if(this.isEditing){var t,e=this._getCursorBoundaries();this.canvas&&this.canvas.contextTop?(t=this.canvas.contextTop,this.clearContextTop(!0)):(t=this.ctx).save(),this.selectionStart===this.selectionEnd?this.renderCursor(e,t):this.renderSelection(e,t),t.restore()}},_clearTextArea:function(t){var e=this.width+4,i=this.height+4;t.clearRect(-e/2,-i/2,e,i)},_getCursorBoundaries:function(t){void 0===t&&(t=this.selectionStart);var e=this._getLeftOffset(),i=this._getTopOffset(),r=this._getCursorBoundariesOffsets(t);return{left:e,top:i,leftOffset:r.left,topOffset:r.top}},_getCursorBoundariesOffsets:function(t){if(this.cursorOffsetCache&&"top"in this.cursorOffsetCache)return this.cursorOffsetCache;for(var e,i,r=0,n=0,s=this.get2DCursorLocation(t),o=0;o0?n:0)},this.cursorOffsetCache=i,this.cursorOffsetCache},renderCursor:function(t,e){var i=this.get2DCursorLocation(),r=i.lineIndex,n=i.charIndex>0?i.charIndex-1:0,s=this.getValueOfPropertyAt(r,n,"fontSize"),o=this.scaleX*this.canvas.getZoom(),a=this.cursorWidth/o,c=t.topOffset;c+=(1-this._fontSizeFraction)*this.getHeightOfLine(r)/this.lineHeight-s*(1-this._fontSizeFraction),this.inCompositionMode&&this.renderSelection(t,e),e.fillStyle=this.getValueOfPropertyAt(r,n,"fill"),e.globalAlpha=this.__isMousedown?1:this._currentCursorOpacity,e.fillRect(t.left+t.leftOffset-a/2,c+t.top,a,s)},renderSelection:function(t,e){for(var i=this.inCompositionMode?this.hiddenTextarea.selectionStart:this.selectionStart,r=this.inCompositionMode?this.hiddenTextarea.selectionEnd:this.selectionEnd,n=this.get2DCursorLocation(i),s=this.get2DCursorLocation(r),o=n.lineIndex,a=s.lineIndex,c=n.charIndex<0?0:n.charIndex,h=s.charIndex<0?0:s.charIndex,l=o;l<=a;l++){var u=this._getLineLeftOffset(l)||0,f=this.getHeightOfLine(l),d=0,g=0,p=0;l===o&&(g=this.__charBounds[o][c].left),l>=o&&l1)&&(f/=this.lineHeight),this.inCompositionMode?(e.fillStyle=this.compositionColor||"black",e.fillRect(t.left+u+g,t.top+t.topOffset+f,p-g,1)):(e.fillStyle=this.selectionColor,e.fillRect(t.left+u+g,t.top+t.topOffset,p-g,f)),t.topOffset+=d}},getCurrentCharFontSize:function(){var t=this._getCurrentCharIndex();return this.getValueOfPropertyAt(t.l,t.c,"fontSize")},getCurrentCharColor:function(){var t=this._getCurrentCharIndex();return this.getValueOfPropertyAt(t.l,t.c,"fill")},_getCurrentCharIndex:function(){var t=this.get2DCursorLocation(this.selectionStart,!0),e=t.charIndex>0?t.charIndex-1:0;return{l:t.lineIndex,c:e}}}),fabric.IText.fromObject=function(e,i){if(t(e),e.styles)for(var r in e.styles)for(var n in e.styles[r])t(e.styles[r][n]);fabric.Object._fromObject("IText",e,i,"text")}}(),function(){var t=fabric.util.object.clone;fabric.util.object.extend(fabric.IText.prototype,{initBehavior:function(){this.initAddedHandler(),this.initRemovedHandler(),this.initCursorSelectionHandlers(),this.initDoubleClickSimulation(),this.mouseMoveHandler=this.mouseMoveHandler.bind(this)},onDeselect:function(t){this.isEditing&&this.exitEditing(),this.selected=!1,fabric.Object.prototype.onDeselect.call(this,t)},initAddedHandler:function(){var t=this;this.on("added",function(){var e=t.canvas;e&&(e._hasITextHandlers||(e._hasITextHandlers=!0,t._initCanvasHandlers(e)),e._iTextInstances=e._iTextInstances||[],e._iTextInstances.push(t))})},initRemovedHandler:function(){var t=this;this.on("removed",function(){var e=t.canvas;e&&(e._iTextInstances=e._iTextInstances||[],fabric.util.removeFromArray(e._iTextInstances,t),0===e._iTextInstances.length&&(e._hasITextHandlers=!1,t._removeCanvasHandlers(e)))})},_initCanvasHandlers:function(t){t._mouseUpITextHandler=function(){t._iTextInstances&&t._iTextInstances.forEach(function(t){t.__isMousedown=!1})}.bind(this),t.on("mouse:up",t._mouseUpITextHandler)},_removeCanvasHandlers:function(t){t.off("mouse:up",t._mouseUpITextHandler)},_tick:function(){this._currentTickState=this._animateCursor(this,1,this.cursorDuration,"_onTickComplete")},_animateCursor:function(t,e,i,r){var n;return n={isAborted:!1,abort:function(){this.isAborted=!0}},t.animate("_currentCursorOpacity",e,{duration:i,onComplete:function(){n.isAborted||t[r]()},onChange:function(){t.canvas&&t.selectionStart===t.selectionEnd&&t.renderCursorOrSelection()},abort:function(){return n.isAborted}}),n},_onTickComplete:function(){var t=this;this._cursorTimeout1&&clearTimeout(this._cursorTimeout1),this._cursorTimeout1=setTimeout(function(){t._currentTickCompleteState=t._animateCursor(t,0,this.cursorDuration/2,"_tick")},100)},initDelayedCursor:function(t){var e=this,i=t?0:this.cursorDelay;this.abortCursorAnimation(),this._currentCursorOpacity=1,this._cursorTimeout2=setTimeout(function(){e._tick()},i)},abortCursorAnimation:function(){var t=this._currentTickState||this._currentTickCompleteState;this._currentTickState&&this._currentTickState.abort(),this._currentTickCompleteState&&this._currentTickCompleteState.abort(),clearTimeout(this._cursorTimeout1),clearTimeout(this._cursorTimeout2),this._currentCursorOpacity=0,t&&this.canvas&&this.canvas.clearContext(this.canvas.contextTop||this.ctx)},selectAll:function(){return this.selectionStart=0,this.selectionEnd=this._text.length,this._fireSelectionChanged(),this._updateTextarea(),this},getSelectedText:function(){return this._text.slice(this.selectionStart,this.selectionEnd).join("")},findWordBoundaryLeft:function(t){var e=0,i=t-1;if(this._reSpace.test(this._text[i]))for(;this._reSpace.test(this._text[i]);)e++,i--;for(;/\S/.test(this._text[i])&&i>-1;)e++,i--;return t-e},findWordBoundaryRight:function(t){var e=0,i=t;if(this._reSpace.test(this._text[i]))for(;this._reSpace.test(this._text[i]);)e++,i++;for(;/\S/.test(this._text[i])&&i-1;)e++,i--;return t-e},findLineBoundaryRight:function(t){for(var e=0,i=t;!/\n/.test(this._text[i])&&i0&&ithis.__selectionStartOnMouseDown?(this.selectionStart=this.__selectionStartOnMouseDown,this.selectionEnd=e):(this.selectionStart=e,this.selectionEnd=this.__selectionStartOnMouseDown),this.selectionStart===i&&this.selectionEnd===r||(this.restartCursorIfNeeded(),this._fireSelectionChanged(),this._updateTextarea(),this.renderCursorOrSelection()))}},_setEditingProps:function(){this.hoverCursor="text",this.canvas&&(this.canvas.defaultCursor=this.canvas.moveCursor="text"),this.borderColor=this.editingBorderColor,this.hasControls=this.selectable=!1,this.lockMovementX=this.lockMovementY=!0},fromStringToGraphemeSelection:function(t,e,i){var r=i.slice(0,t),n=fabric.util.string.graphemeSplit(r).length;if(t===e)return{selectionStart:n,selectionEnd:n};var s=i.slice(t,e);return{selectionStart:n,selectionEnd:n+fabric.util.string.graphemeSplit(s).length}},fromGraphemeToStringSelection:function(t,e,i){var r=i.slice(0,t).join("").length;return t===e?{selectionStart:r,selectionEnd:r}:{selectionStart:r,selectionEnd:r+i.slice(t,e).join("").length}},_updateTextarea:function(){if(this.cursorOffsetCache={},this.hiddenTextarea){if(!this.inCompositionMode){var t=this.fromGraphemeToStringSelection(this.selectionStart,this.selectionEnd,this._text);this.hiddenTextarea.selectionStart=t.selectionStart,this.hiddenTextarea.selectionEnd=t.selectionEnd}this.updateTextareaPosition()}},updateFromTextArea:function(){if(this.hiddenTextarea){this.cursorOffsetCache={},this.text=this.hiddenTextarea.value;var t=this.fromStringToGraphemeSelection(this.hiddenTextarea.selectionStart,this.hiddenTextarea.selectionEnd,this.hiddenTextarea.value);this.selectionEnd=this.selectionStart=t.selectionEnd,this.inCompositionMode||(this.selectionStart=t.selectionStart),this.updateTextareaPosition()}},updateTextareaPosition:function(){if(this.selectionStart===this.selectionEnd){var t=this._calcTextareaPosition();this.hiddenTextarea.style.left=t.left,this.hiddenTextarea.style.top=t.top}},_calcTextareaPosition:function(){if(!this.canvas)return{x:1,y:1};var t=this.inCompositionMode?this.compositionStart:this.selectionStart,e=this._getCursorBoundaries(t),i=this.get2DCursorLocation(t),r=i.lineIndex,n=i.charIndex,s=this.getValueOfPropertyAt(r,n,"fontSize")*this.lineHeight,o=e.leftOffset,a=this.calcTransformMatrix(),c={x:e.left+o,y:e.top+e.topOffset+s},h=this.canvas.upperCanvasEl,l=h.width-s,u=h.height-s;return c=fabric.util.transformPoint(c,a),(c=fabric.util.transformPoint(c,this.canvas.viewportTransform)).x<0&&(c.x=0),c.x>l&&(c.x=l),c.y<0&&(c.y=0),c.y>u&&(c.y=u),c.x+=this.canvas._offset.left,c.y+=this.canvas._offset.top,{left:c.x+"px",top:c.y+"px",fontSize:s+"px",charHeight:s}},_saveEditingProps:function(){this._savedProps={hasControls:this.hasControls,borderColor:this.borderColor,lockMovementX:this.lockMovementX,lockMovementY:this.lockMovementY,hoverCursor:this.hoverCursor,defaultCursor:this.canvas&&this.canvas.defaultCursor,moveCursor:this.canvas&&this.canvas.moveCursor}},_restoreEditingProps:function(){this._savedProps&&(this.hoverCursor=this._savedProps.overCursor,this.hasControls=this._savedProps.hasControls,this.borderColor=this._savedProps.borderColor,this.lockMovementX=this._savedProps.lockMovementX,this.lockMovementY=this._savedProps.lockMovementY,this.canvas&&(this.canvas.defaultCursor=this._savedProps.defaultCursor,this.canvas.moveCursor=this._savedProps.moveCursor))},exitEditing:function(){var t=this._textBeforeEdit!==this.text;return this.selected=!1,this.isEditing=!1,this.selectable=!0,this.selectionEnd=this.selectionStart,this.hiddenTextarea&&(this.hiddenTextarea.blur&&this.hiddenTextarea.blur(),this.canvas&&this.hiddenTextarea.parentNode.removeChild(this.hiddenTextarea),this.hiddenTextarea=null),this.abortCursorAnimation(),this._restoreEditingProps(),this._currentCursorOpacity=0,this.fire("editing:exited"),t&&this.fire("modified"),this.canvas&&(this.canvas.off("mouse:move",this.mouseMoveHandler),this.canvas.fire("text:editing:exited",{target:this}),t&&this.canvas.fire("object:modified",{target:this})),this},_removeExtraneousStyles:function(){for(var t in this.styles)this._textLines[t]||delete this.styles[t]},removeStyleFromTo:function(t,e){var i,r,n=this.get2DCursorLocation(t,!0),s=this.get2DCursorLocation(e,!0),o=n.lineIndex,a=n.charIndex,c=s.lineIndex,h=s.charIndex;if(o!==c){if(this.styles[o])for(i=a;i=h&&(r[l-f]=r[u],delete r[u])}},shiftLineStyles:function(e,i){var r=t(this.styles);for(var n in this.styles){var s=parseInt(n,10);s>e&&(this.styles[s+i]=r[s],r[s-i]||delete this.styles[s])}},restartCursorIfNeeded:function(){this._currentTickState&&!this._currentTickState.isAborted&&this._currentTickCompleteState&&!this._currentTickCompleteState.isAborted||this.initDelayedCursor()},insertNewlineStyleObject:function(e,i,r,n){var s,o={},a=!1;r||(r=1),this.shiftLineStyles(e,r),this.styles[e]&&(s=this.styles[e][0===i?i:i-1]);for(var c in this.styles[e]){var h=parseInt(c,10);h>=i&&(a=!0,o[h-i]=this.styles[e][c],delete this.styles[e][c])}for(a?this.styles[e+r]=o:delete this.styles[e+r];r>1;)r--,n&&n[r]?this.styles[e+r]={0:t(n[r])}:s?this.styles[e+r]={0:t(s)}:delete this.styles[e+r];this._forceClearCache=!0},insertCharStyleObject:function(e,i,r,n){this.styles||(this.styles={});var s=this.styles[e],o=s?t(s):{};r||(r=1);for(var a in o){var c=parseInt(a,10);c>=i&&(s[c+r]=o[c],o[c-r]||delete s[c])}if(this._forceClearCache=!0,n)for(;r--;)Object.keys(n[r]).length&&(this.styles[e]||(this.styles[e]={}),this.styles[e][i+r]=t(n[r]));else if(s)for(var h=s[i?i-1:1];h&&r--;)this.styles[e][i+r]=t(h)},insertNewStyleBlock:function(t,e,i){for(var r=this.get2DCursorLocation(e,!0),n=[0],s=0,o=0;o0&&(this.insertCharStyleObject(r.lineIndex,r.charIndex,n[0],i),i=i&&i.slice(n[0]+1)),s&&this.insertNewlineStyleObject(r.lineIndex,r.charIndex+n[0],s);for(o=1;o<=s;o++)this.insertCharStyleObject(r.lineIndex+o,0,n[o],i),i=i&&i.slice(n[o]+1)},setSelectionStartEndWithShift:function(t,e,i){i<=t?(e===t?this._selectionDirection="left":"right"===this._selectionDirection&&(this._selectionDirection="left",this.selectionEnd=t),this.selectionStart=i):i>t&&it?this.selectionStart=t:this.selectionStart<0&&(this.selectionStart=0),this.selectionEnd>t?this.selectionEnd=t:this.selectionEnd<0&&(this.selectionEnd=0)}})}(),fabric.util.object.extend(fabric.IText.prototype,{initDoubleClickSimulation:function(){this.__lastClickTime=+new Date,this.__lastLastClickTime=+new Date,this.__lastPointer={},this.on("mousedown",this.onMouseDown.bind(this))},onMouseDown:function(t){this.__newClickTime=+new Date;var e=this.canvas.getPointer(t.e);this.isTripleClick(e,t.e)&&(this.fire("tripleclick",t),this._stopEvent(t.e)),this.__lastLastClickTime=this.__lastClickTime,this.__lastClickTime=this.__newClickTime,this.__lastPointer=e,this.__lastIsEditing=this.isEditing,this.__lastSelected=this.selected},isTripleClick:function(t){return this.__newClickTime-this.__lastClickTime<500&&this.__lastClickTime-this.__lastLastClickTime<500&&this.__lastPointer.x===t.x&&this.__lastPointer.y===t.y},_stopEvent:function(t){t.preventDefault&&t.preventDefault(),t.stopPropagation&&t.stopPropagation()},initCursorSelectionHandlers:function(){this.initMousedownHandler(),this.initMouseupHandler(),this.initClicks()},initClicks:function(){this.on("mousedblclick",function(t){this.selectWord(this.getSelectionStartFromPointer(t.e))}),this.on("tripleclick",function(t){this.selectLine(this.getSelectionStartFromPointer(t.e))})},initMousedownHandler:function(){this.on("mousedown",function(t){if(this.editable&&(!t.e.button||1===t.e.button)){var e=this.canvas.getPointer(t.e);this.__mousedownX=e.x,this.__mousedownY=e.y,this.__isMousedown=!0,this.selected&&this.setCursorByClick(t.e),this.isEditing&&(this.__selectionStartOnMouseDown=this.selectionStart,this.selectionStart===this.selectionEnd&&this.abortCursorAnimation(),this.renderCursorOrSelection())}})},_isObjectMoved:function(t){var e=this.canvas.getPointer(t);return this.__mousedownX!==e.x||this.__mousedownY!==e.y},initMouseupHandler:function(){this.on("mouseup",function(t){this.__isMousedown=!1,!this.editable||this._isObjectMoved(t.e)||t.e.button&&1!==t.e.button||(this.__lastSelected&&!this.__corner&&(this.enterEditing(t.e),this.selectionStart===this.selectionEnd?this.initDelayedCursor(!0):this.renderCursorOrSelection()),this.selected=!0)})},setCursorByClick:function(t){var e=this.getSelectionStartFromPointer(t),i=this.selectionStart,r=this.selectionEnd;t.shiftKey?this.setSelectionStartEndWithShift(i,r,e):(this.selectionStart=e,this.selectionEnd=e),this.isEditing&&(this._fireSelectionChanged(),this._updateTextarea())},getSelectionStartFromPointer:function(t){for(var e,i=this.getLocalPointer(t),r=0,n=0,s=0,o=0,a=0,c=0,h=this._textLines.length;c0&&(o+=this._textLines[c-1].length+1);n=this._getLineLeftOffset(a)*this.scaleX;for(var l=0,u=(e=this._textLines[a]).length;ls||o<0?0:1);return this.flipX&&(a=n-a),a>this._text.length&&(a=this._text.length),a}}),fabric.util.object.extend(fabric.IText.prototype,{initHiddenTextarea:function(){this.hiddenTextarea=fabric.document.createElement("textarea"),this.hiddenTextarea.setAttribute("autocapitalize","off"),this.hiddenTextarea.setAttribute("autocorrect","off"),this.hiddenTextarea.setAttribute("autocomplete","off"),this.hiddenTextarea.setAttribute("spellcheck","false"),this.hiddenTextarea.setAttribute("data-fabric-hiddentextarea",""),this.hiddenTextarea.setAttribute("wrap","off");var t=this._calcTextareaPosition();this.hiddenTextarea.style.cssText="position: absolute; top: "+t.top+"; left: "+t.left+"; z-index: -999; opacity: 0; width: 1px; height: 1px; font-size: 1px; line-height: 1px; paddingï½°top: "+t.fontSize+";",fabric.document.body.appendChild(this.hiddenTextarea),fabric.util.addListener(this.hiddenTextarea,"keydown",this.onKeyDown.bind(this)),fabric.util.addListener(this.hiddenTextarea,"keyup",this.onKeyUp.bind(this)),fabric.util.addListener(this.hiddenTextarea,"input",this.onInput.bind(this)),fabric.util.addListener(this.hiddenTextarea,"copy",this.copy.bind(this)),fabric.util.addListener(this.hiddenTextarea,"cut",this.copy.bind(this)),fabric.util.addListener(this.hiddenTextarea,"paste",this.paste.bind(this)),fabric.util.addListener(this.hiddenTextarea,"compositionstart",this.onCompositionStart.bind(this)),fabric.util.addListener(this.hiddenTextarea,"compositionupdate",this.onCompositionUpdate.bind(this)),fabric.util.addListener(this.hiddenTextarea,"compositionend",this.onCompositionEnd.bind(this)),!this._clickHandlerInitialized&&this.canvas&&(fabric.util.addListener(this.canvas.upperCanvasEl,"click",this.onClick.bind(this)),this._clickHandlerInitialized=!0)},keysMap:{9:"exitEditing",27:"exitEditing",33:"moveCursorUp",34:"moveCursorDown",35:"moveCursorRight",36:"moveCursorLeft",37:"moveCursorLeft",38:"moveCursorUp",39:"moveCursorRight",40:"moveCursorDown"},ctrlKeysMapUp:{67:"copy",88:"cut"},ctrlKeysMapDown:{65:"selectAll"},onClick:function(){this.hiddenTextarea&&this.hiddenTextarea.focus()},onKeyDown:function(t){if(this.isEditing&&!this.inCompositionMode){if(t.keyCode in this.keysMap)this[this.keysMap[t.keyCode]](t);else{if(!(t.keyCode in this.ctrlKeysMapDown&&(t.ctrlKey||t.metaKey)))return;this[this.ctrlKeysMapDown[t.keyCode]](t)}t.stopImmediatePropagation(),t.preventDefault(),t.keyCode>=33&&t.keyCode<=40?(this.clearContextTop(),this.renderCursorOrSelection()):this.canvas&&this.canvas.requestRenderAll()}},onKeyUp:function(t){!this.isEditing||this._copyDone||this.inCompositionMode?this._copyDone=!1:t.keyCode in this.ctrlKeysMapUp&&(t.ctrlKey||t.metaKey)&&(this[this.ctrlKeysMapUp[t.keyCode]](t),t.stopImmediatePropagation(),t.preventDefault(),this.canvas&&this.canvas.requestRenderAll())},onInput:function(t){var e=this.fromPaste;if(this.fromPaste=!1,t&&t.stopPropagation(),this.isEditing){var i,r,n=this._splitTextIntoLines(this.hiddenTextarea.value).graphemeText,s=this._text.length,o=n.length,a=o-s;""===this.hiddenTextarea.value&&(this.styles={},this.updateFromTextArea(),this.fire("changed"),this.canvas&&(this.canvas.fire("text:changed",{target:this}),this.canvas.requestRenderAll())),this.selectionStart!==this.selectionEnd?(i=this._text.slice(this.selectionStart,this.selectionEnd),a+=this.selectionEnd-this.selectionStart):oc.selectionStart?this.removeStyleFromTo(this.selectionEnd-i.length,this.selectionEnd):this.removeStyleFromTo(this.selectionEnd,this.selectionEnd+i.length)),r.length&&(e&&r.join("")===fabric.copiedText?this.insertNewStyleBlock(r,this.selectionStart,fabric.copiedTextStyle):this.insertNewStyleBlock(r,this.selectionStart)),this.updateFromTextArea(),this.fire("changed"),this.canvas&&(this.canvas.fire("text:changed",{target:this}),this.canvas.requestRenderAll())}},onCompositionStart:function(){this.inCompositionMode=!0},onCompositionEnd:function(){this.inCompositionMode=!1},onCompositionUpdate:function(t){this.compositionStart=t.target.selectionStart,this.compositionEnd=t.target.selectionEnd,this.updateTextareaPosition()},copy:function(){this.selectionStart!==this.selectionEnd&&(fabric.copiedText=this.getSelectedText(),fabric.copiedTextStyle=this.getSelectionStyles(this.selectionStart,this.selectionEnd,!0),this._copyDone=!0)},paste:function(){this.fromPaste=!0},_getClipboardData:function(t){return t&&t.clipboardData||fabric.window.clipboardData},_getWidthBeforeCursor:function(t,e){var i,r=this._getLineLeftOffset(t);return e>0&&(r+=(i=this.__charBounds[t][e-1]).left+i.width),r},getDownCursorOffset:function(t,e){var i=this._getSelectionForOffset(t,e),r=this.get2DCursorLocation(i),n=r.lineIndex;if(n===this._textLines.length-1||t.metaKey||34===t.keyCode)return this._text.length-i;var s=r.charIndex,o=this._getWidthBeforeCursor(n,s),a=this._getIndexOnLine(n+1,o);return this._textLines[n].slice(s).length+a+2},_getSelectionForOffset:function(t,e){return t.shiftKey&&this.selectionStart!==this.selectionEnd&&e?this.selectionEnd:this.selectionStart},getUpCursorOffset:function(t,e){var i=this._getSelectionForOffset(t,e),r=this.get2DCursorLocation(i),n=r.lineIndex;if(0===n||t.metaKey||33===t.keyCode)return-i;var s=r.charIndex,o=this._getWidthBeforeCursor(n,s),a=this._getIndexOnLine(n-1,o),c=this._textLines[n].slice(0,s);return-this._textLines[n-1].length+a-c.length},_getIndexOnLine:function(t,e){for(var i,r,n=this._textLines[t],s=this._getLineLeftOffset(t),o=0,a=0,c=n.length;ae){r=!0;var h=s-i,l=s,u=Math.abs(h-e);o=Math.abs(l-e)=this._text.length&&this.selectionEnd>=this._text.length||this._moveCursorUpOrDown("Down",t)},moveCursorUp:function(t){0===this.selectionStart&&0===this.selectionEnd||this._moveCursorUpOrDown("Up",t)},_moveCursorUpOrDown:function(t,e){var i=this["get"+t+"CursorOffset"](e,"right"===this._selectionDirection);e.shiftKey?this.moveCursorWithShift(i):this.moveCursorWithoutShift(i),0!==i&&(this.setSelectionInBoundaries(),this.abortCursorAnimation(),this._currentCursorOpacity=1,this.initDelayedCursor(),this._fireSelectionChanged(),this._updateTextarea())},moveCursorWithShift:function(t){var e="left"===this._selectionDirection?this.selectionStart+t:this.selectionEnd+t;return this.setSelectionStartEndWithShift(this.selectionStart,this.selectionEnd,e),0!==t},moveCursorWithoutShift:function(t){return t<0?(this.selectionStart+=t,this.selectionEnd=this.selectionStart):(this.selectionEnd+=t,this.selectionStart=this.selectionEnd),0!==t},moveCursorLeft:function(t){0===this.selectionStart&&0===this.selectionEnd||this._moveCursorLeftOrRight("Left",t)},_move:function(t,e,i){var r;if(t.altKey)r=this["findWordBoundary"+i](this[e]);else{if(!t.metaKey&&35!==t.keyCode&&36!==t.keyCode)return this[e]+="Left"===i?-1:1,!0;r=this["findLineBoundary"+i](this[e])}if(void 0!==typeof r&&this[e]!==r)return this[e]=r,!0},_moveLeft:function(t,e){return this._move(t,e,"Left")},_moveRight:function(t,e){return this._move(t,e,"Right")},moveCursorLeftWithoutShift:function(t){var e=!0;return this._selectionDirection="left",this.selectionEnd===this.selectionStart&&0!==this.selectionStart&&(e=this._moveLeft(t,"selectionStart")),this.selectionEnd=this.selectionStart,e},moveCursorLeftWithShift:function(t){return"right"===this._selectionDirection&&this.selectionStart!==this.selectionEnd?this._moveLeft(t,"selectionEnd"):0!==this.selectionStart?(this._selectionDirection="left",this._moveLeft(t,"selectionStart")):void 0},moveCursorRight:function(t){this.selectionStart>=this._text.length&&this.selectionEnd>=this._text.length||this._moveCursorLeftOrRight("Right",t)},_moveCursorLeftOrRight:function(t,e){var i="moveCursor"+t+"With";this._currentCursorOpacity=1,e.shiftKey?i+="Shift":i+="outShift",this[i](e)&&(this.abortCursorAnimation(),this.initDelayedCursor(),this._fireSelectionChanged(),this._updateTextarea())},moveCursorRightWithShift:function(t){return"left"===this._selectionDirection&&this.selectionStart!==this.selectionEnd?this._moveRight(t,"selectionStart"):this.selectionEnd!==this._text.length?(this._selectionDirection="right",this._moveRight(t,"selectionEnd")):void 0},moveCursorRightWithoutShift:function(t){var e=!0;return this._selectionDirection="right",this.selectionStart===this.selectionEnd?(e=this._moveRight(t,"selectionStart"),this.selectionEnd=this.selectionStart):this.selectionStart=this.selectionEnd,e},removeChars:function(t){this.selectionStart===this.selectionEnd?this._removeCharsNearCursor(t):this._removeCharsFromTo(this.selectionStart,this.selectionEnd),this.set("dirty",!0),this.setSelectionEnd(this.selectionStart),this._removeExtraneousStyles(),this.canvas&&this.canvas.requestRenderAll(),this.setCoords(),this.fire("changed"),this.canvas&&this.canvas.fire("text:changed",{target:this})},_removeCharsNearCursor:function(t){if(0!==this.selectionStart)if(t.metaKey){var e=this.findLineBoundaryLeft(this.selectionStart);this._removeCharsFromTo(e,this.selectionStart),this.setSelectionStart(e)}else if(t.altKey){var i=this.findWordBoundaryLeft(this.selectionStart);this._removeCharsFromTo(i,this.selectionStart),this.setSelectionStart(i)}else this._removeSingleCharAndStyle(this.selectionStart),this.setSelectionStart(this.selectionStart-1)}}),function(){var t=fabric.util.toFixed,e=fabric.Object.NUM_FRACTION_DIGITS;fabric.util.object.extend(fabric.Text.prototype,{toSVG:function(t){var e=this._createBaseSVGMarkup(),i=this._getSVGLeftTopOffsets(),r=this._getSVGTextAndBg(i.textTop,i.textLeft);return this._wrapSVGTextAndBg(e,r),t?t(e.join("")):e.join("")},_getSVGLeftTopOffsets:function(){return{textLeft:-this.width/2,textTop:-this.height/2,lineTop:this.getHeightOfLine(0)}},_wrapSVGTextAndBg:function(t,e){var i=this.getSvgFilter(),r=""===i?"":' style="'+i+'"';t.push("\t\n",e.textBgRects.join(""),'\t\t\n',e.textSpans.join(""),"\t\t\n","\t\n")},_getSVGTextAndBg:function(t,e){var i,r=[],n=[],s=t;this._setSVGBg(n);for(var o=0,a=this._textLines.length;o",fabric.util.string.escapeXml(i),"\n"].join("")},_setSVGTextLineText:function(t,e,i,r){var n,s,o,a,c,h=this.getHeightOfLine(e),l="",u=0,f=this._textLines[e];r+=h*(1-this._fontSizeFraction)/this.lineHeight;for(var d=0,g=f.length-1;d<=g;d++)c=d===g||this.charSpacing,l+=f[d],o=this.__charBounds[e][d],0===u&&(i+=o.kernedWidth-o.width),u+=o.kernedWidth,"justify"!==this.textAlign||c||this._reSpaceAndTab.test(f[d])&&(c=!0),c||(n=n||this.getCompleteStyleDeclaration(e,d),s=this.getCompleteStyleDeclaration(e,d+1),c=this._hasStyleChanged(n,s)),c&&(a=this._getStyleDeclaration(e,d)||{},t.push(this._createTextCharSpan(l,a,i,r)),l="",n=s,i+=u,u=0)},_pushTextBgRect:function(i,r,n,s,o,a){i.push("\t\t\n')},_setSVGTextLineBg:function(t,e,i,r){for(var n,s,o=this._textLines[e],a=this.getHeightOfLine(e)/this.lineHeight,c=0,h=0,l=this.getValueOfPropertyAt(e,0,"textBackgroundColor"),u=0,f=o.length;uthis.width&&this._set("width",this.dynamicMinWidth),"justify"===this.textAlign&&this.enlargeSpaces(),this.height=this.calcTextHeight()}},_generateStyleMap:function(t){for(var e=0,i=0,r=0,n={},s=0;s0?(i=0,r++,e++):this._reSpaceAndTab.test(t.graphemeText[r])&&s>0&&(i++,r++),n[s]={line:e,offset:i},r+=t.graphemeLines[s].length,i+=t.graphemeLines[s].length;return n},styleHas:function(t,i){if(this._styleMap&&!this.isWrapping){var r=this._styleMap[i];r&&(i=r.line)}return e.Text.prototype.styleHas.call(this,t,i)},_getStyleDeclaration:function(t,e){if(this._styleMap&&!this.isWrapping){var i=this._styleMap[t];if(!i)return null;t=i.line,e=i.offset+e}return this.callSuper("_getStyleDeclaration",t,e)},_setStyleDeclaration:function(t,e,i){var r=this._styleMap[t];t=r.line,e=r.offset+e,this.styles[t][e]=i},_deleteStyleDeclaration:function(t,e){var i=this._styleMap[t];t=i.line,e=i.offset+e,delete this.styles[t][e]},_getLineStyle:function(t){var e=this._styleMap[t];return this.styles[e.line]},_setLineStyle:function(t,e){var i=this._styleMap[t];this.styles[i.line]=e},_deleteLineStyle:function(t){var e=this._styleMap[t];delete this.styles[e.line]},_wrapText:function(t,e){var i,r=[];for(this.isWrapping=!0,i=0;i=r&&!d&&(s.push(o),o=[],n=l,d=!0),d||o.push(" "),o=o.concat(c),u=this._measureWord([" "],i,h),h++,d=!1,l>f&&(f=l);return p&&s.push(o),f>this.dynamicMinWidth&&(this.dynamicMinWidth=f-g),s},_splitTextIntoLines:function(t){for(var i=e.Text.prototype._splitTextIntoLines.call(this,t),r=this._wrapText(i.lines,this.width),n=new Array(r.length),s=0;s=c.getMinWidth()?(c.set("width",l),!0):void 0},fabric.util.object.extend(fabric.Textbox.prototype,{_removeExtraneousStyles:function(){for(var t in this._styleMap)this._textLines[t]||delete this.styles[this._styleMap[t].line]}})}(),function(){function request(t,e,i){var r=URL.parse(t);r.port||(r.port=0===r.protocol.indexOf("https:")?443:80);var n=(0===r.protocol.indexOf("https:")?HTTPS:HTTP).request({hostname:r.hostname,port:r.port,path:r.path,method:"GET"},function(t){var r="";e&&t.setEncoding(e),t.on("end",function(){i(r)}),t.on("data",function(e){200===t.statusCode&&(r+=e)})});n.on("error",function(t){t.errno===process.ECONNREFUSED?fabric.log("ECONNREFUSED: connection refused to "+r.hostname+":"+r.port):fabric.log(t.message),i(null)}),n.end()}function requestFs(t,e){require("fs").readFile(t,function(t,i){if(t)throw fabric.log(t),t;e(i)})}if("undefined"==typeof document||"undefined"==typeof window){var DOMParser=require("xmldom").DOMParser,URL=require("url"),HTTP=require("http"),HTTPS=require("https"),Canvas=require(fabric.canvasModule),Image=require(fabric.canvasModule).Image;fabric.util.loadImage=function(t,e,i){function r(r){r?(n.src=new Buffer(r,"binary"),n._src=t,e&&e.call(i,n)):(n=null,e&&e.call(i,null,!0))}var n=new Image;t&&(t instanceof Buffer||0===t.indexOf("data"))?(n.src=n._src=t,e&&e.call(i,n)):t&&0!==t.indexOf("http")?requestFs(t,r):t?request(t,"binary",r):e&&e.call(i,t)},fabric.loadSVGFromURL=function(t,e,i){0!==(t=t.replace(/^\n\s*/,"").replace(/\?.*$/,"").trim()).indexOf("http")?requestFs(t,function(t){fabric.loadSVGFromString(t.toString(),e,i)}):request(t,"",function(t){fabric.loadSVGFromString(t,e,i)})},fabric.loadSVGFromString=function(t,e,i){var r=(new DOMParser).parseFromString(t);fabric.parseSVGDocument(r.documentElement,function(t,i){e&&e(t,i)},i)},fabric.util.getScript=function(url,callback){request(url,"",function(body){eval(body),callback&&callback()})},fabric.createCanvasForNode=function(t,e,i,r){r=r||i;var n=fabric.document.createElement("canvas"),s=new Canvas(t||600,e||600,r),o=new Canvas(t||600,e||600,r);n.width=s.width,n.height=s.height,(i=i||{}).nodeCanvas=s,i.nodeCacheCanvas=o;var a=new(fabric.Canvas||fabric.StaticCanvas)(n,i);return a.nodeCanvas=s,a.nodeCacheCanvas=o,a.contextContainer=s.getContext("2d"),a.contextCache=o.getContext("2d"),a.Font=Canvas.Font,a};var originaInitStatic=fabric.StaticCanvas.prototype._initStatic;fabric.StaticCanvas.prototype._initStatic=function(t,e){t=t||fabric.document.createElement("canvas"),this.nodeCanvas=new Canvas(t.width,t.height),this.nodeCacheCanvas=new Canvas(t.width,t.height),originaInitStatic.call(this,t,e),this.contextContainer=this.nodeCanvas.getContext("2d"),this.contextCache=this.nodeCacheCanvas.getContext("2d"),this.Font=Canvas.Font},fabric.StaticCanvas.prototype.createPNGStream=function(){return this.nodeCanvas.createPNGStream()},fabric.StaticCanvas.prototype.createJPEGStream=function(t){return this.nodeCanvas.createJPEGStream(t)},fabric.StaticCanvas.prototype._initRetinaScaling=function(){if(this._isRetinaScaling())return this.lowerCanvasEl.setAttribute("width",this.width*fabric.devicePixelRatio),this.lowerCanvasEl.setAttribute("height",this.height*fabric.devicePixelRatio),this.nodeCanvas.width=this.width*fabric.devicePixelRatio,this.nodeCanvas.height=this.height*fabric.devicePixelRatio,this.contextContainer.scale(fabric.devicePixelRatio,fabric.devicePixelRatio),this},fabric.Canvas&&(fabric.Canvas.prototype._initRetinaScaling=fabric.StaticCanvas.prototype._initRetinaScaling);var origSetBackstoreDimension=fabric.StaticCanvas.prototype._setBackstoreDimension;fabric.StaticCanvas.prototype._setBackstoreDimension=function(t,e){return origSetBackstoreDimension.call(this,t,e),this.nodeCanvas[t]=e,this},fabric.Canvas&&(fabric.Canvas.prototype._setBackstoreDimension=fabric.StaticCanvas.prototype._setBackstoreDimension)}}(); \ No newline at end of file +function resizeCanvasIfNeeded(t){var e=t.targetCanvas,i=e.width,r=e.height,n=t.destinationWidth,s=t.destinationHeight;i===n&&r===s||(e.width=n,e.height=s)}function copyGLTo2DDrawImage(t,e){var i=t.canvas,r=e.targetCanvas,n=r.getContext("2d");n.translate(0,r.height),n.scale(1,-1);var s=i.height-r.height;n.drawImage(i,0,s,r.width,r.height,0,0,r.width,r.height)}function copyGLTo2DPutImageData(t,e){var i=e.targetCanvas.getContext("2d"),r=e.destinationWidth,n=e.destinationHeight,s=r*n*4,o=new Uint8Array(this.imageBuffer,0,s),a=new Uint8ClampedArray(this.imageBuffer,0,s);t.readPixels(0,0,r,n,t.RGBA,t.UNSIGNED_BYTE,o);var h=new ImageData(a,r,n);i.putImageData(h,0,0)}var fabric=fabric||{version:"2.0.0-rc.1"};"undefined"!=typeof exports&&(exports.fabric=fabric),"undefined"!=typeof document&&"undefined"!=typeof window?(fabric.document=document,fabric.window=window):(fabric.document=require("jsdom").jsdom(decodeURIComponent("%3C!DOCTYPE%20html%3E%3Chtml%3E%3Chead%3E%3C%2Fhead%3E%3Cbody%3E%3C%2Fbody%3E%3C%2Fhtml%3E"),{features:{FetchExternalResources:["img"]}}),fabric.window=fabric.document.defaultView,DOMParser=require("xmldom").DOMParser),fabric.isTouchSupported="ontouchstart"in fabric.window,fabric.isLikelyNode="undefined"!=typeof Buffer&&"undefined"==typeof window,fabric.SHARED_ATTRIBUTES=["display","transform","fill","fill-opacity","fill-rule","opacity","stroke","stroke-dasharray","stroke-linecap","stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke-width","id","paint-order","instantiated_by_use"],fabric.DPI=96,fabric.reNum="(?:[-+]?(?:\\d+|\\d*\\.\\d+)(?:e[-+]?\\d+)?)",fabric.fontPaths={},fabric.iMatrix=[1,0,0,1,0,0],fabric.canvasModule="canvas",fabric.perfLimitSizeTotal=2097152,fabric.maxCacheSideLimit=4096,fabric.minCacheSideLimit=256,fabric.charWidthsCache={},fabric.textureSize=2048,fabric.enableGLFiltering=!0,fabric.devicePixelRatio=fabric.window.devicePixelRatio||fabric.window.webkitDevicePixelRatio||fabric.window.mozDevicePixelRatio||1,fabric.browserShadowBlurConstant=1,fabric.initFilterBackend=function(){return fabric.enableGLFiltering&&fabric.isWebglSupported&&fabric.isWebglSupported(fabric.textureSize)?(console.log("max texture size: "+fabric.maxTextureSize),new fabric.WebglFilterBackend({tileSize:fabric.textureSize})):fabric.Canvas2dFilterBackend?new fabric.Canvas2dFilterBackend:void 0},"undefined"!=typeof document&&"undefined"!=typeof window&&(window.fabric=fabric),function(){function t(t,e){if(this.__eventListeners[t]){var i=this.__eventListeners[t];e?i[i.indexOf(e)]=!1:fabric.util.array.fill(i,!1)}}function e(t,e){if(this.__eventListeners||(this.__eventListeners={}),1===arguments.length)for(var i in t)this.on(i,t[i]);else this.__eventListeners[t]||(this.__eventListeners[t]=[]),this.__eventListeners[t].push(e);return this}function i(e,i){if(this.__eventListeners){if(0===arguments.length)for(e in this.__eventListeners)t.call(this,e);else if(1===arguments.length&&"object"==typeof arguments[0])for(var r in e)t.call(this,r,e[r]);else t.call(this,e,i);return this}}function r(t,e){if(this.__eventListeners){var i=this.__eventListeners[t];if(i){for(var r=0,n=i.length;r-1},complexity:function(){return this.getObjects().reduce(function(t,e){return t+=e.complexity?e.complexity():0},0)}},fabric.CommonMethods={_setOptions:function(t){for(var e in t)this.set(e,t[e])},_initGradient:function(t,e){!t||!t.colorStops||t instanceof fabric.Gradient||this.set(e,new fabric.Gradient(t))},_initPattern:function(t,e,i){!t||!t.source||t instanceof fabric.Pattern?i&&i():this.set(e,new fabric.Pattern(t,i))},_initClipping:function(t){if(t.clipTo&&"string"==typeof t.clipTo){var e=fabric.util.getFunctionBody(t.clipTo);void 0!==e&&(this.clipTo=new Function("ctx",e))}},_setObject:function(t){for(var e in t)this._set(e,t[e])},set:function(t,e){return"object"==typeof t?this._setObject(t):"function"==typeof e&&"clipTo"!==t?this._set(t,e(this.get(t))):this._set(t,e),this},_set:function(t,e){this[t]=e},toggle:function(t){var e=this.get(t);return"boolean"==typeof e&&this.set(t,!e),this},get:function(t){return this[t]}},function(t){var e=Math.sqrt,i=Math.atan2,r=Math.pow,n=Math.abs,s=Math.PI/180;fabric.util={removeFromArray:function(t,e){var i=t.indexOf(e);return-1!==i&&t.splice(i,1),t},getRandomInt:function(t,e){return Math.floor(Math.random()*(e-t+1))+t},degreesToRadians:function(t){return t*s},radiansToDegrees:function(t){return t/s},rotatePoint:function(t,e,i){t.subtractEquals(e);var r=fabric.util.rotateVector(t,i);return new fabric.Point(r.x,r.y).addEquals(e)},rotateVector:function(t,e){var i=Math.sin(e),r=Math.cos(e);return{x:t.x*r-t.y*i,y:t.x*i+t.y*r}},transformPoint:function(t,e,i){return i?new fabric.Point(e[0]*t.x+e[2]*t.y,e[1]*t.x+e[3]*t.y):new fabric.Point(e[0]*t.x+e[2]*t.y+e[4],e[1]*t.x+e[3]*t.y+e[5])},makeBoundingBoxFromPoints:function(t){var e=[t[0].x,t[1].x,t[2].x,t[3].x],i=fabric.util.array.min(e),r=fabric.util.array.max(e)-i,n=[t[0].y,t[1].y,t[2].y,t[3].y],s=fabric.util.array.min(n);return{left:i,top:s,width:r,height:fabric.util.array.max(n)-s}},invertTransform:function(t){var e=1/(t[0]*t[3]-t[1]*t[2]),i=[e*t[3],-e*t[1],-e*t[2],e*t[0]],r=fabric.util.transformPoint({x:t[4],y:t[5]},i,!0);return i[4]=-r.x,i[5]=-r.y,i},toFixed:function(t,e){return parseFloat(Number(t).toFixed(e))},parseUnit:function(t,e){var i=/\D{0,2}$/.exec(t),r=parseFloat(t);switch(e||(e=fabric.Text.DEFAULT_SVG_FONT_SIZE),i[0]){case"mm":return r*fabric.DPI/25.4;case"cm":return r*fabric.DPI/2.54;case"in":return r*fabric.DPI;case"pt":return r*fabric.DPI/72;case"pc":return r*fabric.DPI/72*12;case"em":return r*e;default:return r}},falseFunction:function(){return!1},getKlass:function(t,e){return t=fabric.util.string.camelize(t.charAt(0).toUpperCase()+t.slice(1)),fabric.util.resolveNamespace(e)[t]},getSvgAttributes:function(t){var e=["instantiated_by_use","style","id","class"];switch(t){case"linearGradient":e=e.concat(["x1","y1","x2","y2","gradientUnits","gradientTransform"]);break;case"radialGradient":e=e.concat(["gradientUnits","gradientTransform","cx","cy","r","fx","fy","fr"]);break;case"stop":e=e.concat(["offset","stop-color","stop-opacity"])}return e},resolveNamespace:function(e){if(!e)return fabric;var i,r=e.split("."),n=r.length,s=t||fabric.window;for(i=0;ir;)(r+=a[d++%f])>l&&(r=l),t[g?"lineTo":"moveTo"](r,0),g=!g;t.restore()},createCanvasElement:function(){return fabric.document.createElement("canvas")},createImage:function(){return fabric.document.createElement("img")},clipContext:function(t,e){e.save(),e.beginPath(),t.clipTo(e),e.clip()},multiplyTransformMatrices:function(t,e,i){return[t[0]*e[0]+t[2]*e[1],t[1]*e[0]+t[3]*e[1],t[0]*e[2]+t[2]*e[3],t[1]*e[2]+t[3]*e[3],i?0:t[0]*e[4]+t[2]*e[5]+t[4],i?0:t[1]*e[4]+t[3]*e[5]+t[5]]},qrDecompose:function(t){var n=i(t[1],t[0]),o=r(t[0],2)+r(t[1],2),a=e(o),h=(t[0]*t[3]-t[2]*t[1])/a,c=i(t[0]*t[2]+t[1]*t[3],o);return{angle:n/s,scaleX:a,scaleY:h,skewX:c/s,skewY:0,translateX:t[4],translateY:t[5]}},customTransformMatrix:function(t,e,i){var r=[1,0,n(Math.tan(i*s)),1],o=[n(t),0,0,n(e)];return fabric.util.multiplyTransformMatrices(o,r,!0)},resetObjectTransform:function(t){t.scaleX=1,t.scaleY=1,t.skewX=0,t.skewY=0,t.flipX=!1,t.flipY=!1,t.rotate(0)},getFunctionBody:function(t){return(String(t).match(/function[^{]*\{([\s\S]*)\}/)||{})[1]},isTransparent:function(t,e,i,r){r>0&&(e>r?e-=r:e=0,i>r?i-=r:i=0);var n,s,o=!0,a=t.getImageData(e,i,2*r||1,2*r||1),h=a.data.length;for(n=3;n0?P-=2*f:1===c&&P<0&&(P+=2*f);for(var M=Math.ceil(Math.abs(P/f*2)),F=[],L=P/M,I=8/3*Math.sin(L/4)*Math.sin(L/4)/Math.sin(L/2),R=A+L,B=0;B=n?s-n:2*Math.PI-(n-s)}function r(t,e,i,r,n,s,h,c){var l=a.call(arguments);if(o[l])return o[l];var u,f,d,g,p,v,m,b,_=Math.sqrt,y=Math.min,x=Math.max,C=Math.abs,S=[],w=[[],[]];f=6*t-12*i+6*n,u=-3*t+9*i-9*n+3*h,d=3*i-3*t;for(var T=0;T<2;++T)if(T>0&&(f=6*e-12*r+6*s,u=-3*e+9*r-9*s+3*c,d=3*r-3*e),C(u)<1e-12){if(C(f)<1e-12)continue;0<(g=-d/f)&&g<1&&S.push(g)}else(m=f*f-4*d*u)<0||(0<(p=(-f+(b=_(m)))/(2*u))&&p<1&&S.push(p),0<(v=(-f-b)/(2*u))&&v<1&&S.push(v));for(var O,k,D,E=S.length,j=E;E--;)O=(D=1-(g=S[E]))*D*D*t+3*D*D*g*i+3*D*g*g*n+g*g*g*h,w[0][E]=O,k=D*D*D*e+3*D*D*g*r+3*D*g*g*s+g*g*g*c,w[1][E]=k;w[0][j]=t,w[1][j]=e,w[0][j+1]=h,w[1][j+1]=c;var A=[{x:y.apply(null,w[0]),y:y.apply(null,w[1])},{x:x.apply(null,w[0]),y:x.apply(null,w[1])}];return o[l]=A,A}var n={},s={},o={},a=Array.prototype.join;fabric.util.drawArc=function(e,i,r,n){for(var s=n[0],o=n[1],a=n[2],h=n[3],c=n[4],l=[[],[],[],[]],u=t(n[5]-i,n[6]-r,s,o,h,c,a),f=0,d=u.length;f=e})}}}(),function(){function t(e,i,r){if(r)if(!fabric.isLikelyNode&&i instanceof Element)e=i;else if(i instanceof Array){e=[];for(var n=0,s=i.length;n57343)return t.charAt(e);if(55296<=i&&i<=56319){if(t.length<=e+1)throw"High surrogate without following low surrogate";var r=t.charCodeAt(e+1);if(56320>r||r>57343)throw"High surrogate without following low surrogate";return t.charAt(e)+t.charAt(e+1)}if(0===e)throw"Low surrogate without preceding high surrogate";var n=t.charCodeAt(e-1);if(55296>n||n>56319)throw"Low surrogate without preceding high surrogate";return!1}fabric.util.string={camelize:function(t){return t.replace(/-+(.)?/g,function(t,e){return e?e.toUpperCase():""})},capitalize:function(t,e){return t.charAt(0).toUpperCase()+(e?t.slice(1):t.slice(1).toLowerCase())},escapeXml:function(t){return t.replace(/&/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(//g,">")},graphemeSplit:function(e){var i,r=0,n=[];for(r=0,i;r1?e.apply(this,i.call(arguments,1)):e.call(this):console.log("tried to callSuper "+t+", method not found in prototype chain",this)}var i=Array.prototype.slice,r=function(){},n=function(){for(var t in{toString:1})if("toString"===t)return!1;return!0}(),s=function(t,e,i){for(var r in e)r in t.prototype&&"function"==typeof t.prototype[r]&&(e[r]+"").indexOf("callSuper")>-1?t.prototype[r]=function(t){return function(){var r=this.constructor.superclass;this.constructor.superclass=i;var n=e[t].apply(this,arguments);if(this.constructor.superclass=r,"initialize"!==t)return n}}(r):t.prototype[r]=e[r],n&&(e.toString!==Object.prototype.toString&&(t.prototype.toString=e.toString),e.valueOf!==Object.prototype.valueOf&&(t.prototype.valueOf=e.valueOf))};fabric.util.createClass=function(){function n(){this.initialize.apply(this,arguments)}var o=null,a=i.call(arguments,0);"function"==typeof a[0]&&(o=a.shift()),n.superclass=o,n.subclasses=[],o&&(t.prototype=o.prototype,n.prototype=new t,o.subclasses.push(n));for(var h=0,c=a.length;h=.9999?"":"alpha(opacity="+100*e+")",i.filter=i.filter.replace(r,e)):i.filter+=" alpha(opacity="+100*e+")",t}),fabric.util.setStyle=function(t,e){var i=t.style;if(!i)return t;if("string"==typeof e)return t.style.cssText+=";"+e,e.indexOf("opacity")>-1?n(t,e.match(/opacity:\s*(\d?\.?\d*)/)[1]):t;for(var r in e)"opacity"===r?n(t,e[r]):i["float"===r||"cssFloat"===r?void 0===i.styleFloat?"cssFloat":"styleFloat":r]=e[r];return t}}(),function(){function t(t,e){var i=fabric.document.createElement(t);for(var r in e)"class"===r?i.className=e[r]:"for"===r?i.htmlFor=e[r]:i.setAttribute(r,e[r]);return i}function e(t){for(var e=0,i=0,r=fabric.document.documentElement,n=fabric.document.body||{scrollLeft:0,scrollTop:0};t&&(t.parentNode||t.host)&&((t=t.parentNode||t.host)===fabric.document?(e=n.scrollLeft||r.scrollLeft||0,i=n.scrollTop||r.scrollTop||0):(e+=t.scrollLeft||0,i+=t.scrollTop||0),1!==t.nodeType||"fixed"!==fabric.util.getElementStyle(t,"position")););return{left:e,top:i}}var i,r=Array.prototype.slice,n=function(t){return r.call(t,0)};try{i=n(fabric.document.childNodes)instanceof Array}catch(t){}i||(n=function(t){for(var e=new Array(t.length),i=t.length;i--;)e[i]=t[i];return e});var s;s=fabric.document.defaultView&&fabric.document.defaultView.getComputedStyle?function(t,e){var i=fabric.document.defaultView.getComputedStyle(t,null);return i?i[e]:void 0}:function(t,e){var i=t.style[e];return!i&&t.currentStyle&&(i=t.currentStyle[e]),i},function(){var t=fabric.document.documentElement.style,e="userSelect"in t?"userSelect":"MozUserSelect"in t?"MozUserSelect":"WebkitUserSelect"in t?"WebkitUserSelect":"KhtmlUserSelect"in t?"KhtmlUserSelect":"";fabric.util.makeElementUnselectable=function(t){return void 0!==t.onselectstart&&(t.onselectstart=fabric.util.falseFunction),e?t.style[e]="none":"string"==typeof t.unselectable&&(t.unselectable="on"),t},fabric.util.makeElementSelectable=function(t){return void 0!==t.onselectstart&&(t.onselectstart=null),e?t.style[e]="":"string"==typeof t.unselectable&&(t.unselectable=""),t}}(),function(){fabric.util.getScript=function(t,e){var i=fabric.document.getElementsByTagName("head")[0],r=fabric.document.createElement("script"),n=!0;r.onload=r.onreadystatechange=function(t){if(n){if("string"==typeof this.readyState&&"loaded"!==this.readyState&&"complete"!==this.readyState)return;n=!1,e(t||fabric.window.event),r=r.onload=r.onreadystatechange=null}},r.src=t,i.appendChild(r)}}(),fabric.util.getById=function(t){return"string"==typeof t?fabric.document.getElementById(t):t},fabric.util.toArray=n,fabric.util.makeElement=t,fabric.util.addClass=function(t,e){t&&-1===(" "+t.className+" ").indexOf(" "+e+" ")&&(t.className+=(t.className?" ":"")+e)},fabric.util.wrapElement=function(e,i,r){return"string"==typeof i&&(i=t(i,r)),e.parentNode&&e.parentNode.replaceChild(i,e),i.appendChild(e),i},fabric.util.getScrollLeftTop=e,fabric.util.getElementOffset=function(t){var i,r,n=t&&t.ownerDocument,o={left:0,top:0},a={left:0,top:0},h={borderLeftWidth:"left",borderTopWidth:"top",paddingLeft:"left",paddingTop:"top"};if(!n)return a;for(var c in h)a[h[c]]+=parseInt(s(t,c),10)||0;return i=n.documentElement,void 0!==t.getBoundingClientRect&&(o=t.getBoundingClientRect()),r=e(t),{left:o.left+r.left-(i.clientLeft||0)+a.left,top:o.top+r.top-(i.clientTop||0)+a.top}},fabric.util.getElementStyle=s}(),function(){function t(t,e){return t+(/\?/.test(t)?"&":"?")+e}function e(){}var i=function(){for(var t=[function(){return new ActiveXObject("Microsoft.XMLHTTP")},function(){return new ActiveXObject("Msxml2.XMLHTTP")},function(){return new ActiveXObject("Msxml2.XMLHTTP.3.0")},function(){return new XMLHttpRequest}],e=t.length;e--;)try{if(t[e]())return t[e]}catch(t){}}();fabric.util.request=function(r,n){n||(n={});var s=n.method?n.method.toUpperCase():"GET",o=n.onComplete||function(){},a=i(),h=n.body||n.parameters;return a.onreadystatechange=function(){4===a.readyState&&(o(a),a.onreadystatechange=e)},"GET"===s&&(h=null,"string"==typeof n.parameters&&(r=t(r,n.parameters))),a.open(s,r,!0),"POST"!==s&&"PUT"!==s||a.setRequestHeader("Content-Type","application/x-www-form-urlencoded"),a.send(h),a}}(),fabric.log=function(){},fabric.warn=function(){},"undefined"!=typeof console&&["log","warn"].forEach(function(t){void 0!==console[t]&&"function"==typeof console[t].apply&&(fabric[t]=function(){return console[t].apply(console,arguments)})}),function(){function t(){return!1}function e(){return i.apply(fabric.window,arguments)}var i=fabric.window.requestAnimationFrame||fabric.window.webkitRequestAnimationFrame||fabric.window.mozRequestAnimationFrame||fabric.window.oRequestAnimationFrame||fabric.window.msRequestAnimationFrame||function(t){return fabric.window.setTimeout(t,1e3/60)},r=fabric.window.cancelAnimationFrame||fabric.window.clearTimeout;fabric.util.animate=function(i){e(function(r){i||(i={});var n,s=r||+new Date,o=i.duration||500,a=s+o,h=i.onChange||t,c=i.abort||t,l=i.onComplete||t,u=i.easing||function(t,e,i,r){return-i*Math.cos(t/r*(Math.PI/2))+i+e},f="startValue"in i?i.startValue:0,d="endValue"in i?i.endValue:100,g=i.byValue||d-f;i.onStart&&i.onStart(),function t(r){if(c())l(d,1,1);else{var p=(n=r||+new Date)>a?o:n-s,v=p/o,m=u(p,f,g,o),b=Math.abs((m-f)/g);h(m,b,v),n>a?i.onComplete&&i.onComplete():e(t)}}(s)})},fabric.util.requestAnimFrame=e,fabric.util.cancelAnimFrame=function(){return r.apply(fabric.window,arguments)}}(),function(){function t(t,e,i){var r="rgba("+parseInt(t[0]+i*(e[0]-t[0]),10)+","+parseInt(t[1]+i*(e[1]-t[1]),10)+","+parseInt(t[2]+i*(e[2]-t[2]),10);return r+=","+(t&&e?parseFloat(t[3]+i*(e[3]-t[3])):1),r+=")"}fabric.util.animateColor=function(e,i,r,n){var s=new fabric.Color(e).getSource(),o=new fabric.Color(i).getSource();n=n||{},fabric.util.animate(fabric.util.object.extend(n,{duration:r||500,startValue:s,endValue:o,byValue:o,easing:function(e,i,r,s){return t(i,r,n.colorEasing?n.colorEasing(e,s):1-Math.cos(e/s*(Math.PI/2)))}}))}}(),function(){function t(t,e,i,r){return t-1&&a>-1&&a-1&&(e="stroke")}else n=s?e.map(y):y(e,r);else e="";return!s&&isNaN(n)?e:n}function r(t){return new RegExp("^("+t.join("|")+")\\b","i")}function n(t){for(var e in k)if(void 0!==t[k[e]]&&""!==t[e]){if(void 0===t[e]){if(!v.Object.prototype[e])continue;t[e]=v.Object.prototype[e]}if(0!==t[e].indexOf("url(")){var i=new v.Color(t[e]);t[e]=i.setAlpha(_(i.getAlpha()*t[k[e]],2)).toRgba()}}return t}function s(t,e){var i,r,n,s,o=[];for(n=0,s=e.length;na?a:o),1===o&&1===a&&0===h&&0===c&&0===f&&0===d)return _;if((f||d)&&(x=" translate("+y(f)+" "+y(d)+") "),r=x+" matrix("+o+" 0 0 "+a+" "+h*o+" "+c*a+") ","svg"===t.nodeName){for(n=t.ownerDocument.createElement("g");t.firstChild;)n.appendChild(t.firstChild);t.appendChild(n)}else r=(n=t).getAttribute("transform")+r;return n.setAttribute("transform",r),_}function p(t,e){for(;t&&(t=t.parentNode);)if(t.nodeName&&e.test(t.nodeName.replace("svg:",""))&&!t.getAttribute("instantiated_by_use"))return!0;return!1}var v=t.fabric||(t.fabric={}),m=v.util.object.extend,b=v.util.object.clone,_=v.util.toFixed,y=v.util.parseUnit,x=v.util.multiplyTransformMatrices,C=["path","circle","polygon","polyline","ellipse","rect","line","image","text","linearGradient","radialGradient","stop"],S=["symbol","image","marker","pattern","view","svg"],w=["pattern","defs","symbol","metadata","clipPath","mask","desc"],T=["symbol","g","a","svg"],O={cx:"left",x:"left",r:"radius",cy:"top",y:"top",display:"visible",visibility:"visible",transform:"transformMatrix","fill-opacity":"fillOpacity","fill-rule":"fillRule","font-family":"fontFamily","font-size":"fontSize","font-style":"fontStyle","font-weight":"fontWeight","paint-order":"paintFirst","stroke-dasharray":"strokeDashArray","stroke-linecap":"strokeLineCap","stroke-linejoin":"strokeLineJoin","stroke-miterlimit":"strokeMiterLimit","stroke-opacity":"strokeOpacity","stroke-width":"strokeWidth","text-decoration":"textDecoration","text-anchor":"textAnchor",opacity:"opacity"},k={stroke:"strokeOpacity",fill:"fillOpacity"};v.svgValidTagNamesRegEx=r(C),v.svgViewBoxElementsRegEx=r(S),v.svgInvalidAncestorsRegEx=r(w),v.svgValidParentsRegEx=r(T),v.cssRules={},v.gradientDefs={},v.parseTransformAttribute=function(){function t(t,e){var i=Math.cos(e[0]),r=Math.sin(e[0]),n=0,s=0;3===e.length&&(n=e[1],s=e[2]),t[0]=i,t[1]=r,t[2]=-r,t[3]=i,t[4]=n-(i*n-r*s),t[5]=s-(r*n+i*s)}function e(t,e){var i=e[0],r=2===e.length?e[1]:e[0];t[0]=i,t[3]=r}function i(t,e,i){t[i]=Math.tan(v.util.degreesToRadians(e[0]))}function r(t,e){t[4]=e[0],2===e.length&&(t[5]=e[1])}var n=[1,0,0,1,0,0],s=v.reNum,o="(?:\\s+,?\\s*|,\\s*)",a="(?:"+("(?:(matrix)\\s*\\(\\s*("+s+")"+o+"("+s+")"+o+"("+s+")"+o+"("+s+")"+o+"("+s+")"+o+"("+s+")\\s*\\))")+"|"+("(?:(translate)\\s*\\(\\s*("+s+")(?:"+o+"("+s+"))?\\s*\\))")+"|"+("(?:(scale)\\s*\\(\\s*("+s+")(?:"+o+"("+s+"))?\\s*\\))")+"|"+("(?:(rotate)\\s*\\(\\s*("+s+")(?:"+o+"("+s+")"+o+"("+s+"))?\\s*\\))")+"|"+("(?:(skewX)\\s*\\(\\s*("+s+")\\s*\\))")+"|"+("(?:(skewY)\\s*\\(\\s*("+s+")\\s*\\))")+")",h="^\\s*(?:"+("(?:"+a+"(?:"+o+"*"+a+")*)")+"?)\\s*$",c=new RegExp(h),l=new RegExp(a,"g");return function(s){var o=n.concat(),h=[];if(!s||s&&!c.test(s))return o;s.replace(l,function(s){var c=new RegExp(a).exec(s).filter(function(t){return!!t}),l=c[1],u=c.slice(2).map(parseFloat);switch(l){case"translate":r(o,u);break;case"rotate":u[0]=v.util.degreesToRadians(u[0]),t(o,u);break;case"scale":e(o,u);break;case"skewX":i(o,u,2);break;case"skewY":i(o,u,1);break;case"matrix":o=u}h.push(o.concat()),o=n.concat()});for(var u=h[0];h.length>1;)h.shift(),u=v.util.multiplyTransformMatrices(u,h[0]);return u}}();var D=new RegExp("^\\s*("+v.reNum+"+)\\s*,?\\s*("+v.reNum+"+)\\s*,?\\s*("+v.reNum+"+)\\s*,?\\s*("+v.reNum+"+)\\s*$");v.parseSVGDocument=function(t,e,i,r){if(t){d(t);var n,s,o=v.Object.__uid++,a=g(t),h=v.util.toArray(t.getElementsByTagName("*"));if(a.crossOrigin=r&&r.crossOrigin,a.svgUid=o,0===h.length&&v.isLikelyNode){var c=[];for(n=0,s=(h=t.selectNodes('//*[name(.)!="svg"]')).length;n/i,""))),n&&n.documentElement||e&&e(null),v.parseSVGDocument(n.documentElement,function(t,i,r,n){e&&e(t,i,r,n)},i,r)}})},loadSVGFromString:function(t,e,i,r){t=t.trim();var n;if("undefined"!=typeof DOMParser){var s=new DOMParser;s&&s.parseFromString&&(n=s.parseFromString(t,"text/xml"))}else v.window.ActiveXObject&&((n=new ActiveXObject("Microsoft.XMLDOM")).async="false",n.loadXML(t.replace(//i,"")));v.parseSVGDocument(n.documentElement,function(t,i,r,n){e(t,i,r,n)},i,r)}})}("undefined"!=typeof exports?exports:this),fabric.ElementsParser=function(t,e,i,r,n){this.elements=t,this.callback=e,this.options=i,this.reviver=r,this.svgUid=i&&i.svgUid||0,this.parsingOptions=n},fabric.ElementsParser.prototype.parse=function(){this.instances=new Array(this.elements.length),this.numElements=this.elements.length,this.createObjects()},fabric.ElementsParser.prototype.createObjects=function(){for(var t=0,e=this.elements.length;tt.x&&this.y>t.y},gte:function(t){return this.x>=t.x&&this.y>=t.y},lerp:function(t,i){return void 0===i&&(i=.5),i=Math.max(Math.min(1,i),0),new e(this.x+(t.x-this.x)*i,this.y+(t.y-this.y)*i)},distanceFrom:function(t){var e=this.x-t.x,i=this.y-t.y;return Math.sqrt(e*e+i*i)},midPointFrom:function(t){return this.lerp(t)},min:function(t){return new e(Math.min(this.x,t.x),Math.min(this.y,t.y))},max:function(t){return new e(Math.max(this.x,t.x),Math.max(this.y,t.y))},toString:function(){return this.x+","+this.y},setXY:function(t,e){return this.x=t,this.y=e,this},setX:function(t){return this.x=t,this},setY:function(t){return this.y=t,this},setFromPoint:function(t){return this.x=t.x,this.y=t.y,this},swap:function(t){var e=this.x,i=this.y;this.x=t.x,this.y=t.y,t.x=e,t.y=i},clone:function(){return new e(this.x,this.y)}})}("undefined"!=typeof exports?exports:this),function(t){"use strict";function e(t){this.status=t,this.points=[]}var i=t.fabric||(t.fabric={});i.Intersection?i.warn("fabric.Intersection is already defined"):(i.Intersection=e,i.Intersection.prototype={constructor:e,appendPoint:function(t){return this.points.push(t),this},appendPoints:function(t){return this.points=this.points.concat(t),this}},i.Intersection.intersectLineLine=function(t,r,n,s){var o,a=(s.x-n.x)*(t.y-n.y)-(s.y-n.y)*(t.x-n.x),h=(r.x-t.x)*(t.y-n.y)-(r.y-t.y)*(t.x-n.x),c=(s.y-n.y)*(r.x-t.x)-(s.x-n.x)*(r.y-t.y);if(0!==c){var l=a/c,u=h/c;0<=l&&l<=1&&0<=u&&u<=1?(o=new e("Intersection")).appendPoint(new i.Point(t.x+l*(r.x-t.x),t.y+l*(r.y-t.y))):o=new e}else o=new e(0===a||0===h?"Coincident":"Parallel");return o},i.Intersection.intersectLinePolygon=function(t,i,r){var n,s,o,a,h=new e,c=r.length;for(a=0;a0&&(h.status="Intersection"),h},i.Intersection.intersectPolygonPolygon=function(t,i){var r,n=new e,s=t.length;for(r=0;r0&&(n.status="Intersection"),n},i.Intersection.intersectPolygonRectangle=function(t,r,n){var s=r.min(n),o=r.max(n),a=new i.Point(o.x,s.y),h=new i.Point(s.x,o.y),c=e.intersectLinePolygon(s,a,t),l=e.intersectLinePolygon(a,o,t),u=e.intersectLinePolygon(o,h,t),f=e.intersectLinePolygon(h,s,t),d=new e;return d.appendPoints(c.points),d.appendPoints(l.points),d.appendPoints(u.points),d.appendPoints(f.points),d.points.length>0&&(d.status="Intersection"),d})}("undefined"!=typeof exports?exports:this),function(t){"use strict";function e(t){t?this._tryParsingColor(t):this.setSource([0,0,0,1])}function i(t,e,i){return i<0&&(i+=1),i>1&&(i-=1),i<1/6?t+6*(e-t)*i:i<.5?e:i<2/3?t+(e-t)*(2/3-i)*6:t}var r=t.fabric||(t.fabric={});r.Color?r.warn("fabric.Color is already defined."):(r.Color=e,r.Color.prototype={_tryParsingColor:function(t){var i;t in e.colorNameMap&&(t=e.colorNameMap[t]),"transparent"===t&&(i=[255,255,255,0]),i||(i=e.sourceFromHex(t)),i||(i=e.sourceFromRgb(t)),i||(i=e.sourceFromHsl(t)),i||(i=[0,0,0,1]),i&&this.setSource(i)},_rgbToHsl:function(t,e,i){t/=255,e/=255,i/=255;var n,s,o,a=r.util.array.max([t,e,i]),h=r.util.array.min([t,e,i]);if(o=(a+h)/2,a===h)n=s=0;else{var c=a-h;switch(s=o>.5?c/(2-a-h):c/(a+h),a){case t:n=(e-i)/c+(e1?1:o,s){var a=s.split(/\s*;\s*/);for(""===a[a.length-1]&&a.pop(),n=a.length;n--;){var h=a[n].split(/\s*:\s*/),c=h[0].trim(),l=h[1].trim();"stop-color"===c?e=l:"stop-opacity"===c&&(r=l)}}return e||(e=t.getAttribute("stop-color")||"rgb(0,0,0)"),r||(r=t.getAttribute("stop-opacity")),e=new fabric.Color(e),i=e.getAlpha(),r=isNaN(parseFloat(r))?1:parseFloat(r),r*=i,{offset:o,color:e.toRgb(),opacity:r}}function e(t){return{x1:t.getAttribute("x1")||0,y1:t.getAttribute("y1")||0,x2:t.getAttribute("x2")||"100%",y2:t.getAttribute("y2")||0}}function i(t){return{x1:t.getAttribute("fx")||t.getAttribute("cx")||"50%",y1:t.getAttribute("fy")||t.getAttribute("cy")||"50%",r1:0,x2:t.getAttribute("cx")||"50%",y2:t.getAttribute("cy")||"50%",r2:t.getAttribute("r")||"50%"}}function r(t,e,i){var r,n=0,s=1,o="";for(var a in e)"Infinity"===e[a]?e[a]=1:"-Infinity"===e[a]&&(e[a]=0),r=parseFloat(e[a],10),s="string"==typeof e[a]&&/^\d+%$/.test(e[a])?.01:1,"x1"===a||"x2"===a||"r2"===a?(s*="objectBoundingBox"===i?t.width:1,n="objectBoundingBox"===i?t.left||0:0):"y1"!==a&&"y2"!==a||(s*="objectBoundingBox"===i?t.height:1,n="objectBoundingBox"===i?t.top||0:0),e[a]=r*s+n;if("ellipse"===t.type&&null!==e.r2&&"objectBoundingBox"===i&&t.rx!==t.ry){var h=t.ry/t.rx;o=" scale(1, "+h+")",e.y1&&(e.y1/=h),e.y2&&(e.y2/=h)}return o}var n=fabric.util.object.clone;fabric.Gradient=fabric.util.createClass({offsetX:0,offsetY:0,initialize:function(t){t||(t={});var e={};this.id=fabric.Object.__uid++,this.type=t.type||"linear",e={x1:t.coords.x1||0,y1:t.coords.y1||0,x2:t.coords.x2||0,y2:t.coords.y2||0},"radial"===this.type&&(e.r1=t.coords.r1||0,e.r2=t.coords.r2||0),this.coords=e,this.colorStops=t.colorStops.slice(),t.gradientTransform&&(this.gradientTransform=t.gradientTransform),this.offsetX=t.offsetX||this.offsetX,this.offsetY=t.offsetY||this.offsetY},addColorStop:function(t){for(var e in t){var i=new fabric.Color(t[e]);this.colorStops.push({offset:parseFloat(e),color:i.toRgb(),opacity:i.getAlpha()})}return this},toObject:function(t){var e={type:this.type,coords:this.coords,colorStops:this.colorStops,offsetX:this.offsetX,offsetY:this.offsetY,gradientTransform:this.gradientTransform?this.gradientTransform.concat():this.gradientTransform};return fabric.util.populateWithProperties(this,e,t),e},toSVG:function(t){var e,i,r,s,o=n(this.coords,!0),a=n(this.colorStops,!0),h=o.r1>o.r2,c=t.width/2,l=t.height/2;a.sort(function(t,e){return t.offset-e.offset}),"path"===t.type&&(c-=t.pathOffset.x,l-=t.pathOffset.y);for(var u in o)"x1"===u||"x2"===u?o[u]+=this.offsetX-c:"y1"!==u&&"y2"!==u||(o[u]+=this.offsetY-l);if(s='id="SVGID_'+this.id+'" gradientUnits="userSpaceOnUse"',this.gradientTransform&&(s+=' gradientTransform="matrix('+this.gradientTransform.join(" ")+')" '),"linear"===this.type?r=["\n']:"radial"===this.type&&(r=["\n']),"radial"===this.type){if(h)for((a=a.concat()).reverse(),e=0,i=a.length;e0){var d=f/Math.max(o.r1,o.r2);for(e=0,i=a.length;e\n')}return r.push("linear"===this.type?"\n":"\n"),r.join("")},toLive:function(t){var e,i,r,n=fabric.util.object.clone(this.coords);if(this.type){for("linear"===this.type?e=t.createLinearGradient(n.x1,n.y1,n.x2,n.y2):"radial"===this.type&&(e=t.createRadialGradient(n.x1,n.y1,n.r1,n.x2,n.y2,n.r2)),i=0,r=this.colorStops.length;i\n\n\n'},setOptions:function(t){for(var e in t)this[e]=t[e]},toLive:function(t){var e="function"==typeof this.source?this.source():this.source;if(!e)return"";if(void 0!==e.src){if(!e.complete)return"";if(0===e.naturalWidth||0===e.naturalHeight)return""}return t.createPattern(e,this.repeat)}})}(),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=e.util.toFixed;e.Shadow?e.warn("fabric.Shadow is already defined."):(e.Shadow=e.util.createClass({color:"rgb(0,0,0)",blur:0,offsetX:0,offsetY:0,affectStroke:!1,includeDefaultValues:!0,initialize:function(t){"string"==typeof t&&(t=this._parseShadow(t));for(var i in t)this[i]=t[i];this.id=e.Object.__uid++},_parseShadow:function(t){var i=t.trim(),r=e.Shadow.reOffsetsAndBlur.exec(i)||[];return{color:(i.replace(e.Shadow.reOffsetsAndBlur,"")||"rgb(0,0,0)").trim(),offsetX:parseInt(r[1],10)||0,offsetY:parseInt(r[2],10)||0,blur:parseInt(r[3],10)||0}},toString:function(){return[this.offsetX,this.offsetY,this.blur,this.color].join("px ")},toSVG:function(t){var r=40,n=40,s=e.Object.NUM_FRACTION_DIGITS,o=e.util.rotateVector({x:this.offsetX,y:this.offsetY},e.util.degreesToRadians(-t.angle));return t.width&&t.height&&(r=100*i((Math.abs(o.x)+this.blur)/t.width,s)+20,n=100*i((Math.abs(o.y)+this.blur)/t.height,s)+20),t.flipX&&(o.x*=-1),t.flipY&&(o.y*=-1),'\n\t\n\t\n\t\n\t\n\t\n\t\t\n\t\t\n\t\n\n'},toObject:function(){if(this.includeDefaultValues)return{color:this.color,blur:this.blur,offsetX:this.offsetX,offsetY:this.offsetY,affectStroke:this.affectStroke};var t={},i=e.Shadow.prototype;return["color","blur","offsetX","offsetY","affectStroke"].forEach(function(e){this[e]!==i[e]&&(t[e]=this[e])},this),t}}),e.Shadow.reOffsetsAndBlur=/(?:\s|^)(-?\d+(?:px)?(?:\s?|$))?(-?\d+(?:px)?(?:\s?|$))?(\d+(?:px)?)?(?:\s?|$)(?:$|\s)/)}("undefined"!=typeof exports?exports:this),function(){"use strict";if(fabric.StaticCanvas)fabric.warn("fabric.StaticCanvas is already defined.");else{var t=fabric.util.object.extend,e=fabric.util.getElementOffset,i=fabric.util.removeFromArray,r=fabric.util.toFixed,n=fabric.util.transformPoint,s=fabric.util.invertTransform,o=new Error("Could not initialize `canvas` element");fabric.StaticCanvas=fabric.util.createClass(fabric.CommonMethods,{initialize:function(t,e){e||(e={}),this.renderAndResetBound=this.renderAndReset.bind(this),this.requestRenderAllBound=this.requestRenderAll.bind(this),this._initStatic(t,e)},backgroundColor:"",backgroundImage:null,overlayColor:"",overlayImage:null,includeDefaultValues:!0,stateful:!1,renderOnAddRemove:!0,clipTo:null,controlsAboveOverlay:!1,allowTouchScrolling:!1,imageSmoothingEnabled:!0,viewportTransform:fabric.iMatrix.concat(),backgroundVpt:!0,overlayVpt:!0,onBeforeScaleRotate:function(){},enableRetinaScaling:!0,vptCoords:{},skipOffscreen:!0,_initStatic:function(t,e){var i=this.requestRenderAllBound;this._objects=[],this._createLowerCanvas(t),this._initOptions(e),this._setImageSmoothing(),this.interactive||this._initRetinaScaling(),e.overlayImage&&this.setOverlayImage(e.overlayImage,i),e.backgroundImage&&this.setBackgroundImage(e.backgroundImage,i),e.backgroundColor&&this.setBackgroundColor(e.backgroundColor,i),e.overlayColor&&this.setOverlayColor(e.overlayColor,i),this.calcOffset()},_isRetinaScaling:function(){return 1!==fabric.devicePixelRatio&&this.enableRetinaScaling},getRetinaScaling:function(){return this._isRetinaScaling()?fabric.devicePixelRatio:1},_initRetinaScaling:function(){this._isRetinaScaling()&&(this.lowerCanvasEl.setAttribute("width",this.width*fabric.devicePixelRatio),this.lowerCanvasEl.setAttribute("height",this.height*fabric.devicePixelRatio),this.contextContainer.scale(fabric.devicePixelRatio,fabric.devicePixelRatio))},calcOffset:function(){return this._offset=e(this.lowerCanvasEl),this},setOverlayImage:function(t,e,i){return this.__setBgOverlayImage("overlayImage",t,e,i)},setBackgroundImage:function(t,e,i){return this.__setBgOverlayImage("backgroundImage",t,e,i)},setOverlayColor:function(t,e){return this.__setBgOverlayColor("overlayColor",t,e)},setBackgroundColor:function(t,e){return this.__setBgOverlayColor("backgroundColor",t,e)},_setImageSmoothing:function(){var t=this.getContext();t.imageSmoothingEnabled=t.imageSmoothingEnabled||t.webkitImageSmoothingEnabled||t.mozImageSmoothingEnabled||t.msImageSmoothingEnabled||t.oImageSmoothingEnabled,t.imageSmoothingEnabled=this.imageSmoothingEnabled},__setBgOverlayImage:function(t,e,i,r){return"string"==typeof e?fabric.util.loadImage(e,function(e){e&&(this[t]=new fabric.Image(e,r)),i&&i(e)},this,r&&r.crossOrigin):(r&&e.setOptions(r),this[t]=e,i&&i(e)),this},__setBgOverlayColor:function(t,e,i){return this[t]=e,this._initGradient(e,t),this._initPattern(e,t,i),this},_createCanvasElement:function(){var t=fabric.util.createCanvasElement();if(!t)throw o;if(t.style||(t.style={}),void 0===t.getContext)throw o;return t},_initOptions:function(t){this._setOptions(t),this.width=this.width||parseInt(this.lowerCanvasEl.width,10)||0,this.height=this.height||parseInt(this.lowerCanvasEl.height,10)||0,this.lowerCanvasEl.style&&(this.lowerCanvasEl.width=this.width,this.lowerCanvasEl.height=this.height,this.lowerCanvasEl.style.width=this.width+"px",this.lowerCanvasEl.style.height=this.height+"px",this.viewportTransform=this.viewportTransform.slice())},_createLowerCanvas:function(t){t&&t.getContext?this.lowerCanvasEl=t:this.lowerCanvasEl=fabric.util.getById(t)||this._createCanvasElement(),fabric.util.addClass(this.lowerCanvasEl,"lower-canvas"),this.interactive&&this._applyCanvasStyle(this.lowerCanvasEl),this.contextContainer=this.lowerCanvasEl.getContext("2d")},getWidth:function(){return this.width},getHeight:function(){return this.height},setWidth:function(t,e){return this.setDimensions({width:t},e)},setHeight:function(t,e){return this.setDimensions({height:t},e)},setDimensions:function(t,e){var i;e=e||{};for(var r in t)i=t[r],e.cssOnly||(this._setBackstoreDimension(r,t[r]),i+="px"),e.backstoreOnly||this._setCssDimension(r,i);return this._initRetinaScaling(),this._setImageSmoothing(),this.calcOffset(),e.cssOnly||this.requestRenderAll(),this},_setBackstoreDimension:function(t,e){return this.lowerCanvasEl[t]=e,this.upperCanvasEl&&(this.upperCanvasEl[t]=e),this.cacheCanvasEl&&(this.cacheCanvasEl[t]=e),this[t]=e,this},_setCssDimension:function(t,e){return this.lowerCanvasEl.style[t]=e,this.upperCanvasEl&&(this.upperCanvasEl.style[t]=e),this.wrapperEl&&(this.wrapperEl.style[t]=e),this},getZoom:function(){return this.viewportTransform[0]},setViewportTransform:function(t){var e,i,r,n=this._activeObject;for(this.viewportTransform=t,i=0,r=this._objects.length;i"),i.join("")},_setSVGPreamble:function(t,e){e.suppressPreamble||t.push('\n','\n')},_setSVGHeader:function(t,e){var i,n=e.width||this.width,s=e.height||this.height,o='viewBox="0 0 '+this.width+" "+this.height+'" ',a=fabric.Object.NUM_FRACTION_DIGITS;e.viewBox?o='viewBox="'+e.viewBox.x+" "+e.viewBox.y+" "+e.viewBox.width+" "+e.viewBox.height+'" ':this.svgViewportTransformation&&(i=this.viewportTransform,o='viewBox="'+r(-i[4]/i[0],a)+" "+r(-i[5]/i[3],a)+" "+r(this.width/i[0],a)+" "+r(this.height/i[3],a)+'" '),t.push("\n',"Created with Fabric.js ",fabric.version,"\n","\n",this.createSVGFontFacesMarkup(),this.createSVGRefElementsMarkup(),"\n")},createSVGRefElementsMarkup:function(){var t=this;return["backgroundColor","overlayColor"].map(function(e){var i=t[e];if(i&&i.toLive)return i.toSVG(t,!1)}).join("")},createSVGFontFacesMarkup:function(){var t,e,i,r,n,s,o,a,h="",c={},l=fabric.fontPaths,u=this.getObjects();for(o=0,a=u.length;o',"\n",h,"","\n"].join("")),h},_setSVGObjects:function(t,e){var i,r,n,s=this.getObjects();for(r=0,n=s.length;r\n")}else t.push('\n")},sendToBack:function(t){if(!t)return this;var e,r,n,s=this._activeObject;if(t===s&&"activeSelection"===t.type)for(e=(n=s._objects).length;e--;)r=n[e],i(this._objects,r),this._objects.unshift(r);else i(this._objects,t),this._objects.unshift(t);return this.renderOnAddRemove&&this.requestRenderAll(),this},bringToFront:function(t){if(!t)return this;var e,r,n,s=this._activeObject;if(t===s&&"activeSelection"===t.type)for(n=s._objects,e=0;e0+c&&(o=s-1,i(this._objects,n),this._objects.splice(o,0,n)),c++;else 0!==(s=this._objects.indexOf(t))&&(o=this._findNewLowerIndex(t,s,e),i(this._objects,t),this._objects.splice(o,0,t));return this.renderOnAddRemove&&this.requestRenderAll(),this},_findNewLowerIndex:function(t,e,i){var r,n;if(i){for(r=e,n=e-1;n>=0;--n)if(t.intersectsWithObject(this._objects[n])||t.isContainedWithinObject(this._objects[n])||this._objects[n].isContainedWithinObject(t)){r=n;break}}else r=e-1;return r},bringForward:function(t,e){if(!t)return this;var r,n,s,o,a,h=this._activeObject,c=0;if(t===h&&"activeSelection"===t.type)for(r=(a=h._objects).length;r--;)n=a[r],(s=this._objects.indexOf(n))"}}),t(fabric.StaticCanvas.prototype,fabric.Observable),t(fabric.StaticCanvas.prototype,fabric.Collection),t(fabric.StaticCanvas.prototype,fabric.DataURLExporter),t(fabric.StaticCanvas,{EMPTY_JSON:'{"objects": [], "background": "white"}',supports:function(t){var e=fabric.util.createCanvasElement();if(!e||!e.getContext)return null;var i=e.getContext("2d");if(!i)return null;switch(t){case"getImageData":return void 0!==i.getImageData;case"setLineDash":return void 0!==i.setLineDash;case"toDataURL":return void 0!==e.toDataURL;case"toDataURLWithQuality":try{return e.toDataURL("image/jpeg",0),!0}catch(t){}return!1;default:return null}}}),fabric.StaticCanvas.prototype.toJSON=fabric.StaticCanvas.prototype.toObject}}(),fabric.BaseBrush=fabric.util.createClass({color:"rgb(0, 0, 0)",width:1,shadow:null,strokeLineCap:"round",strokeLineJoin:"round",strokeMiterLimit:10,strokeDashArray:null,setShadow:function(t){return this.shadow=new fabric.Shadow(t),this},_setBrushStyles:function(){var t=this.canvas.contextTop;t.strokeStyle=this.color,t.lineWidth=this.width,t.lineCap=this.strokeLineCap,t.miterLimit=this.strokeMiterLimit,t.lineJoin=this.strokeLineJoin,this.strokeDashArray&&fabric.StaticCanvas.supports("setLineDash")&&t.setLineDash(this.strokeDashArray)},_setShadow:function(){if(this.shadow){var t=this.canvas.contextTop,e=this.canvas.getZoom();t.shadowColor=this.shadow.color,t.shadowBlur=this.shadow.blur*e,t.shadowOffsetX=this.shadow.offsetX*e,t.shadowOffsetY=this.shadow.offsetY*e}},_resetShadow:function(){var t=this.canvas.contextTop;t.shadowColor="",t.shadowBlur=t.shadowOffsetX=t.shadowOffsetY=0}}),fabric.PencilBrush=fabric.util.createClass(fabric.BaseBrush,{initialize:function(t){this.canvas=t,this._points=[]},onMouseDown:function(t){this._prepareForDrawing(t),this._captureDrawingPath(t),this._render()},onMouseMove:function(t){this._captureDrawingPath(t),this.canvas.clearContext(this.canvas.contextTop),this._render()},onMouseUp:function(){this._finalizeAndAddPath()},_prepareForDrawing:function(t){var e=new fabric.Point(t.x,t.y);this._reset(),this._addPoint(e),this.canvas.contextTop.moveTo(e.x,e.y)},_addPoint:function(t){this._points.length>1&&t.eq(this._points[this._points.length-1])||this._points.push(t)},_reset:function(){this._points.length=0,this._setBrushStyles(),this._setShadow()},_captureDrawingPath:function(t){var e=new fabric.Point(t.x,t.y);this._addPoint(e)},_render:function(){var t,e,i=this.canvas.contextTop,r=this.canvas.viewportTransform,n=this._points[0],s=this._points[1];if(i.save(),i.transform(r[0],r[1],r[2],r[3],r[4],r[5]),i.beginPath(),2===this._points.length&&n.x===s.x&&n.y===s.y){var o=this.width/1e3;n=new fabric.Point(n.x,n.y),s=new fabric.Point(s.x,s.y),n.x-=o,s.x+=o}for(i.moveTo(n.x,n.y),t=1,e=this._points.length;t2;for(c&&(i=t[2].xt[e-2].x?1:o.x===t[e-2].x?0:-1,r=o.y>t[e-2].y?1:o.y===t[e-2].y?0:-1),n.push("L ",o.x+i*s," ",o.y+r*s),n},createPath:function(t){var e=new fabric.Path(t,{fill:null,stroke:this.color,strokeWidth:this.width,strokeLineCap:this.strokeLineCap,strokeMiterLimit:this.strokeMiterLimit,strokeLineJoin:this.strokeLineJoin,strokeDashArray:this.strokeDashArray}),i=new fabric.Point(e.left+e.width/2,e.top+e.height/2);return i=e.translateToGivenOrigin(i,"center","center",e.originX,e.originY),e.top=i.y,e.left=i.x,this.shadow&&(this.shadow.affectStroke=!0,e.setShadow(this.shadow)),e},_finalizeAndAddPath:function(){this.canvas.contextTop.closePath();var t=this.convertPointsToSVGPath(this._points).join("");if("M 0 0 Q 0 0 0 0 L 0 0"!==t){var e=this.createPath(t);this.canvas.clearContext(this.canvas.contextTop),this.canvas.add(e),this.canvas.renderAll(),e.setCoords(),this._resetShadow(),this.canvas.fire("path:created",{path:e})}else this.canvas.requestRenderAll()}}),fabric.CircleBrush=fabric.util.createClass(fabric.BaseBrush,{width:10,initialize:function(t){this.canvas=t,this.points=[]},drawDot:function(t){var e=this.addPoint(t),i=this.canvas.contextTop,r=this.canvas.viewportTransform;i.save(),i.transform(r[0],r[1],r[2],r[3],r[4],r[5]),i.fillStyle=e.fill,i.beginPath(),i.arc(e.x,e.y,e.radius,0,2*Math.PI,!1),i.closePath(),i.fill(),i.restore()},onMouseDown:function(t){this.points.length=0,this.canvas.clearContext(this.canvas.contextTop),this._setShadow(),this.drawDot(t)},onMouseMove:function(t){this.drawDot(t)},onMouseUp:function(){var t,e,i=this.canvas.renderOnAddRemove;this.canvas.renderOnAddRemove=!1;var r=[];for(t=0,e=this.points.length;t0&&!this.preserveObjectStacking){e=[],i=[];for(var n=0,s=this._objects.length;n1&&(this._activeObject._objects=i),e.push.apply(e,i)}else e=this._objects;return e},renderAll:function(){!this.contextTopDirty||this._groupSelector||this.isDrawingMode||(this.clearContext(this.contextTop),this.contextTopDirty=!1);var t=this.contextContainer;return this.renderCanvas(t,this._chooseObjectsToRender()),this},renderTop:function(){var t=this.contextTop;return this.clearContext(t),this.selection&&this._groupSelector&&this._drawSelection(t),this.fire("after:render"),this.contextTopDirty=!0,this},_resetCurrentTransform:function(){var t=this._currentTransform;t.target.set({scaleX:t.original.scaleX,scaleY:t.original.scaleY,skewX:t.original.skewX,skewY:t.original.skewY,left:t.original.left,top:t.original.top}),this._shouldCenterTransform(t.target)?"rotate"===t.action?this._setOriginToCenter(t.target):("center"!==t.originX&&("right"===t.originX?t.mouseXSign=-1:t.mouseXSign=1),"center"!==t.originY&&("bottom"===t.originY?t.mouseYSign=-1:t.mouseYSign=1),t.originX="center",t.originY="center"):(t.originX=t.original.originX,t.originY=t.original.originY)},containsPoint:function(t,e,i){var r,n=i||this.getPointer(t,!0);return r=e.group&&e.group===this._activeObject&&"activeSelection"===e.group.type?this._normalizePointer(e.group,n):{x:n.x,y:n.y},e.containsPoint(r)||e._findTargetCorner(n)},_normalizePointer:function(t,e){var i=t.calcTransformMatrix(),r=fabric.util.invertTransform(i),n=this.restorePointerVpt(e);return fabric.util.transformPoint(n,r)},isTargetTransparent:function(t,e,i){var r=this.contextCache,n=t.selectionBackgroundColor,s=this.viewportTransform;return t.selectionBackgroundColor="",this.clearContext(r),r.save(),r.transform(s[0],s[1],s[2],s[3],s[4],s[5]),t.render(r),r.restore(),t===this._activeObject&&t._renderControls(r,{hasBorders:!1,transparentCorners:!1},{hasBorders:!1}),t.selectionBackgroundColor=n,fabric.util.isTransparent(r,e,i,this.targetFindTolerance)},_isSelectionKeyPressed:function(t){return"[object Array]"===Object.prototype.toString.call(this.selectionKey)?!!this.selectionKey.find(function(e){return!0===t[e]}):t[this.selectionKey]},_shouldClearSelection:function(t,e){var i=this.getActiveObjects(),r=this._activeObject;return!e||e&&r&&i.length>1&&-1===i.indexOf(e)&&r!==e&&!this._isSelectionKeyPressed(t)||e&&!e.evented||e&&!e.selectable&&r&&r!==e},_shouldCenterTransform:function(t){if(t){var e,i=this._currentTransform;return"scale"===i.action||"scaleX"===i.action||"scaleY"===i.action?e=this.centeredScaling||t.centeredScaling:"rotate"===i.action&&(e=this.centeredRotation||t.centeredRotation),e?!i.altKey:i.altKey}},_getOriginFromCorner:function(t,e){var i={x:t.originX,y:t.originY};return"ml"===e||"tl"===e||"bl"===e?i.x="right":"mr"!==e&&"tr"!==e&&"br"!==e||(i.x="left"),"tl"===e||"mt"===e||"tr"===e?i.y="bottom":"bl"!==e&&"mb"!==e&&"br"!==e||(i.y="top"),i},_getActionFromCorner:function(t,e,i){if(!e)return"drag";switch(e){case"mtr":return"rotate";case"ml":case"mr":return i[this.altActionKey]?"skewY":"scaleX";case"mt":case"mb":return i[this.altActionKey]?"skewX":"scaleY";default:return"scale"}},_setupCurrentTransform:function(t,i){if(i){var r=this.getPointer(t),n=i._findTargetCorner(this.getPointer(t,!0)),s=this._getActionFromCorner(i,n,t),o=this._getOriginFromCorner(i,n);this._currentTransform={target:i,action:s,corner:n,scaleX:i.scaleX,scaleY:i.scaleY,skewX:i.skewX,skewY:i.skewY,offsetX:r.x-i.left,offsetY:r.y-i.top,originX:o.x,originY:o.y,ex:r.x,ey:r.y,lastX:r.x,lastY:r.y,left:i.left,top:i.top,theta:e(i.angle),width:i.width*i.scaleX,mouseXSign:1,mouseYSign:1,shiftKey:t.shiftKey,altKey:t[this.centeredKey]},this._currentTransform.original={left:i.left,top:i.top,scaleX:i.scaleX,scaleY:i.scaleY,skewX:i.skewX,skewY:i.skewY,originX:o.x,originY:o.y},this._resetCurrentTransform()}},_translateObject:function(t,e){var i=this._currentTransform,r=i.target,n=t-i.offsetX,s=e-i.offsetY,o=!r.get("lockMovementX")&&r.left!==n,a=!r.get("lockMovementY")&&r.top!==s;return o&&r.set("left",n),a&&r.set("top",s),o||a},_changeSkewTransformOrigin:function(t,e,i){var r="originX",n={0:"center"},s=e.target.skewX,o="left",a="right",h="mt"===e.corner||"ml"===e.corner?1:-1,c=1;t=t>0?1:-1,"y"===i&&(s=e.target.skewY,o="top",a="bottom",r="originY"),n[-1]=o,n[1]=a,e.target.flipX&&(c*=-1),e.target.flipY&&(c*=-1),0===s?(e.skewSign=-h*t*c,e[r]=n[-t]):(s=s>0?1:-1,e.skewSign=s,e[r]=n[s*h*c])},_skewObject:function(t,e,i){var r=this._currentTransform,n=r.target,s=!1,o=n.get("lockSkewingX"),a=n.get("lockSkewingY");if(o&&"x"===i||a&&"y"===i)return!1;var h,c,l=n.getCenterPoint(),u=n.toLocalPoint(new fabric.Point(t,e),"center","center")[i],f=n.toLocalPoint(new fabric.Point(r.lastX,r.lastY),"center","center")[i],d=n._getTransformedDimensions();return this._changeSkewTransformOrigin(u-f,r,i),h=n.toLocalPoint(new fabric.Point(t,e),r.originX,r.originY)[i],c=n.translateToOriginPoint(l,r.originX,r.originY),s=this._setObjectSkew(h,r,i,d),r.lastX=t,r.lastY=e,n.setPositionByOrigin(c,r.originX,r.originY),s},_setObjectSkew:function(t,e,i,r){var n,s,o,a,h,c,l,u,f,d=e.target,g=!1,p=e.skewSign;return"x"===i?(a="y",h="Y",c="X",u=0,f=d.skewY):(a="x",h="X",c="Y",u=d.skewX,f=0),o=d._getTransformedDimensions(u,f),(l=2*Math.abs(t)-o[i])<=2?n=0:(n=p*Math.atan(l/d["scale"+c]/(o[a]/d["scale"+h])),n=fabric.util.radiansToDegrees(n)),g=d["skew"+c]!==n,d.set("skew"+c,n),0!==d["skew"+h]&&(s=d._getTransformedDimensions(),n=r[a]/s[a]*d["scale"+h],d.set("scale"+h,n)),g},_scaleObject:function(t,e,i){var r=this._currentTransform,n=r.target,s=n.get("lockScalingX"),o=n.get("lockScalingY"),a=n.get("lockScalingFlip");if(s&&o)return!1;var h=n.translateToOriginPoint(n.getCenterPoint(),r.originX,r.originY),c=n.toLocalPoint(new fabric.Point(t,e),r.originX,r.originY),l=n._getTransformedDimensions(),u=!1;return this._setLocalMouse(c,r),u=this._setObjectScale(c,r,s,o,i,a,l),n.setPositionByOrigin(h,r.originX,r.originY),u},_setObjectScale:function(t,e,i,r,n,s,o){var a,h,c,l,u=e.target,f=!1,d=!1,g=!1;return c=t.x*u.scaleX/o.x,l=t.y*u.scaleY/o.y,a=u.scaleX!==c,h=u.scaleY!==l,s&&c<=0&&cs?t.x<0?t.x+=s:t.x-=s:t.x=0,n(t.y)>s?t.y<0?t.y+=s:t.y-=s:t.y=0},_rotateObject:function(t,e){var n=this._currentTransform;if(n.target.get("lockRotation"))return!1;var s=r(n.ey-n.top,n.ex-n.left),o=r(e-n.top,t-n.left),a=i(o-s+n.theta),h=!0;if(n.target.snapAngle>0){var c=n.target.snapAngle,l=n.target.snapThreshold||c,u=Math.ceil(a/c)*c,f=Math.floor(a/c)*c;Math.abs(a-f)0?0:-i),e.ey-(r>0?0:-r),o,a)),this.selectionLineWidth&&this.selectionBorderColor)if(t.lineWidth=this.selectionLineWidth,t.strokeStyle=this.selectionBorderColor,this.selectionDashArray.length>1&&!s){var h=e.ex+.5-(i>0?0:o),c=e.ey+.5-(r>0?0:a);t.beginPath(),fabric.util.drawDashedLine(t,h,c,h+o,c,this.selectionDashArray),fabric.util.drawDashedLine(t,h,c+a-1,h+o,c+a-1,this.selectionDashArray),fabric.util.drawDashedLine(t,h,c,h,c+a,this.selectionDashArray),fabric.util.drawDashedLine(t,h+o-1,c,h+o-1,c+a,this.selectionDashArray),t.closePath(),t.stroke()}else fabric.Object.prototype._setLineDash.call(this,t,this.selectionDashArray),t.strokeRect(e.ex+.5-(i>0?0:o),e.ey+.5-(r>0?0:a),o,a)},findTarget:function(t,e){if(!this.skipTargetFind){var i,r,n=this.getPointer(t,!0),s=this._activeObject,o=this.getActiveObjects();if(this.targets=[],o.length>1&&!e&&s===this._searchPossibleTargets([s],n))return s;if(1===o.length&&s._findTargetCorner(n))return s;if(1===o.length&&s===this._searchPossibleTargets([s],n)){if(!this.preserveObjectStacking)return s;i=s,r=this.targets,this.targets=[]}var a=this._searchPossibleTargets(this._objects,n);return t[this.altSelectionKey]&&a&&i&&a!==i&&(a=i,this.targets=r),a}},_checkTarget:function(t,e){if(e&&e.visible&&e.evented&&this.containsPoint(null,e,t)){if(!this.perPixelTargetFind&&!e.perPixelTargetFind||e.isEditing)return!0;if(!this.isTargetTransparent(e,t.x,t.y))return!0}},_searchPossibleTargets:function(t,e){for(var i,r,n,s=t.length;s--;)if(this._checkTarget(e,t[s])){"group"===(i=t[s]).type&&i.subTargetCheck&&(r=this._normalizePointer(i,e),(n=this._searchPossibleTargets(i._objects,r))&&this.targets.push(n));break}return i},restorePointerVpt:function(t){return fabric.util.transformPoint(t,fabric.util.invertTransform(this.viewportTransform))},getPointer:function(e,i,r){r||(r=this.upperCanvasEl);var n,s=t(e),o=r.getBoundingClientRect(),a=o.width||0,h=o.height||0;return a&&h||("top"in o&&"bottom"in o&&(h=Math.abs(o.top-o.bottom)),"right"in o&&"left"in o&&(a=Math.abs(o.right-o.left))),this.calcOffset(),s.x=s.x-this._offset.left,s.y=s.y-this._offset.top,i||(s=this.restorePointerVpt(s)),n=0===a||0===h?{width:1,height:1}:{width:r.width/a,height:r.height/h},{x:s.x*n.width,y:s.y*n.height}},_createUpperCanvas:function(){var t=this.lowerCanvasEl.className.replace(/\s*lower-canvas\s*/,"");this.upperCanvasEl?this.upperCanvasEl.className="":this.upperCanvasEl=this._createCanvasElement(),fabric.util.addClass(this.upperCanvasEl,"upper-canvas "+t),this.wrapperEl.appendChild(this.upperCanvasEl),this._copyCanvasStyle(this.lowerCanvasEl,this.upperCanvasEl),this._applyCanvasStyle(this.upperCanvasEl),this.contextTop=this.upperCanvasEl.getContext("2d")},_createCacheCanvas:function(){this.cacheCanvasEl=this._createCanvasElement(),this.cacheCanvasEl.setAttribute("width",this.width),this.cacheCanvasEl.setAttribute("height",this.height),this.contextCache=this.cacheCanvasEl.getContext("2d")},_initWrapperElement:function(){this.wrapperEl=fabric.util.wrapElement(this.lowerCanvasEl,"div",{class:this.containerClass}),fabric.util.setStyle(this.wrapperEl,{width:this.width+"px",height:this.height+"px",position:"relative"}),fabric.util.makeElementUnselectable(this.wrapperEl)},_applyCanvasStyle:function(t){var e=this.width||t.width,i=this.height||t.height;fabric.util.setStyle(t,{position:"absolute",width:e+"px",height:i+"px",left:0,top:0,"touch-action":"none"}),t.width=e,t.height=i,fabric.util.makeElementUnselectable(t)},_copyCanvasStyle:function(t,e){e.style.cssText=t.style.cssText},getSelectionContext:function(){return this.contextTop},getSelectionElement:function(){return this.upperCanvasEl},getActiveObject:function(){return this._activeObject},getActiveObjects:function(){var t=this._activeObject;return t?"activeSelection"===t.type&&t._objects?t._objects.slice(0):[t]:[]},_onObjectRemoved:function(t){t===this._activeObject&&(this.fire("before:selection:cleared",{target:t}),this._discardActiveObject(),this.fire("selection:cleared",{target:t}),t.fire("deselected")),this._hoveredTarget===t&&(this._hoveredTarget=null),this.callSuper("_onObjectRemoved",t)},_fireSelectionEvents:function(t,e){var i=!1,r=this.getActiveObjects(),n=[],s=[],o={e:e};t.forEach(function(t){-1===r.indexOf(t)&&(i=!0,t.fire("deselected",o),s.push(t))}),r.forEach(function(e){-1===t.indexOf(e)&&(i=!0,e.fire("selected",o),n.push(e))}),t.length>0&&r.length>0?(o.selected=n,o.deselected=s,o.updated=n[0]||s[0],o.target=this._activeObject,i&&this.fire("selection:updated",o)):r.length>0?(1===r.length&&(o.target=n[0],this.fire("object:selected",o)),o.selected=n,o.target=this._activeObject,this.fire("selection:created",o)):t.length>0&&(o.deselected=s,this.fire("selection:cleared",o))},setActiveObject:function(t,e){var i=this.getActiveObjects();return this._setActiveObject(t,e),this._fireSelectionEvents(i,e),this},_setActiveObject:function(t,e){return this._activeObject!==t&&(!!this._discardActiveObject(e,t)&&(!t.onSelect({e:e})&&(this._activeObject=t,!0)))},_discardActiveObject:function(t,e){var i=this._activeObject;if(i){if(i.onDeselect({e:t,object:e}))return!1;this._activeObject=null}return!0},discardActiveObject:function(t){var e=this.getActiveObjects();return e.length&&this.fire("before:selection:cleared",{target:e[0],e:t}),this._discardActiveObject(t),this._fireSelectionEvents(e,t),this},dispose:function(){var t=this.wrapperEl;return this.removeListeners(),t.removeChild(this.upperCanvasEl),t.removeChild(this.lowerCanvasEl),delete this.upperCanvasEl,t.parentNode&&t.parentNode.replaceChild(this.lowerCanvasEl,this.wrapperEl),delete this.wrapperEl,fabric.StaticCanvas.prototype.dispose.call(this),this},clear:function(){return this.discardActiveObject(),this.clearContext(this.contextTop),this.callSuper("clear")},drawControls:function(t){var e=this._activeObject;e&&e._renderControls(t)},_toObject:function(t,e,i){var r=this._realizeGroupTransformOnObject(t),n=this.callSuper("_toObject",t,e,i);return this._unwindGroupTransformOnObject(t,r),n},_realizeGroupTransformOnObject:function(t){if(t.group&&"activeSelection"===t.group.type&&this._activeObject===t.group){var e={};return["angle","flipX","flipY","left","scaleX","scaleY","skewX","skewY","top"].forEach(function(i){e[i]=t[i]}),this._activeObject.realizeTransform(t),e}return null},_unwindGroupTransformOnObject:function(t,e){e&&t.set(e)},_setSVGObject:function(t,e,i){var r=this._realizeGroupTransformOnObject(e);this.callSuper("_setSVGObject",t,e,i),this._unwindGroupTransformOnObject(e,r)}});for(var o in fabric.StaticCanvas)"prototype"!==o&&(fabric.Canvas[o]=fabric.StaticCanvas[o]);fabric.isTouchSupported&&(fabric.Canvas.prototype._setCursorFromEvent=function(){})}(),function(){function t(t,e){return"which"in t?t.which===e:t.button===e-1}var e={mt:0,tr:1,mr:2,br:3,mb:4,bl:5,ml:6,tl:7},i=fabric.util.addListener,r=fabric.util.removeListener;fabric.util.object.extend(fabric.Canvas.prototype,{cursorMap:["n-resize","ne-resize","e-resize","se-resize","s-resize","sw-resize","w-resize","nw-resize"],_initEventListeners:function(){this.removeListeners(),this._bindEvents(),i(fabric.window,"resize",this._onResize),i(this.upperCanvasEl,"mousedown",this._onMouseDown),i(this.upperCanvasEl,"dblclick",this._onDoubleClick),i(this.upperCanvasEl,"mousemove",this._onMouseMove),i(this.upperCanvasEl,"mouseout",this._onMouseOut),i(this.upperCanvasEl,"mouseenter",this._onMouseEnter),i(this.upperCanvasEl,"wheel",this._onMouseWheel),i(this.upperCanvasEl,"contextmenu",this._onContextMenu),i(this.upperCanvasEl,"touchstart",this._onMouseDown,{passive:!1}),i(this.upperCanvasEl,"touchmove",this._onMouseMove,{passive:!1}),"undefined"!=typeof eventjs&&"add"in eventjs&&(eventjs.add(this.upperCanvasEl,"gesture",this._onGesture),eventjs.add(this.upperCanvasEl,"drag",this._onDrag),eventjs.add(this.upperCanvasEl,"orientation",this._onOrientationChange),eventjs.add(this.upperCanvasEl,"shake",this._onShake),eventjs.add(this.upperCanvasEl,"longpress",this._onLongPress))},_bindEvents:function(){this.eventsBinded||(this._onMouseDown=this._onMouseDown.bind(this),this._onMouseMove=this._onMouseMove.bind(this),this._onMouseUp=this._onMouseUp.bind(this),this._onResize=this._onResize.bind(this),this._onGesture=this._onGesture.bind(this),this._onDrag=this._onDrag.bind(this),this._onShake=this._onShake.bind(this),this._onLongPress=this._onLongPress.bind(this),this._onOrientationChange=this._onOrientationChange.bind(this),this._onMouseWheel=this._onMouseWheel.bind(this),this._onMouseOut=this._onMouseOut.bind(this),this._onMouseEnter=this._onMouseEnter.bind(this),this._onContextMenu=this._onContextMenu.bind(this),this._onDoubleClick=this._onDoubleClick.bind(this),this.eventsBinded=!0)},removeListeners:function(){r(fabric.window,"resize",this._onResize),r(this.upperCanvasEl,"mousedown",this._onMouseDown),r(this.upperCanvasEl,"mousemove",this._onMouseMove),r(this.upperCanvasEl,"mouseout",this._onMouseOut),r(this.upperCanvasEl,"mouseenter",this._onMouseEnter),r(this.upperCanvasEl,"wheel",this._onMouseWheel),r(this.upperCanvasEl,"contextmenu",this._onContextMenu),r(this.upperCanvasEl,"doubleclick",this._onDoubleClick),r(this.upperCanvasEl,"touchstart",this._onMouseDown),r(this.upperCanvasEl,"touchmove",this._onMouseMove),"undefined"!=typeof eventjs&&"remove"in eventjs&&(eventjs.remove(this.upperCanvasEl,"gesture",this._onGesture),eventjs.remove(this.upperCanvasEl,"drag",this._onDrag),eventjs.remove(this.upperCanvasEl,"orientation",this._onOrientationChange),eventjs.remove(this.upperCanvasEl,"shake",this._onShake),eventjs.remove(this.upperCanvasEl,"longpress",this._onLongPress))},_onGesture:function(t,e){this.__onTransformGesture&&this.__onTransformGesture(t,e)},_onDrag:function(t,e){this.__onDrag&&this.__onDrag(t,e)},_onMouseWheel:function(t){this.__onMouseWheel(t)},_onMouseOut:function(t){var e=this._hoveredTarget;this.fire("mouse:out",{target:e,e:t}),this._hoveredTarget=null,e&&e.fire("mouseout",{e:t}),this._iTextInstances&&this._iTextInstances.forEach(function(t){t.isEditing&&t.hiddenTextarea.focus()})},_onMouseEnter:function(t){this.findTarget(t)||(this.fire("mouse:over",{target:null,e:t}),this._hoveredTarget=null)},_onOrientationChange:function(t,e){this.__onOrientationChange&&this.__onOrientationChange(t,e)},_onShake:function(t,e){this.__onShake&&this.__onShake(t,e)},_onLongPress:function(t,e){this.__onLongPress&&this.__onLongPress(t,e)},_onContextMenu:function(t){return this.stopContextMenu&&(t.stopPropagation(),t.preventDefault()),!1},_onDoubleClick:function(t){this._handleEvent(t,"dblclick",void 0)},_onMouseDown:function(t){this.__onMouseDown(t),i(fabric.document,"touchend",this._onMouseUp,{passive:!1}),i(fabric.document,"touchmove",this._onMouseMove,{passive:!1}),r(this.upperCanvasEl,"mousemove",this._onMouseMove),r(this.upperCanvasEl,"touchmove",this._onMouseMove),"touchstart"===t.type?r(this.upperCanvasEl,"mousedown",this._onMouseDown):(i(fabric.document,"mouseup",this._onMouseUp),i(fabric.document,"mousemove",this._onMouseMove))},_onMouseUp:function(t){if(this.__onMouseUp(t),r(fabric.document,"mouseup",this._onMouseUp),r(fabric.document,"touchend",this._onMouseUp),r(fabric.document,"mousemove",this._onMouseMove),r(fabric.document,"touchmove",this._onMouseMove),i(this.upperCanvasEl,"mousemove",this._onMouseMove),i(this.upperCanvasEl,"touchmove",this._onMouseMove,{passive:!1}),"touchend"===t.type){var e=this;setTimeout(function(){i(e.upperCanvasEl,"mousedown",e._onMouseDown)},400)}},_onMouseMove:function(t){!this.allowTouchScrolling&&t.preventDefault&&t.preventDefault(),this.__onMouseMove(t)},_onResize:function(){this.calcOffset()},_shouldRender:function(t,e){var i=this._activeObject;return(!i||!i.isEditing||t!==i)&&!!(t&&(t.isMoving||t!==i)||!t&&i||!t&&!i&&!this._groupSelector||e&&this._previousPointer&&this.selection&&(e.x!==this._previousPointer.x||e.y!==this._previousPointer.y))},__onMouseUp:function(e){var i,r=!0,n=this._currentTransform,s=this._groupSelector,o=!s||0===s.left&&0===s.top;if(t(e,3))this.fireRightClick&&this._handleEvent(e,"up",i,3,o);else if(t(e,2))this.fireMiddleClick&&this._handleEvent(e,"up",i,2,o);else if(this.isDrawingMode&&this._isCurrentlyDrawing)this._onMouseUpInDrawingMode(e);else{n&&(this._finalizeCurrentTransform(e),r=!n.actionPerformed),i=r?this.findTarget(e,!0):n.target;var a=this._shouldRender(i,this.getPointer(e));i||!o?this._maybeGroupObjects(e):(this._groupSelector=null,this._currentTransform=null),i&&(i.isMoving=!1),this._setCursorFromEvent(e,i),this._handleEvent(e,"up",i||null,1,o),i&&(i.__corner=0),a&&this.requestRenderAll()}},_handleEvent:function(t,e,i,r,n){var s=void 0===i?this.findTarget(t):i,o=this.targets||[],a={e:t,target:s,subTargets:o,button:r||1,isClick:n||!1};this.fire("mouse:"+e,a),s&&s.fire("mouse"+e,a);for(var h=0;h1)){var r=this._groupSelector;r?(i=this.getPointer(t,!0),r.left=i.x-r.ex,r.top=i.y-r.ey,this.renderTop()):this._currentTransform?this._transformObject(t):(e=this.findTarget(t),this._setCursorFromEvent(t,e),this._fireOverOutEvents(e,t)),this._handleEvent(t,"move",this._currentTransform?null:e)}},_fireOverOutEvents:function(t,e){var i,r,n=this._hoveredTarget;n!==t&&(i={e:e,target:t,previousTarget:this._hoveredTarget},r={e:e,target:this._hoveredTarget,nextTarget:t},this._hoveredTarget=t),t?n!==t&&(n&&(this.fire("mouse:out",r),n.fire("mouseout",r)),this.fire("mouse:over",i),t.fire("mouseover",i)):n&&(this.fire("mouse:out",r),n.fire("mouseout",r))},__onMouseWheel:function(t){this._handleEvent(t,"wheel")},_transformObject:function(t){var e=this.getPointer(t),i=this._currentTransform;i.reset=!1,i.target.isMoving=!0,i.shiftKey=t.shiftKey,i.altKey=t[this.centeredKey],this._beforeScaleTransform(t,i),this._performTransformAction(t,i,e),i.actionPerformed&&this.requestRenderAll()},_performTransformAction:function(t,e,i){var r=i.x,n=i.y,s=e.target,o=e.action,a=!1;"rotate"===o?(a=this._rotateObject(r,n))&&this._fire("rotating",s,t):"scale"===o?(a=this._onScale(t,e,r,n))&&this._fire("scaling",s,t):"scaleX"===o?(a=this._scaleObject(r,n,"x"))&&this._fire("scaling",s,t):"scaleY"===o?(a=this._scaleObject(r,n,"y"))&&this._fire("scaling",s,t):"skewX"===o?(a=this._skewObject(r,n,"x"))&&this._fire("skewing",s,t):"skewY"===o?(a=this._skewObject(r,n,"y"))&&this._fire("skewing",s,t):(a=this._translateObject(r,n))&&(this._fire("moving",s,t),this.setCursor(s.moveCursor||this.moveCursor)),e.actionPerformed=e.actionPerformed||a},_fire:function(t,e,i){this.fire("object:"+t,{target:e,e:i}),e.fire(t,{e:i})},_beforeScaleTransform:function(t,e){if("scale"===e.action||"scaleX"===e.action||"scaleY"===e.action){var i=this._shouldCenterTransform(e.target);(i&&("center"!==e.originX||"center"!==e.originY)||!i&&"center"===e.originX&&"center"===e.originY)&&(this._resetCurrentTransform(),e.reset=!0)}},_onScale:function(t,e,i,r){return this._isUniscalePossible(t,e.target)?(e.currentAction="scale",this._scaleObject(i,r)):(e.reset||"scale"!==e.currentAction||this._resetCurrentTransform(),e.currentAction="scaleEqually",this._scaleObject(i,r,"equally"))},_isUniscalePossible:function(t,e){return(t[this.uniScaleKey]||this.uniScaleTransform)&&!e.get("lockUniScaling")},_setCursorFromEvent:function(t,e){if(!e)return this.setCursor(this.defaultCursor),!1;var i=e.hoverCursor||this.hoverCursor,r=this._activeObject&&"activeSelection"===this._activeObject.type?this._activeObject:null,n=(!r||!r.contains(e))&&e._findTargetCorner(this.getPointer(t,!0));n?this.setCursor(this.getCornerCursor(n,e,t)):this.setCursor(i)},getCornerCursor:function(t,i,r){return this.actionIsDisabled(t,i,r)?this.notAllowedCursor:t in e?this._getRotatedCornerCursor(t,i,r):"mtr"===t&&i.hasRotatingPoint?this.rotationCursor:this.defaultCursor},actionIsDisabled:function(t,e,i){return"mt"===t||"mb"===t?i[this.altActionKey]?e.lockSkewingX:e.lockScalingY:"ml"===t||"mr"===t?i[this.altActionKey]?e.lockSkewingY:e.lockScalingX:"mtr"===t?e.lockRotation:this._isUniscalePossible(i,e)?e.lockScalingX&&e.lockScalingY:e.lockScalingX||e.lockScalingY},_getRotatedCornerCursor:function(t,i,r){var n=Math.round(i.angle%360/45);return n<0&&(n+=8),n+=e[t],r[this.altActionKey]&&e[t]%2==0&&(n+=2),n%=8,this.cursorMap[n]}})}(),function(){var t=Math.min,e=Math.max;fabric.util.object.extend(fabric.Canvas.prototype,{_shouldGroup:function(t,e){var i=this._activeObject;return i&&this._isSelectionKeyPressed(t)&&e&&e.selectable&&this.selection&&(i!==e||"activeSelection"===i.type)},_handleGrouping:function(t,e){var i=this._activeObject;i.__corner||(e!==i||(e=this.findTarget(t,!0)))&&(i&&"activeSelection"===i.type?this._updateActiveSelection(e,t):this._createActiveSelection(e,t))},_updateActiveSelection:function(t,e){var i=this._activeObject,r=i._objects.slice(0);i.contains(t)?(i.removeWithUpdate(t),this._hoveredTarget=t,1===i.size()&&this._setActiveObject(i.item(0),e)):(i.addWithUpdate(t),this._hoveredTarget=i),this._fireSelectionEvents(r,e)},_createActiveSelection:function(t,e){var i=this.getActiveObjects(),r=this._createGroup(t);this._hoveredTarget=r,this._setActiveObject(r,e),this._fireSelectionEvents(i,e)},_createGroup:function(t){var e=this.getObjects(),i=e.indexOf(this._activeObject)1&&(e=new fabric.ActiveSelection(i.reverse(),{canvas:this}),this.setActiveObject(e,t))},_collectObjects:function(){for(var i,r=[],n=this._groupSelector.ex,s=this._groupSelector.ey,o=n+this._groupSelector.left,a=s+this._groupSelector.top,h=new fabric.Point(t(n,o),t(s,a)),c=new fabric.Point(e(n,o),e(s,a)),l=n===o&&s===a,u=this._objects.length;u--&&!((i=this._objects[u])&&i.selectable&&i.visible&&(i.intersectsWithRect(h,c)||i.isContainedWithinRect(h,c)||i.containsPoint(h)||i.containsPoint(c))&&(r.push(i),l)););return r},_maybeGroupObjects:function(t){this.selection&&this._groupSelector&&this._groupSelectedObjects(t),this.setCursor(this.defaultCursor),this._groupSelector=null,this._currentTransform=null}})}(),function(){var t=fabric.StaticCanvas.supports("toDataURLWithQuality");fabric.util.object.extend(fabric.StaticCanvas.prototype,{toDataURL:function(t){t||(t={});var e=t.format||"png",i=t.quality||1,r=t.multiplier||1,n={left:t.left||0,top:t.top||0,width:t.width||0,height:t.height||0};return this.__toDataURLWithMultiplier(e,i,n,r)},__toDataURLWithMultiplier:function(t,e,i,r){var n=this.width,s=this.height,o=(i.width||this.width)*r,a=(i.height||this.height)*r,h=this.getZoom()*r,c=this.viewportTransform,l=[h,0,0,h,(c[4]-i.left)*r,(c[5]-i.top)*r],u=this.interactive,f=this.skipOffscreen,d=n!==o||s!==a;this.viewportTransform=l,this.skipOffscreen=!1,this.interactive=!1,d&&this.setDimensions({width:o,height:a},{backstoreOnly:!0}),this.renderAll();var g=this.__toDataURL(t,e,i);return this.interactive=u,this.skipOffscreen=f,this.viewportTransform=c,d&&this.setDimensions({width:n,height:s},{backstoreOnly:!0}),this.renderAll(),g},__toDataURL:function(e,i){var r=this.contextContainer.canvas;return"jpg"===e&&(e="jpeg"),t?r.toDataURL("image/"+e,i):r.toDataURL("image/"+e)}})}(),fabric.util.object.extend(fabric.StaticCanvas.prototype,{loadFromDatalessJSON:function(t,e,i){return this.loadFromJSON(t,e,i)},loadFromJSON:function(t,e,i){if(t){var r="string"==typeof t?JSON.parse(t):fabric.util.object.clone(t),n=this,s=this.renderOnAddRemove;return this.renderOnAddRemove=!1,this._enlivenObjects(r.objects,function(t){n.clear(),n._setBgOverlay(r,function(){t.forEach(function(t,e){n.insertAt(t,e)}),n.renderOnAddRemove=s,delete r.objects,delete r.backgroundImage,delete r.overlayImage,delete r.background,delete r.overlay,n._setOptions(r),n.renderAll(),e&&e()})},i),this}},_setBgOverlay:function(t,e){var i={backgroundColor:!1,overlayColor:!1,backgroundImage:!1,overlayImage:!1};if(t.backgroundImage||t.overlayImage||t.background||t.overlay){var r=function(){i.backgroundImage&&i.overlayImage&&i.backgroundColor&&i.overlayColor&&e&&e()};this.__setBgOverlay("backgroundImage",t.backgroundImage,i,r),this.__setBgOverlay("overlayImage",t.overlayImage,i,r),this.__setBgOverlay("backgroundColor",t.background,i,r),this.__setBgOverlay("overlayColor",t.overlay,i,r)}else e&&e()},__setBgOverlay:function(t,e,i,r){var n=this;if(!e)return i[t]=!0,void(r&&r());"backgroundImage"===t||"overlayImage"===t?fabric.util.enlivenObjects([e],function(e){n[t]=e[0],i[t]=!0,r&&r()}):this["set"+fabric.util.string.capitalize(t,!0)](e,function(){i[t]=!0,r&&r()})},_enlivenObjects:function(t,e,i){t&&0!==t.length?fabric.util.enlivenObjects(t,function(t){e&&e(t)},null,i):e&&e([])},_toDataURL:function(t,e){this.clone(function(i){e(i.toDataURL(t))})},_toDataURLWithMultiplier:function(t,e,i){this.clone(function(r){i(r.toDataURLWithMultiplier(t,e))})},clone:function(t,e){var i=JSON.stringify(this.toJSON(e));this.cloneWithoutData(function(e){e.loadFromJSON(i,function(){t&&t(e)})})},cloneWithoutData:function(t){var e=fabric.document.createElement("canvas");e.width=this.width,e.height=this.height;var i=new fabric.Canvas(e);i.clipTo=this.clipTo,this.backgroundImage?(i.setBackgroundImage(this.backgroundImage.src,function(){i.renderAll(),t&&t(i)}),i.backgroundImageOpacity=this.backgroundImageOpacity,i.backgroundImageStretch=this.backgroundImageStretch):t&&t(i)}}),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=e.util.object.extend,r=e.util.object.clone,n=e.util.toFixed,s=e.util.string.capitalize,o=e.util.degreesToRadians,a=e.StaticCanvas.supports("setLineDash"),h=!e.isLikelyNode;e.Object||(e.Object=e.util.createClass(e.CommonMethods,{type:"object",originX:"left",originY:"top",top:0,left:0,width:0,height:0,scaleX:1,scaleY:1,flipX:!1,flipY:!1,opacity:1,angle:0,skewX:0,skewY:0,cornerSize:13,transparentCorners:!0,hoverCursor:null,moveCursor:null,padding:0,borderColor:"rgba(102,153,255,0.75)",borderDashArray:null,cornerColor:"rgba(102,153,255,0.5)",cornerStrokeColor:null,cornerStyle:"rect",cornerDashArray:null,centeredScaling:!1,centeredRotation:!0,fill:"rgb(0,0,0)",fillRule:"nonzero",globalCompositeOperation:"source-over",backgroundColor:"",selectionBackgroundColor:"",stroke:null,strokeWidth:1,strokeDashArray:null,strokeLineCap:"butt",strokeLineJoin:"miter",strokeMiterLimit:10,shadow:null,borderOpacityWhenMoving:.4,borderScaleFactor:1,transformMatrix:null,minScaleLimit:0,selectable:!0,evented:!0,visible:!0,hasControls:!0,hasBorders:!0,hasRotatingPoint:!0,rotatingPointOffset:40,perPixelTargetFind:!1,includeDefaultValues:!0,clipTo:null,lockMovementX:!1,lockMovementY:!1,lockRotation:!1,lockScalingX:!1,lockScalingY:!1,lockUniScaling:!1,lockSkewingX:!1,lockSkewingY:!1,lockScalingFlip:!1,excludeFromExport:!1,objectCaching:h,statefullCache:!1,noScaleCache:!0,dirty:!0,__corner:0,paintFirst:"fill",stateProperties:"top left width height scaleX scaleY flipX flipY originX originY transformMatrix stroke strokeWidth strokeDashArray strokeLineCap strokeLineJoin strokeMiterLimit angle opacity fill globalCompositeOperation shadow clipTo visible backgroundColor skewX skewY fillRule paintFirst".split(" "),cacheProperties:"fill stroke strokeWidth strokeDashArray width height paintFirst strokeLineCap strokeLineJoin strokeMiterLimit backgroundColor".split(" "),initialize:function(t){t&&this.setOptions(t)},_createCacheCanvas:function(){this._cacheProperties={},this._cacheCanvas=e.document.createElement("canvas"),this._cacheContext=this._cacheCanvas.getContext("2d"),this._updateCacheCanvas()},_limitCacheSize:function(t){var i=e.perfLimitSizeTotal,r=t.width,n=t.height,s=e.maxCacheSideLimit,o=e.minCacheSideLimit;if(r<=s&&n<=s&&r*n<=i)return rl&&(t.zoomX/=r/l,t.width=l,t.capped=!0),n>u&&(t.zoomY/=n/u,t.height=u,t.capped=!0),t},_getCacheCanvasDimensions:function(){var t=this.canvas&&this.canvas.getZoom()||1,i=this.getObjectScaling(),r=this.canvas&&this.canvas._isRetinaScaling()?e.devicePixelRatio:1,n=this._getNonTransformedDimensions(),s=i.scaleX*t*r,o=i.scaleY*t*r;return{width:n.x*s+2,height:n.y*o+2,zoomX:s,zoomY:o,x:n.x,y:n.y}},_updateCacheCanvas:function(){if(this.noScaleCache&&this.canvas&&this.canvas._currentTransform){var t=this.canvas._currentTransform.target,i=this.canvas._currentTransform.action;if(this===t&&i.slice&&"scale"===i.slice(0,5))return!1}var r,n,s=this._cacheCanvas,o=this._limitCacheSize(this._getCacheCanvasDimensions()),a=e.minCacheSideLimit,h=o.width,c=o.height,l=o.zoomX,u=o.zoomY,f=h!==this.cacheWidth||c!==this.cacheHeight,d=this.zoomX!==l||this.zoomY!==u,g=f||d,p=0,v=0,m=!1;if(f){var b=this._cacheCanvas.width,_=this._cacheCanvas.height,y=h>b||c>_,x=(h<.9*b||c<.9*_)&&b>a&&_>a;m=y||x,y&&!o.capped&&(h>a||c>a)&&(p=.1*h,v=.1*c)}return!!g&&(m?(s.width=Math.ceil(h+p),s.height=Math.ceil(c+v)):(this._cacheContext.setTransform(1,0,0,1,0,0),this._cacheContext.clearRect(0,0,s.width,s.height)),r=o.x*l/2,n=o.y*u/2,this.cacheTranslationX=Math.round(s.width/2-r)+r,this.cacheTranslationY=Math.round(s.height/2-n)+n,this.cacheWidth=h,this.cacheHeight=c,this._cacheContext.translate(this.cacheTranslationX,this.cacheTranslationY),this._cacheContext.scale(l,u),this.zoomX=l,this.zoomY=u,!0)},setOptions:function(t){this._setOptions(t),this._initGradient(t.fill,"fill"),this._initGradient(t.stroke,"stroke"),this._initClipping(t),this._initPattern(t.fill,"fill"),this._initPattern(t.stroke,"stroke")},transform:function(t){var e;e=this.group&&!this.group._transformDone?this.calcTransformMatrix():this.calcOwnMatrix(),t.transform(e[0],e[1],e[2],e[3],e[4],e[5])},toObject:function(t){var i=e.Object.NUM_FRACTION_DIGITS,r={type:this.type,version:e.version,originX:this.originX,originY:this.originY,left:n(this.left,i),top:n(this.top,i),width:n(this.width,i),height:n(this.height,i),fill:this.fill&&this.fill.toObject?this.fill.toObject():this.fill,stroke:this.stroke&&this.stroke.toObject?this.stroke.toObject():this.stroke,strokeWidth:n(this.strokeWidth,i),strokeDashArray:this.strokeDashArray?this.strokeDashArray.concat():this.strokeDashArray,strokeLineCap:this.strokeLineCap,strokeLineJoin:this.strokeLineJoin,strokeMiterLimit:n(this.strokeMiterLimit,i),scaleX:n(this.scaleX,i),scaleY:n(this.scaleY,i),angle:n(this.angle,i),flipX:this.flipX,flipY:this.flipY,opacity:n(this.opacity,i),shadow:this.shadow&&this.shadow.toObject?this.shadow.toObject():this.shadow,visible:this.visible,clipTo:this.clipTo&&String(this.clipTo),backgroundColor:this.backgroundColor,fillRule:this.fillRule,paintFirst:this.paintFirst,globalCompositeOperation:this.globalCompositeOperation,transformMatrix:this.transformMatrix?this.transformMatrix.concat():null,skewX:n(this.skewX,i),skewY:n(this.skewY,i)};return e.util.populateWithProperties(this,r,t),this.includeDefaultValues||(r=this._removeDefaultValues(r)),r},toDatalessObject:function(t){return this.toObject(t)},_removeDefaultValues:function(t){var i=e.util.getKlass(t.type).prototype;return i.stateProperties.forEach(function(e){t[e]===i[e]&&delete t[e],"[object Array]"===Object.prototype.toString.call(t[e])&&"[object Array]"===Object.prototype.toString.call(i[e])&&0===t[e].length&&0===i[e].length&&delete t[e]}),t},toString:function(){return"#"},getObjectScaling:function(){var t=this.scaleX,e=this.scaleY;if(this.group){var i=this.group.getObjectScaling();t*=i.scaleX,e*=i.scaleY}return{scaleX:t,scaleY:e}},getObjectOpacity:function(){var t=this.opacity;return this.group&&(t*=this.group.getObjectOpacity()),t},_set:function(t,i){var r="scaleX"===t||"scaleY"===t,n=this[t]!==i,s=!1;return r&&(i=this._constrainScale(i)),"scaleX"===t&&i<0?(this.flipX=!this.flipX,i*=-1):"scaleY"===t&&i<0?(this.flipY=!this.flipY,i*=-1):"shadow"!==t||!i||i instanceof e.Shadow?"dirty"===t&&this.group&&this.group.set("dirty",i):i=new e.Shadow(i),this[t]=i,n&&(s=this.group&&this.group.isOnACache(),this.cacheProperties.indexOf(t)>-1?(this.dirty=!0,s&&this.group.set("dirty",!0)):s&&this.stateProperties.indexOf(t)>-1&&this.group.set("dirty",!0)),this},setOnGroup:function(){},getViewportTransform:function(){return this.canvas&&this.canvas.viewportTransform?this.canvas.viewportTransform:e.iMatrix.concat()},isNotVisible:function(){return 0===this.opacity||0===this.width&&0===this.height||!this.visible},render:function(t){this.isNotVisible()||this.canvas&&this.canvas.skipOffscreen&&!this.group&&!this.isOnScreen()||(t.save(),this._setupCompositeOperation(t),this.drawSelectionBackground(t),this.transform(t),this._setOpacity(t),this._setShadow(t,this),this.transformMatrix&&t.transform.apply(t,this.transformMatrix),this.clipTo&&e.util.clipContext(this,t),this.shouldCache()?(this._cacheCanvas||this._createCacheCanvas(),this.isCacheDirty()&&(this.statefullCache&&this.saveState({propertySet:"cacheProperties"}),this.drawObject(this._cacheContext),this.dirty=!1),this.drawCacheOnCanvas(t)):(this._removeCacheCanvas(),this.dirty=!1,this.drawObject(t),this.objectCaching&&this.statefullCache&&this.saveState({propertySet:"cacheProperties"})),this.clipTo&&t.restore(),t.restore())},_removeCacheCanvas:function(){this._cacheCanvas=null,this.cacheWidth=0,this.cacheHeight=0},needsItsOwnCache:function(){return"stroke"===this.paintFirst&&"object"==typeof this.shadow},shouldCache:function(){return this.ownCaching=this.objectCaching&&(!this.group||this.needsItsOwnCache()||!this.group.isOnACache()),this.ownCaching},willDrawShadow:function(){return!!this.shadow&&(0!==this.shadow.offsetX||0!==this.shadow.offsetY)},drawObject:function(t){this._renderBackground(t),this._setStrokeStyles(t,this),this._setFillStyles(t,this),this._render(t)},drawCacheOnCanvas:function(t){t.scale(1/this.zoomX,1/this.zoomY),t.drawImage(this._cacheCanvas,-this.cacheTranslationX,-this.cacheTranslationY)},isCacheDirty:function(t){if(this.isNotVisible())return!1;if(this._cacheCanvas&&!t&&this._updateCacheCanvas())return!0;if(this.dirty||this.statefullCache&&this.hasStateChanged("cacheProperties")){if(this._cacheCanvas&&!t){var e=this.cacheWidth/this.zoomX,i=this.cacheHeight/this.zoomY;this._cacheContext.clearRect(-e/2,-i/2,e,i)}return!0}return!1},_renderBackground:function(t){if(this.backgroundColor){var e=this._getNonTransformedDimensions();t.fillStyle=this.backgroundColor,t.fillRect(-e.x/2,-e.y/2,e.x,e.y),this._removeShadow(t)}},_setOpacity:function(t){this.group&&!this.group._transformDone?t.globalAlpha=this.getObjectOpacity():t.globalAlpha*=this.opacity},_setStrokeStyles:function(t,e){e.stroke&&(t.lineWidth=e.strokeWidth,t.lineCap=e.strokeLineCap,t.lineJoin=e.strokeLineJoin,t.miterLimit=e.strokeMiterLimit,t.strokeStyle=e.stroke.toLive?e.stroke.toLive(t,this):e.stroke)},_setFillStyles:function(t,e){e.fill&&(t.fillStyle=e.fill.toLive?e.fill.toLive(t,this):e.fill)},_setLineDash:function(t,e,i){e&&(1&e.length&&e.push.apply(e,e),a?t.setLineDash(e):i&&i(t))},_renderControls:function(t,i){var r,n,s,a=this.getViewportTransform(),h=this.calcTransformMatrix();n=void 0!==(i=i||{}).hasBorders?i.hasBorders:this.hasBorders,s=void 0!==i.hasControls?i.hasControls:this.hasControls,h=e.util.multiplyTransformMatrices(a,h),r=e.util.qrDecompose(h),t.save(),t.translate(r.translateX,r.translateY),t.lineWidth=1*this.borderScaleFactor,this.group||(t.globalAlpha=this.isMoving?this.borderOpacityWhenMoving:1),i.forActiveSelection?(t.rotate(o(r.angle)),n&&this.drawBordersInGroup(t,r,i)):(t.rotate(o(this.angle)),n&&this.drawBorders(t,i)),s&&this.drawControls(t,i),t.restore()},_setShadow:function(t){if(this.shadow){var i=this.canvas&&this.canvas.viewportTransform[0]||1,r=this.canvas&&this.canvas.viewportTransform[3]||1,n=this.getObjectScaling();this.canvas&&this.canvas._isRetinaScaling()&&(i*=e.devicePixelRatio,r*=e.devicePixelRatio),t.shadowColor=this.shadow.color,t.shadowBlur=this.shadow.blur*e.browserShadowBlurConstant*(i+r)*(n.scaleX+n.scaleY)/4,t.shadowOffsetX=this.shadow.offsetX*i*n.scaleX,t.shadowOffsetY=this.shadow.offsetY*r*n.scaleY}},_removeShadow:function(t){this.shadow&&(t.shadowColor="",t.shadowBlur=t.shadowOffsetX=t.shadowOffsetY=0)},_applyPatternGradientTransform:function(t,e){if(!e||!e.toLive)return{offsetX:0,offsetY:0};var i=e.gradientTransform||e.patternTransform,r=-this.width/2+e.offsetX||0,n=-this.height/2+e.offsetY||0;return t.translate(r,n),i&&t.transform(i[0],i[1],i[2],i[3],i[4],i[5]),{offsetX:r,offsetY:n}},_renderPaintInOrder:function(t){"stroke"===this.paintFirst?(this._renderStroke(t),this._renderFill(t)):(this._renderFill(t),this._renderStroke(t))},_renderFill:function(t){this.fill&&(t.save(),this._applyPatternGradientTransform(t,this.fill),"evenodd"===this.fillRule?t.fill("evenodd"):t.fill(),t.restore())},_renderStroke:function(t){this.stroke&&0!==this.strokeWidth&&(this.shadow&&!this.shadow.affectStroke&&this._removeShadow(t),t.save(),this._setLineDash(t,this.strokeDashArray,this._renderDashedStroke),this._applyPatternGradientTransform(t,this.stroke),t.stroke(),t.restore())},_findCenterFromElement:function(){return{x:this.left+this.width/2,y:this.top+this.height/2}},_assignTransformMatrixProps:function(){if(this.transformMatrix){var t=e.util.qrDecompose(this.transformMatrix);this.flipX=!1,this.flipY=!1,this.set("scaleX",t.scaleX),this.set("scaleY",t.scaleY),this.angle=t.angle,this.skewX=t.skewX,this.skewY=0}},_removeTransformMatrix:function(t){var i=this._findCenterFromElement();this.transformMatrix&&(this._assignTransformMatrixProps(),i=e.util.transformPoint(i,this.transformMatrix)),this.transformMatrix=null,t&&(this.scaleX*=t.scaleX,this.scaleY*=t.scaleY,this.cropX=t.cropX,this.cropY=t.cropY,i.x+=t.offsetLeft,i.y+=t.offsetTop,this.width=t.width,this.height=t.height),this.setPositionByOrigin(i,"center","center")},clone:function(t,i){var r=this.toObject(i);this.constructor.fromObject?this.constructor.fromObject(r,t):e.Object._fromObject("Object",r,t)},cloneAsImage:function(t,i){var r=this.toDataURL(i);return e.util.loadImage(r,function(i){t&&t(new e.Image(i))}),this},toDataURL:function(t){t||(t={});var i=e.util.createCanvasElement(),r=this.getBoundingRect();i.width=r.width,i.height=r.height,e.util.wrapElement(i,"div");var n=new e.StaticCanvas(i,{enableRetinaScaling:t.enableRetinaScaling});"jpg"===t.format&&(t.format="jpeg"),"jpeg"===t.format&&(n.backgroundColor="#fff");var s={left:this.left,top:this.top};this.setPositionByOrigin(new e.Point(n.width/2,n.height/2),"center","center");var o=this.canvas;n.add(this);var a=n.toDataURL(t);return this.set(s).setCoords(),this.canvas=o,n.dispose(),n=null,a},isType:function(t){return this.type===t},complexity:function(){return 1},toJSON:function(t){return this.toObject(t)},setGradient:function(t,i){i||(i={});var r={colorStops:[]};return r.type=i.type||(i.r1||i.r2?"radial":"linear"),r.coords={x1:i.x1,y1:i.y1,x2:i.x2,y2:i.y2},(i.r1||i.r2)&&(r.coords.r1=i.r1,r.coords.r2=i.r2),r.gradientTransform=i.gradientTransform,e.Gradient.prototype.addColorStop.call(r,i.colorStops),this.set(t,e.Gradient.forObject(this,r))},setPatternFill:function(t){return this.set("fill",new e.Pattern(t))},setShadow:function(t){return this.set("shadow",t?new e.Shadow(t):null)},setColor:function(t){return this.set("fill",t),this},rotate:function(t){var e=("center"!==this.originX||"center"!==this.originY)&&this.centeredRotation;return e&&this._setOriginToCenter(),this.set("angle",t),e&&this._resetOrigin(),this},centerH:function(){return this.canvas&&this.canvas.centerObjectH(this),this},viewportCenterH:function(){return this.canvas&&this.canvas.viewportCenterObjectH(this),this},centerV:function(){return this.canvas&&this.canvas.centerObjectV(this),this},viewportCenterV:function(){return this.canvas&&this.canvas.viewportCenterObjectV(this),this},center:function(){return this.canvas&&this.canvas.centerObject(this),this},viewportCenter:function(){return this.canvas&&this.canvas.viewportCenterObject(this),this},getLocalPointer:function(t,i){i=i||this.canvas.getPointer(t);var r=new e.Point(i.x,i.y),n=this._getLeftTopCoords();return this.angle&&(r=e.util.rotatePoint(r,n,o(-this.angle))),{x:r.x-n.x,y:r.y-n.y}},_setupCompositeOperation:function(t){this.globalCompositeOperation&&(t.globalCompositeOperation=this.globalCompositeOperation)}}),e.util.createAccessors&&e.util.createAccessors(e.Object),i(e.Object.prototype,e.Observable),e.Object.NUM_FRACTION_DIGITS=2,e.Object._fromObject=function(t,i,n,s){var o=e[t];i=r(i,!0),e.util.enlivenPatterns([i.fill,i.stroke],function(t){void 0!==t[0]&&(i.fill=t[0]),void 0!==t[1]&&(i.stroke=t[1]);var e=s?new o(i[s],i):new o(i);n&&n(e)})},e.Object.__uid=0)}("undefined"!=typeof exports?exports:this),function(){var t=fabric.util.degreesToRadians,e={left:-.5,center:0,right:.5},i={top:-.5,center:0,bottom:.5};fabric.util.object.extend(fabric.Object.prototype,{translateToGivenOrigin:function(t,r,n,s,o){var a,h,c,l=t.x,u=t.y;return"string"==typeof r?r=e[r]:r-=.5,"string"==typeof s?s=e[s]:s-=.5,a=s-r,"string"==typeof n?n=i[n]:n-=.5,"string"==typeof o?o=i[o]:o-=.5,h=o-n,(a||h)&&(c=this._getTransformedDimensions(),l=t.x+a*c.x,u=t.y+h*c.y),new fabric.Point(l,u)},translateToCenterPoint:function(e,i,r){var n=this.translateToGivenOrigin(e,i,r,"center","center");return this.angle?fabric.util.rotatePoint(n,e,t(this.angle)):n},translateToOriginPoint:function(e,i,r){var n=this.translateToGivenOrigin(e,"center","center",i,r);return this.angle?fabric.util.rotatePoint(n,e,t(this.angle)):n},getCenterPoint:function(){var t=new fabric.Point(this.left,this.top);return this.translateToCenterPoint(t,this.originX,this.originY)},getPointByOrigin:function(t,e){var i=this.getCenterPoint();return this.translateToOriginPoint(i,t,e)},toLocalPoint:function(e,i,r){var n,s,o=this.getCenterPoint();return n=void 0!==i&&void 0!==r?this.translateToGivenOrigin(o,"center","center",i,r):new fabric.Point(this.left,this.top),s=new fabric.Point(e.x,e.y),this.angle&&(s=fabric.util.rotatePoint(s,o,-t(this.angle))),s.subtractEquals(n)},setPositionByOrigin:function(t,e,i){var r=this.translateToCenterPoint(t,e,i),n=this.translateToOriginPoint(r,this.originX,this.originY);this.set("left",n.x),this.set("top",n.y)},adjustPosition:function(i){var r,n,s=t(this.angle),o=this.getScaledWidth(),a=Math.cos(s)*o,h=Math.sin(s)*o;r="string"==typeof this.originX?e[this.originX]:this.originX-.5,n="string"==typeof i?e[i]:i-.5,this.left+=a*(n-r),this.top+=h*(n-r),this.setCoords(),this.originX=i},_setOriginToCenter:function(){this._originalOriginX=this.originX,this._originalOriginY=this.originY;var t=this.getCenterPoint();this.originX="center",this.originY="center",this.left=t.x,this.top=t.y},_resetOrigin:function(){var t=this.translateToOriginPoint(this.getCenterPoint(),this._originalOriginX,this._originalOriginY);this.originX=this._originalOriginX,this.originY=this._originalOriginY,this.left=t.x,this.top=t.y,this._originalOriginX=null,this._originalOriginY=null},_getLeftTopCoords:function(){return this.translateToOriginPoint(this.getCenterPoint(),"left","top")},onDeselect:function(){}})}(),function(){function t(t){return[new fabric.Point(t.tl.x,t.tl.y),new fabric.Point(t.tr.x,t.tr.y),new fabric.Point(t.br.x,t.br.y),new fabric.Point(t.bl.x,t.bl.y)]}var e=fabric.util.degreesToRadians,i=fabric.util.multiplyTransformMatrices;fabric.util.object.extend(fabric.Object.prototype,{oCoords:null,aCoords:null,ownMatrixCache:null,matrixCache:null,getCoords:function(e,i){this.oCoords||this.setCoords();var r=e?this.aCoords:this.oCoords;return t(i?this.calcCoords(e):r)},intersectsWithRect:function(t,e,i,r){var n=this.getCoords(i,r);return"Intersection"===fabric.Intersection.intersectPolygonRectangle(n,t,e).status},intersectsWithObject:function(t,e,i){return"Intersection"===fabric.Intersection.intersectPolygonPolygon(this.getCoords(e,i),t.getCoords(e,i)).status||t.isContainedWithinObject(this,e,i)||this.isContainedWithinObject(t,e,i)},isContainedWithinObject:function(t,e,i){for(var r=this.getCoords(e,i),n=0,s=t._getImageLines(i?t.calcCoords(e):e?t.aCoords:t.oCoords);n<4;n++)if(!t.containsPoint(r[n],s))return!1;return!0},isContainedWithinRect:function(t,e,i,r){var n=this.getBoundingRect(i,r);return n.left>=t.x&&n.left+n.width<=e.x&&n.top>=t.y&&n.top+n.height<=e.y},containsPoint:function(t,e,i,r){var e=e||this._getImageLines(r?this.calcCoords(i):i?this.aCoords:this.oCoords),n=this._findCrossPoints(t,e);return 0!==n&&n%2==1},isOnScreen:function(t){if(!this.canvas)return!1;for(var e,i=this.canvas.vptCoords.tl,r=this.canvas.vptCoords.br,n=this.getCoords(!0,t),s=0;s<4;s++)if((e=n[s]).x<=r.x&&e.x>=i.x&&e.y<=r.y&&e.y>=i.y)return!0;if(this.intersectsWithRect(i,r,!0))return!0;var o={x:(i.x+r.x)/2,y:(i.y+r.y)/2};return!!this.containsPoint(o,null,!0)},_getImageLines:function(t){return{topline:{o:t.tl,d:t.tr},rightline:{o:t.tr,d:t.br},bottomline:{o:t.br,d:t.bl},leftline:{o:t.bl,d:t.tl}}},_findCrossPoints:function(t,e){var i,r,n,s,o=0;for(var a in e)if(!((s=e[a]).o.y=t.y&&s.d.y>=t.y||(s.o.x===s.d.x&&s.o.x>=t.x?n=s.o.x:(i=0,r=(s.d.y-s.o.y)/(s.d.x-s.o.x),n=-(t.y-i*t.x-(s.o.y-r*s.o.x))/(i-r)),n>=t.x&&(o+=1),2!==o)))break;return o},getBoundingRect:function(t,e){var i=this.getCoords(t,e);return fabric.util.makeBoundingBoxFromPoints(i)},getScaledWidth:function(){return this._getTransformedDimensions().x},getScaledHeight:function(){return this._getTransformedDimensions().y},_constrainScale:function(t){return Math.abs(t)0?Math.atan(o/s):0,l=s/Math.cos(c)/2,u=Math.cos(c+i)*l,f=Math.sin(c+i)*l,d=this.getCenterPoint(),g=t?d:fabric.util.transformPoint(d,r),p=new fabric.Point(g.x-u,g.y-f),v=new fabric.Point(p.x+s*h,p.y+s*a),m=new fabric.Point(p.x-o*a,p.y+o*h),b=new fabric.Point(g.x+u,g.y+f);if(!t)var _=new fabric.Point((p.x+m.x)/2,(p.y+m.y)/2),y=new fabric.Point((v.x+p.x)/2,(v.y+p.y)/2),x=new fabric.Point((b.x+v.x)/2,(b.y+v.y)/2),C=new fabric.Point((b.x+m.x)/2,(b.y+m.y)/2),S=new fabric.Point(y.x+a*this.rotatingPointOffset,y.y-h*this.rotatingPointOffset);g={tl:p,tr:v,br:b,bl:m};return t||(g.ml=_,g.mt=y,g.mr=x,g.mb=C,g.mtr=S),g},setCoords:function(t,e){return this.oCoords=this.calcCoords(t),e||(this.aCoords=this.calcCoords(!0)),t||this._setCornerCoords&&this._setCornerCoords(),this},_calcRotateMatrix:function(){if(this.angle){var t=e(this.angle),i=Math.cos(t),r=Math.sin(t);return 6.123233995736766e-17!==i&&-1.8369701987210297e-16!==i||(i=0),[i,r,-r,i,0,0]}return fabric.iMatrix.concat()},transformMatrixKey:function(t){var e="";return!t&&this.group&&(e=this.group.transformMatrixKey(t)+"_"),e+this.top+"_"+this.left+"_"+this.scaleX+"_"+this.scaleY+"_"+this.skewX+"_"+this.skewY+"_"+this.angle+"_"+this.flipX+"_"+this.flipY},calcTransformMatrix:function(t){if(t)return this.calcOwnMatrix();var e=this.transformMatrixKey(),r=this.matrixCache||(this.matrixCache={});if(r.key===e)return r.value;var n=this.calcOwnMatrix();return this.group&&(n=i(this.group.calcTransformMatrix(),n)),r.key=e,r.value=n,n},calcOwnMatrix:function(){var t=this.transformMatrixKey(!0),e=this.ownMatrixCache||(this.ownMatrixCache={});if(e.key===t)return e.value;var r,n=this.getCenterPoint(),s=[1,0,0,1,n.x,n.y],o=this._calcDimensionsTransformMatrix(this.skewX,this.skewY,!0);return this.angle&&(r=this._calcRotateMatrix(),s=i(s,r)),s=i(s,o),e.key=t,e.value=s,s},_calcDimensionsTransformMatrix:function(t,r,n){var s,o=[this.scaleX*(n&&this.flipX?-1:1),0,0,this.scaleY*(n&&this.flipY?-1:1),0,0];return t&&(s=[1,0,Math.tan(e(t)),1],o=i(o,s,!0)),r&&(s=[1,Math.tan(e(r)),0,1],o=i(o,s,!0)),o},_getNonTransformedDimensions:function(){var t=this.strokeWidth;return{x:this.width+t,y:this.height+t}},_getTransformedDimensions:function(t,e){void 0===t&&(t=this.skewX),void 0===e&&(e=this.skewY);var i,r,n=this._getNonTransformedDimensions(),s=n.x/2,o=n.y/2,a=[{x:-s,y:-o},{x:s,y:-o},{x:-s,y:o},{x:s,y:o}],h=this._calcDimensionsTransformMatrix(t,e,!1);for(i=0;i\n')},_createBaseSVGMarkup:function(){var t=[];return this.fill&&this.fill.toLive&&t.push(this.fill.toSVG(this,!1)),this.stroke&&this.stroke.toLive&&t.push(this.stroke.toSVG(this,!1)),this.shadow&&t.push(this.shadow.toSVG(this)),t},addPaintOrder:function(){return"fill"!==this.paintFirst?' paint-order="'+this.paintFirst+'" ':""}})}(),function(){function t(t,e,r){var n={};r.forEach(function(e){n[e]=t[e]}),i(t[e],n,!0)}function e(t,i,r){if(t===i)return!0;if(Array.isArray(t)){if(t.length!==i.length)return!1;for(var n=0,s=t.length;n\n'),t?t(e.join("")):e.join("")}}),i.Line.ATTRIBUTE_NAMES=i.SHARED_ATTRIBUTES.concat("x1 y1 x2 y2".split(" ")),i.Line.fromElement=function(t,e,n){n=n||{};var s=i.parseAttributes(t,i.Line.ATTRIBUTE_NAMES),o=[s.x1||0,s.y1||0,s.x2||0,s.y2||0];e(new i.Line(o,r(s,n)))},i.Line.fromObject=function(t,e){var r=n(t,!0);r.points=[t.x1,t.y1,t.x2,t.y2],i.Object._fromObject("Line",r,function(t){delete t.points,e&&e(t)},"points")})}("undefined"!=typeof exports?exports:this),function(t){"use strict";function e(t){return"radius"in t&&t.radius>=0}var i=t.fabric||(t.fabric={}),r=Math.PI,n=i.util.object.extend;i.Circle?i.warn("fabric.Circle is already defined."):(i.Circle=i.util.createClass(i.Object,{type:"circle",radius:0,startAngle:0,endAngle:2*r,cacheProperties:i.Object.prototype.cacheProperties.concat("radius"),initialize:function(t){this.callSuper("initialize",t),this.set("radius",t&&t.radius||0)},_set:function(t,e){return this.callSuper("_set",t,e),"radius"===t&&this.setRadius(e),this},toObject:function(t){return this.callSuper("toObject",["radius","startAngle","endAngle"].concat(t))},toSVG:function(t){var e=this._createBaseSVGMarkup(),i=(this.endAngle-this.startAngle)%(2*r);if(0===i)e.push("\n");else{var n=Math.cos(this.startAngle)*this.radius,s=Math.sin(this.startAngle)*this.radius,o=Math.cos(this.endAngle)*this.radius,a=Math.sin(this.endAngle)*this.radius,h=i>r?"1":"0";e.push('\n')}return t?t(e.join("")):e.join("")},_render:function(t){t.beginPath(),t.arc(0,0,this.radius,this.startAngle,this.endAngle,!1),this._renderPaintInOrder(t)},getRadiusX:function(){return this.get("radius")*this.get("scaleX")},getRadiusY:function(){return this.get("radius")*this.get("scaleY")},setRadius:function(t){return this.radius=t,this.set("width",2*t).set("height",2*t)}}),i.Circle.ATTRIBUTE_NAMES=i.SHARED_ATTRIBUTES.concat("cx cy r".split(" ")),i.Circle.fromElement=function(t,r,s){s||(s={});var o=i.parseAttributes(t,i.Circle.ATTRIBUTE_NAMES);if(!e(o))throw new Error("value of `r` attribute is required and can not be negative");o.left=(o.left||0)-o.radius,o.top=(o.top||0)-o.radius,r(new i.Circle(n(o,s)))},i.Circle.fromObject=function(t,e){return i.Object._fromObject("Circle",t,e)})}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={});e.Triangle?e.warn("fabric.Triangle is already defined"):(e.Triangle=e.util.createClass(e.Object,{type:"triangle",initialize:function(t){this.callSuper("initialize",t),this.set("width",t&&t.width||100).set("height",t&&t.height||100)},_render:function(t){var e=this.width/2,i=this.height/2;t.beginPath(),t.moveTo(-e,i),t.lineTo(0,-i),t.lineTo(e,i),t.closePath(),this._renderPaintInOrder(t)},_renderDashedStroke:function(t){var i=this.width/2,r=this.height/2;t.beginPath(),e.util.drawDashedLine(t,-i,r,0,-r,this.strokeDashArray),e.util.drawDashedLine(t,0,-r,i,r,this.strokeDashArray),e.util.drawDashedLine(t,i,r,-i,r,this.strokeDashArray),t.closePath()},toSVG:function(t){var e=this._createBaseSVGMarkup(),i=this.width/2,r=this.height/2,n=[-i+" "+r,"0 "+-r,i+" "+r].join(",");return e.push(""),t?t(e.join("")):e.join("")}}),e.Triangle.fromObject=function(t,i){return e.Object._fromObject("Triangle",t,i)})}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=2*Math.PI,r=e.util.object.extend;e.Ellipse?e.warn("fabric.Ellipse is already defined."):(e.Ellipse=e.util.createClass(e.Object,{type:"ellipse",rx:0,ry:0,cacheProperties:e.Object.prototype.cacheProperties.concat("rx","ry"),initialize:function(t){this.callSuper("initialize",t),this.set("rx",t&&t.rx||0),this.set("ry",t&&t.ry||0)},_set:function(t,e){switch(this.callSuper("_set",t,e),t){case"rx":this.rx=e,this.set("width",2*e);break;case"ry":this.ry=e,this.set("height",2*e)}return this},getRx:function(){return this.get("rx")*this.get("scaleX")},getRy:function(){return this.get("ry")*this.get("scaleY")},toObject:function(t){return this.callSuper("toObject",["rx","ry"].concat(t))},toSVG:function(t){var e=this._createBaseSVGMarkup();return e.push("\n"),t?t(e.join("")):e.join("")},_render:function(t){t.beginPath(),t.save(),t.transform(1,0,0,this.ry/this.rx,0,0),t.arc(0,0,this.rx,0,i,!1),t.restore(),this._renderPaintInOrder(t)}}),e.Ellipse.ATTRIBUTE_NAMES=e.SHARED_ATTRIBUTES.concat("cx cy rx ry".split(" ")),e.Ellipse.fromElement=function(t,i,n){n||(n={});var s=e.parseAttributes(t,e.Ellipse.ATTRIBUTE_NAMES);s.left=(s.left||0)-s.rx,s.top=(s.top||0)-s.ry,i(new e.Ellipse(r(s,n)))},e.Ellipse.fromObject=function(t,i){return e.Object._fromObject("Ellipse",t,i)})}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=e.util.object.extend;e.Rect?e.warn("fabric.Rect is already defined"):(e.Rect=e.util.createClass(e.Object,{stateProperties:e.Object.prototype.stateProperties.concat("rx","ry"),type:"rect",rx:0,ry:0,cacheProperties:e.Object.prototype.cacheProperties.concat("rx","ry"),initialize:function(t){this.callSuper("initialize",t),this._initRxRy()},_initRxRy:function(){this.rx&&!this.ry?this.ry=this.rx:this.ry&&!this.rx&&(this.rx=this.ry)},_render:function(t){if(1!==this.width||1!==this.height){var e=this.rx?Math.min(this.rx,this.width/2):0,i=this.ry?Math.min(this.ry,this.height/2):0,r=this.width,n=this.height,s=-this.width/2,o=-this.height/2,a=0!==e||0!==i,h=.4477152502;t.beginPath(),t.moveTo(s+e,o),t.lineTo(s+r-e,o),a&&t.bezierCurveTo(s+r-h*e,o,s+r,o+h*i,s+r,o+i),t.lineTo(s+r,o+n-i),a&&t.bezierCurveTo(s+r,o+n-h*i,s+r-h*e,o+n,s+r-e,o+n),t.lineTo(s+e,o+n),a&&t.bezierCurveTo(s+h*e,o+n,s,o+n-h*i,s,o+n-i),t.lineTo(s,o+i),a&&t.bezierCurveTo(s,o+h*i,s+h*e,o,s+e,o),t.closePath(),this._renderPaintInOrder(t)}else t.fillRect(-.5,-.5,1,1)},_renderDashedStroke:function(t){var i=-this.width/2,r=-this.height/2,n=this.width,s=this.height;t.beginPath(),e.util.drawDashedLine(t,i,r,i+n,r,this.strokeDashArray),e.util.drawDashedLine(t,i+n,r,i+n,r+s,this.strokeDashArray),e.util.drawDashedLine(t,i+n,r+s,i,r+s,this.strokeDashArray),e.util.drawDashedLine(t,i,r+s,i,r,this.strokeDashArray),t.closePath()},toObject:function(t){return this.callSuper("toObject",["rx","ry"].concat(t))},toSVG:function(t){var e=this._createBaseSVGMarkup(),i=-this.width/2,r=-this.height/2;return e.push("\n"),t?t(e.join("")):e.join("")}}),e.Rect.ATTRIBUTE_NAMES=e.SHARED_ATTRIBUTES.concat("x y rx ry width height".split(" ")),e.Rect.fromElement=function(t,r,n){if(!t)return r(null);n=n||{};var s=e.parseAttributes(t,e.Rect.ATTRIBUTE_NAMES);s.left=s.left||0,s.top=s.top||0;var o=new e.Rect(i(n?e.util.object.clone(n):{},s));o.visible=o.visible&&o.width>0&&o.height>0,r(o)},e.Rect.fromObject=function(t,i){return e.Object._fromObject("Rect",t,i)})}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=e.util.object.extend,r=e.util.array.min,n=e.util.array.max,s=e.util.toFixed,o=e.Object.NUM_FRACTION_DIGITS;e.Polyline?e.warn("fabric.Polyline is already defined"):(e.Polyline=e.util.createClass(e.Object,{type:"polyline",points:null,cacheProperties:e.Object.prototype.cacheProperties.concat("points"),initialize:function(t,e){e=e||{},this.points=t||[],this.callSuper("initialize",e);var i=this._calcDimensions();void 0===e.left&&(this.left=i.left),void 0===e.top&&(this.top=i.top),this.width=i.width,this.height=i.height,this.pathOffset={x:i.left+this.width/2,y:i.top+this.height/2}},_calcDimensions:function(){var t=this.points,e=r(t,"x")||0,i=r(t,"y")||0;return{left:e,top:i,width:(n(t,"x")||0)-e,height:(n(t,"y")||0)-i}},toObject:function(t){return i(this.callSuper("toObject",t),{points:this.points.concat()})},toSVG:function(t){for(var e=[],i=this.pathOffset.x,r=this.pathOffset.y,n=this._createBaseSVGMarkup(),a=0,h=this.points.length;a\n"),t?t(n.join("")):n.join("")},commonRender:function(t){var e,i=this.points.length,r=this.pathOffset.x,n=this.pathOffset.y;if(!i||isNaN(this.points[i-1].y))return!1;t.beginPath(),t.moveTo(this.points[0].x-r,this.points[0].y-n);for(var s=0;s"},toObject:function(t){return n(this.callSuper("toObject",t),{path:this.path.map(function(t){return t.slice()}),top:this.top,left:this.left})},toDatalessObject:function(t){var e=this.toObject(["sourcePath"].concat(t));return e.sourcePath&&delete e.path,e},toSVG:function(t){for(var e=[],i=this._createBaseSVGMarkup(),r="",n=0,s=this.path.length;n\n"),t?t(i.join("")):i.join("")},complexity:function(){return this.path.length},_parsePath:function(){for(var t,e,i,r,n,s=[],o=[],c=/([-+]?((\d+\.\d+)|((\d+)|(\.\d+)))(?:e[-+]?\d+)?)/gi,l=0,u=this.path.length;lp)for(var m=1,b=n.length;m"},addWithUpdate:function(t){return this._restoreObjectsState(),e.util.resetObjectTransform(this),t&&(this._objects.push(t),t.group=this,t._set("canvas",this.canvas)),this._calcBounds(),this._updateObjectsCoords(),this.setCoords(),this.dirty=!0,this},removeWithUpdate:function(t){return this._restoreObjectsState(),e.util.resetObjectTransform(this),this.remove(t),this._calcBounds(),this._updateObjectsCoords(),this.setCoords(),this.dirty=!0,this},_onObjectAdded:function(t){this.dirty=!0,t.group=this,t._set("canvas",this.canvas)},_onObjectRemoved:function(t){this.dirty=!0,delete t.group},_set:function(t,e){var i=this._objects.length;if(this.useSetOnGroup)for(;i--;)this._objects[i].setOnGroup(t,e);if("canvas"===t)for(i=this._objects.length;i--;)this._objects[i]._set(t,e);this.callSuper("_set",t,e)},toObject:function(t){var e=this.getObjects().map(function(e){var i=e.includeDefaultValues;e.includeDefaultValues=e.group.includeDefaultValues;var r=e.toObject(t);return e.includeDefaultValues=i,r});return i(this.callSuper("toObject",t),{objects:e})},toDatalessObject:function(t){var e,r=this.sourcePath;return e=r||this.getObjects().map(function(e){var i=e.includeDefaultValues;e.includeDefaultValues=e.group.includeDefaultValues;var r=e.toDatalessObject(t);return e.includeDefaultValues=i,r}),i(this.callSuper("toDatalessObject",t),{objects:e})},render:function(t){this._transformDone=!0,this.callSuper("render",t),this._transformDone=!1},shouldCache:function(){var t=this.objectCaching&&(!this.group||this.needsItsOwnCache()||!this.group.isOnACache());if(this.ownCaching=t,t)for(var e=0,i=this._objects.length;e\n');for(var i=0,r=this._objects.length;i\n"),t?t(e.join("")):e.join("")}}),e.Group.fromObject=function(t,i){e.util.enlivenObjects(t.objects,function(r){var n=e.util.object.clone(t,!0);delete n.objects,i&&i(new e.Group(r,n,!0))})})}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={});e.ActiveSelection||(e.ActiveSelection=e.util.createClass(e.Group,{type:"activeSelection",initialize:function(t,i){i=i||{},this._objects=t||[];for(var r=this._objects.length;r--;)this._objects[r].group=this;i.originX&&(this.originX=i.originX),i.originY&&(this.originY=i.originY),this._calcBounds(),this._updateObjectsCoords(),e.Object.prototype.initialize.call(this,i),this.setCoords()},toGroup:function(){var t=this._objects;this._objects=[];var i=this.toObject(),r=new e.Group([]);if(delete i.objects,r.set(i),r.type="group",t.forEach(function(t){t.group=r,t.canvas.remove(t)}),r._objects=t,!this.canvas)return r;var n=this.canvas;return n.add(r),n._activeObject=r,r.setCoords(),r},onDeselect:function(){return this.destroy(),!1},toString:function(){return"#"},_set:function(t,i){var r=this._objects.length;if("canvas"===t)for(;r--;)this._objects[r].set(t,i);if(this.useSetOnGroup)for(;r--;)this._objects[r].setOnGroup(t,i);e.Object.prototype._set.call(this,t,i)},shouldCache:function(){return!1},willDrawShadow:function(){if(this.shadow)return this.callSuper("willDrawShadow");for(var t=0,e=this._objects.length;t\n');var n=["\t\n'];if("fill"===this.paintFirst&&Array.prototype.push.apply(e,n),this.stroke||this.strokeDashArray){var s=this.fill;this.fill=null,e.push("\t\n'),this.fill=s}return"fill"!==this.paintFirst&&Array.prototype.push.apply(e,n),e.push("\n"),t?t(e.join("")):e.join("")},getSrc:function(t){var e=t?this._element:this._originalElement;return e?e.toDataURL?e.toDataURL():e.src:this.src||""},setSrc:function(t,e,i){return fabric.util.loadImage(t,function(t){this.setElement(t,i),e(this)},this,i&&i.crossOrigin),this},toString:function(){return'#'},applyResizeFilters:function(){var t=this.resizeFilter,e=this.canvas?this.canvas.getRetinaScaling():1,i=this.minimumScaleTrigger,r=this.scaleX*e,n=this.scaleY*e,s=this._filteredEl||this._originalElement;if(!t||r>i&&n>i)return this._element=s,this._filterScalingX=1,void(this._filterScalingY=1);fabric.filterBackend||(fabric.filterBackend=fabric.initFilterBackend());var o=fabric.util.createCanvasElement(),a=this._filteredEl?this.cacheKey:this.cacheKey+"_filtered",h=s.width,c=s.height;o.width=h,o.height=c,this._element=o,t.scaleX=r,t.scaleY=n,fabric.filterBackend.applyFilters([t],s,h,c,this._element,a),this._filterScalingX=o.width/this._originalElement.width,this._filterScalingY=o.height/this._originalElement.height},applyFilters:function(t){if(t=t||this.filters||[],0===(t=t.filter(function(t){return t})).length)return this._element=this._originalElement,this._filteredEl=null,this._filterScalingX=1,this._filterScalingY=1,this;var e=this._originalElement,i=e.naturalWidth||e.width,r=e.naturalHeight||e.height;if(this._element===this._originalElement){var n=fabric.util.createCanvasElement();n.width=i,n.height=r,this._element=n,this._filteredEl=n}else this._element.getContext("2d").clearRect(0,0,i,r);return fabric.filterBackend||(fabric.filterBackend=fabric.initFilterBackend()),fabric.filterBackend.applyFilters(t,this._originalElement,i,r,this._element,this.cacheKey),this._originalElement.width===this._element.width&&this._originalElement.height===this._element.height||(this._filterScalingX=this._element.width/this._originalElement.width,this._filterScalingY=this._element.height/this._originalElement.height),this},_render:function(t){!1===this.isMoving&&this.resizeFilter&&this._needsResize()&&(this._lastScaleX=this.scaleX,this._lastScaleY=this.scaleY,this.applyResizeFilters()),this._stroke(t),this._renderPaintInOrder(t)},_renderFill:function(t){var e=this.width,i=this.height,r=e*this._filterScalingX,n=i*this._filterScalingY,s=-e/2,o=-i/2,a=this._element;a&&t.drawImage(a,this.cropX*this._filterScalingX,this.cropY*this._filterScalingY,r,n,s,o,e,i)},_needsResize:function(){return this.scaleX!==this._lastScaleX||this.scaleY!==this._lastScaleY},_resetWidthHeight:function(){var t=this.getElement();this.set("width",t.width),this.set("height",t.height)},_initElement:function(t,e){this.setElement(fabric.util.getById(t),e),fabric.util.addClass(this.getElement(),fabric.Image.CSS_CANVAS)},_initConfig:function(t){t||(t={}),this.setOptions(t),this._setWidthHeight(t),this._element&&this.crossOrigin&&(this._element.crossOrigin=this.crossOrigin)},_initFilters:function(t,e){t&&t.length?fabric.util.enlivenObjects(t,function(t){e&&e(t)},"fabric.Image.filters"):e&&e()},_setWidthHeight:function(t){this.width="width"in t?t.width:this.getElement()?this.getElement().width||0:0,this.height="height"in t?t.height:this.getElement()?this.getElement().height||0:0},parsePreserveAspectRatioAttribute:function(){var t,e=fabric.util.parsePreserveAspectRatioAttribute(this.preserveAspectRatio||""),i=this._element.width,r=this._element.height,n=1,s=1,o=0,a=0,h=0,c=0,l=this.width,u=this.height,f={width:l,height:u};return!e||"none"===e.alignX&&"none"===e.alignY?(n=l/i,s=u/r):("meet"===e.meetOrSlice&&(t=(l-i*(n=s=fabric.util.findScaleToFit(this._element,f)))/2,"Min"===e.alignX&&(o=-t),"Max"===e.alignX&&(o=t),t=(u-r*s)/2,"Min"===e.alignY&&(a=-t),"Max"===e.alignY&&(a=t)),"slice"===e.meetOrSlice&&(t=i-l/(n=s=fabric.util.findScaleToCover(this._element,f)),"Mid"===e.alignX&&(h=t/2),"Max"===e.alignX&&(h=t),t=r-u/s,"Mid"===e.alignY&&(c=t/2),"Max"===e.alignY&&(c=t),i=l/n,r=u/s)),{width:i,height:r,scaleX:n,scaleY:s,offsetLeft:o,offsetTop:a,cropX:h,cropY:c}}}),fabric.Image.CSS_CANVAS="canvas-img",fabric.Image.prototype.getSvgSrc=fabric.Image.prototype.getSrc,fabric.Image.fromObject=function(t,e){fabric.util.loadImage(t.src,function(i,r){r?e&&e(null,r):fabric.Image.prototype._initFilters.call(t,t.filters,function(r){t.filters=r||[],fabric.Image.prototype._initFilters.call(t,[t.resizeFilter],function(r){t.resizeFilter=r[0];var n=new fabric.Image(i,t);e(n)})})},null,t.crossOrigin)},fabric.Image.fromURL=function(t,e,i){fabric.util.loadImage(t,function(t){e&&e(new fabric.Image(t,i))},null,i&&i.crossOrigin)},fabric.Image.ATTRIBUTE_NAMES=fabric.SHARED_ATTRIBUTES.concat("x y width height preserveAspectRatio xlink:href crossOrigin".split(" ")),fabric.Image.fromElement=function(t,i,r){var n=fabric.parseAttributes(t,fabric.Image.ATTRIBUTE_NAMES);fabric.Image.fromURL(n["xlink:href"],i,e(r?fabric.util.object.clone(r):{},n))}}}("undefined"!=typeof exports?exports:this),fabric.util.object.extend(fabric.Object.prototype,{_getAngleValueForStraighten:function(){var t=this.angle%360;return t>0?90*Math.round((t-1)/90):90*Math.round(t/90)},straighten:function(){return this.rotate(this._getAngleValueForStraighten()),this},fxStraighten:function(t){var e=function(){},i=(t=t||{}).onComplete||e,r=t.onChange||e,n=this;return fabric.util.animate({startValue:this.get("angle"),endValue:this._getAngleValueForStraighten(),duration:this.FX_DURATION,onChange:function(t){n.rotate(t),r()},onComplete:function(){n.setCoords(),i()}}),this}}),fabric.util.object.extend(fabric.StaticCanvas.prototype,{straightenObject:function(t){return t.straighten(),this.requestRenderAll(),this},fxStraightenObject:function(t){return t.fxStraighten({onChange:this.requestRenderAllBound}),this}}),function(){"use strict";function t(t,e){var i="precision "+e+" float;\nvoid main(){}",r=t.createShader(t.FRAGMENT_SHADER);return t.shaderSource(r,i),t.compileShader(r),!!t.getShaderParameter(r,t.COMPILE_STATUS)}function e(t){t&&t.tileSize&&(this.tileSize=t.tileSize),this.setupGLContext(this.tileSize,this.tileSize),this.captureGPUInfo()}fabric.isWebglSupported=function(e){if(fabric.isLikelyNode)return!1;e=e||fabric.WebglFilterBackend.prototype.tileSize;var i=document.createElement("canvas"),r=i.getContext("webgl")||i.getContext("experimental-webgl"),n=!1;if(r){fabric.maxTextureSize=r.getParameter(r.MAX_TEXTURE_SIZE),n=fabric.maxTextureSize>=e;for(var s=["highp","mediump","lowp"],o=0;o<3;o++)if(t(r,s[o])){fabric.webGlPrecision=s[o];break}}return this.isSupported=n,n},fabric.WebglFilterBackend=e,e.prototype={tileSize:2048,resources:{},setupGLContext:function(t,e){this.dispose(),this.createWebGLCanvas(t,e),this.aPosition=new Float32Array([0,0,0,1,1,0,1,1]),this.chooseFastestCopyGLTo2DMethod(t,e)},chooseFastestCopyGLTo2DMethod:function(t,e){var i,r=void 0!==window.performance;try{new ImageData(1,1),i=!0}catch(t){i=!1}var n="undefined"!=typeof ArrayBuffer,s="undefined"!=typeof Uint8ClampedArray;if(r&&i&&n&&s){var o,a,h=fabric.util.createCanvasElement(),c=new ArrayBuffer(t*e*4),l={imageBuffer:c,destinationWidth:t,destinationHeight:e,targetCanvas:h};h.width=t,h.height=e,o=window.performance.now(),copyGLTo2DDrawImage.call(l,this.gl,l),a=window.performance.now()-o,o=window.performance.now(),copyGLTo2DPutImageData.call(l,this.gl,l),a>window.performance.now()-o?(this.imageBuffer=c,this.copyGLTo2D=copyGLTo2DPutImageData):this.copyGLTo2D=copyGLTo2DDrawImage}},createWebGLCanvas:function(t,e){var i=fabric.util.createCanvasElement();i.width=t,i.height=e;var r={premultipliedAlpha:!1},n=i.getContext("webgl",r);n||(n=i.getContext("experimental-webgl",r)),n&&(n.clearColor(0,0,0,0),this.canvas=i,this.gl=n)},applyFilters:function(t,e,i,r,n,s){var o,a=this.gl;s&&(o=this.getCachedTexture(s,e));var h={originalWidth:e.width||e.originalWidth,originalHeight:e.height||e.originalHeight,sourceWidth:i,sourceHeight:r,destinationWidth:i,destinationHeight:r,context:a,sourceTexture:this.createTexture(a,i,r,!o&&e),targetTexture:this.createTexture(a,i,r),originalTexture:o||this.createTexture(a,i,r,!o&&e),passes:t.length,webgl:!0,aPosition:this.aPosition,programCache:this.programCache,pass:0,filterBackend:this,targetCanvas:n},c=a.createFramebuffer();return a.bindFramebuffer(a.FRAMEBUFFER,c),t.forEach(function(t){t&&t.applyTo(h)}),resizeCanvasIfNeeded(h),this.copyGLTo2D(a,h),a.bindTexture(a.TEXTURE_2D,null),a.deleteTexture(h.sourceTexture),a.deleteTexture(h.targetTexture),a.deleteFramebuffer(c),n.getContext("2d").setTransform(1,0,0,1,0,0),h},applyFiltersDebug:function(t,e,i,r,n,s){var o=this.gl,a=this.applyFilters(t,e,i,r,n,s),h=o.getError();if(h!==o.NO_ERROR){var c=this.glErrorToString(o,h),l=new Error("WebGL Error "+c);throw l.glErrorCode=h,l}return a},glErrorToString:function(t,e){if(!t)return"Context undefined for error code: "+e;if("number"!=typeof e)return"Error code is not a number";switch(e){case t.NO_ERROR:return"NO_ERROR";case t.INVALID_ENUM:return"INVALID_ENUM";case t.INVALID_VALUE:return"INVALID_VALUE";case t.INVALID_OPERATION:return"INVALID_OPERATION";case t.INVALID_FRAMEBUFFER_OPERATION:return"INVALID_FRAMEBUFFER_OPERATION";case t.OUT_OF_MEMORY:return"OUT_OF_MEMORY";case t.CONTEXT_LOST_WEBGL:return"CONTEXT_LOST_WEBGL";default:return"UNKNOWN_ERROR"}},dispose:function(){this.canvas&&(this.canvas=null,this.gl=null),this.clearWebGLCaches()},clearWebGLCaches:function(){this.programCache={},this.textureCache={}},createTexture:function(t,e,i,r){var n=t.createTexture();return t.bindTexture(t.TEXTURE_2D,n),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),r?t.texImage2D(t.TEXTURE_2D,0,t.RGBA,t.RGBA,t.UNSIGNED_BYTE,r):t.texImage2D(t.TEXTURE_2D,0,t.RGBA,e,i,0,t.RGBA,t.UNSIGNED_BYTE,null),n},getCachedTexture:function(t,e){if(this.textureCache[t])return this.textureCache[t];var i=this.createTexture(this.gl,e.width,e.height,e);return this.textureCache[t]=i,i},evictCachesForKey:function(t){this.textureCache[t]&&(this.gl.deleteTexture(this.textureCache[t]),delete this.textureCache[t])},copyGLTo2D:copyGLTo2DDrawImage,captureGPUInfo:function(){if(this.gpuInfo)return this.gpuInfo;var t=this.gl,e=t.getExtension("WEBGL_debug_renderer_info"),i={renderer:"",vendor:""};if(e){var r=t.getParameter(e.UNMASKED_RENDERER_WEBGL),n=t.getParameter(e.UNMASKED_VENDOR_WEBGL);r&&(i.renderer=r.toLowerCase()),n&&(i.vendor=n.toLowerCase())}return this.gpuInfo=i,i}}}(),function(){"use strict";function t(){}var e=function(){};fabric.Canvas2dFilterBackend=t,t.prototype={evictCachesForKey:e,dispose:e,clearWebGLCaches:e,resources:{},applyFilters:function(t,e,i,r,n){var s=n.getContext("2d");s.drawImage(e,0,0,i,r);var o={sourceWidth:i,sourceHeight:r,imageData:s.getImageData(0,0,i,r),originalEl:e,originalImageData:s.getImageData(0,0,i,r),canvasEl:n,ctx:s,filterBackend:this};return t.forEach(function(t){t.applyTo(o)}),o.imageData.width===i&&o.imageData.height===r||(n.width=o.imageData.width,n.height=o.imageData.height),s.putImageData(o.imageData,0,0),o}}}(),fabric.Image.filters=fabric.Image.filters||{},fabric.Image.filters.BaseFilter=fabric.util.createClass({type:"BaseFilter",vertexSource:"attribute vec2 aPosition;\nvarying vec2 vTexCoord;\nvoid main() {\nvTexCoord = aPosition;\ngl_Position = vec4(aPosition * 2.0 - 1.0, 0.0, 1.0);\n}",fragmentSource:"precision highp float;\nvarying vec2 vTexCoord;\nuniform sampler2D uTexture;\nvoid main() {\ngl_FragColor = texture2D(uTexture, vTexCoord);\n}",initialize:function(t){t&&this.setOptions(t)},setOptions:function(t){for(var e in t)this[e]=t[e]},createProgram:function(t,e,i){"highp"!==fabric.webGlPrecision&&(e=e.replace(/precision highp float/g,"precision "+fabric.webGlPrecision+" float"));var r=t.createShader(t.VERTEX_SHADER);if(t.shaderSource(r,i||this.vertexSource),t.compileShader(r),!t.getShaderParameter(r,t.COMPILE_STATUS))throw new Error('Vertex shader compile error for "${this.type}": '+t.getShaderInfoLog(r));var n=t.createShader(t.FRAGMENT_SHADER);if(t.shaderSource(n,e||this.fragmentSource),t.compileShader(n),!t.getShaderParameter(n,t.COMPILE_STATUS))throw new Error('Fragment shader compile error for "${this.type}": '+t.getShaderInfoLog(n));var s=t.createProgram();if(t.attachShader(s,r),t.attachShader(s,n),t.linkProgram(s),!t.getProgramParameter(s,t.LINK_STATUS))throw new Error('Shader link error for "${this.type}" '+t.getProgramInfoLog(s));var o=this.getAttributeLocations(t,s),a=this.getUniformLocations(t,s)||{};return a.uStepW=t.getUniformLocation(s,"uStepW"),a.uStepH=t.getUniformLocation(s,"uStepH"),{program:s,attributeLocations:o,uniformLocations:a}},getAttributeLocations:function(t,e){return{aPosition:t.getAttribLocation(e,"aPosition")}},getUniformLocations:function(){return{}},sendAttributeData:function(t,e,i){var r=e.aPostion,n=t.createBuffer();t.bindBuffer(t.ARRAY_BUFFER,n),t.enableVertexAttribArray(r),t.vertexAttribPointer(r,2,t.FLOAT,!1,0,0),t.bufferData(t.ARRAY_BUFFER,i,t.STATIC_DRAW)},_setupFrameBuffer:function(t){var e,i,r=t.context;t.passes>1?(e=t.destinationWidth,i=t.destinationHeight,t.sourceWidth===e&&t.sourceHeight===i||(r.deleteTexture(t.targetTexture),t.targetTexture=t.filterBackend.createTexture(r,e,i)),r.framebufferTexture2D(r.FRAMEBUFFER,r.COLOR_ATTACHMENT0,r.TEXTURE_2D,t.targetTexture,0)):(r.bindFramebuffer(r.FRAMEBUFFER,null),r.finish())},_swapTextures:function(t){t.passes--,t.pass++;var e=t.targetTexture;t.targetTexture=t.sourceTexture,t.sourceTexture=e},isNeutralState:function(){return!1},applyTo:function(t){if(t.webgl){if(t.passes>1&&this.isNeutralState(t))return;this._setupFrameBuffer(t),this.applyToWebGL(t),this._swapTextures(t)}else this.isNeutralState()||this.applyTo2d(t)},retrieveShader:function(t){return t.programCache.hasOwnProperty(this.type)||(t.programCache[this.type]=this.createProgram(t.context)),t.programCache[this.type]},applyToWebGL:function(t){var e=t.context,i=this.retrieveShader(t);0===t.pass&&t.originalTexture?e.bindTexture(e.TEXTURE_2D,t.originalTexture):e.bindTexture(e.TEXTURE_2D,t.sourceTexture),e.useProgram(i.program),this.sendAttributeData(e,i.attributeLocations,t.aPosition),e.uniform1f(i.uniformLocations.uStepW,1/t.sourceWidth),e.uniform1f(i.uniformLocations.uStepH,1/t.sourceHeight),this.sendUniformData(e,i.uniformLocations),e.viewport(0,0,t.destinationWidth,t.destinationHeight),e.drawArrays(e.TRIANGLE_STRIP,0,4)},bindAdditionalTexture:function(t,e,i){t.activeTexture(i),t.bindTexture(t.TEXTURE_2D,e),t.activeTexture(t.TEXTURE0)},unbindAdditionalTexture:function(t,e){t.activeTexture(e),t.bindTexture(t.TEXTURE_2D,null),t.activeTexture(t.TEXTURE0)},getMainParameter:function(){return this[this.mainParameter]},setMainParameter:function(t){this[this.mainParameter]=t},sendUniformData:function(){},createHelpLayer:function(t){if(!t.helpLayer){var e=document.createElement("canvas");e.width=t.sourceWidth,e.height=t.sourceHeight,t.helpLayer=e}},toObject:function(){var t={type:this.type},e=this.mainParameter;return e&&(t[e]=this[e]),t},toJSON:function(){return this.toObject()}}),fabric.Image.filters.BaseFilter.fromObject=function(t,e){var i=new fabric.Image.filters[t.type](t);return e&&e(i),i},function(t){"use strict";var e=t.fabric||(t.fabric={}),i=e.Image.filters,r=e.util.createClass;i.ColorMatrix=r(i.BaseFilter,{type:"ColorMatrix",fragmentSource:"precision highp float;\nuniform sampler2D uTexture;\nvarying vec2 vTexCoord;\nuniform mat4 uColorMatrix;\nuniform vec4 uConstants;\nvoid main() {\nvec4 color = texture2D(uTexture, vTexCoord);\ncolor *= uColorMatrix;\ncolor += uConstants;\ngl_FragColor = color;\n}",matrix:[1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0],mainParameter:"matrix",colorsOnly:!0,initialize:function(t){this.callSuper("initialize",t),this.matrix=this.matrix.slice(0)},isNeutralState:function(){for(var t=i.ColorMatrix,e=20;e--;)if(this.matrix[e]!==t.prototype.matrix[e])return!1;return!0},applyTo2d:function(t){var e,i,r,n,s,o=t.imageData.data,a=o.length,h=this.matrix,c=this.colorsOnly;for(s=0;sy||o<0||o>_||(h=4*(a*_+o),c=v[d*m+f],e+=p[h]*c,i+=p[h+1]*c,r+=p[h+2]*c,S||(n+=p[h+3]*c));C[s]=e,C[s+1]=i,C[s+2]=r,C[s+3]=S?p[s+3]:n}t.imageData=x},getUniformLocations:function(t,e){return{uMatrix:t.getUniformLocation(e,"uMatrix"),uOpaque:t.getUniformLocation(e,"uOpaque"),uHalfSize:t.getUniformLocation(e,"uHalfSize"),uSize:t.getUniformLocation(e,"uSize")}},sendUniformData:function(t,e){t.uniform1fv(e.uMatrix,this.matrix)},toObject:function(){return i(this.callSuper("toObject"),{opaque:this.opaque,matrix:this.matrix})}}),e.Image.filters.Convolute.fromObject=e.Image.filters.BaseFilter.fromObject}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=e.Image.filters,r=e.util.createClass;i.Grayscale=r(i.BaseFilter,{type:"Grayscale",fragmentSource:{average:"precision highp float;\nuniform sampler2D uTexture;\nvarying vec2 vTexCoord;\nvoid main() {\nvec4 color = texture2D(uTexture, vTexCoord);\nfloat average = (color.r + color.b + color.g) / 3.0;\ngl_FragColor = vec4(average, average, average, color.a);\n}",lightness:"precision highp float;\nuniform sampler2D uTexture;\nuniform int uMode;\nvarying vec2 vTexCoord;\nvoid main() {\nvec4 col = texture2D(uTexture, vTexCoord);\nfloat average = (max(max(col.r, col.g),col.b) + min(min(col.r, col.g),col.b)) / 2.0;\ngl_FragColor = vec4(average, average, average, col.a);\n}",luminosity:"precision highp float;\nuniform sampler2D uTexture;\nuniform int uMode;\nvarying vec2 vTexCoord;\nvoid main() {\nvec4 col = texture2D(uTexture, vTexCoord);\nfloat average = 0.21 * col.r + 0.72 * col.g + 0.07 * col.b;\ngl_FragColor = vec4(average, average, average, col.a);\n}"},mode:"average",mainParameter:"mode",applyTo2d:function(t){var e,i,r=t.imageData.data,n=r.length,s=this.mode;for(e=0;ec[0]&&n>c[1]&&s>c[2]&&r1&&this.isNeutralState(t))return;t.passes++,this.width=t.sourceWidth,this.horizontal=!0,this.dW=Math.round(this.width*this.scaleX),this.dH=t.sourceHeight,this.tempScale=this.dW/this.width,this.taps=this.getTaps(),t.destinationWidth=this.dW,this._setupFrameBuffer(t),this.applyToWebGL(t),this._swapTextures(t),t.sourceWidth=t.destinationWidth,this.height=t.sourceHeight,this.horizontal=!1,this.dH=Math.round(this.height*this.scaleY),this.tempScale=this.dH/this.height,this.taps=this.getTaps(),t.destinationHeight=this.dH,this._setupFrameBuffer(t),this.applyToWebGL(t),this._swapTextures(t),t.sourceHeight=t.destinationHeight}else this.isNeutralState(t)||this.applyTo2d(t)},isNeutralState:function(t){var e=t.scaleX||this.scaleX,i=t.scaleY||this.scaleY;return 1===e&&1===i},lanczosCreate:function(t){return function(e){if(e>=t||e<=-t)return 0;if(e<1.1920929e-7&&e>-1.1920929e-7)return 1;var i=(e*=Math.PI)/t;return a(e)/e*a(i)/i}},applyTo2d:function(t){var e=t.imageData,i=this.scaleX,r=this.scaleY;this.rcpScaleX=1/i,this.rcpScaleY=1/r;var n,s=e.width,a=e.height,h=o(s*i),c=o(a*r);"sliceHack"===this.resizeType?n=this.sliceByTwo(t,s,a,h,c):"hermite"===this.resizeType?n=this.hermiteFastResize(t,s,a,h,c):"bilinear"===this.resizeType?n=this.bilinearFiltering(t,s,a,h,c):"lanczos"===this.resizeType&&(n=this.lanczosResize(t,s,a,h,c)),t.imageData=n},sliceByTwo:function(t,i,n,s,o){var a,h,c=t.imageData,l=!1,u=!1,f=.5*i,d=.5*n,g=e.filterBackend.resources,p=0,v=0,m=i,b=0;for(g.sliceByTwo||(g.sliceByTwo=document.createElement("canvas")),((a=g.sliceByTwo).width<1.5*i||a.height=e)){P=r(1e3*s(w-C.x)),x[P]||(x[P]={});for(var F=S.y-y;F<=S.y+y;F++)F<0||F>=o||(M=r(1e3*s(F-C.y)),x[P][M]||(x[P][M]=g(n(i(P*m,2)+i(M*b,2))/1e3)),(T=x[P][M])>0&&(k+=T,D+=T*u[O=4*(F*e+w)],E+=T*u[O+1],j+=T*u[O+2],A+=T*u[O+3]))}d[O=4*(h*a+t)]=D/k,d[O+1]=E/k,d[O+2]=j/k,d[O+3]=A/k}return++t1&&M<-1||(_=2*M*M*M-3*M*M+1)>0&&(T+=_*d[(P=4*(A+k*e))+3],x+=_,d[P+3]<255&&(_=_*d[P+3]/250),C+=_*d[P],S+=_*d[P+1],w+=_*d[P+2],y+=_)}p[b]=C/y,p[b+1]=S/y,p[b+2]=w/y,p[b+3]=T/x}return g},toObject:function(){return{type:this.type,scaleX:this.scaleX,scaleY:this.scaleY,resizeType:this.resizeType,lanczosLobes:this.lanczosLobes}}}),e.Image.filters.Resize.fromObject=e.Image.filters.BaseFilter.fromObject}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=e.Image.filters,r=e.util.createClass;i.Contrast=r(i.BaseFilter,{type:"Contrast",fragmentSource:"precision highp float;\nuniform sampler2D uTexture;\nuniform float uContrast;\nvarying vec2 vTexCoord;\nvoid main() {\nvec4 color = texture2D(uTexture, vTexCoord);\nfloat contrastF = 1.015 * (uContrast + 1.0) / (1.0 * (1.015 - uContrast));\ncolor.rgb = contrastF * (color.rgb - 0.5) + 0.5;\ngl_FragColor = color;\n}",contrast:0,mainParameter:"contrast",applyTo2d:function(t){if(0!==this.contrast){var e,i=t.imageData.data,r=i.length,n=Math.floor(255*this.contrast),s=259*(n+255)/(255*(259-n));for(e=0;e1&&(e=1/this.aspectRatio):this.aspectRatio<1&&(e=this.aspectRatio),t=e*this.blur*.12,this.horizontal?i[0]=t:i[1]=t,i}}),i.Blur.fromObject=e.Image.filters.BaseFilter.fromObject}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=e.Image.filters,r=e.util.createClass;i.Gamma=r(i.BaseFilter,{type:"Gamma",fragmentSource:"precision highp float;\nuniform sampler2D uTexture;\nuniform vec3 uGamma;\nvarying vec2 vTexCoord;\nvoid main() {\nvec4 color = texture2D(uTexture, vTexCoord);\nvec3 correction = (1.0 / uGamma);\ncolor.r = pow(color.r, correction.r);\ncolor.g = pow(color.g, correction.g);\ncolor.b = pow(color.b, correction.b);\ngl_FragColor = color;\ngl_FragColor.rgb *= color.a;\n}",gamma:[1,1,1],mainParameter:"gamma",applyTo2d:function(t){var e,i=t.imageData.data,r=this.gamma,n=i.length,s=1/r[0],o=1/r[1],a=1/r[2];for(this.rVals||(this.rVals=new Uint8Array(256),this.gVals=new Uint8Array(256),this.bVals=new Uint8Array(256)),e=0,n=256;e'},_getCacheCanvasDimensions:function(){var t=this.callSuper("_getCacheCanvasDimensions"),e=this.fontSize;return t.width+=e*t.zoomX,t.height+=e*t.zoomY,t},_render:function(t){this._setTextStyles(t),this._renderTextLinesBackground(t),this._renderTextDecoration(t,"underline"),this._renderText(t),this._renderTextDecoration(t,"overline"),this._renderTextDecoration(t,"linethrough")},_renderText:function(t){"stroke"===this.paintFirst?(this._renderTextStroke(t),this._renderTextFill(t)):(this._renderTextFill(t),this._renderTextStroke(t))},_setTextStyles:function(t,e,i){t.textBaseline="alphabetic",t.font=this._getFontDeclaration(e,i)},calcTextWidth:function(){for(var t=this.getLineWidth(0),e=1,i=this._textLines.length;et&&(t=r)}return t},_renderTextLine:function(t,e,i,r,n,s){this._renderChars(t,e,i,r,n,s)},_renderTextLinesBackground:function(t){if(this.textBackgroundColor||this.styleHas("textBackgroundColor")){for(var e,i,r,n,s,o,a=0,h=t.fillStyle,c=this._getLeftOffset(),l=this._getTopOffset(),u=0,f=0,d=0,g=this._textLines.length;dn)){var d=a-n;h[t]=a,h[c]+=d,n=a}return{width:n*u,kernedWidth:a*u}},getHeightOfChar:function(t,e){return this.getValueOfPropertyAt(t,e,"fontSize")},measureLine:function(t){var e=this._measureLine(t);return 0!==this.charSpacing&&(e.width-=this._getWidthOfCharSpacing()),e.width<0&&(e.width=0),e},_measureLine:function(t){var e,i,r,n,s=0,o=this._textLines[t],a=new Array(o.length);for(this.__charBounds[t]=a,e=0;e0&&!n){var u=this.__charBounds[e][i-1];l.left=u.left+u.width+a.kernedWidth-a.width}return l},getHeightOfLine:function(t){if(this.__lineHeights[t])return this.__lineHeights[t];for(var e=this._textLines[t],i=this.getHeightOfChar(t,0),r=1,n=e.length;ri&&(i=s)}return this.__lineHeights[t]=i*this.lineHeight*this._fontSizeMult,this.__lineHeights[t]},calcTextHeight:function(){for(var t,e=0,i=0,r=this._textLines.length;i0?(t.fillStyle=f,s&&f&&t.fillRect(d+r+o,g+l*(1-this._fontSizeFraction)+this.offsets[e]*this.fontSize,a,this.fontSize/15),o=h.left,a=h.width,s=c,f=u):a+=h.kernedWidth;t.fillStyle=u,c&&u&&t.fillRect(d+r+o,g+l*(1-this._fontSizeFraction)+this.offsets[e]*this.fontSize,a,this.fontSize/15),g+=i}else g+=i;this._removeShadow(t)}},_getFontDeclaration:function(t,i){var r=t||this;return[e.isLikelyNode?r.fontWeight:r.fontStyle,e.isLikelyNode?r.fontStyle:r.fontWeight,i?"200px":r.fontSize+"px",e.isLikelyNode?'"'+r.fontFamily+'"':r.fontFamily].join(" ")},render:function(t){this.visible&&(this.canvas&&this.canvas.skipOffscreen&&!this.group&&!this.isOnScreen()||(this._shouldClearDimensionCache()&&this.initDimensions(),this.callSuper("render",t)))},_splitTextIntoLines:function(t){for(var i=t.split(this._reNewline),r=new Array(i.length),n=["\n"],s=[],o=0;o-1&&(t.underline=!0),t.textDecoration.indexOf("line-through")>-1&&(t.linethrough=!0),t.textDecoration.indexOf("overline")>-1&&(t.overline=!0),delete t.textDecoration)}fabric.IText=fabric.util.createClass(fabric.Text,fabric.Observable,{type:"i-text",selectionStart:0,selectionEnd:0,selectionColor:"rgba(17,119,255,0.3)",isEditing:!1,editable:!0,editingBorderColor:"rgba(102,153,255,0.25)",cursorWidth:2,cursorColor:"#333",cursorDelay:1e3,cursorDuration:600,caching:!0,_reSpace:/\s|\n/,_currentCursorOpacity:0,_selectionDirection:null,_abortCursorAnimation:!1,__widthOfSpace:[],inCompositionMode:!1,initialize:function(t,e){this.callSuper("initialize",t,e),this.initBehavior()},setSelectionStart:function(t){t=Math.max(t,0),this._updateAndFire("selectionStart",t)},setSelectionEnd:function(t){t=Math.min(t,this.text.length),this._updateAndFire("selectionEnd",t)},_updateAndFire:function(t,e){this[t]!==e&&(this._fireSelectionChanged(),this[t]=e),this._updateTextarea()},_fireSelectionChanged:function(){this.fire("selection:changed"),this.canvas&&this.canvas.fire("text:selection:changed",{target:this})},initDimensions:function(){this.isEditing&&this.initDelayedCursor(),this.clearContextTop(),this.callSuper("initDimensions")},render:function(t){this.clearContextTop(),this.callSuper("render",t),this.cursorOffsetCache={},this.renderCursorOrSelection()},_render:function(t){this.callSuper("_render",t)},clearContextTop:function(t){if(this.isEditing&&this.canvas&&this.canvas.contextTop){var e=this.canvas.contextTop,i=this.canvas.viewportTransform;e.save(),e.transform(i[0],i[1],i[2],i[3],i[4],i[5]),this.transform(e),this.transformMatrix&&e.transform.apply(e,this.transformMatrix),this._clearTextArea(e),t||e.restore()}},renderCursorOrSelection:function(){if(this.isEditing&&this.canvas){var t,e=this._getCursorBoundaries();this.canvas&&this.canvas.contextTop?(t=this.canvas.contextTop,this.clearContextTop(!0)):(t=this.canvas.contextContainer).save(),this.selectionStart===this.selectionEnd?this.renderCursor(e,t):this.renderSelection(e,t),t.restore()}},_clearTextArea:function(t){var e=this.width+4,i=this.height+4;t.clearRect(-e/2,-i/2,e,i)},_getCursorBoundaries:function(t){void 0===t&&(t=this.selectionStart);var e=this._getLeftOffset(),i=this._getTopOffset(),r=this._getCursorBoundariesOffsets(t);return{left:e,top:i,leftOffset:r.left,topOffset:r.top}},_getCursorBoundariesOffsets:function(t){if(this.cursorOffsetCache&&"top"in this.cursorOffsetCache)return this.cursorOffsetCache;for(var e,i,r=0,n=0,s=this.get2DCursorLocation(t),o=0;o0?n:0)},this.cursorOffsetCache=i,this.cursorOffsetCache},renderCursor:function(t,e){var i=this.get2DCursorLocation(),r=i.lineIndex,n=i.charIndex>0?i.charIndex-1:0,s=this.getValueOfPropertyAt(r,n,"fontSize"),o=this.scaleX*this.canvas.getZoom(),a=this.cursorWidth/o,h=t.topOffset;h+=(1-this._fontSizeFraction)*this.getHeightOfLine(r)/this.lineHeight-s*(1-this._fontSizeFraction),this.inCompositionMode&&this.renderSelection(t,e),e.fillStyle=this.getValueOfPropertyAt(r,n,"fill"),e.globalAlpha=this.__isMousedown?1:this._currentCursorOpacity,e.fillRect(t.left+t.leftOffset-a/2,h+t.top,a,s)},renderSelection:function(t,e){for(var i=this.inCompositionMode?this.hiddenTextarea.selectionStart:this.selectionStart,r=this.inCompositionMode?this.hiddenTextarea.selectionEnd:this.selectionEnd,n=-1!==this.textAlign.indexOf("justify"),s=this.get2DCursorLocation(i),o=this.get2DCursorLocation(r),a=s.lineIndex,h=o.lineIndex,c=s.charIndex<0?0:s.charIndex,l=o.charIndex<0?0:o.charIndex,u=a;u<=h;u++){var f=this._getLineLeftOffset(u)||0,d=this.getHeightOfLine(u),g=0,p=0,v=0;u===a&&(p=this.__charBounds[a][c].left),u>=a&&u1)&&(d/=this.lineHeight),this.inCompositionMode?(e.fillStyle=this.compositionColor||"black",e.fillRect(t.left+f+p,t.top+t.topOffset+d,v-p,1)):(e.fillStyle=this.selectionColor,e.fillRect(t.left+f+p,t.top+t.topOffset,v-p,d)),t.topOffset+=g}},getCurrentCharFontSize:function(){var t=this._getCurrentCharIndex();return this.getValueOfPropertyAt(t.l,t.c,"fontSize")},getCurrentCharColor:function(){var t=this._getCurrentCharIndex();return this.getValueOfPropertyAt(t.l,t.c,"fill")},_getCurrentCharIndex:function(){var t=this.get2DCursorLocation(this.selectionStart,!0),e=t.charIndex>0?t.charIndex-1:0;return{l:t.lineIndex,c:e}}}),fabric.IText.fromObject=function(e,i){if(t(e),e.styles)for(var r in e.styles)for(var n in e.styles[r])t(e.styles[r][n]);fabric.Object._fromObject("IText",e,i,"text")}}(),function(){var t=fabric.util.object.clone;fabric.util.object.extend(fabric.IText.prototype,{initBehavior:function(){this.initAddedHandler(),this.initRemovedHandler(),this.initCursorSelectionHandlers(),this.initDoubleClickSimulation(),this.mouseMoveHandler=this.mouseMoveHandler.bind(this)},onDeselect:function(t){this.isEditing&&this.exitEditing(),this.selected=!1,fabric.Object.prototype.onDeselect.call(this,t)},initAddedHandler:function(){var t=this;this.on("added",function(){var e=t.canvas;e&&(e._hasITextHandlers||(e._hasITextHandlers=!0,t._initCanvasHandlers(e)),e._iTextInstances=e._iTextInstances||[],e._iTextInstances.push(t))})},initRemovedHandler:function(){var t=this;this.on("removed",function(){var e=t.canvas;e&&(e._iTextInstances=e._iTextInstances||[],fabric.util.removeFromArray(e._iTextInstances,t),0===e._iTextInstances.length&&(e._hasITextHandlers=!1,t._removeCanvasHandlers(e)))})},_initCanvasHandlers:function(t){t._mouseUpITextHandler=function(){t._iTextInstances&&t._iTextInstances.forEach(function(t){t.__isMousedown=!1})}.bind(this),t.on("mouse:up",t._mouseUpITextHandler)},_removeCanvasHandlers:function(t){t.off("mouse:up",t._mouseUpITextHandler)},_tick:function(){this._currentTickState=this._animateCursor(this,1,this.cursorDuration,"_onTickComplete")},_animateCursor:function(t,e,i,r){var n;return n={isAborted:!1,abort:function(){this.isAborted=!0}},t.animate("_currentCursorOpacity",e,{duration:i,onComplete:function(){n.isAborted||t[r]()},onChange:function(){t.canvas&&t.selectionStart===t.selectionEnd&&t.renderCursorOrSelection()},abort:function(){return n.isAborted}}),n},_onTickComplete:function(){var t=this;this._cursorTimeout1&&clearTimeout(this._cursorTimeout1),this._cursorTimeout1=setTimeout(function(){t._currentTickCompleteState=t._animateCursor(t,0,this.cursorDuration/2,"_tick")},100)},initDelayedCursor:function(t){var e=this,i=t?0:this.cursorDelay;this.abortCursorAnimation(),this._currentCursorOpacity=1,this._cursorTimeout2=setTimeout(function(){e._tick()},i)},abortCursorAnimation:function(){var t=this._currentTickState||this._currentTickCompleteState,e=this.canvas;this._currentTickState&&this._currentTickState.abort(),this._currentTickCompleteState&&this._currentTickCompleteState.abort(),clearTimeout(this._cursorTimeout1),clearTimeout(this._cursorTimeout2),this._currentCursorOpacity=0,t&&e&&e.clearContext(e.contextTop||e.contextContainer)},selectAll:function(){return this.selectionStart=0,this.selectionEnd=this._text.length,this._fireSelectionChanged(),this._updateTextarea(),this},getSelectedText:function(){return this._text.slice(this.selectionStart,this.selectionEnd).join("")},findWordBoundaryLeft:function(t){var e=0,i=t-1;if(this._reSpace.test(this._text[i]))for(;this._reSpace.test(this._text[i]);)e++,i--;for(;/\S/.test(this._text[i])&&i>-1;)e++,i--;return t-e},findWordBoundaryRight:function(t){var e=0,i=t;if(this._reSpace.test(this._text[i]))for(;this._reSpace.test(this._text[i]);)e++,i++;for(;/\S/.test(this._text[i])&&i-1;)e++,i--;return t-e},findLineBoundaryRight:function(t){for(var e=0,i=t;!/\n/.test(this._text[i])&&i0&&ithis.__selectionStartOnMouseDown?(this.selectionStart=this.__selectionStartOnMouseDown,this.selectionEnd=e):(this.selectionStart=e,this.selectionEnd=this.__selectionStartOnMouseDown),this.selectionStart===i&&this.selectionEnd===r||(this.restartCursorIfNeeded(),this._fireSelectionChanged(),this._updateTextarea(),this.renderCursorOrSelection()))}},_setEditingProps:function(){this.hoverCursor="text",this.canvas&&(this.canvas.defaultCursor=this.canvas.moveCursor="text"),this.borderColor=this.editingBorderColor,this.hasControls=this.selectable=!1,this.lockMovementX=this.lockMovementY=!0},fromStringToGraphemeSelection:function(t,e,i){var r=i.slice(0,t),n=fabric.util.string.graphemeSplit(r).length;if(t===e)return{selectionStart:n,selectionEnd:n};var s=i.slice(t,e);return{selectionStart:n,selectionEnd:n+fabric.util.string.graphemeSplit(s).length}},fromGraphemeToStringSelection:function(t,e,i){var r=i.slice(0,t).join("").length;return t===e?{selectionStart:r,selectionEnd:r}:{selectionStart:r,selectionEnd:r+i.slice(t,e).join("").length}},_updateTextarea:function(){if(this.cursorOffsetCache={},this.hiddenTextarea){if(!this.inCompositionMode){var t=this.fromGraphemeToStringSelection(this.selectionStart,this.selectionEnd,this._text);this.hiddenTextarea.selectionStart=t.selectionStart,this.hiddenTextarea.selectionEnd=t.selectionEnd}this.updateTextareaPosition()}},updateFromTextArea:function(){if(this.hiddenTextarea){this.cursorOffsetCache={},this.text=this.hiddenTextarea.value,this._shouldClearDimensionCache()&&(this.initDimensions(),this.setCoords());var t=this.fromStringToGraphemeSelection(this.hiddenTextarea.selectionStart,this.hiddenTextarea.selectionEnd,this.hiddenTextarea.value);this.selectionEnd=this.selectionStart=t.selectionEnd,this.inCompositionMode||(this.selectionStart=t.selectionStart),this.updateTextareaPosition()}},updateTextareaPosition:function(){if(this.selectionStart===this.selectionEnd){var t=this._calcTextareaPosition();this.hiddenTextarea.style.left=t.left,this.hiddenTextarea.style.top=t.top}},_calcTextareaPosition:function(){if(!this.canvas)return{x:1,y:1};var t=this.inCompositionMode?this.compositionStart:this.selectionStart,e=this._getCursorBoundaries(t),i=this.get2DCursorLocation(t),r=i.lineIndex,n=i.charIndex,s=this.getValueOfPropertyAt(r,n,"fontSize")*this.lineHeight,o=e.leftOffset,a=this.calcTransformMatrix(),h={x:e.left+o,y:e.top+e.topOffset+s},c=this.canvas.upperCanvasEl,l=c.width-s,u=c.height-s;return h=fabric.util.transformPoint(h,a),(h=fabric.util.transformPoint(h,this.canvas.viewportTransform)).x<0&&(h.x=0),h.x>l&&(h.x=l),h.y<0&&(h.y=0),h.y>u&&(h.y=u),h.x+=this.canvas._offset.left,h.y+=this.canvas._offset.top,{left:h.x+"px",top:h.y+"px",fontSize:s+"px",charHeight:s}},_saveEditingProps:function(){this._savedProps={hasControls:this.hasControls,borderColor:this.borderColor,lockMovementX:this.lockMovementX,lockMovementY:this.lockMovementY,hoverCursor:this.hoverCursor,defaultCursor:this.canvas&&this.canvas.defaultCursor,moveCursor:this.canvas&&this.canvas.moveCursor}},_restoreEditingProps:function(){this._savedProps&&(this.hoverCursor=this._savedProps.overCursor,this.hasControls=this._savedProps.hasControls,this.borderColor=this._savedProps.borderColor,this.lockMovementX=this._savedProps.lockMovementX,this.lockMovementY=this._savedProps.lockMovementY,this.canvas&&(this.canvas.defaultCursor=this._savedProps.defaultCursor,this.canvas.moveCursor=this._savedProps.moveCursor))},exitEditing:function(){var t=this._textBeforeEdit!==this.text;return this.selected=!1,this.isEditing=!1,this.selectable=!0,this.selectionEnd=this.selectionStart,this.hiddenTextarea&&(this.hiddenTextarea.blur&&this.hiddenTextarea.blur(),this.canvas&&this.hiddenTextarea.parentNode.removeChild(this.hiddenTextarea),this.hiddenTextarea=null),this.abortCursorAnimation(),this._restoreEditingProps(),this._currentCursorOpacity=0,this._shouldClearDimensionCache()&&(this.initDimensions(),this.setCoords()),this.fire("editing:exited"),t&&this.fire("modified"),this.canvas&&(this.canvas.off("mouse:move",this.mouseMoveHandler),this.canvas.fire("text:editing:exited",{target:this}),t&&this.canvas.fire("object:modified",{target:this})),this},_removeExtraneousStyles:function(){for(var t in this.styles)this._textLines[t]||delete this.styles[t]},removeStyleFromTo:function(t,e){var i,r,n=this.get2DCursorLocation(t,!0),s=this.get2DCursorLocation(e,!0),o=n.lineIndex,a=n.charIndex,h=s.lineIndex,c=s.charIndex;if(o!==h){if(this.styles[o])for(i=a;i=c&&(r[l-f]=r[u],delete r[u])}},shiftLineStyles:function(e,i){var r=t(this.styles);for(var n in this.styles){var s=parseInt(n,10);s>e&&(this.styles[s+i]=r[s],r[s-i]||delete this.styles[s])}},restartCursorIfNeeded:function(){this._currentTickState&&!this._currentTickState.isAborted&&this._currentTickCompleteState&&!this._currentTickCompleteState.isAborted||this.initDelayedCursor()},insertNewlineStyleObject:function(e,i,r,n){var s,o={},a=!1;r||(r=1),this.shiftLineStyles(e,r),this.styles[e]&&(s=this.styles[e][0===i?i:i-1]);for(var h in this.styles[e]){var c=parseInt(h,10);c>=i&&(a=!0,o[c-i]=this.styles[e][h],delete this.styles[e][h])}for(a?this.styles[e+r]=o:delete this.styles[e+r];r>1;)r--,n&&n[r]?this.styles[e+r]={0:t(n[r])}:s?this.styles[e+r]={0:t(s)}:delete this.styles[e+r];this._forceClearCache=!0},insertCharStyleObject:function(e,i,r,n){this.styles||(this.styles={});var s=this.styles[e],o=s?t(s):{};r||(r=1);for(var a in o){var h=parseInt(a,10);h>=i&&(s[h+r]=o[h],o[h-r]||delete s[h])}if(this._forceClearCache=!0,n)for(;r--;)Object.keys(n[r]).length&&(this.styles[e]||(this.styles[e]={}),this.styles[e][i+r]=t(n[r]));else if(s)for(var c=s[i?i-1:1];c&&r--;)this.styles[e][i+r]=t(c)},insertNewStyleBlock:function(t,e,i){for(var r=this.get2DCursorLocation(e,!0),n=[0],s=0,o=0;o0&&(this.insertCharStyleObject(r.lineIndex,r.charIndex,n[0],i),i=i&&i.slice(n[0]+1)),s&&this.insertNewlineStyleObject(r.lineIndex,r.charIndex+n[0],s);for(o=1;o0&&this.insertCharStyleObject(r.lineIndex+o,0,n[o],i)},setSelectionStartEndWithShift:function(t,e,i){i<=t?(e===t?this._selectionDirection="left":"right"===this._selectionDirection&&(this._selectionDirection="left",this.selectionEnd=t),this.selectionStart=i):i>t&&it?this.selectionStart=t:this.selectionStart<0&&(this.selectionStart=0),this.selectionEnd>t?this.selectionEnd=t:this.selectionEnd<0&&(this.selectionEnd=0)}})}(),fabric.util.object.extend(fabric.IText.prototype,{initDoubleClickSimulation:function(){this.__lastClickTime=+new Date,this.__lastLastClickTime=+new Date,this.__lastPointer={},this.on("mousedown",this.onMouseDown.bind(this))},onMouseDown:function(t){this.__newClickTime=+new Date;var e=this.canvas.getPointer(t.e);this.isTripleClick(e,t.e)&&(this.fire("tripleclick",t),this._stopEvent(t.e)),this.__lastLastClickTime=this.__lastClickTime,this.__lastClickTime=this.__newClickTime,this.__lastPointer=e,this.__lastIsEditing=this.isEditing,this.__lastSelected=this.selected},isTripleClick:function(t){return this.__newClickTime-this.__lastClickTime<500&&this.__lastClickTime-this.__lastLastClickTime<500&&this.__lastPointer.x===t.x&&this.__lastPointer.y===t.y},_stopEvent:function(t){t.preventDefault&&t.preventDefault(),t.stopPropagation&&t.stopPropagation()},initCursorSelectionHandlers:function(){this.initMousedownHandler(),this.initMouseupHandler(),this.initClicks()},initClicks:function(){this.on("mousedblclick",function(t){this.selectWord(this.getSelectionStartFromPointer(t.e))}),this.on("tripleclick",function(t){this.selectLine(this.getSelectionStartFromPointer(t.e))})},initMousedownHandler:function(){this.on("mousedown",function(t){if(this.editable&&(!t.e.button||1===t.e.button)){var e=this.canvas.getPointer(t.e);this.__mousedownX=e.x,this.__mousedownY=e.y,this.__isMousedown=!0,this.selected&&this.setCursorByClick(t.e),this.isEditing&&(this.__selectionStartOnMouseDown=this.selectionStart,this.selectionStart===this.selectionEnd&&this.abortCursorAnimation(),this.renderCursorOrSelection())}})},_isObjectMoved:function(t){var e=this.canvas.getPointer(t);return this.__mousedownX!==e.x||this.__mousedownY!==e.y},initMouseupHandler:function(){this.on("mouseup",function(t){this.__isMousedown=!1,!this.editable||this._isObjectMoved(t.e)||t.e.button&&1!==t.e.button||(this.__lastSelected&&!this.__corner&&(this.enterEditing(t.e),this.selectionStart===this.selectionEnd?this.initDelayedCursor(!0):this.renderCursorOrSelection()),this.selected=!0)})},setCursorByClick:function(t){var e=this.getSelectionStartFromPointer(t),i=this.selectionStart,r=this.selectionEnd;t.shiftKey?this.setSelectionStartEndWithShift(i,r,e):(this.selectionStart=e,this.selectionEnd=e),this.isEditing&&(this._fireSelectionChanged(),this._updateTextarea())},getSelectionStartFromPointer:function(t){for(var e,i=this.getLocalPointer(t),r=0,n=0,s=0,o=0,a=0,h=0,c=this._textLines.length;h0&&(o+=this._textLines[h-1].length+1);n=this._getLineLeftOffset(a)*this.scaleX;for(var l=0,u=(e=this._textLines[a]).length;ls||o<0?0:1);return this.flipX&&(a=n-a),a>this._text.length&&(a=this._text.length),a}}),fabric.util.object.extend(fabric.IText.prototype,{initHiddenTextarea:function(){this.hiddenTextarea=fabric.document.createElement("textarea"),this.hiddenTextarea.setAttribute("autocapitalize","off"),this.hiddenTextarea.setAttribute("autocorrect","off"),this.hiddenTextarea.setAttribute("autocomplete","off"),this.hiddenTextarea.setAttribute("spellcheck","false"),this.hiddenTextarea.setAttribute("data-fabric-hiddentextarea",""),this.hiddenTextarea.setAttribute("wrap","off");var t=this._calcTextareaPosition();this.hiddenTextarea.style.cssText="position: absolute; top: "+t.top+"; left: "+t.left+"; z-index: -999; opacity: 0; width: 1px; height: 1px; font-size: 1px; line-height: 1px; paddingï½°top: "+t.fontSize+";",fabric.document.body.appendChild(this.hiddenTextarea),fabric.util.addListener(this.hiddenTextarea,"keydown",this.onKeyDown.bind(this)),fabric.util.addListener(this.hiddenTextarea,"keyup",this.onKeyUp.bind(this)),fabric.util.addListener(this.hiddenTextarea,"input",this.onInput.bind(this)),fabric.util.addListener(this.hiddenTextarea,"copy",this.copy.bind(this)),fabric.util.addListener(this.hiddenTextarea,"cut",this.copy.bind(this)),fabric.util.addListener(this.hiddenTextarea,"paste",this.paste.bind(this)),fabric.util.addListener(this.hiddenTextarea,"compositionstart",this.onCompositionStart.bind(this)),fabric.util.addListener(this.hiddenTextarea,"compositionupdate",this.onCompositionUpdate.bind(this)),fabric.util.addListener(this.hiddenTextarea,"compositionend",this.onCompositionEnd.bind(this)),!this._clickHandlerInitialized&&this.canvas&&(fabric.util.addListener(this.canvas.upperCanvasEl,"click",this.onClick.bind(this)),this._clickHandlerInitialized=!0)},keysMap:{9:"exitEditing",27:"exitEditing",33:"moveCursorUp",34:"moveCursorDown",35:"moveCursorRight",36:"moveCursorLeft",37:"moveCursorLeft",38:"moveCursorUp",39:"moveCursorRight",40:"moveCursorDown"},ctrlKeysMapUp:{67:"copy",88:"cut"},ctrlKeysMapDown:{65:"selectAll"},onClick:function(){this.hiddenTextarea&&this.hiddenTextarea.focus()},onKeyDown:function(t){if(this.isEditing&&!this.inCompositionMode){if(t.keyCode in this.keysMap)this[this.keysMap[t.keyCode]](t);else{if(!(t.keyCode in this.ctrlKeysMapDown&&(t.ctrlKey||t.metaKey)))return;this[this.ctrlKeysMapDown[t.keyCode]](t)}t.stopImmediatePropagation(),t.preventDefault(),t.keyCode>=33&&t.keyCode<=40?(this.clearContextTop(),this.renderCursorOrSelection()):this.canvas&&this.canvas.requestRenderAll()}},onKeyUp:function(t){!this.isEditing||this._copyDone||this.inCompositionMode?this._copyDone=!1:t.keyCode in this.ctrlKeysMapUp&&(t.ctrlKey||t.metaKey)&&(this[this.ctrlKeysMapUp[t.keyCode]](t),t.stopImmediatePropagation(),t.preventDefault(),this.canvas&&this.canvas.requestRenderAll())},onInput:function(t){var e=this.fromPaste;if(this.fromPaste=!1,t&&t.stopPropagation(),this.isEditing){var i,r,n=this._splitTextIntoLines(this.hiddenTextarea.value).graphemeText,s=this._text.length,o=n.length,a=o-s;if(""===this.hiddenTextarea.value)return this.styles={},this.updateFromTextArea(),this.fire("changed"),void(this.canvas&&(this.canvas.fire("text:changed",{target:this}),this.canvas.requestRenderAll()));var h=this.fromStringToGraphemeSelection(this.hiddenTextarea.selectionStart,this.hiddenTextarea.selectionEnd,this.hiddenTextarea.value),c=this.selectionStart>h.selectionStart;this.selectionStart!==this.selectionEnd?(i=this._text.slice(this.selectionStart,this.selectionEnd),a+=this.selectionEnd-this.selectionStart):o0&&(r+=(i=this.__charBounds[t][e-1]).left+i.width),r},getDownCursorOffset:function(t,e){var i=this._getSelectionForOffset(t,e),r=this.get2DCursorLocation(i),n=r.lineIndex;if(n===this._textLines.length-1||t.metaKey||34===t.keyCode)return this._text.length-i;var s=r.charIndex,o=this._getWidthBeforeCursor(n,s),a=this._getIndexOnLine(n+1,o);return this._textLines[n].slice(s).length+a+2},_getSelectionForOffset:function(t,e){return t.shiftKey&&this.selectionStart!==this.selectionEnd&&e?this.selectionEnd:this.selectionStart},getUpCursorOffset:function(t,e){var i=this._getSelectionForOffset(t,e),r=this.get2DCursorLocation(i),n=r.lineIndex;if(0===n||t.metaKey||33===t.keyCode)return-i;var s=r.charIndex,o=this._getWidthBeforeCursor(n,s),a=this._getIndexOnLine(n-1,o),h=this._textLines[n].slice(0,s);return-this._textLines[n-1].length+a-h.length},_getIndexOnLine:function(t,e){for(var i,r,n=this._textLines[t],s=this._getLineLeftOffset(t),o=0,a=0,h=n.length;ae){r=!0;var c=s-i,l=s,u=Math.abs(c-e);o=Math.abs(l-e)=this._text.length&&this.selectionEnd>=this._text.length||this._moveCursorUpOrDown("Down",t)},moveCursorUp:function(t){0===this.selectionStart&&0===this.selectionEnd||this._moveCursorUpOrDown("Up",t)},_moveCursorUpOrDown:function(t,e){var i=this["get"+t+"CursorOffset"](e,"right"===this._selectionDirection);e.shiftKey?this.moveCursorWithShift(i):this.moveCursorWithoutShift(i),0!==i&&(this.setSelectionInBoundaries(),this.abortCursorAnimation(),this._currentCursorOpacity=1,this.initDelayedCursor(),this._fireSelectionChanged(),this._updateTextarea())},moveCursorWithShift:function(t){var e="left"===this._selectionDirection?this.selectionStart+t:this.selectionEnd+t;return this.setSelectionStartEndWithShift(this.selectionStart,this.selectionEnd,e),0!==t},moveCursorWithoutShift:function(t){return t<0?(this.selectionStart+=t,this.selectionEnd=this.selectionStart):(this.selectionEnd+=t,this.selectionStart=this.selectionEnd),0!==t},moveCursorLeft:function(t){0===this.selectionStart&&0===this.selectionEnd||this._moveCursorLeftOrRight("Left",t)},_move:function(t,e,i){var r;if(t.altKey)r=this["findWordBoundary"+i](this[e]);else{if(!t.metaKey&&35!==t.keyCode&&36!==t.keyCode)return this[e]+="Left"===i?-1:1,!0;r=this["findLineBoundary"+i](this[e])}if(void 0!==typeof r&&this[e]!==r)return this[e]=r,!0},_moveLeft:function(t,e){return this._move(t,e,"Left")},_moveRight:function(t,e){return this._move(t,e,"Right")},moveCursorLeftWithoutShift:function(t){var e=!0;return this._selectionDirection="left",this.selectionEnd===this.selectionStart&&0!==this.selectionStart&&(e=this._moveLeft(t,"selectionStart")),this.selectionEnd=this.selectionStart,e},moveCursorLeftWithShift:function(t){return"right"===this._selectionDirection&&this.selectionStart!==this.selectionEnd?this._moveLeft(t,"selectionEnd"):0!==this.selectionStart?(this._selectionDirection="left",this._moveLeft(t,"selectionStart")):void 0},moveCursorRight:function(t){this.selectionStart>=this._text.length&&this.selectionEnd>=this._text.length||this._moveCursorLeftOrRight("Right",t)},_moveCursorLeftOrRight:function(t,e){var i="moveCursor"+t+"With";this._currentCursorOpacity=1,e.shiftKey?i+="Shift":i+="outShift",this[i](e)&&(this.abortCursorAnimation(),this.initDelayedCursor(),this._fireSelectionChanged(),this._updateTextarea())},moveCursorRightWithShift:function(t){return"left"===this._selectionDirection&&this.selectionStart!==this.selectionEnd?this._moveRight(t,"selectionStart"):this.selectionEnd!==this._text.length?(this._selectionDirection="right",this._moveRight(t,"selectionEnd")):void 0},moveCursorRightWithoutShift:function(t){var e=!0;return this._selectionDirection="right",this.selectionStart===this.selectionEnd?(e=this._moveRight(t,"selectionStart"),this.selectionEnd=this.selectionStart):this.selectionStart=this.selectionEnd,e},removeChars:function(t){this.selectionStart===this.selectionEnd?this._removeCharsNearCursor(t):this._removeCharsFromTo(this.selectionStart,this.selectionEnd),this.set("dirty",!0),this.setSelectionEnd(this.selectionStart),this._removeExtraneousStyles(),this._shouldClearDimensionCache()&&(this.initDimensions(),this.setCoords()),this.canvas&&this.canvas.requestRenderAll(),this.fire("changed"),this.canvas&&this.canvas.fire("text:changed",{target:this})},_removeCharsNearCursor:function(t){if(0!==this.selectionStart)if(t.metaKey){var e=this.findLineBoundaryLeft(this.selectionStart);this._removeCharsFromTo(e,this.selectionStart),this.setSelectionStart(e)}else if(t.altKey){var i=this.findWordBoundaryLeft(this.selectionStart);this._removeCharsFromTo(i,this.selectionStart),this.setSelectionStart(i)}else this._removeSingleCharAndStyle(this.selectionStart),this.setSelectionStart(this.selectionStart-1)}}),function(){var t=fabric.util.toFixed,e=fabric.Object.NUM_FRACTION_DIGITS;fabric.util.object.extend(fabric.Text.prototype,{toSVG:function(t){var e=this._createBaseSVGMarkup(),i=this._getSVGLeftTopOffsets(),r=this._getSVGTextAndBg(i.textTop,i.textLeft);return this._wrapSVGTextAndBg(e,r),t?t(e.join("")):e.join("")},_getSVGLeftTopOffsets:function(){return{textLeft:-this.width/2,textTop:-this.height/2,lineTop:this.getHeightOfLine(0)}},_wrapSVGTextAndBg:function(t,e){var i=this.getSvgFilter(),r=""===i?"":' style="'+i+'"',n=this.getSvgTextDecoration(this);t.push("\t\n",e.textBgRects.join(""),'\t\t\n",e.textSpans.join(""),"\t\t\n","\t\n")},_getSVGTextAndBg:function(t,e){var i,r=[],n=[],s=t;this._setSVGBg(n);for(var o=0,a=this._textLines.length;o",fabric.util.string.escapeXml(i),"\n"].join("")},_setSVGTextLineText:function(t,e,i,r){var n,s,o,a,h,c=this.getHeightOfLine(e),l=-1!==this.textAlign.indexOf("justify"),u="",f=0,d=this._textLines[e];r+=c*(1-this._fontSizeFraction)/this.lineHeight;for(var g=0,p=d.length-1;g<=p;g++)h=g===p||this.charSpacing,u+=d[g],o=this.__charBounds[e][g],0===f?(i+=o.kernedWidth-o.width,f+=o.width):f+=o.kernedWidth,l&&!h&&this._reSpaceAndTab.test(d[g])&&(h=!0),h||(n=n||this.getCompleteStyleDeclaration(e,g),s=this.getCompleteStyleDeclaration(e,g+1),h=this._hasStyleChangedForSvg(n,s)),h&&(a=this._getStyleDeclaration(e,g)||{},t.push(this._createTextCharSpan(u,a,i,r)),u="",n=s,i+=f,f=0)},_pushTextBgRect:function(i,r,n,s,o,a){i.push("\t\t\n')},_setSVGTextLineBg:function(t,e,i,r){for(var n,s,o=this._textLines[e],a=this.getHeightOfLine(e)/this.lineHeight,h=0,c=0,l=this.getValueOfPropertyAt(e,0,"textBackgroundColor"),u=0,f=o.length;uthis.width&&this._set("width",this.dynamicMinWidth),-1!==this.textAlign.indexOf("justify")&&this.enlargeSpaces(),this.height=this.calcTextHeight(),this.saveState({propertySet:"_dimensionAffectingProps"}))},_generateStyleMap:function(t){for(var e=0,i=0,r=0,n={},s=0;s0?(i=0,r++,e++):this._reSpaceAndTab.test(t.graphemeText[r])&&s>0&&(i++,r++),n[s]={line:e,offset:i},r+=t.graphemeLines[s].length,i+=t.graphemeLines[s].length;return n},styleHas:function(t,i){if(this._styleMap&&!this.isWrapping){var r=this._styleMap[i];r&&(i=r.line)}return e.Text.prototype.styleHas.call(this,t,i)},_getStyleDeclaration:function(t,e){if(this._styleMap&&!this.isWrapping){var i=this._styleMap[t];if(!i)return null;t=i.line,e=i.offset+e}return this.callSuper("_getStyleDeclaration",t,e)},_setStyleDeclaration:function(t,e,i){var r=this._styleMap[t];t=r.line,e=r.offset+e,this.styles[t][e]=i},_deleteStyleDeclaration:function(t,e){var i=this._styleMap[t];t=i.line,e=i.offset+e,delete this.styles[t][e]},_getLineStyle:function(t){var e=this._styleMap[t];return this.styles[e.line]},_setLineStyle:function(t,e){var i=this._styleMap[t];this.styles[i.line]=e},_deleteLineStyle:function(t){var e=this._styleMap[t];delete this.styles[e.line]},_wrapText:function(t,e){var i,r=[];for(this.isWrapping=!0,i=0;i=r&&!d&&(s.push(o),o=[],n=l,d=!0),d||o.push(" "),o=o.concat(h),u=this._measureWord([" "],i,c),c++,d=!1,l>f&&(f=l);return p&&s.push(o),f>this.dynamicMinWidth&&(this.dynamicMinWidth=f-g),s},isEndOfWrapping:function(t){return!this._styleMap[t+1]||this._styleMap[t+1].line!==this._styleMap[t].line},_splitTextIntoLines:function(t){for(var i=e.Text.prototype._splitTextIntoLines.call(this,t),r=this._wrapText(i.lines,this.width),n=new Array(r.length),s=0;s=h.getMinWidth()?(h.set("width",l),!0):void 0},fabric.util.object.extend(fabric.Textbox.prototype,{_removeExtraneousStyles:function(){for(var t in this._styleMap)this._textLines[t]||delete this.styles[this._styleMap[t].line]}})}(); \ No newline at end of file diff --git a/dist/fabric.min.js.gz b/dist/fabric.min.js.gz index ba3a13bfac86b3b601f53383d51536fd699d2577..beccb6a57ad13abe9ba2224a78cdde0b12066e3d 100644 GIT binary patch literal 78630 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 v-h92+LLjJsKx^5>3P9Tnye& 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 literal 77542 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

avZaIq>RCn^L?>*`C-hyu{{C{}1Q8MfCwkJ@c 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 diff --git a/dist/fabric.require.js b/dist/fabric.require.js index bcac88b8..eb93fa04 100644 --- a/dist/fabric.require.js +++ b/dist/fabric.require.js @@ -1,5 +1,5 @@ var fabric = fabric || { - version: "2.0.0-beta7" + version: "2.0.0-rc.1" }; if (typeof exports !== "undefined") { @@ -16,13 +16,14 @@ if (typeof document !== "undefined" && typeof window !== "undefined") { } }); fabric.window = fabric.document.defaultView; + DOMParser = require("xmldom").DOMParser; } fabric.isTouchSupported = "ontouchstart" in fabric.window; fabric.isLikelyNode = typeof Buffer !== "undefined" && typeof window === "undefined"; -fabric.SHARED_ATTRIBUTES = [ "display", "transform", "fill", "fill-opacity", "fill-rule", "opacity", "stroke", "stroke-dasharray", "stroke-linecap", "stroke-linejoin", "stroke-miterlimit", "stroke-opacity", "stroke-width", "id", "instantiated_by_use" ]; +fabric.SHARED_ATTRIBUTES = [ "display", "transform", "fill", "fill-opacity", "fill-rule", "opacity", "stroke", "stroke-dasharray", "stroke-linecap", "stroke-linejoin", "stroke-miterlimit", "stroke-opacity", "stroke-width", "id", "paint-order", "instantiated_by_use" ]; fabric.DPI = 96; @@ -48,6 +49,8 @@ fabric.enableGLFiltering = true; fabric.devicePixelRatio = fabric.window.devicePixelRatio || fabric.window.webkitDevicePixelRatio || fabric.window.mozDevicePixelRatio || 1; +fabric.browserShadowBlurConstant = 1; + fabric.initFilterBackend = function() { if (fabric.enableGLFiltering && fabric.isWebglSupported && fabric.isWebglSupported(fabric.textureSize)) { console.log("max texture size: " + fabric.maxTextureSize); @@ -302,7 +305,7 @@ fabric.CommonMethods = { return new fabric.Point(t[0] * p.x + t[2] * p.y + t[4], t[1] * p.x + t[3] * p.y + t[5]); }, makeBoundingBoxFromPoints: function(points) { - var xPoints = [ points[0].x, points[1].x, points[2].x, points[3].x ], minX = fabric.util.array.min(xPoints), maxX = fabric.util.array.max(xPoints), width = Math.abs(minX - maxX), yPoints = [ points[0].y, points[1].y, points[2].y, points[3].y ], minY = fabric.util.array.min(yPoints), maxY = fabric.util.array.max(yPoints), height = Math.abs(minY - maxY); + var xPoints = [ points[0].x, points[1].x, points[2].x, points[3].x ], minX = fabric.util.array.min(xPoints), maxX = fabric.util.array.max(xPoints), width = maxX - minX, yPoints = [ points[0].y, points[1].y, points[2].y, points[3].y ], minY = fabric.util.array.min(yPoints), maxY = fabric.util.array.max(yPoints), height = maxY - minY; return { left: minX, top: minY, @@ -390,10 +393,11 @@ fabric.CommonMethods = { return; } var img = fabric.util.createImage(); - img.onload = function() { + var onLoadCallback = function() { callback && callback.call(context, img); img = img.onload = img.onerror = null; }; + img.onload = onLoadCallback; img.onerror = function() { fabric.log("Error loading " + img.src); callback && callback.call(context, null, true); @@ -402,8 +406,25 @@ fabric.CommonMethods = { if (url.indexOf("data") !== 0 && crossOrigin) { img.crossOrigin = crossOrigin; } + if (url.substring(0, 14) === "data:image/svg") { + img.onload = null; + fabric.util.loadImageInDom(img, onLoadCallback); + } img.src = url; }, + loadImageInDom: function(img, onLoadCallback) { + var div = fabric.document.createElement("div"); + div.style.width = div.style.height = "1px"; + div.style.left = div.style.top = "-100%"; + div.style.position = "absolute"; + div.appendChild(img); + fabric.document.querySelector("body").appendChild(div); + img.onload = function() { + onLoadCallback(); + div.parentNode.removeChild(div); + div = null; + }; + }, enlivenObjects: function(objects, callback, namespace, reviver) { objects = objects || []; function onLoaded() { @@ -1736,6 +1757,7 @@ if (typeof console !== "undefined") { "font-size": "fontSize", "font-style": "fontStyle", "font-weight": "fontWeight", + "paint-order": "paintFirst", "stroke-dasharray": "strokeDashArray", "stroke-linecap": "strokeLineCap", "stroke-linejoin": "strokeLineJoin", @@ -1791,6 +1813,15 @@ if (typeof console !== "undefined") { } } else if (attr === "textAnchor") { value = value === "start" ? "left" : value === "end" ? "right" : "center"; + } else if (attr === "paintFirst") { + var fillIndex = value.indexOf("fill"); + var strokeIndex = value.indexOf("stroke"); + var value = "fill"; + if (fillIndex > -1 && strokeIndex > -1 && strokeIndex < fillIndex) { + value = "stroke"; + } else if (fillIndex === -1 && strokeIndex > -1) { + value = "stroke"; + } } else { parsed = isArray ? value.map(parseUnit) : parseUnit(value, fontSize); } @@ -2339,12 +2370,13 @@ fabric.ElementsParser.prototype._createObject = function(klass, el, index) { fabric.ElementsParser.prototype.createCallback = function(index, el) { var _this = this; return function(obj) { + var _options; _this.resolveGradient(obj, "fill"); _this.resolveGradient(obj, "stroke"); - obj._removeTransformMatrix(); if (obj instanceof fabric.Image) { - obj.parsePreserveAspectRatioAttribute(el); + _options = obj.parsePreserveAspectRatioAttribute(el); } + obj._removeTransformMatrix(_options); _this.reviver && _this.reviver(el, obj); _this.instances[index] = obj; _this.checkIfDone(); @@ -3660,6 +3692,7 @@ fabric.ElementsParser.prototype.checkIfDone = function() { return points; }, renderCanvas: function(ctx, objects) { + var v = this.viewportTransform; if (this.isRendering) { fabric.util.cancelAnimFrame(this.isRendering); this.isRendering = 0; @@ -3672,7 +3705,7 @@ fabric.ElementsParser.prototype.checkIfDone = function() { } this._renderBackground(ctx); ctx.save(); - ctx.transform.apply(ctx, this.viewportTransform); + ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]); this._renderObjects(ctx, objects); ctx.restore(); if (!this.controlsAboveOverlay && this.interactive) { @@ -3694,7 +3727,7 @@ fabric.ElementsParser.prototype.checkIfDone = function() { } }, _renderBackgroundOrOverlay: function(ctx, property) { - var object = this[property + "Color"]; + var object = this[property + "Color"], v; if (object) { ctx.fillStyle = object.toLive ? object.toLive(ctx, this) : object; ctx.fillRect(object.offsetX || 0, object.offsetY || 0, this.width, this.height); @@ -3702,8 +3735,9 @@ fabric.ElementsParser.prototype.checkIfDone = function() { object = this[property + "Image"]; if (object) { if (this[property + "Vpt"]) { + v = this.viewportTransform; ctx.save(); - ctx.transform.apply(ctx, this.viewportTransform); + ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]); } object.render(ctx); this[property + "Vpt"] && ctx.restore(); @@ -4044,7 +4078,12 @@ fabric.ElementsParser.prototype.checkIfDone = function() { return this.renderOnAddRemove && this.requestRenderAll(); }, dispose: function() { - this.clear(); + this._objects.length = 0; + this.backgroundImage = null; + this.overlayImage = null; + this._iTextInstances = null; + this.lowerCanvasEl = null; + this.cacheCanvasEl = null; return this; }, toString: function() { @@ -4096,6 +4135,7 @@ fabric.BaseBrush = fabric.util.createClass({ shadow: null, strokeLineCap: "round", strokeLineJoin: "round", + strokeMiterLimit: 10, strokeDashArray: null, setShadow: function(options) { this.shadow = new fabric.Shadow(options); @@ -4106,6 +4146,7 @@ fabric.BaseBrush = fabric.util.createClass({ ctx.strokeStyle = this.color; ctx.lineWidth = this.width; ctx.lineCap = this.strokeLineCap; + ctx.miterLimit = this.strokeMiterLimit; ctx.lineJoin = this.strokeLineJoin; if (this.strokeDashArray && fabric.StaticCanvas.supports("setLineDash")) { ctx.setLineDash(this.strokeDashArray); @@ -4154,6 +4195,9 @@ fabric.BaseBrush = fabric.util.createClass({ this.canvas.contextTop.moveTo(p.x, p.y); }, _addPoint: function(point) { + if (this._points.length > 1 && point.eq(this._points[this._points.length - 1])) { + return; + } this._points.push(point); }, _reset: function() { @@ -4189,8 +4233,12 @@ fabric.BaseBrush = fabric.util.createClass({ ctx.restore(); }, convertPointsToSVGPath: function(points) { - var path = [], i, width = this.width / 1e3, p1 = new fabric.Point(points[0].x, points[0].y), p2 = new fabric.Point(points[1].x, points[1].y), len = points.length; - path.push("M ", p1.x - width, " ", p1.y, " "); + var path = [], i, width = this.width / 1e3, p1 = new fabric.Point(points[0].x, points[0].y), p2 = new fabric.Point(points[1].x, points[1].y), len = points.length, multSignX, multSignY, manyPoints = len > 2; + if (manyPoints) { + multSignX = points[2].x < p2.x ? -1 : points[2].x === p2.x ? 0 : 1; + multSignY = points[2].y < p2.y ? -1 : points[2].y === p2.y ? 0 : 1; + } + path.push("M ", p1.x - multSignX * width, " ", p1.y - multSignY * width, " "); for (i = 1; i < len; i++) { if (!p1.eq(p2)) { var midPoint = p1.midPointFrom(p2); @@ -4201,7 +4249,11 @@ fabric.BaseBrush = fabric.util.createClass({ p2 = points[i + 1]; } } - path.push("L ", p1.x + width, " ", p1.y, " "); + if (manyPoints) { + multSignX = p1.x > points[i - 2].x ? 1 : p1.x === points[i - 2].x ? 0 : -1; + multSignY = p1.y > points[i - 2].y ? 1 : p1.y === points[i - 2].y ? 0 : -1; + } + path.push("L ", p1.x + multSignX * width, " ", p1.y + multSignY * width); return path; }, createPath: function(pathData) { @@ -4210,6 +4262,7 @@ fabric.BaseBrush = fabric.util.createClass({ stroke: this.color, strokeWidth: this.width, strokeLineCap: this.strokeLineCap, + strokeMiterLimit: this.strokeMiterLimit, strokeLineJoin: this.strokeLineJoin, strokeDashArray: this.strokeDashArray }); @@ -4232,11 +4285,11 @@ fabric.BaseBrush = fabric.util.createClass({ return; } var path = this.createPath(pathData); - this.canvas.add(path); - path.setCoords(); this.canvas.clearContext(this.canvas.contextTop); + this.canvas.add(path); + this.canvas.renderAll(); + path.setCoords(); this._resetShadow(); - this.canvas.requestRenderAll(); this.canvas.fire("path:created", { path: path }); @@ -4596,25 +4649,37 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, { return fabric.util.transformPoint(vptPointer, invertedM); }, isTargetTransparent: function(target, x, y) { - var ctx = this.contextCache, originalColor = target.selectionBackgroundColor; - target.hasBorders = target.transparentCorners = false; + var ctx = this.contextCache, originalColor = target.selectionBackgroundColor, v = this.viewportTransform; target.selectionBackgroundColor = ""; + this.clearContext(ctx); ctx.save(); - ctx.transform.apply(ctx, this.viewportTransform); + ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]); target.render(ctx); ctx.restore(); target === this._activeObject && target._renderControls(ctx, { hasBorders: false, transparentCorners: false + }, { + hasBorders: false }); target.selectionBackgroundColor = originalColor; var isTransparent = fabric.util.isTransparent(ctx, x, y, this.targetFindTolerance); - this.clearContext(ctx); return isTransparent; }, + _isSelectionKeyPressed: function(e) { + var selectionKeyPressed = false; + if (Object.prototype.toString.call(this.selectionKey) === "[object Array]") { + selectionKeyPressed = !!this.selectionKey.find(function(key) { + return e[key] === true; + }); + } else { + selectionKeyPressed = e[this.selectionKey]; + } + return selectionKeyPressed; + }, _shouldClearSelection: function(e, target) { var activeObjects = this.getActiveObjects(), activeObject = this._activeObject; - return !target || target && activeObject && activeObjects.length > 1 && activeObjects.indexOf(target) === -1 && activeObject !== target && !e[this.selectionKey] || target && !target.evented || target && !target.selectable && activeObject && activeObject !== target; + 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; }, _shouldCenterTransform: function(target) { if (!target) { @@ -4825,7 +4890,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, { return scaled; }, _scaleObjectEqually: function(localMouse, target, transform, _dim) { - var dist = localMouse.y + localMouse.x, lastDist = _dim.y * transform.original.scaleY / target.scaleY + _dim.x * transform.original.scaleX / target.scaleX, scaled, signX = localMouse.x / Math.abs(localMouse.x), signY = localMouse.y / Math.abs(localMouse.y); + var dist = localMouse.y + localMouse.x, lastDist = _dim.y * transform.original.scaleY / target.scaleY + _dim.x * transform.original.scaleX / target.scaleX, scaled, signX = localMouse.x < 0 ? -1 : 1, signY = localMouse.y < 0 ? -1 : 1; transform.newScaleX = signX * Math.abs(transform.original.scaleX * dist / lastDist); transform.newScaleY = signY * Math.abs(transform.original.scaleY * dist / lastDist); scaled = transform.newScaleX !== target.scaleX || transform.newScaleY !== target.scaleY; @@ -4891,7 +4956,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, { if (t.target.get("lockRotation")) { return false; } - var lastAngle = atan2(t.ey - t.top, t.ex - t.left), curAngle = atan2(y - t.top, x - t.left), angle = radiansToDegrees(curAngle - lastAngle + t.theta), hasRoated = true; + var lastAngle = atan2(t.ey - t.top, t.ex - t.left), curAngle = atan2(y - t.top, x - t.left), angle = radiansToDegrees(curAngle - lastAngle + t.theta), hasRotated = true; if (t.target.snapAngle > 0) { var snapAngle = t.target.snapAngle, snapThreshold = t.target.snapThreshold || snapAngle, rightAngleLocked = Math.ceil(angle / snapAngle) * snapAngle, leftAngleLocked = Math.floor(angle / snapAngle) * snapAngle; if (Math.abs(angle - leftAngleLocked) < snapThreshold) { @@ -4905,11 +4970,11 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, { } angle %= 360; if (t.target.angle === angle) { - hasRoated = false; + hasRotated = false; } else { t.target.angle = angle; } - return hasRoated; + return hasRotated; }, setCursor: function(value) { this.upperCanvasEl.style.cursor = value; @@ -5122,23 +5187,47 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, { } this.callSuper("_onObjectRemoved", obj); }, + _fireSelectionEvents: function(oldObjects, e) { + var somethingChanged = false, objects = this.getActiveObjects(), added = [], removed = [], opt = { + e: e + }; + oldObjects.forEach(function(oldObject) { + if (objects.indexOf(oldObject) === -1) { + somethingChanged = true; + oldObject.fire("deselected", opt); + removed.push(oldObject); + } + }); + objects.forEach(function(object) { + if (oldObjects.indexOf(object) === -1) { + somethingChanged = true; + object.fire("selected", opt); + added.push(object); + } + }); + if (oldObjects.length > 0 && objects.length > 0) { + opt.selected = added; + opt.deselected = removed; + opt.updated = added[0] || removed[0]; + opt.target = this._activeObject; + somethingChanged && this.fire("selection:updated", opt); + } else if (objects.length > 0) { + if (objects.length === 1) { + opt.target = added[0]; + this.fire("object:selected", opt); + } + opt.selected = added; + opt.target = this._activeObject; + this.fire("selection:created", opt); + } else if (oldObjects.length > 0) { + opt.deselected = removed; + this.fire("selection:cleared", opt); + } + }, setActiveObject: function(object, e) { - var currentActiveObject = this._activeObject; - if (object === currentActiveObject) { - return this; - } - if (this._setActiveObject(object, e)) { - currentActiveObject && currentActiveObject.fire("deselected", { - e: e - }); - this.fire("object:selected", { - target: object, - e: e - }); - object.fire("selected", { - e: e - }); - } + var currentActives = this.getActiveObjects(); + this._setActiveObject(object, e); + this._fireSelectionEvents(currentActives, e); return this; }, _setActiveObject: function(object, e) { @@ -5170,26 +5259,18 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, { return true; }, discardActiveObject: function(e) { - var activeObject = this._activeObject; - if (activeObject) { + var currentActives = this.getActiveObjects(); + if (currentActives.length) { this.fire("before:selection:cleared", { - target: activeObject, + target: currentActives[0], e: e }); - if (this._discardActiveObject(e)) { - this.fire("selection:cleared", { - e: e, - target: activeObject - }); - activeObject.fire("deselected", { - e: e - }); - } } + this._discardActiveObject(e); + this._fireSelectionEvents(currentActives, e); return this; }, dispose: function() { - fabric.StaticCanvas.prototype.dispose.call(this); var wrapper = this.wrapperEl; this.removeListeners(); wrapper.removeChild(this.upperCanvasEl); @@ -5199,6 +5280,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, { wrapper.parentNode.replaceChild(this.lowerCanvasEl, this.wrapperEl); } delete this.wrapperEl; + fabric.StaticCanvas.prototype.dispose.call(this); return this; }, clear: function() { @@ -5639,7 +5721,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, { } else { this._transformObject(e); } - this._handleEvent(e, "move", target ? target : null); + this._handleEvent(e, "move", this._currentTransform ? null : target); }, _fireOverOutEvents: function(target, e) { var overOpt, outOpt, hoveredTarget = this._hoveredTarget; @@ -5793,7 +5875,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, { fabric.util.object.extend(fabric.Canvas.prototype, { _shouldGroup: function(e, target) { var activeObject = this._activeObject; - return activeObject && e[this.selectionKey] && target && target.selectable && this.selection && (activeObject !== target || activeObject.type === "activeSelection"); + return activeObject && this._isSelectionKeyPressed(e) && target && target.selectable && this.selection && (activeObject !== target || activeObject.type === "activeSelection"); }, _handleGrouping: function(e, target) { var activeObject = this._activeObject; @@ -5813,40 +5895,24 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, { } }, _updateActiveSelection: function(target, e) { - var activeSelection = this._activeObject; + var activeSelection = this._activeObject, currentActiveObjects = activeSelection._objects.slice(0); if (activeSelection.contains(target)) { activeSelection.removeWithUpdate(target); - target.fire("deselected", { - e: e - }); this._hoveredTarget = target; if (activeSelection.size() === 1) { - this.setActiveObject(activeSelection.item(0), e); - return; + this._setActiveObject(activeSelection.item(0), e); } } else { activeSelection.addWithUpdate(target); - target.fire("selected", { - e: e - }); this._hoveredTarget = activeSelection; } - this.fire("selection:updated", { - target: activeSelection, - e: e, - updated: target - }); + this._fireSelectionEvents(currentActiveObjects, e); }, _createActiveSelection: function(target, e) { - var group = this._createGroup(target); - this.setActiveObject(group, e); - target.fire("selected", { - e: e - }); - this.fire("selection:created", { - target: group, - e: e - }); + var currentActives = this.getActiveObjects(), group = this._createGroup(target); + this._hoveredTarget = group; + this._setActiveObject(group, e); + this._fireSelectionEvents(currentActives, e); }, _createGroup: function(target) { var objects = this.getObjects(), isActiveLower = objects.indexOf(this._activeObject) < objects.indexOf(target), groupObjects = isActiveLower ? [ this._activeObject, target ] : [ target, this._activeObject ]; @@ -5863,16 +5929,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, { aGroup = new fabric.ActiveSelection(group.reverse(), { canvas: this }); - group.forEach(function(object) { - object.fire("selected", { - e: e - }); - }); this.setActiveObject(aGroup, e); - this.fire("selection:created", { - target: aGroup, - e: e - }); } }, _collectObjects: function() { @@ -6148,8 +6205,9 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { noScaleCache: true, dirty: true, __corner: 0, - stateProperties: ("top left width height scaleX scaleY flipX flipY originX originY transformMatrix " + "stroke strokeWidth strokeDashArray strokeLineCap strokeLineJoin strokeMiterLimit " + "angle opacity fill globalCompositeOperation shadow clipTo visible backgroundColor " + "skewX skewY fillRule").split(" "), - cacheProperties: ("fill stroke strokeWidth strokeDashArray width height" + " strokeLineCap strokeLineJoin strokeMiterLimit backgroundColor").split(" "), + paintFirst: "fill", + stateProperties: ("top left width height scaleX scaleY flipX flipY originX originY transformMatrix " + "stroke strokeWidth strokeDashArray strokeLineCap strokeLineJoin strokeMiterLimit " + "angle opacity fill globalCompositeOperation shadow clipTo visible backgroundColor " + "skewX skewY fillRule paintFirst").split(" "), + cacheProperties: ("fill stroke strokeWidth strokeDashArray width height paintFirst" + " strokeLineCap strokeLineJoin strokeMiterLimit backgroundColor").split(" "), initialize: function(options) { if (options) { this.setOptions(options); @@ -6162,56 +6220,68 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { this._updateCacheCanvas(); }, _limitCacheSize: function(dims) { - var perfLimitSizeTotal = fabric.perfLimitSizeTotal, maximumSide = fabric.cacheSideLimit, width = dims.width, height = dims.height, ar = width / height, limitedDims = fabric.util.limitDimsByArea(ar, perfLimitSizeTotal, maximumSide), capValue = fabric.util.capValue, max = fabric.maxCacheSideLimit, min = fabric.minCacheSideLimit, x = capValue(min, limitedDims.x, max), y = capValue(min, limitedDims.y, max); + var perfLimitSizeTotal = fabric.perfLimitSizeTotal, width = dims.width, height = dims.height, max = fabric.maxCacheSideLimit, min = fabric.minCacheSideLimit; + if (width <= max && height <= max && width * height <= perfLimitSizeTotal) { + if (width < min) { + dims.width = min; + } + if (height < min) { + dims.height = min; + } + return dims; + } + var ar = width / height, limitedDims = fabric.util.limitDimsByArea(ar, perfLimitSizeTotal), capValue = fabric.util.capValue, x = capValue(min, limitedDims.x, max), y = capValue(min, limitedDims.y, max); if (width > x) { dims.zoomX /= width / x; dims.width = x; - } else if (width < min) { - dims.width = min; + dims.capped = true; } if (height > y) { dims.zoomY /= height / y; dims.height = y; - } else if (height < min) { - dims.height = min; + dims.capped = true; } return dims; }, _getCacheCanvasDimensions: function() { - var zoom = this.canvas && this.canvas.getZoom() || 1, objectScale = this.getObjectScaling(), dim = this._getNonTransformedDimensions(), retina = this.canvas && this.canvas._isRetinaScaling() ? fabric.devicePixelRatio : 1, zoomX = objectScale.scaleX * zoom * retina, zoomY = objectScale.scaleY * zoom * retina, width = dim.x * zoomX, height = dim.y * zoomY; + var zoom = this.canvas && this.canvas.getZoom() || 1, objectScale = this.getObjectScaling(), retina = this.canvas && this.canvas._isRetinaScaling() ? fabric.devicePixelRatio : 1, dim = this._getNonTransformedDimensions(), zoomX = objectScale.scaleX * zoom * retina, zoomY = objectScale.scaleY * zoom * retina, width = dim.x * zoomX, height = dim.y * zoomY; return { width: width + ALIASING_LIMIT, height: height + ALIASING_LIMIT, zoomX: zoomX, - zoomY: zoomY + zoomY: zoomY, + x: dim.x, + y: dim.y }; }, _updateCacheCanvas: function() { if (this.noScaleCache && this.canvas && this.canvas._currentTransform) { - var action = this.canvas._currentTransform.action; - if (action.slice && action.slice(0, 5) === "scale") { + var target = this.canvas._currentTransform.target, action = this.canvas._currentTransform.action; + if (this === target && action.slice && action.slice(0, 5) === "scale") { return false; } } - var dims = this._limitCacheSize(this._getCacheCanvasDimensions()), minCacheSize = fabric.minCacheSideLimit, width = dims.width, height = dims.height, zoomX = dims.zoomX, zoomY = dims.zoomY, dimensionsChanged = width !== this.cacheWidth || height !== this.cacheHeight, zoomChanged = this.zoomX !== zoomX || this.zoomY !== zoomY, shouldRedraw = dimensionsChanged || zoomChanged, additionalWidth = 0, additionalHeight = 0, shouldResizeCanvas = false; + var canvas = this._cacheCanvas, dims = this._limitCacheSize(this._getCacheCanvasDimensions()), minCacheSize = fabric.minCacheSideLimit, width = dims.width, height = dims.height, drawingWidth, drawingHeight, zoomX = dims.zoomX, zoomY = dims.zoomY, dimensionsChanged = width !== this.cacheWidth || height !== this.cacheHeight, zoomChanged = this.zoomX !== zoomX || this.zoomY !== zoomY, shouldRedraw = dimensionsChanged || zoomChanged, additionalWidth = 0, additionalHeight = 0, shouldResizeCanvas = false; if (dimensionsChanged) { var canvasWidth = this._cacheCanvas.width, canvasHeight = this._cacheCanvas.height, sizeGrowing = width > canvasWidth || height > canvasHeight, sizeShrinking = (width < canvasWidth * .9 || height < canvasHeight * .9) && canvasWidth > minCacheSize && canvasHeight > minCacheSize; shouldResizeCanvas = sizeGrowing || sizeShrinking; - if (sizeGrowing) { - additionalWidth = width * .1 & ~1; - additionalHeight = height * .1 & ~1; + if (sizeGrowing && !dims.capped && (width > minCacheSize || height > minCacheSize)) { + additionalWidth = width * .1; + additionalHeight = height * .1; } } if (shouldRedraw) { if (shouldResizeCanvas) { - this._cacheCanvas.width = Math.max(Math.ceil(width) + additionalWidth, minCacheSize); - this._cacheCanvas.height = Math.max(Math.ceil(height) + additionalHeight, minCacheSize); - this.cacheTranslationX = (width + additionalWidth) / 2; - this.cacheTranslationY = (height + additionalHeight) / 2; + canvas.width = Math.ceil(width + additionalWidth); + canvas.height = Math.ceil(height + additionalHeight); } else { this._cacheContext.setTransform(1, 0, 0, 1, 0, 0); - this._cacheContext.clearRect(0, 0, this._cacheCanvas.width, this._cacheCanvas.height); + this._cacheContext.clearRect(0, 0, canvas.width, canvas.height); } + drawingWidth = dims.x * zoomX / 2; + drawingHeight = dims.y * zoomY / 2; + this.cacheTranslationX = Math.round(canvas.width / 2 - drawingWidth) + drawingWidth; + this.cacheTranslationY = Math.round(canvas.height / 2 - drawingHeight) + drawingHeight; this.cacheWidth = width; this.cacheHeight = height; this._cacheContext.translate(this.cacheTranslationX, this.cacheTranslationY); @@ -6230,16 +6300,14 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { this._initPattern(options.fill, "fill"); this._initPattern(options.stroke, "stroke"); }, - transform: function(ctx, fromLeft) { + transform: function(ctx) { + var m; if (this.group && !this.group._transformDone) { - this.group.transform(ctx); + m = this.calcTransformMatrix(); + } else { + m = this.calcOwnMatrix(); } - var center = fromLeft ? this._getLeftTopCoords() : this.getCenterPoint(); - ctx.translate(center.x, center.y); - this.angle && ctx.rotate(degreesToRadians(this.angle)); - ctx.scale(this.scaleX * (this.flipX ? -1 : 1), this.scaleY * (this.flipY ? -1 : 1)); - this.skewX && ctx.transform(1, 0, Math.tan(degreesToRadians(this.skewX)), 1, 0, 0); - this.skewY && ctx.transform(1, Math.tan(degreesToRadians(this.skewY)), 0, 1, 0, 0); + ctx.transform(m[0], m[1], m[2], m[3], m[4], m[5]); }, toObject: function(propertiesToInclude) { var NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS, object = { @@ -6269,6 +6337,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { clipTo: this.clipTo && String(this.clipTo), backgroundColor: this.backgroundColor, fillRule: this.fillRule, + paintFirst: this.paintFirst, globalCompositeOperation: this.globalCompositeOperation, transformMatrix: this.transformMatrix ? this.transformMatrix.concat() : null, skewX: toFixed(this.skewX, NUM_FRACTION_DIGITS), @@ -6319,7 +6388,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { return opacity; }, _set: function(key, value) { - var shouldConstrainValue = key === "scaleX" || key === "scaleY"; + var shouldConstrainValue = key === "scaleX" || key === "scaleY", isChanged = this[key] !== value, groupNeedsUpdate = false; if (shouldConstrainValue) { value = this._constrainScale(value); } @@ -6335,14 +6404,14 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { this.group.set("dirty", value); } this[key] = value; - if (this.cacheProperties.indexOf(key) > -1) { - if (this.group) { + if (isChanged) { + groupNeedsUpdate = this.group && this.group.isOnACache(); + if (this.cacheProperties.indexOf(key) > -1) { + this.dirty = true; + groupNeedsUpdate && this.group.set("dirty", true); + } else if (groupNeedsUpdate && this.stateProperties.indexOf(key) > -1) { this.group.set("dirty", true); } - this.dirty = true; - } - if (this.group && this.stateProperties.indexOf(key) > -1 && this.group.isOnACache()) { - this.group.set("dirty", true); } return this; }, @@ -6386,6 +6455,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { } this.drawCacheOnCanvas(ctx); } else { + this._removeCacheCanvas(); this.dirty = false; this.drawObject(ctx); if (this.objectCaching && this.statefullCache) { @@ -6397,7 +6467,15 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { this.clipTo && ctx.restore(); ctx.restore(); }, + _removeCacheCanvas: function() { + this._cacheCanvas = null; + this.cacheWidth = 0; + this.cacheHeight = 0; + }, needsItsOwnCache: function() { + if (this.paintFirst === "stroke" && typeof this.shadow === "object") { + return true; + } return false; }, shouldCache: function() { @@ -6511,7 +6589,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { multY *= fabric.devicePixelRatio; } ctx.shadowColor = this.shadow.color; - ctx.shadowBlur = this.shadow.blur * (multX + multY) * (scaling.scaleX + scaling.scaleY) / 4; + ctx.shadowBlur = this.shadow.blur * fabric.browserShadowBlurConstant * (multX + multY) * (scaling.scaleX + scaling.scaleY) / 4; ctx.shadowOffsetX = this.shadow.offsetX * multX * scaling.scaleX; ctx.shadowOffsetY = this.shadow.offsetY * multY * scaling.scaleY; }, @@ -6529,17 +6607,26 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { offsetY: 0 }; } - var transform = filler.gradientTransform || filler.patternTransform; + var t = filler.gradientTransform || filler.patternTransform; var offsetX = -this.width / 2 + filler.offsetX || 0, offsetY = -this.height / 2 + filler.offsetY || 0; ctx.translate(offsetX, offsetY); - if (transform) { - ctx.transform.apply(ctx, transform); + if (t) { + ctx.transform(t[0], t[1], t[2], t[3], t[4], t[5]); } return { offsetX: offsetX, offsetY: offsetY }; }, + _renderPaintInOrder: function(ctx) { + if (this.paintFirst === "stroke") { + this._renderStroke(ctx); + this._renderFill(ctx); + } else { + this._renderFill(ctx); + this._renderStroke(ctx); + } + }, _renderFill: function(ctx) { if (!this.fill) { return; @@ -6584,13 +6671,23 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { this.skewY = 0; } }, - _removeTransformMatrix: function() { + _removeTransformMatrix: function(preserveAspectRatioOptions) { var center = this._findCenterFromElement(); if (this.transformMatrix) { this._assignTransformMatrixProps(); center = fabric.util.transformPoint(center, this.transformMatrix); } this.transformMatrix = null; + if (preserveAspectRatioOptions) { + this.scaleX *= preserveAspectRatioOptions.scaleX; + this.scaleY *= preserveAspectRatioOptions.scaleY; + this.cropX = preserveAspectRatioOptions.cropX; + this.cropY = preserveAspectRatioOptions.cropY; + center.x += preserveAspectRatioOptions.offsetLeft; + center.y += preserveAspectRatioOptions.offsetTop; + this.width = preserveAspectRatioOptions.width; + this.height = preserveAspectRatioOptions.height; + } this.setPositionByOrigin(center, "center", "center"); }, clone: function(callback, propertiesToInclude) { @@ -6882,6 +6979,8 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { fabric.util.object.extend(fabric.Object.prototype, { oCoords: null, aCoords: null, + ownMatrixCache: null, + matrixCache: null, getCoords: function(absolute, calculate) { if (!this.oCoords) { this.setCoords(); @@ -6986,12 +7085,6 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { } return xcount; }, - getBoundingRectWidth: function() { - return this.getBoundingRect().width; - }, - getBoundingRectHeight: function() { - return this.getBoundingRect().height; - }, getBoundingRect: function(absolute, calculate) { var coords = this.getCoords(absolute, calculate); return fabric.util.makeBoundingBoxFromPoints(coords); @@ -7019,16 +7112,16 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { this._set("scaleY", value); return this.setCoords(); }, - scaleToWidth: function(value) { - var boundingRectFactor = this.getBoundingRect().width / this.getScaledWidth(); + scaleToWidth: function(value, absolute) { + var boundingRectFactor = this.getBoundingRect(absolute).width / this.getScaledWidth(); return this.scale(value / this.width / boundingRectFactor); }, - scaleToHeight: function(value) { - var boundingRectFactor = this.getBoundingRect().height / this.getScaledHeight(); + scaleToHeight: function(value, absolute) { + var boundingRectFactor = this.getBoundingRect(absolute).height / this.getScaledHeight(); return this.scale(value / this.height / boundingRectFactor); }, calcCoords: function(absolute) { - var theta = degreesToRadians(this.angle), vpt = this.getViewportTransform(), dim = absolute ? this._getTransformedDimensions() : this._calculateCurrentDimensions(), currentWidth = dim.x, currentHeight = dim.y, sinTh = Math.sin(theta), cosTh = Math.cos(theta), _angle = currentWidth > 0 ? Math.atan(currentHeight / currentWidth) : 0, _hypotenuse = currentWidth / Math.cos(_angle) / 2, offsetX = Math.cos(_angle + theta) * _hypotenuse, offsetY = Math.sin(_angle + theta) * _hypotenuse, center = this.getCenterPoint(), coords = absolute ? center : fabric.util.transformPoint(center, vpt), tl = new fabric.Point(coords.x - offsetX, coords.y - offsetY), tr = new fabric.Point(tl.x + currentWidth * cosTh, tl.y + currentWidth * sinTh), bl = new fabric.Point(tl.x - currentHeight * sinTh, tl.y + currentHeight * cosTh), br = new fabric.Point(coords.x + offsetX, coords.y + offsetY); + var theta = degreesToRadians(this.angle), vpt = this.getViewportTransform(), dim = absolute ? this._getTransformedDimensions() : this._calculateCurrentDimensions(), currentWidth = dim.x, currentHeight = dim.y, sinTh = theta ? Math.sin(theta) : 0, cosTh = theta ? Math.cos(theta) : 1, _angle = currentWidth > 0 ? Math.atan(currentHeight / currentWidth) : 0, _hypotenuse = currentWidth / Math.cos(_angle) / 2, offsetX = Math.cos(_angle + theta) * _hypotenuse, offsetY = Math.sin(_angle + theta) * _hypotenuse, center = this.getCenterPoint(), coords = absolute ? center : fabric.util.transformPoint(center, vpt), tl = new fabric.Point(coords.x - offsetX, coords.y - offsetY), tr = new fabric.Point(tl.x + currentWidth * cosTh, tl.y + currentWidth * sinTh), bl = new fabric.Point(tl.x - currentHeight * sinTh, tl.y + currentHeight * cosTh), br = new fabric.Point(coords.x + offsetX, coords.y + offsetY); if (!absolute) { var ml = new fabric.Point((tl.x + bl.x) / 2, (tl.y + bl.y) / 2), mt = new fabric.Point((tr.x + tl.x) / 2, (tr.y + tl.y) / 2), mr = new fabric.Point((br.x + tr.x) / 2, (br.y + tr.y) / 2), mb = new fabric.Point((br.x + bl.x) / 2, (br.y + bl.y) / 2), mtr = new fabric.Point(mt.x + sinTh * this.rotatingPointOffset, mt.y - cosTh * this.rotatingPointOffset); } @@ -7065,18 +7158,42 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { } return fabric.iMatrix.concat(); }, - calcTransformMatrix: function(skipGroup) { - var center = this.getCenterPoint(), translateMatrix = [ 1, 0, 0, 1, center.x, center.y ], rotateMatrix, dimensionMatrix = this._calcDimensionsTransformMatrix(this.skewX, this.skewY, true), matrix; - if (this.group && !skipGroup) { - matrix = multiplyMatrices(this.group.calcTransformMatrix(), translateMatrix); - } else { - matrix = translateMatrix; + transformMatrixKey: function(skipGroup) { + var sep = "_", prefix = ""; + if (!skipGroup && this.group) { + prefix = this.group.transformMatrixKey(skipGroup) + sep; } + return prefix + this.top + sep + this.left + sep + this.scaleX + sep + this.scaleY + sep + this.skewX + sep + this.skewY + sep + this.angle + sep + this.flipX + sep + this.flipY; + }, + calcTransformMatrix: function(skipGroup) { + if (skipGroup) { + return this.calcOwnMatrix(); + } + var key = this.transformMatrixKey(), cache = this.matrixCache || (this.matrixCache = {}); + if (cache.key === key) { + return cache.value; + } + var matrix = this.calcOwnMatrix(); + if (this.group) { + matrix = multiplyMatrices(this.group.calcTransformMatrix(), matrix); + } + cache.key = key; + cache.value = matrix; + return matrix; + }, + calcOwnMatrix: function() { + var key = this.transformMatrixKey(true), cache = this.ownMatrixCache || (this.ownMatrixCache = {}); + if (cache.key === key) { + return cache.value; + } + var center = this.getCenterPoint(), matrix = [ 1, 0, 0, 1, center.x, center.y ], rotateMatrix, dimensionMatrix = this._calcDimensionsTransformMatrix(this.skewX, this.skewY, true); if (this.angle) { rotateMatrix = this._calcRotateMatrix(); matrix = multiplyMatrices(matrix, rotateMatrix); } matrix = multiplyMatrices(matrix, dimensionMatrix); + cache.key = key; + cache.value = matrix; return matrix; }, _calcDimensionsTransformMatrix: function(skewX, skewY, flipping) { @@ -7168,7 +7285,7 @@ fabric.util.object.extend(fabric.Object.prototype, { return this; }, moveTo: function(index) { - if (this.group) { + if (this.group && this.group.type !== "activeSelection") { fabric.StaticCanvas.prototype.moveTo.call(this.group, this, index); } else { this.canvas.moveTo(this, index); @@ -7199,12 +7316,15 @@ fabric.util.object.extend(fabric.Object.prototype, { return [ stroke, "stroke-width: ", strokeWidth, "; ", "stroke-dasharray: ", strokeDashArray, "; ", "stroke-linecap: ", strokeLineCap, "; ", "stroke-linejoin: ", strokeLineJoin, "; ", "stroke-miterlimit: ", strokeMiterLimit, "; ", fill, "fill-rule: ", fillRule, "; ", "opacity: ", opacity, ";", filter, visibility ].join(""); }, getSvgSpanStyles: function(style, useWhiteSpace) { - var strokeWidth = style.strokeWidth ? "stroke-width: " + style.strokeWidth + "; " : "", fontFamily = style.fontFamily ? "font-family: " + style.fontFamily.replace(/"/g, "'") + "; " : "", fontSize = style.fontSize ? "font-size: " + style.fontSize + "; " : "", fontStyle = style.fontStyle ? "font-style: " + style.fontStyle + "; " : "", fontWeight = style.fontWeight ? "font-weight: " + style.fontWeight + "; " : "", fill = style.fill ? getSvgColorString("fill", style.fill) : "", stroke = style.stroke ? getSvgColorString("stroke", style.stroke) : "", textDecoration = this.getSvgTextDecoration(style); + var term = "; ", strokeWidth = style.strokeWidth ? "stroke-width: " + style.strokeWidth + term : "", fontFamily = style.fontFamily ? "font-family: " + style.fontFamily.replace(/"/g, "'") + term : "", fontSize = style.fontSize ? "font-size: " + style.fontSize + term : "", fontStyle = style.fontStyle ? "font-style: " + style.fontStyle + term : "", fontWeight = style.fontWeight ? "font-weight: " + style.fontWeight + term : "", fill = style.fill ? getSvgColorString("fill", style.fill) : "", stroke = style.stroke ? getSvgColorString("stroke", style.stroke) : "", textDecoration = this.getSvgTextDecoration(style); + if (textDecoration) { + textDecoration = "text-decoration: " + textDecoration + term; + } return [ stroke, strokeWidth, fontFamily, fontSize, fontStyle, fontWeight, textDecoration, fill, useWhiteSpace ? "white-space: pre; " : "" ].join(""); }, getSvgTextDecoration: function(style) { if ("overline" in style || "underline" in style || "linethrough" in style) { - return "text-decoration: " + (style.overline ? "overline " : "") + (style.underline ? "underline " : "") + (style.linethrough ? "line-through " : "") + ";"; + return (style.overline ? "overline " : "") + (style.underline ? "underline " : "") + (style.linethrough ? "line-through " : ""); } return ""; }, @@ -7238,6 +7358,9 @@ fabric.util.object.extend(fabric.Object.prototype, { markup.push(this.shadow.toSVG(this)); } return markup; + }, + addPaintOrder: function() { + return this.paintFirst !== "fill" ? ' paint-order="' + this.paintFirst + '" ' : ""; } }); })(); @@ -7633,15 +7756,13 @@ fabric.util.object.extend(fabric.Object.prototype, { fabric.warn("fabric.Line is already defined"); return; } - var cacheProperties = fabric.Object.prototype.cacheProperties.concat(); - cacheProperties.push("x1", "x2", "y1", "y2"); fabric.Line = fabric.util.createClass(fabric.Object, { type: "line", x1: 0, y1: 0, x2: 0, y2: 0, - cacheProperties: cacheProperties, + cacheProperties: fabric.Object.prototype.cacheProperties.concat("x1", "x2", "y1", "y2"), initialize: function(points, options) { if (!points) { points = [ 0, 0, 0, 0 ]; @@ -7781,14 +7902,12 @@ fabric.util.object.extend(fabric.Object.prototype, { fabric.warn("fabric.Circle is already defined."); return; } - var cacheProperties = fabric.Object.prototype.cacheProperties.concat(); - cacheProperties.push("radius"); fabric.Circle = fabric.util.createClass(fabric.Object, { type: "circle", radius: 0, startAngle: 0, endAngle: pi * 2, - cacheProperties: cacheProperties, + cacheProperties: fabric.Object.prototype.cacheProperties.concat("radius"), initialize: function(options) { this.callSuper("initialize", options); this.set("radius", options && options.radius || 0); @@ -7806,18 +7925,17 @@ fabric.util.object.extend(fabric.Object.prototype, { toSVG: function(reviver) { var markup = this._createBaseSVGMarkup(), x = 0, y = 0, angle = (this.endAngle - this.startAngle) % (2 * pi); if (angle === 0) { - markup.push("\n'); + markup.push("\n"); } else { var startX = Math.cos(this.startAngle) * this.radius, startY = Math.sin(this.startAngle) * this.radius, endX = Math.cos(this.endAngle) * this.radius, endY = Math.sin(this.endAngle) * this.radius, largeFlag = angle > pi ? "1" : "0"; - markup.push('\n'); + markup.push('\n'); } return reviver ? reviver(markup.join("")) : markup.join(""); }, _render: function(ctx) { ctx.beginPath(); ctx.arc(0, 0, this.radius, this.startAngle, this.endAngle, false); - this._renderFill(ctx); - this._renderStroke(ctx); + this._renderPaintInOrder(ctx); }, getRadiusX: function() { return this.get("radius") * this.get("scaleX"); @@ -7869,8 +7987,7 @@ fabric.util.object.extend(fabric.Object.prototype, { ctx.lineTo(0, -heightBy2); ctx.lineTo(widthBy2, heightBy2); ctx.closePath(); - this._renderFill(ctx); - this._renderStroke(ctx); + this._renderPaintInOrder(ctx); }, _renderDashedStroke: function(ctx) { var widthBy2 = this.width / 2, heightBy2 = this.height / 2; @@ -7882,7 +7999,7 @@ fabric.util.object.extend(fabric.Object.prototype, { }, toSVG: function(reviver) { var markup = this._createBaseSVGMarkup(), widthBy2 = this.width / 2, heightBy2 = this.height / 2, points = [ -widthBy2 + " " + heightBy2, "0 " + -heightBy2, widthBy2 + " " + heightBy2 ].join(","); - markup.push("'); + markup.push(""); return reviver ? reviver(markup.join("")) : markup.join(""); } }); @@ -7898,13 +8015,11 @@ fabric.util.object.extend(fabric.Object.prototype, { fabric.warn("fabric.Ellipse is already defined."); return; } - var cacheProperties = fabric.Object.prototype.cacheProperties.concat(); - cacheProperties.push("rx", "ry"); fabric.Ellipse = fabric.util.createClass(fabric.Object, { type: "ellipse", rx: 0, ry: 0, - cacheProperties: cacheProperties, + cacheProperties: fabric.Object.prototype.cacheProperties.concat("rx", "ry"), initialize: function(options) { this.callSuper("initialize", options); this.set("rx", options && options.rx || 0); @@ -7936,7 +8051,7 @@ fabric.util.object.extend(fabric.Object.prototype, { }, toSVG: function(reviver) { var markup = this._createBaseSVGMarkup(); - markup.push("\n'); + markup.push("\n"); return reviver ? reviver(markup.join("")) : markup.join(""); }, _render: function(ctx) { @@ -7945,8 +8060,7 @@ fabric.util.object.extend(fabric.Object.prototype, { ctx.transform(1, 0, 0, this.ry / this.rx, 0, 0); ctx.arc(0, 0, this.rx, 0, piBy2, false); ctx.restore(); - this._renderFill(ctx); - this._renderStroke(ctx); + this._renderPaintInOrder(ctx); } }); fabric.Ellipse.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat("cx cy rx ry".split(" ")); @@ -7969,16 +8083,12 @@ fabric.util.object.extend(fabric.Object.prototype, { fabric.warn("fabric.Rect is already defined"); return; } - var stateProperties = fabric.Object.prototype.stateProperties.concat(); - stateProperties.push("rx", "ry"); - var cacheProperties = fabric.Object.prototype.cacheProperties.concat(); - cacheProperties.push("rx", "ry"); fabric.Rect = fabric.util.createClass(fabric.Object, { - stateProperties: stateProperties, + stateProperties: fabric.Object.prototype.stateProperties.concat("rx", "ry"), type: "rect", rx: 0, ry: 0, - cacheProperties: cacheProperties, + cacheProperties: fabric.Object.prototype.cacheProperties.concat("rx", "ry"), initialize: function(options) { this.callSuper("initialize", options); this._initRxRy(); @@ -8007,8 +8117,7 @@ fabric.util.object.extend(fabric.Object.prototype, { ctx.lineTo(x, y + ry); isRounded && ctx.bezierCurveTo(x, y + k * ry, x + k * rx, y, x + rx, y); ctx.closePath(); - this._renderFill(ctx); - this._renderStroke(ctx); + this._renderPaintInOrder(ctx); }, _renderDashedStroke: function(ctx) { var x = -this.width / 2, y = -this.height / 2, w = this.width, h = this.height; @@ -8024,7 +8133,7 @@ fabric.util.object.extend(fabric.Object.prototype, { }, toSVG: function(reviver) { var markup = this._createBaseSVGMarkup(), x = -this.width / 2, y = -this.height / 2; - markup.push("\n'); + markup.push("\n"); return reviver ? reviver(markup.join("")) : markup.join(""); } }); @@ -8053,12 +8162,10 @@ fabric.util.object.extend(fabric.Object.prototype, { fabric.warn("fabric.Polyline is already defined"); return; } - var cacheProperties = fabric.Object.prototype.cacheProperties.concat(); - cacheProperties.push("points"); fabric.Polyline = fabric.util.createClass(fabric.Object, { type: "polyline", points: null, - cacheProperties: cacheProperties, + cacheProperties: fabric.Object.prototype.cacheProperties.concat("points"), initialize: function(points, options) { options = options || {}; this.points = points || []; @@ -8096,7 +8203,7 @@ fabric.util.object.extend(fabric.Object.prototype, { for (var i = 0, len = this.points.length; i < len; i++) { points.push(toFixed(this.points[i].x - diffX, NUM_FRACTION_DIGITS), ",", toFixed(this.points[i].y - diffY, NUM_FRACTION_DIGITS), " "); } - markup.push("<", this.type, " ", this.getSvgId(), 'points="', points.join(""), '" style="', this.getSvgStyles(), '" transform="', this.getSvgTransform(), " ", this.getSvgTransformMatrix(), '"/>\n'); + markup.push("<", this.type, " ", this.getSvgId(), 'points="', points.join(""), '" style="', this.getSvgStyles(), '" transform="', this.getSvgTransform(), " ", this.getSvgTransformMatrix(), '"', this.addPaintOrder(), "/>\n"); return reviver ? reviver(markup.join("")) : markup.join(""); }, commonRender: function(ctx) { @@ -8116,8 +8223,7 @@ fabric.util.object.extend(fabric.Object.prototype, { if (!this.commonRender(ctx)) { return; } - this._renderFill(ctx); - this._renderStroke(ctx); + this._renderPaintInOrder(ctx); }, _renderDashedStroke: function(ctx) { var p1, p2; @@ -8160,8 +8266,7 @@ fabric.util.object.extend(fabric.Object.prototype, { return; } ctx.closePath(); - this._renderFill(ctx); - this._renderStroke(ctx); + this._renderPaintInOrder(ctx); }, _renderDashedStroke: function(ctx) { this.callSuper("_renderDashedStroke", ctx); @@ -8202,15 +8307,11 @@ fabric.util.object.extend(fabric.Object.prototype, { fabric.warn("fabric.Path is already defined"); return; } - var stateProperties = fabric.Object.prototype.stateProperties.concat(); - stateProperties.push("path"); - var cacheProperties = fabric.Object.prototype.cacheProperties.concat(); - cacheProperties.push("path", "fillRule"); fabric.Path = fabric.util.createClass(fabric.Object, { type: "path", path: null, - cacheProperties: cacheProperties, - stateProperties: stateProperties, + cacheProperties: fabric.Object.prototype.cacheProperties.concat("path", "fillRule"), + stateProperties: fabric.Object.prototype.stateProperties.concat("path"), initialize: function(path, options) { options = options || {}; this.callSuper("initialize", options); @@ -8422,8 +8523,7 @@ fabric.util.object.extend(fabric.Object.prototype, { }, _render: function(ctx) { this._renderPathCommands(ctx); - this._renderFill(ctx); - this._renderStroke(ctx); + this._renderPaintInOrder(ctx); }, toString: function() { return "#"; @@ -8452,7 +8552,7 @@ fabric.util.object.extend(fabric.Object.prototype, { } var path = chunks.join(" "); addTransform = " translate(" + -this.pathOffset.x + ", " + -this.pathOffset.y + ") "; - markup.push("\n"); + markup.push("\n"); return reviver ? reviver(markup.join("")) : markup.join(""); }, complexity: function() { @@ -8725,9 +8825,17 @@ fabric.util.object.extend(fabric.Object.prototype, { this._updateObjectsCoords(center); delete options.centerPoint; this.callSuper("initialize", options); + } else { + this._updateObjectsACoords(); } this.setCoords(); }, + _updateObjectsACoords: function() { + var ignoreZoom = true, skipAbsolute = true; + for (var i = this._objects.length; i--; ) { + this._objects[i].setCoords(ignoreZoom, skipAbsolute); + } + }, _updateObjectsCoords: function(center) { var center = center || this.getCenterPoint(); for (var i = this._objects.length; i--; ) { @@ -9142,6 +9250,11 @@ fabric.util.object.extend(fabric.Object.prototype, { return this._element; }, setElement: function(element, options) { + var backend = fabric.filterBackend; + if (backend && backend.evictCachesForKey) { + backend.evictCachesForKey(this.cacheKey); + backend.evictCachesForKey(this.cacheKey + "_filtered"); + } this._element = element; this._originalElement = element; this._initConfig(options); @@ -9204,19 +9317,24 @@ fabric.util.object.extend(fabric.Object.prototype, { if (this.resizeFilter) { object.resizeFilter = this.resizeFilter.toObject(); } - object.width /= this._filterScalingX; - object.height /= this._filterScalingY; return object; }, toSVG: function(reviver) { var markup = this._createBaseSVGMarkup(), x = -this.width / 2, y = -this.height / 2; - markup.push('\n', "\t\n'); + markup.push('\n'); + var imageMarkup = [ "\t\n' ]; + if (this.paintFirst === "fill") { + Array.prototype.push.apply(markup, imageMarkup); + } if (this.stroke || this.strokeDashArray) { var origFill = this.fill; this.fill = null; - markup.push("\n'); + markup.push("\t\n'); this.fill = origFill; } + if (this.paintFirst !== "fill") { + Array.prototype.push.apply(markup, imageMarkup); + } markup.push("\n"); return reviver ? reviver(markup.join("")) : markup.join(""); }, @@ -9226,7 +9344,7 @@ fabric.util.object.extend(fabric.Object.prototype, { if (element.toDataURL) { return element.toDataURL(); } - return fabric.isLikelyNode ? element._src : element.src; + return element.src; } else { return this.src || ""; } @@ -9242,43 +9360,25 @@ fabric.util.object.extend(fabric.Object.prototype, { return '#'; }, applyResizeFilters: function() { - var filter = this.resizeFilter, retinaScaling = this.canvas ? this.canvas.getRetinaScaling() : 1, minimumScale = this.minimumScaleTrigger, scaleX = this.scaleX < minimumScale ? this.scaleX : 1, scaleY = this.scaleY < minimumScale ? this.scaleY : 1; - if (scaleX * retinaScaling < 1) { - scaleX *= retinaScaling; - } - if (scaleY * retinaScaling < 1) { - scaleY *= retinaScaling; - } - if (!filter || scaleX >= 1 && scaleY >= 1) { - this._element = this._filteredEl; + var filter = this.resizeFilter, retinaScaling = this.canvas ? this.canvas.getRetinaScaling() : 1, minimumScale = this.minimumScaleTrigger, scaleX = this.scaleX * retinaScaling, scaleY = this.scaleY * retinaScaling, elementToFilter = this._filteredEl || this._originalElement; + if (!filter || scaleX > minimumScale && scaleY > minimumScale) { + this._element = elementToFilter; + this._filterScalingX = 1; + this._filterScalingY = 1; return; } if (!fabric.filterBackend) { fabric.filterBackend = fabric.initFilterBackend(); } - var elementToFilter = this._filteredEl || this._originalElement, imageData; - if (this._element === this._originalElement) { - var canvasEl = fabric.util.createCanvasElement(); - canvasEl.width = elementToFilter.width; - canvasEl.height = elementToFilter.height; - this._element = canvasEl; - } - var ctx = this._element.getContext("2d"); - if (elementToFilter.getContext) { - imageData = elementToFilter.getContext("2d").getImageData(0, 0, elementToFilter.width, elementToFilter.height); - } else { - ctx.drawImage(elementToFilter, 0, 0); - imageData = ctx.getImageData(0, 0, elementToFilter.width, elementToFilter.height); - } - var options = { - imageData: imageData, - scaleX: scaleX, - scaleY: scaleY - }; - filter.applyTo2d(options); - this.width = this._element.width = options.imageData.width; - this.height = this._element.height = options.imageData.height; - ctx.putImageData(options.imageData, 0, 0); + var canvasEl = fabric.util.createCanvasElement(), cacheKey = this._filteredEl ? this.cacheKey : this.cacheKey + "_filtered", sourceWidth = elementToFilter.width, sourceHeight = elementToFilter.height; + canvasEl.width = sourceWidth; + canvasEl.height = sourceHeight; + this._element = canvasEl; + filter.scaleX = scaleX; + filter.scaleY = scaleY; + fabric.filterBackend.applyFilters([ filter ], elementToFilter, sourceWidth, sourceHeight, this._element, cacheKey); + this._filterScalingX = canvasEl.width / this._originalElement.width; + this._filterScalingY = canvasEl.height / this._originalElement.height; }, applyFilters: function(filters) { filters = filters || this.filters || []; @@ -9287,6 +9387,7 @@ fabric.util.object.extend(fabric.Object.prototype, { }); if (filters.length === 0) { this._element = this._originalElement; + this._filteredEl = null; this._filterScalingX = 1; this._filterScalingY = 1; return this; @@ -9294,9 +9395,10 @@ fabric.util.object.extend(fabric.Object.prototype, { var imgElement = this._originalElement, sourceWidth = imgElement.naturalWidth || imgElement.width, sourceHeight = imgElement.naturalHeight || imgElement.height; if (this._element === this._originalElement) { var canvasEl = fabric.util.createCanvasElement(); - canvasEl.width = imgElement.width; - canvasEl.height = imgElement.height; + canvasEl.width = sourceWidth; + canvasEl.height = sourceHeight; this._element = canvasEl; + this._filteredEl = canvasEl; } else { this._element.getContext("2d").clearRect(0, 0, sourceWidth, sourceHeight); } @@ -9304,25 +9406,24 @@ fabric.util.object.extend(fabric.Object.prototype, { fabric.filterBackend = fabric.initFilterBackend(); } fabric.filterBackend.applyFilters(filters, this._originalElement, sourceWidth, sourceHeight, this._element, this.cacheKey); - if (this.width !== this._element.width || this.height !== this._element.height) { - this._filterScalingX = this._element.width / this.width; - this._filterScalingY = this._element.height / this.height; - this.width = this._element.width; - this.height = this._element.height; + if (this._originalElement.width !== this._element.width || this._originalElement.height !== this._element.height) { + this._filterScalingX = this._element.width / this._originalElement.width; + this._filterScalingY = this._element.height / this._originalElement.height; } return this; }, _render: function(ctx) { - var x = -this.width / 2, y = -this.height / 2, elementToDraw; if (this.isMoving === false && this.resizeFilter && this._needsResize()) { this._lastScaleX = this.scaleX; this._lastScaleY = this.scaleY; this.applyResizeFilters(); } - elementToDraw = this._element; - elementToDraw && ctx.drawImage(elementToDraw, this.cropX, this.cropY, this.width, this.height, x, y, this.width, this.height); this._stroke(ctx); - this._renderStroke(ctx); + this._renderPaintInOrder(ctx); + }, + _renderFill: function(ctx) { + var w = this.width, h = this.height, sW = w * this._filterScalingX, sH = h * this._filterScalingY, x = -w / 2, y = -h / 2, elementToDraw = this._element; + elementToDraw && ctx.drawImage(elementToDraw, this.cropX * this._filterScalingX, this.cropY * this._filterScalingY, sW, sH, x, y, w, h); }, _needsResize: function() { return this.scaleX !== this._lastScaleX || this.scaleY !== this._lastScaleY; @@ -9358,52 +9459,61 @@ fabric.util.object.extend(fabric.Object.prototype, { this.height = "height" in options ? options.height : this.getElement() ? this.getElement().height || 0 : 0; }, parsePreserveAspectRatioAttribute: function() { - if (!this.preserveAspectRatio) { - return; - } - var pAR = fabric.util.parsePreserveAspectRatioAttribute(this.preserveAspectRatio), width = this._element.width, height = this._element.height, scale, pWidth = this.width, pHeight = this.height, parsedAttributes = { + var pAR = fabric.util.parsePreserveAspectRatioAttribute(this.preserveAspectRatio || ""), rWidth = this._element.width, rHeight = this._element.height, scaleX = 1, scaleY = 1, offsetLeft = 0, offsetTop = 0, cropX = 0, cropY = 0, offset, pWidth = this.width, pHeight = this.height, parsedAttributes = { width: pWidth, height: pHeight }; if (pAR && (pAR.alignX !== "none" || pAR.alignY !== "none")) { if (pAR.meetOrSlice === "meet") { - this.width = width; - this.height = height; - this.scaleX = this.scaleY = scale = fabric.util.findScaleToFit(this._element, parsedAttributes); - if (pAR.alignX === "Mid") { - this.left += (pWidth - width * scale) / 2; + scaleX = scaleY = fabric.util.findScaleToFit(this._element, parsedAttributes); + offset = (pWidth - rWidth * scaleX) / 2; + if (pAR.alignX === "Min") { + offsetLeft = -offset; } if (pAR.alignX === "Max") { - this.left += pWidth - width * scale; + offsetLeft = offset; } - if (pAR.alignY === "Mid") { - this.top += (pHeight - height * scale) / 2; + offset = (pHeight - rHeight * scaleY) / 2; + if (pAR.alignY === "Min") { + offsetTop = -offset; } if (pAR.alignY === "Max") { - this.top += pHeight - height * scale; + offsetTop = offset; } } if (pAR.meetOrSlice === "slice") { - this.scaleX = this.scaleY = scale = fabric.util.findScaleToCover(this._element, parsedAttributes); - this.width = pWidth / scale; - this.height = pHeight / scale; + scaleX = scaleY = fabric.util.findScaleToCover(this._element, parsedAttributes); + offset = rWidth - pWidth / scaleX; if (pAR.alignX === "Mid") { - this.cropX = (width - this.width) / 2; + cropX = offset / 2; } if (pAR.alignX === "Max") { - this.cropX = width - this.width; + cropX = offset; } + offset = rHeight - pHeight / scaleY; if (pAR.alignY === "Mid") { - this.cropY = (height - this.height) / 2; + cropY = offset / 2; } if (pAR.alignY === "Max") { - this.cropY = height - this.height; + cropY = offset; } + rWidth = pWidth / scaleX; + rHeight = pHeight / scaleY; } } else { - this.scaleX = pWidth / width; - this.scaleY = pHeight / height; + scaleX = pWidth / rWidth; + scaleY = pHeight / rHeight; } + return { + width: rWidth, + height: rHeight, + scaleX: scaleX, + scaleY: scaleY, + offsetLeft: offsetLeft, + offsetTop: offsetTop, + cropX: cropX, + cropY: cropY + }; } }); fabric.Image.CSS_CANVAS = "canvas-img"; @@ -9484,6 +9594,16 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { (function() { "use strict"; + function testPrecision(gl, precision) { + var fragmentSource = "precision " + precision + " float;\nvoid main(){}"; + var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER); + gl.shaderSource(fragmentShader, fragmentSource); + gl.compileShader(fragmentShader); + if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) { + return false; + } + return true; + } fabric.isWebglSupported = function(tileSize) { if (fabric.isLikelyNode) { return false; @@ -9495,6 +9615,13 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { if (gl) { fabric.maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE); isSupported = fabric.maxTextureSize >= tileSize; + var precisions = [ "highp", "mediump", "lowp" ]; + for (var i = 0; i < 3; i++) { + if (testPrecision(gl, precisions[i])) { + fabric.webGlPrecision = precisions[i]; + break; + } + } } this.isSupported = isSupported; return isSupported; @@ -9513,7 +9640,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { setupGLContext: function(width, height) { this.dispose(); this.createWebGLCanvas(width, height); - this.squareVertices = new Float32Array([ 0, 0, 0, 1, 1, 0, 1, 1 ]); + this.aPosition = new Float32Array([ 0, 0, 0, 1, 1, 0, 1, 1 ]); this.chooseFastestCopyGLTo2DMethod(width, height); }, chooseFastestCopyGLTo2DMethod: function(width, height) { @@ -9533,16 +9660,19 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { var targetCanvas = fabric.util.createCanvasElement(); var imageBuffer = new ArrayBuffer(width * height * 4); var testContext = { - imageBuffer: imageBuffer + imageBuffer: imageBuffer, + destinationWidth: width, + destinationHeight: height, + targetCanvas: targetCanvas }; var startTime, drawImageTime, putImageDataTime; targetCanvas.width = width; targetCanvas.height = height; startTime = window.performance.now(); - copyGLTo2DDrawImage.call(testContext, this.gl, targetCanvas); + copyGLTo2DDrawImage.call(testContext, this.gl, testContext); drawImageTime = window.performance.now() - startTime; startTime = window.performance.now(); - copyGLTo2DPutImageData.call(testContext, this.gl, targetCanvas); + copyGLTo2DPutImageData.call(testContext, this.gl, testContext); putImageDataTime = window.performance.now() - startTime; if (drawImageTime > putImageDataTime) { this.imageBuffer = imageBuffer; @@ -9579,23 +9709,27 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { originalHeight: source.height || source.originalHeight, sourceWidth: width, sourceHeight: height, + destinationWidth: width, + destinationHeight: height, context: gl, sourceTexture: this.createTexture(gl, width, height, !cachedTexture && source), targetTexture: this.createTexture(gl, width, height), originalTexture: cachedTexture || this.createTexture(gl, width, height, !cachedTexture && source), passes: filters.length, webgl: true, - squareVertices: this.squareVertices, + aPosition: this.aPosition, programCache: this.programCache, pass: 0, - filterBackend: this + filterBackend: this, + targetCanvas: targetCanvas }; var tempFbo = gl.createFramebuffer(); gl.bindFramebuffer(gl.FRAMEBUFFER, tempFbo); filters.forEach(function(filter) { filter && filter.applyTo(pipelineState); }); - this.copyGLTo2D(gl, targetCanvas); + resizeCanvasIfNeeded(pipelineState); + this.copyGLTo2D(gl, pipelineState); gl.bindTexture(gl.TEXTURE_2D, null); gl.deleteTexture(pipelineState.sourceTexture); gl.deleteTexture(pipelineState.targetTexture); @@ -9661,8 +9795,8 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { createTexture: function(gl, width, height, textureImageSource) { var texture = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, texture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); if (textureImageSource) { @@ -9714,24 +9848,28 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { }; })(); -function copyGLTo2DDrawImage(gl, targetCanvas) { - var sourceCanvas = gl.canvas; - var ctx = targetCanvas.getContext("2d"); - ctx.translate(0, targetCanvas.height); - ctx.scale(1, -1); - var sourceY = sourceCanvas.height - targetCanvas.height; - ctx.drawImage(sourceCanvas, 0, sourceY, targetCanvas.width, targetCanvas.height, 0, 0, targetCanvas.width, targetCanvas.height); +function resizeCanvasIfNeeded(pipelineState) { + var targetCanvas = pipelineState.targetCanvas, width = targetCanvas.width, height = targetCanvas.height, dWidth = pipelineState.destinationWidth, dHeight = pipelineState.destinationHeight; + if (width !== dWidth || height !== dHeight) { + targetCanvas.width = dWidth; + targetCanvas.height = dHeight; + } } -function copyGLTo2DPutImageData(gl, targetCanvas) { - var ctx = targetCanvas.getContext("2d"); - var width = targetCanvas.width; - var height = targetCanvas.height; - var numBytes = width * height * 4; +function copyGLTo2DDrawImage(gl, pipelineState) { + var glCanvas = gl.canvas, targetCanvas = pipelineState.targetCanvas, ctx = targetCanvas.getContext("2d"); + ctx.translate(0, targetCanvas.height); + ctx.scale(1, -1); + var sourceY = glCanvas.height - targetCanvas.height; + ctx.drawImage(glCanvas, 0, sourceY, targetCanvas.width, targetCanvas.height, 0, 0, targetCanvas.width, targetCanvas.height); +} + +function copyGLTo2DPutImageData(gl, pipelineState) { + var targetCanvas = pipelineState.targetCanvas, ctx = targetCanvas.getContext("2d"), dWidth = pipelineState.destinationWidth, dHeight = pipelineState.destinationHeight, numBytes = dWidth * dHeight * 4; var u8 = new Uint8Array(this.imageBuffer, 0, numBytes); var u8Clamped = new Uint8ClampedArray(this.imageBuffer, 0, numBytes); - gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, u8); - var imgData = new ImageData(u8Clamped, width); + gl.readPixels(0, 0, dWidth, dHeight, gl.RGBA, gl.UNSIGNED_BYTE, u8); + var imgData = new ImageData(u8Clamped, dWidth, dHeight); ctx.putImageData(imgData, 0, 0); } @@ -9777,7 +9915,7 @@ fabric.Image.filters = fabric.Image.filters || {}; fabric.Image.filters.BaseFilter = fabric.util.createClass({ type: "BaseFilter", - vertexSource: "attribute vec2 aPosition;\n" + "attribute vec2 aTexCoord;\n" + "varying vec2 vTexCoord;\n" + "void main() {\n" + "vTexCoord = aTexCoord;\n" + "gl_Position = vec4(aPosition * 2.0 - 1.0, 0.0, 1.0);\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" + "}", fragmentSource: "precision highp float;\n" + "varying vec2 vTexCoord;\n" + "uniform sampler2D uTexture;\n" + "void main() {\n" + "gl_FragColor = texture2D(uTexture, vTexCoord);\n" + "}", initialize: function(options) { if (options) { @@ -9790,8 +9928,8 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass({ } }, createProgram: function(gl, fragmentSource, vertexSource) { - if (!this.vertexSource || !this.fragmentSource) { - return; + if (fabric.webGlPrecision !== "highp") { + fragmentSource = fragmentSource.replace(/precision highp float/g, "precision " + fabric.webGlPrecision + " float"); } var vertexShader = gl.createShader(gl.VERTEX_SHADER); gl.shaderSource(vertexShader, vertexSource || this.vertexSource); @@ -9824,24 +9962,29 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass({ }, getAttributeLocations: function(gl, program) { return { - aPosition: gl.getAttribLocation(program, "aPosition"), - aTexCoord: gl.getAttribLocation(program, "aTexCoord") + aPosition: gl.getAttribLocation(program, "aPosition") }; }, - getUniformLocations: function() {}, - sendAttributeData: function(gl, attributeLocations, squareVertices) { - [ "aPosition", "aTexCoord" ].forEach(function(attribute) { - var attributeLocation = attributeLocations[attribute]; - var buffer = gl.createBuffer(); - gl.bindBuffer(gl.ARRAY_BUFFER, buffer); - gl.enableVertexAttribArray(attributeLocation); - gl.vertexAttribPointer(attributeLocation, 2, gl.FLOAT, false, 0, 0); - gl.bufferData(gl.ARRAY_BUFFER, squareVertices, gl.STATIC_DRAW); - }); + getUniformLocations: function() { + return {}; + }, + sendAttributeData: function(gl, attributeLocations, aPositionData) { + var attributeLocation = attributeLocations.aPostion; + var buffer = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, buffer); + gl.enableVertexAttribArray(attributeLocation); + gl.vertexAttribPointer(attributeLocation, 2, gl.FLOAT, false, 0, 0); + gl.bufferData(gl.ARRAY_BUFFER, aPositionData, gl.STATIC_DRAW); }, _setupFrameBuffer: function(options) { - var gl = options.context; + var gl = options.context, width, height; if (options.passes > 1) { + width = options.destinationWidth; + height = options.destinationHeight; + if (options.sourceWidth !== width || options.sourceHeight !== height) { + gl.deleteTexture(options.targetTexture); + options.targetTexture = options.filterBackend.createTexture(gl, width, height); + } gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, options.targetTexture, 0); } else { gl.bindFramebuffer(gl.FRAMEBUFFER, null); @@ -9866,7 +10009,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass({ this._setupFrameBuffer(options); this.applyToWebGL(options); this._swapTextures(options); - } else { + } else if (!this.isNeutralState()) { this.applyTo2d(options); } }, @@ -9885,11 +10028,11 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass({ gl.bindTexture(gl.TEXTURE_2D, options.sourceTexture); } gl.useProgram(shader.program); - this.sendAttributeData(gl, shader.attributeLocations, options.squareVertices); + this.sendAttributeData(gl, shader.attributeLocations, options.aPosition); gl.uniform1f(shader.uniformLocations.uStepW, 1 / options.sourceWidth); gl.uniform1f(shader.uniformLocations.uStepH, 1 / options.sourceHeight); this.sendUniformData(gl, shader.uniformLocations); - gl.viewport(0, 0, options.sourceWidth, options.sourceHeight); + gl.viewport(0, 0, options.destinationWidth, options.destinationHeight); gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); }, bindAdditionalTexture: function(gl, texture, textureUnit) { @@ -9950,6 +10093,15 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) { this.callSuper("initialize", options); this.matrix = this.matrix.slice(0); }, + isNeutralState: function() { + var _class = filters.ColorMatrix; + for (var i = 20; i--; ) { + if (this.matrix[i] !== _class.prototype.matrix[i]) { + return false; + } + } + return true; + }, applyTo2d: function(options) { var imageData = options.imageData, data = imageData.data, iLen = data.length, m = this.matrix, r, g, b, a, i, colorsOnly = this.colorsOnly; for (i = 0; i < iLen; i += 4) { @@ -10252,6 +10404,9 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) { } } }, + isNeutralState: function() { + return this.blocksize === 1; + }, getUniformLocations: function(gl, program) { return { uBlocksize: gl.getUniformLocation(program, "uBlocksize"), @@ -10565,11 +10720,104 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) { scaleX: 0, scaleY: 0, lanczosLobes: 3, - applyTo2d: function(options) { - var imageData = options.imageData, scaleX = options.scaleX || this.scaleX, scaleY = options.scaleY || this.scaleY; - if (scaleX === 1 && scaleY === 1) { - return; + getUniformLocations: function(gl, program) { + return { + uDelta: gl.getUniformLocation(program, "uDelta"), + uTaps: gl.getUniformLocation(program, "uTaps") + }; + }, + sendUniformData: function(gl, uniformLocations) { + gl.uniform2fv(uniformLocations.uDelta, this.horizontal ? [ 1 / this.width, 0 ] : [ 0, 1 / this.height ]); + gl.uniform1fv(uniformLocations.uTaps, this.taps); + }, + retrieveShader: function(options) { + var filterWindow = this.getFilterWindow(), cacheKey = this.type + "_" + filterWindow; + if (!options.programCache.hasOwnProperty(cacheKey)) { + var fragmentShader = this.generateShader(filterWindow); + options.programCache[cacheKey] = this.createProgram(options.context, fragmentShader); } + return options.programCache[cacheKey]; + }, + getFilterWindow: function() { + var scale = this.tempScale; + return Math.ceil(this.lanczosLobes / scale); + }, + getTaps: function() { + var lobeFunction = this.lanczosCreate(this.lanczosLobes), scale = this.tempScale, filterWindow = this.getFilterWindow(), taps = new Array(filterWindow); + for (var i = 1; i <= filterWindow; i++) { + taps[i - 1] = lobeFunction(i * scale); + } + return taps; + }, + generateShader: function(filterWindow) { + var offsets = new Array(filterWindow), fragmentShader = this.fragmentSourceTOP, filterWindow; + for (var i = 1; i <= filterWindow; i++) { + offsets[i - 1] = i + ".0 * uDelta"; + } + fragmentShader += "uniform float uTaps[" + filterWindow + "];\n"; + fragmentShader += "void main() {\n"; + fragmentShader += " vec4 color = texture2D(uTexture, vTexCoord);\n"; + fragmentShader += " float sum = 1.0;\n"; + offsets.forEach(function(offset, i) { + fragmentShader += " color += texture2D(uTexture, vTexCoord + " + offset + ") * uTaps[" + i + "];\n"; + fragmentShader += " color += texture2D(uTexture, vTexCoord - " + offset + ") * uTaps[" + i + "];\n"; + fragmentShader += " sum += 2.0 * uTaps[" + i + "];\n"; + }); + fragmentShader += " gl_FragColor = color / sum;\n"; + fragmentShader += "}"; + return fragmentShader; + }, + fragmentSourceTOP: "precision highp float;\n" + "uniform sampler2D uTexture;\n" + "uniform vec2 uDelta;\n" + "varying vec2 vTexCoord;\n", + applyTo: function(options) { + if (options.webgl) { + if (options.passes > 1 && this.isNeutralState(options)) { + return; + } + options.passes++; + this.width = options.sourceWidth; + this.horizontal = true; + this.dW = Math.round(this.width * this.scaleX); + this.dH = options.sourceHeight; + this.tempScale = this.dW / this.width; + this.taps = this.getTaps(); + options.destinationWidth = this.dW; + this._setupFrameBuffer(options); + this.applyToWebGL(options); + this._swapTextures(options); + options.sourceWidth = options.destinationWidth; + this.height = options.sourceHeight; + this.horizontal = false; + this.dH = Math.round(this.height * this.scaleY); + this.tempScale = this.dH / this.height; + this.taps = this.getTaps(); + options.destinationHeight = this.dH; + this._setupFrameBuffer(options); + this.applyToWebGL(options); + this._swapTextures(options); + options.sourceHeight = options.destinationHeight; + } else if (!this.isNeutralState(options)) { + this.applyTo2d(options); + } + }, + isNeutralState: function(options) { + var scaleX = options.scaleX || this.scaleX, scaleY = options.scaleY || this.scaleY; + return scaleX === 1 && scaleY === 1; + }, + lanczosCreate: function(lobes) { + return function(x) { + if (x >= lobes || x <= -lobes) { + return 0; + } + if (x < 1.1920929e-7 && x > -1.1920929e-7) { + return 1; + } + x *= Math.PI; + var xx = x / lobes; + return sin(x) / x * sin(xx) / xx; + }; + }, + applyTo2d: function(options) { + var imageData = options.imageData, scaleX = this.scaleX, scaleY = this.scaleY; this.rcpScaleX = 1 / scaleX; this.rcpScaleY = 1 / scaleY; var oW = imageData.width, oH = imageData.height, dW = round(oW * scaleX), dH = round(oH * scaleY), newData; @@ -10622,19 +10870,6 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) { return ctx.getImageData(sX, sY, dW, dH); }, lanczosResize: function(options, oW, oH, dW, dH) { - function lanczosCreate(lobes) { - return function(x) { - if (x > lobes) { - return 0; - } - x *= Math.PI; - if (abs(x) < 1e-16) { - return 1; - } - var xx = x / lobes; - return sin(x) * sin(xx) / x / xx; - }; - } function process(u) { var v, i, weight, idx, a, red, green, blue, alpha, fX, fY; center.x = (u + .5) * ratioX; @@ -10686,7 +10921,7 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) { return destImg; } } - var srcData = options.imageData.data, destImg = options.ctx.creteImageData(dW, dH), destData = destImg.data, lanczos = lanczosCreate(this.lanczosLobes), ratioX = this.rcpScaleX, ratioY = this.rcpScaleY, rcpRatioX = 2 / this.rcpScaleX, rcpRatioY = 2 / this.rcpScaleY, range2X = ceil(ratioX * this.lanczosLobes / 2), range2Y = ceil(ratioY * this.lanczosLobes / 2), cacheLanc = {}, center = {}, icenter = {}; + var srcData = options.imageData.data, destImg = options.ctx.createImageData(dW, dH), destData = destImg.data, lanczos = this.lanczosCreate(this.lanczosLobes), ratioX = this.rcpScaleX, ratioY = this.rcpScaleY, rcpRatioX = 2 / this.rcpScaleX, rcpRatioY = 2 / this.rcpScaleY, range2X = ceil(ratioX * this.lanczosLobes / 2), range2Y = ceil(ratioY * this.lanczosLobes / 2), cacheLanc = {}, center = {}, icenter = {}; return process(0); }, bilinearFiltering: function(options, oW, oH, dW, dH) { @@ -11029,10 +11264,6 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) { fabric.warn("fabric.Text is already defined"); return; } - var stateProperties = fabric.Object.prototype.stateProperties.concat(); - stateProperties.push("fontFamily", "fontWeight", "fontSize", "text", "underline", "overline", "linethrough", "textAlign", "fontStyle", "lineHeight", "textBackgroundColor", "charSpacing", "styles"); - var cacheProperties = fabric.Object.prototype.cacheProperties.concat(); - cacheProperties.push("fontFamily", "fontWeight", "fontSize", "text", "underline", "overline", "linethrough", "textAlign", "fontStyle", "lineHeight", "textBackgroundColor", "charSpacing", "styles"); fabric.Text = fabric.util.createClass(fabric.Object, { _dimensionAffectingProps: [ "fontSize", "fontWeight", "fontFamily", "fontStyle", "lineHeight", "text", "charSpacing", "textAlign", "styles" ], _reNewline: /\r?\n/, @@ -11050,8 +11281,8 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) { fontStyle: "normal", lineHeight: 1.16, textBackgroundColor: "", - stateProperties: stateProperties, - cacheProperties: cacheProperties, + stateProperties: fabric.Object.prototype.stateProperties.concat("fontFamily", "fontWeight", "fontSize", "text", "underline", "overline", "linethrough", "textAlign", "fontStyle", "lineHeight", "textBackgroundColor", "charSpacing", "styles"), + cacheProperties: fabric.Object.prototype.cacheProperties.concat("fontFamily", "fontWeight", "fontSize", "text", "underline", "overline", "linethrough", "textAlign", "fontStyle", "lineHeight", "textBackgroundColor", "charSpacing", "styles"), stroke: null, shadow: null, _fontSizeFraction: .222, @@ -11084,25 +11315,35 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) { } return fabric._measuringContext; }, + _splitText: function() { + var newLines = this._splitTextIntoLines(this.text); + this.textLines = newLines.lines; + this._textLines = newLines.graphemeLines; + this._unwrappedTextLines = newLines._unwrappedLines; + this._text = newLines.graphemeText; + return newLines; + }, initDimensions: function() { if (this.__skipDimension) { return; } - var newLines = this._splitTextIntoLines(this.text); - this.textLines = newLines.lines; - this._unwrappedTextLines = newLines._unwrappedLines; - this._textLines = newLines.graphemeLines; - this._text = newLines.graphemeText; + this._splitText(); this._clearCache(); this.width = this.calcTextWidth() || this.cursorWidth || MIN_TEXT_WIDTH; - if (this.textAlign === "justify") { + if (this.textAlign.indexOf("justify") !== -1) { this.enlargeSpaces(); } this.height = this.calcTextHeight(); + this.saveState({ + propertySet: "_dimensionAffectingProps" + }); }, enlargeSpaces: function() { var diffSpace, currentLineWidth, numberOfSpaces, accumulatedSpace, line, charBound, spaces; for (var i = 0, len = this._textLines.length; i < len; i++) { + if (this.textAlign !== "justify" && (i === len - 1 || this.isEndOfWrapping(i))) { + continue; + } accumulatedSpace = 0; line = this._textLines[i]; currentLineWidth = this.getLineWidth(i); @@ -11123,15 +11364,18 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) { } } }, + isEndOfWrapping: function(lineIndex) { + return lineIndex === this._textLines.length - 1; + }, toString: function() { return "#'; }, _getCacheCanvasDimensions: function() { - var dim = this.callSuper("_getCacheCanvasDimensions"); + var dims = this.callSuper("_getCacheCanvasDimensions"); var fontSize = this.fontSize; - dim.width += fontSize * dim.zoomX; - dim.height += fontSize * dim.zoomY; - return dim; + dims.width += fontSize * dims.zoomX; + dims.height += fontSize * dims.zoomY; + return dims; }, _render: function(ctx) { this._setTextStyles(ctx); @@ -11142,8 +11386,13 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) { this._renderTextDecoration(ctx, "linethrough"); }, _renderText: function(ctx) { - this._renderTextFill(ctx); - this._renderTextStroke(ctx); + if (this.paintFirst === "stroke") { + this._renderTextStroke(ctx); + this._renderTextFill(ctx); + } else { + this._renderTextFill(ctx); + this._renderTextStroke(ctx); + } }, _setTextStyles: function(ctx, charStyle, forMeasuring) { ctx.textBaseline = "alphabetic"; @@ -11367,7 +11616,7 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) { ctx.restore(); }, _renderChars: function(method, ctx, line, left, top, lineIndex) { - var lineHeight = this.getHeightOfLine(lineIndex), actualStyle, nextStyle, charsToRender = "", charBox, boxWidth = 0, timeToRender; + var lineHeight = this.getHeightOfLine(lineIndex), isJustify = this.textAlign.indexOf("justify") !== -1, actualStyle, nextStyle, charsToRender = "", charBox, boxWidth = 0, timeToRender; ctx.save(); top -= lineHeight * this._fontSizeFraction / this.lineHeight; for (var i = 0, len = line.length - 1; i <= len; i++) { @@ -11376,9 +11625,11 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) { charBox = this.__charBounds[lineIndex][i]; if (boxWidth === 0) { left += charBox.kernedWidth - charBox.width; + boxWidth += charBox.width; + } else { + boxWidth += charBox.kernedWidth; } - boxWidth += charBox.kernedWidth; - if (this.textAlign === "justify" && !timeToRender) { + if (isJustify && !timeToRender) { if (this._reSpaceAndTab.test(line[i])) { timeToRender = true; } @@ -11415,6 +11666,9 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) { _hasStyleChanged: function(prevStyle, thisStyle) { 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; }, + _hasStyleChangedForSvg: function(prevStyle, thisStyle) { + return this._hasStyleChanged(prevStyle, thisStyle) || prevStyle.overline !== thisStyle.overline || prevStyle.underline !== thisStyle.underline || prevStyle.linethrough !== thisStyle.linethrough; + }, _getLineLeftOffset: function(lineIndex) { var lineWidth = this.getLineWidth(lineIndex); if (this.textAlign === "center") { @@ -11423,21 +11677,23 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) { if (this.textAlign === "right") { return this.width - lineWidth; } + if (this.textAlign === "justify-center" && this.isEndOfWrapping(lineIndex)) { + return (this.width - lineWidth) / 2; + } + if (this.textAlign === "justify-right" && this.isEndOfWrapping(lineIndex)) { + return this.width - lineWidth; + } return 0; }, _clearCache: function() { this.__lineWidths = []; this.__lineHeights = []; - this.__numberOfSpaces = []; this.__charBounds = []; }, _shouldClearDimensionCache: function() { var shouldClear = this._forceClearCache; shouldClear || (shouldClear = this.hasStateChanged("_dimensionAffectingProps")); if (shouldClear) { - this.saveState({ - propertySet: "_dimensionAffectingProps" - }); this.dirty = true; this._forceClearCache = false; } @@ -11455,7 +11711,6 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) { width = lineInfo.width; } this.__lineWidths[lineIndex] = width; - this.__numberOfSpaces[lineIndex] = lineInfo.numberOfSpaces; return width; }, _getWidthOfCharSpacing: function() { @@ -11543,12 +11798,21 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) { obj.styles = clone(this.styles, true); return obj; }, - _set: function(key, value) { - this.callSuper("_set", key, value); - if (this._dimensionAffectingProps.indexOf(key) > -1) { + set: function(key, value) { + this.callSuper("set", key, value); + var needsDims = false; + if (typeof key === "object") { + for (var _key in key) { + needsDims = needsDims || this._dimensionAffectingProps.indexOf(_key) !== -1; + } + } else { + needsDims = this._dimensionAffectingProps.indexOf(key) !== -1; + } + if (needsDims) { this.initDimensions(); this.setCoords(); } + return this; }, complexity: function() { return 1; @@ -11869,16 +12133,15 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) { }, _render: function(ctx) { this.callSuper("_render", ctx); - this.ctx = ctx; }, clearContextTop: function(skipRestore) { if (!this.isEditing) { return; } if (this.canvas && this.canvas.contextTop) { - var ctx = this.canvas.contextTop; + var ctx = this.canvas.contextTop, v = this.canvas.viewportTransform; ctx.save(); - ctx.transform.apply(ctx, this.canvas.viewportTransform); + ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]); this.transform(ctx); this.transformMatrix && ctx.transform.apply(ctx, this.transformMatrix); this._clearTextArea(ctx); @@ -11886,7 +12149,7 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) { } }, renderCursorOrSelection: function() { - if (!this.isEditing) { + if (!this.isEditing || !this.canvas) { return; } var boundaries = this._getCursorBoundaries(), ctx; @@ -11894,7 +12157,7 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) { ctx = this.canvas.contextTop; this.clearContextTop(true); } else { - ctx = this.ctx; + ctx = this.canvas.contextContainer; ctx.save(); } if (this.selectionStart === this.selectionEnd) { @@ -11952,14 +12215,14 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) { ctx.fillRect(boundaries.left + boundaries.leftOffset - cursorWidth / 2, topOffset + boundaries.top, cursorWidth, charHeight); }, renderSelection: function(boundaries, ctx) { - var selectionStart = this.inCompositionMode ? this.hiddenTextarea.selectionStart : this.selectionStart, selectionEnd = this.inCompositionMode ? this.hiddenTextarea.selectionEnd : this.selectionEnd, start = this.get2DCursorLocation(selectionStart), end = this.get2DCursorLocation(selectionEnd), startLine = start.lineIndex, endLine = end.lineIndex, startChar = start.charIndex < 0 ? 0 : start.charIndex, endChar = end.charIndex < 0 ? 0 : end.charIndex; + var selectionStart = this.inCompositionMode ? this.hiddenTextarea.selectionStart : this.selectionStart, selectionEnd = this.inCompositionMode ? this.hiddenTextarea.selectionEnd : this.selectionEnd, isJustify = this.textAlign.indexOf("justify") !== -1, start = this.get2DCursorLocation(selectionStart), end = this.get2DCursorLocation(selectionEnd), startLine = start.lineIndex, endLine = end.lineIndex, startChar = start.charIndex < 0 ? 0 : start.charIndex, endChar = end.charIndex < 0 ? 0 : end.charIndex; for (var i = startLine; i <= endLine; i++) { var lineOffset = this._getLineLeftOffset(i) || 0, lineHeight = this.getHeightOfLine(i), realLineHeight = 0, boxStart = 0, boxEnd = 0; if (i === startLine) { boxStart = this.__charBounds[startLine][startChar].left; } if (i >= startLine && i < endLine) { - boxEnd = this.getLineWidth(i) || 5; + boxEnd = isJustify && !this.isEndOfWrapping(i) ? this.width : this.getLineWidth(i) || 5; } else if (i === endLine) { if (endChar === 0) { boxEnd = this.__charBounds[endLine][endChar].left; @@ -12113,14 +12376,14 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) { }, delay); }, abortCursorAnimation: function() { - var shouldClear = this._currentTickState || this._currentTickCompleteState; + var shouldClear = this._currentTickState || this._currentTickCompleteState, canvas = this.canvas; this._currentTickState && this._currentTickState.abort(); this._currentTickCompleteState && this._currentTickCompleteState.abort(); clearTimeout(this._cursorTimeout1); clearTimeout(this._cursorTimeout2); this._currentCursorOpacity = 0; - if (shouldClear) { - this.canvas && this.canvas.clearContext(this.canvas.contextTop || this.ctx); + if (shouldClear && canvas) { + canvas.clearContext(canvas.contextTop || canvas.contextContainer); } }, selectAll: function() { @@ -12324,6 +12587,10 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) { } this.cursorOffsetCache = {}; this.text = this.hiddenTextarea.value; + if (this._shouldClearDimensionCache()) { + this.initDimensions(); + this.setCoords(); + } var newSelection = this.fromStringToGraphemeSelection(this.hiddenTextarea.selectionStart, this.hiddenTextarea.selectionEnd, this.hiddenTextarea.value); this.selectionEnd = this.selectionStart = newSelection.selectionEnd; if (!this.inCompositionMode) { @@ -12411,6 +12678,10 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) { this.abortCursorAnimation(); this._restoreEditingProps(); this._currentCursorOpacity = 0; + if (this._shouldClearDimensionCache()) { + this.initDimensions(); + this.setCoords(); + } this.fire("editing:exited"); isTextChanged && this.fire("modified"); if (this.canvas) { @@ -12573,10 +12844,13 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) { copiedStyle = copiedStyle && copiedStyle.slice(addedLines[0] + 1); } linesLenght && this.insertNewlineStyleObject(cursorLoc.lineIndex, cursorLoc.charIndex + addedLines[0], linesLenght); - for (var i = 1; i <= linesLenght; i++) { + for (var i = 1; i < linesLenght; i++) { this.insertCharStyleObject(cursorLoc.lineIndex + i, 0, addedLines[i], copiedStyle); copiedStyle = copiedStyle && copiedStyle.slice(addedLines[i] + 1); } + if (addedLines[i] > 0) { + this.insertCharStyleObject(cursorLoc.lineIndex + i, 0, addedLines[i], copiedStyle); + } }, setSelectionStartEndWithShift: function(start, end, newSelection) { if (newSelection <= start) { @@ -12853,19 +13127,25 @@ fabric.util.object.extend(fabric.IText.prototype, { }); this.canvas.requestRenderAll(); } + return; } + var textareaSelection = this.fromStringToGraphemeSelection(this.hiddenTextarea.selectionStart, this.hiddenTextarea.selectionEnd, this.hiddenTextarea.value); + var backDelete = this.selectionStart > textareaSelection.selectionStart; if (this.selectionStart !== this.selectionEnd) { removedText = this._text.slice(this.selectionStart, this.selectionEnd); charDiff += this.selectionEnd - this.selectionStart; } else if (nextCharCount < charCount) { - removedText = this._text.slice(this.selectionEnd + charDiff, this.selectionEnd); + if (backDelete) { + removedText = this._text.slice(this.selectionEnd + charDiff, this.selectionEnd); + } else { + removedText = this._text.slice(this.selectionStart, this.selectionStart - charDiff); + } } - var textareaSelection = this.fromStringToGraphemeSelection(this.hiddenTextarea.selectionStart, this.hiddenTextarea.selectionEnd, this.hiddenTextarea.value); insertedText = nextText.slice(textareaSelection.selectionEnd - charDiff, textareaSelection.selectionEnd); if (removedText && removedText.length) { if (this.selectionStart !== this.selectionEnd) { this.removeStyleFromTo(this.selectionStart, this.selectionEnd); - } else if (this.selectionStart > textareaSelection.selectionStart) { + } else if (backDelete) { this.removeStyleFromTo(this.selectionEnd - removedText.length, this.selectionEnd); } else { this.removeStyleFromTo(this.selectionEnd, this.selectionEnd + removedText.length); @@ -13096,8 +13376,11 @@ fabric.util.object.extend(fabric.IText.prototype, { this.set("dirty", true); this.setSelectionEnd(this.selectionStart); this._removeExtraneousStyles(); + if (this._shouldClearDimensionCache()) { + this.initDimensions(); + this.setCoords(); + } this.canvas && this.canvas.requestRenderAll(); - this.setCoords(); this.fire("changed"); this.canvas && this.canvas.fire("text:changed", { target: this @@ -13138,8 +13421,8 @@ fabric.util.object.extend(fabric.IText.prototype, { }; }, _wrapSVGTextAndBg: function(markup, textAndBg) { - var noShadow = true, filter = this.getSvgFilter(), style = filter === "" ? "" : ' style="' + filter + '"'; - markup.push("\t\n", textAndBg.textBgRects.join(""), '\t\t\n', textAndBg.textSpans.join(""), "\t\t\n", "\t\n"); + var noShadow = true, filter = this.getSvgFilter(), style = filter === "" ? "" : ' style="' + filter + '"', textDecoration = this.getSvgTextDecoration(this); + markup.push("\t\n", textAndBg.textBgRects.join(""), '\t\t\n", textAndBg.textSpans.join(""), "\t\t\n", "\t\n"); }, _getSVGTextAndBg: function(textTopOffset, textLeftOffset) { var textSpans = [], textBgRects = [], height = textTopOffset, lineOffset; @@ -13162,7 +13445,7 @@ fabric.util.object.extend(fabric.IText.prototype, { return [ '\t\t\t", fabric.util.string.escapeXml(_char), "\n" ].join(""); }, _setSVGTextLineText: function(textSpans, lineIndex, textLeftOffset, textTopOffset) { - var lineHeight = this.getHeightOfLine(lineIndex), actualStyle, nextStyle, charsToRender = "", charBox, style, boxWidth = 0, line = this._textLines[lineIndex], timeToRender; + var lineHeight = this.getHeightOfLine(lineIndex), isJustify = this.textAlign.indexOf("justify") !== -1, actualStyle, nextStyle, charsToRender = "", charBox, style, boxWidth = 0, line = this._textLines[lineIndex], timeToRender; textTopOffset += lineHeight * (1 - this._fontSizeFraction) / this.lineHeight; for (var i = 0, len = line.length - 1; i <= len; i++) { timeToRender = i === len || this.charSpacing; @@ -13170,9 +13453,11 @@ fabric.util.object.extend(fabric.IText.prototype, { charBox = this.__charBounds[lineIndex][i]; if (boxWidth === 0) { textLeftOffset += charBox.kernedWidth - charBox.width; + boxWidth += charBox.width; + } else { + boxWidth += charBox.kernedWidth; } - boxWidth += charBox.kernedWidth; - if (this.textAlign === "justify" && !timeToRender) { + if (isJustify && !timeToRender) { if (this._reSpaceAndTab.test(line[i])) { timeToRender = true; } @@ -13180,7 +13465,7 @@ fabric.util.object.extend(fabric.IText.prototype, { if (!timeToRender) { actualStyle = actualStyle || this.getCompleteStyleDeclaration(lineIndex, i); nextStyle = this.getCompleteStyleDeclaration(lineIndex, i + 1); - timeToRender = this._hasStyleChanged(actualStyle, nextStyle); + timeToRender = this._hasStyleChangedForSvg(actualStyle, nextStyle); } if (timeToRender) { style = this._getStyleDeclaration(lineIndex, i) || {}; @@ -13246,10 +13531,9 @@ fabric.util.object.extend(fabric.IText.prototype, { __cachedLines: null, lockScalingFlip: true, noScaleCache: false, + _dimensionAffectingProps: fabric.Text.prototype._dimensionAffectingProps.concat("width"), initialize: function(text, options) { this.callSuper("initialize", text, options); - this.ctx = this.objectCaching ? this._cacheContext : fabric.util.createCanvasElement().getContext("2d"); - this._dimensionAffectingProps.push("width"); }, initDimensions: function() { if (this.__skipDimension) { @@ -13259,19 +13543,17 @@ fabric.util.object.extend(fabric.IText.prototype, { this.clearContextTop(); this._clearCache(); this.dynamicMinWidth = 0; - var newText = this._splitTextIntoLines(this.text); - this.textLines = newText.lines; - this._textLines = newText.graphemeLines; - this._unwrappedTextLines = newText._unwrappedLines; - this._text = newText.graphemeText; - this._styleMap = this._generateStyleMap(newText); + this._styleMap = this._generateStyleMap(this._splitText()); if (this.dynamicMinWidth > this.width) { this._set("width", this.dynamicMinWidth); } - if (this.textAlign === "justify") { + if (this.textAlign.indexOf("justify") !== -1) { this.enlargeSpaces(); } this.height = this.calcTextHeight(); + this.saveState({ + propertySet: "_dimensionAffectingProps" + }); }, _generateStyleMap: function(textInfo) { var realLineCount = 0, realLineCharCount = 0, charCount = 0, map = {}; @@ -13386,6 +13668,15 @@ fabric.util.object.extend(fabric.IText.prototype, { } return graphemeLines; }, + isEndOfWrapping: function(lineIndex) { + if (!this._styleMap[lineIndex + 1]) { + return true; + } + if (this._styleMap[lineIndex + 1].line !== this._styleMap[lineIndex].line) { + return true; + } + return false; + }, _splitTextIntoLines: function(text) { var newText = fabric.Text.prototype._splitTextIntoLines.call(this, text), graphemeLines = this._wrapText(newText.lines, this.width), lines = new Array(graphemeLines.length); for (var i = 0; i < graphemeLines.length; i++) { @@ -13433,160 +13724,6 @@ fabric.util.object.extend(fabric.IText.prototype, { }); })(); -(function() { - if (typeof document !== "undefined" && typeof window !== "undefined") { - return; - } - var DOMParser = require("xmldom").DOMParser, URL = require("url"), HTTP = require("http"), HTTPS = require("https"), Canvas = require(fabric.canvasModule), Image = require(fabric.canvasModule).Image; - function request(url, encoding, callback) { - var oURL = URL.parse(url); - if (!oURL.port) { - oURL.port = oURL.protocol.indexOf("https:") === 0 ? 443 : 80; - } - var reqHandler = oURL.protocol.indexOf("https:") === 0 ? HTTPS : HTTP, req = reqHandler.request({ - hostname: oURL.hostname, - port: oURL.port, - path: oURL.path, - method: "GET" - }, function(response) { - var body = ""; - if (encoding) { - response.setEncoding(encoding); - } - response.on("end", function() { - callback(body); - }); - response.on("data", function(chunk) { - if (response.statusCode === 200) { - body += chunk; - } - }); - }); - req.on("error", function(err) { - if (err.errno === process.ECONNREFUSED) { - fabric.log("ECONNREFUSED: connection refused to " + oURL.hostname + ":" + oURL.port); - } else { - fabric.log(err.message); - } - callback(null); - }); - req.end(); - } - function requestFs(path, callback) { - var fs = require("fs"); - fs.readFile(path, function(err, data) { - if (err) { - fabric.log(err); - throw err; - } else { - callback(data); - } - }); - } - fabric.util.loadImage = function(url, callback, context) { - function createImageAndCallBack(data) { - if (data) { - img.src = new Buffer(data, "binary"); - img._src = url; - callback && callback.call(context, img); - } else { - img = null; - callback && callback.call(context, null, true); - } - } - var img = new Image(); - if (url && (url instanceof Buffer || url.indexOf("data") === 0)) { - img.src = img._src = url; - callback && callback.call(context, img); - } else if (url && url.indexOf("http") !== 0) { - requestFs(url, createImageAndCallBack); - } else if (url) { - request(url, "binary", createImageAndCallBack); - } else { - callback && callback.call(context, url); - } - }; - fabric.loadSVGFromURL = function(url, callback, reviver) { - url = url.replace(/^\n\s*/, "").replace(/\?.*$/, "").trim(); - if (url.indexOf("http") !== 0) { - requestFs(url, function(body) { - fabric.loadSVGFromString(body.toString(), callback, reviver); - }); - } else { - request(url, "", function(body) { - fabric.loadSVGFromString(body, callback, reviver); - }); - } - }; - fabric.loadSVGFromString = function(string, callback, reviver) { - var doc = new DOMParser().parseFromString(string); - fabric.parseSVGDocument(doc.documentElement, function(results, options) { - callback && callback(results, options); - }, reviver); - }; - fabric.util.getScript = function(url, callback) { - request(url, "", function(body) { - eval(body); - callback && callback(); - }); - }; - fabric.createCanvasForNode = function(width, height, options, nodeCanvasOptions) { - nodeCanvasOptions = nodeCanvasOptions || options; - var canvasEl = fabric.document.createElement("canvas"), nodeCanvas = new Canvas(width || 600, height || 600, nodeCanvasOptions), nodeCacheCanvas = new Canvas(width || 600, height || 600, nodeCanvasOptions); - canvasEl.width = nodeCanvas.width; - canvasEl.height = nodeCanvas.height; - options = options || {}; - options.nodeCanvas = nodeCanvas; - options.nodeCacheCanvas = nodeCacheCanvas; - var FabricCanvas = fabric.Canvas || fabric.StaticCanvas, fabricCanvas = new FabricCanvas(canvasEl, options); - fabricCanvas.nodeCanvas = nodeCanvas; - fabricCanvas.nodeCacheCanvas = nodeCacheCanvas; - fabricCanvas.contextContainer = nodeCanvas.getContext("2d"); - fabricCanvas.contextCache = nodeCacheCanvas.getContext("2d"); - fabricCanvas.Font = Canvas.Font; - return fabricCanvas; - }; - var originaInitStatic = fabric.StaticCanvas.prototype._initStatic; - fabric.StaticCanvas.prototype._initStatic = function(el, options) { - el = el || fabric.document.createElement("canvas"); - this.nodeCanvas = new Canvas(el.width, el.height); - this.nodeCacheCanvas = new Canvas(el.width, el.height); - originaInitStatic.call(this, el, options); - this.contextContainer = this.nodeCanvas.getContext("2d"); - this.contextCache = this.nodeCacheCanvas.getContext("2d"); - this.Font = Canvas.Font; - }; - fabric.StaticCanvas.prototype.createPNGStream = function() { - return this.nodeCanvas.createPNGStream(); - }; - fabric.StaticCanvas.prototype.createJPEGStream = function(opts) { - return this.nodeCanvas.createJPEGStream(opts); - }; - fabric.StaticCanvas.prototype._initRetinaScaling = function() { - if (!this._isRetinaScaling()) { - return; - } - this.lowerCanvasEl.setAttribute("width", this.width * fabric.devicePixelRatio); - this.lowerCanvasEl.setAttribute("height", this.height * fabric.devicePixelRatio); - this.nodeCanvas.width = this.width * fabric.devicePixelRatio; - this.nodeCanvas.height = this.height * fabric.devicePixelRatio; - this.contextContainer.scale(fabric.devicePixelRatio, fabric.devicePixelRatio); - return this; - }; - if (fabric.Canvas) { - fabric.Canvas.prototype._initRetinaScaling = fabric.StaticCanvas.prototype._initRetinaScaling; - } - var origSetBackstoreDimension = fabric.StaticCanvas.prototype._setBackstoreDimension; - fabric.StaticCanvas.prototype._setBackstoreDimension = function(prop, value) { - origSetBackstoreDimension.call(this, prop, value); - this.nodeCanvas[prop] = value; - return this; - }; - if (fabric.Canvas) { - fabric.Canvas.prototype._setBackstoreDimension = fabric.StaticCanvas.prototype._setBackstoreDimension; - } -})(); - window.fabric = fabric; if (typeof define === "function" && define.amd) { diff --git a/package.json b/package.json index 3be462b7..f7f3f422 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "fabric", "description": "Object model for HTML5 canvas, and SVG-to-canvas parser. Backed by jsdom and node-canvas.", "homepage": "http://fabricjs.com/", - "version": "2.0.0-beta.7", + "version": "2.0.0-rc.1", "author": "Juriy Zaytsev ", "contributors": [ {