From de99a508c2d2b5458d46aff2a7aa1f90eb684818 Mon Sep 17 00:00:00 2001 From: Stefan Kienzle Date: Mon, 7 Jul 2014 16:18:31 +0200 Subject: [PATCH 1/4] Make setCursor public. JSCS tweaks. --- src/canvas.class.js | 34 ++++++++++++++++++++--------- src/mixins/canvas_events.mixin.js | 18 +++++++++------ src/mixins/canvas_grouping.mixin.js | 10 ++++++--- 3 files changed, 42 insertions(+), 20 deletions(-) diff --git a/src/canvas.class.js b/src/canvas.class.js index a6865c03..7e00d2d6 100644 --- a/src/canvas.class.js +++ b/src/canvas.class.js @@ -339,7 +339,9 @@ * @param {fabric.Object} target */ _shouldCenterTransform: function (e, target) { - if (!target) return; + if (!target) { + return; + } var t = this._currentTransform, centerTransform; @@ -403,7 +405,9 @@ * @param {fabric.Object} target */ _setupCurrentTransform: function (e, target) { - if (!target) return; + if (!target) { + return; + } var pointer = this.getPointer(e), corner = target._findTargetCorner(this.getPointer(e, true)), @@ -472,7 +476,9 @@ lockScalingX = target.get('lockScalingX'), lockScalingY = target.get('lockScalingY'); - if (lockScalingX && lockScalingY) return; + if (lockScalingX && lockScalingY) { + return; + } // Get the constraint point var constraintPosition = target.translateToOriginPoint(target.getCenterPoint(), t.originX, t.originY), @@ -616,14 +622,16 @@ /** * Rotates object by invoking its rotate method * @private - * @param x {Number} pointer's x coordinate - * @param y {Number} pointer's y coordinate + * @param {Number} x pointer's x coordinate + * @param {Number} y pointer's y coordinate */ _rotateObject: function (x, y) { var t = this._currentTransform; - if (t.target.get('lockRotation')) return; + if (t.target.get('lockRotation')) { + return; + } var lastAngle = atan2(t.ey - t.top, t.ex - t.left), curAngle = atan2(y - t.top, x - t.left), @@ -638,9 +646,11 @@ }, /** - * @private + * Set the cursor type of the canvas element + * @param {String} value Cursor type of the canvas element. + * @see http://www.w3.org/TR/css3-ui/#cursor */ - _setCursor: function (value) { + setCursor: function (value) { this.upperCanvasEl.style.cursor = value; }, @@ -720,7 +730,9 @@ * @param {Boolean} skipGroup when true, group is skipped and only objects are traversed through */ findTarget: function (e, skipGroup) { - if (this.skipTargetFind) return; + if (this.skipTargetFind) { + return; + } if (this._isLastRenderedObject(e)) { return this.lastRenderedObjectWithControlsAboveOverlay; @@ -1100,7 +1112,9 @@ */ _drawObjectsControls: function(ctx) { for (var i = 0, len = this._objects.length; i < len; ++i) { - if (!this._objects[i] || !this._objects[i].active) continue; + if (!this._objects[i] || !this._objects[i].active) { + continue; + } this._objects[i]._renderControls(ctx); this.lastRenderedObjectWithControlsAboveOverlay = this._objects[i]; } diff --git a/src/mixins/canvas_events.mixin.js b/src/mixins/canvas_events.mixin.js index 353b5abf..54d48daa 100644 --- a/src/mixins/canvas_events.mixin.js +++ b/src/mixins/canvas_events.mixin.js @@ -334,8 +334,8 @@ if (this.clipTo) { fabric.util.clipContext(this, this.contextTop); } - var ivt = fabric.util.invertTransform(this.viewportTransform); - var pointer = fabric.util.transformPoint(this.getPointer(e, true), ivt); + var ivt = fabric.util.invertTransform(this.viewportTransform), + pointer = fabric.util.transformPoint(this.getPointer(e, true), ivt); this.freeDrawingBrush.onMouseDown(pointer); this.fire('mouse:down', { e: e }); }, @@ -350,7 +350,7 @@ pointer = fabric.util.transformPoint(this.getPointer(e, true), ivt); this.freeDrawingBrush.onMouseMove(pointer); } - this.upperCanvasEl.style.cursor = this.freeDrawingCursor; + this.setCursor(this.freeDrawingCursor); this.fire('mouse:move', { e: e }); }, @@ -379,7 +379,9 @@ // accept only left clicks var isLeftClick = 'which' in e ? e.which === 1 : e.button === 1; - if (!isLeftClick && !fabric.isTouchSupported) return; + if (!isLeftClick && !fabric.isTouchSupported) { + return; + } if (this.isDrawingMode) { this._onMouseDownInDrawingMode(e); @@ -387,7 +389,9 @@ } // ignore if some object is being transformed at this moment - if (this._currentTransform) return; + if (this._currentTransform) { + return; + } var target = this.findTarget(e), pointer = this.getPointer(e, true); @@ -529,7 +533,7 @@ target = this.findTarget(e); if (!target || target && !target.selectable) { - this.upperCanvasEl.style.cursor = this.defaultCursor; + this.setCursor(this.defaultCursor); } else { this._setCursorFromEvent(e, target); @@ -588,7 +592,7 @@ else { this._translateObject(x, y); this._fire('moving', target, e); - this._setCursor(this.moveCursor); + this.setCursor(this.moveCursor); } }, diff --git a/src/mixins/canvas_grouping.mixin.js b/src/mixins/canvas_grouping.mixin.js index 54f5877e..e0821a43 100644 --- a/src/mixins/canvas_grouping.mixin.js +++ b/src/mixins/canvas_grouping.mixin.js @@ -156,7 +156,9 @@ for (var i = this._objects.length; i--; ) { currentObject = this._objects[i]; - if (!currentObject || !currentObject.selectable || !currentObject.visible) continue; + if (!currentObject || !currentObject.selectable || !currentObject.visible) { + continue; + } if (currentObject.intersectsWithRect(selectionX1Y1, selectionX2Y2) || currentObject.isContainedWithinRect(selectionX1Y1, selectionX2Y2) || @@ -167,7 +169,9 @@ group.push(currentObject); // only add one object if it's a click - if (isClick) break; + if (isClick) { + break; + } } } @@ -186,7 +190,7 @@ if (activeGroup) { activeGroup.setObjectsCoords().setCoords(); activeGroup.isMoving = false; - this._setCursor(this.defaultCursor); + this.setCursor(this.defaultCursor); } // clear selection and current transformation From 6df9412bf74ddb8f684fb05cecf1d40230ed26ee Mon Sep 17 00:00:00 2001 From: Simon van Lankveld Date: Tue, 8 Jul 2014 21:49:20 +1200 Subject: [PATCH 2/4] Changing isVML to a function so that the G_vmlCanvasManager can be evaluated when needed instead a single time at the beginning. --- src/mixins/object_interactivity.mixin.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mixins/object_interactivity.mixin.js b/src/mixins/object_interactivity.mixin.js index ac1f6d60..e3738d8e 100644 --- a/src/mixins/object_interactivity.mixin.js +++ b/src/mixins/object_interactivity.mixin.js @@ -1,7 +1,7 @@ (function(){ var degreesToRadians = fabric.util.degreesToRadians, - isVML = typeof G_vmlCanvasManager !== 'undefined'; + isVML = function() { return typeof G_vmlCanvasManager !== 'undefined'; }; fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ { @@ -411,7 +411,7 @@ var size = this.cornerSize; if (this.isControlVisible(control)) { - isVML || this.transparentCorners || ctx.clearRect(left, top, size, size); + isVML() || this.transparentCorners || ctx.clearRect(left, top, size, size); ctx[methodName](left, top, size, size); } }, From 9ad2279e8a06e689d0d897ff6d3508c1be466935 Mon Sep 17 00:00:00 2001 From: Stefan Kienzle Date: Tue, 8 Jul 2014 13:32:58 +0200 Subject: [PATCH 3/4] Revert JSCS tweaks for single-line return statements. --- src/canvas.class.js | 24 ++++++------------------ src/mixins/canvas_events.mixin.js | 22 +++++++--------------- src/mixins/canvas_grouping.mixin.js | 8 ++------ 3 files changed, 15 insertions(+), 39 deletions(-) diff --git a/src/canvas.class.js b/src/canvas.class.js index 7e00d2d6..35965847 100644 --- a/src/canvas.class.js +++ b/src/canvas.class.js @@ -339,9 +339,7 @@ * @param {fabric.Object} target */ _shouldCenterTransform: function (e, target) { - if (!target) { - return; - } + if (!target) return; var t = this._currentTransform, centerTransform; @@ -405,9 +403,7 @@ * @param {fabric.Object} target */ _setupCurrentTransform: function (e, target) { - if (!target) { - return; - } + if (!target) return; var pointer = this.getPointer(e), corner = target._findTargetCorner(this.getPointer(e, true)), @@ -476,9 +472,7 @@ lockScalingX = target.get('lockScalingX'), lockScalingY = target.get('lockScalingY'); - if (lockScalingX && lockScalingY) { - return; - } + if (lockScalingX && lockScalingY) return; // Get the constraint point var constraintPosition = target.translateToOriginPoint(target.getCenterPoint(), t.originX, t.originY), @@ -629,9 +623,7 @@ var t = this._currentTransform; - if (t.target.get('lockRotation')) { - return; - } + if (t.target.get('lockRotation')) return; var lastAngle = atan2(t.ey - t.top, t.ex - t.left), curAngle = atan2(y - t.top, x - t.left), @@ -730,9 +722,7 @@ * @param {Boolean} skipGroup when true, group is skipped and only objects are traversed through */ findTarget: function (e, skipGroup) { - if (this.skipTargetFind) { - return; - } + if (this.skipTargetFind) return; if (this._isLastRenderedObject(e)) { return this.lastRenderedObjectWithControlsAboveOverlay; @@ -1112,9 +1102,7 @@ */ _drawObjectsControls: function(ctx) { for (var i = 0, len = this._objects.length; i < len; ++i) { - if (!this._objects[i] || !this._objects[i].active) { - continue; - } + if (!this._objects[i] || !this._objects[i].active) continue; this._objects[i]._renderControls(ctx); this.lastRenderedObjectWithControlsAboveOverlay = this._objects[i]; } diff --git a/src/mixins/canvas_events.mixin.js b/src/mixins/canvas_events.mixin.js index 54d48daa..d2a80719 100644 --- a/src/mixins/canvas_events.mixin.js +++ b/src/mixins/canvas_events.mixin.js @@ -379,9 +379,7 @@ // accept only left clicks var isLeftClick = 'which' in e ? e.which === 1 : e.button === 1; - if (!isLeftClick && !fabric.isTouchSupported) { - return; - } + if (!isLeftClick && !fabric.isTouchSupported) return; if (this.isDrawingMode) { this._onMouseDownInDrawingMode(e); @@ -389,9 +387,7 @@ } // ignore if some object is being transformed at this moment - if (this._currentTransform) { - return; - } + if (this._currentTransform) return; var target = this.findTarget(e), pointer = this.getPointer(e, true); @@ -650,10 +646,8 @@ * @param {Object} target Object that the mouse is hovering, if so. */ _setCursorFromEvent: function (e, target) { - var style = this.upperCanvasEl.style; - if (!target || !target.selectable) { - style.cursor = this.defaultCursor; + this.setCursor(this.defaultCursor); return false; } else { @@ -664,7 +658,7 @@ && target._findTargetCorner(this.getPointer(e, true)); if (!corner) { - style.cursor = target.hoverCursor || this.hoverCursor; + this.setCursor(target.hoverCursor || this.hoverCursor); } else { this._setCornerCursor(corner, target); @@ -677,16 +671,14 @@ * @private */ _setCornerCursor: function(corner, target) { - var style = this.upperCanvasEl.style; - if (corner in cursorOffset) { - style.cursor = this._getRotatedCornerCursor(corner, target); + this.setCursor(this._getRotatedCornerCursor(corner, target)); } else if (corner === 'mtr' && target.hasRotatingPoint) { - style.cursor = this.rotationCursor; + this.setCursor(this.rotationCursor); } else { - style.cursor = this.defaultCursor; + this.setCursor(this.defaultCursor); return false; } }, diff --git a/src/mixins/canvas_grouping.mixin.js b/src/mixins/canvas_grouping.mixin.js index e0821a43..bee95e87 100644 --- a/src/mixins/canvas_grouping.mixin.js +++ b/src/mixins/canvas_grouping.mixin.js @@ -156,9 +156,7 @@ for (var i = this._objects.length; i--; ) { currentObject = this._objects[i]; - if (!currentObject || !currentObject.selectable || !currentObject.visible) { - continue; - } + if (!currentObject || !currentObject.selectable || !currentObject.visible) continue; if (currentObject.intersectsWithRect(selectionX1Y1, selectionX2Y2) || currentObject.isContainedWithinRect(selectionX1Y1, selectionX2Y2) || @@ -169,9 +167,7 @@ group.push(currentObject); // only add one object if it's a click - if (isClick) { - break; - } + if (isClick) break; } } From 01972adb86af7398f5342e7a58410f1848a30796 Mon Sep 17 00:00:00 2001 From: kangax Date: Wed, 9 Jul 2014 15:20:04 +0200 Subject: [PATCH 4/4] Version 1.4.8 --- HEADER.js | 2 +- bower.json | 2 +- dist/fabric.js | 826 ++++++++++++++++++++++++++--------------- dist/fabric.min.js | 14 +- dist/fabric.min.js.gz | Bin 54971 -> 56030 bytes dist/fabric.require.js | 826 ++++++++++++++++++++++++++--------------- package.json | 2 +- 7 files changed, 1050 insertions(+), 622 deletions(-) diff --git a/HEADER.js b/HEADER.js index 1d2d4bf5..cc4dc696 100644 --- a/HEADER.js +++ b/HEADER.js @@ -1,6 +1,6 @@ /*! Fabric.js Copyright 2008-2014, Printio (Juriy Zaytsev, Maxim Chernyak) */ -var fabric = fabric || { version: "1.4.7" }; +var fabric = fabric || { version: "1.4.8" }; if (typeof exports !== 'undefined') { exports.fabric = fabric; } diff --git a/bower.json b/bower.json index 2f74ec24..76bb5a66 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "fabric.js", - "version": "1.4.7", + "version": "1.4.8", "homepage": "http://fabricjs.com", "authors": [ "kangax", "Kienz" diff --git a/dist/fabric.js b/dist/fabric.js index 908f0f8d..7f334b56 100644 --- a/dist/fabric.js +++ b/dist/fabric.js @@ -1,7 +1,7 @@ /* build: `node build.js modules=ALL exclude=gestures,cufon,json minifier=uglifyjs` */ /*! Fabric.js Copyright 2008-2014, Printio (Juriy Zaytsev, Maxim Chernyak) */ -var fabric = fabric || { version: "1.4.7" }; +var fabric = fabric || { version: "1.4.8" }; if (typeof exports !== 'undefined') { exports.fabric = fabric; } @@ -395,6 +395,45 @@ fabric.Collection = { return new fabric.Point(rx, ry).addEquals(origin); }, + /** + * Apply transform t to point p + * @static + * @memberOf fabric.util + * @param {fabric.Point} p The point to transform + * @param {Array} t The transform + * @param {Boolean} [ignoreOffset] Indicates that the offset should not be applied + * @return {fabric.Point} The transformed point + */ + transformPoint: function(p, t, ignoreOffset) { + if (ignoreOffset) { + return new fabric.Point( + t[0] * p.x + t[1] * p.y, + t[2] * p.x + t[3] * p.y + ); + } + return new fabric.Point( + t[0] * p.x + t[1] * p.y + t[4], + t[2] * p.x + t[3] * p.y + t[5] + ); + }, + + /** + * Invert transformation t + * @static + * @memberOf fabric.util + * @param {Array} t The transform + * @return {Array} The inverted transform + */ + invertTransform: function(t) { + var r = t.slice(), + a = 1 / (t[0] * t[3] - t[1] * t[2]); + r = [a * t[3], -a * t[1], -a * t[2], a * t[0], 0, 0]; + var o = fabric.util.transformPoint({x: t[4], y: t[5]}, r); + r[4] = -o.x; + r[5] = -o.y; + return r; + }, + /** * A wrapper around Number#toFixed, which contrary to native method returns number, not string. * @static @@ -861,7 +900,7 @@ fabric.Collection = { else if (thArc > 0 && sweep === 0) { thArc -= 2 * Math.PI; } - + var segments = Math.ceil(Math.abs(thArc / (Math.PI * 0.5 + 0.001))), result = []; @@ -888,7 +927,9 @@ fabric.Collection = { var px = cosTh * (ox - x) + sinTh * (oy - y), py = cosTh * (oy - y) - sinTh * (ox - x), pl = (px * px) / (rx * rx) + (py * py) / (ry * ry); - pl *= 0.25; + + pl *= 0.25; + if (pl > 1) { pl = Math.sqrt(pl); rx *= pl; @@ -919,14 +960,15 @@ fabric.Collection = { var sinTh0 = Math.sin(th0), cosTh0 = Math.cos(th0), - sinTh1 = Math.sin(th1), - cosTh1 = Math.cos(th1); - - var a00 = cosTh * rx, + sinTh1 = Math.sin(th1), + cosTh1 = Math.cos(th1), + + a00 = cosTh * rx, a01 = -sinTh * ry, a10 = sinTh * rx, a11 = cosTh * ry, thHalf = 0.25 * (th1 - th0), + t = (8 / 3) * Math.sin(thHalf) * Math.sin(thHalf) / Math.sin(thHalf * 2), @@ -1369,7 +1411,9 @@ fabric.Collection = { IS_DONTENUM_BUGGY = (function(){ for (var p in { toString: 1 }) { - if (p === 'toString') return false; + if (p === 'toString') { + return false; + } } return true; })(), @@ -1472,7 +1516,9 @@ fabric.Collection = { t, i, len = methodNames.length; for (i = 0; i < len; i++) { t = typeof object[methodNames[i]]; - if (!(/^(?:function|object|unknown)$/).test(t)) return false; + if (!(/^(?:function|object|unknown)$/).test(t)) { + return false; + } } return true; } @@ -2983,13 +3029,44 @@ if (typeof console !== 'undefined') { if (ruleMatchesElement) { for (var property in fabric.cssRules[rule]) { - styles[property] = fabric.cssRules[rule][property]; + var attr = normalizeAttr(property), + value = normalizeValue(attr, fabric.cssRules[rule][property]); + styles[attr] = value; } } } return styles; } + + /** + * @private + */ + function parseUseDirectives(doc) { + var nodelist = doc.querySelectorAll("use"); + for (var i = 0; i < nodelist.length; i++) { + var el = nodelist[i]; + var xlink = el.getAttribute('xlink:href').substr(1); + var x = el.getAttribute('x') || 0; + var y = el.getAttribute('y') || 0; + var el2 = doc.getElementById(xlink).cloneNode(true); + var currentTrans = (el.getAttribute('transform') || '') + ' translate(' + x + ', ' + y + ')'; + for (var j = 0, attrs = el.attributes, l = attrs.length; j < l; j++) { + var attr = attrs.item(j); + if (attr.nodeName !== 'x' && attr.nodeName !== 'y' && attr.nodeName !== 'xlink:href') { + if (attr.nodeName === 'transform') { + currentTrans = currentTrans + ' ' + attr.nodeValue; + } else { + el2.setAttribute(attr.nodeName, attr.nodeValue); + } + } + } + el2.setAttribute('transform', currentTrans); + el2.removeAttribute('id'); + var pNode=el.parentNode; + pNode.replaceChild(el2, el); + } + } /** * Parses an SVG document, converts it to an array of corresponding fabric.* instances and passes them to a callback @@ -3030,9 +3107,11 @@ if (typeof console !== 'undefined') { return function(doc, callback, reviver) { if (!doc) return; - - var startTime = new Date(), - descendants = fabric.util.toArray(doc.getElementsByTagName('*')); + var startTime = new Date(); + + parseUseDirectives(doc); + + var descendants = fabric.util.toArray(doc.getElementsByTagName('*')); if (descendants.length === 0 && fabric.isLikelyNode) { // we're likely in node, where "o3-xml" library fails to gEBTN("*") @@ -3091,7 +3170,6 @@ if (typeof console !== 'undefined') { fabric.gradientDefs = fabric.getGradientDefs(doc); fabric.cssRules = fabric.getCSSRules(doc); - // Precedence of rules: style > class > attribute fabric.parseElements(elements, function(instances) { @@ -3107,46 +3185,46 @@ if (typeof console !== 'undefined') { * Used for caching SVG documents (loaded via `fabric.Canvas#loadSVGFromURL`) * @namespace */ - var svgCache = { + var svgCache = { - /** - * @param {String} name - * @param {Function} callback - */ - has: function (name, callback) { - callback(false); - }, + /** + * @param {String} name + * @param {Function} callback + */ + has: function (name, callback) { + callback(false); + }, - /** - * @param {String} url - * @param {Function} callback - */ - get: function () { - /* NOOP */ - }, + /** + * @param {String} url + * @param {Function} callback + */ + get: function () { + /* NOOP */ + }, - /** - * @param {String} url - * @param {Object} object - */ - set: function () { - /* NOOP */ - } - }; + /** + * @param {String} url + * @param {Object} object + */ + set: function () { + /* NOOP */ + } + }; /** * @private */ function _enlivenCachedObject(cachedObject) { - var objects = cachedObject.objects, - options = cachedObject.options; + var objects = cachedObject.objects, + options = cachedObject.options; - objects = objects.map(function (o) { - return fabric[capitalize(o.type)].fromObject(o); - }); + objects = objects.map(function (o) { + return fabric[capitalize(o.type)].fromObject(o); + }); - return ({ objects: objects, options: options }); + return ({ objects: objects, options: options }); } /** @@ -3403,7 +3481,6 @@ if (typeof console !== 'undefined') { loadSVGFromURL: function(url, callback, reviver) { url = url.replace(/^\n\s*/, '').trim(); - svgCache.has(url, function (hasUrl) { if (hasUrl) { svgCache.get(url, function (value) { @@ -5132,6 +5209,7 @@ fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ * @return {fabric.Shadow} thisArg */ initialize: function(options) { + if (typeof options === 'string') { options = this._parseShadow(options); } @@ -5373,6 +5451,13 @@ fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ */ imageSmoothingEnabled: true, + /** + * The transformation (in the format of Canvas transform) which focuses the viewport + * @type Array + * @default + */ + viewportTransform: [1, 0, 0, 1, 0, 0], + /** * Callback; invoked right before object is about to be scaled/rotated * @param {fabric.Object} target Object that's about to be scaled/rotated @@ -5569,7 +5654,7 @@ fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ * @private * @param {String} property Property to set ({@link fabric.StaticCanvas#backgroundImage|backgroundImage} * or {@link fabric.StaticCanvas#overlayImage|overlayImage}) - * @param {(fabric.Image|String)} image fabric.Image instance or URL of an image to set background or overlay to + * @param {(fabric.Image|String|null)} image fabric.Image instance, URL of an image or null to set background or overlay to * @param {Function} callback Callback to invoke when image is loaded and set as background or overlay * @param {Object} [options] Optional options to set for the {@link fabric.Image|image}. */ @@ -5592,11 +5677,11 @@ fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ * @private * @param {String} property Property to set ({@link fabric.StaticCanvas#backgroundColor|backgroundColor} * or {@link fabric.StaticCanvas#overlayColor|overlayColor}) - * @param {(Object|String)} color Object with pattern information or color value + * @param {(Object|String|null)} color Object with pattern information, color value or null * @param {Function} [callback] Callback is invoked when color is set */ __setBgOverlayColor: function(property, color, callback) { - if (color.source) { + if (color && color.source) { var _this = this; fabric.util.loadImage(color.source, function(img) { _this[property] = new fabric.Pattern({ @@ -5766,6 +5851,92 @@ fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ return this; }, + /** + * Returns canvas zoom level + * @return {Number} + */ + getZoom: function () { + return Math.sqrt(this.viewportTransform[0] * this.viewportTransform[3]); + }, + + /** + * Sets viewport transform of this canvas instance + * @param {Array} vpt the transform in the form of context.transform + * @return {fabric.Canvas} instance + * @chainable true + */ + setViewportTransform: function (vpt) { + this.viewportTransform = vpt; + this.renderAll(); + for (var i = 0, len = this._objects.length; i < len; i++) { + this._objects[i].setCoords(); + } + return this; + }, + + /** + * Sets zoom level of this canvas instance, zoom centered around point + * @param {fabric.Point} point to zoom with respect to + * @param {Number} value to set zoom to, less than 1 zooms out + * @return {fabric.Canvas} instance + * @chainable true + */ + zoomToPoint: function (point, value) { + // TODO: just change the scale, preserve other transformations + var before = point; + point = fabric.util.transformPoint(point, fabric.util.invertTransform(this.viewportTransform)); + this.viewportTransform[0] = value; + this.viewportTransform[3] = value; + var after = fabric.util.transformPoint(point, this.viewportTransform); + this.viewportTransform[4] += before.x - after.x; + this.viewportTransform[5] += before.y - after.y; + this.renderAll(); + for (var i = 0, len = this._objects.length; i < len; i++) { + this._objects[i].setCoords(); + } + return this; + }, + + /** + * Sets zoom level of this canvas instance + * @param {Number} value to set zoom to, less than 1 zooms out + * @return {fabric.Canvas} instance + * @chainable true + */ + setZoom: function (value) { + this.zoomToPoint(new fabric.Point(0, 0), value); + return this; + }, + + /** + * Pan viewport so as to place point at top left corner of canvas + * @param {fabric.Point} point to move to + * @return {fabric.Canvas} instance + * @chainable true + */ + absolutePan: function (point) { + this.viewportTransform[4] = -point.x; + this.viewportTransform[5] = -point.y; + this.renderAll(); + for (var i = 0, len = this._objects.length; i < len; i++) { + this._objects[i].setCoords(); + } + return this; + }, + + /** + * Pans viewpoint relatively + * @param {fabric.Point} point (position vector) to move by + * @return {fabric.Canvas} instance + * @chainable true + */ + relativePan: function (point) { + return this.absolutePan(new fabric.Point( + -point.x - this.viewportTransform[4], + -point.y - this.viewportTransform[5] + )); + }, + /** * Returns <canvas> element corresponding to this instance * @return {HTMLCanvasElement} @@ -5798,17 +5969,13 @@ fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ */ _draw: function (ctx, object) { if (!object) return; - - if (this.controlsAboveOverlay) { - var hasBorders = object.hasBorders, hasControls = object.hasControls; - object.hasBorders = object.hasControls = false; - object.render(ctx); - object.hasBorders = hasBorders; - object.hasControls = hasControls; - } - else { - object.render(ctx); - } + + ctx.save(); + var v = this.viewportTransform; + ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]); + object.render(ctx); + ctx.restore(); + if (!this.controlsAboveOverlay) object._renderControls(ctx); }, /** @@ -5817,8 +5984,8 @@ fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ */ _onObjectAdded: function(obj) { this.stateful && obj.setupState(); - obj.setCoords(); obj.canvas = this; + obj.setCoords(); this.fire('object:added', { target: obj }); obj.fire('added'); }, @@ -5887,7 +6054,6 @@ fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ * @chainable */ renderAll: function (allOnTop) { - var canvasToDrawOn = this[(allOnTop === true && this.interactive) ? 'contextTop' : 'contextContainer'], activeGroup = this.getActiveGroup(); @@ -5986,7 +6152,7 @@ fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ this.height); } if (this.backgroundImage) { - this.backgroundImage.render(ctx); + this._draw(ctx, this.backgroundImage); } }, @@ -6007,7 +6173,7 @@ fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ this.height); } if (this.overlayImage) { - this.overlayImage.render(ctx); + this._draw(ctx, this.overlayImage); } }, @@ -6163,7 +6329,6 @@ fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ } } - return data; }, @@ -6816,6 +6981,9 @@ fabric.BaseBrush = fabric.util.createClass(/** @lends fabric.BaseBrush.prototype */ _render: function() { var ctx = this.canvas.contextTop; + var v = this.canvas.viewportTransform; + ctx.save(); + ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]); ctx.beginPath(); var p1 = this._points[0], @@ -6845,6 +7013,7 @@ fabric.BaseBrush = fabric.util.createClass(/** @lends fabric.BaseBrush.prototype // the bezier control point ctx.lineTo(p1.x, p1.y); ctx.stroke(); + ctx.restore(); }, /** @@ -6856,7 +7025,7 @@ fabric.BaseBrush = fabric.util.createClass(/** @lends fabric.BaseBrush.prototype this.box = this.getPathBoundingBox(this._points); return this.convertPointsToSVGPath( this._points, this.box.minx, this.box.maxx, this.box.miny, this.box.maxy); - }, + }, /** * Returns bounding box of a path based on given points @@ -7017,13 +7186,18 @@ fabric.CircleBrush = fabric.util.createClass(fabric.BaseBrush, /** @lends fabric */ drawDot: function(pointer) { var point = this.addPoint(pointer), - ctx = this.canvas.contextTop; + ctx = this.canvas.contextTop, + v = this.canvas.viewportTransform; + ctx.save(); + ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]); ctx.fillStyle = point.fill; ctx.beginPath(); ctx.arc(point.x, point.y, point.radius, 0, Math.PI * 2, false); ctx.closePath(); ctx.fill(); + + ctx.restore(); }, /** @@ -7069,6 +7243,7 @@ fabric.CircleBrush = fabric.util.createClass(fabric.BaseBrush, /** @lends fabric circles.push(circle); } var group = new fabric.Group(circles, { originX: 'center', originY: 'center' }); + group.canvas = this.canvas; this.canvas.add(group); this.canvas.fire('path:created', { path: group }); @@ -7217,6 +7392,8 @@ fabric.SprayBrush = fabric.util.createClass( fabric.BaseBrush, /** @lends fabric } var group = new fabric.Group(rects, { originX: 'center', originY: 'center' }); + group.canvas = this.canvas; + this.canvas.add(group); this.canvas.fire('path:created', { path: group }); @@ -7251,7 +7428,10 @@ fabric.SprayBrush = fabric.util.createClass( fabric.BaseBrush, /** @lends fabric render: function() { var ctx = this.canvas.contextTop; ctx.fillStyle = this.color; + + var v = this.canvas.viewportTransform; ctx.save(); + ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]); for (var i = 0, len = this.sprayChunkPoints.length; i < len; i++) { var point = this.sprayChunkPoints[i]; @@ -7285,8 +7465,9 @@ fabric.SprayBrush = fabric.util.createClass( fabric.BaseBrush, /** @lends fabric else { width = this.dotWidth; } - - var point = { x: x, y: y, width: width }; + + var point = new fabric.Point(x, y); + point.width = width; if (this.randomOpacity) { point.opacity = fabric.util.getRandomInt(0, 100) / 100; @@ -7609,7 +7790,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab * @return {Boolean} true if point is contained within an area of given object */ containsPoint: function (e, target) { - var pointer = this.getPointer(e), + var pointer = this.getPointer(e, true), xy = this._normalizePointer(target, pointer); // http://www.geog.ubc.ca/courses/klink/gis.notes/ncgia/u32.html @@ -7627,11 +7808,14 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab isObjectInGroup = ( activeGroup && object.type !== 'group' && - activeGroup.contains(object)); + activeGroup.contains(object)), + lt; if (isObjectInGroup) { - x -= activeGroup.left; - y -= activeGroup.top; + lt = new fabric.Point(activeGroup.left, activeGroup.top); + lt = fabric.util.transformPoint(lt, this.viewportTransform, true); + x -= lt.x; + y -= lt.y; } return { x: x, y: y }; }, @@ -7762,7 +7946,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab if (!target) return; var pointer = this.getPointer(e), - corner = target._findTargetCorner(pointer), + corner = target._findTargetCorner(this.getPointer(e, true)), action = this._getActionFromCorner(target, corner), origin = this._getOriginFromCorner(target, corner); @@ -7972,8 +8156,8 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab /** * Rotates object by invoking its rotate method * @private - * @param x {Number} pointer's x coordinate - * @param y {Number} pointer's y coordinate + * @param {Number} x pointer's x coordinate + * @param {Number} y pointer's y coordinate */ _rotateObject: function (x, y) { @@ -7994,9 +8178,11 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab }, /** - * @private + * Set the cursor type of the canvas element + * @param {String} value Cursor type of the canvas element. + * @see http://www.w3.org/TR/css3-ui/#cursor */ - _setCursor: function (value) { + setCursor: function (value) { this.upperCanvasEl.style.cursor = value; }, @@ -8067,7 +8253,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab this.lastRenderedObjectWithControlsAboveOverlay && this.lastRenderedObjectWithControlsAboveOverlay.visible && this.containsPoint(e, this.lastRenderedObjectWithControlsAboveOverlay) && - this.lastRenderedObjectWithControlsAboveOverlay._findTargetCorner(this.getPointer(e))); + this.lastRenderedObjectWithControlsAboveOverlay._findTargetCorner(this.getPointer(e, true))); }, /** @@ -8090,6 +8276,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab var target = this._searchPossibleTargets(e); this._fireOverOutEvents(target); + return target; }, @@ -8142,9 +8329,8 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab // Cache all targets where their bounding box contains point. var target, - pointer = this.getPointer(e); - - var i = this._objects.length; + pointer = this.getPointer(e, true), + i = this._objects.length; while (i--) { if (this._checkTarget(e, this._objects[i], pointer)){ @@ -8162,24 +8348,36 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab * @param {Event} e * @return {Object} object with "x" and "y" number values */ - getPointer: function (e) { - var pointer = getPointer(e, this.upperCanvasEl), - bounds = this.upperCanvasEl.getBoundingClientRect(), + getPointer: function (e, ignoreZoom, upperCanvasEl) { + if (!upperCanvasEl) { + upperCanvasEl = this.upperCanvasEl; + } + var pointer = getPointer(e, upperCanvasEl), + bounds = upperCanvasEl.getBoundingClientRect(), cssScale; + pointer.x = pointer.x - this._offset.left; + pointer.y = pointer.y - this._offset.top; + if (!ignoreZoom) { + pointer = fabric.util.transformPoint( + pointer, + fabric.util.invertTransform(this.viewportTransform) + ); + } + if (bounds.width === 0 || bounds.height === 0) { // If bounds are not available (i.e. not visible), do not apply scale. cssScale = { width: 1, height: 1 }; } else { cssScale = { - width: this.upperCanvasEl.width / bounds.width, - height: this.upperCanvasEl.height / bounds.height + width: upperCanvasEl.width / bounds.width, + height: upperCanvasEl.height / bounds.height }; } return { - x: (pointer.x - this._offset.left) * cssScale.width, - y: (pointer.y - this._offset.top) * cssScale.height + x: pointer.x * cssScale.width, + y: pointer.y * cssScale.height }; }, @@ -8338,7 +8536,6 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab _setActiveGroup: function(group) { this._activeGroup = group; if (group) { - group.canvas = this; group.set('active', true); } }, @@ -8437,7 +8634,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab * @private */ _drawGroupControls: function(ctx, activeGroup) { - this._drawControls(ctx, activeGroup, 'Group'); + activeGroup._renderControls(ctx); }, /** @@ -8446,19 +8643,9 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab _drawObjectsControls: function(ctx) { for (var i = 0, len = this._objects.length; i < len; ++i) { if (!this._objects[i] || !this._objects[i].active) continue; - this._drawControls(ctx, this._objects[i], 'Object'); + this._objects[i]._renderControls(ctx); this.lastRenderedObjectWithControlsAboveOverlay = this._objects[i]; } - }, - - /** - * @private - */ - _drawControls: function(ctx, object, klass) { - ctx.save(); - fabric[klass].prototype.transform.call(object, ctx); - object.drawBorders(ctx).drawControls(ctx); - ctx.restore(); } }); @@ -8640,7 +8827,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab if (e.type === 'touchstart') { // Unbind mousedown to prevent double triggers from touch devices - removeListener(this.upperCanvasEl, 'mousedown', this._onMouseDown); + removeListener(this.upperCanvasEl, 'mousedown', this._onMouseDown); } else { addListener(fabric.document, 'mouseup', this._onMouseUp); @@ -8821,7 +9008,9 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab if (this.clipTo) { fabric.util.clipContext(this, this.contextTop); } - this.freeDrawingBrush.onMouseDown(this.getPointer(e)); + var ivt = fabric.util.invertTransform(this.viewportTransform), + pointer = fabric.util.transformPoint(this.getPointer(e, true), ivt); + this.freeDrawingBrush.onMouseDown(pointer); this.fire('mouse:down', { e: e }); }, @@ -8831,10 +9020,11 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab */ _onMouseMoveInDrawingMode: function(e) { if (this._isCurrentlyDrawing) { - var pointer = this.getPointer(e); + var ivt = fabric.util.invertTransform(this.viewportTransform), + pointer = fabric.util.transformPoint(this.getPointer(e, true), ivt); this.freeDrawingBrush.onMouseMove(pointer); } - this.upperCanvasEl.style.cursor = this.freeDrawingCursor; + this.setCursor(this.freeDrawingCursor); this.fire('mouse:move', { e: e }); }, @@ -8874,7 +9064,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab if (this._currentTransform) return; var target = this.findTarget(e), - pointer = this.getPointer(e); + pointer = this.getPointer(e, true); // save pointer for check in __onMouseUp event this._previousPointer = pointer; @@ -9001,7 +9191,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab // We initially clicked in an empty area, so we draw a box for multiple selection if (groupSelector) { - pointer = this.getPointer(e); + pointer = this.getPointer(e, true); groupSelector.left = pointer.x - groupSelector.ex; groupSelector.top = pointer.y - groupSelector.ey; @@ -9013,7 +9203,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab target = this.findTarget(e); if (!target || target && !target.selectable) { - this.upperCanvasEl.style.cursor = this.defaultCursor; + this.setCursor(this.defaultCursor); } else { this._setCursorFromEvent(e, target); @@ -9032,7 +9222,6 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab * @param {Event} e Event fired on mousemove */ _transformObject: function(e) { - var pointer = this.getPointer(e), transform = this._currentTransform; @@ -9073,7 +9262,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab else { this._translateObject(x, y); this._fire('moving', target, e); - this._setCursor(this.moveCursor); + this.setCursor(this.moveCursor); } }, @@ -9131,10 +9320,8 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab * @param {Object} target Object that the mouse is hovering, if so. */ _setCursorFromEvent: function (e, target) { - var style = this.upperCanvasEl.style; - if (!target || !target.selectable) { - style.cursor = this.defaultCursor; + this.setCursor(this.defaultCursor); return false; } else { @@ -9142,10 +9329,10 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab // only show proper corner when group selection is not active corner = target._findTargetCorner && (!activeGroup || !activeGroup.contains(target)) - && target._findTargetCorner(this.getPointer(e)); + && target._findTargetCorner(this.getPointer(e, true)); if (!corner) { - style.cursor = target.hoverCursor || this.hoverCursor; + this.setCursor(target.hoverCursor || this.hoverCursor); } else { this._setCornerCursor(corner, target); @@ -9158,16 +9345,14 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab * @private */ _setCornerCursor: function(corner, target) { - var style = this.upperCanvasEl.style; - if (corner in cursorOffset) { - style.cursor = this._getRotatedCornerCursor(corner, target); + this.setCursor(this._getRotatedCornerCursor(corner, target)); } else if (corner === 'mtr' && target.hasRotatingPoint) { - style.cursor = this.rotationCursor; + this.setCursor(this.rotationCursor); } else { - style.cursor = this.defaultCursor; + this.setCursor(this.defaultCursor); return false; } }, @@ -9276,6 +9461,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab if (this._activeObject && target !== this._activeObject) { var group = this._createGroup(target); + group.addWithUpdate(); this.setActiveGroup(group); this._activeObject = null; @@ -9300,7 +9486,8 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab return new fabric.Group(groupObjects, { originX: 'center', - originY: 'center' + originY: 'center', + canvas: this }); }, @@ -9319,8 +9506,10 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab else if (group.length > 1) { group = new fabric.Group(group.reverse(), { originX: 'center', - originY: 'center' + originY: 'center', + canvas: this }); + group.addWithUpdate(); this.setActiveGroup(group, e); group.saveCoords(); this.fire('selection:created', { target: group }); @@ -9375,7 +9564,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab if (activeGroup) { activeGroup.setObjectsCoords().setCoords(); activeGroup.isMoving = false; - this._setCursor(this.defaultCursor); + this.setCursor(this.defaultCursor); } // clear selection and current transformation @@ -10563,6 +10752,9 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati * @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) { + if (this.group) { + this.group.transform(ctx, fromLeft); + } ctx.globalAlpha = this.opacity; var center = fromLeft ? this._getLeftTopCoords() : this.getCenterPoint(); @@ -10751,6 +10943,18 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati return this; }, + /** + * Retrieves viewportTransform from Object's canvas if possible + * @method getViewportTransform + * @memberOf fabric.Object.prototype + * @return {Boolean} flipY value // TODO + */ + getViewportTransform: function() { + if (this.canvas && this.canvas.viewportTransform) + return this.canvas.viewportTransform; + return [1, 0, 0, 1, 0, 0]; + }, + /** * Renders an object on a specified context * @param {CanvasRenderingContext2D} ctx Context to render on @@ -10780,19 +10984,14 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati this._render(ctx, noTransform); this.clipTo && ctx.restore(); this._removeShadow(ctx); - this._restoreFillRule(ctx); - if (this.active && !noTransform) { - this.drawBorders(ctx); - this.drawControls(ctx); - } - ctx.restore(); }, _transform: function(ctx, noTransform) { var m = this.transformMatrix; + if (m && !this.group) { ctx.setTransform(m[0], m[1], m[2], m[3], m[4], m[5]); } @@ -10821,6 +11020,35 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati } }, + /** + * Renders controls and borders for the object + * @param {CanvasRenderingContext2D} ctx Context to render on + * @param {Boolean} [noTransform] When true, context is not transformed + */ + _renderControls: function(ctx, noTransform) { + var v = this.getViewportTransform(); + + ctx.save(); + if (this.active && !noTransform) { + var center; + if (this.group) { + center = fabric.util.transformPoint(this.group.getCenterPoint(), v); + ctx.translate(center.x, center.y); + ctx.rotate(degreesToRadians(this.group.angle)); + } + center = fabric.util.transformPoint(this.getCenterPoint(), v, null != this.group); + if (this.group) { + center.x *= this.group.scaleX; + center.y *= this.group.scaleY; + } + ctx.translate(center.x, center.y); + ctx.rotate(degreesToRadians(this.angle)); + this.drawBorders(ctx); + this.drawControls(ctx); + } + ctx.restore(); + }, + /** * @private * @param {CanvasRenderingContext2D} ctx Context to render on @@ -11135,7 +11363,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati * canvas.renderAll(); */ setShadow: function(options) { - return this.set('shadow', new fabric.Shadow(options)); + return this.set('shadow', options ? new fabric.Shadow(options) : null); }, /** @@ -11840,11 +12068,15 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati setCoords: function() { var strokeWidth = this.strokeWidth > 1 ? this.strokeWidth : 0, - padding = this.padding, - theta = degreesToRadians(this.angle); + theta = degreesToRadians(this.angle), + vpt = this.getViewportTransform(); - this.currentWidth = (this.width + strokeWidth) * this.scaleX + padding * 2; - this.currentHeight = (this.height + strokeWidth) * this.scaleY + padding * 2; + var f = function (p) { + return fabric.util.transformPoint(p, vpt); + }; + + this.currentWidth = (this.width + strokeWidth) * this.scaleX; + this.currentHeight = (this.height + strokeWidth) * this.scaleY; // If width is negative, make postive. Fixes path selection issue if (this.currentWidth < 0) { @@ -11862,45 +12094,34 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati offsetY = Math.sin(_angle + theta) * _hypotenuse, sinTh = Math.sin(theta), cosTh = Math.cos(theta), - coords = this.getCenterPoint(), + wh = new fabric.Point(this.currentWidth, this.currentHeight), + _tl = new fabric.Point(coords.x - offsetX, coords.y - offsetY), + _tr = new fabric.Point(_tl.x + (wh.x * cosTh), _tl.y + (wh.x * sinTh)), + _bl = new fabric.Point(_tl.x - (wh.y * sinTh), _tl.y + (wh.y * cosTh)), + _mt = new fabric.Point(_tl.x + (wh.x/2 * cosTh), _tl.y + (wh.x/2 * sinTh)), + tl = f(_tl), + tr = f(_tr), + br = f(new fabric.Point(_tr.x - (wh.y * sinTh), _tr.y + (wh.y * cosTh))), + bl = f(_bl), + ml = f(new fabric.Point(_tl.x - (wh.y/2 * sinTh), _tl.y + (wh.y/2 * cosTh))), + mt = f(_mt), + mr = f(new fabric.Point(_tr.x - (wh.y/2 * sinTh), _tr.y + (wh.y/2 * cosTh))), + mb = f(new fabric.Point(_bl.x + (wh.x/2 * cosTh), _bl.y + (wh.x/2 * sinTh))), + mtr = f(new fabric.Point(_mt.x, _mt.y)); - tl = { - x: coords.x - offsetX, - y: coords.y - offsetY - }, - tr = { - x: tl.x + (this.currentWidth * cosTh), - y: tl.y + (this.currentWidth * sinTh) - }, - br = { - x: tr.x - (this.currentHeight * sinTh), - y: tr.y + (this.currentHeight * cosTh) - }, - bl = { - x: tl.x - (this.currentHeight * sinTh), - y: tl.y + (this.currentHeight * cosTh) - }, - ml = { - x: tl.x - (this.currentHeight/2 * sinTh), - y: tl.y + (this.currentHeight/2 * cosTh) - }, - mt = { - x: tl.x + (this.currentWidth/2 * cosTh), - y: tl.y + (this.currentWidth/2 * sinTh) - }, - mr = { - x: tr.x - (this.currentHeight/2 * sinTh), - y: tr.y + (this.currentHeight/2 * cosTh) - }, - mb = { - x: bl.x + (this.currentWidth/2 * cosTh), - y: bl.y + (this.currentWidth/2 * sinTh) - }, - mtr = { - x: mt.x, - y: mt.y - }; + // padding + var padX = Math.cos(_angle + theta) * this.padding * Math.sqrt(2), + padY = Math.sin(_angle + theta) * this.padding * Math.sqrt(2); + tl = tl.add(new fabric.Point(-padX, -padY)); + tr = tr.add(new fabric.Point(padY, -padX)); + br = br.add(new fabric.Point(padX, padY)); + bl = bl.add(new fabric.Point(-padY, padX)); + ml = ml.add(new fabric.Point((-padX - padY) / 2, (-padY + padX) / 2)); + mt = mt.add(new fabric.Point((padY - padX) / 2, -(padY + padX) / 2)); + mr = mr.add(new fabric.Point((padY + padX) / 2, (padY - padX) / 2)); + mb = mb.add(new fabric.Point((padX - padY) / 2, (padX + padY) / 2)); + mtr = mtr.add(new fabric.Point((padY - padX) / 2, -(padY + padX) / 2)); // debugging @@ -12064,7 +12285,8 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot getSvgTransform: function() { var toFixed = fabric.util.toFixed, angle = this.getAngle(), - center = this.getCenterPoint(), + vpt = this.getViewportTransform(), + center = fabric.util.transformPoint(this.getCenterPoint(), vpt), NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS, @@ -12078,12 +12300,12 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot ? (' rotate(' + toFixed(angle, NUM_FRACTION_DIGITS) + ')') : '', - scalePart = (this.scaleX === 1 && this.scaleY === 1) + scalePart = (this.scaleX === 1 && this.scaleY === 1 && vpt[0] === 1 && vpt[3] === 1) ? '' : (' scale(' + - toFixed(this.scaleX, NUM_FRACTION_DIGITS) + + toFixed(this.scaleX * vpt[0], NUM_FRACTION_DIGITS) + ' ' + - toFixed(this.scaleY, NUM_FRACTION_DIGITS) + + toFixed(this.scaleY * vpt[3], NUM_FRACTION_DIGITS) + ')'), flipXPart = this.flipX ? 'matrix(-1 0 0 1 0 0) ' : '', @@ -12166,7 +12388,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot (function(){ var degreesToRadians = fabric.util.degreesToRadians, - isVML = typeof G_vmlCanvasManager !== 'undefined'; + isVML = function() { return typeof G_vmlCanvasManager !== 'undefined'; }; fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ { @@ -12183,7 +12405,9 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot * @return {String|Boolean} corner code (tl, tr, bl, br, etc.), or false if nothing is found */ _findTargetCorner: function(pointer) { - if (!this.hasControls || !this.active) return false; + if (!this.hasControls || !this.active) { + return false; + } var ex = pointer.x, ey = pointer.y, @@ -12440,25 +12664,32 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot scaleY = 1 / this._constrainScale(this.scaleY); ctx.lineWidth = 1 / this.borderScaleFactor; - - ctx.scale(scaleX, scaleY); - - var w = this.getWidth(), - h = this.getHeight(); + + var vpt = this.getViewportTransform(), + wh = fabric.util.transformPoint(new fabric.Point(this.getWidth(), this.getHeight()), vpt, true), + sxy = fabric.util.transformPoint(new fabric.Point(scaleX, scaleY), vpt, true), + w = wh.x, + h = wh.y, + sx= sxy.x, + sy= sxy.y; + if (this.group) { + w = w * this.group.scaleX; + h = h * this.group.scaleY; + } ctx.strokeRect( - ~~(-(w / 2) - padding - strokeWidth / 2 * this.scaleX) - 0.5, // offset needed to make lines look sharper - ~~(-(h / 2) - padding - strokeWidth / 2 * this.scaleY) - 0.5, - ~~(w + padding2 + strokeWidth * this.scaleX) + 1, // double offset needed to make lines look sharper - ~~(h + padding2 + strokeWidth * this.scaleY) + 1 + ~~(-(w / 2) - padding - strokeWidth / 2 * sx) - 0.5, // offset needed to make lines look sharper + ~~(-(h / 2) - padding - strokeWidth / 2 * sy) - 0.5, + ~~(w + padding2 + strokeWidth * sx) + 1, // double offset needed to make lines look sharper + ~~(h + padding2 + strokeWidth * sy) + 1 ); if (this.hasRotatingPoint && this.isControlVisible('mtr') && !this.get('lockRotation') && this.hasControls) { var rotateHeight = ( this.flipY - ? h + (strokeWidth * this.scaleY) + (padding * 2) - : -h - (strokeWidth * this.scaleY) - (padding * 2) + ? h + (strokeWidth * sx) + (padding * 2) + : -h - (strokeWidth * sy) - (padding * 2) ) / 2; ctx.beginPath(); @@ -12474,7 +12705,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot /** * Draws corners of an object's bounding box. - * Requires public properties: width, height, scaleX, scaleY + * Requires public properties: width, height * Requires public options: cornerSize, padding * @param {CanvasRenderingContext2D} ctx Context to draw on * @return {fabric.Object} thisArg @@ -12486,75 +12717,73 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot var size = this.cornerSize, size2 = size / 2, strokeWidth2 = ~~(this.strokeWidth / 2), // half strokeWidth rounded down - left = -(this.width / 2), - top = -(this.height / 2), - paddingX = this.padding / this.scaleX, - paddingY = this.padding / this.scaleY, - scaleOffsetY = size2 / this.scaleY, - scaleOffsetX = size2 / this.scaleX, - scaleOffsetSizeX = (size2 - size) / this.scaleX, - scaleOffsetSizeY = (size2 - size) / this.scaleY, - height = this.height, - width = this.width, + wh = fabric.util.transformPoint(new fabric.Point(this.getWidth(), this.getHeight()), this.getViewportTransform(), true), + width = wh.x, + height = wh.y, + left = -(width / 2), + top = -(height / 2), + padding = this.padding, + scaleOffset = size2, + scaleOffsetSize = size2 - size, methodName = this.transparentCorners ? 'strokeRect' : 'fillRect'; ctx.save(); - ctx.lineWidth = 1 / Math.max(this.scaleX, this.scaleY); + ctx.lineWidth = 1; ctx.globalAlpha = this.isMoving ? this.borderOpacityWhenMoving : 1; ctx.strokeStyle = ctx.fillStyle = this.cornerColor; // top-left this._drawControl('tl', ctx, methodName, - left - scaleOffsetX - strokeWidth2 - paddingX, - top - scaleOffsetY - strokeWidth2 - paddingY); + left - scaleOffset - strokeWidth2 - padding, + top - scaleOffset - strokeWidth2 - padding); // top-right this._drawControl('tr', ctx, methodName, - left + width - scaleOffsetX + strokeWidth2 + paddingX, - top - scaleOffsetY - strokeWidth2 - paddingY); + left + width - scaleOffset + strokeWidth2 + padding, + top - scaleOffset - strokeWidth2 - padding); // bottom-left this._drawControl('bl', ctx, methodName, - left - scaleOffsetX - strokeWidth2 - paddingX, - top + height + scaleOffsetSizeY + strokeWidth2 + paddingY); + left - scaleOffset - strokeWidth2 - padding, + top + height + scaleOffsetSize + strokeWidth2 + padding); // bottom-right this._drawControl('br', ctx, methodName, - left + width + scaleOffsetSizeX + strokeWidth2 + paddingX, - top + height + scaleOffsetSizeY + strokeWidth2 + paddingY); + left + width + scaleOffsetSize + strokeWidth2 + padding, + top + height + scaleOffsetSize + strokeWidth2 + padding); if (!this.get('lockUniScaling')) { // middle-top this._drawControl('mt', ctx, methodName, - left + width/2 - scaleOffsetX, - top - scaleOffsetY - strokeWidth2 - paddingY); + left + width/2 - scaleOffset, + top - scaleOffset - strokeWidth2 - padding); // middle-bottom this._drawControl('mb', ctx, methodName, - left + width/2 - scaleOffsetX, - top + height + scaleOffsetSizeY + strokeWidth2 + paddingY); + left + width/2 - scaleOffset, + top + height + scaleOffsetSize + strokeWidth2 + padding); // middle-right this._drawControl('mr', ctx, methodName, - left + width + scaleOffsetSizeX + strokeWidth2 + paddingX, - top + height/2 - scaleOffsetY); + left + width + scaleOffsetSize + strokeWidth2 + padding, + top + height/2 - scaleOffset); // middle-left this._drawControl('ml', ctx, methodName, - left - scaleOffsetX - strokeWidth2 - paddingX, - top + height/2 - scaleOffsetY); + left - scaleOffset - strokeWidth2 - padding, + top + height/2 - scaleOffset); } // middle-top-rotate if (this.hasRotatingPoint) { this._drawControl('mtr', ctx, methodName, - left + width/2 - scaleOffsetX, + left + width/2 - scaleOffset, this.flipY - ? (top + height + (this.rotatingPointOffset / this.scaleY) - this.cornerSize/this.scaleX/2 + strokeWidth2 + paddingY) - : (top - (this.rotatingPointOffset / this.scaleY) - this.cornerSize/this.scaleY/2 - strokeWidth2 - paddingY)); + ? (top + height + this.rotatingPointOffset - this.cornerSize/2 + strokeWidth2 + padding) + : (top - this.rotatingPointOffset - this.cornerSize/2 - strokeWidth2 - padding)); } ctx.restore(); @@ -12566,12 +12795,11 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot * @private */ _drawControl: function(control, ctx, methodName, left, top) { - var sizeX = this.cornerSize / this.scaleX, - sizeY = this.cornerSize / this.scaleY; + var size = this.cornerSize; if (this.isControlVisible(control)) { - isVML || this.transparentCorners || ctx.clearRect(left, top, sizeX, sizeY); - ctx[methodName](left, top, sizeX, sizeY); + isVML() || this.transparentCorners || ctx.clearRect(left, top, size, size); + ctx[methodName](left, top, size, size); } }, @@ -13359,22 +13587,24 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot */ fabric.Circle.fromElement = function(element, options) { options || (options = { }); + var parsedAttributes = fabric.parseAttributes(element, fabric.Circle.ATTRIBUTE_NAMES); + if (!isValidRadius(parsedAttributes)) { throw new Error('value of `r` attribute is required and can not be negative'); } - - + if (!('left' in parsedAttributes)) { - parsedAttributes.left = 0; + parsedAttributes.left = 0; } if (!('top' in parsedAttributes)) { - parsedAttributes.top = 0 + parsedAttributes.top = 0; } if (!('transformMatrix' in parsedAttributes)) { parsedAttributes.left -= (options.width / 2); - parsedAttributes.top -= (options.height / 2); - } + parsedAttributes.top -= (options.height / 2); + } + var obj = new fabric.Circle(extend(parsedAttributes, options)); obj.cx = parseFloat(element.getAttribute('cx')) || 0; @@ -14863,6 +15093,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot ctx.save(); var m = this.transformMatrix; + if (m) { ctx.transform(m[0], m[1], m[2], m[3], m[4], m[5]); } @@ -14880,11 +15111,6 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot this._renderStroke(ctx); this.clipTo && ctx.restore(); this._removeShadow(ctx); - - if (!noTransform && this.active) { - this.drawBorders(ctx); - this.drawControls(ctx); - } ctx.restore(); }, @@ -15237,10 +15463,10 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot ctx.save(); var m = this.transformMatrix; + if (m) { ctx.transform(m[0], m[1], m[2], m[3], m[4], m[5]); } - this.transform(ctx); this._setShadow(ctx); @@ -15250,11 +15476,6 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot } this.clipTo && ctx.restore(); this._removeShadow(ctx); - - if (this.active) { - this.drawBorders(ctx); - this.drawControls(ctx); - } ctx.restore(); }, @@ -15474,7 +15695,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot } this._setOpacityIfSame(); - this.setCoords(true); + this.setCoords(); this.saveCoords(); }, @@ -15522,8 +15743,10 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot */ addWithUpdate: function(object) { this._restoreObjectsState(); - this._objects.push(object); - object.group = this; + if (object) { + this._objects.push(object); + object.group = this; + } // since _restoreObjectsState set objects inactive this.forEachObject(this._setObjectActive, this); this._calcBounds(); @@ -15621,15 +15844,12 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot /** * Renders instance on a given context * @param {CanvasRenderingContext2D} ctx context to render instance on - * @param {Boolean} [noTransform] When true, context is not transformed */ - render: function(ctx, noTransform) { + render: function(ctx) { // do not render if object is not visible if (!this.visible) return; ctx.save(); - this.transform(ctx); - this.clipTo && fabric.util.clipContext(this, ctx); // the array is now sorted in order of highest first, so start from end @@ -15639,31 +15859,34 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot this.clipTo && ctx.restore(); - if (!noTransform && this.active) { - this.drawBorders(ctx); - this.drawControls(ctx); - } ctx.restore(); }, + /** + * Renders controls and borders for the object + * @param {CanvasRenderingContext2D} ctx Context to render on + * @param {Boolean} [noTransform] When true, context is not transformed + */ + _renderControls: function(ctx, noTransform) { + this.callSuper('_renderControls', ctx, noTransform); + for (var i = 0, len = this._objects.length; i < len; i++) { + this._objects[i]._renderControls(ctx); + } + }, + /** * @private */ _renderObject: function(object, ctx) { - - var originalScaleFactor = object.borderScaleFactor, - originalHasRotatingPoint = object.hasRotatingPoint, - groupScaleFactor = Math.max(this.scaleX, this.scaleY); + var originalHasRotatingPoint = object.hasRotatingPoint; // do not render if object is not visible if (!object.visible) return; - object.borderScaleFactor = groupScaleFactor; object.hasRotatingPoint = false; object.render(ctx); - object.borderScaleFactor = originalScaleFactor; object.hasRotatingPoint = originalHasRotatingPoint; }, @@ -15858,20 +16081,17 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot * @private */ _getBounds: function(aX, aY, onlyWidthHeight) { - var minX = min(aX), - maxX = max(aX), - minY = min(aY), - maxY = max(aY), - width = (maxX - minX) || 0, - height = (maxY - minY) || 0, - obj = { - width: width, - height: height + var ivt = fabric.util.invertTransform(this.getViewportTransform()), + minXY = fabric.util.transformPoint(new fabric.Point(min(aX), min(aY)), ivt), + maxXY = fabric.util.transformPoint(new fabric.Point(max(aX), max(aY)), ivt), + obj = { + width: (maxXY.x - minXY.x) || 0, + height: (maxXY.y - minXY.y) || 0 }; if (!onlyWidthHeight) { - obj.left = (minX + width / 2) || 0; - obj.top = (minY + height / 2) || 0; + obj.left = (minXY.x + maxXY.x) / 2 || 0; + obj.top = (minXY.y + maxXY.y) / 2 || 0; } return obj; }, @@ -16078,7 +16298,6 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot if (!this.visible) return; ctx.save(); - var m = this.transformMatrix, isInPathGroup = this.group && this.group.type === 'path-group'; @@ -16096,7 +16315,6 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot ctx.translate(this.width/2, this.height/2); } - ctx.save(); this._setShadow(ctx); this.clipTo && fabric.util.clipContext(this, ctx); this._render(ctx); @@ -16106,12 +16324,6 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot this._renderStroke(ctx); this.clipTo && ctx.restore(); ctx.restore(); - - if (this.active && !noTransform) { - this.drawBorders(ctx); - this.drawControls(ctx); - } - ctx.restore(); }, /** @@ -16132,10 +16344,10 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot * @param {CanvasRenderingContext2D} ctx Context to render on */ _renderDashedStroke: function(ctx) { - var x = -this.width/2, - y = -this.height/2, - w = this.width, - h = this.height; + var x = -this.width / 2, + y = -this.height / 2, + w = this.width, + h = this.height; ctx.save(); this._setStrokeStyles(ctx); @@ -16295,13 +16507,14 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot * @param {CanvasRenderingContext2D} ctx Context to render on */ _render: function(ctx) { - this._element && ctx.drawImage( - this._element, - -this.width / 2, - -this.height / 2, - this.width, - this.height - ); + this._element && + ctx.drawImage( + this._element, + -this.width / 2, + -this.height / 2, + this.width, + this.height + ); }, /** @@ -17764,10 +17977,9 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag source = new fabric.Color(this.color).getSource(); for (i = 0; i < iLen; i+=4) { - data[i] *= source[0]/255; - data[i + 1] *= source[1]/255; - data[i + 2] *= source[2]/255; - + data[i] *= source[0] / 255; + data[i + 1] *= source[1] / 255; + data[i + 2] *= source[2] / 255; } context.putImageData(imageData, 0, 0); @@ -18118,7 +18330,6 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag this.setOptions(options); this.__skipDimension = false; this._initDimensions(); - this.setCoords(); }, /** @@ -18559,9 +18770,8 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag /** * Renders text instance on a specified context * @param {CanvasRenderingContext2D} ctx Context to render on - * @param {Boolean} [noTransform] When true, context is not transformed */ - render: function(ctx, noTransform) { + render: function(ctx) { // do not render if object is not visible if (!this.visible) return; @@ -18571,10 +18781,6 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag ctx.transform(m[0], m[1], m[2], m[3], m[4], m[5]); } this._render(ctx); - if (!noTransform && this.active) { - this.drawBorders(ctx); - this.drawControls(ctx); - } ctx.restore(); }, @@ -18935,6 +19141,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag * @mixes fabric.Observable * * @fires changed ("text:changed" when observing canvas) + * @fires selection:changed ("text:selection:changed" when observing canvas) * @fires editing:entered ("text:editing:entered" when observing canvas) * @fires editing:exited ("text:editing:exited" when observing canvas) * @@ -19145,6 +19352,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag */ setSelectionStart: function(index) { if (this.selectionStart !== index) { + this.fire('selection:changed'); this.canvas && this.canvas.fire('text:selection:changed', { target: this }); } this.selectionStart = index; @@ -19157,6 +19365,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag */ setSelectionEnd: function(index) { if (this.selectionEnd !== index) { + this.fire('selection:changed'); this.canvas && this.canvas.fire('text:selection:changed', { target: this }); } this.selectionEnd = index; @@ -19282,6 +19491,8 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag textBackgroundColor: style && style.textBackgroundColor || this.textBackgroundColor, textDecoration: style && style.textDecoration || this.textDecoration, fontFamily: style && style.fontFamily || this.fontFamily, + fontWeight: style && style.fontWeight || this.fontWeight, + fontStyle: style && style.fontStyle || this.fontStyle, stroke: style && style.stroke || this.stroke, strokeWidth: style && style.strokeWidth || this.strokeWidth }; @@ -19621,6 +19832,8 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag prevStyle.textBackgroundColor !== thisStyle.textBackgroundColor || prevStyle.textDecoration !== thisStyle.textDecoration || prevStyle.fontFamily !== thisStyle.fontFamily || + prevStyle.fontWeight !== thisStyle.fontWeight || + prevStyle.fontStyle !== thisStyle.fontStyle || prevStyle.stroke !== thisStyle.stroke || prevStyle.strokeWidth !== thisStyle.strokeWidth ); @@ -20218,6 +20431,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag selectAll: function() { this.selectionStart = 0; this.selectionEnd = this.text.length; + this.fire('selection:changed'); this.canvas && this.canvas.fire('text:selection:changed', { target: this }); }, @@ -20989,10 +21203,10 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot mouseOffset, prevWidth, width, charIndex + i, jlen); } - if (mouseOffset.y < height) { - return this._getNewSelectionStartFromOffset( - mouseOffset, prevWidth, width, charIndex + i, jlen, j); - } + if (mouseOffset.y < height) { + return this._getNewSelectionStartFromOffset( + mouseOffset, prevWidth, width, charIndex + i, jlen, j); + } } // clicked somewhere after all chars, so set at the end @@ -21047,7 +21261,6 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot fabric.util.addListener(this.hiddenTextarea, 'copy', this.copy.bind(this)); fabric.util.addListener(this.hiddenTextarea, 'paste', this.paste.bind(this)); - if (!this._clickHandlerInitialized && this.canvas) { fabric.util.addListener(this.canvas.upperCanvasEl, 'click', this.onClick.bind(this)); this._clickHandlerInitialized = true; @@ -21119,7 +21332,7 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot copy: function(e) { var selectedText = this.getSelectedText(), clipboardData = this._getClipboardData(e); - + // Check for backward compatibility with old browsers if (clipboardData) { clipboardData.setData('text', selectedText); @@ -21138,14 +21351,14 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot paste: function(e) { var copiedText = null, clipboardData = this._getClipboardData(e); - + // Check for backward compatibility with old browsers if (clipboardData) { copiedText = clipboardData.getData('text'); } else { copiedText = this.copiedText; } - + if (copiedText) { this.insertChars(copiedText); } @@ -21672,6 +21885,7 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot } }); + /* _TO_SVG_START_ */ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.prototype */ { @@ -21782,7 +21996,7 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot fabric.util.string.escapeXml(_char), '' - ].join(''); + ].join(''); } }); /* _TO_SVG_END_ */ diff --git a/dist/fabric.min.js b/dist/fabric.min.js index 081c57be..435595b4 100644 --- a/dist/fabric.min.js +++ b/dist/fabric.min.js @@ -1,7 +1,7 @@ -/* build: `node build.js modules=ALL exclude=gestures,cufon,json minifier=uglifyjs` *//*! Fabric.js Copyright 2008-2014, Printio (Juriy Zaytsev, Maxim Chernyak) */var fabric=fabric||{version:"1.4.7"};typeof exports!="undefined"&&(exports.fabric=fabric),typeof document!="undefined"&&typeof window!="undefined"?(fabric.document=document,fabric.window=window):(fabric.document=require("jsdom").jsdom(""),fabric.window=fabric.document.createWindow()),fabric.isTouchSupported="ontouchstart"in fabric.document.documentElement,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"],function(){function e(e,t){if(!this.__eventListeners[e])return;t?fabric.util.removeFromArray(this.__eventListeners[e],t):this.__eventListeners[e].length=0}function t(e,t){this.__eventListeners||(this.__eventListeners={});if(arguments.length===1)for(var n in e)this.on(n,e[n]);else this.__eventListeners[e]||(this.__eventListeners[e]=[]),this.__eventListeners[e].push(t);return this}function n(t,n){if(!this.__eventListeners)return;if(arguments.length===0)this.__eventListeners={};else if(arguments.length===1&&typeof arguments[0]=="object")for(var r in t)e.call(this,r,t[r]);else e.call(this,t,n);return this}function r(e,t){if(!this.__eventListeners)return;var n=this.__eventListeners[e];if(!n)return;for(var r=0,i=n.length;r-1},complexity:function(){return this.getObjects().reduce(function(e,t){return e+=t.complexity?t.complexity():0,e},0)}},function(e){var t=Math.sqrt,n=Math.atan2,r=Math.PI/180;fabric.util={removeFromArray:function(e,t){var n=e.indexOf(t);return n!==-1&&e.splice(n,1),e},getRandomInt:function(e,t){return Math.floor(Math.random()*(t-e+1))+e},degreesToRadians:function(e){return e*r},radiansToDegrees:function(e){return e/r},rotatePoint:function(e,t,n){var r=Math.sin(n),i=Math.cos(n);e.subtractEquals(t);var s=e.x*i-e.y*r,o=e.x*r+e.y*i;return(new fabric.Point(s,o)).addEquals(t)},toFixed:function(e,t){return parseFloat(Number(e).toFixed(t))},falseFunction:function(){return!1},getKlass:function(e,t){return e=fabric.util.string.camelize(e.charAt(0).toUpperCase()+e.slice(1)),fabric.util.resolveNamespace(t)[e]},resolveNamespace:function(t){if(!t)return fabric;var n=t.split("."),r=n.length,i=e||fabric.window;for(var s=0;s1?r=new fabric.PathGroup(e,t):r=e[0],typeof n!="undefined"&&r.setSourcePath(n),r},populateWithProperties:function(e,t,n){if(n&&Object.prototype.toString.call(n)==="[object Array]")for(var r=0,i=n.length;rr)r+=u[p++%h],r>l&&(r=l),e[d?"lineTo":"moveTo"](r,0),d=!d;e.restore()},createCanvasElement:function(e){return e||(e=fabric.document.createElement("canvas")),!e.getContext&&typeof G_vmlCanvasManager!="undefined"&&G_vmlCanvasManager.initElement(e),e},createImage:function(){return fabric.isLikelyNode?new(require("canvas").Image):fabric.document.createElement("img")},createAccessors:function(e){var t=e.prototype;for(var n=t.stateProperties.length;n--;){var r=t.stateProperties[n],i=r.charAt(0).toUpperCase()+r.slice(1),s="set"+i,o="get"+i;t[o]||(t[o]=function(e){return new Function('return this.get("'+e+'")')}(r)),t[s]||(t[s]=function(e){return new Function("value",'return this.set("'+e+'", value)')}(r))}},clipContext:function(e,t){t.save(),t.beginPath(),e.clipTo(t),t.clip()},multiplyTransformMatrices:function(e,t){var n=[[e[0],e[2],e[4]],[e[1],e[3],e[5]],[0,0,1]],r=[[t[0],t[2],t[4]],[t[1],t[3],t[5]],[0,0,1]],i=[];for(var s=0;s<3;s++){i[s]=[];for(var o=0;o<3;o++){var u=0;for(var a=0;a<3;a++)u+=n[s][a]*r[a][o];i[s][o]=u}}return[i[0][0],i[1][0],i[0][1],i[1][1],i[0][2],i[1][2]]},getFunctionBody:function(e){return(String(e).match(/function[^{]*\{([\s\S]*)\}/)||{})[1]},normalizePoints:function(e,t){var n=fabric.util.array.min(e,"x"),r=fabric.util.array.min(e,"y");n=n<0?n:0,r=n<0?r:0;for(var i=0,s=e.length;i0&&(t>r?t-=r:t=0,n>r?n-=r:n=0);var i=!0,s=e.getImageData(t,n,r*2||1,r*2||1);for(var o=3,u=s.data.length;o0&&f===0&&(E-=2*Math.PI);var S=Math.ceil(Math.abs(E/(Math.PI*.5+.001))),x=[];for(var T=0;T1&&(h=Math.sqrt(h),t*=h,n*=h);var p=f/t,d=a/t,v=-a/n,m=f/n;return{x0:p*r+d*i,y0:v*r+m*i,x1:p*s+d*o,y1:v*s+m*o,sinTh:a,cosTh:f}}function o(e,i,s,o,u,a,f,l){r=n.call(arguments);if(t[r])return t[r];var c=Math.sin(s),h=Math.cos(s),p=Math.sin(o),d=Math.cos(o),v=l*u,m=-f*a,g=f*u,y=l*a,b=.25*(o-s),w=8/3*Math.sin(b)*Math.sin(b)/Math.sin(b*2),E=e+h-w*c,S=i+c+w*h,x=e+d,T=i+p,N=x+w*p,C=T-w*d;return t[r]=[v*E+m*S,g*E+y*S,v*N+m*C,g*N+y*C,v*x+m*T,g*x+y*T],t[r]}var e={},t={},n=Array.prototype.join,r;fabric.util.drawArc=function(e,t,n,r){var s=r[0],u=r[1],a=r[2],f=r[3],l=r[4],c=r[5],h=r[6],p=i(c,h,s,u,f,l,a,t,n);for(var d=0;d=t})}function r(e,t){return i(e,t,function(e,t){return e>>0;if(n===0)return-1;var r=0;arguments.length>0&&(r=Number(arguments[1]),r!==r?r=0:r!==0&&r!==Number.POSITIVE_INFINITY&&r!==Number.NEGATIVE_INFINITY&&(r=(r>0||-1)*Math.floor(Math.abs(r))));if(r>=n)return-1;var i=r>=0?r:Math.max(n-Math.abs(r),0);for(;i>>0;n>>0;r>>0;n>>0;n>>0;i>>0,n=0,r;if(arguments.length>1)r=arguments[1];else do{if(n in this){r=this[n++];break}if(++n>=t)throw new TypeError}while(!0);for(;n/g,">")}String.prototype.trim||(String.prototype.trim=function(){return this.replace(/^[\s\xA0]+/,"").replace(/[\s\xA0]+$/,"")}),fabric.util.string={camelize:e,capitalize:t,escapeXml:n}}(),function(){var e=Array.prototype.slice,t=Function.prototype.apply,n=function(){};Function.prototype.bind||(Function.prototype.bind=function(r){var i=this,s=e.call(arguments,1),o;return s.length?o=function(){return t.call(i,this instanceof n?this:r,s.concat(e.call(arguments)))}:o=function(){return t.call(i,this instanceof n?this:r,arguments)},n.prototype=this.prototype,o.prototype=new n,o})}(),function(){function i(){}function s(t){var n=this.constructor.superclass.prototype[t];return arguments.length>1?n.apply(this,e.call(arguments,1)):n.call(this)}function o(){function u(){this.initialize.apply(this,arguments)}var n=null,o=e.call(arguments,0);typeof o[0]=="function"&&(n=o.shift()),u.superclass=n,u.subclasses=[],n&&(i.prototype=n.prototype,u.prototype=new i,n.subclasses.push(u));for(var a=0,f=o.length;a-1?e.prototype[i]=function(e){return function(){var n=this.constructor.superclass;this.constructor.superclass=r;var i=t[e].apply(this,arguments);this.constructor.superclass=n;if(e!=="initialize")return i}}(i):e.prototype[i]=t[i],n&&(t.toString!==Object.prototype.toString&&(e.prototype.toString=t.toString),t.valueOf!==Object.prototype.valueOf&&(e.prototype.valueOf=t.valueOf))};fabric.util.createClass=o}(),function(){function t(e){var t=Array.prototype.slice.call(arguments,1),n,r,i=t.length;for(r=0;r-1?s(e,t.match(/opacity:\s*(\d?\.?\d*)/)[1]):e;for(var r in t)if(r==="opacity")s(e,t[r]);else{var i=r==="float"||r==="cssFloat"?typeof n.styleFloat=="undefined"?"cssFloat":"styleFloat":r;n[i]=t[r]}return e}var t=fabric.document.createElement("div"),n=typeof t.style.opacity=="string",r=typeof t.style.filter=="string",i=/alpha\s*\(\s*opacity\s*=\s*([^\)]+)\)/,s=function(e){return e};n?s=function(e,t){return e.style.opacity=t,e}:r&&(s=function(e,t){var n=e.style;return e.currentStyle&&!e.currentStyle.hasLayout&&(n.zoom=1),i.test(n.filter)?(t=t>=.9999?"":"alpha(opacity="+t*100+")",n.filter=n.filter.replace(i,t)):n.filter+=" alpha(opacity="+t*100+")",e}),fabric.util.setStyle=e}(),function(){function t(e){return typeof e=="string"?fabric.document.getElementById(e):e}function s(e,t){var n=fabric.document.createElement(e);for(var r in t)r==="class"?n.className=t[r]:r==="for"?n.htmlFor=t[r]:n.setAttribute(r,t[r]);return n}function o(e,t){e&&(" "+e.className+" ").indexOf(" "+t+" ")===-1&&(e.className+=(e.className?" ":"")+t)}function u(e,t,n){return typeof t=="string"&&(t=s(t,n)),e.parentNode&&e.parentNode.replaceChild(t,e),t.appendChild(e),t}function a(e,t){var n,r,i=0,s=0,o=fabric.document.documentElement,u=fabric.document.body||{scrollLeft:0,scrollTop:0};r=e;while(e&&e.parentNode&&!n)e=e.parentNode,e!==fabric.document&&fabric.util.getElementStyle(e,"position")==="fixed"&&(n=e),e!==fabric.document&&r!==t&&fabric.util.getElementStyle(e,"position")==="absolute"?(i=0,s=0):e===fabric.document?(i=u.scrollLeft||o.scrollLeft||0,s=u.scrollTop||o.scrollTop||0):(i+=e.scrollLeft||0,s+=e.scrollTop||0);return{left:i,top:s}}function f(e){var t,n=e&&e.ownerDocument,r={left:0,top:0},i={left:0,top:0},s,o={borderLeftWidth:"left",borderTopWidth:"top",paddingLeft:"left",paddingTop:"top"};if(!n)return{left:0,top:0};for(var u in o)i[o[u]]+=parseInt(l(e,u),10)||0;return t=n.documentElement,typeof e.getBoundingClientRect!="undefined"&&(r=e.getBoundingClientRect()),s=fabric.util.getScrollLeftTop(e,null),{left:r.left+s.left-(t.clientLeft||0)+i.left,top:r.top+s.top-(t.clientTop||0)+i.top}}var e=Array.prototype.slice,n,r=function(t){return e.call(t,0)};try{n=r(fabric.document.childNodes)instanceof Array}catch(i){}n||(r=function(e){var t=new Array(e.length),n=e.length;while(n--)t[n]=e[n];return t});var l;fabric.document.defaultView&&fabric.document.defaultView.getComputedStyle?l=function(e,t){return fabric.document.defaultView.getComputedStyle(e,null)[t]}:l=function(e,t){var n=e.style[t];return!n&&e.currentStyle&&(n=e.currentStyle[t]),n},function(){function n(e){return typeof e.onselectstart!="undefined"&&(e.onselectstart=fabric.util.falseFunction),t?e.style[t]="none":typeof e.unselectable=="string"&&(e.unselectable="on"),e}function r(e){return typeof e.onselectstart!="undefined"&&(e.onselectstart=null),t?e.style[t]="":typeof e.unselectable=="string"&&(e.unselectable=""),e}var e=fabric.document.documentElement.style,t="userSelect"in e?"userSelect":"MozUserSelect"in e?"MozUserSelect":"WebkitUserSelect"in e?"WebkitUserSelect":"KhtmlUserSelect"in e?"KhtmlUserSelect":"";fabric.util.makeElementUnselectable=n,fabric.util.makeElementSelectable=r}(),function(){function e(e,t){var n=fabric.document.getElementsByTagName("head")[0],r=fabric.document.createElement("script"),i=!0;r.onload=r.onreadystatechange=function(e){if(i){if(typeof this.readyState=="string"&&this.readyState!=="loaded"&&this.readyState!=="complete")return;i=!1,t(e||fabric.window.event),r=r.onload=r.onreadystatechange=null}},r.src=e,n.appendChild(r)}fabric.util.getScript=e}(),fabric.util.getById=t,fabric.util.toArray=r,fabric.util.makeElement=s,fabric.util.addClass=o,fabric.util.wrapElement=u,fabric.util.getScrollLeftTop=a,fabric.util.getElementOffset=f,fabric.util.getElementStyle=l}(),function(){function e(e,t){return e+(/\?/.test(e)?"&":"?")+t}function n(){}function r(r,i){i||(i={});var s=i.method?i.method.toUpperCase():"GET",o=i.onComplete||function(){},u=t(),a;return u.onreadystatechange=function(){u.readyState===4&&(o(u),u.onreadystatechange=n)},s==="GET"&&(a=null,typeof i.parameters=="string"&&(r=e(r,i.parameters))),u.open(s,r,!0),(s==="POST"||s==="PUT")&&u.setRequestHeader("Content-Type","application/x-www-form-urlencoded"),u.send(a),u}var t=function(){var e=[function(){return new ActiveXObject("Microsoft.XMLHTTP")},function(){return new ActiveXObject("Msxml2.XMLHTTP")},function(){return new ActiveXObject("Msxml2.XMLHTTP.3.0")},function(){return new XMLHttpRequest}];for(var t=e.length;t--;)try{var n=e[t]();if(n)return e[t]}catch(r){}}();fabric.util.request=r}(),fabric.log=function(){},fabric.warn=function(){},typeof console!="undefined"&&["log","warn"].forEach(function(e){typeof console[e]!="undefined"&&console[e].apply&&(fabric[e]=function(){return console[e].apply(console,arguments)})}),function(){function e(e){n(function(t){e||(e={});var r=t||+(new Date),i=e.duration||500,s=r+i,o,u=e.onChange||function(){},a=e.abort||function(){return!1},f=e.easing||function(e,t,n,r){return-n*Math.cos(e/r*(Math.PI/2))+n+t},l="startValue"in e?e.startValue:0,c="endValue"in e?e.endValue:100,h=e.byValue||c-l;e.onStart&&e.onStart(),function p(t){o=t||+(new Date);var c=o>s?i:o-r;if(a()){e.onComplete&&e.onComplete();return}u(f(c,l,h,i));if(o>s){e.onComplete&&e.onComplete();return}n(p)}(r)})}function n(){return t.apply(fabric.window,arguments)}var t=fabric.window.requestAnimationFrame||fabric.window.webkitRequestAnimationFrame||fabric.window.mozRequestAnimationFrame||fabric.window.oRequestAnimationFrame||fabric.window.msRequestAnimationFrame||function(e){fabric.window.setTimeout(e,1e3/60)};fabric.util.animate=e,fabric.util.requestAnimFrame=n}(),function(){function e(e,t,n,r){return e','')}var t=e.fabric||(e.fabric={}),n=t.util.object.extend,r=t.util.string.capitalize,i=t.util.object.clone,s=t.util.toFixed,o=t.util.multiplyTransformMatrices,u={cx:"left",x:"left",r:"radius",cy:"top",y:"top",display:"visible",visibility:"visible",transform:"transformMatrix","fill-opacity":"fillOpacity","fill-rule":"fillRule","font-family":"fontFamily","font-size":"fontSize","font-style":"fontStyle","font-weight":"fontWeight","stroke-dasharray":"strokeDashArray","stroke-linecap":"strokeLineCap","stroke-linejoin":"strokeLineJoin","stroke-miterlimit":"strokeMiterLimit","stroke-opacity":"strokeOpacity","stroke-width":"strokeWidth","text-decoration":"textDecoration","text-anchor":"originX"},a={stroke:"strokeOpacity",fill:"fillOpacity"};t.parseTransformAttribute=function(){function e(e,t){var n=t[0];e[0]=Math.cos(n),e[1]=Math.sin(n),e[2]=-Math.sin(n),e[3]=Math.cos(n)}function n(e,t){var n=t[0],r=t.length===2?t[1]:t[0];e[0]=n,e[3]=r}function r(e,t){e[2]=t[0]}function i(e,t){e[1]=t[0]}function s(e,t){e[4]=t[0],t.length===2&&(e[5]=t[1])}var o=[1,0,0,1,0,0],u="(?:[-+]?(?:\\d+|\\d*\\.\\d+)(?:e[-+]?\\d+)?)",a="(?:\\s+,?\\s*|,\\s*)",f="(?:(skewX)\\s*\\(\\s*("+u+")\\s*\\))",l="(?:(skewY)\\s*\\(\\s*("+u+")\\s*\\))",c="(?:(rotate)\\s*\\(\\s*("+u+")(?:"+a+"("+u+")"+a+"("+u+"))?\\s*\\))",h="(?:(scale)\\s*\\(\\s*("+u+")(?:"+a+"("+u+"))?\\s*\\))",p="(?:(translate)\\s*\\(\\s*("+u+")(?:"+a+"("+u+"))?\\s*\\))",d="(?:(matrix)\\s*\\(\\s*("+u+")"+a+"("+u+")"+a+"("+u+")"+a+"("+u+")"+a+"("+u+")"+a+"("+u+")"+"\\s*\\))",v="(?:"+d+"|"+p+"|"+h+"|"+c+"|"+f+"|"+l+")",m="(?:"+v+"(?:"+a+v+")*"+")",g="^\\s*(?:"+m+"?)\\s*$",y=new RegExp(g),b=new RegExp(v,"g");return function(u){var a=o.concat(),f=[];if(!u||u&&!y.test(u))return a;u.replace(b,function(u){var l=(new RegExp(v)).exec(u).filter(function(e){return e!==""&&e!=null}),c=l[1],h=l.slice(2).map(parseFloat);switch(c){case"translate":s(a,h);break;case"rotate":h[0]=t.util.degreesToRadians(h[0]),e(a,h);break;case"scale":n(a,h);break;case"skewX":r(a,h);break;case"skewY":i(a,h);break;case"matrix":a=h}f.push(a.concat()),a=o.concat()});var l=f[0];while(f.length>1)f.shift(),l=t.util.multiplyTransformMatrices(l,f[0]);return l}}(),t.parseSVGDocument=function(){function s(e,t){while(e&&(e=e.parentNode))if(t.test(e.nodeName))return!0;return!1}var e=/^(path|circle|polygon|polyline|ellipse|rect|line|image|text)$/,n="(?:[-+]?(?:\\d+|\\d*\\.\\d+)(?:e[-+]?\\d+)?)",r=new RegExp("^\\s*("+n+"+)\\s*,?"+"\\s*("+n+"+)\\s*,?"+"\\s*("+n+"+)\\s*,?"+"\\s*("+n+"+)\\s*"+"$");return function(n,o,u){if(!n)return;var a=new Date,f=t.util.toArray(n.getElementsByTagName("*"));if(f.length===0&&t.isLikelyNode){f=n.selectNodes('//*[name(.)!="svg"]');var l=[];for(var c=0,h=f.length;c-1;e=e.split(/\s+/);var n=[],r,i;if(t){r=0,i=e.length;for(;r/i,"")));if(!s||!s.documentElement)return;t.parseSVGDocument(s.documentElement,function(r,i){m.set(e,{objects:t.util.array.invoke(r,"toObject"),options:i}),n(r,i)},r)}e=e.replace(/^\n\s*/,"").trim(),m.has(e,function(r){r?m.get(e,function(e){var t=g(e);n(t.objects,t.options)}):new t.util.request(e,{method:"get",onComplete:i})})},loadSVGFromString:function(e,n,r){e=e.trim();var i;if(typeof DOMParser!="undefined"){var s=new DOMParser;s&&s.parseFromString&&(i=s.parseFromString(e,"text/xml"))}else t.window.ActiveXObject&&(i=new ActiveXObject("Microsoft.XMLDOM"),i.async="false",i.loadXML(e.replace(//i,"")));t.parseSVGDocument(i.documentElement,function(e,t){n(e,t)},r)},createSVGFontFacesMarkup:function(e){var t="";for(var n=0,r=e.length;n',"",""].join("")),t},createSVGRefElementsMarkup:function(e){var t=[];return y(t,e,"backgroundColor"),y(t,e,"overlayColor"),t.join("")}})}(typeof exports!="undefined"?exports:this),fabric.ElementsParser=function(e,t,n,r){this.elements=e,this.callback=t,this.options=n,this.reviver=r},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 e=0,t=this.elements.length;ee.x&&this.y>e.y},gte:function(e){return this.x>=e.x&&this.y>=e.y},lerp:function(e,t){return new n(this.x+(e.x-this.x)*t,this.y+(e.y-this.y)*t)},distanceFrom:function(e){var t=this.x-e.x,n=this.y-e.y;return Math.sqrt(t*t+n*n)},midPointFrom:function(e){return new n(this.x+(e.x-this.x)/2,this.y+(e.y-this.y)/2)},min:function(e){return new n(Math.min(this.x,e.x),Math.min(this.y,e.y))},max:function(e){return new n(Math.max(this.x,e.x),Math.max(this.y,e.y))},toString:function(){return this.x+","+this.y},setXY:function(e,t){this.x=e,this.y=t},setFromPoint:function(e){this.x=e.x,this.y=e.y},swap:function(e){var t=this.x,n=this.y;this.x=e.x,this.y=e.y,e.x=t,e.y=n}}}(typeof exports!="undefined"?exports:this),function(e){"use strict";function n(e){this.status=e,this.points=[]}var t=e.fabric||(e.fabric={});if(t.Intersection){t.warn("fabric.Intersection is already defined");return}t.Intersection=n,t.Intersection.prototype={appendPoint:function(e){this.points.push(e)},appendPoints:function(e){this.points=this.points.concat(e)}},t.Intersection.intersectLineLine=function(e,r,i,s){var o,u=(s.x-i.x)*(e.y-i.y)-(s.y-i.y)*(e.x-i.x),a=(r.x-e.x)*(e.y-i.y)-(r.y-e.y)*(e.x-i.x),f=(s.y-i.y)*(r.x-e.x)-(s.x-i.x)*(r.y-e.y);if(f!==0){var l=u/f,c=a/f;0<=l&&l<=1&&0<=c&&c<=1?(o=new n("Intersection"),o.points.push(new t.Point(e.x+l*(r.x-e.x),e.y+l*(r.y-e.y)))):o=new n}else u===0||a===0?o=new n("Coincident"):o=new n("Parallel");return o},t.Intersection.intersectLinePolygon=function(e,t,r){var i=new n,s=r.length;for(var o=0;o0&&(i.status="Intersection"),i},t.Intersection.intersectPolygonPolygon=function(e,t){var r=new n,i=e.length;for(var s=0;s0&&(r.status="Intersection"),r},t.Intersection.intersectPolygonRectangle=function(e,r,i){var s=r.min(i),o=r.max(i),u=new t.Point(o.x,s.y),a=new t.Point(s.x,o.y),f=n.intersectLinePolygon(s,u,e),l=n.intersectLinePolygon(u,o,e),c=n.intersectLinePolygon(o,a,e),h=n.intersectLinePolygon(a,s,e),p=new n;return p.appendPoints(f.points),p.appendPoints(l.points),p.appendPoints(c.points),p.appendPoints(h.points),p.points.length>0&&(p.status="Intersection"),p}}(typeof exports!="undefined"?exports:this),function(e){"use strict";function n(e){e?this._tryParsingColor(e):this.setSource([0,0,0,1])}function r(e,t,n){return n<0&&(n+=1),n>1&&(n-=1),n<1/6?e+(t-e)*6*n:n<.5?t:n<2/3?e+(t-e)*(2/3-n)*6:e}var t=e.fabric||(e.fabric={});if(t.Color){t.warn("fabric.Color is already defined.");return}t.Color=n,t.Color.prototype={_tryParsingColor:function(e){var t;e in n.colorNameMap&&(e=n.colorNameMap[e]);if(e==="transparent"){this.setSource([255,255,255,0]);return}t=n.sourceFromHex(e),t||(t=n.sourceFromRgb(e)),t||(t=n.sourceFromHsl(e)),t&&this.setSource(t)},_rgbToHsl:function(e,n,r){e/=255,n/=255,r/=255;var i,s,o,u=t.util.array.max([e,n,r]),a=t.util.array.min([e,n,r]);o=(u+a)/2;if(u===a)i=s=0;else{var f=u-a;s=o>.5?f/(2-u-a):f/(u+a);switch(u){case e:i=(n-r)/f+(n']:this.type==="radial"&&(r=["']);for(var i=0;i');return r.push(this.type==="linear"?"":""),r.join("")},toLive:function(e){var t;if(!this.type)return;this.type==="linear"?t=e.createLinearGradient(this.coords.x1,this.coords.y1,this.coords.x2,this.coords.y2):this.type==="radial"&&(t=e.createRadialGradient(this.coords.x1,this.coords.y1,this.coords.r1,this.coords.x2,this.coords.y2,this.coords.r2));for(var n=0,r=this.colorStops.length;n'+''+""},toLive:function(e){var t=typeof this.source=="function"?this.source():this.source;if(!t)return"";if(typeof t.src!="undefined"){if(!t.complete)return"";if(t.naturalWidth===0||t.naturalHeight===0)return""}return e.createPattern(t,this.repeat)}}),function(e){"use strict";var t=e.fabric||(e.fabric={});if(t.Shadow){t.warn("fabric.Shadow is already defined.");return}t.Shadow=t.util.createClass({color:"rgb(0,0,0)",blur:0,offsetX:0,offsetY:0,affectStroke:!1,includeDefaultValues:!0,initialize:function(e){typeof e=="string"&&(e=this._parseShadow(e));for(var n in e)this[n]=e[n];this.id=t.Object.__uid++},_parseShadow:function(e){var n=e.trim(),r=t.Shadow.reOffsetsAndBlur.exec(n)||[],i=n.replace(t.Shadow.reOffsetsAndBlur,"")||"rgb(0,0,0)";return{color:i.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(e){var t="SourceAlpha";return e&&(e.fill===this.color||e.stroke===this.color)&&(t="SourceGraphic"),''+''+''+""+""+''+""+""},toObject:function(){if(this.includeDefaultValues)return{color:this.color,blur:this.blur,offsetX:this.offsetX,offsetY:this.offsetY};var e={},n=t.Shadow.prototype;return this.color!==n.color&&(e.color=this.color),this.blur!==n.blur&&(e.blur=this.blur),this.offsetX!==n.offsetX&&(e.offsetX=this.offsetX),this.offsetY!==n.offsetY&&(e.offsetY=this.offsetY),e}}),t.Shadow.reOffsetsAndBlur=/(?:\s|^)(-?\d+(?:px)?(?:\s?|$))?(-?\d+(?:px)?(?:\s?|$))?(\d+(?:px)?)?(?:\s?|$)(?:$|\s)/}(typeof exports!="undefined"?exports:this),function(){"use strict";if(fabric.StaticCanvas){fabric.warn("fabric.StaticCanvas is already defined.");return}var e=fabric.util.object.extend,t=fabric.util.getElementOffset,n=fabric.util.removeFromArray,r=new Error("Could not initialize `canvas` element");fabric.StaticCanvas=fabric.util.createClass({initialize:function(e,t){t||(t={}),this._initStatic(e,t),fabric.StaticCanvas.activeInstance=this},backgroundColor:"",backgroundImage:null,overlayColor:"",overlayImage:null,includeDefaultValues:!0,stateful:!0,renderOnAddRemove:!0,clipTo:null,controlsAboveOverlay:!1,allowTouchScrolling:!1,imageSmoothingEnabled:!0,onBeforeScaleRotate:function(){},_initStatic:function(e,t){this._objects=[],this._createLowerCanvas(e),this._initOptions(t),this._setImageSmoothing(),t.overlayImage&&this.setOverlayImage(t.overlayImage,this.renderAll.bind(this)),t.backgroundImage&&this.setBackgroundImage(t.backgroundImage,this.renderAll.bind(this)),t.backgroundColor&&this.setBackgroundColor(t.backgroundColor,this.renderAll.bind(this)),t.overlayColor&&this.setOverlayColor(t.overlayColor,this.renderAll.bind(this)),this.calcOffset()},calcOffset:function(){return this._offset=t(this.lowerCanvasEl),this},setOverlayImage:function(e,t,n){return this.__setBgOverlayImage("overlayImage",e,t,n)},setBackgroundImage:function(e,t,n){return this.__setBgOverlayImage("backgroundImage",e,t,n)},setOverlayColor:function(e,t){return this.__setBgOverlayColor("overlayColor",e,t)},setBackgroundColor:function(e,t){return this.__setBgOverlayColor("backgroundColor",e,t)},_setImageSmoothing:function(){var e=this.getContext();e.imageSmoothingEnabled=this.imageSmoothingEnabled,e.webkitImageSmoothingEnabled=this.imageSmoothingEnabled,e.mozImageSmoothingEnabled=this.imageSmoothingEnabled,e.msImageSmoothingEnabled=this.imageSmoothingEnabled,e.oImageSmoothingEnabled=this.imageSmoothingEnabled},__setBgOverlayImage:function(e,t,n,r){return typeof t=="string"?fabric.util.loadImage(t,function(t){this[e]=new fabric.Image(t,r),n&&n()},this):(this[e]=t,n&&n()),this},__setBgOverlayColor:function(e,t,n){if(t.source){var r=this;fabric.util.loadImage(t.source,function(i){r[e]=new fabric.Pattern({source:i,repeat:t.repeat,offsetX:t.offsetX,offsetY:t.offsetY}),n&&n()})}else this[e]=t,n&&n();return this},_createCanvasElement:function(){var e=fabric.document.createElement("canvas");e.style||(e.style={});if(!e)throw r;return this._initCanvasElement(e),e},_initCanvasElement:function(e){fabric.util.createCanvasElement(e);if(typeof e.getContext=="undefined")throw r},_initOptions:function(e){for(var t in e)this[t]=e[t];this.width=this.width||parseInt(this.lowerCanvasEl.width,10)||0,this.height=this.height||parseInt(this.lowerCanvasEl.height,10)||0;if(!this.lowerCanvasEl.style)return;this.lowerCanvasEl.width=this.width,this.lowerCanvasEl.height=this.height,this.lowerCanvasEl.style.width=this.width+"px",this.lowerCanvasEl.style.height=this.height+"px"},_createLowerCanvas:function(e){this.lowerCanvasEl=fabric.util.getById(e)||this._createCanvasElement(),this._initCanvasElement(this.lowerCanvasEl),fabric.util.addClass(this.lowerCanvasEl,"lower-canvas"),this.interactive&&this._applyCanvasStyle(this.lowerCanvasEl),this.contextContainer=this.lowerCanvasEl.getContext("2d")},getWidth:function(){return this.width},getHeight:function(){return this.height},setWidth:function(e){return this._setDimension("width",e)},setHeight:function(e){return this._setDimension("height",e)},setDimensions:function(e){for(var t in e)this._setDimension(t,e[t]);return this},_setDimension:function(e,t){return this.lowerCanvasEl[e]=t,this.lowerCanvasEl.style[e]=t+"px",this.upperCanvasEl&&(this.upperCanvasEl[e]=t,this.upperCanvasEl.style[e]=t+"px"),this.cacheCanvasEl&&(this.cacheCanvasEl[e]=t),this.wrapperEl&&(this.wrapperEl.style[e]=t+"px"),this[e]=t,this.calcOffset(),this.renderAll(),this},getElement:function(){return this.lowerCanvasEl},getActiveObject:function(){return null},getActiveGroup:function(){return null},_draw:function(e,t){if(!t)return;if(this.controlsAboveOverlay){var n=t.hasBorders,r=t.hasControls;t.hasBorders=t.hasControls=!1,t.render(e),t.hasBorders=n,t.hasControls=r}else t.render(e)},_onObjectAdded:function(e){this.stateful&&e.setupState(),e.setCoords(),e.canvas=this,this.fire("object:added",{target:e}),e.fire("added")},_onObjectRemoved:function(e){this.getActiveObject()===e&&(this.fire("before:selection:cleared",{target:e}),this._discardActiveObject(),this.fire("selection:cleared")),this.fire("object:removed",{target:e}),e.fire("removed")},clearContext:function(e){return e.clearRect(0,0,this.width,this.height),this},getContext:function(){return this.contextContainer},clear:function(){return this._objects.length=0,this.discardActiveGroup&&this.discardActiveGroup(),this.discardActiveObject&&this.discardActiveObject(),this.clearContext(this.contextContainer),this.contextTop&&this.clearContext(this.contextTop),this.fire("canvas:cleared"),this.renderAll(),this},renderAll:function(e){var t=this[e===!0&&this.interactive?"contextTop":"contextContainer"],n=this.getActiveGroup();return this.contextTop&&this.selection&&!this._groupSelector&&this.clearContext(this.contextTop),e||this.clearContext(t),this.fire("before:render"),this.clipTo&&fabric.util.clipContext(this,t),this._renderBackground(t),this._renderObjects(t,n),this._renderActiveGroup(t,n),this.clipTo&&t.restore(),this._renderOverlay(t),this.controlsAboveOverlay&&this.interactive&&this.drawControls(t),this.fire("after:render"),this},_renderObjects:function(e,t){var n,r;if(!t)for(n=0,r=this._objects.length;n"),n.join("")},_setSVGPreamble:function(e,t){t.suppressPreamble||e.push('','\n')},_setSVGHeader:function(e,t){e.push("',"Created with Fabric.js ",fabric.version,"","",fabric.createSVGFontFacesMarkup(this.getObjects()),fabric.createSVGRefElementsMarkup(this),"")},_setSVGObjects:function(e,t){var n=this.getActiveGroup();n&&this.discardActiveGroup();for(var r=0,i=this.getObjects(),s=i.length;r"):this[t]&&t==="overlayColor"&&e.push('")},sendToBack:function(e){return n(this._objects,e),this._objects.unshift(e),this.renderAll&&this.renderAll()},bringToFront:function(e){return n(this._objects,e),this._objects.push(e),this.renderAll&&this.renderAll()},sendBackwards:function(e,t){var r=this._objects.indexOf(e);if(r!==0){var i=this._findNewLowerIndex(e,r,t);n(this._objects,e),this._objects.splice(i,0,e),this.renderAll&&this.renderAll()}return this},_findNewLowerIndex:function(e,t,n){var r;if(n){r=t;for(var i=t-1;i>=0;--i){var s=e.intersectsWithObject(this._objects[i])||e.isContainedWithinObject(this._objects[i])||this._objects[i].isContainedWithinObject(e);if(s){r=i;break}}}else r=t-1;return r},bringForward:function(e,t){var r=this._objects.indexOf(e);if(r!==this._objects.length-1){var i=this._findNewUpperIndex(e,r,t);n(this._objects,e),this._objects.splice(i,0,e),this.renderAll&&this.renderAll()}return this},_findNewUpperIndex:function(e,t,n){var r;if(n){r=t;for(var i=t+1;i"}}),e(fabric.StaticCanvas.prototype,fabric.Observable),e(fabric.StaticCanvas.prototype,fabric.Collection),e(fabric.StaticCanvas.prototype,fabric.DataURLExporter),e(fabric.StaticCanvas,{EMPTY_JSON:'{"objects": [], "background": "white"}',supports:function(e){var t=fabric.util.createCanvasElement();if(!t||!t.getContext)return null;var n=t.getContext("2d");if(!n)return null;switch(e){case"getImageData":return typeof n.getImageData!="undefined";case"setLineDash":return typeof n.setLineDash!="undefined";case"toDataURL":return typeof t.toDataURL!="undefined";case"toDataURLWithQuality":try{return t.toDataURL("image/jpeg",0),!0}catch(r){}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",setShadow:function(e){return this.shadow=new fabric.Shadow(e),this},_setBrushStyles:function(){var e=this.canvas.contextTop;e.strokeStyle=this.color,e.lineWidth=this.width,e.lineCap=this.strokeLineCap,e.lineJoin=this.strokeLineJoin},_setShadow:function(){if(!this.shadow)return;var e=this.canvas.contextTop;e.shadowColor=this.shadow.color,e.shadowBlur=this.shadow.blur,e.shadowOffsetX=this.shadow.offsetX,e.shadowOffsetY=this.shadow.offsetY},_resetShadow:function(){var e=this.canvas.contextTop;e.shadowColor="",e.shadowBlur=e.shadowOffsetX=e.shadowOffsetY=0}}),function(){var e=fabric.util.array.min,t=fabric.util.array.max;fabric.PencilBrush=fabric.util.createClass(fabric.BaseBrush,{initialize:function(e){this.canvas=e,this._points=[]},onMouseDown:function(e){this._prepareForDrawing(e),this._captureDrawingPath(e),this._render()},onMouseMove:function(e){this._captureDrawingPath(e),this.canvas.clearContext(this.canvas.contextTop),this._render()},onMouseUp:function(){this._finalizeAndAddPath()},_prepareForDrawing:function(e){var t=new fabric.Point(e.x,e.y);this._reset(),this._addPoint(t),this.canvas.contextTop.moveTo(t.x,t.y)},_addPoint:function(e){this._points.push(e)},_reset:function(){this._points.length=0,this._setBrushStyles(),this._setShadow()},_captureDrawingPath:function(e){var t=new fabric.Point(e.x,e.y);this._addPoint(t)},_render:function(){var e=this.canvas.contextTop;e.beginPath();var t=this._points[0],n=this._points[1];this._points.length===2&&t.x===n.x&&t.y===n.y&&(t.x-=.5,n.x+=.5),e.moveTo(t.x,t.y);for(var r=1,i=this._points.length;rn.padding?e.x<0?e.x+=n.padding:e.x-=n.padding:e.x=0,i(e.y)>n.padding?e.y<0?e.y+=n.padding:e.y-=n.padding:e.y=0},_rotateObject:function(e,t){var i=this._currentTransform;if(i.target.get("lockRotation"))return;var s=r(i.ey-i.top,i.ex-i.left),o=r(t-i.top,e-i.left),u=n(o-s+i.theta);u<0&&(u=360+u),i.target.angle=u},_setCursor:function(e){this.upperCanvasEl.style.cursor=e},_resetObjectTransform:function(e){e.scaleX=1,e.scaleY=1,e.setAngle(0)},_drawSelection:function(){var e=this.contextTop,t=this._groupSelector,n=t.left,r=t.top,o=i(n),u=i(r);e.fillStyle=this.selectionColor,e.fillRect(t.ex-(n>0?0:-n),t.ey-(r>0?0:-r),o,u),e.lineWidth=this.selectionLineWidth,e.strokeStyle=this.selectionBorderColor;if(this.selectionDashArray.length>1){var a=t.ex+s-(n>0?0:o),f=t.ey+s-(r>0?0:u);e.beginPath(),fabric.util.drawDashedLine(e,a,f,a+o,f,this.selectionDashArray),fabric.util.drawDashedLine(e,a,f+u-1,a+o,f+u-1,this.selectionDashArray),fabric.util.drawDashedLine(e,a,f,a,f+u,this.selectionDashArray),fabric.util.drawDashedLine(e,a+o-1,f,a+o-1,f+u,this.selectionDashArray),e.closePath(),e.stroke()}else e.strokeRect(t.ex+s-(n>0?0:o),t.ey+s-(r>0?0:u),o,u)},_isLastRenderedObject:function(e){return this.controlsAboveOverlay&&this.lastRenderedObjectWithControlsAboveOverlay&&this.lastRenderedObjectWithControlsAboveOverlay.visible&&this.containsPoint(e,this.lastRenderedObjectWithControlsAboveOverlay)&&this.lastRenderedObjectWithControlsAboveOverlay._findTargetCorner(this.getPointer(e))},findTarget:function(e,t){if(this.skipTargetFind)return;if(this._isLastRenderedObject(e))return this.lastRenderedObjectWithControlsAboveOverlay;var n=this.getActiveGroup();if(n&&!t&&this.containsPoint(e,n))return n;var r=this._searchPossibleTargets(e);return this._fireOverOutEvents(r),r},_fireOverOutEvents:function(e){e?this._hoveredTarget!==e&&(this.fire("mouse:over",{target:e}),e.fire("mouseover"),this._hoveredTarget&&(this.fire("mouse:out",{target:this._hoveredTarget}),this._hoveredTarget.fire("mouseout")),this._hoveredTarget=e):this._hoveredTarget&&(this.fire("mouse:out",{target:this._hoveredTarget}),this._hoveredTarget.fire("mouseout"),this._hoveredTarget=null)},_checkTarget:function(e,t,n){if(t&&t.visible&&t.evented&&this.containsPoint(e,t)){if(!this.perPixelTargetFind&&!t.perPixelTargetFind||!!t.isEditing)return!0;var r=this.isTargetTransparent(t,n.x,n.y);if(!r)return!0}},_searchPossibleTargets:function(e){var t,n=this.getPointer(e),r=this._objects.length;while(r--)if(this._checkTarget(e,this._objects[r],n)){this.relatedTarget=this._objects[r],t=this._objects[r];break}return t},getPointer:function(t){var n=e(t,this.upperCanvasEl),r=this.upperCanvasEl.getBoundingClientRect(),i;return r.width===0||r.height===0?i={width:1,height:1}:i={width:this.upperCanvasEl.width/r.width,height:this.upperCanvasEl.height/r.height},{x:(n.x-this._offset.left)*i.width,y:(n.y-this._offset.top)*i.height}},_createUpperCanvas:function(){var e=this.lowerCanvasEl.className.replace(/\s*lower-canvas\s*/,"");this.upperCanvasEl=this._createCanvasElement(),fabric.util.addClass(this.upperCanvasEl,"upper-canvas "+e),this.wrapperEl.appendChild(this.upperCanvasEl),this._copyCanvasStyle(this.lowerCanvasEl,this.upperCanvasEl),this._applyCanvasStyle(this.upperCanvasEl),this.contextTop=this.upperCanvasEl.getContext("2d")},_createCacheCanvas:function(){this.cacheCanvasEl=this._createCanvasElement(),this.cacheCanvasEl.setAttribute("width",this.width),this.cacheCanvasEl.setAttribute("height",this.height),this.contextCache=this.cacheCanvasEl.getContext("2d")},_initWrapperElement:function(){this.wrapperEl=fabric.util.wrapElement(this.lowerCanvasEl,"div",{"class":this.containerClass}),fabric.util.setStyle(this.wrapperEl,{width:this.getWidth()+"px",height:this.getHeight()+"px",position:"relative"}),fabric.util.makeElementUnselectable(this.wrapperEl)},_applyCanvasStyle:function(e){var t=this.getWidth()||e.width,n=this.getHeight()||e.height;fabric.util.setStyle(e,{position:"absolute",width:t+"px",height:n+"px",left:0,top:0}),e.width=t,e.height=n,fabric.util.makeElementUnselectable(e)},_copyCanvasStyle:function(e,t){t.style.cssText=e.style.cssText},getSelectionContext:function(){return this.contextTop},getSelectionElement:function(){return this.upperCanvasEl},_setActiveObject:function(e){this._activeObject&&this._activeObject.set("active",!1),this._activeObject=e,e.set("active",!0)},setActiveObject:function(e,t){return this._setActiveObject(e),this.renderAll(),this.fire("object:selected",{target:e,e:t}),e.fire("selected",{e:t}),this},getActiveObject:function(){return this._activeObject},_discardActiveObject:function(){this._activeObject&&this._activeObject.set("active",!1),this._activeObject=null},discardActiveObject:function(e){return this._discardActiveObject(),this.renderAll(),this.fire("selection:cleared",{e:e}),this},_setActiveGroup:function(e){this._activeGroup=e,e&&(e.canvas=this,e.set("active",!0))},setActiveGroup:function(e,t){return this._setActiveGroup(e),e&&(this.fire("object:selected",{target:e,e:t}),e.fire("selected",{e:t})),this},getActiveGroup:function(){return this._activeGroup},_discardActiveGroup:function(){var e=this.getActiveGroup();e&&e.destroy(),this.setActiveGroup(null)},discardActiveGroup:function(e){return this._discardActiveGroup(),this.fire("selection:cleared",{e:e}),this},deactivateAll:function(){var e=this.getObjects(),t=0,n=e.length;for(;t1&&(t=new fabric.Group(t.reverse(),{originX:"center",originY:"center"}),this.setActiveGroup(t,e),t.saveCoords(),this.fire("selection:created",{target:t}),this.renderAll())},_collectObjects:function(){var n=[],r,i=this._groupSelector.ex,s=this._groupSelector.ey,o=i+this._groupSelector.left,u=s+this._groupSelector.top,a=new fabric.Point(e(i,o),e(s,u)),f=new fabric.Point(t(i,o),t(s,u)),l=i===o&&s===u;for(var c=this._objects.length;c--;){r=this._objects[c];if(!r||!r.selectable||!r.visible)continue;if(r.intersectsWithRect(a,f)||r.isContainedWithinRect(a,f)||r.containsPoint(a)||r.containsPoint(f)){r.set("active",!0),n.push(r);if(l)break}}return n},_maybeGroupObjects:function(e){this.selection&&this._groupSelector&&this._groupSelectedObjects(e);var t=this.getActiveGroup();t&&(t.setObjectsCoords().setCoords(),t.isMoving=!1,this._setCursor(this.defaultCursor)),this._groupSelector=null,this._currentTransform=null}})}(),fabric.util.object.extend(fabric.StaticCanvas.prototype,{toDataURL:function(e){e||(e={});var t=e.format||"png",n=e.quality||1,r=e.multiplier||1,i={left:e.left,top:e.top,width:e.width,height:e.height};return r!==1?this.__toDataURLWithMultiplier(t,n,i,r):this.__toDataURL(t,n,i)},__toDataURL:function(e,t,n){this.renderAll(!0);var r=this.upperCanvasEl||this.lowerCanvasEl,i=this.__getCroppedCanvas(r,n);e==="jpg"&&(e="jpeg");var s=fabric.StaticCanvas.supports("toDataURLWithQuality")?(i||r).toDataURL("image/"+e,t):(i||r).toDataURL("image/"+e);return this.contextTop&&this.clearContext(this.contextTop),this.renderAll(),i&&(i=null),s},__getCroppedCanvas:function(e,t){var n,r,i="left"in t||"top"in t||"width"in t||"height"in t;return i&&(n=fabric.util.createCanvasElement(),r=n.getContext("2d"),n.width=t.width||this.width,n.height=t.height||this.height,r.drawImage(e,-t.left||0,-t.top||0)),n},__toDataURLWithMultiplier:function(e,t,n,r){var i=this.getWidth(),s=this.getHeight(),o=i*r,u=s*r,a=this.getActiveObject(),f=this.getActiveGroup(),l=this.contextTop||this.contextContainer;r>1&&this.setWidth(o).setHeight(u),l.scale(r,r),n.left&&(n.left*=r),n.top&&(n.top*=r),n.width?n.width*=r:r<1&&(n.width=o),n.height?n.height*=r:r<1&&(n.height=u),f?this._tempRemoveBordersControlsFromGroup(f):a&&this.deactivateAll&&this.deactivateAll(),this.renderAll(!0);var c=this.__toDataURL(e,t,n);return this.width=i,this.height=s,l.scale(1/r,1/r),this.setWidth(i).setHeight(s),f?this._restoreBordersControlsOnGroup(f):a&&this.setActiveObject&&this.setActiveObject(a),this.contextTop&&this.clearContext(this.contextTop),this.renderAll(),c},toDataURLWithMultiplier:function(e,t,n){return this.toDataURL({format:e,multiplier:t,quality:n})},_tempRemoveBordersControlsFromGroup:function(e){e.origHasControls=e.hasControls,e.origBorderColor=e.borderColor,e.hasControls=!0,e.borderColor="rgba(0,0,0,0)",e.forEachObject(function(e){e.origBorderColor=e.borderColor,e.borderColor="rgba(0,0,0,0)"})},_restoreBordersControlsOnGroup:function(e){e.hideControls=e.origHideControls,e.borderColor=e.origBorderColor,e.forEachObject(function(e){e.borderColor=e.origBorderColor,delete e.origBorderColor})}}),fabric.util.object.extend(fabric.StaticCanvas.prototype,{loadFromDatalessJSON:function(e,t,n){return this.loadFromJSON(e,t,n)},loadFromJSON:function(e,t,n){if(!e)return;var r=typeof e=="string"?JSON.parse(e):e;this.clear();var i=this;return this._enlivenObjects(r.objects,function(){i._setBgOverlay(r,t)},n),this},_setBgOverlay:function(e,t){var n=this,r={backgroundColor:!1,overlayColor:!1,backgroundImage:!1,overlayImage:!1};if(!e.backgroundImage&&!e.overlayImage&&!e.background&&!e.overlay){t&&t();return}var i=function(){r.backgroundImage&&r.overlayImage&&r.backgroundColor&&r.overlayColor&&(n.renderAll(),t&&t())};this.__setBgOverlay("backgroundImage",e.backgroundImage,r,i),this.__setBgOverlay("overlayImage",e.overlayImage,r,i),this.__setBgOverlay("backgroundColor",e.background,r,i),this.__setBgOverlay("overlayColor",e.overlay,r,i),i()},__setBgOverlay:function(e,t,n,r){var i=this;if(!t){n[e]=!0;return}e==="backgroundImage"||e==="overlayImage"?fabric.Image.fromObject(t,function(t){i[e]=t,n[e]=!0,r&&r()}):this["set"+fabric.util.string.capitalize(e,!0)](t,function(){n[e]=!0,r&&r()})},_enlivenObjects:function(e,t,n){var r=this;if(!e||e.length===0){t&&t();return}var i=this.renderOnAddRemove;this.renderOnAddRemove=!1,fabric.util.enlivenObjects(e,function(e){e.forEach(function(e,t){r.insertAt(e,t,!0)}),r.renderOnAddRemove=i,t&&t()},null,n)},_toDataURL:function(e,t){this.clone(function(n){t(n.toDataURL(e))})},_toDataURLWithMultiplier:function(e,t,n){this.clone(function(r){n(r.toDataURLWithMultiplier(e,t))})},clone:function(e,t){var n=JSON.stringify(this.toJSON(t));this.cloneWithoutData(function(t){t.loadFromJSON(n,function(){e&&e(t)})})},cloneWithoutData:function(e){var t=fabric.document.createElement("canvas");t.width=this.getWidth(),t.height=this.getHeight();var n=new fabric.Canvas(t);n.clipTo=this.clipTo,this.backgroundImage?(n.setBackgroundImage(this.backgroundImage.src,function(){n.renderAll(),e&&e(n)}),n.backgroundImageOpacity=this.backgroundImageOpacity,n.backgroundImageStretch=this.backgroundImageStretch):e&&e(n)}}),function(e){"use strict";var t=e.fabric||(e.fabric={}),n=t.util.object.extend,r=t.util.toFixed,i=t.util.string.capitalize,s=t.util.degreesToRadians,o=t.StaticCanvas.supports("setLineDash");if(t.Object)return;t.Object=t.util.createClass({type:"object",originX:"left",originY:"top",top:0,left:0,width:0,height:0,scaleX:1,scaleY:1,flipX:!1,flipY:!1,opacity:1,angle:0,cornerSize:12,transparentCorners:!0,hoverCursor:null,padding:0,borderColor:"rgba(102,153,255,0.75)",cornerColor:"rgba(102,153,255,0.5)",centeredScaling:!1,centeredRotation:!0,fill:"rgb(0,0,0)",fillRule:"source-over",backgroundColor:"",stroke:null,strokeWidth:1,strokeDashArray:null,strokeLineCap:"butt",strokeLineJoin:"miter",strokeMiterLimit:10,shadow:null,borderOpacityWhenMoving:.4,borderScaleFactor:1,transformMatrix:null,minScaleLimit:.01,selectable:!0,evented:!0,visible:!0,hasControls:!0,hasBorders:!0,hasRotatingPoint:!0,rotatingPointOffset:40,perPixelTargetFind:!1,includeDefaultValues:!0,clipTo:null,lockMovementX:!1,lockMovementY:!1,lockRotation:!1,lockScalingX:!1,lockScalingY:!1,lockUniScaling:!1,stateProperties:"top left width height scaleX scaleY flipX flipY originX originY transformMatrix stroke strokeWidth strokeDashArray strokeLineCap strokeLineJoin strokeMiterLimit angle opacity fill fillRule shadow clipTo visible backgroundColor".split(" "),initialize:function(e){e&&this.setOptions(e)},_initGradient:function(e){e.fill&&e.fill.colorStops&&!(e.fill instanceof t.Gradient)&&this.set("fill",new t.Gradient(e.fill))},_initPattern:function(e){e.fill&&e.fill.source&&!(e.fill instanceof t.Pattern)&&this.set("fill",new t.Pattern(e.fill)),e.stroke&&e.stroke.source&&!(e.stroke instanceof t.Pattern)&&this.set("stroke",new t.Pattern(e.stroke))},_initClipping:function(e){if(!e.clipTo||typeof e.clipTo!="string")return;var n=t.util.getFunctionBody(e.clipTo);typeof n!="undefined"&&(this.clipTo=new Function("ctx",n))},setOptions:function(e){for(var t in e)this.set(t,e[t]);this._initGradient(e),this._initPattern(e),this._initClipping -(e)},transform:function(e,t){e.globalAlpha=this.opacity;var n=t?this._getLeftTopCoords():this.getCenterPoint();e.translate(n.x,n.y),e.rotate(s(this.angle)),e.scale(this.scaleX*(this.flipX?-1:1),this.scaleY*(this.flipY?-1:1))},toObject:function(e){var n=t.Object.NUM_FRACTION_DIGITS,i={type:this.type,originX:this.originX,originY:this.originY,left:r(this.left,n),top:r(this.top,n),width:r(this.width,n),height:r(this.height,n),fill:this.fill&&this.fill.toObject?this.fill.toObject():this.fill,stroke:this.stroke&&this.stroke.toObject?this.stroke.toObject():this.stroke,strokeWidth:r(this.strokeWidth,n),strokeDashArray:this.strokeDashArray,strokeLineCap:this.strokeLineCap,strokeLineJoin:this.strokeLineJoin,strokeMiterLimit:r(this.strokeMiterLimit,n),scaleX:r(this.scaleX,n),scaleY:r(this.scaleY,n),angle:r(this.getAngle(),n),flipX:this.flipX,flipY:this.flipY,opacity:r(this.opacity,n),shadow:this.shadow&&this.shadow.toObject?this.shadow.toObject():this.shadow,visible:this.visible,clipTo:this.clipTo&&String(this.clipTo),backgroundColor:this.backgroundColor};return this.includeDefaultValues||(i=this._removeDefaultValues(i)),t.util.populateWithProperties(this,i,e),i},toDatalessObject:function(e){return this.toObject(e)},_removeDefaultValues:function(e){var n=t.util.getKlass(e.type).prototype,r=n.stateProperties;return r.forEach(function(t){e[t]===n[t]&&delete e[t]}),e},toString:function(){return"#"},get:function(e){return this[e]},_setObject:function(e){for(var t in e)this._set(t,e[t])},set:function(e,t){return typeof e=="object"?this._setObject(e):typeof t=="function"&&e!=="clipTo"?this._set(e,t(this.get(e))):this._set(e,t),this},_set:function(e,n){var i=e==="scaleX"||e==="scaleY";return i&&(n=this._constrainScale(n)),e==="scaleX"&&n<0?(this.flipX=!this.flipX,n*=-1):e==="scaleY"&&n<0?(this.flipY=!this.flipY,n*=-1):e==="width"||e==="height"?this.minScaleLimit=r(Math.min(.1,1/Math.max(this.width,this.height)),2):e==="shadow"&&n&&!(n instanceof t.Shadow)&&(n=new t.Shadow(n)),this[e]=n,this},toggle:function(e){var t=this.get(e);return typeof t=="boolean"&&this.set(e,!t),this},setSourcePath:function(e){return this.sourcePath=e,this},render:function(e,n){if(this.width===0||this.height===0||!this.visible)return;e.save(),this._setupFillRule(e),this._transform(e,n),this._setStrokeStyles(e),this._setFillStyles(e);var r=this.transformMatrix;r&&this.group&&(e.translate(-this.group.width/2,-this.group.height/2),e.transform(r[0],r[1],r[2],r[3],r[4],r[5])),this._setShadow(e),this.clipTo&&t.util.clipContext(this,e),this._render(e,n),this.clipTo&&e.restore(),this._removeShadow(e),this._restoreFillRule(e),this.active&&!n&&(this.drawBorders(e),this.drawControls(e)),e.restore()},_transform:function(e,t){var n=this.transformMatrix;n&&!this.group&&e.setTransform(n[0],n[1],n[2],n[3],n[4],n[5]),t||this.transform(e)},_setStrokeStyles:function(e){this.stroke&&(e.lineWidth=this.strokeWidth,e.lineCap=this.strokeLineCap,e.lineJoin=this.strokeLineJoin,e.miterLimit=this.strokeMiterLimit,e.strokeStyle=this.stroke.toLive?this.stroke.toLive(e):this.stroke)},_setFillStyles:function(e){this.fill&&(e.fillStyle=this.fill.toLive?this.fill.toLive(e):this.fill)},_setShadow:function(e){if(!this.shadow)return;e.shadowColor=this.shadow.color,e.shadowBlur=this.shadow.blur,e.shadowOffsetX=this.shadow.offsetX,e.shadowOffsetY=this.shadow.offsetY},_removeShadow:function(e){if(!this.shadow)return;e.shadowColor="",e.shadowBlur=e.shadowOffsetX=e.shadowOffsetY=0},_renderFill:function(e){if(!this.fill)return;this.fill.toLive&&(e.save(),e.translate(-this.width/2+this.fill.offsetX||0,-this.height/2+this.fill.offsetY||0)),this.fillRule==="destination-over"?e.fill("evenodd"):e.fill(),this.fill.toLive&&e.restore(),this.shadow&&!this.shadow.affectStroke&&this._removeShadow(e)},_renderStroke:function(e){if(!this.stroke)return;e.save(),this.strokeDashArray?(1&this.strokeDashArray.length&&this.strokeDashArray.push.apply(this.strokeDashArray,this.strokeDashArray),o?(e.setLineDash(this.strokeDashArray),this._stroke&&this._stroke(e)):this._renderDashedStroke&&this._renderDashedStroke(e),e.stroke()):this._stroke?this._stroke(e):e.stroke(),this._removeShadow(e),e.restore()},clone:function(e,n){return this.constructor.fromObject?this.constructor.fromObject(this.toObject(n),e):new t.Object(this.toObject(n))},cloneAsImage:function(e){var n=this.toDataURL();return t.util.loadImage(n,function(n){e&&e(new t.Image(n))}),this},toDataURL:function(e){e||(e={});var n=t.util.createCanvasElement(),r=this.getBoundingRect();n.width=r.width,n.height=r.height,t.util.wrapElement(n,"div");var i=new t.Canvas(n);e.format==="jpg"&&(e.format="jpeg"),e.format==="jpeg"&&(i.backgroundColor="#fff");var s={active:this.get("active"),left:this.getLeft(),top:this.getTop()};this.set("active",!1),this.setPositionByOrigin(new t.Point(n.width/2,n.height/2),"center","center");var o=this.canvas;i.add(this);var u=i.toDataURL(e);return this.set(s).setCoords(),this.canvas=o,i.dispose(),i=null,u},isType:function(e){return this.type===e},complexity:function(){return 0},toJSON:function(e){return this.toObject(e)},setGradient:function(e,n){n||(n={});var r={colorStops:[]};r.type=n.type||(n.r1||n.r2?"radial":"linear"),r.coords={x1:n.x1,y1:n.y1,x2:n.x2,y2:n.y2};if(n.r1||n.r2)r.coords.r1=n.r1,r.coords.r2=n.r2;for(var i in n.colorStops){var s=new t.Color(n.colorStops[i]);r.colorStops.push({offset:i,color:s.toRgb(),opacity:s.getAlpha()})}return this.set(e,t.Gradient.forObject(this,r))},setPatternFill:function(e){return this.set("fill",new t.Pattern(e))},setShadow:function(e){return this.set("shadow",new t.Shadow(e))},setColor:function(e){return this.set("fill",e),this},setAngle:function(e){var t=(this.originX!=="center"||this.originY!=="center")&&this.centeredRotation;return t&&this._setOriginToCenter(),this.set("angle",e),t&&this._resetOrigin(),this},centerH:function(){return this.canvas.centerObjectH(this),this},centerV:function(){return this.canvas.centerObjectV(this),this},center:function(){return this.canvas.centerObject(this),this},remove:function(){return this.canvas.remove(this),this},getLocalPointer:function(e,t){t=t||this.canvas.getPointer(e);var n=this.translateToOriginPoint(this.getCenterPoint(),"left","top");return{x:t.x-n.x,y:t.y-n.y}},_setupFillRule:function(e){this.fillRule&&(this._prevFillRule=e.globalCompositeOperation,e.globalCompositeOperation=this.fillRule)},_restoreFillRule:function(e){this.fillRule&&this._prevFillRule&&(e.globalCompositeOperation=this._prevFillRule)}}),t.util.createAccessors(t.Object),t.Object.prototype.rotate=t.Object.prototype.setAngle,n(t.Object.prototype,t.Observable),t.Object.NUM_FRACTION_DIGITS=2,t.Object.__uid=0}(typeof exports!="undefined"?exports:this),function(){var e=fabric.util.degreesToRadians;fabric.util.object.extend(fabric.Object.prototype,{translateToCenterPoint:function(t,n,r){var i=t.x,s=t.y,o=this.stroke?this.strokeWidth:0;return n==="left"?i=t.x+(this.getWidth()+o*this.scaleX)/2:n==="right"&&(i=t.x-(this.getWidth()+o*this.scaleX)/2),r==="top"?s=t.y+(this.getHeight()+o*this.scaleY)/2:r==="bottom"&&(s=t.y-(this.getHeight()+o*this.scaleY)/2),fabric.util.rotatePoint(new fabric.Point(i,s),t,e(this.angle))},translateToOriginPoint:function(t,n,r){var i=t.x,s=t.y,o=this.stroke?this.strokeWidth:0;return n==="left"?i=t.x-(this.getWidth()+o*this.scaleX)/2:n==="right"&&(i=t.x+(this.getWidth()+o*this.scaleX)/2),r==="top"?s=t.y-(this.getHeight()+o*this.scaleY)/2:r==="bottom"&&(s=t.y+(this.getHeight()+o*this.scaleY)/2),fabric.util.rotatePoint(new fabric.Point(i,s),t,e(this.angle))},getCenterPoint:function(){var e=new fabric.Point(this.left,this.top);return this.translateToCenterPoint(e,this.originX,this.originY)},getPointByOrigin:function(e,t){var n=this.getCenterPoint();return this.translateToOriginPoint(n,e,t)},toLocalPoint:function(t,n,r){var i=this.getCenterPoint(),s=this.stroke?this.strokeWidth:0,o,u;return n&&r?(n==="left"?o=i.x-(this.getWidth()+s*this.scaleX)/2:n==="right"?o=i.x+(this.getWidth()+s*this.scaleX)/2:o=i.x,r==="top"?u=i.y-(this.getHeight()+s*this.scaleY)/2:r==="bottom"?u=i.y+(this.getHeight()+s*this.scaleY)/2:u=i.y):(o=this.left,u=this.top),fabric.util.rotatePoint(new fabric.Point(t.x,t.y),i,-e(this.angle)).subtractEquals(new fabric.Point(o,u))},setPositionByOrigin:function(e,t,n){var r=this.translateToCenterPoint(e,t,n),i=this.translateToOriginPoint(r,this.originX,this.originY);this.set("left",i.x),this.set("top",i.y)},adjustPosition:function(t){var n=e(this.angle),r=this.getWidth()/2,i=Math.cos(n)*r,s=Math.sin(n)*r,o=this.getWidth(),u=Math.cos(n)*o,a=Math.sin(n)*o;this.originX==="center"&&t==="left"||this.originX==="right"&&t==="center"?(this.left-=i,this.top-=s):this.originX==="left"&&t==="center"||this.originX==="center"&&t==="right"?(this.left+=i,this.top+=s):this.originX==="left"&&t==="right"?(this.left+=u,this.top+=a):this.originX==="right"&&t==="left"&&(this.left-=u,this.top-=a),this.setCoords(),this.originX=t},_setOriginToCenter:function(){this._originalOriginX=this.originX,this._originalOriginY=this.originY;var e=this.getCenterPoint();this.originX="center",this.originY="center",this.left=e.x,this.top=e.y},_resetOrigin:function(){var e=this.translateToOriginPoint(this.getCenterPoint(),this._originalOriginX,this._originalOriginY);this.originX=this._originalOriginX,this.originY=this._originalOriginY,this.left=e.x,this.top=e.y,this._originalOriginX=null,this._originalOriginY=null},_getLeftTopCoords:function(){return this.translateToOriginPoint(this.getCenterPoint(),"left","center")}})}(),function(){var e=fabric.util.degreesToRadians;fabric.util.object.extend(fabric.Object.prototype,{oCoords:null,intersectsWithRect:function(e,t){var n=this.oCoords,r=new fabric.Point(n.tl.x,n.tl.y),i=new fabric.Point(n.tr.x,n.tr.y),s=new fabric.Point(n.bl.x,n.bl.y),o=new fabric.Point(n.br.x,n.br.y),u=fabric.Intersection.intersectPolygonRectangle([r,i,o,s],e,t);return u.status==="Intersection"},intersectsWithObject:function(e){function t(e){return{tl:new fabric.Point(e.tl.x,e.tl.y),tr:new fabric.Point(e.tr.x,e.tr.y),bl:new fabric.Point(e.bl.x,e.bl.y),br:new fabric.Point(e.br.x,e.br.y)}}var n=t(this.oCoords),r=t(e.oCoords),i=fabric.Intersection.intersectPolygonPolygon([n.tl,n.tr,n.br,n.bl],[r.tl,r.tr,r.br,r.bl]);return i.status==="Intersection"},isContainedWithinObject:function(e){var t=e.getBoundingRect(),n=new fabric.Point(t.left,t.top),r=new fabric.Point(t.left+t.width,t.top+t.height);return this.isContainedWithinRect(n,r)},isContainedWithinRect:function(e,t){var n=this.getBoundingRect();return n.left>=e.x&&n.left+n.width<=t.x&&n.top>=e.y&&n.top+n.height<=t.y},containsPoint:function(e){var t=this._getImageLines(this.oCoords),n=this._findCrossPoints(e,t);return n!==0&&n%2===1},_getImageLines:function(e){return{topline:{o:e.tl,d:e.tr},rightline:{o:e.tr,d:e.br},bottomline:{o:e.br,d:e.bl},leftline:{o:e.bl,d:e.tl}}},_findCrossPoints:function(e,t){var n,r,i,s,o,u,a=0,f;for(var l in t){f=t[l];if(f.o.y=e.y&&f.d.y>=e.y)continue;f.o.x===f.d.x&&f.o.x>=e.x?(o=f.o.x,u=e.y):(n=0,r=(f.d.y-f.o.y)/(f.d.x-f.o.x),i=e.y-n*e.x,s=f.o.y-r*f.o.x,o=-(i-s)/(n-r),u=i+n*o),o>=e.x&&(a+=1);if(a===2)break}return a},getBoundingRectWidth:function(){return this.getBoundingRect().width},getBoundingRectHeight:function(){return this.getBoundingRect().height},getBoundingRect:function(){this.oCoords||this.setCoords();var e=[this.oCoords.tl.x,this.oCoords.tr.x,this.oCoords.br.x,this.oCoords.bl.x],t=fabric.util.array.min(e),n=fabric.util.array.max(e),r=Math.abs(t-n),i=[this.oCoords.tl.y,this.oCoords.tr.y,this.oCoords.br.y,this.oCoords.bl.y],s=fabric.util.array.min(i),o=fabric.util.array.max(i),u=Math.abs(s-o);return{left:t,top:s,width:r,height:u}},getWidth:function(){return this.width*this.scaleX},getHeight:function(){return this.height*this.scaleY},_constrainScale:function(e){return Math.abs(e)1?this.strokeWidth:0,n=this.padding,r=e(this.angle);this.currentWidth=(this.width+t)*this.scaleX+n*2,this.currentHeight=(this.height+t)*this.scaleY+n*2,this.currentWidth<0&&(this.currentWidth=Math.abs(this.currentWidth));var i=Math.sqrt(Math.pow(this.currentWidth/2,2)+Math.pow(this.currentHeight/2,2)),s=Math.atan(isFinite(this.currentHeight/this.currentWidth)?this.currentHeight/this.currentWidth:0),o=Math.cos(s+r)*i,u=Math.sin(s+r)*i,a=Math.sin(r),f=Math.cos(r),l=this.getCenterPoint(),c={x:l.x-o,y:l.y-u},h={x:c.x+this.currentWidth*f,y:c.y+this.currentWidth*a},p={x:h.x-this.currentHeight*a,y:h.y+this.currentHeight*f},d={x:c.x-this.currentHeight*a,y:c.y+this.currentHeight*f},v={x:c.x-this.currentHeight/2*a,y:c.y+this.currentHeight/2*f},m={x:c.x+this.currentWidth/2*f,y:c.y+this.currentWidth/2*a},g={x:h.x-this.currentHeight/2*a,y:h.y+this.currentHeight/2*f},y={x:d.x+this.currentWidth/2*f,y:d.y+this.currentWidth/2*a},b={x:m.x,y:m.y};return this.oCoords={tl:c,tr:h,br:p,bl:d,ml:v,mt:m,mr:g,mb:y,mtr:b},this._setCornerCoords&&this._setCornerCoords(),this}})}(),fabric.util.object.extend(fabric.Object.prototype,{sendToBack:function(){return this.group?fabric.StaticCanvas.prototype.sendToBack.call(this.group,this):this.canvas.sendToBack(this),this},bringToFront:function(){return this.group?fabric.StaticCanvas.prototype.bringToFront.call(this.group,this):this.canvas.bringToFront(this),this},sendBackwards:function(e){return this.group?fabric.StaticCanvas.prototype.sendBackwards.call(this.group,this,e):this.canvas.sendBackwards(this,e),this},bringForward:function(e){return this.group?fabric.StaticCanvas.prototype.bringForward.call(this.group,this,e):this.canvas.bringForward(this,e),this},moveTo:function(e){return this.group?fabric.StaticCanvas.prototype.moveTo.call(this.group,this,e):this.canvas.moveTo(this,e),this}}),fabric.util.object.extend(fabric.Object.prototype,{getSvgStyles:function(){var e=this.fill?this.fill.toLive?"url(#SVGID_"+this.fill.id+")":this.fill:"none",t=this.stroke?this.stroke.toLive?"url(#SVGID_"+this.stroke.id+")":this.stroke:"none",n=this.strokeWidth?this.strokeWidth:"0",r=this.strokeDashArray?this.strokeDashArray.join(" "):"",i=this.strokeLineCap?this.strokeLineCap:"butt",s=this.strokeLineJoin?this.strokeLineJoin:"miter",o=this.strokeMiterLimit?this.strokeMiterLimit:"4",u=typeof this.opacity!="undefined"?this.opacity:"1",a=this.visible?"":" visibility: hidden;",f=this.shadow&&this.type!=="text"?"filter: url(#SVGID_"+this.shadow.id+");":"";return["stroke: ",t,"; ","stroke-width: ",n,"; ","stroke-dasharray: ",r,"; ","stroke-linecap: ",i,"; ","stroke-linejoin: ",s,"; ","stroke-miterlimit: ",o,"; ","fill: ",e,"; ","opacity: ",u,";",f,a].join("")},getSvgTransform:function(){var e=fabric.util.toFixed,t=this.getAngle(),n=this.getCenterPoint(),r=fabric.Object.NUM_FRACTION_DIGITS,i="translate("+e(n.x,r)+" "+e(n.y,r)+")",s=t!==0?" rotate("+e(t,r)+")":"",o=this.scaleX===1&&this.scaleY===1?"":" scale("+e(this.scaleX,r)+" "+e(this.scaleY,r)+")",u=this.flipX?"matrix(-1 0 0 1 0 0) ":"",a=this.flipY?"matrix(1 0 0 -1 0 0)":"";return[i,s,o,u,a].join("")},_createBaseSVGMarkup:function(){var e=[];return this.fill&&this.fill.toLive&&e.push(this.fill.toSVG(this,!1)),this.stroke&&this.stroke.toLive&&e.push(this.stroke.toSVG(this,!1)),this.shadow&&e.push(this.shadow.toSVG(this)),e}}),fabric.util.object.extend(fabric.Object.prototype,{hasStateChanged:function(){return this.stateProperties.some(function(e){return this.get(e)!==this.originalState[e]},this)},saveState:function(e){return this.stateProperties.forEach(function(e){this.originalState[e]=this.get(e)},this),e&&e.stateProperties&&e.stateProperties.forEach(function(e){this.originalState[e]=this.get(e)},this),this},setupState:function(){return this.originalState={},this.saveState(),this}}),function(){var e=fabric.util.degreesToRadians,t=typeof G_vmlCanvasManager!="undefined";fabric.util.object.extend(fabric.Object.prototype,{_controlsVisibility:null,_findTargetCorner:function(e){if(!this.hasControls||!this.active)return!1;var t=e.x,n=e.y,r,i;for(var s in this.oCoords){if(!this.isControlVisible(s))continue;if(s==="mtr"&&!this.hasRotatingPoint)continue;if(!(!this.get("lockUniScaling")||s!=="mt"&&s!=="mr"&&s!=="mb"&&s!=="ml"))continue;i=this._getImageLines(this.oCoords[s].corner),r=this._findCrossPoints({x:t,y:n},i);if(r!==0&&r%2===1)return this.__corner=s,s}return!1},_setCornerCoords:function(){var t=this.oCoords,n=e(this.angle),r=e(45-this.angle),i=Math.sqrt(2*Math.pow(this.cornerSize,2))/2,s=i*Math.cos(r),o=i*Math.sin(r),u=Math.sin(n),a=Math.cos(n);t.tl.corner={tl:{x:t.tl.x-o,y:t.tl.y-s},tr:{x:t.tl.x+s,y:t.tl.y-o},bl:{x:t.tl.x-s,y:t.tl.y+o},br:{x:t.tl.x+o,y:t.tl.y+s}},t.tr.corner={tl:{x:t.tr.x-o,y:t.tr.y-s},tr:{x:t.tr.x+s,y:t.tr.y-o},br:{x:t.tr.x+o,y:t.tr.y+s},bl:{x:t.tr.x-s,y:t.tr.y+o}},t.bl.corner={tl:{x:t.bl.x-o,y:t.bl.y-s},bl:{x:t.bl.x-s,y:t.bl.y+o},br:{x:t.bl.x+o,y:t.bl.y+s},tr:{x:t.bl.x+s,y:t.bl.y-o}},t.br.corner={tr:{x:t.br.x+s,y:t.br.y-o},bl:{x:t.br.x-s,y:t.br.y+o},br:{x:t.br.x+o,y:t.br.y+s},tl:{x:t.br.x-o,y:t.br.y-s}},t.ml.corner={tl:{x:t.ml.x-o,y:t.ml.y-s},tr:{x:t.ml.x+s,y:t.ml.y-o},bl:{x:t.ml.x-s,y:t.ml.y+o},br:{x:t.ml.x+o,y:t.ml.y+s}},t.mt.corner={tl:{x:t.mt.x-o,y:t.mt.y-s},tr:{x:t.mt.x+s,y:t.mt.y-o},bl:{x:t.mt.x-s,y:t.mt.y+o},br:{x:t.mt.x+o,y:t.mt.y+s}},t.mr.corner={tl:{x:t.mr.x-o,y:t.mr.y-s},tr:{x:t.mr.x+s,y:t.mr.y-o},bl:{x:t.mr.x-s,y:t.mr.y+o},br:{x:t.mr.x+o,y:t.mr.y+s}},t.mb.corner={tl:{x:t.mb.x-o,y:t.mb.y-s},tr:{x:t.mb.x+s,y:t.mb.y-o},bl:{x:t.mb.x-s,y:t.mb.y+o},br:{x:t.mb.x+o,y:t.mb.y+s}},t.mtr.corner={tl:{x:t.mtr.x-o+u*this.rotatingPointOffset,y:t.mtr.y-s-a*this.rotatingPointOffset},tr:{x:t.mtr.x+s+u*this.rotatingPointOffset,y:t.mtr.y-o-a*this.rotatingPointOffset},bl:{x:t.mtr.x-s+u*this.rotatingPointOffset,y:t.mtr.y+o-a*this.rotatingPointOffset},br:{x:t.mtr.x+o+u*this.rotatingPointOffset,y:t.mtr.y+s-a*this.rotatingPointOffset}}},drawBorders:function(e){if(!this.hasBorders)return this;var t=this.padding,n=t*2,r=~~(this.strokeWidth/2)*2;e.save(),e.globalAlpha=this.isMoving?this.borderOpacityWhenMoving:1,e.strokeStyle=this.borderColor;var i=1/this._constrainScale(this.scaleX),s=1/this._constrainScale(this.scaleY);e.lineWidth=1/this.borderScaleFactor,e.scale(i,s);var o=this.getWidth(),u=this.getHeight();e.strokeRect(~~(-(o/2)-t-r/2*this.scaleX)-.5,~~(-(u/2)-t-r/2*this.scaleY)-.5,~~(o+n+r*this.scaleX)+1,~~(u+n+r*this.scaleY)+1);if(this.hasRotatingPoint&&this.isControlVisible("mtr")&&!this.get("lockRotation")&&this.hasControls){var a=(this.flipY?u+r*this.scaleY+t*2:-u-r*this.scaleY-t*2)/2;e.beginPath(),e.moveTo(0,a),e.lineTo(0,a+(this.flipY?this.rotatingPointOffset:-this.rotatingPointOffset)),e.closePath(),e.stroke()}return e.restore(),this},drawControls:function(e){if(!this.hasControls)return this;var t=this.cornerSize,n=t/2,r=~~(this.strokeWidth/2),i=-(this.width/2),s=-(this.height/2),o=this.padding/this.scaleX,u=this.padding/this.scaleY,a=n/this.scaleY,f=n/this.scaleX,l=(n-t)/this.scaleX,c=(n-t)/this.scaleY,h=this.height,p=this.width,d=this.transparentCorners?"strokeRect":"fillRect";return e.save(),e.lineWidth=1/Math.max(this.scaleX,this.scaleY),e.globalAlpha=this.isMoving?this.borderOpacityWhenMoving:1,e.strokeStyle=e.fillStyle=this.cornerColor,this._drawControl("tl",e,d,i-f-r-o,s-a-r-u),this._drawControl("tr",e,d,i+p-f+r+o,s-a-r-u),this._drawControl("bl",e,d,i-f-r-o,s+h+c+r+u),this._drawControl("br",e,d,i+p+l+r+o,s+h+c+r+u),this.get("lockUniScaling")||(this._drawControl("mt",e,d,i+p/2-f,s-a-r-u),this._drawControl("mb",e,d,i+p/2-f,s+h+c+r+u),this._drawControl("mr",e,d,i+p+l+r+o,s+h/2-a),this._drawControl("ml",e,d,i-f-r-o,s+h/2-a)),this.hasRotatingPoint&&this._drawControl("mtr",e,d,i+p/2-f,this.flipY?s+h+this.rotatingPointOffset/this.scaleY-this.cornerSize/this.scaleX/2+r+u:s-this.rotatingPointOffset/this.scaleY-this.cornerSize/this.scaleY/2-r-u),e.restore(),this},_drawControl:function(e,n,r,i,s){var o=this.cornerSize/this.scaleX,u=this.cornerSize/this.scaleY;this.isControlVisible(e)&&(t||this.transparentCorners||n.clearRect(i,s,o,u),n[r](i,s,o,u))},isControlVisible:function(e){return this._getControlsVisibility()[e]},setControlVisible:function(e,t){return this._getControlsVisibility()[e]=t,this},setControlsVisibility:function(e){e||(e={});for(var t in e)this.setControlVisible(t,e[t]);return this},_getControlsVisibility:function(){return this._controlsVisibility||(this._controlsVisibility={tl:!0,tr:!0,br:!0,bl:!0,ml:!0,mt:!0,mr:!0,mb:!0,mtr:!0}),this._controlsVisibility}})}(),fabric.util.object.extend(fabric.StaticCanvas.prototype,{FX_DURATION:500,fxCenterObjectH:function(e,t){t=t||{};var n=function(){},r=t.onComplete||n,i=t.onChange||n,s=this;return fabric.util.animate({startValue:e.get("left"),endValue:this.getCenter().left,duration:this.FX_DURATION,onChange:function(t){e.set("left",t),s.renderAll(),i()},onComplete:function(){e.setCoords(),r()}}),this},fxCenterObjectV:function(e,t){t=t||{};var n=function(){},r=t.onComplete||n,i=t.onChange||n,s=this;return fabric.util.animate({startValue:e.get("top"),endValue:this.getCenter().top,duration:this.FX_DURATION,onChange:function(t){e.set("top",t),s.renderAll(),i()},onComplete:function(){e.setCoords(),r()}}),this},fxRemove:function(e,t){t=t||{};var n=function(){},r=t.onComplete||n,i=t.onChange||n,s=this;return fabric.util.animate({startValue:e.get("opacity"),endValue:0,duration:this.FX_DURATION,onStart:function(){e.set("active",!1)},onChange:function(t){e.set("opacity",t),s.renderAll(),i()},onComplete:function(){s.remove(e),r()}}),this}}),fabric.util.object.extend(fabric.Object.prototype,{animate:function(){if(arguments[0]&&typeof arguments[0]=="object"){var e=[],t,n;for(t in arguments[0])e.push(t);for(var r=0,i=e.length;r'),e?e(t.join("")):t.join("")},complexity:function(){return 1}}),t.Line.ATTRIBUTE_NAMES=t.SHARED_ATTRIBUTES.concat("x1 y1 x2 y2".split(" ")),t.Line.fromElement=function(e,r){var i=t.parseAttributes(e,t.Line.ATTRIBUTE_NAMES),s=[i.x1||0,i.y1||0,i.x2||0,i.y2||0];return new t.Line(s,n(i,r))},t.Line.fromObject=function(e){var n=[e.x1,e.y1,e.x2,e.y2];return new t.Line(n,e)}}(typeof exports!="undefined"?exports:this),function(e){"use strict";function i(e){return"radius"in e&&e.radius>0}var t=e.fabric||(e.fabric={}),n=Math.PI*2,r=t.util.object.extend;if(t.Circle){t.warn("fabric.Circle is already defined.");return}t.Circle=t.util.createClass(t.Object,{type:"circle",radius:0,initialize:function(e){e=e||{},this.set("radius",e.radius||0),this.callSuper("initialize",e)},_set:function(e,t){return this.callSuper("_set",e,t),e==="radius"&&this.setRadius(t),this},toObject:function(e){return r(this.callSuper("toObject",e),{radius:this.get("radius")})},toSVG:function(e){var t=this._createBaseSVGMarkup();return t.push("'),e?e(t.join("")):t.join("")},_render:function(e,t){e.beginPath(),e.globalAlpha=this.group?e.globalAlpha*this.opacity:this.opacity,e.arc(t?this.left:0,t?this.top:0,this.radius,0,n,!1),this._renderFill(e),this.stroke&&this._renderStroke(e)},getRadiusX:function(){return this.get("radius")*this.get("scaleX")},getRadiusY:function(){return this.get("radius")*this.get("scaleY")},setRadius:function(e){this.radius=e,this.set("width",e*2).set("height",e*2)},complexity:function(){return 1}}),t.Circle.ATTRIBUTE_NAMES=t.SHARED_ATTRIBUTES.concat("cx cy r".split(" ")),t.Circle.fromElement=function(e,n){n||(n={});var s=t.parseAttributes(e,t.Circle.ATTRIBUTE_NAMES);if(!i(s))throw new Error("value of `r` attribute is required and can not be negative");"left"in s||(s.left=0),"top"in s||(s.top=0),"transformMatrix"in s||(s.left-=n.width/2,s.top-=n.height/2);var o=new t.Circle(r(s,n));return o.cx=parseFloat(e.getAttribute("cx"))||0,o.cy=parseFloat(e.getAttribute("cy"))||0,o},t.Circle.fromObject=function(e){return new t.Circle(e)}}(typeof exports!="undefined"?exports:this),function(e){"use strict";var t=e.fabric||(e.fabric={});if(t.Triangle){t.warn("fabric.Triangle is already defined");return}t.Triangle=t.util.createClass(t.Object,{type:"triangle",initialize:function(e){e=e||{},this.callSuper("initialize",e),this.set("width",e.width||100).set("height",e.height||100)},_render:function(e){var t=this.width/2,n=this.height/2;e.beginPath(),e.moveTo(-t,n),e.lineTo(0,-n),e.lineTo(t,n),e.closePath(),this._renderFill(e),this._renderStroke(e)},_renderDashedStroke:function(e){var n=this.width/2,r=this.height/2;e.beginPath(),t.util.drawDashedLine(e,-n,r,0,-r,this.strokeDashArray),t.util.drawDashedLine(e,0,-r,n,r,this.strokeDashArray),t.util.drawDashedLine(e,n,r,-n,r,this.strokeDashArray),e.closePath()},toSVG:function(e){var t=this._createBaseSVGMarkup(),n=this.width/2,r=this.height/2,i=[-n+" "+r,"0 "+ -r,n+" "+r].join(",");return t.push("'),e?e(t.join("")):t.join("")},complexity:function(){return 1}}),t.Triangle.fromObject=function(e){return new t.Triangle(e)}}(typeof exports!="undefined"?exports:this),function(e){"use strict";var t=e.fabric||(e.fabric={}),n=Math.PI*2,r=t.util.object.extend;if(t.Ellipse){t.warn("fabric.Ellipse is already defined.");return}t.Ellipse=t.util.createClass(t.Object,{type:"ellipse",rx:0,ry:0,initialize:function(e){e=e||{},this.callSuper("initialize",e),this.set("rx",e.rx||0),this.set("ry",e.ry||0),this.set("width",this.get("rx")*2),this.set("height",this.get("ry")*2)},toObject:function(e){return r(this.callSuper("toObject",e),{rx:this.get("rx"),ry:this.get("ry")})},toSVG:function(e){var t=this._createBaseSVGMarkup();return t.push("'),e?e(t.join("")):t.join("")},render:function(e,t){if(this.rx===0||this.ry===0)return;return this.callSuper("render",e,t)},_render:function(e,t){e.beginPath(),e.save(),e.globalAlpha=this.group?e.globalAlpha*this.opacity:this.opacity,e.transform(1,0,0,this.ry/this.rx,0,0),e.arc(t?this.left:0,t?this.top*this.rx/this.ry:0,this.rx,0,n,!1),this._renderFill(e),this._renderStroke(e),e.restore()},complexity:function(){return 1}}),t.Ellipse.ATTRIBUTE_NAMES=t.SHARED_ATTRIBUTES.concat("cx cy rx ry".split(" ")),t.Ellipse.fromElement=function(e,n){n||(n={});var i=t.parseAttributes(e,t.Ellipse.ATTRIBUTE_NAMES);"left"in i||(i.left=0),"top"in i||(i.top=0),"transformMatrix"in i||(i.left-=n.width/2,i.top-=n.height/2);var s=new t.Ellipse(r(i,n));return s.cx=parseFloat(e.getAttribute("cx"))||0,s.cy=parseFloat(e.getAttribute("cy"))||0,s},t.Ellipse.fromObject=function(e){return new t.Ellipse(e)}}(typeof exports!="undefined"?exports:this),function(e){"use strict";function i(e){return e.left=e.left||0,e.top=e.top||0,e}var t=e.fabric||(e.fabric={}),n=t.util.object.extend;if(t.Rect){console.warn("fabric.Rect is already defined");return}var r=t.Object.prototype.stateProperties.concat();r.push("rx","ry","x","y"),t.Rect=t.util.createClass(t.Object,{stateProperties:r,type:"rect",rx:0,ry:0,x:0,y:0,strokeDashArray:null,initialize:function(e){e=e||{},this.callSuper("initialize",e),this._initRxRy(),this.x=e.x||0,this.y=e.y||0},_initRxRy:function(){this.rx&&!this.ry?this.ry=this.rx:this.ry&&!this.rx&&(this.rx=this.ry)},_render:function(e){if(this.width===1&&this.height===1){e.fillRect(0,0,1,1);return}var t=this.rx?Math.min(this.rx,this.width/2):0,n=this.ry?Math.min(this.ry,this.height/2):0,r=this.width,i=this.height,s=-r/2,o=-i/2,u=this.group&&this.group.type==="path-group",a=t!==0||n!==0,f=.4477152502;e.beginPath(),e.globalAlpha=u?e.globalAlpha*this.opacity:this.opacity,this.transformMatrix&&u&&e.translate(this.width/2+this.x,this.height/2+this.y),!this.transformMatrix&&u&&e.translate(-this.group.width/2+this.width/2+this.x,-this.group.height/2+this.height/2+this.y),e.moveTo(s+t,o),e.lineTo(s+r-t,o),a&&e.bezierCurveTo(s+r-f*t,o,s+r,o+f*n,s+r,o+n),e.lineTo(s+r,o+i-n),a&&e.bezierCurveTo(s+r,o+i-f*n,s+r-f*t,o+i,s+r-t,o+i),e.lineTo(s+t,o+i),a&&e.bezierCurveTo(s+f*t,o+i,s,o+i-f*n,s,o+i-n),e.lineTo(s,o+n),a&&e.bezierCurveTo(s,o+f*n,s+f*t,o,s+t,o),e.closePath(),this._renderFill(e),this._renderStroke(e)},_renderDashedStroke:function(e){var n=-this.width/2,r=-this.height/2,i=this.width,s=this.height;e.beginPath(),t.util.drawDashedLine(e,n,r,n+i,r,this.strokeDashArray),t.util.drawDashedLine(e,n+i,r,n+i,r+s,this.strokeDashArray),t.util.drawDashedLine(e,n+i,r+s,n,r+s,this.strokeDashArray),t.util.drawDashedLine(e,n,r+s,n,r,this.strokeDashArray),e.closePath()},_normalizeLeftTopProperties:function(e){return"left"in e&&this.set("left",e.left+this.getWidth()/2),this.set("x",e.left||0),"top"in e&&this.set("top",e.top+this.getHeight()/2),this.set("y",e.top||0),this},toObject:function(e){var t=n(this.callSuper("toObject",e),{rx:this.get("rx")||0,ry:this.get("ry")||0,x:this.get("x"),y:this.get("y")});return this.includeDefaultValues||this._removeDefaultValues(t),t},toSVG:function(e){var t=this._createBaseSVGMarkup();return t.push("'),e?e(t.join("")):t.join("")},complexity:function(){return 1}}),t.Rect.ATTRIBUTE_NAMES=t.SHARED_ATTRIBUTES.concat("x y rx ry width height".split(" ")),t.Rect.fromElement=function(e,r){if(!e)return null;var s=t.parseAttributes(e,t.Rect.ATTRIBUTE_NAMES);s=i(s);var o=new t.Rect(n(r?t.util.object.clone(r):{},s));return o._normalizeLeftTopProperties(s),o},t.Rect.fromObject=function(e){return new t.Rect(e)}}(typeof exports!="undefined"?exports:this),function(e){"use strict";var t=e.fabric||(e.fabric={}),n=t.util.toFixed;if(t.Polyline){t.warn("fabric.Polyline is already defined");return}t.Polyline=t.util.createClass(t.Object,{type:"polyline",points:null,initialize:function(e,t,n){t=t||{},this.set("points",e),this.callSuper("initialize",t),this._calcDimensions(n)},_calcDimensions:function(e){return t.Polygon.prototype._calcDimensions.call(this,e)},toObject:function(e){return t.Polygon.prototype.toObject.call(this,e)},toSVG:function(e){var t=[],r=this._createBaseSVGMarkup();for(var i=0,s=this.points.length;i'),e?e(r.join("")):r.join("")},_render:function(e){var t;e.beginPath(),e.moveTo(this.points[0].x,this.points[0].y);for(var n=0,r=this.points.length;n'),e?e(n.join("")):n.join("")},_render:function(e){var t;e.beginPath(),e.globalAlpha=this.group?e.globalAlpha*this.opacity:this.opacity,e.moveTo(this.points[0].x,this.points[0].y);for(var n=0,r=this.points.length;n"},toObject:function(e){var t=i(this.callSuper("toObject",e),{path:this.path.map(function(e){return e.slice()}),pathOffset:this.pathOffset});return this.sourcePath&&(t.sourcePath=this.sourcePath),this.transformMatrix&&(t.transformMatrix=this.transformMatrix),t},toDatalessObject:function(e){var t=this.toObject(e);return this.sourcePath&&(t.path=this.sourcePath),delete t.sourcePath,t},toSVG:function(e){var t=[],n=this._createBaseSVGMarkup();for(var r=0,i=this.path.length;r',"",""),e?e(n.join("")):n.join("")},complexity:function(){return this.path.length},_parsePath:function(){var e=[],t=[],n,r,i=/([-+]?((\d+\.\d+)|((\d+)|(\.\d+)))(?:e[-+]?\d+)?)/ig,s,o;for(var f=0,l,c=this.path.length;fv)for(var g=1,y=l.length;g"];for(var r=0,i=t.length;r"),e?e(n.join("")):n.join("")},toString:function(){return"#"},isSameColor:function(){var e=(this.getObjects()[0].get("fill")||"").toLowerCase();return this.getObjects().every(function(t){return(t.get("fill")||"").toLowerCase()===e})},complexity:function(){return this.paths.reduce(function(e,t){return e+(t&&t.complexity?t.complexity():0)},0)},getObjects:function(){return this.paths}}),t.PathGroup.fromObject=function(e,n){typeof e.paths=="string"?t.loadSVGFromURL(e.paths,function(r){var i=e.paths;delete e.paths;var s=t.util.groupSVGElements(r,e,i);n(s)}):t.util.enlivenObjects(e.paths,function(r){delete e.paths,n(new t.PathGroup(r,e))})},t.PathGroup.async=!0}(typeof exports!="undefined"?exports:this),function(e){"use strict";var t=e.fabric||(e.fabric={}),n=t.util.object.extend,r=t.util.array.min,i=t.util.array.max,s=t.util.array.invoke;if(t.Group)return;var o={lockMovementX:!0,lockMovementY:!0,lockRotation:!0,lockScalingX:!0,lockScalingY:!0,lockUniScaling:!0};t.Group=t.util.createClass(t.Object,t.Collection,{type:"group",initialize:function(e,t){t=t||{},this._objects=e||[];for(var r=this._objects.length;r--;)this._objects[r].group=this;this.originalState={},this.callSuper("initialize"),this._calcBounds(),this._updateObjectsCoords(),t&&n(this,t),this._setOpacityIfSame(),this.setCoords(!0),this.saveCoords()},_updateObjectsCoords:function(){this.forEachObject(this._updateObjectCoords,this)},_updateObjectCoords:function(e){var t=e.getLeft(),n=e.getTop();e.set({originalLeft:t,originalTop:n,left:t-this.left,top:n-this.top}),e.setCoords(),e.__origHasControls=e.hasControls,e.hasControls=!1},toString:function(){return"#"},addWithUpdate:function(e){return this._restoreObjectsState(),this._objects.push(e),e.group=this,this.forEachObject(this._setObjectActive,this),this._calcBounds(),this._updateObjectsCoords(),this},_setObjectActive:function(e){e.set("active",!0),e.group=this},removeWithUpdate:function(e){return this._moveFlippedObject(e),this._restoreObjectsState(),this.forEachObject(this._setObjectActive,this),this.remove(e),this._calcBounds(),this._updateObjectsCoords(),this},_onObjectAdded:function(e){e.group=this},_onObjectRemoved:function(e){delete e.group,e.set("active",!1)},delegatedProperties:{fill:!0,opacity:!0,fontFamily:!0,fontWeight:!0,fontSize:!0,fontStyle:!0,lineHeight:!0,textDecoration:!0,textAlign:!0,backgroundColor:!0},_set:function(e,t){if(e in this.delegatedProperties){var n=this._objects.length;this[e]=t;while(n--)this._objects[n].set(e,t)}else this[e]=t},toObject:function(e){return n(this.callSuper("toObject",e),{objects:s(this._objects,"toObject",e)})},render:function(e,n){if(!this.visible)return;e.save(),this.transform(e),this.clipTo&&t.util.clipContext(this,e);for(var r=0,i=this._objects.length;r'];for(var n=0,r=this._objects.length;n"),e?e(t.join("")):t.join("")},get:function(e){if(e in o){if(this[e])return this[e];for(var t=0,n=this._objects.length;t','");if(this.stroke||this.strokeDashArray){var n=this.fill;this.fill=null,t.push("'),this.fill=n}return t.push(""),e?e(t.join("")):t.join("")},getSrc:function(){if(this.getElement())return this.getElement().src||this.getElement()._src},toString:function(){return'#'},clone:function(e,t){this.constructor.fromObject(this.toObject(t),e)},applyFilters:function(e){if(!this._originalElement)return;if(this.filters.length===0){this._element=this._originalElement,e&&e();return}var t=this._originalElement,n=fabric.util.createCanvasElement(),r=fabric.util.createImage(),i=this;return n.width=t.width,n.height=t.height,n.getContext("2d").drawImage(t,0,0,t.width,t.height),this.filters.forEach(function(e){e&&e.applyTo(n)}),r.width=t.width,r.height=t.height,fabric.isLikelyNode?(r.src=n.toBuffer(undefined,fabric.Image.pngCompression),i._element=r,e&&e()):(r.onload=function(){i._element=r,e&&e(),r.onload=n=t=null},r.src=n.toDataURL("image/png")),this},_render:function(e){this._element&&e.drawImage(this._element,-this.width/2,-this.height/2,this.width,this.height)},_resetWidthHeight:function(){var e=this.getElement();this.set("width",e.width),this.set("height",e.height)},_initElement:function(e){this.setElement(fabric.util.getById(e)),fabric.util.addClass(this.getElement(),fabric.Image.CSS_CANVAS)},_initConfig:function(e){e||(e={}),this.setOptions(e),this._setWidthHeight(e),this._element&&this.crossOrigin&&(this._element.crossOrigin=this.crossOrigin)},_initFilters:function(e,t){e.filters&&e.filters.length?fabric.util.enlivenObjects(e.filters,function(e){t&&t(e)},"fabric.Image.filters"):t&&t()},_setWidthHeight:function(e){this.width="width"in e?e.width:this.getElement()?this.getElement().width||0:0,this.height="height"in e?e.height:this.getElement()?this.getElement().height||0:0},complexity:function(){return 1}}),fabric.Image.CSS_CANVAS="canvas-img",fabric.Image.prototype.getSvgSrc=fabric.Image.prototype.getSrc,fabric.Image.fromObject=function(e,t){fabric.util.loadImage(e.src,function(n){fabric.Image.prototype._initFilters.call(e,e,function(r){e.filters=r||[];var i=new fabric.Image(n,e);t&&t(i)})},null,e.crossOrigin)},fabric.Image.fromURL=function(e,t,n){fabric.util.loadImage(e,function(e){t(new fabric.Image(e,n))},null,n&&n.crossOrigin)},fabric.Image.ATTRIBUTE_NAMES=fabric.SHARED_ATTRIBUTES.concat("x y width height xlink:href".split(" ")),fabric.Image.fromElement=function(e,n,r){var i=fabric.parseAttributes(e,fabric.Image.ATTRIBUTE_NAMES);fabric.Image.fromURL(i["xlink:href"],n,t(r?fabric.util.object.clone(r):{},i))},fabric.Image.async=!0,fabric.Image.pngCompression=1}(typeof exports!="undefined"?exports:this),fabric.util.object.extend(fabric.Object.prototype,{_getAngleValueForStraighten:function(){var e=this.getAngle()%360;return e>0?Math.round((e-1)/90)*90:Math.round(e/90)*90},straighten:function(){return this.setAngle(this._getAngleValueForStraighten()),this},fxStraighten:function(e){e=e||{};var t=function(){},n=e.onComplete||t,r=e.onChange||t,i=this;return fabric.util.animate({startValue:this.get("angle"),endValue:this._getAngleValueForStraighten(),duration:this.FX_DURATION,onChange:function(e){i.setAngle(e),r()},onComplete:function(){i.setCoords(),n()},onStart:function(){i.set("active",!1)}}),this}}),fabric.util.object.extend(fabric.StaticCanvas.prototype,{straightenObject:function(e){return e.straighten(),this.renderAll(),this},fxStraightenObject:function(e){return e.fxStraighten({onChange:this.renderAll.bind(this)}),this}}),fabric.Image.filters=fabric.Image.filters||{},fabric.Image.filters.BaseFilter=fabric.util.createClass({type:"BaseFilter",toObject:function(){return{type:this.type}},toJSON:function(){return this.toObject()}}),function(e){"use strict";var t=e.fabric||(e.fabric={}),n=t.util.object.extend;t.Image.filters.Brightness=t.util.createClass(t.Image.filters.BaseFilter,{type:"Brightness",initialize:function(e){e=e||{},this.brightness=e.brightness||0},applyTo:function(e){var t=e.getContext("2d"),n=t.getImageData(0,0,e.width,e.height),r=n.data,i=this.brightness;for(var s=0,o=r.length;sa||C<0||C>u)continue;var k=(N*u+C)*4,L=t[x*i+T];b+=o[k]*L,w+=o[k+1]*L,E+=o[k+2]*L,S+=o[k+3]*L}h[y]=b,h[y+1]=w,h[y+2]=E,h[y+3]=S+p*(255-S)}n.putImageData(c,0,0)},toObject:function(){return n(this.callSuper("toObject"),{opaque:this.opaque,matrix:this.matrix})}}),t.Image.filters.Convolute.fromObject=function(e){return new t.Image.filters.Convolute(e)}}(typeof exports!="undefined"?exports:this),function(e){"use strict";var t=e.fabric||(e.fabric={}),n=t.util.object.extend;t.Image.filters.GradientTransparency=t.util.createClass(t.Image.filters.BaseFilter,{type:"GradientTransparency",initialize:function(e){e=e||{},this.threshold=e.threshold||100},applyTo:function(e){var t=e.getContext("2d"),n=t.getImageData(0,0,e.width,e.height),r=n.data,i=this.threshold,s=r.length;for(var o=0,u=r.length;o-1?e.channel:0},applyTo:function(e){if(!this.mask)return;var n=e.getContext("2d"),r=n.getImageData(0,0,e.width,e.height),i=r.data,s=this.mask.getElement(),o=t.util.createCanvasElement(),u=this.channel,a,f=r.width*r.height*4;o.width=s.width,o.height=s.height,o.getContext("2d").drawImage(s,0,0,s.width,s.height);var l=o.getContext("2d").getImageData(0,0,s.width,s.height),c=l.data;for(a=0;ao&&f>o&&l>o&&u(a-f)'},_render:function(e){var t=this.group&&this.group.type==="path-group";t&&!this.transformMatrix?e.translate(-this.group.width/2+this.left,-this.group.height/2+this.top):t&&this.transformMatrix&&e.translate(-this.group.width/2,-this.group.height/2),typeof Cufon=="undefined"||this.useNative===!0?this._renderViaNative(e):this._renderViaCufon(e)},_renderViaNative:function(e){var n=this.text.split(this._reNewline);this.transform(e,t.isLikelyNode),this._setTextStyles(e),this.width=this._getTextWidth(e,n),this.height=this._getTextHeight(e,n),this.clipTo&&t.util.clipContext(this,e),this._renderTextBackground(e,n),this._translateForTextAlign(e),this._renderText(e,n),this.textAlign!=="left"&&this.textAlign!=="justify"&&e.restore(),this._renderTextDecoration(e,n),this.clipTo&&e.restore(),this._setBoundaries(e,n),this._totalLineHeight=0},_renderText:function(e,t){e.save(),this._setShadow(e),this._renderTextFill(e,t),this._renderTextStroke(e,t),this._removeShadow(e),e.restore()},_translateForTextAlign:function(e){this.textAlign!=="left"&&this.textAlign!=="justify"&&(e.save(),e.translate(this.textAlign==="center"?this.width/2:this.width,0))},_setBoundaries:function(e,t){this._boundaries=[];for(var n=0,r=t.length;nn&&(n=s)}return n},_renderChars:function(e,t,n,r,i){t[e](n,r,i)},_renderTextLine:function(e,t,n,r,i,s){i-=this.fontSize/4;if(this.textAlign!=="justify"){this._renderChars(e,t,n,r,i,s);return}var o=t.measureText(n).width,u=this.width;if(u>o){var a=n.split(/\s+/),f=t.measureText(n.replace(/\s+/g,"")).width,l=u-f,c=a.length-1,h=l/c,p=0;for(var d=0,v=a.length;d-1&&i(this.fontSize*this.lineHeight),this.textDecoration.indexOf("line-through")>-1&&i(this.fontSize*this.lineHeight-this.fontSize/2),this.textDecoration.indexOf("overline")>-1&&i(this.fontSize*this.lineHeight-this.fontSize)},_getFontDeclaration:function(){return[t.isLikelyNode?this.fontWeight:this.fontStyle,t.isLikelyNode?this.fontStyle:this.fontWeight,this.fontSize+"px",t.isLikelyNode?'"'+this.fontFamily+'"':this.fontFamily].join(" ")},render:function(e,t){if(!this.visible)return;e.save();var n=this.transformMatrix;n&&(!this.group||this.group.type==="path-group")&&e.transform(n[0],n[1],n[2],n[3],n[4],n[5]),this._render(e),!t&&this.active&&(this.drawBorders(e),this.drawControls(e)),e.restore()},toObject:function(e){var t=n(this.callSuper("toObject",e),{text:this.text,fontSize:this.fontSize,fontWeight:this.fontWeight,fontFamily:this.fontFamily,fontStyle:this.fontStyle,lineHeight:this.lineHeight,textDecoration:this.textDecoration,textAlign:this.textAlign,path:this.path,textBackgroundColor:this.textBackgroundColor,useNative:this.useNative});return this.includeDefaultValues||this._removeDefaultValues(t),t},toSVG:function(e){var t=[],n=this.text.split(this._reNewline),r=this._getSVGLeftTopOffsets(n),i=this._getSVGTextAndBg(r.lineTop,r.textLeft,n),s=this._getSVGShadows(r.lineTop,n);return r.textTop+=this._fontAscent?this._fontAscent/5*this.lineHeight:0,this._wrapSVGTextAndBg(t,i,s,r),e?e(t.join("")):t.join("")},_getSVGLeftTopOffsets:function(e){var t=this.useNative?this.fontSize*this.lineHeight:-this._fontAscent-this._fontAscent/5*this.lineHeight,n=-(this.width/2),r=this.useNative?this.fontSize-1:this.height/2-e.length*this.fontSize-this._totalLineHeight;return{textLeft:n,textTop:r,lineTop:t}},_wrapSVGTextAndBg:function(e,t,n,r){e.push('',t.textBgRects.join(""),"',n.join(""),t.textSpans.join(""),"","")},_getSVGShadows:function(e,n){var r=[],s,o,u=1;if(!this.shadow||!this._boundaries)return r;for(s=0,o=n.length;s",t.util.string.escapeXml(n[s]),""),u=1}else u++;return r},_getSVGTextAndBg:function(e,t,n){var r=[],i=[],s=1;this._setSVGBg(i);for(var o=0,u=n.length;o",t.util.string.escapeXml(e),"")},_setSVGTextLineBg:function(e,t,n,r){e.push("')},_setSVGBg:function(e){this.backgroundColor&&this._boundaries&&e.push("')},_getFillAttributes:function(e){var n=e&&typeof e=="string"?new t.Color(e):"";return!n||!n.getSource()||n.getAlpha()===1?'fill="'+e+'"':'opacity="'+n.getAlpha()+'" fill="'+n.setAlpha(1).toRgb()+'"'},_set:function(e,t){e==="fontFamily"&&this.path&&(this.path=this.path.replace(/(.*?)([^\/]*)(\.font\.js)/,"$1"+t+"$3")),this.callSuper("_set",e,t),e in this._dimensionAffectingProps&&(this._initDimensions(),this.setCoords())},complexity:function(){return 1}}),t.Text.ATTRIBUTE_NAMES=t.SHARED_ATTRIBUTES.concat("x y dx dy font-family font-style font-weight font-size text-decoration text-anchor".split(" ")),t.Text.DEFAULT_SVG_FONT_SIZE=16,t.Text.fromElement=function(e,n){if(!e)return null;var r=t.parseAttributes(e,t.Text.ATTRIBUTE_NAMES);n=t.util.object.extend(n?t.util.object.clone(n):{},r),"dx"in r&&(n.left+=r.dx),"dy"in r&&(n.top+=r.dy),"fontSize"in n||(n.fontSize=t.Text.DEFAULT_SVG_FONT_SIZE),n.originX||(n.originX="center");var i=new t.Text(e.textContent,n);return i.set({left:i.getLeft()+i.getWidth()/2,top:i.getTop()-i.getHeight()/2}),i},t.Text.fromObject=function(e){return new t.Text(e.text,r(e))},t.util.createAccessors(t.Text)}(typeof exports!="undefined"?exports:this),function(){var e=fabric.util.object.clone;fabric.IText=fabric.util.createClass(fabric.Text,fabric.Observable,{type:"i-text",selectionStart:0,selectionEnd:0,selectionColor:"rgba(17,119,255,0.3)",isEditing:!1,editable:!0,editingBorderColor:"rgba(102,153,255,0.25)",cursorWidth:2,cursorColor:"#333",cursorDelay:1e3,cursorDuration:600,styles:null,caching:!0,_skipFillStrokeCheck:!0,_reSpace:/\s|\n/,_fontSizeFraction:4,_currentCursorOpacity:0,_selectionDirection:null,_abortCursorAnimation:!1,_charWidthsCache:{},initialize:function(e,t){this.styles=t?t.styles||{}:{},this.callSuper("initialize",e,t),this.initBehavior(),fabric.IText.instances.push(this),this.__lineWidths={},this.__lineHeights={},this.__lineOffsets={}},isEmptyStyles:function(){if(!this.styles)return!0;var e=this.styles;for(var t in e)for(var n in e[t])for(var r in e[t][n])return!1;return!0},setSelectionStart:function(e){this.selectionStart!==e&&this.canvas&&this.canvas.fire("text:selection:changed",{target:this}),this.selectionStart=e,this.hiddenTextarea&&(this.hiddenTextarea.selectionStart=e)},setSelectionEnd:function(e){this.selectionEnd!==e&&this.canvas&&this.canvas.fire("text:selection:changed",{target:this}),this.selectionEnd=e,this.hiddenTextarea&&(this.hiddenTextarea.selectionEnd=e)},getSelectionStyles:function(e,t){if(arguments.length===2){var n=[];for(var r=e;r=r.charIndex&&(a!==o||hs&&a-1&&this._renderCharDecorationAtOffset(e,n,r+this.fontSize/this._fontSizeFraction,i,0,this.fontSize/20),u.indexOf("line-through")>-1&&this._renderCharDecorationAtOffset(e,n,r+this.fontSize/this._fontSizeFraction,i,o/2,a/20),u.indexOf("overline")>-1&&this._renderCharDecorationAtOffset(e,n,r,i,s-this.fontSize/this._fontSizeFraction,this.fontSize/20)},_renderCharDecorationAtOffset:function(e,t,n,r,i,s){e.fillRect(t,n-i,r,s)},_renderTextLine:function(e,t,n,r,i,s){i+=this.fontSize/4,this.callSuper("_renderTextLine",e,t,n,r,i,s)},_renderTextDecoration:function(e,t){if(this.isEmptyStyles())return this.callSuper("_renderTextDecoration",e,t)},_renderTextLinesBackground:function(e,t){if(!this.textBackgroundColor&&!this.styles)return;e.save(),this.textBackgroundColor&&(e.fillStyle=this.textBackgroundColor);var n=0,r=this.fontSize/this._fontSizeFraction;for(var i=0,s=t.length;in&&(n=s)}return n},_getHeightOfLine:function(e,t,n){n=n||this.text.split(this._reNewline);var r=this._getHeightOfChar(e,n[t][0],t,0),i=n[t],s=i.split("");for(var o=1,u=s.length;or&&(r=a)}return r*this.lineHeight},_getTextHeight:function(e,t){var n=0;for(var r=0,i=t.length;r-1)t++,n--;return e-t},findWordBoundaryRight:function(e){var t=0,n=e;if(this._reSpace.test(this.text.charAt(n)))while(this._reSpace.test(this.text.charAt(n)))t++,n++;while(/\S/.test(this.text.charAt(n))&&n-1)t++,n--;return e-t},findLineBoundaryRight:function(e){var t=0,n=e;while(!/\n/.test(this.text.charAt(n))&&n0&&nr;s?this.removeStyleObject(s,n+1):this.removeStyleObject(this.get2DCursorLocation(n).charIndex===0,n)}this.text=this.text.slice(0,e)+this.text.slice(t)},insertChars:function(e){var t=this.text.slice(this.selectionStart,this.selectionStart+1)==="\n";this.text=this.text.slice(0,this.selectionStart)+e+this.text.slice(this.selectionEnd),this.selectionStart===this.selectionEnd&&this.insertStyleObjects(e,t,this.copiedStyles),this.selectionStart+=e.length,this.selectionEnd=this.selectionStart,this.canvas&&this.canvas.renderAll().renderAll(),this.setCoords(),this.fire("changed"),this.canvas&&this.canvas.fire("text:changed",{target:this})},insertNewlineStyleObject:function(t,n,r){this.shiftLineStyles(t,1),this.styles[t+1]||(this.styles[t+1]={});var i=this.styles[t][n-1],s={};if(r)s[0]=e(i),this.styles[t+1]=s;else{for(var o in this.styles[t])parseInt(o,10)>=n&&(s[parseInt(o,10)-n]=this.styles[t][o],delete this.styles[t][o]);this.styles[t+1]=s}},insertCharStyleObject:function(t,n,r){var i=this.styles[t],s=e(i);n===0&&!r&&(n=1);for(var o in s){var u=parseInt(o,10);u>=n&&(i[u+1]=s[u])}this.styles[t][n]=r||e(i[n-1])},insertStyleObjects:function(e,t,n){if(this.isEmptyStyles())return;var r=this.get2DCursorLocation(),i=r.lineIndex,s=r.charIndex;this.styles[i]||(this.styles[i]={}),e==="\n"?this.insertNewlineStyleObject(i,s,t):n?this._insertStyles(n):this.insertCharStyleObject(i,s)},_insertStyles:function(e){for(var t=0,n=e.length;tt&&(this.styles[s+n]=r[s])}},removeStyleObject:function(t,n){var r=this.get2DCursorLocation(n),i=r.lineIndex,s=r.charIndex;if(t){var o=this.text.split(this._reNewline),u=o[i-1],a=u?u.length:0;this.styles[i-1]||(this.styles[i-1]={});for(s in this.styles[i])this.styles[i-1][parseInt(s,10)+a]=this.styles[i][s];this.shiftLineStyles(i,-1)}else{var f=this.styles[i];if(f){var l=this.selectionStart===this.selectionEnd?-1:0;delete f[s+l]}var c=e(f);for(var h in c){var p=parseInt(h,10);p>=s&&p!==0&&(f[p-1]=c[p],delete f[p])}}},insertNewline:function(){this.insertChars("\n")}})}(),fabric.util.object.extend(fabric.IText.prototype,{initDoubleClickSimulation:function(){this.__lastClickTime=+(new Date),this.__lastLastClickTime=+(new Date),this.__lastPointer={},this.on("mousedown",this.onMouseDown.bind(this))},onMouseDown:function(e){this.__newClickTime=+(new Date);var t=this.canvas.getPointer(e.e);this.isTripleClick(t)?(this.fire("tripleclick",e),this._stopEvent(e.e)):this.isDoubleClick(t)&&(this.fire("dblclick",e),this._stopEvent(e.e)),this.__lastLastClickTime=this.__lastClickTime,this.__lastClickTime=this.__newClickTime,this.__lastPointer=t,this.__lastIsEditing=this.isEditing,this.__lastSelected=this.selected},isDoubleClick:function(e){return this.__newClickTime-this.__lastClickTime<500&&this.__lastPointer.x===e.x&&this.__lastPointer.y===e.y&&this.__lastIsEditing},isTripleClick:function(e){return this.__newClickTime-this.__lastClickTime<500&&this.__lastClickTime-this.__lastLastClickTime<500&&this.__lastPointer.x===e.x&&this.__lastPointer.y===e.y},_stopEvent:function(e){e.preventDefault&&e.preventDefault(),e.stopPropagation&&e.stopPropagation()},initCursorSelectionHandlers:function(){this.initSelectedHandler(),this.initMousedownHandler(),this.initMousemoveHandler(),this.initMouseupHandler(),this.initClicks()},initClicks -:function(){this.on("dblclick",function(e){this.selectWord(this.getSelectionStartFromPointer(e.e))}),this.on("tripleclick",function(e){this.selectLine(this.getSelectionStartFromPointer(e.e))})},initMousedownHandler:function(){this.on("mousedown",function(e){var t=this.canvas.getPointer(e.e);this.__mousedownX=t.x,this.__mousedownY=t.y,this.__isMousedown=!0,this.hiddenTextarea&&this.canvas&&this.canvas.wrapperEl.appendChild(this.hiddenTextarea),this.selected&&this.setCursorByClick(e.e),this.isEditing&&(this.__selectionStartOnMouseDown=this.selectionStart,this.initDelayedCursor(!0))})},initMousemoveHandler:function(){this.on("mousemove",function(e){if(!this.__isMousedown||!this.isEditing)return;var t=this.getSelectionStartFromPointer(e.e);t>=this.__selectionStartOnMouseDown?(this.setSelectionStart(this.__selectionStartOnMouseDown),this.setSelectionEnd(t)):(this.setSelectionStart(t),this.setSelectionEnd(this.__selectionStartOnMouseDown))})},_isObjectMoved:function(e){var t=this.canvas.getPointer(e);return this.__mousedownX!==t.x||this.__mousedownY!==t.y},initMouseupHandler:function(){this.on("mouseup",function(e){this.__isMousedown=!1;if(this._isObjectMoved(e.e))return;this.__lastSelected&&(this.enterEditing(),this.initDelayedCursor(!0)),this.selected=!0})},setCursorByClick:function(e){var t=this.getSelectionStartFromPointer(e);e.shiftKey?to?0:1,f=r+a;return this.flipX&&(f=i-f),f>this.text.length&&(f=this.text.length),s===i&&f--,f}}),fabric.util.object.extend(fabric.IText.prototype,{initHiddenTextarea:function(){this.hiddenTextarea=fabric.document.createElement("textarea"),this.hiddenTextarea.setAttribute("autocapitalize","off"),this.hiddenTextarea.style.cssText="position: absolute; top: 0; left: -9999px",fabric.document.body.appendChild(this.hiddenTextarea),fabric.util.addListener(this.hiddenTextarea,"keydown",this.onKeyDown.bind(this)),fabric.util.addListener(this.hiddenTextarea,"keypress",this.onKeyPress.bind(this)),fabric.util.addListener(this.hiddenTextarea,"copy",this.copy.bind(this)),fabric.util.addListener(this.hiddenTextarea,"paste",this.paste.bind(this)),!this._clickHandlerInitialized&&this.canvas&&(fabric.util.addListener(this.canvas.upperCanvasEl,"click",this.onClick.bind(this)),this._clickHandlerInitialized=!0)},_keysMap:{8:"removeChars",13:"insertNewline",37:"moveCursorLeft",38:"moveCursorUp",39:"moveCursorRight",40:"moveCursorDown",46:"forwardDelete"},_ctrlKeysMap:{65:"selectAll",88:"cut"},onClick:function(){this.hiddenTextarea&&this.hiddenTextarea.focus()},onKeyDown:function(e){if(!this.isEditing)return;if(e.keyCode in this._keysMap)this[this._keysMap[e.keyCode]](e);else{if(!(e.keyCode in this._ctrlKeysMap&&(e.ctrlKey||e.metaKey)))return;this[this._ctrlKeysMap[e.keyCode]](e)}e.stopPropagation(),this.canvas&&this.canvas.renderAll()},forwardDelete:function(e){this.selectionStart===this.selectionEnd&&this.moveCursorRight(e),this.removeChars(e)},copy:function(e){var t=this.getSelectedText(),n=this._getClipboardData(e);n&&n.setData("text",t),this.copiedText=t,this.copiedStyles=this.getSelectionStyles(this.selectionStart,this.selectionEnd)},paste:function(e){var t=null,n=this._getClipboardData(e);n?t=n.getData("text"):t=this.copiedText,t&&this.insertChars(t)},cut:function(e){if(this.selectionStart===this.selectionEnd)return;this.copy(),this.removeChars(e)},_getClipboardData:function(e){return e&&(e.clipboardData||fabric.window.clipboardData)},onKeyPress:function(e){if(!this.isEditing||e.metaKey||e.ctrlKey||e.keyCode===8||e.keyCode===13)return;this.insertChars(String.fromCharCode(e.which)),e.stopPropagation()},getDownCursorOffset:function(e,t){var n=t?this.selectionEnd:this.selectionStart,r=this.text.split(this._reNewline),i,s,o=this.text.slice(0,n),u=this.text.slice(n),a=o.slice(o.lastIndexOf("\n")+1),f=u.match(/(.*)\n?/)[1],l=(u.match(/.*\n(.*)\n?/)||{})[1]||"",c=this.get2DCursorLocation(n);if(c.lineIndex===r.length-1||e.metaKey)return this.text.length-n;var h=this._getWidthOfLine(this.ctx,c.lineIndex,r);s=this._getLineLeftOffset(h);var p=s,d=c.lineIndex;for(var v=0,m=a.length;vn){f=!0;var d=u-p,v=u,m=Math.abs(d-n),g=Math.abs(v-n);a=gthis.text.length&&(this.selectionStart=this.text.length),this.selectionEnd=this.selectionStart},moveCursorDownWithShift:function(e){if(this._selectionDirection==="left"&&this.selectionStart!==this.selectionEnd){this.selectionStart+=e,this._selectionDirection="left";return}this._selectionDirection="right",this.selectionEnd+=e,this.selectionEnd>this.text.length&&(this.selectionEnd=this.text.length)},getUpCursorOffset:function(e,t){var n=t?this.selectionEnd:this.selectionStart,r=this.get2DCursorLocation(n);if(r.lineIndex===0||e.metaKey)return n;var i=this.text.slice(0,n),s=i.slice(i.lastIndexOf("\n")+1),o=(i.match(/\n?(.*)\n.*$/)||{})[1]||"",u=this.text.split(this._reNewline),a,f=this._getWidthOfLine(this.ctx,r.lineIndex,u),l=this._getLineLeftOffset(f),c=l,h=r.lineIndex;for(var p=0,d=s.length;pn){f=!0;var d=u-p,v=u,m=Math.abs(d-n),g=Math.abs(v-n);a=g=this.text.length&&this.selectionEnd>=this.text.length)return;this.abortCursorAnimation(),this._currentCursorOpacity=1,e.shiftKey?this.moveCursorRightWithShift(e):this.moveCursorRightWithoutShift(e),this.initDelayedCursor()},moveCursorRightWithShift:function(e){this._selectionDirection==="left"&&this.selectionStart!==this.selectionEnd?this._moveRight(e,"selectionStart"):(this._selectionDirection="right",this._moveRight(e,"selectionEnd"),this.text.charAt(this.selectionEnd-1)==="\n"&&this.selectionEnd++,this.selectionEnd>this.text.length&&(this.selectionEnd=this.text.length))},moveCursorRightWithoutShift:function(e){this._selectionDirection="right",this.selectionStart===this.selectionEnd?(this._moveRight(e,"selectionStart"),this.selectionEnd=this.selectionStart):(this.selectionEnd+=this.getNumNewLinesInSelectedText(),this.selectionEnd>this.text.length&&(this.selectionEnd=this.text.length),this.selectionStart=this.selectionEnd)},removeChars:function(e){this.selectionStart===this.selectionEnd?this._removeCharsNearCursor(e):this._removeCharsFromTo(this.selectionStart,this.selectionEnd),this.selectionEnd=this.selectionStart,this._removeExtraneousStyles(),this.canvas&&this.canvas.renderAll().renderAll(),this.setCoords(),this.fire("changed"),this.canvas&&this.canvas.fire("text:changed",{target:this})},_removeCharsNearCursor:function(e){if(this.selectionStart!==0)if(e.metaKey){var t=this.findLineBoundaryLeft(this.selectionStart);this._removeCharsFromTo(t,this.selectionStart),this.selectionStart=t}else if(e.altKey){var n=this.findWordBoundaryLeft(this.selectionStart);this._removeCharsFromTo(n,this.selectionStart),this.selectionStart=n}else{var r=this.text.slice(this.selectionStart-1,this.selectionStart)==="\n";this.removeStyleObject(r),this.selectionStart--,this.text=this.text.slice(0,this.selectionStart)+this.text.slice(this.selectionStart+1)}}}),fabric.util.object.extend(fabric.IText.prototype,{_setSVGTextLineText:function(e,t,n,r,i,s){this.styles[t]?this._setSVGTextLineChars(e,t,n,r,i,s):this.callSuper("_setSVGTextLineText",e,t,n,r,i)},_setSVGTextLineChars:function(e,t,n,r,i,s){var o=t===0||this.useNative?"y":"dy",u=e.split(""),a=0,f=this._getSVGLineLeftOffset(t),l=this._getSVGLineTopOffset(t),c=this._getHeightOfLine(this.ctx,t);for(var h=0,p=u.length;h'].join("")},_createTextCharSpan:function(e,t,n,r,i,s){var o=this.getSvgStyles.call(fabric.util.object.extend({visible:!0,fill:this.fill,stroke:this.stroke,type:"text"},t));return['',fabric.util.string.escapeXml(e),""].join("")}}),function(){function request(e,t,n){var r=URL.parse(e);r.port||(r.port=r.protocol.indexOf("https:")===0?443:80);var i=r.port===443?HTTPS:HTTP,s=i.request({hostname:r.hostname,port:r.port,path:r.path,method:"GET"},function(e){var r="";t&&e.setEncoding(t),e.on("end",function(){n(r)}),e.on("data",function(t){e.statusCode===200&&(r+=t)})});s.on("error",function(e){e.errno===process.ECONNREFUSED?fabric.log("ECONNREFUSED: connection refused to "+r.hostname+":"+r.port):fabric.log(e.message)}),s.end()}function requestFs(e,t){var n=require("fs");n.readFile(e,function(e,n){if(e)throw fabric.log(e),e;t(n)})}if(typeof document!="undefined"&&typeof window!="undefined")return;var DOMParser=require("xmldom").DOMParser,URL=require("url"),HTTP=require("http"),HTTPS=require("https"),Canvas=require("canvas"),Image=require("canvas").Image;fabric.util.loadImage=function(e,t,n){function r(r){i.src=new Buffer(r,"binary"),i._src=e,t&&t.call(n,i)}var i=new Image;e&&(e instanceof Buffer||e.indexOf("data")===0)?(i.src=i._src=e,t&&t.call(n,i)):e&&e.indexOf("http")!==0?requestFs(e,r):e?request(e,"binary",r):t&&t.call(n,e)},fabric.loadSVGFromURL=function(e,t,n){e=e.replace(/^\n\s*/,"").replace(/\?.*$/,"").trim(),e.indexOf("http")!==0?requestFs(e,function(e){fabric.loadSVGFromString(e.toString(),t,n)}):request(e,"",function(e){fabric.loadSVGFromString(e,t,n)})},fabric.loadSVGFromString=function(e,t,n){var r=(new DOMParser).parseFromString(e);fabric.parseSVGDocument(r.documentElement,function(e,n){t&&t(e,n)},n)},fabric.util.getScript=function(url,callback){request(url,"",function(body){eval(body),callback&&callback()})},fabric.Image.fromObject=function(e,t){fabric.util.loadImage(e.src,function(n){var r=new fabric.Image(n);r._initConfig(e),r._initFilters(e,function(e){r.filters=e||[],t&&t(r)})})},fabric.createCanvasForNode=function(e,t,n,r){r=r||n;var i=fabric.document.createElement("canvas"),s=new Canvas(e||600,t||600,r);i.style={},i.width=s.width,i.height=s.height;var o=fabric.Canvas||fabric.StaticCanvas,u=new o(i,n);return u.contextContainer=s.getContext("2d"),u.nodeCanvas=s,u.Font=Canvas.Font,u},fabric.StaticCanvas.prototype.createPNGStream=function(){return this.nodeCanvas.createPNGStream()},fabric.StaticCanvas.prototype.createJPEGStream=function(e){return this.nodeCanvas.createJPEGStream(e)};var origSetWidth=fabric.StaticCanvas.prototype.setWidth;fabric.StaticCanvas.prototype.setWidth=function(e){return origSetWidth.call(this,e),this.nodeCanvas.width=e,this},fabric.Canvas&&(fabric.Canvas.prototype.setWidth=fabric.StaticCanvas.prototype.setWidth);var origSetHeight=fabric.StaticCanvas.prototype.setHeight;fabric.StaticCanvas.prototype.setHeight=function(e){return origSetHeight.call(this,e),this.nodeCanvas.height=e,this},fabric.Canvas&&(fabric.Canvas.prototype.setHeight=fabric.StaticCanvas.prototype.setHeight)}(); \ No newline at end of file +/* build: `node build.js modules=ALL exclude=gestures,cufon,json minifier=uglifyjs` *//*! Fabric.js Copyright 2008-2014, Printio (Juriy Zaytsev, Maxim Chernyak) */var fabric=fabric||{version:"1.4.8"};typeof exports!="undefined"&&(exports.fabric=fabric),typeof document!="undefined"&&typeof window!="undefined"?(fabric.document=document,fabric.window=window):(fabric.document=require("jsdom").jsdom(""),fabric.window=fabric.document.createWindow()),fabric.isTouchSupported="ontouchstart"in fabric.document.documentElement,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"],function(){function e(e,t){if(!this.__eventListeners[e])return;t?fabric.util.removeFromArray(this.__eventListeners[e],t):this.__eventListeners[e].length=0}function t(e,t){this.__eventListeners||(this.__eventListeners={});if(arguments.length===1)for(var n in e)this.on(n,e[n]);else this.__eventListeners[e]||(this.__eventListeners[e]=[]),this.__eventListeners[e].push(t);return this}function n(t,n){if(!this.__eventListeners)return;if(arguments.length===0)this.__eventListeners={};else if(arguments.length===1&&typeof arguments[0]=="object")for(var r in t)e.call(this,r,t[r]);else e.call(this,t,n);return this}function r(e,t){if(!this.__eventListeners)return;var n=this.__eventListeners[e];if(!n)return;for(var r=0,i=n.length;r-1},complexity:function(){return this.getObjects().reduce(function(e,t){return e+=t.complexity?t.complexity():0,e},0)}},function(e){var t=Math.sqrt,n=Math.atan2,r=Math.PI/180;fabric.util={removeFromArray:function(e,t){var n=e.indexOf(t);return n!==-1&&e.splice(n,1),e},getRandomInt:function(e,t){return Math.floor(Math.random()*(t-e+1))+e},degreesToRadians:function(e){return e*r},radiansToDegrees:function(e){return e/r},rotatePoint:function(e,t,n){var r=Math.sin(n),i=Math.cos(n);e.subtractEquals(t);var s=e.x*i-e.y*r,o=e.x*r+e.y*i;return(new fabric.Point(s,o)).addEquals(t)},transformPoint:function(e,t,n){return n?new fabric.Point(t[0]*e.x+t[1]*e.y,t[2]*e.x+t[3]*e.y):new fabric.Point(t[0]*e.x+t[1]*e.y+t[4],t[2]*e.x+t[3]*e.y+t[5])},invertTransform:function(e){var t=e.slice(),n=1/(e[0]*e[3]-e[1]*e[2]);t=[n*e[3],-n*e[1],-n*e[2],n*e[0],0,0];var r=fabric.util.transformPoint({x:e[4],y:e[5]},t);return t[4]=-r.x,t[5]=-r.y,t},toFixed:function(e,t){return parseFloat(Number(e).toFixed(t))},falseFunction:function(){return!1},getKlass:function(e,t){return e=fabric.util.string.camelize(e.charAt(0).toUpperCase()+e.slice(1)),fabric.util.resolveNamespace(t)[e]},resolveNamespace:function(t){if(!t)return fabric;var n=t.split("."),r=n.length,i=e||fabric.window;for(var s=0;s1?r=new fabric.PathGroup(e,t):r=e[0],typeof n!="undefined"&&r.setSourcePath(n),r},populateWithProperties:function(e,t,n){if(n&&Object.prototype.toString.call(n)==="[object Array]")for(var r=0,i=n.length;rr)r+=u[p++%h],r>l&&(r=l),e[d?"lineTo":"moveTo"](r,0),d=!d;e.restore()},createCanvasElement:function(e){return e||(e=fabric.document.createElement("canvas")),!e.getContext&&typeof G_vmlCanvasManager!="undefined"&&G_vmlCanvasManager.initElement(e),e},createImage:function(){return fabric.isLikelyNode?new(require("canvas").Image):fabric.document.createElement("img")},createAccessors:function(e){var t=e.prototype;for(var n=t.stateProperties.length;n--;){var r=t.stateProperties[n],i=r.charAt(0).toUpperCase()+r.slice(1),s="set"+i,o="get"+i;t[o]||(t[o]=function(e){return new Function('return this.get("'+e+'")')}(r)),t[s]||(t[s]=function(e){return new Function("value",'return this.set("'+e+'", value)')}(r))}},clipContext:function(e,t){t.save(),t.beginPath(),e.clipTo(t),t.clip()},multiplyTransformMatrices:function(e,t){var n=[[e[0],e[2],e[4]],[e[1],e[3],e[5]],[0,0,1]],r=[[t[0],t[2],t[4]],[t[1],t[3],t[5]],[0,0,1]],i=[];for(var s=0;s<3;s++){i[s]=[];for(var o=0;o<3;o++){var u=0;for(var a=0;a<3;a++)u+=n[s][a]*r[a][o];i[s][o]=u}}return[i[0][0],i[1][0],i[0][1],i[1][1],i[0][2],i[1][2]]},getFunctionBody:function(e){return(String(e).match(/function[^{]*\{([\s\S]*)\}/)||{})[1]},normalizePoints:function(e,t){var n=fabric.util.array.min(e,"x"),r=fabric.util.array.min(e,"y");n=n<0?n:0,r=n<0?r:0;for(var i=0,s=e.length;i0&&(t>r?t-=r:t=0,n>r?n-=r:n=0);var i=!0,s=e.getImageData(t,n,r*2||1,r*2||1);for(var o=3,u=s.data.length;o0&&f===0&&(E-=2*Math.PI);var S=Math.ceil(Math.abs(E/(Math.PI*.5+.001))),x=[];for(var T=0;T1&&(h=Math.sqrt(h),t*=h,n*=h);var p=f/t,d=a/t,v=-a/n,m=f/n;return{x0:p*r+d*i,y0:v*r+m*i,x1:p*s+d*o,y1:v*s+m*o,sinTh:a,cosTh:f}}function o(e,i,s,o,u,a,f,l){r=n.call(arguments);if(t[r])return t[r];var c=Math.sin(s),h=Math.cos(s),p=Math.sin(o),d=Math.cos(o),v=l*u,m=-f*a,g=f*u,y=l*a,b=.25*(o-s),w=8/3*Math.sin(b)*Math.sin(b)/Math.sin(b*2),E=e+h-w*c,S=i+c+w*h,x=e+d,T=i+p,N=x+w*p,C=T-w*d;return t[r]=[v*E+m*S,g*E+y*S,v*N+m*C,g*N+y*C,v*x+m*T,g*x+y*T],t[r]}var e={},t={},n=Array.prototype.join,r;fabric.util.drawArc=function(e,t,n,r){var s=r[0],u=r[1],a=r[2],f=r[3],l=r[4],c=r[5],h=r[6],p=i(c,h,s,u,f,l,a,t,n);for(var d=0;d=t})}function r(e,t){return i(e,t,function(e,t){return e>>0;if(n===0)return-1;var r=0;arguments.length>0&&(r=Number(arguments[1]),r!==r?r=0:r!==0&&r!==Number.POSITIVE_INFINITY&&r!==Number.NEGATIVE_INFINITY&&(r=(r>0||-1)*Math.floor(Math.abs(r))));if(r>=n)return-1;var i=r>=0?r:Math.max(n-Math.abs(r),0);for(;i>>0;n>>0;r>>0;n>>0;n>>0;i>>0,n=0,r;if(arguments.length>1)r=arguments[1];else do{if(n in this){r=this[n++];break}if(++n>=t)throw new TypeError}while(!0);for(;n/g,">")}String.prototype.trim||(String.prototype.trim=function(){return this.replace(/^[\s\xA0]+/,"").replace(/[\s\xA0]+$/,"")}),fabric.util.string={camelize:e,capitalize:t,escapeXml:n}}(),function(){var e=Array.prototype.slice,t=Function.prototype.apply,n=function(){};Function.prototype.bind||(Function.prototype.bind=function(r){var i=this,s=e.call(arguments,1),o;return s.length?o=function(){return t.call(i,this instanceof n?this:r,s.concat(e.call(arguments)))}:o=function(){return t.call(i,this instanceof n?this:r,arguments)},n.prototype=this.prototype,o.prototype=new n,o})}(),function(){function i(){}function s(t){var n=this.constructor.superclass.prototype[t];return arguments.length>1?n.apply(this,e.call(arguments,1)):n.call(this)}function o(){function u(){this.initialize.apply(this,arguments)}var n=null,o=e.call(arguments,0);typeof o[0]=="function"&&(n=o.shift()),u.superclass=n,u.subclasses=[],n&&(i.prototype=n.prototype,u.prototype=new i,n.subclasses.push(u));for(var a=0,f=o.length;a-1?e.prototype[i]=function(e){return function(){var n=this.constructor.superclass;this.constructor.superclass=r;var i=t[e].apply(this,arguments);this.constructor.superclass=n;if(e!=="initialize")return i}}(i):e.prototype[i]=t[i],n&&(t.toString!==Object.prototype.toString&&(e.prototype.toString=t.toString),t.valueOf!==Object.prototype.valueOf&&(e.prototype.valueOf=t.valueOf))};fabric.util.createClass=o}(),function(){function t(e){var t=Array.prototype.slice.call(arguments,1),n,r,i=t.length;for(r=0;r-1?s(e,t.match(/opacity:\s*(\d?\.?\d*)/)[1]):e;for(var r in t)if(r==="opacity")s(e,t[r]);else{var i=r==="float"||r==="cssFloat"?typeof n.styleFloat=="undefined"?"cssFloat":"styleFloat":r;n[i]=t[r]}return e}var t=fabric.document.createElement("div"),n=typeof t.style.opacity=="string",r=typeof t.style.filter=="string",i=/alpha\s*\(\s*opacity\s*=\s*([^\)]+)\)/,s=function(e){return e};n?s=function(e,t){return e.style.opacity=t,e}:r&&(s=function(e,t){var n=e.style;return e.currentStyle&&!e.currentStyle.hasLayout&&(n.zoom=1),i.test(n.filter)?(t=t>=.9999?"":"alpha(opacity="+t*100+")",n.filter=n.filter.replace(i,t)):n.filter+=" alpha(opacity="+t*100+")",e}),fabric.util.setStyle=e}(),function(){function t(e){return typeof e=="string"?fabric.document.getElementById(e):e}function s(e,t){var n=fabric.document.createElement(e);for(var r in t)r==="class"?n.className=t[r]:r==="for"?n.htmlFor=t[r]:n.setAttribute(r,t[r]);return n}function o(e,t){e&&(" "+e.className+" ").indexOf(" "+t+" ")===-1&&(e.className+=(e.className?" ":"")+t)}function u(e,t,n){return typeof t=="string"&&(t=s(t,n)),e.parentNode&&e.parentNode.replaceChild(t,e),t.appendChild(e),t}function a(e,t){var n,r,i=0,s=0,o=fabric.document.documentElement,u=fabric.document.body||{scrollLeft:0,scrollTop:0};r=e;while(e&&e.parentNode&&!n)e=e.parentNode,e!==fabric.document&&fabric.util.getElementStyle(e,"position")==="fixed"&&(n=e),e!==fabric.document&&r!==t&&fabric.util.getElementStyle(e,"position")==="absolute"?(i=0,s=0):e===fabric.document?(i=u.scrollLeft||o.scrollLeft||0,s=u.scrollTop||o.scrollTop||0):(i+=e.scrollLeft||0,s+=e.scrollTop||0);return{left:i,top:s}}function f(e){var t,n=e&&e.ownerDocument,r={left:0,top:0},i={left:0,top:0},s,o={borderLeftWidth:"left",borderTopWidth:"top",paddingLeft:"left",paddingTop:"top"};if(!n)return{left:0,top:0};for(var u in o)i[o[u]]+=parseInt(l(e,u),10)||0;return t=n.documentElement,typeof e.getBoundingClientRect!="undefined"&&(r=e.getBoundingClientRect()),s=fabric.util.getScrollLeftTop(e,null),{left:r.left+s.left-(t.clientLeft||0)+i.left,top:r.top+s.top-(t.clientTop||0)+i.top}}var e=Array.prototype.slice,n,r=function(t){return e.call(t,0)};try{n=r(fabric.document.childNodes)instanceof Array}catch(i){}n||(r=function(e){var t=new Array(e.length),n=e.length;while(n--)t[n]=e[n];return t});var l;fabric.document.defaultView&&fabric.document.defaultView.getComputedStyle?l=function(e,t){return fabric.document.defaultView.getComputedStyle(e,null)[t]}:l=function(e,t){var n=e.style[t];return!n&&e.currentStyle&&(n=e.currentStyle[t]),n},function(){function n(e){return typeof e.onselectstart!="undefined"&&(e.onselectstart=fabric.util.falseFunction),t?e.style[t]="none":typeof e.unselectable=="string"&&(e.unselectable="on"),e}function r(e){return typeof e.onselectstart!="undefined"&&(e.onselectstart=null),t?e.style[t]="":typeof e.unselectable=="string"&&(e.unselectable=""),e}var e=fabric.document.documentElement.style,t="userSelect"in e?"userSelect":"MozUserSelect"in e?"MozUserSelect":"WebkitUserSelect"in e?"WebkitUserSelect":"KhtmlUserSelect"in e?"KhtmlUserSelect":"";fabric.util.makeElementUnselectable=n,fabric.util.makeElementSelectable=r}(),function(){function e(e,t){var n=fabric.document.getElementsByTagName("head")[0],r=fabric.document.createElement("script"),i=!0;r.onload=r.onreadystatechange=function(e){if(i){if(typeof this.readyState=="string"&&this.readyState!=="loaded"&&this.readyState!=="complete")return;i=!1,t(e||fabric.window.event),r=r.onload=r.onreadystatechange=null}},r.src=e,n.appendChild(r)}fabric.util.getScript=e}(),fabric.util.getById=t,fabric.util.toArray=r,fabric.util.makeElement=s,fabric.util.addClass=o,fabric.util.wrapElement=u,fabric.util.getScrollLeftTop=a,fabric.util.getElementOffset=f,fabric.util.getElementStyle=l}(),function(){function e(e,t){return e+(/\?/.test(e)?"&":"?")+t}function n(){}function r(r,i){i||(i={});var s=i.method?i.method.toUpperCase():"GET",o=i.onComplete||function(){},u=t(),a;return u.onreadystatechange=function(){u.readyState===4&&(o(u),u.onreadystatechange=n)},s==="GET"&&(a=null,typeof i.parameters=="string"&&(r=e(r,i.parameters))),u.open(s,r,!0),(s==="POST"||s==="PUT")&&u.setRequestHeader("Content-Type","application/x-www-form-urlencoded"),u.send(a),u}var t=function(){var e=[function(){return new ActiveXObject("Microsoft.XMLHTTP")},function(){return new ActiveXObject("Msxml2.XMLHTTP")},function(){return new ActiveXObject("Msxml2.XMLHTTP.3.0")},function(){return new XMLHttpRequest}];for(var t=e.length;t--;)try{var n=e[t]();if(n)return e[t]}catch(r){}}();fabric.util.request=r}(),fabric.log=function(){},fabric.warn=function(){},typeof console!="undefined"&&["log","warn"].forEach(function(e){typeof console[e]!="undefined"&&console[e].apply&&(fabric[e]=function(){return console[e].apply(console,arguments)})}),function(){function e(e){n(function(t){e||(e={});var r=t||+(new Date),i=e.duration||500,s=r+i,o,u=e.onChange||function(){},a=e.abort||function(){return!1},f=e.easing||function(e,t,n,r){return-n*Math.cos(e/r*(Math.PI/2))+n+t},l="startValue"in e?e.startValue:0,c="endValue"in e?e.endValue:100,h=e.byValue||c-l;e.onStart&&e.onStart(),function p(t){o=t||+(new Date);var c=o>s?i:o-r;if(a()){e.onComplete&&e.onComplete();return}u(f(c,l,h,i));if(o>s){e.onComplete&&e.onComplete();return}n(p)}(r)})}function n(){return t.apply(fabric.window,arguments)}var t=fabric.window.requestAnimationFrame||fabric.window.webkitRequestAnimationFrame||fabric.window.mozRequestAnimationFrame||fabric.window.oRequestAnimationFrame||fabric.window.msRequestAnimationFrame||function(e){fabric.window.setTimeout(e,1e3/60)};fabric.util.animate=e,fabric.util.requestAnimFrame=n}(),function(){function e(e,t,n,r){return e','')}var t=e.fabric||(e.fabric={}),n=t.util.object.extend,r=t.util.string.capitalize,i=t.util.object.clone,s=t.util.toFixed,o=t.util.multiplyTransformMatrices,u={cx:"left",x:"left",r:"radius",cy:"top",y:"top",display:"visible",visibility:"visible",transform:"transformMatrix","fill-opacity":"fillOpacity","fill-rule":"fillRule","font-family":"fontFamily","font-size":"fontSize","font-style":"fontStyle","font-weight":"fontWeight","stroke-dasharray":"strokeDashArray","stroke-linecap":"strokeLineCap","stroke-linejoin":"strokeLineJoin","stroke-miterlimit":"strokeMiterLimit","stroke-opacity":"strokeOpacity","stroke-width":"strokeWidth","text-decoration":"textDecoration","text-anchor":"originX"},a={stroke:"strokeOpacity",fill:"fillOpacity"};t.parseTransformAttribute=function(){function e(e,t){var n=t[0];e[0]=Math.cos(n),e[1]=Math.sin(n),e[2]=-Math.sin(n),e[3]=Math.cos(n)}function n(e,t){var n=t[0],r=t.length===2?t[1]:t[0];e[0]=n,e[3]=r}function r(e,t){e[2]=t[0]}function i(e,t){e[1]=t[0]}function s(e,t){e[4]=t[0],t.length===2&&(e[5]=t[1])}var o=[1,0,0,1,0,0],u="(?:[-+]?(?:\\d+|\\d*\\.\\d+)(?:e[-+]?\\d+)?)",a="(?:\\s+,?\\s*|,\\s*)",f="(?:(skewX)\\s*\\(\\s*("+u+")\\s*\\))",l="(?:(skewY)\\s*\\(\\s*("+u+")\\s*\\))",c="(?:(rotate)\\s*\\(\\s*("+u+")(?:"+a+"("+u+")"+a+"("+u+"))?\\s*\\))",h="(?:(scale)\\s*\\(\\s*("+u+")(?:"+a+"("+u+"))?\\s*\\))",p="(?:(translate)\\s*\\(\\s*("+u+")(?:"+a+"("+u+"))?\\s*\\))",d="(?:(matrix)\\s*\\(\\s*("+u+")"+a+"("+u+")"+a+"("+u+")"+a+"("+u+")"+a+"("+u+")"+a+"("+u+")"+"\\s*\\))",v="(?:"+d+"|"+p+"|"+h+"|"+c+"|"+f+"|"+l+")",m="(?:"+v+"(?:"+a+v+")*"+")",g="^\\s*(?:"+m+"?)\\s*$",y=new RegExp(g),b=new RegExp(v,"g");return function(u){var a=o.concat(),f=[];if(!u||u&&!y.test(u))return a;u.replace(b,function(u){var l=(new RegExp(v)).exec(u).filter(function(e){return e!==""&&e!=null}),c=l[1],h=l.slice(2).map(parseFloat);switch(c){case"translate":s(a,h);break;case"rotate":h[0]=t.util.degreesToRadians(h[0]),e(a,h);break;case"scale":n(a,h);break;case"skewX":r(a,h);break;case"skewY":i(a,h);break;case"matrix":a=h}f.push(a.concat()),a=o.concat()});var l=f[0];while(f.length>1)f.shift(),l=t.util.multiplyTransformMatrices(l,f[0]);return l}}(),t.parseSVGDocument=function(){function s(e,t){while(e&&(e=e.parentNode))if(t.test(e.nodeName))return!0;return!1}var e=/^(path|circle|polygon|polyline|ellipse|rect|line|image|text)$/,n="(?:[-+]?(?:\\d+|\\d*\\.\\d+)(?:e[-+]?\\d+)?)",r=new RegExp("^\\s*("+n+"+)\\s*,?"+"\\s*("+n+"+)\\s*,?"+"\\s*("+n+"+)\\s*,?"+"\\s*("+n+"+)\\s*"+"$");return function(n,o,u){if(!n)return;var a=new Date;m(n);var f=t.util.toArray(n.getElementsByTagName("*"));if(f.length===0&&t.isLikelyNode){f=n.selectNodes('//*[name(.)!="svg"]');var l=[];for(var c=0,h=f.length;c-1;e=e.split(/\s+/);var n=[],r,i;if(t){r=0,i=e.length;for(;r/i,"")));if(!s||!s.documentElement)return;t.parseSVGDocument(s.documentElement,function(r,i){g.set(e,{objects:t.util.array.invoke(r,"toObject"),options:i}),n(r,i)},r)}e=e.replace(/^\n\s*/,"").trim(),g.has(e,function(r){r?g.get(e,function(e){var t=y(e);n(t.objects,t.options)}):new t.util.request(e,{method:"get",onComplete:i})})},loadSVGFromString:function(e,n,r){e=e.trim();var i;if(typeof DOMParser!="undefined"){var s=new DOMParser;s&&s.parseFromString&&(i=s.parseFromString(e,"text/xml"))}else t.window.ActiveXObject&&(i=new ActiveXObject("Microsoft.XMLDOM"),i.async="false",i.loadXML(e.replace(//i,"")));t.parseSVGDocument(i.documentElement,function(e,t){n(e,t)},r)},createSVGFontFacesMarkup:function(e){var t="";for(var n=0,r=e.length;n',"",""].join("")),t},createSVGRefElementsMarkup +:function(e){var t=[];return b(t,e,"backgroundColor"),b(t,e,"overlayColor"),t.join("")}})}(typeof exports!="undefined"?exports:this),fabric.ElementsParser=function(e,t,n,r){this.elements=e,this.callback=t,this.options=n,this.reviver=r},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 e=0,t=this.elements.length;ee.x&&this.y>e.y},gte:function(e){return this.x>=e.x&&this.y>=e.y},lerp:function(e,t){return new n(this.x+(e.x-this.x)*t,this.y+(e.y-this.y)*t)},distanceFrom:function(e){var t=this.x-e.x,n=this.y-e.y;return Math.sqrt(t*t+n*n)},midPointFrom:function(e){return new n(this.x+(e.x-this.x)/2,this.y+(e.y-this.y)/2)},min:function(e){return new n(Math.min(this.x,e.x),Math.min(this.y,e.y))},max:function(e){return new n(Math.max(this.x,e.x),Math.max(this.y,e.y))},toString:function(){return this.x+","+this.y},setXY:function(e,t){this.x=e,this.y=t},setFromPoint:function(e){this.x=e.x,this.y=e.y},swap:function(e){var t=this.x,n=this.y;this.x=e.x,this.y=e.y,e.x=t,e.y=n}}}(typeof exports!="undefined"?exports:this),function(e){"use strict";function n(e){this.status=e,this.points=[]}var t=e.fabric||(e.fabric={});if(t.Intersection){t.warn("fabric.Intersection is already defined");return}t.Intersection=n,t.Intersection.prototype={appendPoint:function(e){this.points.push(e)},appendPoints:function(e){this.points=this.points.concat(e)}},t.Intersection.intersectLineLine=function(e,r,i,s){var o,u=(s.x-i.x)*(e.y-i.y)-(s.y-i.y)*(e.x-i.x),a=(r.x-e.x)*(e.y-i.y)-(r.y-e.y)*(e.x-i.x),f=(s.y-i.y)*(r.x-e.x)-(s.x-i.x)*(r.y-e.y);if(f!==0){var l=u/f,c=a/f;0<=l&&l<=1&&0<=c&&c<=1?(o=new n("Intersection"),o.points.push(new t.Point(e.x+l*(r.x-e.x),e.y+l*(r.y-e.y)))):o=new n}else u===0||a===0?o=new n("Coincident"):o=new n("Parallel");return o},t.Intersection.intersectLinePolygon=function(e,t,r){var i=new n,s=r.length;for(var o=0;o0&&(i.status="Intersection"),i},t.Intersection.intersectPolygonPolygon=function(e,t){var r=new n,i=e.length;for(var s=0;s0&&(r.status="Intersection"),r},t.Intersection.intersectPolygonRectangle=function(e,r,i){var s=r.min(i),o=r.max(i),u=new t.Point(o.x,s.y),a=new t.Point(s.x,o.y),f=n.intersectLinePolygon(s,u,e),l=n.intersectLinePolygon(u,o,e),c=n.intersectLinePolygon(o,a,e),h=n.intersectLinePolygon(a,s,e),p=new n;return p.appendPoints(f.points),p.appendPoints(l.points),p.appendPoints(c.points),p.appendPoints(h.points),p.points.length>0&&(p.status="Intersection"),p}}(typeof exports!="undefined"?exports:this),function(e){"use strict";function n(e){e?this._tryParsingColor(e):this.setSource([0,0,0,1])}function r(e,t,n){return n<0&&(n+=1),n>1&&(n-=1),n<1/6?e+(t-e)*6*n:n<.5?t:n<2/3?e+(t-e)*(2/3-n)*6:e}var t=e.fabric||(e.fabric={});if(t.Color){t.warn("fabric.Color is already defined.");return}t.Color=n,t.Color.prototype={_tryParsingColor:function(e){var t;e in n.colorNameMap&&(e=n.colorNameMap[e]);if(e==="transparent"){this.setSource([255,255,255,0]);return}t=n.sourceFromHex(e),t||(t=n.sourceFromRgb(e)),t||(t=n.sourceFromHsl(e)),t&&this.setSource(t)},_rgbToHsl:function(e,n,r){e/=255,n/=255,r/=255;var i,s,o,u=t.util.array.max([e,n,r]),a=t.util.array.min([e,n,r]);o=(u+a)/2;if(u===a)i=s=0;else{var f=u-a;s=o>.5?f/(2-u-a):f/(u+a);switch(u){case e:i=(n-r)/f+(n']:this.type==="radial"&&(r=["']);for(var i=0;i');return r.push(this.type==="linear"?"":""),r.join("")},toLive:function(e){var t;if(!this.type)return;this.type==="linear"?t=e.createLinearGradient(this.coords.x1,this.coords.y1,this.coords.x2,this.coords.y2):this.type==="radial"&&(t=e.createRadialGradient(this.coords.x1,this.coords.y1,this.coords.r1,this.coords.x2,this.coords.y2,this.coords.r2));for(var n=0,r=this.colorStops.length;n'+''+""},toLive:function(e){var t=typeof this.source=="function"?this.source():this.source;if(!t)return"";if(typeof t.src!="undefined"){if(!t.complete)return"";if(t.naturalWidth===0||t.naturalHeight===0)return""}return e.createPattern(t,this.repeat)}}),function(e){"use strict";var t=e.fabric||(e.fabric={});if(t.Shadow){t.warn("fabric.Shadow is already defined.");return}t.Shadow=t.util.createClass({color:"rgb(0,0,0)",blur:0,offsetX:0,offsetY:0,affectStroke:!1,includeDefaultValues:!0,initialize:function(e){typeof e=="string"&&(e=this._parseShadow(e));for(var n in e)this[n]=e[n];this.id=t.Object.__uid++},_parseShadow:function(e){var n=e.trim(),r=t.Shadow.reOffsetsAndBlur.exec(n)||[],i=n.replace(t.Shadow.reOffsetsAndBlur,"")||"rgb(0,0,0)";return{color:i.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(e){var t="SourceAlpha";return e&&(e.fill===this.color||e.stroke===this.color)&&(t="SourceGraphic"),''+''+''+""+""+''+""+""},toObject:function(){if(this.includeDefaultValues)return{color:this.color,blur:this.blur,offsetX:this.offsetX,offsetY:this.offsetY};var e={},n=t.Shadow.prototype;return this.color!==n.color&&(e.color=this.color),this.blur!==n.blur&&(e.blur=this.blur),this.offsetX!==n.offsetX&&(e.offsetX=this.offsetX),this.offsetY!==n.offsetY&&(e.offsetY=this.offsetY),e}}),t.Shadow.reOffsetsAndBlur=/(?:\s|^)(-?\d+(?:px)?(?:\s?|$))?(-?\d+(?:px)?(?:\s?|$))?(\d+(?:px)?)?(?:\s?|$)(?:$|\s)/}(typeof exports!="undefined"?exports:this),function(){"use strict";if(fabric.StaticCanvas){fabric.warn("fabric.StaticCanvas is already defined.");return}var e=fabric.util.object.extend,t=fabric.util.getElementOffset,n=fabric.util.removeFromArray,r=new Error("Could not initialize `canvas` element");fabric.StaticCanvas=fabric.util.createClass({initialize:function(e,t){t||(t={}),this._initStatic(e,t),fabric.StaticCanvas.activeInstance=this},backgroundColor:"",backgroundImage:null,overlayColor:"",overlayImage:null,includeDefaultValues:!0,stateful:!0,renderOnAddRemove:!0,clipTo:null,controlsAboveOverlay:!1,allowTouchScrolling:!1,imageSmoothingEnabled:!0,viewportTransform:[1,0,0,1,0,0],onBeforeScaleRotate:function(){},_initStatic:function(e,t){this._objects=[],this._createLowerCanvas(e),this._initOptions(t),this._setImageSmoothing(),t.overlayImage&&this.setOverlayImage(t.overlayImage,this.renderAll.bind(this)),t.backgroundImage&&this.setBackgroundImage(t.backgroundImage,this.renderAll.bind(this)),t.backgroundColor&&this.setBackgroundColor(t.backgroundColor,this.renderAll.bind(this)),t.overlayColor&&this.setOverlayColor(t.overlayColor,this.renderAll.bind(this)),this.calcOffset()},calcOffset:function(){return this._offset=t(this.lowerCanvasEl),this},setOverlayImage:function(e,t,n){return this.__setBgOverlayImage("overlayImage",e,t,n)},setBackgroundImage:function(e,t,n){return this.__setBgOverlayImage("backgroundImage",e,t,n)},setOverlayColor:function(e,t){return this.__setBgOverlayColor("overlayColor",e,t)},setBackgroundColor:function(e,t){return this.__setBgOverlayColor("backgroundColor",e,t)},_setImageSmoothing:function(){var e=this.getContext();e.imageSmoothingEnabled=this.imageSmoothingEnabled,e.webkitImageSmoothingEnabled=this.imageSmoothingEnabled,e.mozImageSmoothingEnabled=this.imageSmoothingEnabled,e.msImageSmoothingEnabled=this.imageSmoothingEnabled,e.oImageSmoothingEnabled=this.imageSmoothingEnabled},__setBgOverlayImage:function(e,t,n,r){return typeof t=="string"?fabric.util.loadImage(t,function(t){this[e]=new fabric.Image(t,r),n&&n()},this):(this[e]=t,n&&n()),this},__setBgOverlayColor:function(e,t,n){if(t&&t.source){var r=this;fabric.util.loadImage(t.source,function(i){r[e]=new fabric.Pattern({source:i,repeat:t.repeat,offsetX:t.offsetX,offsetY:t.offsetY}),n&&n()})}else this[e]=t,n&&n();return this},_createCanvasElement:function(){var e=fabric.document.createElement("canvas");e.style||(e.style={});if(!e)throw r;return this._initCanvasElement(e),e},_initCanvasElement:function(e){fabric.util.createCanvasElement(e);if(typeof e.getContext=="undefined")throw r},_initOptions:function(e){for(var t in e)this[t]=e[t];this.width=this.width||parseInt(this.lowerCanvasEl.width,10)||0,this.height=this.height||parseInt(this.lowerCanvasEl.height,10)||0;if(!this.lowerCanvasEl.style)return;this.lowerCanvasEl.width=this.width,this.lowerCanvasEl.height=this.height,this.lowerCanvasEl.style.width=this.width+"px",this.lowerCanvasEl.style.height=this.height+"px"},_createLowerCanvas:function(e){this.lowerCanvasEl=fabric.util.getById(e)||this._createCanvasElement(),this._initCanvasElement(this.lowerCanvasEl),fabric.util.addClass(this.lowerCanvasEl,"lower-canvas"),this.interactive&&this._applyCanvasStyle(this.lowerCanvasEl),this.contextContainer=this.lowerCanvasEl.getContext("2d")},getWidth:function(){return this.width},getHeight:function(){return this.height},setWidth:function(e){return this._setDimension("width",e)},setHeight:function(e){return this._setDimension("height",e)},setDimensions:function(e){for(var t in e)this._setDimension(t,e[t]);return this},_setDimension:function(e,t){return this.lowerCanvasEl[e]=t,this.lowerCanvasEl.style[e]=t+"px",this.upperCanvasEl&&(this.upperCanvasEl[e]=t,this.upperCanvasEl.style[e]=t+"px"),this.cacheCanvasEl&&(this.cacheCanvasEl[e]=t),this.wrapperEl&&(this.wrapperEl.style[e]=t+"px"),this[e]=t,this.calcOffset(),this.renderAll(),this},getZoom:function(){return Math.sqrt(this.viewportTransform[0]*this.viewportTransform[3])},setViewportTransform:function(e){this.viewportTransform=e,this.renderAll();for(var t=0,n=this._objects.length;t"),n.join("")},_setSVGPreamble:function(e,t){t.suppressPreamble||e.push('','\n')},_setSVGHeader:function(e,t){e.push("',"Created with Fabric.js ",fabric.version,"","",fabric.createSVGFontFacesMarkup(this.getObjects()),fabric.createSVGRefElementsMarkup(this),"")},_setSVGObjects:function(e,t){var n=this.getActiveGroup();n&&this.discardActiveGroup();for(var r=0,i=this.getObjects(),s=i.length;r"):this[t]&&t==="overlayColor"&&e.push('")},sendToBack:function(e){return n(this._objects,e),this._objects.unshift(e),this.renderAll&&this.renderAll()},bringToFront:function(e){return n(this._objects,e),this._objects.push(e),this.renderAll&&this.renderAll()},sendBackwards:function(e,t){var r=this._objects.indexOf(e);if(r!==0){var i=this._findNewLowerIndex(e,r,t);n(this._objects,e),this._objects.splice(i,0,e),this.renderAll&&this.renderAll()}return this},_findNewLowerIndex:function(e,t,n){var r;if(n){r=t;for(var i=t-1;i>=0;--i){var s=e.intersectsWithObject(this._objects[i])||e.isContainedWithinObject(this._objects[i])||this._objects[i].isContainedWithinObject(e);if(s){r=i;break}}}else r=t-1;return r},bringForward:function(e,t){var r=this._objects.indexOf(e);if(r!==this._objects.length-1){var i=this._findNewUpperIndex(e,r,t);n(this._objects,e),this._objects.splice(i,0,e),this.renderAll&&this.renderAll()}return this},_findNewUpperIndex:function(e,t,n){var r;if(n){r=t;for(var i=t+1;i"}}),e(fabric.StaticCanvas.prototype,fabric.Observable),e(fabric.StaticCanvas.prototype,fabric.Collection),e(fabric.StaticCanvas.prototype,fabric.DataURLExporter),e(fabric.StaticCanvas,{EMPTY_JSON:'{"objects": [], "background": "white"}',supports:function(e){var t=fabric.util.createCanvasElement();if(!t||!t.getContext)return null;var n=t.getContext("2d");if(!n)return null;switch(e){case"getImageData":return typeof n.getImageData!="undefined";case"setLineDash":return typeof n.setLineDash!="undefined";case"toDataURL":return typeof t.toDataURL!="undefined";case"toDataURLWithQuality":try{return t.toDataURL("image/jpeg",0),!0}catch(r){}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",setShadow:function(e){return this.shadow=new fabric.Shadow(e),this},_setBrushStyles:function(){var e=this.canvas.contextTop;e.strokeStyle=this.color,e.lineWidth=this.width,e.lineCap=this.strokeLineCap,e.lineJoin=this.strokeLineJoin},_setShadow:function(){if(!this.shadow)return;var e=this.canvas.contextTop;e.shadowColor=this.shadow.color,e.shadowBlur=this.shadow.blur,e.shadowOffsetX=this.shadow.offsetX,e.shadowOffsetY=this.shadow.offsetY},_resetShadow:function(){var e=this.canvas.contextTop;e.shadowColor="",e.shadowBlur=e.shadowOffsetX=e.shadowOffsetY=0}}),function(){var e=fabric.util.array.min,t=fabric.util.array.max;fabric.PencilBrush=fabric.util.createClass(fabric.BaseBrush,{initialize:function(e){this.canvas=e,this._points=[]},onMouseDown:function(e){this._prepareForDrawing(e),this._captureDrawingPath(e),this._render()},onMouseMove:function(e){this._captureDrawingPath(e),this.canvas.clearContext(this.canvas.contextTop),this._render()},onMouseUp:function(){this._finalizeAndAddPath()},_prepareForDrawing:function(e){var t=new fabric.Point(e.x,e.y);this._reset(),this._addPoint(t),this.canvas.contextTop.moveTo(t.x,t.y)},_addPoint:function(e){this._points.push(e)},_reset:function(){this._points.length=0,this._setBrushStyles(),this._setShadow()},_captureDrawingPath:function(e){var t=new fabric.Point(e.x,e.y);this._addPoint(t)},_render:function(){var e=this.canvas.contextTop,t=this.canvas.viewportTransform;e.save(),e.transform(t[0],t[1],t[2],t[3],t[4],t[5]),e.beginPath();var n=this._points[0],r=this._points[1];this._points.length===2&&n.x===r.x&&n.y===r.y&&(n.x-=.5,r.x+=.5),e.moveTo(n.x,n.y);for(var i=1,s=this._points.length;in.padding?e.x<0?e.x+=n.padding:e.x-=n.padding:e.x=0,i(e.y)>n.padding?e.y<0?e.y+=n.padding:e.y-=n.padding:e.y=0},_rotateObject:function(e,t){var i=this._currentTransform;if(i.target.get("lockRotation"))return;var s=r(i.ey-i.top,i.ex-i.left),o=r(t-i.top,e-i.left),u=n(o-s+i.theta);u<0&&(u=360+u),i.target.angle=u},setCursor:function(e){this.upperCanvasEl.style.cursor=e},_resetObjectTransform:function(e){e.scaleX=1,e.scaleY=1,e.setAngle(0)},_drawSelection:function(){var e=this.contextTop,t=this._groupSelector,n=t.left,r=t.top,o=i(n),u=i(r);e.fillStyle=this.selectionColor,e.fillRect(t.ex-(n>0?0:-n),t.ey-(r>0?0:-r),o,u),e.lineWidth=this.selectionLineWidth,e.strokeStyle=this.selectionBorderColor;if(this.selectionDashArray.length>1){var a=t.ex+s-(n>0?0:o),f=t.ey+s-(r>0?0:u);e.beginPath(),fabric.util.drawDashedLine(e,a,f,a+o,f,this.selectionDashArray),fabric.util.drawDashedLine(e,a,f+u-1,a+o,f+u-1,this.selectionDashArray),fabric.util.drawDashedLine(e,a,f,a,f+u,this.selectionDashArray),fabric.util.drawDashedLine(e,a+o-1,f,a+o-1,f+u,this.selectionDashArray),e.closePath(),e.stroke()}else e.strokeRect(t.ex+s-(n>0?0:o),t.ey+s-(r>0?0:u),o,u)},_isLastRenderedObject:function(e){return this.controlsAboveOverlay&&this.lastRenderedObjectWithControlsAboveOverlay&&this.lastRenderedObjectWithControlsAboveOverlay.visible&&this.containsPoint(e,this.lastRenderedObjectWithControlsAboveOverlay)&&this.lastRenderedObjectWithControlsAboveOverlay._findTargetCorner(this.getPointer(e,!0))},findTarget:function(e,t){if(this.skipTargetFind)return;if(this._isLastRenderedObject(e))return this.lastRenderedObjectWithControlsAboveOverlay;var n=this.getActiveGroup();if(n&&!t&&this.containsPoint(e,n))return n;var r=this._searchPossibleTargets(e);return this._fireOverOutEvents(r),r},_fireOverOutEvents:function(e){e?this._hoveredTarget!==e&&(this.fire("mouse:over",{target:e}),e.fire("mouseover"),this._hoveredTarget&&(this.fire("mouse:out",{target:this._hoveredTarget}),this._hoveredTarget.fire("mouseout")),this._hoveredTarget=e):this._hoveredTarget&&(this.fire("mouse:out",{target:this._hoveredTarget}),this._hoveredTarget.fire("mouseout"),this._hoveredTarget=null)},_checkTarget:function(e,t,n){if(t&&t.visible&&t.evented&&this.containsPoint(e,t)){if(!this.perPixelTargetFind&&!t.perPixelTargetFind||!!t.isEditing)return!0;var r=this.isTargetTransparent(t,n.x,n.y);if(!r)return!0}},_searchPossibleTargets:function(e){var t,n=this.getPointer(e,!0),r=this._objects.length;while(r--)if(this._checkTarget(e,this._objects[r],n)){this.relatedTarget=this._objects[r],t=this._objects[r];break}return t},getPointer:function(t,n,r){r||(r=this.upperCanvasEl);var i=e(t,r),s=r.getBoundingClientRect(),o;return i.x=i.x-this._offset.left,i.y=i.y-this._offset.top,n||(i=fabric.util.transformPoint(i,fabric.util.invertTransform(this.viewportTransform))),s.width===0||s.height===0?o={width:1,height:1}:o={width:r.width/s.width,height:r.height/s.height},{x:i.x*o.width,y:i.y*o.height}},_createUpperCanvas:function(){var e=this.lowerCanvasEl.className.replace(/\s*lower-canvas\s*/,"");this.upperCanvasEl=this._createCanvasElement(),fabric.util.addClass(this.upperCanvasEl,"upper-canvas "+e),this.wrapperEl.appendChild(this.upperCanvasEl),this._copyCanvasStyle(this.lowerCanvasEl,this.upperCanvasEl),this._applyCanvasStyle(this.upperCanvasEl),this.contextTop=this.upperCanvasEl.getContext("2d")},_createCacheCanvas:function(){this.cacheCanvasEl=this._createCanvasElement(),this.cacheCanvasEl.setAttribute("width",this.width),this.cacheCanvasEl.setAttribute("height",this.height),this.contextCache=this.cacheCanvasEl.getContext("2d")},_initWrapperElement:function(){this.wrapperEl=fabric.util.wrapElement(this.lowerCanvasEl,"div",{"class":this.containerClass}),fabric.util.setStyle(this.wrapperEl,{width:this.getWidth()+"px",height:this.getHeight()+"px",position:"relative"}),fabric.util.makeElementUnselectable(this.wrapperEl)},_applyCanvasStyle:function(e){var t=this.getWidth()||e.width,n=this.getHeight()||e.height;fabric.util.setStyle(e,{position:"absolute",width:t+"px",height:n+"px",left:0,top:0}),e.width=t,e.height=n,fabric.util.makeElementUnselectable(e)},_copyCanvasStyle:function(e,t){t.style.cssText=e.style.cssText},getSelectionContext:function(){return this.contextTop},getSelectionElement:function(){return this.upperCanvasEl},_setActiveObject:function(e){this._activeObject&&this._activeObject.set("active",!1),this._activeObject=e,e.set("active",!0)},setActiveObject:function(e,t){return this._setActiveObject(e),this.renderAll(),this.fire("object:selected",{target:e,e:t}),e.fire("selected",{e:t}),this},getActiveObject:function(){return this._activeObject},_discardActiveObject:function(){this._activeObject&&this._activeObject.set("active",!1),this._activeObject=null},discardActiveObject:function(e){return this._discardActiveObject(),this.renderAll(),this.fire("selection:cleared",{e:e}),this},_setActiveGroup:function(e){this._activeGroup=e,e&&e.set("active",!0)},setActiveGroup:function(e,t){return this._setActiveGroup(e),e&&(this.fire("object:selected",{target:e,e:t}),e.fire("selected",{e:t})),this},getActiveGroup:function(){return this._activeGroup},_discardActiveGroup:function(){var e=this.getActiveGroup();e&&e.destroy(),this.setActiveGroup(null)},discardActiveGroup:function(e){return this._discardActiveGroup(),this.fire("selection:cleared",{e:e}),this},deactivateAll:function(){var e=this.getObjects(),t=0,n=e.length;for(;t1&&(t=new fabric.Group(t.reverse(),{originX:"center",originY:"center",canvas:this}),t.addWithUpdate(),this.setActiveGroup(t,e),t.saveCoords(),this.fire("selection:created",{target:t}),this.renderAll())},_collectObjects:function(){var n=[],r,i=this._groupSelector.ex,s=this._groupSelector.ey,o=i+this._groupSelector.left,u=s+this._groupSelector.top,a=new fabric.Point(e(i,o),e(s,u)),f=new fabric.Point(t(i,o),t(s,u)),l=i===o&&s===u;for(var c=this._objects.length;c--;){r=this._objects[c];if(!r||!r.selectable||!r.visible)continue;if(r.intersectsWithRect(a,f)||r.isContainedWithinRect(a,f)||r.containsPoint(a)||r.containsPoint(f)){r.set("active",!0),n.push(r);if(l)break}}return n},_maybeGroupObjects:function(e){this.selection&&this._groupSelector&&this._groupSelectedObjects(e);var t=this.getActiveGroup();t&&(t.setObjectsCoords().setCoords(),t.isMoving=!1,this.setCursor(this.defaultCursor)),this._groupSelector=null,this._currentTransform=null}})}(),fabric.util.object.extend(fabric.StaticCanvas.prototype,{toDataURL:function(e){e||(e={});var t=e.format||"png",n=e.quality||1,r=e.multiplier||1,i={left:e.left,top:e.top,width:e.width,height:e.height};return r!==1?this.__toDataURLWithMultiplier(t,n,i,r):this.__toDataURL(t,n,i)},__toDataURL:function(e,t,n){this.renderAll(!0);var r=this.upperCanvasEl||this.lowerCanvasEl,i=this.__getCroppedCanvas(r,n);e==="jpg"&&(e="jpeg");var s=fabric.StaticCanvas.supports("toDataURLWithQuality")?(i||r).toDataURL("image/"+e,t):(i||r).toDataURL("image/"+e);return this.contextTop&&this.clearContext(this.contextTop),this.renderAll(),i&&(i=null),s},__getCroppedCanvas:function(e,t){var n,r,i="left"in t||"top"in t||"width"in t||"height"in t;return i&&(n=fabric.util.createCanvasElement(),r=n.getContext("2d"),n.width=t.width||this.width,n.height=t.height||this.height,r.drawImage(e,-t.left||0,-t.top||0)),n},__toDataURLWithMultiplier:function(e,t,n,r){var i=this.getWidth(),s=this.getHeight(),o=i*r,u=s*r,a=this.getActiveObject(),f=this.getActiveGroup(),l=this.contextTop||this.contextContainer;r>1&&this.setWidth(o).setHeight(u),l.scale(r,r),n.left&&(n.left*=r),n.top&&(n.top*=r),n.width?n.width*=r:r<1&&(n.width=o),n.height?n.height*=r:r<1&&(n.height=u),f?this._tempRemoveBordersControlsFromGroup(f):a&&this.deactivateAll&&this.deactivateAll(),this.renderAll(!0);var c=this.__toDataURL(e,t,n);return this.width=i,this.height=s,l.scale(1/r,1/r),this.setWidth(i).setHeight(s),f?this._restoreBordersControlsOnGroup(f):a&&this.setActiveObject&&this.setActiveObject(a),this.contextTop&&this.clearContext(this.contextTop),this.renderAll(),c},toDataURLWithMultiplier:function(e,t,n){return this.toDataURL({format:e,multiplier:t,quality:n})},_tempRemoveBordersControlsFromGroup:function(e){e.origHasControls=e.hasControls,e.origBorderColor=e.borderColor,e.hasControls=!0,e.borderColor="rgba(0,0,0,0)",e.forEachObject(function(e){e.origBorderColor=e.borderColor,e.borderColor="rgba(0,0,0,0)"})},_restoreBordersControlsOnGroup:function(e){e.hideControls=e.origHideControls,e.borderColor=e.origBorderColor,e.forEachObject(function(e){e.borderColor=e.origBorderColor,delete e.origBorderColor})}}),fabric.util.object.extend(fabric.StaticCanvas.prototype,{loadFromDatalessJSON:function(e,t,n){return this.loadFromJSON(e,t,n)},loadFromJSON:function(e,t,n){if(!e)return;var r=typeof e=="string"?JSON.parse(e):e;this.clear();var i=this;return this._enlivenObjects(r.objects,function(){i._setBgOverlay(r,t)},n),this},_setBgOverlay:function(e,t){var n=this,r={backgroundColor:!1,overlayColor:!1,backgroundImage:!1,overlayImage:!1};if(!e.backgroundImage&&!e.overlayImage&&!e.background&&!e.overlay){t&&t();return}var i=function(){r.backgroundImage&&r.overlayImage&&r.backgroundColor&&r.overlayColor&&(n.renderAll(),t&&t())};this.__setBgOverlay("backgroundImage",e.backgroundImage,r,i),this.__setBgOverlay("overlayImage",e.overlayImage,r,i),this.__setBgOverlay("backgroundColor",e.background,r,i),this.__setBgOverlay("overlayColor",e.overlay,r,i),i()},__setBgOverlay:function(e,t,n,r){var i=this;if(!t){n[e]=!0;return}e==="backgroundImage"||e==="overlayImage"?fabric.Image.fromObject(t,function(t){i[e]=t,n[e]=!0,r&&r()}):this["set"+fabric.util.string.capitalize(e,!0)](t,function(){n[e]=!0,r&&r()})},_enlivenObjects:function(e,t,n){var r=this;if(!e||e.length===0){t&&t();return}var i=this.renderOnAddRemove;this.renderOnAddRemove=!1,fabric.util.enlivenObjects(e,function(e){e.forEach(function(e,t){r.insertAt(e,t,!0)}),r.renderOnAddRemove=i,t&&t()},null,n)},_toDataURL:function(e,t){this.clone(function(n){t(n.toDataURL(e))})},_toDataURLWithMultiplier:function(e,t,n){this.clone(function( +r){n(r.toDataURLWithMultiplier(e,t))})},clone:function(e,t){var n=JSON.stringify(this.toJSON(t));this.cloneWithoutData(function(t){t.loadFromJSON(n,function(){e&&e(t)})})},cloneWithoutData:function(e){var t=fabric.document.createElement("canvas");t.width=this.getWidth(),t.height=this.getHeight();var n=new fabric.Canvas(t);n.clipTo=this.clipTo,this.backgroundImage?(n.setBackgroundImage(this.backgroundImage.src,function(){n.renderAll(),e&&e(n)}),n.backgroundImageOpacity=this.backgroundImageOpacity,n.backgroundImageStretch=this.backgroundImageStretch):e&&e(n)}}),function(e){"use strict";var t=e.fabric||(e.fabric={}),n=t.util.object.extend,r=t.util.toFixed,i=t.util.string.capitalize,s=t.util.degreesToRadians,o=t.StaticCanvas.supports("setLineDash");if(t.Object)return;t.Object=t.util.createClass({type:"object",originX:"left",originY:"top",top:0,left:0,width:0,height:0,scaleX:1,scaleY:1,flipX:!1,flipY:!1,opacity:1,angle:0,cornerSize:12,transparentCorners:!0,hoverCursor:null,padding:0,borderColor:"rgba(102,153,255,0.75)",cornerColor:"rgba(102,153,255,0.5)",centeredScaling:!1,centeredRotation:!0,fill:"rgb(0,0,0)",fillRule:"source-over",backgroundColor:"",stroke:null,strokeWidth:1,strokeDashArray:null,strokeLineCap:"butt",strokeLineJoin:"miter",strokeMiterLimit:10,shadow:null,borderOpacityWhenMoving:.4,borderScaleFactor:1,transformMatrix:null,minScaleLimit:.01,selectable:!0,evented:!0,visible:!0,hasControls:!0,hasBorders:!0,hasRotatingPoint:!0,rotatingPointOffset:40,perPixelTargetFind:!1,includeDefaultValues:!0,clipTo:null,lockMovementX:!1,lockMovementY:!1,lockRotation:!1,lockScalingX:!1,lockScalingY:!1,lockUniScaling:!1,stateProperties:"top left width height scaleX scaleY flipX flipY originX originY transformMatrix stroke strokeWidth strokeDashArray strokeLineCap strokeLineJoin strokeMiterLimit angle opacity fill fillRule shadow clipTo visible backgroundColor".split(" "),initialize:function(e){e&&this.setOptions(e)},_initGradient:function(e){e.fill&&e.fill.colorStops&&!(e.fill instanceof t.Gradient)&&this.set("fill",new t.Gradient(e.fill))},_initPattern:function(e){e.fill&&e.fill.source&&!(e.fill instanceof t.Pattern)&&this.set("fill",new t.Pattern(e.fill)),e.stroke&&e.stroke.source&&!(e.stroke instanceof t.Pattern)&&this.set("stroke",new t.Pattern(e.stroke))},_initClipping:function(e){if(!e.clipTo||typeof e.clipTo!="string")return;var n=t.util.getFunctionBody(e.clipTo);typeof n!="undefined"&&(this.clipTo=new Function("ctx",n))},setOptions:function(e){for(var t in e)this.set(t,e[t]);this._initGradient(e),this._initPattern(e),this._initClipping(e)},transform:function(e,t){this.group&&this.group.transform(e,t),e.globalAlpha=this.opacity;var n=t?this._getLeftTopCoords():this.getCenterPoint();e.translate(n.x,n.y),e.rotate(s(this.angle)),e.scale(this.scaleX*(this.flipX?-1:1),this.scaleY*(this.flipY?-1:1))},toObject:function(e){var n=t.Object.NUM_FRACTION_DIGITS,i={type:this.type,originX:this.originX,originY:this.originY,left:r(this.left,n),top:r(this.top,n),width:r(this.width,n),height:r(this.height,n),fill:this.fill&&this.fill.toObject?this.fill.toObject():this.fill,stroke:this.stroke&&this.stroke.toObject?this.stroke.toObject():this.stroke,strokeWidth:r(this.strokeWidth,n),strokeDashArray:this.strokeDashArray,strokeLineCap:this.strokeLineCap,strokeLineJoin:this.strokeLineJoin,strokeMiterLimit:r(this.strokeMiterLimit,n),scaleX:r(this.scaleX,n),scaleY:r(this.scaleY,n),angle:r(this.getAngle(),n),flipX:this.flipX,flipY:this.flipY,opacity:r(this.opacity,n),shadow:this.shadow&&this.shadow.toObject?this.shadow.toObject():this.shadow,visible:this.visible,clipTo:this.clipTo&&String(this.clipTo),backgroundColor:this.backgroundColor};return this.includeDefaultValues||(i=this._removeDefaultValues(i)),t.util.populateWithProperties(this,i,e),i},toDatalessObject:function(e){return this.toObject(e)},_removeDefaultValues:function(e){var n=t.util.getKlass(e.type).prototype,r=n.stateProperties;return r.forEach(function(t){e[t]===n[t]&&delete e[t]}),e},toString:function(){return"#"},get:function(e){return this[e]},_setObject:function(e){for(var t in e)this._set(t,e[t])},set:function(e,t){return typeof e=="object"?this._setObject(e):typeof t=="function"&&e!=="clipTo"?this._set(e,t(this.get(e))):this._set(e,t),this},_set:function(e,n){var i=e==="scaleX"||e==="scaleY";return i&&(n=this._constrainScale(n)),e==="scaleX"&&n<0?(this.flipX=!this.flipX,n*=-1):e==="scaleY"&&n<0?(this.flipY=!this.flipY,n*=-1):e==="width"||e==="height"?this.minScaleLimit=r(Math.min(.1,1/Math.max(this.width,this.height)),2):e==="shadow"&&n&&!(n instanceof t.Shadow)&&(n=new t.Shadow(n)),this[e]=n,this},toggle:function(e){var t=this.get(e);return typeof t=="boolean"&&this.set(e,!t),this},setSourcePath:function(e){return this.sourcePath=e,this},getViewportTransform:function(){return this.canvas&&this.canvas.viewportTransform?this.canvas.viewportTransform:[1,0,0,1,0,0]},render:function(e,n){if(this.width===0||this.height===0||!this.visible)return;e.save(),this._setupFillRule(e),this._transform(e,n),this._setStrokeStyles(e),this._setFillStyles(e);var r=this.transformMatrix;r&&this.group&&(e.translate(-this.group.width/2,-this.group.height/2),e.transform(r[0],r[1],r[2],r[3],r[4],r[5])),this._setShadow(e),this.clipTo&&t.util.clipContext(this,e),this._render(e,n),this.clipTo&&e.restore(),this._removeShadow(e),this._restoreFillRule(e),e.restore()},_transform:function(e,t){var n=this.transformMatrix;n&&!this.group&&e.setTransform(n[0],n[1],n[2],n[3],n[4],n[5]),t||this.transform(e)},_setStrokeStyles:function(e){this.stroke&&(e.lineWidth=this.strokeWidth,e.lineCap=this.strokeLineCap,e.lineJoin=this.strokeLineJoin,e.miterLimit=this.strokeMiterLimit,e.strokeStyle=this.stroke.toLive?this.stroke.toLive(e):this.stroke)},_setFillStyles:function(e){this.fill&&(e.fillStyle=this.fill.toLive?this.fill.toLive(e):this.fill)},_renderControls:function(e,n){var r=this.getViewportTransform();e.save();if(this.active&&!n){var i;this.group&&(i=t.util.transformPoint(this.group.getCenterPoint(),r),e.translate(i.x,i.y),e.rotate(s(this.group.angle))),i=t.util.transformPoint(this.getCenterPoint(),r,null!=this.group),this.group&&(i.x*=this.group.scaleX,i.y*=this.group.scaleY),e.translate(i.x,i.y),e.rotate(s(this.angle)),this.drawBorders(e),this.drawControls(e)}e.restore()},_setShadow:function(e){if(!this.shadow)return;e.shadowColor=this.shadow.color,e.shadowBlur=this.shadow.blur,e.shadowOffsetX=this.shadow.offsetX,e.shadowOffsetY=this.shadow.offsetY},_removeShadow:function(e){if(!this.shadow)return;e.shadowColor="",e.shadowBlur=e.shadowOffsetX=e.shadowOffsetY=0},_renderFill:function(e){if(!this.fill)return;this.fill.toLive&&(e.save(),e.translate(-this.width/2+this.fill.offsetX||0,-this.height/2+this.fill.offsetY||0)),this.fillRule==="destination-over"?e.fill("evenodd"):e.fill(),this.fill.toLive&&e.restore(),this.shadow&&!this.shadow.affectStroke&&this._removeShadow(e)},_renderStroke:function(e){if(!this.stroke)return;e.save(),this.strokeDashArray?(1&this.strokeDashArray.length&&this.strokeDashArray.push.apply(this.strokeDashArray,this.strokeDashArray),o?(e.setLineDash(this.strokeDashArray),this._stroke&&this._stroke(e)):this._renderDashedStroke&&this._renderDashedStroke(e),e.stroke()):this._stroke?this._stroke(e):e.stroke(),this._removeShadow(e),e.restore()},clone:function(e,n){return this.constructor.fromObject?this.constructor.fromObject(this.toObject(n),e):new t.Object(this.toObject(n))},cloneAsImage:function(e){var n=this.toDataURL();return t.util.loadImage(n,function(n){e&&e(new t.Image(n))}),this},toDataURL:function(e){e||(e={});var n=t.util.createCanvasElement(),r=this.getBoundingRect();n.width=r.width,n.height=r.height,t.util.wrapElement(n,"div");var i=new t.Canvas(n);e.format==="jpg"&&(e.format="jpeg"),e.format==="jpeg"&&(i.backgroundColor="#fff");var s={active:this.get("active"),left:this.getLeft(),top:this.getTop()};this.set("active",!1),this.setPositionByOrigin(new t.Point(n.width/2,n.height/2),"center","center");var o=this.canvas;i.add(this);var u=i.toDataURL(e);return this.set(s).setCoords(),this.canvas=o,i.dispose(),i=null,u},isType:function(e){return this.type===e},complexity:function(){return 0},toJSON:function(e){return this.toObject(e)},setGradient:function(e,n){n||(n={});var r={colorStops:[]};r.type=n.type||(n.r1||n.r2?"radial":"linear"),r.coords={x1:n.x1,y1:n.y1,x2:n.x2,y2:n.y2};if(n.r1||n.r2)r.coords.r1=n.r1,r.coords.r2=n.r2;for(var i in n.colorStops){var s=new t.Color(n.colorStops[i]);r.colorStops.push({offset:i,color:s.toRgb(),opacity:s.getAlpha()})}return this.set(e,t.Gradient.forObject(this,r))},setPatternFill:function(e){return this.set("fill",new t.Pattern(e))},setShadow:function(e){return this.set("shadow",e?new t.Shadow(e):null)},setColor:function(e){return this.set("fill",e),this},setAngle:function(e){var t=(this.originX!=="center"||this.originY!=="center")&&this.centeredRotation;return t&&this._setOriginToCenter(),this.set("angle",e),t&&this._resetOrigin(),this},centerH:function(){return this.canvas.centerObjectH(this),this},centerV:function(){return this.canvas.centerObjectV(this),this},center:function(){return this.canvas.centerObject(this),this},remove:function(){return this.canvas.remove(this),this},getLocalPointer:function(e,t){t=t||this.canvas.getPointer(e);var n=this.translateToOriginPoint(this.getCenterPoint(),"left","top");return{x:t.x-n.x,y:t.y-n.y}},_setupFillRule:function(e){this.fillRule&&(this._prevFillRule=e.globalCompositeOperation,e.globalCompositeOperation=this.fillRule)},_restoreFillRule:function(e){this.fillRule&&this._prevFillRule&&(e.globalCompositeOperation=this._prevFillRule)}}),t.util.createAccessors(t.Object),t.Object.prototype.rotate=t.Object.prototype.setAngle,n(t.Object.prototype,t.Observable),t.Object.NUM_FRACTION_DIGITS=2,t.Object.__uid=0}(typeof exports!="undefined"?exports:this),function(){var e=fabric.util.degreesToRadians;fabric.util.object.extend(fabric.Object.prototype,{translateToCenterPoint:function(t,n,r){var i=t.x,s=t.y,o=this.stroke?this.strokeWidth:0;return n==="left"?i=t.x+(this.getWidth()+o*this.scaleX)/2:n==="right"&&(i=t.x-(this.getWidth()+o*this.scaleX)/2),r==="top"?s=t.y+(this.getHeight()+o*this.scaleY)/2:r==="bottom"&&(s=t.y-(this.getHeight()+o*this.scaleY)/2),fabric.util.rotatePoint(new fabric.Point(i,s),t,e(this.angle))},translateToOriginPoint:function(t,n,r){var i=t.x,s=t.y,o=this.stroke?this.strokeWidth:0;return n==="left"?i=t.x-(this.getWidth()+o*this.scaleX)/2:n==="right"&&(i=t.x+(this.getWidth()+o*this.scaleX)/2),r==="top"?s=t.y-(this.getHeight()+o*this.scaleY)/2:r==="bottom"&&(s=t.y+(this.getHeight()+o*this.scaleY)/2),fabric.util.rotatePoint(new fabric.Point(i,s),t,e(this.angle))},getCenterPoint:function(){var e=new fabric.Point(this.left,this.top);return this.translateToCenterPoint(e,this.originX,this.originY)},getPointByOrigin:function(e,t){var n=this.getCenterPoint();return this.translateToOriginPoint(n,e,t)},toLocalPoint:function(t,n,r){var i=this.getCenterPoint(),s=this.stroke?this.strokeWidth:0,o,u;return n&&r?(n==="left"?o=i.x-(this.getWidth()+s*this.scaleX)/2:n==="right"?o=i.x+(this.getWidth()+s*this.scaleX)/2:o=i.x,r==="top"?u=i.y-(this.getHeight()+s*this.scaleY)/2:r==="bottom"?u=i.y+(this.getHeight()+s*this.scaleY)/2:u=i.y):(o=this.left,u=this.top),fabric.util.rotatePoint(new fabric.Point(t.x,t.y),i,-e(this.angle)).subtractEquals(new fabric.Point(o,u))},setPositionByOrigin:function(e,t,n){var r=this.translateToCenterPoint(e,t,n),i=this.translateToOriginPoint(r,this.originX,this.originY);this.set("left",i.x),this.set("top",i.y)},adjustPosition:function(t){var n=e(this.angle),r=this.getWidth()/2,i=Math.cos(n)*r,s=Math.sin(n)*r,o=this.getWidth(),u=Math.cos(n)*o,a=Math.sin(n)*o;this.originX==="center"&&t==="left"||this.originX==="right"&&t==="center"?(this.left-=i,this.top-=s):this.originX==="left"&&t==="center"||this.originX==="center"&&t==="right"?(this.left+=i,this.top+=s):this.originX==="left"&&t==="right"?(this.left+=u,this.top+=a):this.originX==="right"&&t==="left"&&(this.left-=u,this.top-=a),this.setCoords(),this.originX=t},_setOriginToCenter:function(){this._originalOriginX=this.originX,this._originalOriginY=this.originY;var e=this.getCenterPoint();this.originX="center",this.originY="center",this.left=e.x,this.top=e.y},_resetOrigin:function(){var e=this.translateToOriginPoint(this.getCenterPoint(),this._originalOriginX,this._originalOriginY);this.originX=this._originalOriginX,this.originY=this._originalOriginY,this.left=e.x,this.top=e.y,this._originalOriginX=null,this._originalOriginY=null},_getLeftTopCoords:function(){return this.translateToOriginPoint(this.getCenterPoint(),"left","center")}})}(),function(){var e=fabric.util.degreesToRadians;fabric.util.object.extend(fabric.Object.prototype,{oCoords:null,intersectsWithRect:function(e,t){var n=this.oCoords,r=new fabric.Point(n.tl.x,n.tl.y),i=new fabric.Point(n.tr.x,n.tr.y),s=new fabric.Point(n.bl.x,n.bl.y),o=new fabric.Point(n.br.x,n.br.y),u=fabric.Intersection.intersectPolygonRectangle([r,i,o,s],e,t);return u.status==="Intersection"},intersectsWithObject:function(e){function t(e){return{tl:new fabric.Point(e.tl.x,e.tl.y),tr:new fabric.Point(e.tr.x,e.tr.y),bl:new fabric.Point(e.bl.x,e.bl.y),br:new fabric.Point(e.br.x,e.br.y)}}var n=t(this.oCoords),r=t(e.oCoords),i=fabric.Intersection.intersectPolygonPolygon([n.tl,n.tr,n.br,n.bl],[r.tl,r.tr,r.br,r.bl]);return i.status==="Intersection"},isContainedWithinObject:function(e){var t=e.getBoundingRect(),n=new fabric.Point(t.left,t.top),r=new fabric.Point(t.left+t.width,t.top+t.height);return this.isContainedWithinRect(n,r)},isContainedWithinRect:function(e,t){var n=this.getBoundingRect();return n.left>=e.x&&n.left+n.width<=t.x&&n.top>=e.y&&n.top+n.height<=t.y},containsPoint:function(e){var t=this._getImageLines(this.oCoords),n=this._findCrossPoints(e,t);return n!==0&&n%2===1},_getImageLines:function(e){return{topline:{o:e.tl,d:e.tr},rightline:{o:e.tr,d:e.br},bottomline:{o:e.br,d:e.bl},leftline:{o:e.bl,d:e.tl}}},_findCrossPoints:function(e,t){var n,r,i,s,o,u,a=0,f;for(var l in t){f=t[l];if(f.o.y=e.y&&f.d.y>=e.y)continue;f.o.x===f.d.x&&f.o.x>=e.x?(o=f.o.x,u=e.y):(n=0,r=(f.d.y-f.o.y)/(f.d.x-f.o.x),i=e.y-n*e.x,s=f.o.y-r*f.o.x,o=-(i-s)/(n-r),u=i+n*o),o>=e.x&&(a+=1);if(a===2)break}return a},getBoundingRectWidth:function(){return this.getBoundingRect().width},getBoundingRectHeight:function(){return this.getBoundingRect().height},getBoundingRect:function(){this.oCoords||this.setCoords();var e=[this.oCoords.tl.x,this.oCoords.tr.x,this.oCoords.br.x,this.oCoords.bl.x],t=fabric.util.array.min(e),n=fabric.util.array.max(e),r=Math.abs(t-n),i=[this.oCoords.tl.y,this.oCoords.tr.y,this.oCoords.br.y,this.oCoords.bl.y],s=fabric.util.array.min(i),o=fabric.util.array.max(i),u=Math.abs(s-o);return{left:t,top:s,width:r,height:u}},getWidth:function(){return this.width*this.scaleX},getHeight:function(){return this.height*this.scaleY},_constrainScale:function(e){return Math.abs(e)1?this.strokeWidth:0,n=e(this.angle),r=this.getViewportTransform(),i=function(e){return fabric.util.transformPoint(e,r)};this.currentWidth=(this.width+t)*this.scaleX,this.currentHeight=(this.height+t)*this.scaleY,this.currentWidth<0&&(this.currentWidth=Math.abs(this.currentWidth));var s=Math.sqrt(Math.pow(this.currentWidth/2,2)+Math.pow(this.currentHeight/2,2)),o=Math.atan(isFinite(this.currentHeight/this.currentWidth)?this.currentHeight/this.currentWidth:0),u=Math.cos(o+n)*s,a=Math.sin(o+n)*s,f=Math.sin(n),l=Math.cos(n),c=this.getCenterPoint(),h=new fabric.Point(this.currentWidth,this.currentHeight),p=new fabric.Point(c.x-u,c.y-a),d=new fabric.Point(p.x+h.x*l,p.y+h.x*f),v=new fabric.Point(p.x-h.y*f,p.y+h.y*l),m=new fabric.Point(p.x+h.x/2*l,p.y+h.x/2*f),g=i(p),y=i(d),b=i(new fabric.Point(d.x-h.y*f,d.y+h.y*l)),w=i(v),E=i(new fabric.Point(p.x-h.y/2*f,p.y+h.y/2*l)),S=i(m),x=i(new fabric.Point(d.x-h.y/2*f,d.y+h.y/2*l)),T=i(new fabric.Point(v.x+h.x/2*l,v.y+h.x/2*f)),N=i(new fabric.Point(m.x,m.y)),C=Math.cos(o+n)*this.padding*Math.sqrt(2),k=Math.sin(o+n)*this.padding*Math.sqrt(2);return g=g.add(new fabric.Point(-C,-k)),y=y.add(new fabric.Point(k,-C)),b=b.add(new fabric.Point(C,k)),w=w.add(new fabric.Point(-k,C)),E=E.add(new fabric.Point((-C-k)/2,(-k+C)/2)),S=S.add(new fabric.Point((k-C)/2,-(k+C)/2)),x=x.add(new fabric.Point((k+C)/2,(k-C)/2)),T=T.add(new fabric.Point((C-k)/2,(C+k)/2)),N=N.add(new fabric.Point((k-C)/2,-(k+C)/2)),this.oCoords={tl:g,tr:y,br:b,bl:w,ml:E,mt:S,mr:x,mb:T,mtr:N},this._setCornerCoords&&this._setCornerCoords(),this}})}(),fabric.util.object.extend(fabric.Object.prototype,{sendToBack:function(){return this.group?fabric.StaticCanvas.prototype.sendToBack.call(this.group,this):this.canvas.sendToBack(this),this},bringToFront:function(){return this.group?fabric.StaticCanvas.prototype.bringToFront.call(this.group,this):this.canvas.bringToFront(this),this},sendBackwards:function(e){return this.group?fabric.StaticCanvas.prototype.sendBackwards.call(this.group,this,e):this.canvas.sendBackwards(this,e),this},bringForward:function(e){return this.group?fabric.StaticCanvas.prototype.bringForward.call(this.group,this,e):this.canvas.bringForward(this,e),this},moveTo:function(e){return this.group?fabric.StaticCanvas.prototype.moveTo.call(this.group,this,e):this.canvas.moveTo(this,e),this}}),fabric.util.object.extend(fabric.Object.prototype,{getSvgStyles:function(){var e=this.fill?this.fill.toLive?"url(#SVGID_"+this.fill.id+")":this.fill:"none",t=this.stroke?this.stroke.toLive?"url(#SVGID_"+this.stroke.id+")":this.stroke:"none",n=this.strokeWidth?this.strokeWidth:"0",r=this.strokeDashArray?this.strokeDashArray.join(" "):"",i=this.strokeLineCap?this.strokeLineCap:"butt",s=this.strokeLineJoin?this.strokeLineJoin:"miter",o=this.strokeMiterLimit?this.strokeMiterLimit:"4",u=typeof this.opacity!="undefined"?this.opacity:"1",a=this.visible?"":" visibility: hidden;",f=this.shadow&&this.type!=="text"?"filter: url(#SVGID_"+this.shadow.id+");":"";return["stroke: ",t,"; ","stroke-width: ",n,"; ","stroke-dasharray: ",r,"; ","stroke-linecap: ",i,"; ","stroke-linejoin: ",s,"; ","stroke-miterlimit: ",o,"; ","fill: ",e,"; ","opacity: ",u,";",f,a].join("")},getSvgTransform:function(){var e=fabric.util.toFixed,t=this.getAngle(),n=this.getViewportTransform(),r=fabric.util.transformPoint(this.getCenterPoint(),n),i=fabric.Object.NUM_FRACTION_DIGITS,s="translate("+e(r.x,i)+" "+e(r.y,i)+")",o=t!==0?" rotate("+e(t,i)+")":"",u=this.scaleX===1&&this.scaleY===1&&n[0]===1&&n[3]===1?"":" scale("+e(this.scaleX*n[0],i)+" "+e(this.scaleY*n[3],i)+")",a=this.flipX?"matrix(-1 0 0 1 0 0) ":"",f=this.flipY?"matrix(1 0 0 -1 0 0)":"";return[s,o,u,a,f].join("")},_createBaseSVGMarkup:function(){var e=[];return this.fill&&this.fill.toLive&&e.push(this.fill.toSVG(this,!1)),this.stroke&&this.stroke.toLive&&e.push(this.stroke.toSVG(this,!1)),this.shadow&&e.push(this.shadow.toSVG(this)),e}}),fabric.util.object.extend(fabric.Object.prototype,{hasStateChanged:function(){return this.stateProperties.some(function(e){return this.get(e)!==this.originalState[e]},this)},saveState:function(e){return this.stateProperties.forEach(function(e){this.originalState[e]=this.get(e)},this),e&&e.stateProperties&&e.stateProperties.forEach(function(e){this.originalState[e]=this.get(e)},this),this},setupState:function(){return this.originalState={},this.saveState(),this}}),function(){var e=fabric.util.degreesToRadians,t=function(){return typeof G_vmlCanvasManager!="undefined"};fabric.util.object.extend(fabric.Object.prototype,{_controlsVisibility:null,_findTargetCorner:function(e){if(!this.hasControls||!this.active)return!1;var t=e.x,n=e.y,r,i;for(var s in this.oCoords){if(!this.isControlVisible(s))continue;if(s==="mtr"&&!this.hasRotatingPoint)continue;if(!(!this.get("lockUniScaling")||s!=="mt"&&s!=="mr"&&s!=="mb"&&s!=="ml"))continue;i=this._getImageLines(this.oCoords[s].corner),r=this._findCrossPoints({x:t,y:n},i);if(r!==0&&r%2===1)return this.__corner=s,s}return!1},_setCornerCoords:function(){var t=this.oCoords,n=e(this.angle),r=e(45-this.angle),i=Math.sqrt(2*Math.pow(this.cornerSize,2))/2,s=i*Math.cos(r),o=i*Math.sin(r),u=Math.sin(n),a=Math.cos(n);t.tl.corner={tl:{x:t.tl.x-o,y:t.tl.y-s},tr:{x:t.tl.x+s,y:t.tl.y-o},bl:{x:t.tl.x-s,y:t.tl.y+o},br:{x:t.tl.x+o,y:t.tl.y+s}},t.tr.corner={tl:{x:t.tr.x-o,y:t.tr.y-s},tr:{x:t.tr.x+s,y:t.tr.y-o},br:{x:t.tr.x+o,y:t.tr.y+s},bl:{x:t.tr.x-s,y:t.tr.y+o}},t.bl.corner={tl:{x:t.bl.x-o,y:t.bl.y-s},bl:{x:t.bl.x-s,y:t.bl.y+o},br:{x:t.bl.x+o,y:t.bl.y+s},tr:{x:t.bl.x+s,y:t.bl.y-o}},t.br.corner={tr:{x:t.br.x+s,y:t.br.y-o},bl:{x:t.br.x-s,y:t.br.y+o},br:{x:t.br.x+o,y:t.br.y+s},tl:{x:t.br.x-o,y:t.br.y-s}},t.ml.corner={tl:{x:t.ml.x-o,y:t.ml.y-s},tr:{x:t.ml.x+s,y:t.ml.y-o},bl:{x:t.ml.x-s,y:t.ml.y+o},br:{x:t.ml.x+o,y:t.ml.y+s}},t.mt.corner={tl:{x:t.mt.x-o,y:t.mt.y-s},tr:{x:t.mt.x+s,y:t.mt.y-o},bl:{x:t.mt.x-s,y:t.mt.y+o},br:{x:t.mt.x+o,y:t.mt.y+s}},t.mr.corner={tl:{x:t.mr.x-o,y:t.mr.y-s},tr:{x:t.mr.x+s,y:t.mr.y-o},bl:{x:t.mr.x-s,y:t.mr.y+o},br:{x:t.mr.x+o,y:t.mr.y+s}},t.mb.corner={tl:{x:t.mb.x-o,y:t.mb.y-s},tr:{x:t.mb.x+s,y:t.mb.y-o},bl:{x:t.mb.x-s,y:t.mb.y+o},br:{x:t.mb.x+o,y:t.mb.y+s}},t.mtr.corner={tl:{x:t.mtr.x-o+u*this.rotatingPointOffset,y:t.mtr.y-s-a*this.rotatingPointOffset},tr:{x:t.mtr.x+s+u*this.rotatingPointOffset,y:t.mtr.y-o-a*this.rotatingPointOffset},bl:{x:t.mtr.x-s+u*this.rotatingPointOffset,y:t.mtr.y+o-a*this.rotatingPointOffset},br:{x:t.mtr.x+o+u*this.rotatingPointOffset,y:t.mtr.y+s-a*this.rotatingPointOffset}}},drawBorders:function(e){if(!this.hasBorders)return this;var t=this.padding,n=t*2,r=~~(this.strokeWidth/2)*2;e.save(),e.globalAlpha=this.isMoving?this.borderOpacityWhenMoving:1,e.strokeStyle=this.borderColor;var i=1/this._constrainScale(this.scaleX),s=1/this._constrainScale(this.scaleY);e.lineWidth=1/this.borderScaleFactor;var o=this.getViewportTransform(),u=fabric.util.transformPoint(new fabric.Point(this.getWidth(),this.getHeight()),o,!0),a=fabric.util.transformPoint(new fabric.Point(i,s),o,!0),f=u.x,l=u.y,c=a.x,h=a.y;this.group&&(f*=this.group.scaleX,l*=this.group.scaleY),e.strokeRect(~~(-(f/2)-t-r/2*c)-.5,~~(-(l/2)-t-r/2*h)-.5,~~(f+n+r*c)+1,~~(l+n+r*h)+1);if(this.hasRotatingPoint&&this.isControlVisible("mtr")&&!this.get("lockRotation")&&this.hasControls){var p=(this.flipY?l+r*c+t*2:-l-r*h-t*2)/2;e.beginPath(),e.moveTo(0,p),e.lineTo(0,p+(this.flipY?this.rotatingPointOffset:-this.rotatingPointOffset)),e.closePath(),e.stroke()}return e.restore(),this},drawControls:function(e){if(!this.hasControls)return this;var t=this.cornerSize,n=t/2,r=~~(this.strokeWidth/2),i=fabric.util.transformPoint(new fabric.Point(this.getWidth(),this.getHeight()),this.getViewportTransform(),!0),s=i.x,o=i.y,u=-(s/2),a=-(o/2),f=this.padding,l=n,c=n-t,h=this.transparentCorners?"strokeRect":"fillRect";return e.save(),e.lineWidth=1,e.globalAlpha=this.isMoving?this.borderOpacityWhenMoving:1,e.strokeStyle=e.fillStyle=this.cornerColor,this._drawControl("tl",e,h,u-l-r-f,a-l-r-f),this._drawControl("tr",e,h,u+s-l+r+f,a-l-r-f),this._drawControl("bl",e,h,u-l-r-f,a+o+c+r+f),this._drawControl("br",e,h,u+s+c+r+f,a+o+c+r+f),this.get("lockUniScaling")||(this._drawControl("mt",e,h,u+s/2-l,a-l-r-f),this._drawControl("mb",e,h,u+s/2-l,a+o+c+r+f),this._drawControl("mr",e,h,u+s+c+r+f,a+o/2-l),this._drawControl("ml",e,h,u-l-r-f,a+o/2-l)),this.hasRotatingPoint&&this._drawControl("mtr",e,h,u+s/2-l,this.flipY?a+o+this.rotatingPointOffset-this.cornerSize/2+r+f:a-this.rotatingPointOffset-this.cornerSize/2-r-f),e.restore(),this},_drawControl:function(e,n,r,i,s){var o=this.cornerSize;this.isControlVisible(e)&&(t()||this.transparentCorners||n.clearRect(i,s,o,o),n[r](i,s,o,o))},isControlVisible:function(e){return this._getControlsVisibility()[e]},setControlVisible:function(e,t){return this._getControlsVisibility()[e]=t,this},setControlsVisibility:function(e){e||(e={});for(var t in e)this.setControlVisible(t,e[t]);return this},_getControlsVisibility:function(){return this._controlsVisibility||(this._controlsVisibility={tl:!0,tr:!0,br:!0,bl:!0,ml:!0,mt:!0,mr:!0,mb:!0,mtr:!0}),this._controlsVisibility}})}(),fabric.util.object.extend(fabric.StaticCanvas.prototype,{FX_DURATION:500,fxCenterObjectH:function(e,t){t=t||{};var n=function(){},r=t.onComplete||n,i=t.onChange||n,s=this;return fabric.util.animate({startValue:e.get("left"),endValue:this.getCenter().left,duration:this.FX_DURATION,onChange:function(t){e.set("left",t),s.renderAll(),i()},onComplete:function(){e.setCoords(),r()}}),this},fxCenterObjectV:function(e,t){t=t||{};var n=function(){},r=t.onComplete||n,i=t.onChange||n,s=this;return fabric.util.animate({startValue:e.get("top"),endValue:this.getCenter().top,duration:this.FX_DURATION,onChange:function(t){e.set("top",t),s.renderAll(),i()},onComplete:function(){e.setCoords(),r()}}),this},fxRemove:function(e,t){t=t||{};var n=function(){},r=t.onComplete||n,i=t.onChange||n,s=this;return fabric.util.animate({startValue:e.get("opacity"),endValue:0,duration:this.FX_DURATION,onStart:function(){e.set("active",!1)},onChange:function(t){e.set("opacity",t),s.renderAll(),i()},onComplete:function(){s.remove(e),r()}}),this}}),fabric.util.object.extend(fabric.Object.prototype,{animate:function(){if(arguments[0]&&typeof arguments[0]=="object"){var e=[],t,n;for(t in arguments[0])e.push(t);for(var r=0,i=e.length;r'),e?e(t.join("")):t.join("")},complexity:function(){return 1}}),t.Line.ATTRIBUTE_NAMES=t.SHARED_ATTRIBUTES.concat("x1 y1 x2 y2".split(" ")),t.Line.fromElement=function(e,r){var i=t.parseAttributes(e,t.Line.ATTRIBUTE_NAMES),s=[i.x1||0,i.y1||0,i.x2||0,i.y2||0];return new t.Line(s,n(i,r))},t.Line.fromObject=function(e){var n=[e.x1,e.y1,e.x2,e.y2];return new t.Line(n,e)}}(typeof exports!="undefined"?exports:this),function(e){"use strict";function i(e){return"radius"in e&&e.radius>0}var t=e.fabric||(e.fabric={}),n=Math.PI*2,r=t.util.object.extend;if(t.Circle){t.warn("fabric.Circle is already defined.");return}t.Circle=t.util.createClass(t.Object,{type:"circle",radius:0,initialize:function(e){e=e||{},this.set("radius",e.radius||0),this.callSuper("initialize",e)},_set:function(e,t){return this.callSuper("_set",e,t),e==="radius"&&this.setRadius(t),this},toObject:function(e){return r(this.callSuper("toObject",e),{radius:this.get("radius")})},toSVG:function(e){var t=this._createBaseSVGMarkup();return t.push("'),e?e(t.join("")):t.join("")},_render:function(e,t){e.beginPath(),e.globalAlpha=this.group?e.globalAlpha*this.opacity:this.opacity,e.arc(t?this.left:0,t?this.top:0,this.radius,0,n,!1),this._renderFill(e),this.stroke&&this._renderStroke(e)},getRadiusX:function(){return this.get("radius")*this.get("scaleX")},getRadiusY:function(){return this.get("radius")*this.get("scaleY")},setRadius:function(e){this.radius=e,this.set("width",e*2).set("height",e*2)},complexity:function(){return 1}}),t.Circle.ATTRIBUTE_NAMES=t.SHARED_ATTRIBUTES.concat("cx cy r".split(" ")),t.Circle.fromElement=function(e,n){n||(n={});var s=t.parseAttributes(e,t.Circle.ATTRIBUTE_NAMES);if(!i(s))throw new Error("value of `r` attribute is required and can not be negative");"left"in s||(s.left=0),"top"in s||(s.top=0),"transformMatrix"in s||(s.left-=n.width/2,s.top-=n.height/2);var o=new t.Circle(r(s,n));return o.cx=parseFloat(e.getAttribute("cx"))||0,o.cy=parseFloat(e.getAttribute("cy"))||0,o},t.Circle.fromObject=function(e){return new t.Circle(e)}}(typeof exports!="undefined"?exports:this),function(e){"use strict";var t=e.fabric||(e.fabric={});if(t.Triangle){t.warn("fabric.Triangle is already defined");return}t.Triangle=t.util.createClass(t.Object,{type:"triangle",initialize:function(e){e=e||{},this.callSuper("initialize",e),this.set("width",e.width||100).set("height",e.height||100)},_render:function(e){var t=this.width/2,n=this.height/2;e.beginPath(),e.moveTo(-t,n),e.lineTo(0,-n),e.lineTo(t,n),e.closePath(),this._renderFill(e),this._renderStroke(e)},_renderDashedStroke:function(e){var n=this.width/2,r=this.height/2;e.beginPath(),t.util.drawDashedLine(e,-n,r,0,-r,this.strokeDashArray),t.util.drawDashedLine(e,0,-r,n,r,this.strokeDashArray),t.util.drawDashedLine(e,n,r,-n,r,this.strokeDashArray),e.closePath()},toSVG:function(e){var t=this._createBaseSVGMarkup(),n=this.width/2,r=this.height/2,i=[-n+" "+r,"0 "+ -r,n+" "+r].join(",");return t.push("'),e?e(t.join("")):t.join("")},complexity:function(){return 1}}),t.Triangle.fromObject=function(e){return new t.Triangle(e)}}(typeof exports!="undefined"?exports:this),function(e){"use strict";var t=e.fabric||(e.fabric={}),n=Math.PI*2,r=t.util.object.extend;if(t.Ellipse){t.warn("fabric.Ellipse is already defined.");return}t.Ellipse=t.util.createClass(t.Object,{type:"ellipse",rx:0,ry:0,initialize:function(e){e=e||{},this.callSuper("initialize",e),this.set("rx",e.rx||0),this.set("ry",e.ry||0),this.set("width",this.get("rx")*2),this.set("height",this.get("ry")*2)},toObject:function( +e){return r(this.callSuper("toObject",e),{rx:this.get("rx"),ry:this.get("ry")})},toSVG:function(e){var t=this._createBaseSVGMarkup();return t.push("'),e?e(t.join("")):t.join("")},render:function(e,t){if(this.rx===0||this.ry===0)return;return this.callSuper("render",e,t)},_render:function(e,t){e.beginPath(),e.save(),e.globalAlpha=this.group?e.globalAlpha*this.opacity:this.opacity,e.transform(1,0,0,this.ry/this.rx,0,0),e.arc(t?this.left:0,t?this.top*this.rx/this.ry:0,this.rx,0,n,!1),this._renderFill(e),this._renderStroke(e),e.restore()},complexity:function(){return 1}}),t.Ellipse.ATTRIBUTE_NAMES=t.SHARED_ATTRIBUTES.concat("cx cy rx ry".split(" ")),t.Ellipse.fromElement=function(e,n){n||(n={});var i=t.parseAttributes(e,t.Ellipse.ATTRIBUTE_NAMES);"left"in i||(i.left=0),"top"in i||(i.top=0),"transformMatrix"in i||(i.left-=n.width/2,i.top-=n.height/2);var s=new t.Ellipse(r(i,n));return s.cx=parseFloat(e.getAttribute("cx"))||0,s.cy=parseFloat(e.getAttribute("cy"))||0,s},t.Ellipse.fromObject=function(e){return new t.Ellipse(e)}}(typeof exports!="undefined"?exports:this),function(e){"use strict";function i(e){return e.left=e.left||0,e.top=e.top||0,e}var t=e.fabric||(e.fabric={}),n=t.util.object.extend;if(t.Rect){console.warn("fabric.Rect is already defined");return}var r=t.Object.prototype.stateProperties.concat();r.push("rx","ry","x","y"),t.Rect=t.util.createClass(t.Object,{stateProperties:r,type:"rect",rx:0,ry:0,x:0,y:0,strokeDashArray:null,initialize:function(e){e=e||{},this.callSuper("initialize",e),this._initRxRy(),this.x=e.x||0,this.y=e.y||0},_initRxRy:function(){this.rx&&!this.ry?this.ry=this.rx:this.ry&&!this.rx&&(this.rx=this.ry)},_render:function(e){if(this.width===1&&this.height===1){e.fillRect(0,0,1,1);return}var t=this.rx?Math.min(this.rx,this.width/2):0,n=this.ry?Math.min(this.ry,this.height/2):0,r=this.width,i=this.height,s=-r/2,o=-i/2,u=this.group&&this.group.type==="path-group",a=t!==0||n!==0,f=.4477152502;e.beginPath(),e.globalAlpha=u?e.globalAlpha*this.opacity:this.opacity,this.transformMatrix&&u&&e.translate(this.width/2+this.x,this.height/2+this.y),!this.transformMatrix&&u&&e.translate(-this.group.width/2+this.width/2+this.x,-this.group.height/2+this.height/2+this.y),e.moveTo(s+t,o),e.lineTo(s+r-t,o),a&&e.bezierCurveTo(s+r-f*t,o,s+r,o+f*n,s+r,o+n),e.lineTo(s+r,o+i-n),a&&e.bezierCurveTo(s+r,o+i-f*n,s+r-f*t,o+i,s+r-t,o+i),e.lineTo(s+t,o+i),a&&e.bezierCurveTo(s+f*t,o+i,s,o+i-f*n,s,o+i-n),e.lineTo(s,o+n),a&&e.bezierCurveTo(s,o+f*n,s+f*t,o,s+t,o),e.closePath(),this._renderFill(e),this._renderStroke(e)},_renderDashedStroke:function(e){var n=-this.width/2,r=-this.height/2,i=this.width,s=this.height;e.beginPath(),t.util.drawDashedLine(e,n,r,n+i,r,this.strokeDashArray),t.util.drawDashedLine(e,n+i,r,n+i,r+s,this.strokeDashArray),t.util.drawDashedLine(e,n+i,r+s,n,r+s,this.strokeDashArray),t.util.drawDashedLine(e,n,r+s,n,r,this.strokeDashArray),e.closePath()},_normalizeLeftTopProperties:function(e){return"left"in e&&this.set("left",e.left+this.getWidth()/2),this.set("x",e.left||0),"top"in e&&this.set("top",e.top+this.getHeight()/2),this.set("y",e.top||0),this},toObject:function(e){var t=n(this.callSuper("toObject",e),{rx:this.get("rx")||0,ry:this.get("ry")||0,x:this.get("x"),y:this.get("y")});return this.includeDefaultValues||this._removeDefaultValues(t),t},toSVG:function(e){var t=this._createBaseSVGMarkup();return t.push("'),e?e(t.join("")):t.join("")},complexity:function(){return 1}}),t.Rect.ATTRIBUTE_NAMES=t.SHARED_ATTRIBUTES.concat("x y rx ry width height".split(" ")),t.Rect.fromElement=function(e,r){if(!e)return null;var s=t.parseAttributes(e,t.Rect.ATTRIBUTE_NAMES);s=i(s);var o=new t.Rect(n(r?t.util.object.clone(r):{},s));return o._normalizeLeftTopProperties(s),o},t.Rect.fromObject=function(e){return new t.Rect(e)}}(typeof exports!="undefined"?exports:this),function(e){"use strict";var t=e.fabric||(e.fabric={}),n=t.util.toFixed;if(t.Polyline){t.warn("fabric.Polyline is already defined");return}t.Polyline=t.util.createClass(t.Object,{type:"polyline",points:null,initialize:function(e,t,n){t=t||{},this.set("points",e),this.callSuper("initialize",t),this._calcDimensions(n)},_calcDimensions:function(e){return t.Polygon.prototype._calcDimensions.call(this,e)},toObject:function(e){return t.Polygon.prototype.toObject.call(this,e)},toSVG:function(e){var t=[],r=this._createBaseSVGMarkup();for(var i=0,s=this.points.length;i'),e?e(r.join("")):r.join("")},_render:function(e){var t;e.beginPath(),e.moveTo(this.points[0].x,this.points[0].y);for(var n=0,r=this.points.length;n'),e?e(n.join("")):n.join("")},_render:function(e){var t;e.beginPath(),e.globalAlpha=this.group?e.globalAlpha*this.opacity:this.opacity,e.moveTo(this.points[0].x,this.points[0].y);for(var n=0,r=this.points.length;n"},toObject:function(e){var t=i(this.callSuper("toObject",e),{path:this.path.map(function(e){return e.slice()}),pathOffset:this.pathOffset});return this.sourcePath&&(t.sourcePath=this.sourcePath),this.transformMatrix&&(t.transformMatrix=this.transformMatrix),t},toDatalessObject:function(e){var t=this.toObject(e);return this.sourcePath&&(t.path=this.sourcePath),delete t.sourcePath,t},toSVG:function(e){var t=[],n=this._createBaseSVGMarkup();for(var r=0,i=this.path.length;r',"",""),e?e(n.join("")):n.join("")},complexity:function(){return this.path.length},_parsePath:function(){var e=[],t=[],n,r,i=/([-+]?((\d+\.\d+)|((\d+)|(\.\d+)))(?:e[-+]?\d+)?)/ig,s,o;for(var f=0,l,c=this.path.length;fv)for(var g=1,y=l.length;g"];for(var r=0,i=t.length;r"),e?e(n.join("")):n.join("")},toString:function(){return"#"},isSameColor:function(){var e=(this.getObjects()[0].get("fill")||"").toLowerCase();return this.getObjects().every(function(t){return(t.get("fill")||"").toLowerCase()===e})},complexity:function(){return this.paths.reduce(function(e,t){return e+(t&&t.complexity?t.complexity():0)},0)},getObjects:function(){return this.paths}}),t.PathGroup.fromObject=function(e,n){typeof e.paths=="string"?t.loadSVGFromURL(e.paths,function(r){var i=e.paths;delete e.paths;var s=t.util.groupSVGElements(r,e,i);n(s)}):t.util.enlivenObjects(e.paths,function(r){delete e.paths,n(new t.PathGroup(r,e))})},t.PathGroup.async=!0}(typeof exports!="undefined"?exports:this),function(e){"use strict";var t=e.fabric||(e.fabric={}),n=t.util.object.extend,r=t.util.array.min,i=t.util.array.max,s=t.util.array.invoke;if(t.Group)return;var o={lockMovementX:!0,lockMovementY:!0,lockRotation:!0,lockScalingX:!0,lockScalingY:!0,lockUniScaling:!0};t.Group=t.util.createClass(t.Object,t.Collection,{type:"group",initialize:function(e,t){t=t||{},this._objects=e||[];for(var r=this._objects.length;r--;)this._objects[r].group=this;this.originalState={},this.callSuper("initialize"),this._calcBounds(),this._updateObjectsCoords(),t&&n(this,t),this._setOpacityIfSame(),this.setCoords(),this.saveCoords()},_updateObjectsCoords:function(){this.forEachObject(this._updateObjectCoords,this)},_updateObjectCoords:function(e){var t=e.getLeft(),n=e.getTop();e.set({originalLeft:t,originalTop:n,left:t-this.left,top:n-this.top}),e.setCoords(),e.__origHasControls=e.hasControls,e.hasControls=!1},toString:function(){return"#"},addWithUpdate:function(e){return this._restoreObjectsState(),e&&(this._objects.push(e),e.group=this),this.forEachObject(this._setObjectActive,this),this._calcBounds(),this._updateObjectsCoords(),this},_setObjectActive:function(e){e.set("active",!0),e.group=this},removeWithUpdate:function(e){return this._moveFlippedObject(e),this._restoreObjectsState(),this.forEachObject(this._setObjectActive,this),this.remove(e),this._calcBounds(),this._updateObjectsCoords(),this},_onObjectAdded:function(e){e.group=this},_onObjectRemoved:function(e){delete e.group,e.set("active",!1)},delegatedProperties:{fill:!0,opacity:!0,fontFamily:!0,fontWeight:!0,fontSize:!0,fontStyle:!0,lineHeight:!0,textDecoration:!0,textAlign:!0,backgroundColor:!0},_set:function(e,t){if(e in this.delegatedProperties){var n=this._objects.length;this[e]=t;while(n--)this._objects[n].set(e,t)}else this[e]=t},toObject:function(e){return n(this.callSuper("toObject",e),{objects:s(this._objects,"toObject",e)})},render:function(e){if(!this.visible)return;e.save(),this.clipTo&&t.util.clipContext(this,e);for(var n=0,r=this._objects.length;n'];for(var n=0,r=this._objects.length;n"),e?e(t.join("")):t.join("")},get:function(e){if(e in o){if(this[e])return this[e];for(var t=0,n=this._objects.length;t','");if(this.stroke||this.strokeDashArray){var n=this.fill;this.fill=null,t.push("'),this.fill=n}return t.push(""),e?e(t.join("")):t.join("")},getSrc:function(){if(this.getElement())return this.getElement().src||this.getElement()._src},toString:function(){return'#'},clone:function(e,t){this.constructor.fromObject(this.toObject(t),e)},applyFilters:function(e){if(!this._originalElement)return;if(this.filters.length===0){this._element=this._originalElement,e&&e();return}var t=this._originalElement,n=fabric.util.createCanvasElement(),r=fabric.util.createImage(),i=this;return n.width=t.width,n.height=t.height,n.getContext("2d").drawImage(t,0,0,t.width,t.height),this.filters.forEach(function(e){e&&e.applyTo(n)}),r.width=t.width,r.height=t.height,fabric.isLikelyNode?(r.src=n.toBuffer(undefined,fabric.Image.pngCompression),i._element=r,e&&e()):(r.onload=function(){i._element=r,e&&e(),r.onload=n=t=null},r.src=n.toDataURL("image/png")),this},_render:function(e){this._element&&e.drawImage(this._element,-this.width/2,-this.height/2,this.width,this.height)},_resetWidthHeight:function(){var e=this.getElement();this.set("width",e.width),this.set("height",e.height)},_initElement:function(e){this.setElement(fabric.util.getById(e)),fabric.util.addClass(this.getElement(),fabric.Image.CSS_CANVAS)},_initConfig:function(e){e||(e={}),this.setOptions(e),this._setWidthHeight(e),this._element&&this.crossOrigin&&(this._element.crossOrigin=this.crossOrigin)},_initFilters:function(e,t){e.filters&&e.filters.length?fabric.util.enlivenObjects(e.filters,function(e){t&&t(e)},"fabric.Image.filters"):t&&t()},_setWidthHeight:function(e){this.width="width"in e?e.width:this.getElement()?this.getElement().width||0:0,this.height="height"in e?e.height:this.getElement()?this.getElement().height||0:0},complexity:function(){return 1}}),fabric.Image.CSS_CANVAS="canvas-img",fabric.Image.prototype.getSvgSrc=fabric.Image.prototype.getSrc,fabric.Image.fromObject=function(e,t){fabric.util.loadImage(e.src,function(n){fabric.Image.prototype._initFilters.call(e,e,function(r){e.filters=r||[];var i=new fabric.Image(n,e);t&&t(i)})},null,e.crossOrigin)},fabric.Image.fromURL=function(e,t,n){fabric.util.loadImage(e,function(e){t(new fabric.Image(e,n))},null,n&&n.crossOrigin)},fabric.Image.ATTRIBUTE_NAMES=fabric.SHARED_ATTRIBUTES.concat("x y width height xlink:href".split(" ")),fabric.Image.fromElement=function(e,n,r){var i=fabric.parseAttributes(e,fabric.Image.ATTRIBUTE_NAMES);fabric.Image.fromURL(i["xlink:href"],n,t(r?fabric.util.object.clone(r):{},i))},fabric.Image.async=!0,fabric.Image.pngCompression=1}(typeof exports!="undefined"?exports:this),fabric.util.object.extend(fabric.Object.prototype,{_getAngleValueForStraighten:function(){var e=this.getAngle()%360;return e>0?Math.round((e-1)/90)*90:Math.round(e/90)*90},straighten:function(){return this.setAngle(this._getAngleValueForStraighten()),this},fxStraighten:function(e){e=e||{};var t=function(){},n=e.onComplete||t,r=e.onChange||t,i=this;return fabric.util.animate({startValue:this.get("angle"),endValue:this._getAngleValueForStraighten(),duration:this.FX_DURATION,onChange:function(e){i.setAngle(e),r()},onComplete:function(){i.setCoords(),n()},onStart:function(){i.set("active",!1)}}),this}}),fabric.util.object.extend(fabric.StaticCanvas.prototype,{straightenObject:function(e){return e.straighten(),this.renderAll(),this},fxStraightenObject:function(e){return e.fxStraighten({onChange:this.renderAll.bind(this)}),this}}),fabric.Image.filters=fabric.Image.filters||{},fabric.Image.filters.BaseFilter=fabric.util.createClass({type:"BaseFilter",toObject:function(){return{type:this.type}},toJSON:function(){return this.toObject()}}),function(e){"use strict";var t=e.fabric||(e.fabric={}),n=t.util.object.extend;t.Image.filters.Brightness=t.util.createClass(t.Image.filters.BaseFilter,{type:"Brightness",initialize:function(e){e=e||{},this.brightness=e.brightness||0},applyTo:function(e){var t=e.getContext("2d"),n=t.getImageData(0,0,e.width,e.height),r=n.data,i=this.brightness;for(var s=0,o=r.length;sa||C<0||C>u)continue;var k=(N*u+C)*4,L=t[x*i+T];b+=o[k]*L,w+=o[k+1]*L,E+=o[k+2]*L,S+=o[k+3]*L}h[y]=b,h[y+1]=w,h[y+2]=E,h[y+3]=S+p*(255-S)}n.putImageData(c,0,0)},toObject:function(){return n(this.callSuper("toObject"),{opaque:this.opaque,matrix:this.matrix})}}),t.Image.filters.Convolute.fromObject=function(e){return new t.Image.filters.Convolute(e)}}(typeof exports!="undefined"?exports:this),function(e){"use strict";var t=e.fabric||(e.fabric={}),n=t.util.object.extend;t.Image.filters.GradientTransparency=t.util.createClass(t.Image.filters.BaseFilter,{type:"GradientTransparency",initialize:function(e){e=e||{},this.threshold=e.threshold||100},applyTo:function(e){var t=e.getContext("2d"),n=t.getImageData(0,0,e.width,e.height),r=n.data,i=this.threshold,s=r.length;for(var o=0,u=r.length;o-1?e.channel:0},applyTo:function(e){if(!this.mask)return;var n=e.getContext("2d"),r=n.getImageData(0,0,e.width,e.height),i=r.data,s=this.mask.getElement(),o=t.util.createCanvasElement(),u=this.channel,a,f=r.width*r.height*4;o.width=s.width,o.height=s.height,o.getContext("2d").drawImage(s,0,0,s.width,s.height);var l=o.getContext("2d").getImageData(0,0,s.width,s.height),c=l.data;for(a=0;ao&&f>o&&l>o&&u(a-f)'},_render:function(e){var t=this.group&&this.group.type==="path-group";t&&!this.transformMatrix?e.translate(-this.group.width/2+this.left,-this.group.height/2+this.top):t&&this.transformMatrix&&e.translate(-this.group.width/2,-this.group.height/2),typeof Cufon=="undefined"||this.useNative===!0?this._renderViaNative(e):this._renderViaCufon(e)},_renderViaNative:function(e){var n=this.text.split(this._reNewline);this.transform(e,t.isLikelyNode),this._setTextStyles(e),this.width=this._getTextWidth(e,n),this.height=this._getTextHeight(e,n),this.clipTo&&t.util.clipContext(this,e),this._renderTextBackground(e,n),this._translateForTextAlign(e),this._renderText(e,n),this.textAlign!=="left"&&this.textAlign!=="justify"&&e.restore(),this._renderTextDecoration(e,n),this.clipTo&&e.restore(),this._setBoundaries(e,n),this._totalLineHeight=0},_renderText:function(e,t){e.save(),this._setShadow(e),this._renderTextFill(e,t),this._renderTextStroke(e,t),this._removeShadow(e),e.restore()},_translateForTextAlign:function(e){this.textAlign!=="left"&&this.textAlign!=="justify"&&(e.save(),e.translate(this.textAlign==="center"?this.width/2:this.width,0))},_setBoundaries:function(e,t){this._boundaries=[];for(var n=0,r=t.length;nn&&(n=s)}return n},_renderChars:function(e,t,n,r,i){t[e](n,r,i)},_renderTextLine:function(e,t,n,r,i,s){i-=this.fontSize/4;if(this.textAlign!=="justify"){this._renderChars(e,t,n,r,i,s);return}var o=t.measureText(n).width,u=this.width;if(u>o){var a=n.split(/\s+/),f=t.measureText(n.replace(/\s+/g,"")).width,l=u-f,c=a.length-1,h=l/c,p=0;for(var d=0,v=a.length;d-1&&i(this.fontSize*this.lineHeight),this.textDecoration.indexOf("line-through")>-1&&i(this.fontSize*this.lineHeight-this.fontSize/2),this.textDecoration.indexOf("overline")>-1&&i(this.fontSize*this.lineHeight-this.fontSize)},_getFontDeclaration:function(){return[t.isLikelyNode?this.fontWeight:this.fontStyle,t.isLikelyNode?this.fontStyle:this.fontWeight,this.fontSize+"px",t.isLikelyNode?'"'+this.fontFamily+'"':this.fontFamily].join(" ")},render:function(e){if(!this.visible)return;e.save();var t=this.transformMatrix;t&&(!this.group||this.group.type==="path-group")&&e.transform(t[0],t[1],t[2],t[3],t[4],t[5]),this._render(e),e.restore()},toObject:function(e){var t=n(this.callSuper("toObject",e),{text:this.text,fontSize:this.fontSize,fontWeight:this.fontWeight,fontFamily:this.fontFamily,fontStyle:this.fontStyle,lineHeight:this.lineHeight,textDecoration:this.textDecoration,textAlign:this.textAlign,path:this.path,textBackgroundColor:this.textBackgroundColor,useNative:this.useNative});return this.includeDefaultValues||this._removeDefaultValues(t),t},toSVG:function(e){var t=[],n=this.text.split(this._reNewline),r=this._getSVGLeftTopOffsets(n),i=this._getSVGTextAndBg(r.lineTop,r.textLeft,n),s=this._getSVGShadows(r.lineTop,n);return r.textTop+=this._fontAscent?this._fontAscent/5*this.lineHeight:0,this._wrapSVGTextAndBg(t,i,s,r),e?e(t.join("")):t.join("")},_getSVGLeftTopOffsets:function(e){var t=this.useNative?this.fontSize*this.lineHeight:-this._fontAscent-this._fontAscent/5*this.lineHeight,n=-(this.width/2),r=this.useNative?this.fontSize-1:this.height/2-e.length*this.fontSize-this._totalLineHeight;return{textLeft:n,textTop:r,lineTop:t}},_wrapSVGTextAndBg:function(e,t,n,r){e.push('',t.textBgRects.join(""),"',n.join(""),t.textSpans.join(""),"","")},_getSVGShadows:function(e,n){var r=[],s,o,u=1;if(!this.shadow||!this._boundaries)return r;for(s=0,o=n.length;s",t.util.string.escapeXml(n[s]),""),u=1}else u++;return r},_getSVGTextAndBg:function(e,t,n){var r=[],i=[],s=1;this._setSVGBg(i);for(var o=0,u=n.length;o",t.util.string.escapeXml(e),"")},_setSVGTextLineBg:function(e,t,n,r){e.push("')},_setSVGBg:function(e){this.backgroundColor&&this._boundaries&&e.push("')},_getFillAttributes:function(e){var n=e&&typeof e=="string"?new t.Color(e):"";return!n||!n.getSource()||n.getAlpha()===1?'fill="'+e+'"':'opacity="'+n.getAlpha()+'" fill="'+n.setAlpha(1).toRgb()+'"'},_set:function(e,t){e==="fontFamily"&&this.path&&(this.path=this.path.replace(/(.*?)([^\/]*)(\.font\.js)/,"$1"+t+"$3")),this.callSuper("_set",e,t),e in this._dimensionAffectingProps&&(this._initDimensions(),this.setCoords())},complexity:function(){return 1}}),t.Text.ATTRIBUTE_NAMES=t.SHARED_ATTRIBUTES.concat("x y dx dy font-family font-style font-weight font-size text-decoration text-anchor".split(" ")),t.Text.DEFAULT_SVG_FONT_SIZE=16,t.Text.fromElement=function(e,n){if(!e)return null;var r=t.parseAttributes(e,t.Text.ATTRIBUTE_NAMES);n=t.util.object.extend(n?t.util.object.clone(n):{},r),"dx"in r&&(n.left+=r.dx),"dy"in r&&(n.top+=r.dy),"fontSize"in n||(n.fontSize=t.Text.DEFAULT_SVG_FONT_SIZE),n.originX||(n.originX="center");var i=new t.Text(e.textContent,n);return i.set({left:i.getLeft()+i.getWidth()/2,top:i.getTop()-i.getHeight()/2}),i},t.Text.fromObject=function(e){return new t.Text(e.text,r(e))},t.util.createAccessors(t.Text)}(typeof exports!="undefined"?exports:this),function(){var e=fabric.util.object.clone;fabric.IText=fabric.util.createClass(fabric.Text,fabric.Observable,{type:"i-text",selectionStart:0,selectionEnd:0,selectionColor:"rgba(17,119,255,0.3)",isEditing:!1,editable:!0,editingBorderColor:"rgba(102,153,255,0.25)",cursorWidth:2,cursorColor:"#333",cursorDelay:1e3,cursorDuration:600,styles:null,caching:!0,_skipFillStrokeCheck:!0,_reSpace:/\s|\n/,_fontSizeFraction:4,_currentCursorOpacity:0,_selectionDirection:null,_abortCursorAnimation:!1,_charWidthsCache:{},initialize:function(e,t){this.styles=t?t.styles||{}:{},this.callSuper("initialize",e,t),this.initBehavior(),fabric.IText.instances.push(this),this.__lineWidths={},this.__lineHeights={},this.__lineOffsets={}},isEmptyStyles:function(){if(!this.styles)return!0;var e=this.styles;for(var t in e)for(var n in e[t])for(var r in e[t][n])return!1;return!0},setSelectionStart:function(e){this.selectionStart!==e&&(this.fire("selection:changed"),this.canvas&&this.canvas.fire("text:selection:changed",{target:this})),this.selectionStart=e,this.hiddenTextarea&&(this.hiddenTextarea.selectionStart=e)},setSelectionEnd:function(e){this.selectionEnd!==e&&(this.fire("selection:changed"),this.canvas&&this.canvas.fire("text:selection:changed",{target:this})),this.selectionEnd=e,this.hiddenTextarea&&(this.hiddenTextarea.selectionEnd=e)},getSelectionStyles:function(e,t){if(arguments.length===2){var n=[];for(var r=e;r=r.charIndex&&(a!==o||hs&&a-1&&this._renderCharDecorationAtOffset(e,n,r+this.fontSize/this._fontSizeFraction,i,0,this.fontSize/20),u.indexOf("line-through")>-1&&this._renderCharDecorationAtOffset(e,n,r+this.fontSize/this._fontSizeFraction,i,o/2,a/20),u.indexOf("overline")>-1&&this._renderCharDecorationAtOffset(e,n,r,i,s-this.fontSize/this._fontSizeFraction,this.fontSize/20)},_renderCharDecorationAtOffset:function(e,t,n,r,i,s){e.fillRect(t,n-i,r,s)},_renderTextLine:function(e,t,n,r,i,s){i+=this.fontSize/4,this.callSuper("_renderTextLine",e,t,n,r,i,s)},_renderTextDecoration:function(e,t){if(this.isEmptyStyles())return this.callSuper("_renderTextDecoration",e,t)},_renderTextLinesBackground:function(e,t){if(!this.textBackgroundColor&&!this.styles)return;e.save(),this.textBackgroundColor&&(e.fillStyle=this.textBackgroundColor);var n=0,r=this.fontSize/this._fontSizeFraction;for(var i=0,s=t.length;in&&(n=s)}return n},_getHeightOfLine:function(e,t,n){n=n||this.text.split(this._reNewline);var r=this._getHeightOfChar(e,n[t][0],t,0),i=n[t],s=i.split("");for(var o=1,u=s.length;or&&(r=a)}return r*this.lineHeight},_getTextHeight:function(e,t){var n=0;for(var r=0,i=t.length;r-1)t++,n--;return e-t},findWordBoundaryRight:function(e){var t=0,n=e;if(this._reSpace.test(this.text.charAt(n)))while(this._reSpace.test(this.text.charAt(n)))t++,n++;while(/\S/.test(this.text.charAt(n))&&n-1)t++,n--;return e-t},findLineBoundaryRight:function(e){var t=0,n=e;while(!/\n/.test(this.text.charAt(n))&&n0&&nr;s?this.removeStyleObject(s,n+1):this.removeStyleObject(this.get2DCursorLocation(n).charIndex===0,n)}this.text=this.text.slice(0,e)+this.text.slice(t)},insertChars:function(e){var t=this.text.slice(this.selectionStart,this.selectionStart+1)==="\n";this.text=this.text.slice(0,this.selectionStart)+e+this.text.slice(this.selectionEnd),this.selectionStart===this.selectionEnd&&this.insertStyleObjects(e,t,this.copiedStyles),this.selectionStart+=e.length,this.selectionEnd=this.selectionStart,this.canvas&&this.canvas.renderAll().renderAll(),this.setCoords(),this.fire("changed"),this.canvas&&this.canvas.fire("text:changed",{target:this})},insertNewlineStyleObject:function(t,n,r){this.shiftLineStyles(t,1),this.styles[t+1]||(this.styles[t+1]={});var i=this.styles[t][n-1],s={};if(r)s[0]=e(i),this.styles[t+1]=s;else{for(var o in this.styles[t])parseInt(o,10)>=n&&(s[parseInt(o,10)-n]=this.styles[t][o],delete this.styles[t][o]);this.styles[t+1]=s}},insertCharStyleObject:function(t,n,r){var i=this.styles[t],s=e(i);n===0&&!r&&(n=1);for(var o in s){var u=parseInt(o,10);u>=n&&(i[u+1]=s[u])}this.styles[t][n]=r||e(i[n-1])},insertStyleObjects:function(e,t,n){if(this.isEmptyStyles())return;var r=this.get2DCursorLocation(),i=r.lineIndex,s=r.charIndex;this.styles[i]||(this.styles[i]={}),e==="\n"?this.insertNewlineStyleObject(i,s,t):n?this._insertStyles(n):this.insertCharStyleObject(i,s)},_insertStyles:function(e){for(var t=0,n=e.length;tt&&(this.styles[s+n]=r[s])}},removeStyleObject:function(t,n){var r=this.get2DCursorLocation(n),i=r.lineIndex,s=r.charIndex;if(t){var o=this.text.split(this._reNewline),u=o[i-1],a=u?u.length:0;this.styles[i-1]||(this.styles[i-1]={});for(s in this.styles[i])this.styles[i-1][parseInt(s,10)+a]=this.styles[i][s];this.shiftLineStyles(i,-1)}else{var f=this.styles[i];if(f){var l=this.selectionStart===this.selectionEnd?-1:0;delete f[s+l]}var c=e(f);for(var h in c){var p=parseInt(h,10);p>=s&&p!==0&&(f[p-1]=c[p],delete f[p])}}},insertNewline:function(){this.insertChars("\n")}})}(),fabric.util.object.extend(fabric.IText.prototype,{initDoubleClickSimulation:function(){this.__lastClickTime=+(new Date),this.__lastLastClickTime=+(new Date),this.__lastPointer={},this.on("mousedown",this.onMouseDown.bind(this))},onMouseDown:function(e){this.__newClickTime=+(new Date);var t=this.canvas.getPointer(e.e);this.isTripleClick(t)?(this.fire("tripleclick",e),this._stopEvent(e.e)):this.isDoubleClick(t)&&(this.fire("dblclick",e),this._stopEvent(e.e)),this.__lastLastClickTime=this.__lastClickTime,this.__lastClickTime=this.__newClickTime,this.__lastPointer=t,this.__lastIsEditing=this.isEditing,this.__lastSelected=this.selected},isDoubleClick:function(e){return this.__newClickTime-this.__lastClickTime<500&&this.__lastPointer.x===e.x&&this.__lastPointer.y===e.y&&this.__lastIsEditing},isTripleClick:function(e){return this.__newClickTime-this.__lastClickTime<500&&this.__lastClickTime-this.__lastLastClickTime<500&&this.__lastPointer.x===e.x&&this.__lastPointer.y===e.y},_stopEvent:function(e){e.preventDefault&&e.preventDefault(),e.stopPropagation&&e.stopPropagation()},initCursorSelectionHandlers:function(){this.initSelectedHandler(),this.initMousedownHandler(),this.initMousemoveHandler(),this.initMouseupHandler(),this.initClicks()},initClicks:function(){this.on("dblclick",function(e){this.selectWord(this.getSelectionStartFromPointer(e.e))}),this.on("tripleclick",function(e){this.selectLine(this.getSelectionStartFromPointer(e.e))})},initMousedownHandler:function(){this.on("mousedown",function(e){var t=this.canvas.getPointer(e.e);this.__mousedownX=t.x,this.__mousedownY=t.y,this.__isMousedown=!0,this.hiddenTextarea&&this.canvas&&this.canvas.wrapperEl.appendChild(this.hiddenTextarea),this.selected&&this.setCursorByClick(e.e),this.isEditing&&(this.__selectionStartOnMouseDown=this.selectionStart,this.initDelayedCursor(!0))})},initMousemoveHandler:function(){this.on("mousemove",function(e){if(!this.__isMousedown||!this.isEditing)return;var t=this.getSelectionStartFromPointer(e.e);t>=this.__selectionStartOnMouseDown?(this.setSelectionStart(this.__selectionStartOnMouseDown),this.setSelectionEnd(t)):(this.setSelectionStart(t),this.setSelectionEnd(this.__selectionStartOnMouseDown))})},_isObjectMoved:function(e){var t=this.canvas.getPointer(e);return this.__mousedownX!==t.x||this.__mousedownY!==t.y},initMouseupHandler:function(){this.on("mouseup",function(e){this.__isMousedown=!1;if(this._isObjectMoved(e.e))return;this.__lastSelected&&(this.enterEditing(),this.initDelayedCursor(!0)),this.selected=!0})},setCursorByClick:function(e){var t=this.getSelectionStartFromPointer(e);e.shiftKey?to?0:1,f=r+a;return this.flipX&&(f=i-f),f>this.text.length&&(f=this.text.length),s===i&&f--,f}}),fabric.util.object.extend(fabric.IText.prototype,{initHiddenTextarea:function(){this.hiddenTextarea=fabric.document.createElement("textarea"),this.hiddenTextarea.setAttribute("autocapitalize","off"),this.hiddenTextarea.style.cssText="position: absolute; top: 0; left: -9999px",fabric.document.body.appendChild(this.hiddenTextarea),fabric.util.addListener(this.hiddenTextarea,"keydown",this.onKeyDown.bind(this)),fabric.util.addListener(this.hiddenTextarea,"keypress",this.onKeyPress.bind(this)),fabric.util.addListener(this.hiddenTextarea,"copy",this.copy.bind(this)),fabric.util.addListener(this.hiddenTextarea,"paste",this.paste.bind(this)),!this._clickHandlerInitialized&&this.canvas&&(fabric.util.addListener(this.canvas.upperCanvasEl,"click",this.onClick.bind(this)),this._clickHandlerInitialized=!0)},_keysMap:{8:"removeChars",13:"insertNewline",37:"moveCursorLeft",38:"moveCursorUp",39:"moveCursorRight",40:"moveCursorDown",46:"forwardDelete"},_ctrlKeysMap:{65:"selectAll",88:"cut"},onClick:function(){this.hiddenTextarea&&this.hiddenTextarea.focus()},onKeyDown:function(e){if(!this.isEditing)return;if(e.keyCode in this._keysMap)this[this._keysMap[e.keyCode]](e);else{if(!(e.keyCode in this._ctrlKeysMap&&(e.ctrlKey||e.metaKey)))return;this[this._ctrlKeysMap[e.keyCode]](e)}e.stopPropagation(),this.canvas&&this.canvas.renderAll()},forwardDelete:function(e){this.selectionStart===this.selectionEnd&&this.moveCursorRight(e),this.removeChars(e)},copy:function(e){var t=this.getSelectedText(),n=this._getClipboardData(e);n&&n.setData("text",t),this.copiedText=t,this.copiedStyles=this.getSelectionStyles(this.selectionStart,this.selectionEnd)},paste:function(e){var t=null,n=this._getClipboardData(e);n?t=n.getData("text"):t=this.copiedText,t&&this.insertChars(t)},cut:function(e){if(this.selectionStart===this.selectionEnd)return;this.copy(),this.removeChars(e)},_getClipboardData:function(e){return e&&(e.clipboardData||fabric.window.clipboardData)},onKeyPress:function(e){if(!this.isEditing||e.metaKey||e.ctrlKey||e.keyCode===8||e.keyCode===13)return;this.insertChars(String.fromCharCode(e.which)),e.stopPropagation()},getDownCursorOffset:function(e,t){var n=t?this.selectionEnd:this.selectionStart,r=this.text.split(this._reNewline),i,s,o=this.text.slice(0,n),u=this.text.slice(n),a=o.slice(o.lastIndexOf("\n")+1),f=u.match(/(.*)\n?/)[1],l=(u.match(/.*\n(.*)\n?/)||{})[1]||"",c=this.get2DCursorLocation(n);if(c.lineIndex===r.length-1||e.metaKey)return this.text.length-n;var h=this._getWidthOfLine(this.ctx,c.lineIndex,r);s=this._getLineLeftOffset(h);var p=s,d=c.lineIndex;for(var v=0,m=a.length;vn){f=!0;var d=u-p,v=u,m=Math.abs(d-n),g=Math.abs(v-n);a=gthis.text.length&&(this.selectionStart=this.text.length),this.selectionEnd=this.selectionStart},moveCursorDownWithShift:function(e){if(this._selectionDirection==="left"&&this.selectionStart!==this.selectionEnd){this.selectionStart+=e,this._selectionDirection="left";return}this._selectionDirection="right",this.selectionEnd+=e,this.selectionEnd>this.text.length&&(this.selectionEnd=this.text.length)},getUpCursorOffset:function(e,t){var n=t?this.selectionEnd:this.selectionStart,r=this.get2DCursorLocation(n);if(r.lineIndex===0||e.metaKey)return n;var i=this.text.slice(0,n),s=i.slice(i.lastIndexOf("\n")+1),o=(i.match(/\n?(.*)\n.*$/)||{})[1]||"",u=this.text.split(this._reNewline),a,f=this._getWidthOfLine(this.ctx,r.lineIndex,u),l=this._getLineLeftOffset(f),c=l,h=r.lineIndex;for(var p=0,d=s.length;pn){f=!0;var d=u-p,v=u,m=Math.abs(d-n),g=Math.abs(v-n);a=g=this.text.length&&this.selectionEnd>=this.text.length)return;this.abortCursorAnimation(),this._currentCursorOpacity=1,e.shiftKey?this.moveCursorRightWithShift(e):this.moveCursorRightWithoutShift(e),this.initDelayedCursor()},moveCursorRightWithShift:function(e){this._selectionDirection==="left"&&this.selectionStart!==this.selectionEnd?this._moveRight(e,"selectionStart"):(this._selectionDirection="right",this._moveRight(e,"selectionEnd"),this.text.charAt(this.selectionEnd-1)==="\n"&&this.selectionEnd++,this.selectionEnd>this.text.length&&(this.selectionEnd=this.text.length))},moveCursorRightWithoutShift:function(e){this._selectionDirection="right",this.selectionStart===this.selectionEnd?(this._moveRight(e,"selectionStart"),this.selectionEnd=this.selectionStart):(this.selectionEnd+=this.getNumNewLinesInSelectedText(),this.selectionEnd>this.text.length&&(this.selectionEnd=this.text.length),this.selectionStart=this.selectionEnd)},removeChars:function(e){this.selectionStart===this.selectionEnd?this._removeCharsNearCursor(e):this._removeCharsFromTo(this.selectionStart,this.selectionEnd),this.selectionEnd=this.selectionStart,this._removeExtraneousStyles(),this.canvas&&this.canvas.renderAll().renderAll(),this.setCoords(),this.fire("changed"),this.canvas&&this.canvas.fire("text:changed",{target:this})},_removeCharsNearCursor:function(e){if(this.selectionStart!==0)if(e.metaKey){var t=this.findLineBoundaryLeft(this.selectionStart);this._removeCharsFromTo(t,this.selectionStart),this.selectionStart=t}else if(e.altKey){var n=this.findWordBoundaryLeft(this.selectionStart);this._removeCharsFromTo(n,this.selectionStart),this.selectionStart=n}else{var r=this.text.slice(this.selectionStart-1,this.selectionStart)==="\n";this.removeStyleObject(r),this.selectionStart--,this.text=this.text.slice(0,this.selectionStart)+this.text.slice(this.selectionStart+1)}}}),fabric.util.object.extend(fabric.IText.prototype,{_setSVGTextLineText:function(e,t,n,r,i,s){this.styles[t]?this._setSVGTextLineChars(e,t,n,r,i,s):this.callSuper("_setSVGTextLineText",e,t,n,r,i)},_setSVGTextLineChars:function(e,t,n,r,i,s){var o=t===0||this.useNative?"y":"dy",u=e.split(""),a=0,f=this._getSVGLineLeftOffset(t),l=this._getSVGLineTopOffset(t),c=this._getHeightOfLine(this.ctx,t);for(var h=0,p=u.length;h'].join("")},_createTextCharSpan:function(e,t,n,r,i,s){var o=this.getSvgStyles.call(fabric.util.object.extend({visible:!0,fill:this.fill,stroke:this.stroke,type:"text"},t));return['',fabric.util.string.escapeXml(e),""].join("")}}),function(){function request(e,t,n){var r=URL.parse(e);r.port||(r.port=r.protocol.indexOf("https:")===0?443:80);var i=r.port===443?HTTPS:HTTP,s=i.request({hostname:r.hostname,port:r.port,path:r.path,method:"GET"},function(e){var r="";t&&e.setEncoding(t),e.on("end",function(){n(r)}),e.on("data",function(t){e.statusCode===200&&(r+=t)})});s.on("error",function(e){e.errno===process.ECONNREFUSED?fabric.log("ECONNREFUSED: connection refused to "+r.hostname+":"+r.port):fabric.log(e.message)}),s.end()}function requestFs(e,t){var n=require("fs");n.readFile(e,function(e,n){if(e)throw fabric.log(e),e;t(n)})}if(typeof document!="undefined"&&typeof window!="undefined")return;var DOMParser=require("xmldom").DOMParser,URL=require("url"),HTTP=require("http"),HTTPS=require("https"),Canvas=require("canvas"),Image=require("canvas").Image;fabric.util.loadImage=function(e,t,n){function r(r){i.src=new Buffer(r,"binary"),i._src=e,t&&t.call(n,i)}var i=new Image;e&&(e instanceof Buffer||e.indexOf("data")===0)?(i.src=i._src=e,t&&t.call(n,i)):e&&e.indexOf("http")!==0?requestFs(e,r):e?request(e,"binary",r):t&&t.call(n,e)},fabric.loadSVGFromURL=function(e,t,n){e=e.replace(/^\n\s*/,"").replace(/\?.*$/,"").trim(),e.indexOf("http")!==0?requestFs(e,function(e){fabric.loadSVGFromString(e.toString(),t,n)}):request(e,"",function(e){fabric.loadSVGFromString(e,t,n)})},fabric.loadSVGFromString=function(e,t,n){var r=(new DOMParser).parseFromString(e);fabric.parseSVGDocument(r.documentElement,function(e,n){t&&t(e,n)},n)},fabric.util.getScript=function(url,callback){request(url,"",function(body){eval(body),callback&&callback()})},fabric.Image.fromObject=function(e,t){fabric.util.loadImage(e.src,function(n){var r=new fabric.Image(n);r._initConfig(e),r._initFilters(e,function(e){r.filters=e||[],t&&t(r)})})},fabric.createCanvasForNode=function(e,t,n,r){r=r||n;var i=fabric.document.createElement("canvas"),s=new Canvas(e||600,t||600,r);i.style={},i.width=s.width,i.height=s.height;var o=fabric.Canvas||fabric.StaticCanvas,u=new o(i,n);return u.contextContainer=s.getContext("2d"),u.nodeCanvas=s,u.Font=Canvas.Font,u},fabric.StaticCanvas.prototype.createPNGStream=function(){return this.nodeCanvas.createPNGStream()},fabric.StaticCanvas.prototype.createJPEGStream=function(e){return this.nodeCanvas.createJPEGStream(e)};var origSetWidth=fabric.StaticCanvas.prototype.setWidth;fabric.StaticCanvas.prototype.setWidth=function(e){return origSetWidth.call(this,e),this.nodeCanvas.width=e,this},fabric.Canvas&&(fabric.Canvas.prototype.setWidth=fabric.StaticCanvas.prototype.setWidth);var origSetHeight=fabric.StaticCanvas.prototype.setHeight;fabric.StaticCanvas.prototype.setHeight=function(e){return origSetHeight.call(this,e),this.nodeCanvas.height=e,this},fabric.Canvas&&(fabric.Canvas.prototype.setHeight=fabric.StaticCanvas.prototype.setHeight)}(); \ No newline at end of file diff --git a/dist/fabric.min.js.gz b/dist/fabric.min.js.gz index 46827bc99e3c573c98d4fe293bab7866af09157e..0ffa1185e21660c59a02d22e473e4a33f0aabf71 100644 GIT binary patch literal 56030 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 z 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 literal 54971 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

f7 z=Vr)d%oxne$rwfjb>$w?`{Q5{%#1Pcz3B_cjaHGnr`Bi!#F^1jAj0CD1nOE_(|S|P zVTJw6yoTq+6uYj3ic91etI=`ryNEJ=cEHvMlo52<Dt1d8<#tS9wrXP=x_cWn9Dvnj+mgyh|@LLaz@a!}#0iC!?KU zsah-bL;zym=_I2UwPlMgc5Y}3GG415R}#gMWyRHKFl8UXM*S{)P~B2dhw`@3xgt3Z zfCT~SejDrXB!04+Mgy_~FM^r9mTks~Qw$9*VCEYzi(Ea7?Ht9fJUu(8y^MW8j6ITf zdx2u>gLsb!K@p}i_1ZFa=~#CSA-zR9dbAsW4uY1O1eh_;de%X9l~o%>{K|J4SODEc zBB6J;Gs}h8%Zv3~cax}rBV|2AAZ)Z@n>NN6j`8Vy$iQoO+dFGh6dBFSj$~QAoi3|A zgc*-9NwQk<=5!j<9SEgyx(Ia#Gjv^706}(#TK$wNE0%Cj7GidMRhpH=I%z~*#eyTI z5vBG2UyeT7rY)#bQH)MvG?J#ZRsttg&VTs^?i(D^pAhn25BMMggbyF_&AoyAWPQu@ z%3%n)518<(JKyn}0c_S~M&l)DEly_bMqZt;(XuHlp-IkT-D>*P z7IImd2{hS z4N1F05>9dPY0zD-ss%{*CdvBMYKvRvrxvI6OQHbT8lJn)6FjfZ>~!|2>a;-%t3J;fROK;2MSVk`gn$zI`%HdyOJ zm{zzx4l8yR8xFRFN8c`2Y)tRY9eSq*dNa0bfJ2@dPYiZLPpD45!k4e2emdt-tE(k3 zX+qlVInk&9?UaHVoWro~4h<#zy1Yn335ZV4l6~mm+8z6oLOti%Q~+JHsI`n2Y&Fbk>BY#uPT>S!BCiWxv-b$VeKba zv?$)gl)yP*ND#$_!=%39nu$lgBy=$r#ePRZCyyMrImLcZ#ga97U-w(oRj9pcx;@UT zE9~!Oo%0k9RdZp`GY*Xt%X`L+a_=0gbnA|?NdeKU4q1ex?nD3)c+x}@!BBByWeaX0 zjH`$*5CVN0>jNka_W3ub0eh830Kx~lhhj&C@Q@_XS3Q8NEae9y3)Y*^S}?lv&G3=9 z-KCuWoO8}GgA(=9b$7AiQQB+M_=7~Xm-}5a)4UfdxtfPDww_@FePdE*9o0NaoQi~Y zu2z$gis~ZF-c}Avug;`p9Wq<8Z3bno^L?(!$`uSY^h!9*r07ce5F3x^2C?K)x;~1T zK7p>@(K8X7Y#xy`LMxdO)@?c(Xs+$E$Fa#Aw8-i8a%hGbPewWVxX8jvBt)x0$s)w- zybL%lXQ**pc!D?4onV|pc}#Ks0N-@!l}?3uA31CG0*%GDaz@I5+b@6jb12oC8< zdW}Ek$xZ7^Gb-!PnbtVHR8xA=Fkj;vHKCKtJ2YXq0C+d)?u#cgpY@kL8`AzuQ;*T9 zbVuUbxDwwsRE_h@By$8$QA%(up!ju{$MC6~W+oEU%3&{#ib(@)7RG0?z0FJ&_-M#m z4BWq1@Ldee)GUge&RHSc2ill7m5D~TiA7uFk%BStN+d<3_G0UZB!4$?WUB|iNe8gA z_#S+9nVv(r{L6TSrKoN&RXwHA5M5SiI1&^x!W^>%@w_VQ`djWts7qvsHXO=36ma4| zAlIbX(k|Ll0y+%j0%$5v3kH(xEI()OvAkGupo&^#1b@^+=YVfmNEoqw!wYY{$TAjB zcaf9Ub!^L%3j=ID#BzT(!gI zS&)ITDgWqrF*mlXN3mHKZOF_ul_d}s+1DUFJ0q^jbmHK765m~C*?D6Z@{vc)$GoV! zrplh-vQ)+$5MJrrJ~UN4E%i0(del#j=#t;NUgpIwpek*lP7mEA?Vq}Chd)~fO%Y_AX?)VgpslMiU<)+r>*?ja`twX zZiCMZQd20oBXs(>ODd-&yia-k zb^c4X+`KIp*)*(hg(U?{<>zZ4U8+#BU$MS`2CL#6T{pvdfXel#RV-(u;-eppQHW8X z){O3S-jgzx>EJY=y?+<0hM*1`>f12h=m2UCA}MO}sA3xH1II-hUp*>*2#LbvW3t)O1LER>yCw9P$Un0E-tvu4&IGS$b#k!J{w z));JPDq;H=5&)4jfCC;AZ1Ll)){~AfG3D!E?99p3J>)F4(axt0W2LbYAxJ%k#iGC8UbGq->Io1W3slBkYw%HBu}?Q;6pV+uhlKXhCVV zBh%S+=?jM=oy3_T!jiL_RHS~zWWgxH(u*XAn-iM-oWxl~wq({ab-DzHnbDuPXzh`? z4nwB_D4P@YqLi(xYTJB+M|K1M>X5%0#cHDeIz8+%_Q*xWuEj@JbEAoG9K-xL&{~DY zc}-XuTigQ)oJaQ92>D~zC6|ouC7o;&KbmqswJPJA6Y)Yvz}Rm}6b7U?@LAD*$M7e; z|Mm2M=CIMMd)Up{1dryqeFh zea%;HF@%^_Rd`45JZ15UPND|c22vD&kc+f9r*D(oGOo7*=mX$?(4|Mku*Ef)a^^q} z$kJk=MRj&0UaYz95v6_e)5#a#fA{kJSKq#kMT< zom8g!m3U#h+hKX(t7SfCl&rqU)LgeS>Lkcf<3QbKgw{(qD}58(RhFJEypcm^mO41i zq3yJF++G^@ZQ=_gy;)zx0L`q~QQsr{{TX67_%?W>QK>*l1aJj) zykN0X237{9KiaWnwC)IPI&%Y6tYOC@hNQh-{8O3@ZY;c6?hH5uaEM{wN~JJ z2zw7x(S&Sd_dE9cDg3^>INr>X(-{6h zy5u+daX3p}(~qaKUnsN|-6z&R!J z{%ajme?#x&u+2$I4;)EW%r_4^v3w=%c6c?wyVMuua)Ivm#BXxE{Ks6QvQ9)9mmnlU zX^FrSWpH`4o|NoDEpeshJy@puVcjpIgZh)-q_SmWv!VXw>6?KEtW;kyf6SuwtvX_^aY7t6IENZku41_jjLNvHN32XT!__VVx_&I>D<7e~3xs z-@VaH%%%uAob5iNtataHPL}Uq=#u#+t$%sg1Y^$KE|E*DBcnfDbp+V#B3mZMNbVlS zPiF(*u(RuLQOS+RMKAiJsr(wZTsQKu4$Ich#>n3zYJbdQMv@g{_nV ziJRh9%8ygLQs?kzJ)2l`U-hwfDUR@1jkS_X#A5#S0rlUoxE#0Yi0T4)s>+bclW?6D ztG0DfA(SmIU02ktJCtgpo_77yP1>D(|F+EQ2VUKjb+?^gP%Rnz`-jP1sJ6J?N+;Gy zIC##iN`RhPl$T)??W6Riob{3#|B^h0{X%)nr>7#Rsbke@|JtSze*n2i`Tn(-n!o4Q z8R`N(Z0U*IJIVkNAfbjNC;}9}Z*QOd?yFFcns9>@;&hMKco8swcUqZiIA7O5svsz^ z(b`CzzBQh{R_slgtoNVo*S!=dS-4qXwZ_YYEmkh`&J1Yy4-4|E$Bbe-<6p z?AMb2I^(}W%mnLy6#ZdBhgkG|Y>b3|Uudh~0b4`M{ZEoSyvtU3`mhZ^S^q$ultbzo zTxppMp6-*lVetH~`&{HO7>)KB56Wc@z0q(e{tMlW z?-6L?LCXen?sgl_5zPe}N`G%}gFg-Fe}R1GW462krHuzzVxme5weToioPWUXIO|>PuRgh;g8DyJLm_d6 z^iKG1U0h}lxNb4qzZMnx&3f77uqZvd?ca708}jTQx8?rOjWJp8wiVpfi;HwWS;PJ~ zfNPsCR16rYfI|v6q=4Uj!M4cG_?$doeTuCA)HSLA8+DCJh1tm6ITK=|p?p@aSJbF5 zsIvww%+Lae+XxNbL*Wk2H3oJ!7hx#-->yC1uvT_wl`nwM!fDllqr@C0$RTUa@T@A#LsLq$ACQUHAX!pq6v{2fu?0 z2`OO~ufN{d;tikDlQeO5PWv5!kZC7(Iyb^)qwLV|v-c#3_waH>z{4|&R> z1O$i{LFI*-8*7=^LjuSN;WDv2j&bWXp{0!}=rp3I zCd2;4NF$7mWTGA1l<9-;-Z(_Ga!%wly(uXbolCa)K1OJnQW$-B9+%0gRA2@MPdHgHyE*4-Uub1BgX#>!k+RXDNGfDx;HQ z2gJw*F5#e(rN_Lo!%d(Ao4_vSI>RcHAVseGGz0pO^YnN_$yp{^RLzDtIanC>LJh~>Fj(p&=+MPg?ql3(%1Rr#nrS-bXXy>CVUtpka18%IR!KIFTJ_$H5 zmt9CT6Zz{GXcbu`wRAvH$nE;-BCTwwFXr8;InHJw`)zD)TsEEzaSa4RKQRX7;F+|+ z_U6d-8(>lGOGwUFILMG7(z;L z9;2Z>FLjxq3(|R#N^fKFMY24Y$E(E9H;%7llF8!eid2vNokAC8an)N<&*D|jY79p6 z%6k_I2Dp82*uqj9*k?Op+GP*NhOshVndPc2zvV1DwvOpGoFIfX5Tp=Mj%<(PhJJOC z&87B_?|kED+cq~G!r_zH!ECF2d&Z$hDrgU!he_>RB9wrD`x+OvH;MBmNp(!#rdjXZkni{L}_*dK`pIWz4Keeo?2EoAtt z@!Q_Kkp*hA)7+I?=dNs-J68Kg&0ZHkkkz1eG)w(;hOEoJNiR##3R-Dni`3!Qrm>7P5s+o|&%gF^n35aQ;;%6+{`gsi3Tf_a*E4d& z>6_}cG1Zkj&uRRRe}s9j-miQoAo@P(1DU#x(OTD7@v2wmrQzpZn@FOSO*}%cDHiC0+lWNd|LUYkEXdLw}!KT?t-0U6aM0E_PL zflxy~eAIk0cj>K81-3cNAOW>pdP)v$%vbDN1$<&P$+R_7v1c`~rK1U;?StKtWqUS- zCfqiU&e(Lr?v-n|-HDovo07;+%a34Q%$Ms$_C|m|KB8qb(o+JXr;`4Jjg)u**jVmf2bD}t_HqtX$Qmv&{{vB982;+L5 zCpd*KYrGbxcEG`N`xFvzJ14(Y>B?vs-rwkVwiEHq+ut^EwVbc1v2dLx_3dUm0d7AK z4%2`~l~dAEYkxF0*vNin2ufr!R<$Kp6u`A&#>Q;Hqkn=b=2J9Aex^$T9VV(c{s0IH|-6Z))iE z9wA-kVcO%m8NKO)(feI zsV{OE(X8RD%Oe;iBN~{Ko{ed7pp#bNmYn(29Ax!8U1dLAE@?p73}g2ZL=z^AiPF}+ zo;=6pjJF*Y+N|d^^)T&RdPDi((9R>vW~DG~R)BRVj!QPZ(@@VWcw8odM2)F3Mz5XZ zuO4cO#;`mlU3{)@$w_npUsc#%sHH(TP3=IXodM^lcEX|8`PkD?V^ctLVKWHcXop2x z%%*$+nW5~>^Dt^zxofsK3hx>XHo-VpY=V~cS?^oY%W=J5?zY~LaqC`ZnX$;60qeSa zBn)k56MVvr_=(uhMb8<_MvkRKvW3%ezp>ybS+vBn^-KyB#AG!rslvGRr{%^ol=#Kb z0ru_16Ez~AdpufMQYCk}AQy3uv9iTlYMe}DPGe|x8kf$2XzjVvOrPEx^qT8mX}*DV z#kDMg3sd;)C}77Iy87DfZK0{2!u}Y+J&s_)Z~w}_<8W(b#xF1 z|2_(OO)vQOrvi@E?-xB*?n>IUnI!P%R;8D1?xjae^A7j3gLl|$fjV4V!>zfeQGt7k zEZfs)tvyNL?O9Y5`%a7bMOm2$iM&Z)yngfY`>)@hzy>>c^X*&s@zwu%os2#c@om_N zOc)>}0DGvGG~wQWJur&?{zntPUSC*DJ$ik>kRehcUfYXngchyv9g_JZM+MGnjM%6M zbYPC*n@H27%bBmBLK479*Epc-BkqEaGV$M1d?}pyvCYObE$F-@eU3tR=*O`0Zn*P4 z=|QYVznLHq1#HZxpKwLir=MH|2hp&S@;iNIwkd6DO^PcrRgMi6tC#b6R@Wu^8DV;l z57Oln0FZ4Mml7wFvhc@ zs`FDgnEo7(Mt_Y_19v!h8UfK?zh2}GInf@)8T`bmP!%s@!Aw?U6fr!EN6(+~G7g_Z zA@g+wBgn+ihy06Y`P0*E2@rrKO1AAVr;(1EB1p`e3G8R?6Tx9 z3A&QhGe=O;Manu@zkJCsX4AoLEG!sV*j*xDt=+bc#XA6OdbDT`7L zw(xq%q-||MpFrWrkV=H$Gmr44B`)Y8`TBWhE^rUhwjK|xf$-(RkdKWIphBxGB*n(D z%r~AB=;b1St(8{jPz-Y@^lZI&p+$O;FBVyW(~!c(6?dc=>ST?~{=BxH6wT@&_V?=x z6#lTDP)6=5LG{kkL*fE*sDF*OrRE{vP>^bx&Q+CUlj^9UN9;oL5a(7AR?0;j(_YCX z)b8OIY`cD4&bc0*DO6<(^EfA&+gJGH!C8J!1bpB=XCHjO+Dp+xv%t`029rXd^ ziY)Ag=RNaeMfhrBvX!?wPpV0CwJ~O=AZyUs>geEsJg~iAHPByKlFRn5~ZQi zyOHprk9%t&Mmj379dUQ3GW2JEcT4J&GfNXl&D42wEjE(8LisM`3P$YCspQfL<&%;V zTL}hbR4lIyR6GBK@9+|E_Q_2 zi^?2(#mXtd3l&9u+aQ`~JA{qQG6yDUh%<$>b&DFbaIY)Y#kf$4X>xsxi(?f$k79IBuYD(IELoM!@mni;HX2lNqXuu@vx2#OCOp z$MY^l3B7`^HtC4{QYK4KVOnPG`AmDTlO15+S{L{Wo-pmebRL&PhP8{9=tt&oK}$&? z&a}J{BiXJPvD?&iMz&3n-5NF%zjIU6TF_{4CPT3|?ETJs`6$)(lxX1C%9BD@)Ifo( zB`PZ0&lK?rDP(?zOYEHZ#G2Hjxz(mDZy5)_@BBmIzWxazqjENkZw@Gy z9>!_XkoFEcE2pychSG_+BI04x7lZ0qnxS?v#oE0TX&Ag`sJ(gQIr%1MC>2NdsK;kB zY|_tg@ZKP{4g*4~d!fugQ;RcYH(8s<~wp z3L8%lDRy{^8m1aC;S*ZbyiI#c@1#?+40dM9s+V28zPV{X2|VqjG!wUZd|;jSsqj`s zKJt~K6B}*M@X(J*<59C|JFxW4g~(KLdkH0lmQ9Ho`UtR{kU!d7J-B&ScBP(jTMou( zoDI}5HEC=uO3y{X+RzNnm*r`?B$+ZFzmvTFrd-$AqWrCxa#aAYn1gu;W-4N zqg?gqU)GvfyDeyf57Z5qWZmuahY( zvsy|=F5seBCF|o<5S^2Yqt)aBs=asteUU2}sN(cdl9ac%7e^ZJ8bSEH{%U>Ls<(=)8k8!Bj@E7&t$LUcS&AnF(J2lu?JXe{Zw`F9SeQ52MmLFR>vB1VG zqDi4C0<)!lhT00S)EjN7&k^-r3+N@wyTYS2-Dbi=7CD^RH)Lg&Ye>DAH)-8yMnIfZ z(`~EJ4!P=EHdWmQZ{51VV@3d!+X=RH%ca4t^tA0RW6@`=2l_gKHD72P>O8(k@b#^i zoZ*I$XSf3B8^()dDVF-`C}GHaH}gdEt7&swKvS&PJ#ghaM`fDcNO?Xzxkzh@VD4@f z;XJ;Ag}H)(TsUS%G;dGfEe9vR@s$*%t-m5SyAt`spiHF{5Ew5|~l6LKXub=4^4# zF;I=92)0*S)gR4GoMg`(s;!fnI(phDRps0rpX>; zbwV~FyrffvSdW=5U(jNHG^``c5p3BnQoCpBHq0YO@v0`LNr>5%ga~FTvcwLg=(H9> z!*#n!Li-wcDb8_HO)_;Q8FlD9wLu?;ro!dH;SlbZP8)_#-GcJqFi!1yEz^cw>%>Xx z?^LhT>y~x#(zOlJ=?dMHDK7ds>V)lXCfu{lgk8-Kvmoubx9e#&^x1{<@zl@c6{aw^3EqGHyV~?;`Dl30Xqyq&&RCPFB_VnGX=Ea86z*7lL6_>GWJF= zhIhCkT;oGxwoqlO<<{-#S6xqCAp9p+Om8&h_J%77L-{SlgsMtAhu8|QB_T)SSy>ZQ z&0vTp<+Mz)u#Co~lF%{7^r8_p#7?Y5FMA3MV5wG=bs~vl-cs2(Ue6>AOzI^j)8?k0 z@Q0|9kA_k$giRv@HSfP1IYmT8to>>%i zy^0XOL;=<}mLr0Ypp#-lSwzc=O5AkgdN3!=k}Q@mG(21`cRt)gZQC7aDKd1UT0km9 zoo)s+^YP^nOIfWi6ME6021ET*o&M}w;GHl^HOw?UI{lgu$$sSSyhHs{CH+yFZ_Dkc z3RQ=b{1o;T_}go6N&5Dlm!-zqhopHk%|a(E8Vl*Tb`-Tfj>yGfwFWD^x$1A{%InDdcx9rko5r+`;$*8e;JAW=qU#xBW#= z_e?vfj|yf&u#Wjalr1lnVG_RdJlz+o@pN-2nVt~bl;;&EN zy)pFN_2eNFHN{8)Mt3bL#L4mOE_{F@d%KVOugrB8-{`8$&J#XHzFaJ_#g}QZSY}nI z=|8iFJ^9?oQ`CBrFUs}lGJCbm=fAwmFV{;6IERrer!3m38-8)6HPoARh5*w{5OOcS z%*u5WY6-G|$cL`Y;?ZzO9?~OdnP=)e?Ne^A}wn+q75uR_t>TN0T34N=_4sw zpJjo8+?G;k2A8+*IX{R;@y%kbi-%1kiWr~M(Fm(C^kiUg%Hln=PekJ8fTSd+Hxr5# zD1LGM&6hN7F}2@g+?Dyec1HtaR_(G*~mJ$_6}QtVG(63HkUp-J1W z-Zlrr?m0kxwzgToHS$M}J)KE(B9Ylmw&+x@K?nAzMyT}(b4?^}jJF~@ZSFG#&WI+X z*f{+3J*$m?cNPz~PyeAmW6Sh6ZJmThs`)F#eAre(j&j;ZjM#lT<__v`r$L?UaLcs~ z2re%&YQeMgr4C)`warN+)VgL(q6mJ@1GP5#KK3q}g-W(CP3>J!G_EV|X|da0q@eO* z@ncynxa#PJbQInFG{nu+AE~3Co2o&Tb)yW@N!{fo>AywHA@{DSn_e$2`hD)k`{3ty z2knU;KQ3PMM>30|?cMHt=V(A`{rR1H)9dZpn@9_9LLQUG&`IF8kE zA(W0`v#KUFcq*jT{6b$@9V({X>m!SzDIy+ahW@!6Bxu;d@!rqH&x3gK=;!Ir{n>#S z+?CP^ASeCa12LvA&x=paGUC?J0vg?{ZS+ky1elt zp)O{dLP|dsmQi6?=$w&$>xYljaczlUjCT6AO_<4MdY8E}2>Vp+B*iyjmh7P!rNNaz zZV`6Nf^O8$c@GIM8Awr%CV2OCi(*9hKi3&gh7pZfLGt zK(`+^#~#zzpx2$9u1hD!7mwmhH;prxDH5chu!%uq=mX`D5*Mh$ z!InqD9oiUOHyGjt1IXja^%#WDGfLqjc&ZHC6SiNwYV7`JW`BU!8#M|%#HhQXDSM6hkZ zPc(nrt_xTEFnT5|TKl0U( zkm@Ey_}DhhdyTVn!(I4E>mq`|z5hMLGWo9|j&b_>8dXk#7p+|+3cnS!=$2!!(MXUZ zE>lOqiQC&nhVmKfbzIiZw70AB(r~e;(XE`sL@m=yK-&qj+Ob9{BF(G;*@i9X1$ugX zzL&M4&INy^r8Cgv#|*(S#++uU;hhSY02R zq5WcJx1pTH-XjAdOe_r6jyrvCbPbuW!_Zgk-lSmGhmQ!zD;a6e*VwOG=#!gmpR8G* z^5ZqN1offr>;avjG6vK^Ln~)kU*paLeYf_(HUmB`Kadu8wQj*?j9+fAjhvx;Wc*B+ zYMatsl4J+bMB{>6Yib=sDC@D7*_xS`$tq1jbSg1LG(=#bcCh4r2D2ZQMRA#`E;)W~O%omd?hHI7g( zH4lt@hI(h-<1j~=51Iey)}t~XcK3{Rcj>zzyr3@q5p|^Oi3uf{@S%@F6Pf0_o{e z8Sp;s`yc?)x}j9~f|2ydU-cKjUn@v7NbvP8iT+;ZC?}B`$?|a;pOuBL`+^>tzkraz zY0fn}B6`=85gyNcCs3icejUDsU(2vhcuT@;AcSjq{l3aqd^})NOa-_uUEvfp$0&tR zbOKcV>h%>mj>Tfc`B!V>3gw8s%?etaF1M7@KB&Iwh`n><84}+#GF8{5?Ty<|+{TELy}`z56Z=UU=S}|g zr|J(%jKtEgRH;{0hN0Y91>p}HA*AMonUVKQ&uL?mXEZZNsPVL@0eMx4ER`Q!RY)p` zw8h~?))u#3`Sg=;9BbK3`uaDo&X3wxEx3Ou`uCyV!Ksg|sD2(u-4-m^*!eAGDlJJ08R2QlYDTb%84fr-qyP;y9p1jW0F zY`sp&H_2{mWzxJzwsmC!&6hI*VLD@?sN^+<2@hHY)bOQ>;QinXi1yBSKB&eAlu z3BGDDh*M*mv<+hS%0gdnL^uCuwwc-(mz3PIsN_7`I5Dkjg_A?>0=xhE62MBx)GWU% z8zAczygT<&AYE99kgTDzjQu+(Uzr^hX_^D4{g z_vLr#B2SB&L-?n~`7(>lH7&X(n@SiFU9;HM?Uqr}UYNW1JEkVDp|NSeJj3`*xeQ5< z&KN{b-KIg$CZV~G(}?Nr6X4N@iN<=hLTRPw=4#$*YrBjlc{0~Z<*z1Z%Y5|{3UiKu zU&Mcue#HQ(BjCuwNO`N8m{3542MXwhVdoSKmS<8WdE8>cq8h)5Q>{7ERsUjqp%1}N zc!bnPcs||U=J@wIxwu3%LzbasFO63bI$nfQkLu`wCBzr33}%$M zHqb#MN3)A#b;esNXtAhg5(l7w`wjY{>BBFSD!eFB=L42n)k}>nA}04N$@^!(@V>Ac zLUDE=^B0sqetg#N$7gq)aJF5XvZ=A)KA@YgM7*R$IVX^24nWTx958V(rVG4pOyuH1 zxHSlablt#qUgZtPFAvJIv$l*V4Oe z8sjG1O5#cdOC3@ZE{oF=o0>K$4lx5a&Kmj_Do&By>NzVU@w_|w2A_MIF%62K#vqVkPh=LTTt5u_*2^)e91%i{$hTPo*LcLN9`SRn}#-k3@3DvLCb%; z$mbW4N1zrm8XZpxuFcVb_BwS&dF)$3yMRC=+LhQT)jQP z@K+M;T|dHFh|4~cmt1V&7qlACguLCO{RMjrSS5A5NVHs%6}SRc;4(=CA8>VaIk`f+ z^&~yMn#HSaw0{oN{}rp_TqR`#UcBW{OyN9U0#9gc1GfgJruV&=I6XNaOZb{A!|CPGe6kdb5lqYR5=Ldqpj<%3z_P7-$qJXl z`b81loF&}1%_3R%SMgP{hG8dcbD&kj1^SXdSKn9gJxP=Eqs!^CHySS|r*L2Yawiz2 zv)fyQKa?bYdKa4{g?m+XYH#_?s4U5yz3W5qz~VYSQW&D9|@A$_l?VVIYm- zANj69A6X-N?;SO&fbZ+Odk!wt=ngFeZXZ~mtrxqSzF&Rno2mVruZ(kk=sDgCT>;6y zy9i2xK6C#yRVEO_uOqmI*lje}|99&?+Kx6Ir#iH*_o&qMCDsPSsdZ?cp`dCRU+5YZ z7V2)TPbz9YkjS`JzF++wmx{SvKl)1fe${oMu-N-vCt8^w<)h0?*H1FZ2Jg^k z*PmOz^H^rtjC0wk-xqu|Y`MgS(Y8y#9kcceco)Xm*9>U2S1opHvv<>z-K}$u-Dm4c z7}_^4)(*iYM#KF#QQW=*uyJY+WX>KC@p2brUAy1}Gdil9*&toYx{n*Cs&*XMw!cBI zn1wtE`m5k~qbHYc|7YgnKY9sm1`@QPcG`$H&6*17D3ckH(Q=3m#QW#ALE543x=pR8 zb&)b3_8cDldmbIe8gR|8{oDS9LzsFF0XNa_cqCBEyUqleV7Eh|t>m4T*Zr6hZFOMJ9pH!z>t;ceKJnQKggeqpKWpExP6#+JAahAgU;s(imw${ zAoLXf!142T+9k_`rnzfxwCkV=MoX6R7X6B`og(&`YXY{TB>i5Li{H*|$A^wT+5pHu zVmlnJs7@Zy>yu!#w;~Pr7U-mPV!T#h{^fKh91jU{$N-`6;kw+fEyeC_DU|-dAx>|z zlIxGWWgAvxtz6uy_pz$mp^3c_8V5W?dx1csfB2j517Jdy7#bO@T4BXB6-TL_ zo4@>Mxr8yd!bNrKvpnB;itN-8X_z#LDq7ds+Z3JlPJ>M_4i+1f_vkn(Oizim{hTVY z1QLxQ&EfG1$FeaLkNg@-xI5w6h#*aE%& z#ATdDjsVCj51~v=d=X6+ejfyNd##_Jhpf7Je1#RpX)n3rD9p|Pw(HNIN_U@vcvm6E z*=(w>-KKn#UuQyd)JVq^?hd2z&}e}Nd{tro=)gLY;wZ@oK&RQNo2GDR8q;YiDjZm2 z)Urld{^KV{NNMaLaB31fiM`%+;wQl#`TBv@UM7KZ`|~7bwR0C_aj+M}dV6|R97F+T zzsACwUX8yu_!}J?z;DWl-#LD8h@2<|-UCKZj z+s~t$tGv!nm)ZEykoi*P_W-&+VqS^)?jT=Ocvg+s6ZakZ(VWO(ZE9#5>vzHWO`Q~- zgD>6p!t@FL?w>JO`QVA+m;ny))iQ+x_8>SokAo*c)WZVCK@cmK4ZMUJ(dK1-^5tNq z#ZeH62}@U{CJzs0at1=r)Bh&s$Mg@Oa^OHHmoC#M_}yQ~0G88CBy&Fzt%1`6CjW_X zXE5&ygRGvXtL&%CC9*cb(E$zei$Gf-cLrds__#We*fLq1G0A`RqeqF zxV78cko`z1b{WmfrE(c`(KM@i97N>z^VzefJf^g19a zzqu&urbsWdaWxP>W6U;Yx#LyZT;Ol`69Z**Q7*>8-(J6mrDdNT6?)Ah`x(T@Ddyz@ z6|)JD81=$oAsdjX1>E{~B65*7sTSK1Hcyi_>zZpC9HQw@SivcT`tQ+%>6&L%RaT~^ zc{YH+qJ%6kR&!Kgd;RL$w{O3D{pS03ufGrn=dwHx13hBAH!q7K6Ek!6|2n&(9<^Z@ z{8zX>oSIQ}(;oH!s*t7|(Idq}~4e{MkukN)Onc2u@-rj_o?F z;~+|Xu&)Q%F!5zbPsyRM#f%gpxQtD+c(j-g;?h^Nm+da|w9y}m0Az1=-DJ2Bk_^ad ziZl&YO(vXWwgxv*wc*rEk@z-7>aRaK$TWr=-W=aVA8I8$^p^*3_nWZyr~x} zY2AHym^e<7_1l$=Uve1w+rxToaYt?T-Rck|}O%R&OV18_dUw?BrFQQPu~w@bt9$w#clA>ltrJY0vOk&6$^ zNKLIbt8ovO(6w*E(&S{$VvywEYLs3hmQ^D*QMR~-P~HU{B9j}{Da0Cg6cbCqCCRa> zMHG+rrFTD6+H+Es0_%qK@bGhl1AuBCAXJ!^>*r!4#kR}sZ7k)Q4J@R+Y1Y})^r{Ul z3CU)n+44%~W9No&=t5%ddbf6Lbpn7))!zE96nMBKfLHeE>FWbaKO1>9WO0?m4oqv0 z>_Ju6R|+?9#4p?zBEVZ4((n`nbxtFA^NRL}^5f0e$>ss4rJXp3Rm`66f@@esA2Hm! z5(o>%Hq4IpkbAcjAfoMwW}Q3b{vJx4K7cbwKMOLnzLMKs1)68C@s{II?r848AQGYy z7tU1jpUcIeWtt|b(tQgfW}n}aG~30tQV&9e8-=6Z zJ>G{sS9P9l6Pk^$Yt}a`O)cFQ(Vi4n0~TqpA+OWXs;8LoGqkT7qR}jn9n|HX((W=7 gBEDz2APvs5At=Fr@ZsO4gCq;%zhEWgm83ia03G5k 0 && sweep === 0) { thArc -= 2 * Math.PI; } - + var segments = Math.ceil(Math.abs(thArc / (Math.PI * 0.5 + 0.001))), result = []; @@ -888,7 +927,9 @@ fabric.Collection = { var px = cosTh * (ox - x) + sinTh * (oy - y), py = cosTh * (oy - y) - sinTh * (ox - x), pl = (px * px) / (rx * rx) + (py * py) / (ry * ry); - pl *= 0.25; + + pl *= 0.25; + if (pl > 1) { pl = Math.sqrt(pl); rx *= pl; @@ -919,14 +960,15 @@ fabric.Collection = { var sinTh0 = Math.sin(th0), cosTh0 = Math.cos(th0), - sinTh1 = Math.sin(th1), - cosTh1 = Math.cos(th1); - - var a00 = cosTh * rx, + sinTh1 = Math.sin(th1), + cosTh1 = Math.cos(th1), + + a00 = cosTh * rx, a01 = -sinTh * ry, a10 = sinTh * rx, a11 = cosTh * ry, thHalf = 0.25 * (th1 - th0), + t = (8 / 3) * Math.sin(thHalf) * Math.sin(thHalf) / Math.sin(thHalf * 2), @@ -1369,7 +1411,9 @@ fabric.Collection = { IS_DONTENUM_BUGGY = (function(){ for (var p in { toString: 1 }) { - if (p === 'toString') return false; + if (p === 'toString') { + return false; + } } return true; })(), @@ -1472,7 +1516,9 @@ fabric.Collection = { t, i, len = methodNames.length; for (i = 0; i < len; i++) { t = typeof object[methodNames[i]]; - if (!(/^(?:function|object|unknown)$/).test(t)) return false; + if (!(/^(?:function|object|unknown)$/).test(t)) { + return false; + } } return true; } @@ -2983,13 +3029,44 @@ if (typeof console !== 'undefined') { if (ruleMatchesElement) { for (var property in fabric.cssRules[rule]) { - styles[property] = fabric.cssRules[rule][property]; + var attr = normalizeAttr(property), + value = normalizeValue(attr, fabric.cssRules[rule][property]); + styles[attr] = value; } } } return styles; } + + /** + * @private + */ + function parseUseDirectives(doc) { + var nodelist = doc.querySelectorAll("use"); + for (var i = 0; i < nodelist.length; i++) { + var el = nodelist[i]; + var xlink = el.getAttribute('xlink:href').substr(1); + var x = el.getAttribute('x') || 0; + var y = el.getAttribute('y') || 0; + var el2 = doc.getElementById(xlink).cloneNode(true); + var currentTrans = (el.getAttribute('transform') || '') + ' translate(' + x + ', ' + y + ')'; + for (var j = 0, attrs = el.attributes, l = attrs.length; j < l; j++) { + var attr = attrs.item(j); + if (attr.nodeName !== 'x' && attr.nodeName !== 'y' && attr.nodeName !== 'xlink:href') { + if (attr.nodeName === 'transform') { + currentTrans = currentTrans + ' ' + attr.nodeValue; + } else { + el2.setAttribute(attr.nodeName, attr.nodeValue); + } + } + } + el2.setAttribute('transform', currentTrans); + el2.removeAttribute('id'); + var pNode=el.parentNode; + pNode.replaceChild(el2, el); + } + } /** * Parses an SVG document, converts it to an array of corresponding fabric.* instances and passes them to a callback @@ -3030,9 +3107,11 @@ if (typeof console !== 'undefined') { return function(doc, callback, reviver) { if (!doc) return; - - var startTime = new Date(), - descendants = fabric.util.toArray(doc.getElementsByTagName('*')); + var startTime = new Date(); + + parseUseDirectives(doc); + + var descendants = fabric.util.toArray(doc.getElementsByTagName('*')); if (descendants.length === 0 && fabric.isLikelyNode) { // we're likely in node, where "o3-xml" library fails to gEBTN("*") @@ -3091,7 +3170,6 @@ if (typeof console !== 'undefined') { fabric.gradientDefs = fabric.getGradientDefs(doc); fabric.cssRules = fabric.getCSSRules(doc); - // Precedence of rules: style > class > attribute fabric.parseElements(elements, function(instances) { @@ -3107,46 +3185,46 @@ if (typeof console !== 'undefined') { * Used for caching SVG documents (loaded via `fabric.Canvas#loadSVGFromURL`) * @namespace */ - var svgCache = { + var svgCache = { - /** - * @param {String} name - * @param {Function} callback - */ - has: function (name, callback) { - callback(false); - }, + /** + * @param {String} name + * @param {Function} callback + */ + has: function (name, callback) { + callback(false); + }, - /** - * @param {String} url - * @param {Function} callback - */ - get: function () { - /* NOOP */ - }, + /** + * @param {String} url + * @param {Function} callback + */ + get: function () { + /* NOOP */ + }, - /** - * @param {String} url - * @param {Object} object - */ - set: function () { - /* NOOP */ - } - }; + /** + * @param {String} url + * @param {Object} object + */ + set: function () { + /* NOOP */ + } + }; /** * @private */ function _enlivenCachedObject(cachedObject) { - var objects = cachedObject.objects, - options = cachedObject.options; + var objects = cachedObject.objects, + options = cachedObject.options; - objects = objects.map(function (o) { - return fabric[capitalize(o.type)].fromObject(o); - }); + objects = objects.map(function (o) { + return fabric[capitalize(o.type)].fromObject(o); + }); - return ({ objects: objects, options: options }); + return ({ objects: objects, options: options }); } /** @@ -3403,7 +3481,6 @@ if (typeof console !== 'undefined') { loadSVGFromURL: function(url, callback, reviver) { url = url.replace(/^\n\s*/, '').trim(); - svgCache.has(url, function (hasUrl) { if (hasUrl) { svgCache.get(url, function (value) { @@ -5132,6 +5209,7 @@ fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ * @return {fabric.Shadow} thisArg */ initialize: function(options) { + if (typeof options === 'string') { options = this._parseShadow(options); } @@ -5373,6 +5451,13 @@ fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ */ imageSmoothingEnabled: true, + /** + * The transformation (in the format of Canvas transform) which focuses the viewport + * @type Array + * @default + */ + viewportTransform: [1, 0, 0, 1, 0, 0], + /** * Callback; invoked right before object is about to be scaled/rotated * @param {fabric.Object} target Object that's about to be scaled/rotated @@ -5569,7 +5654,7 @@ fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ * @private * @param {String} property Property to set ({@link fabric.StaticCanvas#backgroundImage|backgroundImage} * or {@link fabric.StaticCanvas#overlayImage|overlayImage}) - * @param {(fabric.Image|String)} image fabric.Image instance or URL of an image to set background or overlay to + * @param {(fabric.Image|String|null)} image fabric.Image instance, URL of an image or null to set background or overlay to * @param {Function} callback Callback to invoke when image is loaded and set as background or overlay * @param {Object} [options] Optional options to set for the {@link fabric.Image|image}. */ @@ -5592,11 +5677,11 @@ fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ * @private * @param {String} property Property to set ({@link fabric.StaticCanvas#backgroundColor|backgroundColor} * or {@link fabric.StaticCanvas#overlayColor|overlayColor}) - * @param {(Object|String)} color Object with pattern information or color value + * @param {(Object|String|null)} color Object with pattern information, color value or null * @param {Function} [callback] Callback is invoked when color is set */ __setBgOverlayColor: function(property, color, callback) { - if (color.source) { + if (color && color.source) { var _this = this; fabric.util.loadImage(color.source, function(img) { _this[property] = new fabric.Pattern({ @@ -5766,6 +5851,92 @@ fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ return this; }, + /** + * Returns canvas zoom level + * @return {Number} + */ + getZoom: function () { + return Math.sqrt(this.viewportTransform[0] * this.viewportTransform[3]); + }, + + /** + * Sets viewport transform of this canvas instance + * @param {Array} vpt the transform in the form of context.transform + * @return {fabric.Canvas} instance + * @chainable true + */ + setViewportTransform: function (vpt) { + this.viewportTransform = vpt; + this.renderAll(); + for (var i = 0, len = this._objects.length; i < len; i++) { + this._objects[i].setCoords(); + } + return this; + }, + + /** + * Sets zoom level of this canvas instance, zoom centered around point + * @param {fabric.Point} point to zoom with respect to + * @param {Number} value to set zoom to, less than 1 zooms out + * @return {fabric.Canvas} instance + * @chainable true + */ + zoomToPoint: function (point, value) { + // TODO: just change the scale, preserve other transformations + var before = point; + point = fabric.util.transformPoint(point, fabric.util.invertTransform(this.viewportTransform)); + this.viewportTransform[0] = value; + this.viewportTransform[3] = value; + var after = fabric.util.transformPoint(point, this.viewportTransform); + this.viewportTransform[4] += before.x - after.x; + this.viewportTransform[5] += before.y - after.y; + this.renderAll(); + for (var i = 0, len = this._objects.length; i < len; i++) { + this._objects[i].setCoords(); + } + return this; + }, + + /** + * Sets zoom level of this canvas instance + * @param {Number} value to set zoom to, less than 1 zooms out + * @return {fabric.Canvas} instance + * @chainable true + */ + setZoom: function (value) { + this.zoomToPoint(new fabric.Point(0, 0), value); + return this; + }, + + /** + * Pan viewport so as to place point at top left corner of canvas + * @param {fabric.Point} point to move to + * @return {fabric.Canvas} instance + * @chainable true + */ + absolutePan: function (point) { + this.viewportTransform[4] = -point.x; + this.viewportTransform[5] = -point.y; + this.renderAll(); + for (var i = 0, len = this._objects.length; i < len; i++) { + this._objects[i].setCoords(); + } + return this; + }, + + /** + * Pans viewpoint relatively + * @param {fabric.Point} point (position vector) to move by + * @return {fabric.Canvas} instance + * @chainable true + */ + relativePan: function (point) { + return this.absolutePan(new fabric.Point( + -point.x - this.viewportTransform[4], + -point.y - this.viewportTransform[5] + )); + }, + /** * Returns <canvas> element corresponding to this instance * @return {HTMLCanvasElement} @@ -5798,17 +5969,13 @@ fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ */ _draw: function (ctx, object) { if (!object) return; - - if (this.controlsAboveOverlay) { - var hasBorders = object.hasBorders, hasControls = object.hasControls; - object.hasBorders = object.hasControls = false; - object.render(ctx); - object.hasBorders = hasBorders; - object.hasControls = hasControls; - } - else { - object.render(ctx); - } + + ctx.save(); + var v = this.viewportTransform; + ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]); + object.render(ctx); + ctx.restore(); + if (!this.controlsAboveOverlay) object._renderControls(ctx); }, /** @@ -5817,8 +5984,8 @@ fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ */ _onObjectAdded: function(obj) { this.stateful && obj.setupState(); - obj.setCoords(); obj.canvas = this; + obj.setCoords(); this.fire('object:added', { target: obj }); obj.fire('added'); }, @@ -5887,7 +6054,6 @@ fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ * @chainable */ renderAll: function (allOnTop) { - var canvasToDrawOn = this[(allOnTop === true && this.interactive) ? 'contextTop' : 'contextContainer'], activeGroup = this.getActiveGroup(); @@ -5986,7 +6152,7 @@ fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ this.height); } if (this.backgroundImage) { - this.backgroundImage.render(ctx); + this._draw(ctx, this.backgroundImage); } }, @@ -6007,7 +6173,7 @@ fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ this.height); } if (this.overlayImage) { - this.overlayImage.render(ctx); + this._draw(ctx, this.overlayImage); } }, @@ -6163,7 +6329,6 @@ fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ } } - return data; }, @@ -6816,6 +6981,9 @@ fabric.BaseBrush = fabric.util.createClass(/** @lends fabric.BaseBrush.prototype */ _render: function() { var ctx = this.canvas.contextTop; + var v = this.canvas.viewportTransform; + ctx.save(); + ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]); ctx.beginPath(); var p1 = this._points[0], @@ -6845,6 +7013,7 @@ fabric.BaseBrush = fabric.util.createClass(/** @lends fabric.BaseBrush.prototype // the bezier control point ctx.lineTo(p1.x, p1.y); ctx.stroke(); + ctx.restore(); }, /** @@ -6856,7 +7025,7 @@ fabric.BaseBrush = fabric.util.createClass(/** @lends fabric.BaseBrush.prototype this.box = this.getPathBoundingBox(this._points); return this.convertPointsToSVGPath( this._points, this.box.minx, this.box.maxx, this.box.miny, this.box.maxy); - }, + }, /** * Returns bounding box of a path based on given points @@ -7017,13 +7186,18 @@ fabric.CircleBrush = fabric.util.createClass(fabric.BaseBrush, /** @lends fabric */ drawDot: function(pointer) { var point = this.addPoint(pointer), - ctx = this.canvas.contextTop; + ctx = this.canvas.contextTop, + v = this.canvas.viewportTransform; + ctx.save(); + ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]); ctx.fillStyle = point.fill; ctx.beginPath(); ctx.arc(point.x, point.y, point.radius, 0, Math.PI * 2, false); ctx.closePath(); ctx.fill(); + + ctx.restore(); }, /** @@ -7069,6 +7243,7 @@ fabric.CircleBrush = fabric.util.createClass(fabric.BaseBrush, /** @lends fabric circles.push(circle); } var group = new fabric.Group(circles, { originX: 'center', originY: 'center' }); + group.canvas = this.canvas; this.canvas.add(group); this.canvas.fire('path:created', { path: group }); @@ -7217,6 +7392,8 @@ fabric.SprayBrush = fabric.util.createClass( fabric.BaseBrush, /** @lends fabric } var group = new fabric.Group(rects, { originX: 'center', originY: 'center' }); + group.canvas = this.canvas; + this.canvas.add(group); this.canvas.fire('path:created', { path: group }); @@ -7251,7 +7428,10 @@ fabric.SprayBrush = fabric.util.createClass( fabric.BaseBrush, /** @lends fabric render: function() { var ctx = this.canvas.contextTop; ctx.fillStyle = this.color; + + var v = this.canvas.viewportTransform; ctx.save(); + ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]); for (var i = 0, len = this.sprayChunkPoints.length; i < len; i++) { var point = this.sprayChunkPoints[i]; @@ -7285,8 +7465,9 @@ fabric.SprayBrush = fabric.util.createClass( fabric.BaseBrush, /** @lends fabric else { width = this.dotWidth; } - - var point = { x: x, y: y, width: width }; + + var point = new fabric.Point(x, y); + point.width = width; if (this.randomOpacity) { point.opacity = fabric.util.getRandomInt(0, 100) / 100; @@ -7609,7 +7790,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab * @return {Boolean} true if point is contained within an area of given object */ containsPoint: function (e, target) { - var pointer = this.getPointer(e), + var pointer = this.getPointer(e, true), xy = this._normalizePointer(target, pointer); // http://www.geog.ubc.ca/courses/klink/gis.notes/ncgia/u32.html @@ -7627,11 +7808,14 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab isObjectInGroup = ( activeGroup && object.type !== 'group' && - activeGroup.contains(object)); + activeGroup.contains(object)), + lt; if (isObjectInGroup) { - x -= activeGroup.left; - y -= activeGroup.top; + lt = new fabric.Point(activeGroup.left, activeGroup.top); + lt = fabric.util.transformPoint(lt, this.viewportTransform, true); + x -= lt.x; + y -= lt.y; } return { x: x, y: y }; }, @@ -7762,7 +7946,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab if (!target) return; var pointer = this.getPointer(e), - corner = target._findTargetCorner(pointer), + corner = target._findTargetCorner(this.getPointer(e, true)), action = this._getActionFromCorner(target, corner), origin = this._getOriginFromCorner(target, corner); @@ -7972,8 +8156,8 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab /** * Rotates object by invoking its rotate method * @private - * @param x {Number} pointer's x coordinate - * @param y {Number} pointer's y coordinate + * @param {Number} x pointer's x coordinate + * @param {Number} y pointer's y coordinate */ _rotateObject: function (x, y) { @@ -7994,9 +8178,11 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab }, /** - * @private + * Set the cursor type of the canvas element + * @param {String} value Cursor type of the canvas element. + * @see http://www.w3.org/TR/css3-ui/#cursor */ - _setCursor: function (value) { + setCursor: function (value) { this.upperCanvasEl.style.cursor = value; }, @@ -8067,7 +8253,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab this.lastRenderedObjectWithControlsAboveOverlay && this.lastRenderedObjectWithControlsAboveOverlay.visible && this.containsPoint(e, this.lastRenderedObjectWithControlsAboveOverlay) && - this.lastRenderedObjectWithControlsAboveOverlay._findTargetCorner(this.getPointer(e))); + this.lastRenderedObjectWithControlsAboveOverlay._findTargetCorner(this.getPointer(e, true))); }, /** @@ -8090,6 +8276,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab var target = this._searchPossibleTargets(e); this._fireOverOutEvents(target); + return target; }, @@ -8142,9 +8329,8 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab // Cache all targets where their bounding box contains point. var target, - pointer = this.getPointer(e); - - var i = this._objects.length; + pointer = this.getPointer(e, true), + i = this._objects.length; while (i--) { if (this._checkTarget(e, this._objects[i], pointer)){ @@ -8162,24 +8348,36 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab * @param {Event} e * @return {Object} object with "x" and "y" number values */ - getPointer: function (e) { - var pointer = getPointer(e, this.upperCanvasEl), - bounds = this.upperCanvasEl.getBoundingClientRect(), + getPointer: function (e, ignoreZoom, upperCanvasEl) { + if (!upperCanvasEl) { + upperCanvasEl = this.upperCanvasEl; + } + var pointer = getPointer(e, upperCanvasEl), + bounds = upperCanvasEl.getBoundingClientRect(), cssScale; + pointer.x = pointer.x - this._offset.left; + pointer.y = pointer.y - this._offset.top; + if (!ignoreZoom) { + pointer = fabric.util.transformPoint( + pointer, + fabric.util.invertTransform(this.viewportTransform) + ); + } + if (bounds.width === 0 || bounds.height === 0) { // If bounds are not available (i.e. not visible), do not apply scale. cssScale = { width: 1, height: 1 }; } else { cssScale = { - width: this.upperCanvasEl.width / bounds.width, - height: this.upperCanvasEl.height / bounds.height + width: upperCanvasEl.width / bounds.width, + height: upperCanvasEl.height / bounds.height }; } return { - x: (pointer.x - this._offset.left) * cssScale.width, - y: (pointer.y - this._offset.top) * cssScale.height + x: pointer.x * cssScale.width, + y: pointer.y * cssScale.height }; }, @@ -8338,7 +8536,6 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab _setActiveGroup: function(group) { this._activeGroup = group; if (group) { - group.canvas = this; group.set('active', true); } }, @@ -8437,7 +8634,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab * @private */ _drawGroupControls: function(ctx, activeGroup) { - this._drawControls(ctx, activeGroup, 'Group'); + activeGroup._renderControls(ctx); }, /** @@ -8446,19 +8643,9 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab _drawObjectsControls: function(ctx) { for (var i = 0, len = this._objects.length; i < len; ++i) { if (!this._objects[i] || !this._objects[i].active) continue; - this._drawControls(ctx, this._objects[i], 'Object'); + this._objects[i]._renderControls(ctx); this.lastRenderedObjectWithControlsAboveOverlay = this._objects[i]; } - }, - - /** - * @private - */ - _drawControls: function(ctx, object, klass) { - ctx.save(); - fabric[klass].prototype.transform.call(object, ctx); - object.drawBorders(ctx).drawControls(ctx); - ctx.restore(); } }); @@ -8640,7 +8827,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab if (e.type === 'touchstart') { // Unbind mousedown to prevent double triggers from touch devices - removeListener(this.upperCanvasEl, 'mousedown', this._onMouseDown); + removeListener(this.upperCanvasEl, 'mousedown', this._onMouseDown); } else { addListener(fabric.document, 'mouseup', this._onMouseUp); @@ -8821,7 +9008,9 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab if (this.clipTo) { fabric.util.clipContext(this, this.contextTop); } - this.freeDrawingBrush.onMouseDown(this.getPointer(e)); + var ivt = fabric.util.invertTransform(this.viewportTransform), + pointer = fabric.util.transformPoint(this.getPointer(e, true), ivt); + this.freeDrawingBrush.onMouseDown(pointer); this.fire('mouse:down', { e: e }); }, @@ -8831,10 +9020,11 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab */ _onMouseMoveInDrawingMode: function(e) { if (this._isCurrentlyDrawing) { - var pointer = this.getPointer(e); + var ivt = fabric.util.invertTransform(this.viewportTransform), + pointer = fabric.util.transformPoint(this.getPointer(e, true), ivt); this.freeDrawingBrush.onMouseMove(pointer); } - this.upperCanvasEl.style.cursor = this.freeDrawingCursor; + this.setCursor(this.freeDrawingCursor); this.fire('mouse:move', { e: e }); }, @@ -8874,7 +9064,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab if (this._currentTransform) return; var target = this.findTarget(e), - pointer = this.getPointer(e); + pointer = this.getPointer(e, true); // save pointer for check in __onMouseUp event this._previousPointer = pointer; @@ -9001,7 +9191,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab // We initially clicked in an empty area, so we draw a box for multiple selection if (groupSelector) { - pointer = this.getPointer(e); + pointer = this.getPointer(e, true); groupSelector.left = pointer.x - groupSelector.ex; groupSelector.top = pointer.y - groupSelector.ey; @@ -9013,7 +9203,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab target = this.findTarget(e); if (!target || target && !target.selectable) { - this.upperCanvasEl.style.cursor = this.defaultCursor; + this.setCursor(this.defaultCursor); } else { this._setCursorFromEvent(e, target); @@ -9032,7 +9222,6 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab * @param {Event} e Event fired on mousemove */ _transformObject: function(e) { - var pointer = this.getPointer(e), transform = this._currentTransform; @@ -9073,7 +9262,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab else { this._translateObject(x, y); this._fire('moving', target, e); - this._setCursor(this.moveCursor); + this.setCursor(this.moveCursor); } }, @@ -9131,10 +9320,8 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab * @param {Object} target Object that the mouse is hovering, if so. */ _setCursorFromEvent: function (e, target) { - var style = this.upperCanvasEl.style; - if (!target || !target.selectable) { - style.cursor = this.defaultCursor; + this.setCursor(this.defaultCursor); return false; } else { @@ -9142,10 +9329,10 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab // only show proper corner when group selection is not active corner = target._findTargetCorner && (!activeGroup || !activeGroup.contains(target)) - && target._findTargetCorner(this.getPointer(e)); + && target._findTargetCorner(this.getPointer(e, true)); if (!corner) { - style.cursor = target.hoverCursor || this.hoverCursor; + this.setCursor(target.hoverCursor || this.hoverCursor); } else { this._setCornerCursor(corner, target); @@ -9158,16 +9345,14 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab * @private */ _setCornerCursor: function(corner, target) { - var style = this.upperCanvasEl.style; - if (corner in cursorOffset) { - style.cursor = this._getRotatedCornerCursor(corner, target); + this.setCursor(this._getRotatedCornerCursor(corner, target)); } else if (corner === 'mtr' && target.hasRotatingPoint) { - style.cursor = this.rotationCursor; + this.setCursor(this.rotationCursor); } else { - style.cursor = this.defaultCursor; + this.setCursor(this.defaultCursor); return false; } }, @@ -9276,6 +9461,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab if (this._activeObject && target !== this._activeObject) { var group = this._createGroup(target); + group.addWithUpdate(); this.setActiveGroup(group); this._activeObject = null; @@ -9300,7 +9486,8 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab return new fabric.Group(groupObjects, { originX: 'center', - originY: 'center' + originY: 'center', + canvas: this }); }, @@ -9319,8 +9506,10 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab else if (group.length > 1) { group = new fabric.Group(group.reverse(), { originX: 'center', - originY: 'center' + originY: 'center', + canvas: this }); + group.addWithUpdate(); this.setActiveGroup(group, e); group.saveCoords(); this.fire('selection:created', { target: group }); @@ -9375,7 +9564,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab if (activeGroup) { activeGroup.setObjectsCoords().setCoords(); activeGroup.isMoving = false; - this._setCursor(this.defaultCursor); + this.setCursor(this.defaultCursor); } // clear selection and current transformation @@ -10563,6 +10752,9 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati * @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) { + if (this.group) { + this.group.transform(ctx, fromLeft); + } ctx.globalAlpha = this.opacity; var center = fromLeft ? this._getLeftTopCoords() : this.getCenterPoint(); @@ -10751,6 +10943,18 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati return this; }, + /** + * Retrieves viewportTransform from Object's canvas if possible + * @method getViewportTransform + * @memberOf fabric.Object.prototype + * @return {Boolean} flipY value // TODO + */ + getViewportTransform: function() { + if (this.canvas && this.canvas.viewportTransform) + return this.canvas.viewportTransform; + return [1, 0, 0, 1, 0, 0]; + }, + /** * Renders an object on a specified context * @param {CanvasRenderingContext2D} ctx Context to render on @@ -10780,19 +10984,14 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati this._render(ctx, noTransform); this.clipTo && ctx.restore(); this._removeShadow(ctx); - this._restoreFillRule(ctx); - if (this.active && !noTransform) { - this.drawBorders(ctx); - this.drawControls(ctx); - } - ctx.restore(); }, _transform: function(ctx, noTransform) { var m = this.transformMatrix; + if (m && !this.group) { ctx.setTransform(m[0], m[1], m[2], m[3], m[4], m[5]); } @@ -10821,6 +11020,35 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati } }, + /** + * Renders controls and borders for the object + * @param {CanvasRenderingContext2D} ctx Context to render on + * @param {Boolean} [noTransform] When true, context is not transformed + */ + _renderControls: function(ctx, noTransform) { + var v = this.getViewportTransform(); + + ctx.save(); + if (this.active && !noTransform) { + var center; + if (this.group) { + center = fabric.util.transformPoint(this.group.getCenterPoint(), v); + ctx.translate(center.x, center.y); + ctx.rotate(degreesToRadians(this.group.angle)); + } + center = fabric.util.transformPoint(this.getCenterPoint(), v, null != this.group); + if (this.group) { + center.x *= this.group.scaleX; + center.y *= this.group.scaleY; + } + ctx.translate(center.x, center.y); + ctx.rotate(degreesToRadians(this.angle)); + this.drawBorders(ctx); + this.drawControls(ctx); + } + ctx.restore(); + }, + /** * @private * @param {CanvasRenderingContext2D} ctx Context to render on @@ -11135,7 +11363,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati * canvas.renderAll(); */ setShadow: function(options) { - return this.set('shadow', new fabric.Shadow(options)); + return this.set('shadow', options ? new fabric.Shadow(options) : null); }, /** @@ -11840,11 +12068,15 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati setCoords: function() { var strokeWidth = this.strokeWidth > 1 ? this.strokeWidth : 0, - padding = this.padding, - theta = degreesToRadians(this.angle); + theta = degreesToRadians(this.angle), + vpt = this.getViewportTransform(); - this.currentWidth = (this.width + strokeWidth) * this.scaleX + padding * 2; - this.currentHeight = (this.height + strokeWidth) * this.scaleY + padding * 2; + var f = function (p) { + return fabric.util.transformPoint(p, vpt); + }; + + this.currentWidth = (this.width + strokeWidth) * this.scaleX; + this.currentHeight = (this.height + strokeWidth) * this.scaleY; // If width is negative, make postive. Fixes path selection issue if (this.currentWidth < 0) { @@ -11862,45 +12094,34 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati offsetY = Math.sin(_angle + theta) * _hypotenuse, sinTh = Math.sin(theta), cosTh = Math.cos(theta), - coords = this.getCenterPoint(), + wh = new fabric.Point(this.currentWidth, this.currentHeight), + _tl = new fabric.Point(coords.x - offsetX, coords.y - offsetY), + _tr = new fabric.Point(_tl.x + (wh.x * cosTh), _tl.y + (wh.x * sinTh)), + _bl = new fabric.Point(_tl.x - (wh.y * sinTh), _tl.y + (wh.y * cosTh)), + _mt = new fabric.Point(_tl.x + (wh.x/2 * cosTh), _tl.y + (wh.x/2 * sinTh)), + tl = f(_tl), + tr = f(_tr), + br = f(new fabric.Point(_tr.x - (wh.y * sinTh), _tr.y + (wh.y * cosTh))), + bl = f(_bl), + ml = f(new fabric.Point(_tl.x - (wh.y/2 * sinTh), _tl.y + (wh.y/2 * cosTh))), + mt = f(_mt), + mr = f(new fabric.Point(_tr.x - (wh.y/2 * sinTh), _tr.y + (wh.y/2 * cosTh))), + mb = f(new fabric.Point(_bl.x + (wh.x/2 * cosTh), _bl.y + (wh.x/2 * sinTh))), + mtr = f(new fabric.Point(_mt.x, _mt.y)); - tl = { - x: coords.x - offsetX, - y: coords.y - offsetY - }, - tr = { - x: tl.x + (this.currentWidth * cosTh), - y: tl.y + (this.currentWidth * sinTh) - }, - br = { - x: tr.x - (this.currentHeight * sinTh), - y: tr.y + (this.currentHeight * cosTh) - }, - bl = { - x: tl.x - (this.currentHeight * sinTh), - y: tl.y + (this.currentHeight * cosTh) - }, - ml = { - x: tl.x - (this.currentHeight/2 * sinTh), - y: tl.y + (this.currentHeight/2 * cosTh) - }, - mt = { - x: tl.x + (this.currentWidth/2 * cosTh), - y: tl.y + (this.currentWidth/2 * sinTh) - }, - mr = { - x: tr.x - (this.currentHeight/2 * sinTh), - y: tr.y + (this.currentHeight/2 * cosTh) - }, - mb = { - x: bl.x + (this.currentWidth/2 * cosTh), - y: bl.y + (this.currentWidth/2 * sinTh) - }, - mtr = { - x: mt.x, - y: mt.y - }; + // padding + var padX = Math.cos(_angle + theta) * this.padding * Math.sqrt(2), + padY = Math.sin(_angle + theta) * this.padding * Math.sqrt(2); + tl = tl.add(new fabric.Point(-padX, -padY)); + tr = tr.add(new fabric.Point(padY, -padX)); + br = br.add(new fabric.Point(padX, padY)); + bl = bl.add(new fabric.Point(-padY, padX)); + ml = ml.add(new fabric.Point((-padX - padY) / 2, (-padY + padX) / 2)); + mt = mt.add(new fabric.Point((padY - padX) / 2, -(padY + padX) / 2)); + mr = mr.add(new fabric.Point((padY + padX) / 2, (padY - padX) / 2)); + mb = mb.add(new fabric.Point((padX - padY) / 2, (padX + padY) / 2)); + mtr = mtr.add(new fabric.Point((padY - padX) / 2, -(padY + padX) / 2)); // debugging @@ -12064,7 +12285,8 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot getSvgTransform: function() { var toFixed = fabric.util.toFixed, angle = this.getAngle(), - center = this.getCenterPoint(), + vpt = this.getViewportTransform(), + center = fabric.util.transformPoint(this.getCenterPoint(), vpt), NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS, @@ -12078,12 +12300,12 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot ? (' rotate(' + toFixed(angle, NUM_FRACTION_DIGITS) + ')') : '', - scalePart = (this.scaleX === 1 && this.scaleY === 1) + scalePart = (this.scaleX === 1 && this.scaleY === 1 && vpt[0] === 1 && vpt[3] === 1) ? '' : (' scale(' + - toFixed(this.scaleX, NUM_FRACTION_DIGITS) + + toFixed(this.scaleX * vpt[0], NUM_FRACTION_DIGITS) + ' ' + - toFixed(this.scaleY, NUM_FRACTION_DIGITS) + + toFixed(this.scaleY * vpt[3], NUM_FRACTION_DIGITS) + ')'), flipXPart = this.flipX ? 'matrix(-1 0 0 1 0 0) ' : '', @@ -12166,7 +12388,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot (function(){ var degreesToRadians = fabric.util.degreesToRadians, - isVML = typeof G_vmlCanvasManager !== 'undefined'; + isVML = function() { return typeof G_vmlCanvasManager !== 'undefined'; }; fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ { @@ -12183,7 +12405,9 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot * @return {String|Boolean} corner code (tl, tr, bl, br, etc.), or false if nothing is found */ _findTargetCorner: function(pointer) { - if (!this.hasControls || !this.active) return false; + if (!this.hasControls || !this.active) { + return false; + } var ex = pointer.x, ey = pointer.y, @@ -12440,25 +12664,32 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot scaleY = 1 / this._constrainScale(this.scaleY); ctx.lineWidth = 1 / this.borderScaleFactor; - - ctx.scale(scaleX, scaleY); - - var w = this.getWidth(), - h = this.getHeight(); + + var vpt = this.getViewportTransform(), + wh = fabric.util.transformPoint(new fabric.Point(this.getWidth(), this.getHeight()), vpt, true), + sxy = fabric.util.transformPoint(new fabric.Point(scaleX, scaleY), vpt, true), + w = wh.x, + h = wh.y, + sx= sxy.x, + sy= sxy.y; + if (this.group) { + w = w * this.group.scaleX; + h = h * this.group.scaleY; + } ctx.strokeRect( - ~~(-(w / 2) - padding - strokeWidth / 2 * this.scaleX) - 0.5, // offset needed to make lines look sharper - ~~(-(h / 2) - padding - strokeWidth / 2 * this.scaleY) - 0.5, - ~~(w + padding2 + strokeWidth * this.scaleX) + 1, // double offset needed to make lines look sharper - ~~(h + padding2 + strokeWidth * this.scaleY) + 1 + ~~(-(w / 2) - padding - strokeWidth / 2 * sx) - 0.5, // offset needed to make lines look sharper + ~~(-(h / 2) - padding - strokeWidth / 2 * sy) - 0.5, + ~~(w + padding2 + strokeWidth * sx) + 1, // double offset needed to make lines look sharper + ~~(h + padding2 + strokeWidth * sy) + 1 ); if (this.hasRotatingPoint && this.isControlVisible('mtr') && !this.get('lockRotation') && this.hasControls) { var rotateHeight = ( this.flipY - ? h + (strokeWidth * this.scaleY) + (padding * 2) - : -h - (strokeWidth * this.scaleY) - (padding * 2) + ? h + (strokeWidth * sx) + (padding * 2) + : -h - (strokeWidth * sy) - (padding * 2) ) / 2; ctx.beginPath(); @@ -12474,7 +12705,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot /** * Draws corners of an object's bounding box. - * Requires public properties: width, height, scaleX, scaleY + * Requires public properties: width, height * Requires public options: cornerSize, padding * @param {CanvasRenderingContext2D} ctx Context to draw on * @return {fabric.Object} thisArg @@ -12486,75 +12717,73 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot var size = this.cornerSize, size2 = size / 2, strokeWidth2 = ~~(this.strokeWidth / 2), // half strokeWidth rounded down - left = -(this.width / 2), - top = -(this.height / 2), - paddingX = this.padding / this.scaleX, - paddingY = this.padding / this.scaleY, - scaleOffsetY = size2 / this.scaleY, - scaleOffsetX = size2 / this.scaleX, - scaleOffsetSizeX = (size2 - size) / this.scaleX, - scaleOffsetSizeY = (size2 - size) / this.scaleY, - height = this.height, - width = this.width, + wh = fabric.util.transformPoint(new fabric.Point(this.getWidth(), this.getHeight()), this.getViewportTransform(), true), + width = wh.x, + height = wh.y, + left = -(width / 2), + top = -(height / 2), + padding = this.padding, + scaleOffset = size2, + scaleOffsetSize = size2 - size, methodName = this.transparentCorners ? 'strokeRect' : 'fillRect'; ctx.save(); - ctx.lineWidth = 1 / Math.max(this.scaleX, this.scaleY); + ctx.lineWidth = 1; ctx.globalAlpha = this.isMoving ? this.borderOpacityWhenMoving : 1; ctx.strokeStyle = ctx.fillStyle = this.cornerColor; // top-left this._drawControl('tl', ctx, methodName, - left - scaleOffsetX - strokeWidth2 - paddingX, - top - scaleOffsetY - strokeWidth2 - paddingY); + left - scaleOffset - strokeWidth2 - padding, + top - scaleOffset - strokeWidth2 - padding); // top-right this._drawControl('tr', ctx, methodName, - left + width - scaleOffsetX + strokeWidth2 + paddingX, - top - scaleOffsetY - strokeWidth2 - paddingY); + left + width - scaleOffset + strokeWidth2 + padding, + top - scaleOffset - strokeWidth2 - padding); // bottom-left this._drawControl('bl', ctx, methodName, - left - scaleOffsetX - strokeWidth2 - paddingX, - top + height + scaleOffsetSizeY + strokeWidth2 + paddingY); + left - scaleOffset - strokeWidth2 - padding, + top + height + scaleOffsetSize + strokeWidth2 + padding); // bottom-right this._drawControl('br', ctx, methodName, - left + width + scaleOffsetSizeX + strokeWidth2 + paddingX, - top + height + scaleOffsetSizeY + strokeWidth2 + paddingY); + left + width + scaleOffsetSize + strokeWidth2 + padding, + top + height + scaleOffsetSize + strokeWidth2 + padding); if (!this.get('lockUniScaling')) { // middle-top this._drawControl('mt', ctx, methodName, - left + width/2 - scaleOffsetX, - top - scaleOffsetY - strokeWidth2 - paddingY); + left + width/2 - scaleOffset, + top - scaleOffset - strokeWidth2 - padding); // middle-bottom this._drawControl('mb', ctx, methodName, - left + width/2 - scaleOffsetX, - top + height + scaleOffsetSizeY + strokeWidth2 + paddingY); + left + width/2 - scaleOffset, + top + height + scaleOffsetSize + strokeWidth2 + padding); // middle-right this._drawControl('mr', ctx, methodName, - left + width + scaleOffsetSizeX + strokeWidth2 + paddingX, - top + height/2 - scaleOffsetY); + left + width + scaleOffsetSize + strokeWidth2 + padding, + top + height/2 - scaleOffset); // middle-left this._drawControl('ml', ctx, methodName, - left - scaleOffsetX - strokeWidth2 - paddingX, - top + height/2 - scaleOffsetY); + left - scaleOffset - strokeWidth2 - padding, + top + height/2 - scaleOffset); } // middle-top-rotate if (this.hasRotatingPoint) { this._drawControl('mtr', ctx, methodName, - left + width/2 - scaleOffsetX, + left + width/2 - scaleOffset, this.flipY - ? (top + height + (this.rotatingPointOffset / this.scaleY) - this.cornerSize/this.scaleX/2 + strokeWidth2 + paddingY) - : (top - (this.rotatingPointOffset / this.scaleY) - this.cornerSize/this.scaleY/2 - strokeWidth2 - paddingY)); + ? (top + height + this.rotatingPointOffset - this.cornerSize/2 + strokeWidth2 + padding) + : (top - this.rotatingPointOffset - this.cornerSize/2 - strokeWidth2 - padding)); } ctx.restore(); @@ -12566,12 +12795,11 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot * @private */ _drawControl: function(control, ctx, methodName, left, top) { - var sizeX = this.cornerSize / this.scaleX, - sizeY = this.cornerSize / this.scaleY; + var size = this.cornerSize; if (this.isControlVisible(control)) { - isVML || this.transparentCorners || ctx.clearRect(left, top, sizeX, sizeY); - ctx[methodName](left, top, sizeX, sizeY); + isVML() || this.transparentCorners || ctx.clearRect(left, top, size, size); + ctx[methodName](left, top, size, size); } }, @@ -13359,22 +13587,24 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot */ fabric.Circle.fromElement = function(element, options) { options || (options = { }); + var parsedAttributes = fabric.parseAttributes(element, fabric.Circle.ATTRIBUTE_NAMES); + if (!isValidRadius(parsedAttributes)) { throw new Error('value of `r` attribute is required and can not be negative'); } - - + if (!('left' in parsedAttributes)) { - parsedAttributes.left = 0; + parsedAttributes.left = 0; } if (!('top' in parsedAttributes)) { - parsedAttributes.top = 0 + parsedAttributes.top = 0; } if (!('transformMatrix' in parsedAttributes)) { parsedAttributes.left -= (options.width / 2); - parsedAttributes.top -= (options.height / 2); - } + parsedAttributes.top -= (options.height / 2); + } + var obj = new fabric.Circle(extend(parsedAttributes, options)); obj.cx = parseFloat(element.getAttribute('cx')) || 0; @@ -14863,6 +15093,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot ctx.save(); var m = this.transformMatrix; + if (m) { ctx.transform(m[0], m[1], m[2], m[3], m[4], m[5]); } @@ -14880,11 +15111,6 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot this._renderStroke(ctx); this.clipTo && ctx.restore(); this._removeShadow(ctx); - - if (!noTransform && this.active) { - this.drawBorders(ctx); - this.drawControls(ctx); - } ctx.restore(); }, @@ -15237,10 +15463,10 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot ctx.save(); var m = this.transformMatrix; + if (m) { ctx.transform(m[0], m[1], m[2], m[3], m[4], m[5]); } - this.transform(ctx); this._setShadow(ctx); @@ -15250,11 +15476,6 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot } this.clipTo && ctx.restore(); this._removeShadow(ctx); - - if (this.active) { - this.drawBorders(ctx); - this.drawControls(ctx); - } ctx.restore(); }, @@ -15474,7 +15695,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot } this._setOpacityIfSame(); - this.setCoords(true); + this.setCoords(); this.saveCoords(); }, @@ -15522,8 +15743,10 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot */ addWithUpdate: function(object) { this._restoreObjectsState(); - this._objects.push(object); - object.group = this; + if (object) { + this._objects.push(object); + object.group = this; + } // since _restoreObjectsState set objects inactive this.forEachObject(this._setObjectActive, this); this._calcBounds(); @@ -15621,15 +15844,12 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot /** * Renders instance on a given context * @param {CanvasRenderingContext2D} ctx context to render instance on - * @param {Boolean} [noTransform] When true, context is not transformed */ - render: function(ctx, noTransform) { + render: function(ctx) { // do not render if object is not visible if (!this.visible) return; ctx.save(); - this.transform(ctx); - this.clipTo && fabric.util.clipContext(this, ctx); // the array is now sorted in order of highest first, so start from end @@ -15639,31 +15859,34 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot this.clipTo && ctx.restore(); - if (!noTransform && this.active) { - this.drawBorders(ctx); - this.drawControls(ctx); - } ctx.restore(); }, + /** + * Renders controls and borders for the object + * @param {CanvasRenderingContext2D} ctx Context to render on + * @param {Boolean} [noTransform] When true, context is not transformed + */ + _renderControls: function(ctx, noTransform) { + this.callSuper('_renderControls', ctx, noTransform); + for (var i = 0, len = this._objects.length; i < len; i++) { + this._objects[i]._renderControls(ctx); + } + }, + /** * @private */ _renderObject: function(object, ctx) { - - var originalScaleFactor = object.borderScaleFactor, - originalHasRotatingPoint = object.hasRotatingPoint, - groupScaleFactor = Math.max(this.scaleX, this.scaleY); + var originalHasRotatingPoint = object.hasRotatingPoint; // do not render if object is not visible if (!object.visible) return; - object.borderScaleFactor = groupScaleFactor; object.hasRotatingPoint = false; object.render(ctx); - object.borderScaleFactor = originalScaleFactor; object.hasRotatingPoint = originalHasRotatingPoint; }, @@ -15858,20 +16081,17 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot * @private */ _getBounds: function(aX, aY, onlyWidthHeight) { - var minX = min(aX), - maxX = max(aX), - minY = min(aY), - maxY = max(aY), - width = (maxX - minX) || 0, - height = (maxY - minY) || 0, - obj = { - width: width, - height: height + var ivt = fabric.util.invertTransform(this.getViewportTransform()), + minXY = fabric.util.transformPoint(new fabric.Point(min(aX), min(aY)), ivt), + maxXY = fabric.util.transformPoint(new fabric.Point(max(aX), max(aY)), ivt), + obj = { + width: (maxXY.x - minXY.x) || 0, + height: (maxXY.y - minXY.y) || 0 }; if (!onlyWidthHeight) { - obj.left = (minX + width / 2) || 0; - obj.top = (minY + height / 2) || 0; + obj.left = (minXY.x + maxXY.x) / 2 || 0; + obj.top = (minXY.y + maxXY.y) / 2 || 0; } return obj; }, @@ -16078,7 +16298,6 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot if (!this.visible) return; ctx.save(); - var m = this.transformMatrix, isInPathGroup = this.group && this.group.type === 'path-group'; @@ -16096,7 +16315,6 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot ctx.translate(this.width/2, this.height/2); } - ctx.save(); this._setShadow(ctx); this.clipTo && fabric.util.clipContext(this, ctx); this._render(ctx); @@ -16106,12 +16324,6 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot this._renderStroke(ctx); this.clipTo && ctx.restore(); ctx.restore(); - - if (this.active && !noTransform) { - this.drawBorders(ctx); - this.drawControls(ctx); - } - ctx.restore(); }, /** @@ -16132,10 +16344,10 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot * @param {CanvasRenderingContext2D} ctx Context to render on */ _renderDashedStroke: function(ctx) { - var x = -this.width/2, - y = -this.height/2, - w = this.width, - h = this.height; + var x = -this.width / 2, + y = -this.height / 2, + w = this.width, + h = this.height; ctx.save(); this._setStrokeStyles(ctx); @@ -16295,13 +16507,14 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot * @param {CanvasRenderingContext2D} ctx Context to render on */ _render: function(ctx) { - this._element && ctx.drawImage( - this._element, - -this.width / 2, - -this.height / 2, - this.width, - this.height - ); + this._element && + ctx.drawImage( + this._element, + -this.width / 2, + -this.height / 2, + this.width, + this.height + ); }, /** @@ -17764,10 +17977,9 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag source = new fabric.Color(this.color).getSource(); for (i = 0; i < iLen; i+=4) { - data[i] *= source[0]/255; - data[i + 1] *= source[1]/255; - data[i + 2] *= source[2]/255; - + data[i] *= source[0] / 255; + data[i + 1] *= source[1] / 255; + data[i + 2] *= source[2] / 255; } context.putImageData(imageData, 0, 0); @@ -18118,7 +18330,6 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag this.setOptions(options); this.__skipDimension = false; this._initDimensions(); - this.setCoords(); }, /** @@ -18559,9 +18770,8 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag /** * Renders text instance on a specified context * @param {CanvasRenderingContext2D} ctx Context to render on - * @param {Boolean} [noTransform] When true, context is not transformed */ - render: function(ctx, noTransform) { + render: function(ctx) { // do not render if object is not visible if (!this.visible) return; @@ -18571,10 +18781,6 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag ctx.transform(m[0], m[1], m[2], m[3], m[4], m[5]); } this._render(ctx); - if (!noTransform && this.active) { - this.drawBorders(ctx); - this.drawControls(ctx); - } ctx.restore(); }, @@ -18935,6 +19141,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag * @mixes fabric.Observable * * @fires changed ("text:changed" when observing canvas) + * @fires selection:changed ("text:selection:changed" when observing canvas) * @fires editing:entered ("text:editing:entered" when observing canvas) * @fires editing:exited ("text:editing:exited" when observing canvas) * @@ -19145,6 +19352,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag */ setSelectionStart: function(index) { if (this.selectionStart !== index) { + this.fire('selection:changed'); this.canvas && this.canvas.fire('text:selection:changed', { target: this }); } this.selectionStart = index; @@ -19157,6 +19365,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag */ setSelectionEnd: function(index) { if (this.selectionEnd !== index) { + this.fire('selection:changed'); this.canvas && this.canvas.fire('text:selection:changed', { target: this }); } this.selectionEnd = index; @@ -19282,6 +19491,8 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag textBackgroundColor: style && style.textBackgroundColor || this.textBackgroundColor, textDecoration: style && style.textDecoration || this.textDecoration, fontFamily: style && style.fontFamily || this.fontFamily, + fontWeight: style && style.fontWeight || this.fontWeight, + fontStyle: style && style.fontStyle || this.fontStyle, stroke: style && style.stroke || this.stroke, strokeWidth: style && style.strokeWidth || this.strokeWidth }; @@ -19621,6 +19832,8 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag prevStyle.textBackgroundColor !== thisStyle.textBackgroundColor || prevStyle.textDecoration !== thisStyle.textDecoration || prevStyle.fontFamily !== thisStyle.fontFamily || + prevStyle.fontWeight !== thisStyle.fontWeight || + prevStyle.fontStyle !== thisStyle.fontStyle || prevStyle.stroke !== thisStyle.stroke || prevStyle.strokeWidth !== thisStyle.strokeWidth ); @@ -20218,6 +20431,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag selectAll: function() { this.selectionStart = 0; this.selectionEnd = this.text.length; + this.fire('selection:changed'); this.canvas && this.canvas.fire('text:selection:changed', { target: this }); }, @@ -20989,10 +21203,10 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot mouseOffset, prevWidth, width, charIndex + i, jlen); } - if (mouseOffset.y < height) { - return this._getNewSelectionStartFromOffset( - mouseOffset, prevWidth, width, charIndex + i, jlen, j); - } + if (mouseOffset.y < height) { + return this._getNewSelectionStartFromOffset( + mouseOffset, prevWidth, width, charIndex + i, jlen, j); + } } // clicked somewhere after all chars, so set at the end @@ -21047,7 +21261,6 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot fabric.util.addListener(this.hiddenTextarea, 'copy', this.copy.bind(this)); fabric.util.addListener(this.hiddenTextarea, 'paste', this.paste.bind(this)); - if (!this._clickHandlerInitialized && this.canvas) { fabric.util.addListener(this.canvas.upperCanvasEl, 'click', this.onClick.bind(this)); this._clickHandlerInitialized = true; @@ -21119,7 +21332,7 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot copy: function(e) { var selectedText = this.getSelectedText(), clipboardData = this._getClipboardData(e); - + // Check for backward compatibility with old browsers if (clipboardData) { clipboardData.setData('text', selectedText); @@ -21138,14 +21351,14 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot paste: function(e) { var copiedText = null, clipboardData = this._getClipboardData(e); - + // Check for backward compatibility with old browsers if (clipboardData) { copiedText = clipboardData.getData('text'); } else { copiedText = this.copiedText; } - + if (copiedText) { this.insertChars(copiedText); } @@ -21672,6 +21885,7 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot } }); + /* _TO_SVG_START_ */ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.prototype */ { @@ -21782,7 +21996,7 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot fabric.util.string.escapeXml(_char), '' - ].join(''); + ].join(''); } }); /* _TO_SVG_END_ */ diff --git a/package.json b/package.json index 0ad5413f..cf6bb32d 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "fabric", "description": "Object model for HTML5 canvas, and SVG-to-canvas parser. Backed by jsdom and node-canvas.", "homepage": "http://fabricjs.com/", - "version": "1.4.7", + "version": "1.4.8", "author": "Juriy Zaytsev ", "keywords": [ "canvas",