From 0c1fd43fc1e10f363fb4da70aca286819976a158 Mon Sep 17 00:00:00 2001 From: kangax Date: Thu, 6 Dec 2012 19:12:54 +0100 Subject: [PATCH] First stab at dynamic origin of transformation (based on the excellent work of https://github.com/stormbreakerbg). --- dist/all.js | 588 +++++++++++++++++++++++++++++++++++++++----- dist/all.min.js | 10 +- dist/all.min.js.gz | Bin 40707 -> 42000 bytes src/canvas.class.js | 281 ++++++++++++++++++--- src/object.class.js | 284 +++++++++++++++++++-- src/util/misc.js | 23 ++ 6 files changed, 1069 insertions(+), 117 deletions(-) diff --git a/dist/all.js b/dist/all.js index e926cec2..4864dd81 100644 --- a/dist/all.js +++ b/dist/all.js @@ -1922,6 +1922,28 @@ fabric.Observable.off = fabric.Observable.stopObserving; return radians / PiBy180; } + /** + * Rotates `point` around `origin` with `radians` + * @static + * @method rotatePoint + * @memberOf fabric.util + * @param {fabric.Point} The point to rotate + * @param {fabric.Point} The origin of the rotation + * @param {Number} The radians of the angle for the rotation + * @return {fabric.Point} The new rotated point + */ + function rotatePoint(point, origin, radians) { + var sin = Math.sin(radians), + cos = Math.cos(radians); + + point.subtractEquals(origin); + + var rx = point.x * cos - point.y * sin; + var ry = point.x * sin + point.y * cos; + + return new fabric.Point(rx, ry).addEquals(origin); + } + /** * A wrapper around Number#toFixed, which contrary to native method returns number, not string. * @static @@ -2105,6 +2127,7 @@ fabric.Observable.off = fabric.Observable.stopObserving; fabric.util.removeFromArray = removeFromArray; fabric.util.degreesToRadians = degreesToRadians; fabric.util.radiansToDegrees = radiansToDegrees; + fabric.util.rotatePoint = rotatePoint; fabric.util.toFixed = toFixed; fabric.util.getRandomInt = getRandomInt; fabric.util.falseFunction = falseFunction; @@ -6272,7 +6295,6 @@ fabric.util.string = { utilMax = fabric.util.array.max, sqrt = Math.sqrt, - pow = Math.pow, atan2 = Math.atan2, abs = Math.abs, min = Math.min, @@ -6520,6 +6542,11 @@ fabric.util.string = { this.fire('object:modified', { target: target }); target.fire('modified'); } + + if (this._previousOriginX) { + this._adjustPosition(this._currentTransform.target, this._previousOriginX); + this._previousOriginX = null; + } } this._currentTransform = null; @@ -6598,7 +6625,6 @@ fabric.util.string = { } else { // determine if it's a drag or rotate case - // rotate and scale will happen at the same time this.stateful && target.saveState(); if ((corner = target._findTargetCorner(e, this._offset))) { @@ -6624,6 +6650,14 @@ fabric.util.string = { this.fire('mouse:down', { target: target, e: e }); target && target.fire('mousedown', { e: e }); + + // center origin when rotating + if (corner === 'mtr') { + this._previousOriginX = this._currentTransform.target.originX; + this._adjustPosition(this._currentTransform.target, 'center'); + this._currentTransform.left = this._currentTransform.target.left; + this._currentTransform.top = this._currentTransform.target.top; + } }, /** @@ -6692,33 +6726,77 @@ fabric.util.string = { this._currentTransform.target.isMoving = true; + var t = this._currentTransform, reset = false; + if ( + (t.action === 'scale' || t.action === 'scaleX' || t.action === 'scaleY') + && + ( + // Switch from a normal resize to center-based + (e.altKey && (t.originX !== 'center' || t.originY !== 'center')) + || + // Switch from center-based resize to normal one + (!e.altKey && t.originX === 'center' && t.originY === 'center') + ) + ) { + this._resetCurrentTransform(e); + reset = true; + } + if (this._currentTransform.action === 'rotate') { + this._rotateObject(x, y); + + this.fire('object:rotating', { + target: this._currentTransform.target + }); + this._currentTransform.target.fire('rotating'); + } + else if (this._currentTransform.action === 'scale') { // rotate object only if shift key is not pressed // and if it is not a group we are transforming - if (!e.shiftKey) { + // TODO + /*if (!e.shiftKey) { this._rotateObject(x, y); this.fire('object:rotating', { target: this._currentTransform.target }); this._currentTransform.target.fire('rotating'); - } - if (!this._currentTransform.target.hasRotatingPoint) { + }*/ + + // if (!this._currentTransform.target.hasRotatingPoint) { + // this._scaleObject(x, y); + // this.fire('object:scaling', { + // target: this._currentTransform.target + // }); + // this._currentTransform.target.fire('scaling'); + // } + + if (e.shiftKey) { + this._currentTransform.currentAction = 'scale'; this._scaleObject(x, y); - this.fire('object:scaling', { - target: this._currentTransform.target - }); - this._currentTransform.target.fire('scaling'); } - } - else if (this._currentTransform.action === 'scale') { - this._scaleObject(x, y); + else { + if (!reset && t.currentAction === 'scale') { + // Switch from a normal resize to proportional + this._resetCurrentTransform(e); + } + + this._currentTransform.currentAction = 'scaleEqually'; + this._scaleObject(x, y, 'equally'); + } + this.fire('object:scaling', { target: this._currentTransform.target }); - this._currentTransform.target.fire('scaling'); } + // else if (this._currentTransform.action === 'scale') { + // this._scaleObject(x, y); + // this.fire('object:scaling', { + // target: this._currentTransform.target + // }); + // this._currentTransform.target.fire('scaling'); + // } else if (this._currentTransform.action === 'scaleX') { this._scaleObject(x, y, 'x'); @@ -6753,6 +6831,45 @@ fabric.util.string = { target && target.fire('mousemove', { e: e }); }, + /** + * Resets the current transform to its original values and chooses the type of resizing based on the event + * @method _resetCurrentTransform + * @param e {Event} Event object fired on mousemove + */ + _resetCurrentTransform: function(e) { + var t = this._currentTransform; + t.target.set('scaleX', t.original.scaleX); + t.target.set('scaleY', t.original.scaleY); + t.target.set('left', t.original.left); + t.target.set('top', t.original.top); + + if (e.altKey) { + if (t.originX !== 'center') { + if (t.originX === 'right') { + t.mouseXSign = -1; + } + else { + t.mouseXSign = 1; + } + } + if (t.originY !== 'center') { + if (t.originY === 'bottom') { + t.mouseYSign = -1; + } + else { + t.mouseYSign = 1; + } + } + + t.originX = 'center'; + t.originY = 'center'; + } + else { + t.originX = t.original.originX; + t.originY = t.original.originY; + } + }, + /** * Applies one implementation of 'point inside polygon' algorithm * @method containsPoint @@ -6874,18 +6991,39 @@ fabric.util.string = { corner, pointer = getPointer(e); - if ((corner = target._findTargetCorner(e, this._offset))) { + corner = target._findTargetCorner(e, this._offset); + if (corner) { action = (corner === 'ml' || corner === 'mr') ? 'scaleX' : (corner === 'mt' || corner === 'mb') ? 'scaleY' : corner === 'mtr' ? 'rotate' - : (target.hasRotatingPoint) - ? 'scale' - : 'rotate'; + : 'scale'; } + var originX = "center", originY = "center"; + + if (corner === 'ml' || corner === 'tl' || corner === 'bl') { + originX = "right"; + } + else if (corner === 'mr' || corner === 'tr' || corner === 'br') { + originX = "left"; + } + + if (corner === 'tl' || corner === 'mt' || corner === 'tr') { + originY = "bottom"; + } + else if (corner === 'bl' || corner === 'mb' || corner === 'br') { + originY = "top"; + } + + if (corner === 'mtr') { + originX = 'center'; + originY = 'center'; + } + + // var center = target.getCenterPoint(); this._currentTransform = { target: target, action: action, @@ -6893,18 +7031,28 @@ fabric.util.string = { scaleY: target.scaleY, offsetX: pointer.x - target.left, offsetY: pointer.y - target.top, + originX: originX, + originY: originY, ex: pointer.x, ey: pointer.y, left: target.left, top: target.top, theta: degreesToRadians(target.angle), - width: target.width * target.scaleX + width: target.width * target.scaleX, + mouseXSign: 1, + mouseYSign: 1 }; this._currentTransform.original = { left: target.left, - top: target.top + top: target.top, + scaleX: target.scaleX, + scaleY: target.scaleY, + originX: originX, + originY: originY }; + + this._resetCurrentTransform(e); }, _handleGroupLogic: function (e, target) { @@ -7064,23 +7212,81 @@ fabric.util.string = { offset = this._offset, target = t.target; + // Nothing to do here... if (target.lockScalingX && target.lockScalingY) return; - var lastLen = sqrt(pow(t.ey - t.top - offset.top, 2) + pow(t.ex - t.left - offset.left, 2)), - curLen = sqrt(pow(y - t.top - offset.top, 2) + pow(x - t.left - offset.left, 2)); + // Get the constraint point + var constraintPosition = target.translateToOriginPoint(target.getCenterPoint(), t.originX, t.originY); + var localMouse = target.toLocalPoint(new fabric.Point(x - offset.left, y - offset.top), t.originX, t.originY); - target._scaling = true; + if (t.originX === 'right') { + localMouse.x *= -1; + } + else if (t.originX === 'center') { + localMouse.x *= t.mouseXSign * 2; - if (!by) { - target.lockScalingX || target.set('scaleX', t.scaleX * curLen/lastLen); - target.lockScalingY || target.set('scaleY', t.scaleY * curLen/lastLen); + if (localMouse.x < 0) { + t.mouseXSign = -t.mouseXSign; + } + } + + if (t.originY === 'bottom') { + localMouse.y *= -1; + } + else if (t.originY === 'center') { + localMouse.y *= t.mouseYSign * 2; + + if (localMouse.y < 0) { + t.mouseYSign = -t.mouseYSign; + } + } + + // Actually scale the object + var newScaleX = target.scaleX, newScaleY = target.scaleY; + if (by === 'equally' && !target.lockScalingX && !target.lockScalingY) { + var dist = localMouse.y + localMouse.x; + var lastDist = target.height * t.original.scaleY + target.width * t.original.scaleX; + + // We use t.scaleX/Y instead of target.scaleX/Y because the object may have a min scale and we'll loose the proportions + newScaleX = t.original.scaleX * dist/lastDist; + newScaleY = t.original.scaleY * dist/lastDist; + target.set('scaleX', newScaleX); + target.set('scaleY', newScaleY); + } + else if (!by) { + newScaleX = localMouse.x/target.width; + newScaleY = localMouse.y/target.height; + target.lockScalingX || target.set('scaleX', newScaleX); + target.lockScalingY || target.set('scaleY', newScaleY); } else if (by === 'x' && !target.lockUniScaling) { - target.lockScalingX || target.set('scaleX', t.scaleX * curLen/lastLen); + newScaleX = localMouse.x/target.width; + target.lockScalingX || target.set('scaleX', newScaleX); } else if (by === 'y' && !target.lockUniScaling) { - target.lockScalingY || target.set('scaleY', t.scaleY * curLen/lastLen); + newScaleY = localMouse.y/target.height; + target.lockScalingY || target.set('scaleY', newScaleY); } + + // Check if we flipped + if (newScaleX < 0) + { + if (t.originX === 'left') + t.originX = 'right'; + else if (t.originX === 'right') + t.originX = 'left'; + } + + if (newScaleY < 0) + { + if (t.originY === 'top') + t.originY = 'bottom'; + else if (t.originY === 'bottom') + t.originY = 'top'; + } + + // Make sure the constraints apply + target.setPositionByOrigin(constraintPosition, t.originX, t.originY); }, /** @@ -7219,8 +7425,8 @@ fabric.util.string = { drawDashedLine: function(ctx, x, y, x2, y2, da) { var dx = x2 - x, dy = y2 - y, - len = Math.sqrt(dx*dx + dy*dy), - rot = Math.atan2(dy, dx), + len = sqrt(dx*dx + dy*dy), + rot = atan2(dy, dx), dc = da.length, di = 0, draw = true; @@ -7542,6 +7748,46 @@ fabric.util.string = { this.fire('selection:cleared'); } return this; + }, + + _adjustPosition: function(obj, to) { + console.log('adjusting position'); + + var angle = fabric.util.degreesToRadians(obj.angle); + + var hypotHalf = obj.getWidth() / 2; + var xHalf = Math.cos(angle) * hypotHalf; + var yHalf = Math.sin(angle) * hypotHalf; + + var hypotFull = obj.getWidth(); + var xFull = Math.cos(angle) * hypotFull; + var yFull = Math.sin(angle) * hypotFull; + + if (obj.originX === 'center' && to === 'left' || + obj.originX === 'right' && to === 'center') { + // move half left + obj.left -= xHalf; + obj.top -= yHalf; + } + else if (obj.originX === 'left' && to === 'center' || + obj.originX === 'center' && to === 'right') { + // move half right + obj.left += xHalf; + obj.top += yHalf; + } + else if (obj.originX === 'left' && to === 'right') { + // move full right + obj.left += xFull; + obj.top += yFull; + } + else if (obj.originX === 'right' && to === 'left') { + // move full left + obj.left -= xFull; + obj.top -= yFull; + } + + obj.setCoords(); + obj.originX = to; } }; @@ -7986,67 +8232,91 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { type: 'object', /** + * Horizontal origin of transformation of an object (one of "left", "right", "center") + * @property + * @type String + */ + originX: 'center', + + /** + * Vertical origin of transformation of an object (one of "top", "bottom", "center") + * @property + * @type String + */ + originY: 'center', + + /** + * Top position of an object * @property * @type Number */ top: 0, /** + * Left position of an object * @property * @type Number */ left: 0, /** + * Width of an object * @property * @type Number */ width: 0, /** + * Height of an object * @property * @type Number */ height: 0, /** + * Horizontal scale of an object * @property * @type Number */ scaleX: 1, /** + * Vertical scale of an object * @property * @type Number */ scaleY: 1, /** + * When true, an object is rendered as flipped horizontally * @property * @type Boolean */ flipX: false, /** + * When true, an object is rendered as flipped vertically * @property * @type Boolean */ flipY: false, /** + * Opacity of an object * @property * @type Number */ opacity: 1, /** + * Angle of an object (in degrees) * @property * @type Number */ angle: 0, /** - * Size of object's corners + * Size of object's corners (in pixels) * @property * @type Number */ @@ -8060,25 +8330,28 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { transparentCorners: true, /** - * Padding between object and its borders + * Padding between object and its borders (in pixels) * @property * @type Number */ padding: 0, /** + * Color of object's borders (when in active state) * @property * @type String */ borderColor: 'rgba(102,153,255,0.75)', /** + * Color of object's corners (when in active state) * @property * @type String */ cornerColor: 'rgba(102,153,255,0.5)', /** + * Color of object's fill * @property * @type String */ @@ -8097,7 +8370,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { overlayFill: null, /** - * When `true`, an object is rendered via stroke + * When `true`, an object is rendered via stroke and this property specifies its color * @property * @type String */ @@ -8111,12 +8384,14 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { strokeWidth: 1, /** + * Dash pattern of a stroke for this object * @property * @type Array */ strokeDashArray: null, /** + * Border opacity when object is active and moving * @property * @type Number */ @@ -8129,12 +8404,19 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { borderScaleFactor: 1, /** - * Transform matrix + * Transform matrix (similar to SVG's transform matrix) * @property * @type Array */ transformMatrix: null, + /** + * Minimum allowed scale value of an object + * @property + * @type Number + */ + minScaleLimit: 0.01, + /** * When set to `false`, an object can not be selected for modification (using either point-click-based or group-based selection) * @property @@ -8164,7 +8446,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { hasRotatingPoint: false, /** - * Offset for object's rotating point (when enabled) + * Offset for object's rotating point (when enabled via `hasRotatingPoint`) * @property * @type Number */ @@ -8178,6 +8460,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { perPixelTargetFind: false, /** + * When `false`, default object's values are not included in its serialization * @property * @type Boolean */ @@ -8191,7 +8474,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { */ stateProperties: ( 'top left width height scaleX scaleY flipX flipY ' + - 'angle opacity cornersize fill overlayFill ' + + 'angle opacity cornersize fill overlayFill originX originY ' + 'stroke strokeWidth strokeDashArray fillRule ' + 'borderScaleFactor transformMatrix selectable' ).split(' '), @@ -8234,7 +8517,9 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { */ transform: function(ctx) { ctx.globalAlpha = this.opacity; - ctx.translate(this.left, this.top); + + var center = this.getCenterPoint(); + ctx.translate(center.x, center.y); ctx.rotate(degreesToRadians(this.angle)); ctx.scale( this.scaleX * (this.flipX ? -1 : 1), @@ -8254,6 +8539,8 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { var object = { type: this.type, + originX: this.originX, + originY: this.originY, left: toFixed(this.left, NUM_FRACTION_DIGITS), top: toFixed(this.top, NUM_FRACTION_DIGITS), width: toFixed(this.width, NUM_FRACTION_DIGITS), @@ -8318,12 +8605,14 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { */ getSvgTransform: function() { var angle = this.getAngle(); + var center = this.getCenterPoint(); + var NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS; var translatePart = "translate(" + - toFixed(this.left, NUM_FRACTION_DIGITS) + + toFixed(center.x, NUM_FRACTION_DIGITS) + " " + - toFixed(this.top, NUM_FRACTION_DIGITS) + + toFixed(center.y, NUM_FRACTION_DIGITS) + ")"; var anglePart = angle !== 0 @@ -8387,6 +8676,24 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { return "#"; }, + /** + * Makes sure the scale is valid and modifies it if necessary + * @private + * @method _constrainScale + * @param {Number} value + * @return {Number} + */ + _constrainScale: function(value) { + if (Math.abs(value) < this.minScaleLimit) { + if (value < 0) + return -this.minScaleLimit; + else + return this.minScaleLimit; + } + + return value; + }, + /** * Sets property to a given value * @method set @@ -8413,13 +8720,26 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { }, _set: function(key, value) { - var shouldConstrainValue = (key === 'scaleX' || key === 'scaleY') && - value < fabric.Object.MIN_SCALE_LIMIT; + var shouldConstrainValue = (key === 'scaleX' || key === 'scaleY'); if (shouldConstrainValue) { - value = fabric.Object.MIN_SCALE_LIMIT; + value = this._constrainScale(value); } + if (key === 'scaleX' && value < 0) { + this.flipX = !this.flipX; + value *= -1; + } + else if (key === 'scaleY' && value < 0) { + this.flipY = !this.flipY; + value *= -1; + } + else if (key === 'width' || key === 'height') { + this.minScaleLimit = Math.min(0.1, 1/Math.max(this.width, this.height)); + } + this[key] = value; + + return this; }, /** @@ -8525,6 +8845,162 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { return this.height * this.scaleY; }, + /** + * Translates the coordinates from origin to center coordinates (based on the object's dimensions) + * @method translateToCenterPoint + * @param {fabric.Point} point The point which corresponds to the originX and originY params + * @param {string} enum('left', 'center', 'right') Horizontal origin + * @param {string} enum('top', 'center', 'bottom') Vertical origin + * @return {fabric.Point} + */ + translateToCenterPoint: function(point, originX, originY) { + var cx = point.x, cy = point.y; + + if ( originX === "left" ) { + cx = point.x + this.getWidth() / 2; + } + else if ( originX === "right" ) { + cx = point.x - this.getWidth() / 2; + } + + if ( originY === "top" ) { + cy = point.y + this.getHeight() / 2; + } + else if ( originY === "bottom" ) { + cy = point.y - this.getHeight() / 2; + } + + // Apply the reverse rotation to the point (it's already scaled properly) + return fabric.util.rotatePoint(new fabric.Point(cx, cy), point, degreesToRadians(this.angle)); + }, + + /** + * Translates the coordinates from center to origin coordinates (based on the object's dimensions) + * @method translateToOriginPoint + * @param {fabric.Point} point The point which corresponds to center of the object + * @param {string} enum('left', 'center', 'right') Horizontal origin + * @param {string} enum('top', 'center', 'bottom') Vertical origin + * @return {fabric.Point} + */ + translateToOriginPoint: function(center, originX, originY) { + var x = center.x, y = center.y; + + // Get the point coordinates + if ( originX === "left" ) { + x = center.x - this.getWidth() / 2; + } + else if ( originX === "right" ) { + x = center.x + this.getWidth() / 2; + } + if ( originY === "top" ) { + y = center.y - this.getHeight() / 2; + } + else if ( originY === "bottom" ) { + y = center.y + this.getHeight() / 2; + } + + // Apply the rotation to the point (it's already scaled properly) + return fabric.util.rotatePoint(new fabric.Point(x, y), center, degreesToRadians(this.angle)); + }, + + /** + * Returns the real center coordinates of the object + * @method getCenterPoint + * @return {fabric.Point} + */ + getCenterPoint: function() { + return this.translateToCenterPoint( + new fabric.Point(this.left, this.top), this.originX, this.originY); + }, + + /** + * Returns the coordinates of the object based on center coordinates + * @method getOriginPoint + * @param {fabric.Point} point The point which corresponds to the originX and originY params + * @return {fabric.Point} + */ + getOriginPoint: function(center) { + return this.translateToOriginPoint(center, this.originX, this.originY); + }, + + /** + * Returns the coordinates of the object as if it has a different origin + * @method getPointByOrigin + * @param {string} enum('left', 'center', 'right') Horizontal origin + * @param {string} enum('top', 'center', 'bottom') Vertical origin + * @return {fabric.Point} + */ + getPointByOrigin: function(originX, originY) { + var center = this.getCenterPoint(); + + return this.translateToOriginPoint(center, originX, originY); + }, + + /** + * Returns the point in local coordinates + * @method toLocalPoint + * @param {fabric.Point} The point relative to the global coordinate system + * @return {fabric.Point} + */ + toLocalPoint: function(point, originX, originY) { + var center = this.getCenterPoint(); + + var x, y; + if (originX !== undefined && originY !== undefined) { + if ( originX === "left" ) { + x = center.x - this.getWidth() / 2; + } + else if ( originX === "right" ) { + x = center.x + this.getWidth() / 2; + } + else { + x = center.x; + } + + if ( originY === "top" ) { + y = center.y - this.getHeight() / 2; + } + else if ( originY === "bottom" ) { + y = center.y + this.getHeight() / 2; + } + else { + y = center.y; + } + } + else { + x = this.left; + y = this.top; + } + + return fabric.util.rotatePoint(new fabric.Point(point.x, point.y), center, -degreesToRadians(this.angle)).subtractEquals(new fabric.Point(x, y)); + }, + + /** + * Returns the point in global coordinates + * @method toGlobalPoint + * @param {fabric.Point} The point relative to the local coordinate system + * @return {fabric.Point} + */ + toGlobalPoint: function(point) { + return fabric.util.rotatePoint(point, this.getCenterPoint(), degreesToRadians(this.angle)).addEquals(new fabric.Point(this.left, this.top)); + }, + + /** + * Sets the position of the object taking into consideration the object's origin + * @method setPositionByOrigin + * @param {fabric.Point} point The new position of the object + * @param {string} enum('left', 'center', 'right') Horizontal origin + * @param {string} enum('top', 'center', 'bottom') Vertical origin + * @return {void} + */ + setPositionByOrigin: function(pos, originX, originY) { + var center = this.translateToCenterPoint(pos, originX, originY); + var position = this.translateToOriginPoint(center, this.originX, this.originY); + + this.set('left', position.x); + this.set('top', position.y); + }, + /** * Scales an object (equally by x and y) * @method scale @@ -8533,6 +9009,14 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { * @chainable */ scale: function(value) { + value = this._constrainScale(value); + + if (value < 0) { + this.flipX = !this.flipX; + this.flipY = !this.flipY; + value *= -1; + } + this.scaleX = value; this.scaleY = value; this.setCoords(); @@ -8597,9 +9081,10 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { sinTh = Math.sin(theta), cosTh = Math.cos(theta); + var coords = this.getCenterPoint(); var tl = { - x: this.left - offsetX, - y: this.top - offsetY + x: coords.x - offsetX, + y: coords.y - offsetY }; var tr = { x: tl.x + (this.currentWidth * cosTh), @@ -8695,8 +9180,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { drawBorders: function(ctx) { if (!this.hasBorders) return; - var MIN_SCALE_LIMIT = fabric.Object.MIN_SCALE_LIMIT, - padding = this.padding, + var padding = this.padding, padding2 = padding * 2, strokeWidth = this.strokeWidth > 1 ? this.strokeWidth : 0; @@ -8705,8 +9189,8 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { ctx.globalAlpha = this.isMoving ? this.borderOpacityWhenMoving : 1; ctx.strokeStyle = this.borderColor; - var scaleX = 1 / (this.scaleX < MIN_SCALE_LIMIT ? MIN_SCALE_LIMIT : this.scaleX), - scaleY = 1 / (this.scaleY < MIN_SCALE_LIMIT ? MIN_SCALE_LIMIT : this.scaleY); + var scaleX = 1 / this._constrainScale(this.scaleX), + scaleY = 1 / this._constrainScale(this.scaleY); ctx.lineWidth = 1 / this.borderScaleFactor; @@ -9663,15 +10147,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { * @constant * @type Number */ - NUM_FRACTION_DIGITS: 2, - - /** - * @static - * @constant - * @type Number - */ - MIN_SCALE_LIMIT: 0.1 - + NUM_FRACTION_DIGITS: 2 }); })(typeof exports !== 'undefined' ? exports : this); diff --git a/dist/all.min.js b/dist/all.min.js index 4c8a92e6..939a5a7d 100644 --- a/dist/all.min.js +++ b/dist/all.min.js @@ -1,5 +1,5 @@ -/* build: `node build.js modules=ALL` *//*! Fabric.js Copyright 2008-2012, Printio (Juriy Zaytsev, Maxim Chernyak) */var fabric=fabric||{version:"0.9.27"};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";var Cufon=function(){function r(e){var t=this.face=e.face;this.glyphs=e.glyphs,this.w=e.w,this.baseSize=parseInt(t["units-per-em"],10),this.family=t["font-family"].toLowerCase(),this.weight=t["font-weight"],this.style=t["font-style"]||"normal",this.viewBox=function(){var e=t.bbox.split(/\s+/),n={minX:parseInt(e[0],10),minY:parseInt(e[1],10),maxX:parseInt(e[2],10),maxY:parseInt(e[3],10)};return n.width=n.maxX-n.minX,n.height=n.maxY-n.minY,n.toString=function(){return[this.minX,this.minY,this.width,this.height].join(" ")},n}(),this.ascent=-parseInt(t.ascent,10),this.descent=-parseInt(t.descent,10),this.height=-this.ascent+this.descent}function i(){var e={},t={oblique:"italic",italic:"oblique"};this.add=function(t){(e[t.style]||(e[t.style]={}))[t.weight]=t},this.get=function(n,r){var i=e[n]||e[t[n]]||e.normal||e.italic||e.oblique;if(!i)return null;r={normal:400,bold:700}[r]||parseInt(r,10);if(i[r])return i[r];var s={1:1,99:0}[r%100],o=[],u,a;s===undefined&&(s=r>400),r==500&&(r=400);for(var f in i){f=parseInt(f,10);if(!u||fa)a=f;o.push(f)}return ra&&(r=a),o.sort(function(e,t){return(s?e>r&&t>r?et:et:e=i.length+e?r():setTimeout(arguments.callee,10)}),function(t){e?t():n.push(t)}}(),supports:function(e,t){var n=fabric.document.createElement("span").style;return n[e]===undefined?!1:(n[e]=t,n[e]===t)},textAlign:function(e,t,n,r){return t.get("textAlign")=="right"?n>0&&(e=" "+e):nk&&(k=N),A.push(N),N=0;continue}var O=t.glyphs[T[b]]||t.missingGlyph;if(!O)continue;N+=C=Number(O.w||t.w)+h}A.push(N),N=Math.max(k,N);var M=[];for(var b=A.length;b--;)M[b]=N-A[b];if(C===null)return null;d+=l.width-C,m+=l.minX;var _,D;if(f)_=u,D=u.firstChild;else{_=fabric.document.createElement("span"),_.className="cufon cufon-canvas",_.alt=n,D=fabric.document.createElement("canvas"),_.appendChild(D);if(i.printable){var P=fabric.document.createElement("span");P.className="cufon-alt",P.appendChild(fabric.document.createTextNode(n)),_.appendChild(P)}}var H=_.style,B=D.style||{},j=c.convert(l.height-p+v),F=Math.ceil(j),I=F/j;D.width=Math.ceil(c.convert(N+d-m)*I),D.height=F,p+=l.minY,B.top=Math.round(c.convert(p-t.ascent))+"px",B.left=Math.round(c.convert(m))+"px";var q=Math.ceil(c.convert(N*I)),R=q+"px",U=c.convert(t.height),z=(i.lineHeight-1)*c.convert(-t.ascent/5)*(L-1);Cufon.textOptions.width=q,Cufon.textOptions.height=U*L+z,Cufon.textOptions.lines=L,Cufon.textOptions.totalLineHeight=z,e?(H.width=R,H.height=U+"px"):(H.paddingLeft=R,H.paddingBottom=U-1+"px");var W=Cufon.textOptions.context||D.getContext("2d"),X=F/l.height;Cufon.textOptions.fontAscent=t.ascent*X,Cufon.textOptions.boundaries=null;for(var V=Cufon.textOptions.shadowOffsets,b=y.length;b--;)V[b]=[y[b][0]*X,y[b][1]*X];W.save(),W.scale(X,X),W.translate(-m-1/X*D.width/2+(Cufon.fonts[t.family].offsetLeft||0),-p-Cufon.textOptions.height/X/2+(Cufon.fonts[t.family].offsetTop||0)),W.lineWidth=t.face["underline-thickness"],W.save();var J=Cufon.getTextDecoration(i),K=i.fontStyle==="italic";W.save(),Q();if(g)for(var b=0,w=g.length;b.cufon-vml-canvas{text-indent:0}@media screen{cvml\\:shape,cvml\\:shadow{behavior:url(#default#VML);display:block;antialias:true;position:absolute}.cufon-vml-canvas{position:absolute;text-align:left}.cufon-vml{display:inline-block;position:relative;vertical-align:middle}.cufon-vml .cufon-alt{position:absolute;left:-10000in;font-size:1px}a .cufon-vml{cursor:pointer}}@media print{.cufon-vml *{display:none}.cufon-vml .cufon-alt{display:inline}}'),function(e,t,i,s,o,u,a){var f=t===null;f&&(t=o.alt);var l=e.viewBox,c=i.computedFontSize||(i.computedFontSize=new Cufon.CSS.Size(n(u,i.get("fontSize"))+"px",e.baseSize)),h=i.computedLSpacing;h==undefined&&(h=i.get("letterSpacing"),i.computedLSpacing=h=h=="normal"?0:~~c.convertFrom(r(u,h)));var p,d;if(f)p=o,d=o.firstChild;else{p=fabric.document.createElement("span"),p.className="cufon cufon-vml",p.alt=t,d=fabric.document.createElement("span"),d.className="cufon-vml-canvas",p.appendChild(d);if(s.printable){var v=fabric.document.createElement("span");v.className="cufon-alt",v.appendChild(fabric.document.createTextNode(t)),p.appendChild(v)}a||p.appendChild(fabric.document.createElement("cvml:shape"))}var m=p.style,g=d.style,y=c.convert(l.height),b=Math.ceil(y),w=b/y,E=l.minX,S=l.minY;g.height=b,g.top=Math.round(c.convert(S-e.ascent)),g.left=Math.round(c.convert(E)),m.height=c.convert(e.height)+"px";var x=Cufon.getTextDecoration(s),T=i.get("color"),N=Cufon.CSS.textTransform(t,i).split(""),C=0,k=0,L=null,A,O,M=s.textShadow;for(var _=0,D=0,P=N.length;_r?n:i-t;s(u(l,a,c,n));if(i>r||o()){e.onComplete&&e.onComplete();return}f(h)}()}function l(e,t,n){if(e){var r=new Image;r.onload=function(){t&&t.call(n,r),r=r.onload=null},r.src=e}else t&&t.call(n,e)}function c(e,t){function n(e){return fabric[fabric.util.string.camelize(fabric.util.string.capitalize(e))]}function r(){++s===o&&t&&t(i)}var i=[],s=0,o=e.length;e.forEach(function(e,t){if(!e.type)return;var s=n(e.type);s.async?s.fromObject(e,function(e){i[t]=e,r()}):(i[t]=s.fromObject(e),r())})}function h(e,t,n){var r=e.length>1?new fabric.PathGroup(e,t):e[0];return typeof n!="undefined"&&r.setSourcePath(n),r}function p(e,t,n){if(n&&Object.prototype.toString.call(n)==="[object Array]")for(var r=0,i=n.length;r=r&&(r=e[n][t]);else while(n--)e[n]>=r&&(r=e[n]);return r}function r(e,t){if(!e||e.length===0)return undefined;var n=e.length-1,r=t?e[n][t]:e[n];if(t)while(n--)e[n][t]>>0;if(n===0)return-1;var r=0;arguments.length>0&&(r=Number(arguments[1]),r!==r?r=0:r!==0&&r!==1/0&&r!==-1/0&&(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?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.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){var t=0,n=0;do t+=e.offsetTop||0,n+=e.offsetLeft||0,e=e.offsetParent;while(e);return{left:n,top:t}}var e=Array.prototype.slice,n=function(t){return e.call(t,0)},r;try{r=n(fabric.document.childNodes)instanceof Array}catch(i){}r||(n=function(e){var t=new Array(e.length),n=e.length;while(n--)t[n]=e[n];return t});var f;fabric.document.defaultView&&fabric.document.defaultView.getComputedStyle?f=function(e){return fabric.document.defaultView.getComputedStyle(e,null).position}:f=function(e){var t=e.style.position;return!t&&e.currentStyle&&(t=e.currentStyle.position),t},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.type="text/javascript",r.setAttribute("runat","server"),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=n,fabric.util.makeElement=s,fabric.util.addClass=o,fabric.util.wrapElement=u,fabric.util.getElementOffset=a,fabric.util.getElementPosition=f}(),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}(),function(){function e(e,t,n,r){return n*(e/=r)*e+t}function t(e,t,n,r){return-n*(e/=r)*(e-2)+t}function n(e,t,n,r){return e/=r/2,e<1?n/2*e*e+t:-n/2*(--e*(e-2)-1)+t}function r(e,t,n,r){return n*(e/=r)*e*e+t}function i(e,t,n,r){return n*((e=e/r-1)*e*e+1)+t}function s(e,t,n,r){return e/=r/2,e<1?n/2*e*e*e+t:n/2*((e-=2)*e*e+2)+t}function o(e,t,n,r){return n*(e/=r)*e*e*e+t}function u(e,t,n,r){return-n*((e=e/r-1)*e*e*e-1)+t}function a(e,t,n,r){return e/=r/2,e<1?n/2*e*e*e*e+t:-n/2*((e-=2)*e*e*e-2)+t}function f(e,t,n,r){return n*(e/=r)*e*e*e*e+t}function l(e,t,n,r){return n*((e=e/r-1)*e*e*e*e+1)+t}function c(e,t,n,r){return e/=r/2,e<1?n/2*e*e*e*e*e+t:n/2*((e-=2)*e*e*e*e+2)+t}function h(e,t,n,r){return-n*Math.cos(e/r*(Math.PI/2))+n+t}function p(e,t,n,r){return n*Math.sin(e/r*(Math.PI/2))+t}function d(e,t,n,r){return-n/2*(Math.cos(Math.PI*e/r)-1)+t}function v(e,t,n,r){return e===0?t:n*Math.pow(2,10*(e/r-1))+t}function m(e,t,n,r){return e===r?t+n:n*(-Math.pow(2,-10*e/r)+1)+t}function g(e,t,n,r){return e===0?t:e===r?t+n:(e/=r/2,e<1?n/2*Math.pow(2,10*(e-1))+t:n/2*(-Math.pow(2,-10*--e)+2)+t)}function y(e,t,n,r){return-n*(Math.sqrt(1-(e/=r)*e)-1)+t}function b(e,t,n,r){return n*Math.sqrt(1-(e=e/r-1)*e)+t}function w(e,t,n,r){return e/=r/2,e<1?-n/2*(Math.sqrt(1-e*e)-1)+t:n/2*(Math.sqrt(1-(e-=2)*e)+1)+t}function E(e,t,n,r){var i=1.70158,s=0,o=n;return e===0?t:(e/=r,e===1?t+n:(s||(s=r*.3),o-1;e=e.split(/\s+/);var n=[],r,i;if(t){r=0,i=e.length;for(;r/i,"")));if(!s.documentElement)return;t.parseSVGDocument(s.documentElement,function(r,i){d.set(e,{objects:t.util.array.invoke(r,"toObject"),options:i}),n(r,i)},r)}e=e.replace(/^\n\s*/,"").trim(),d.has(e,function(r){r?d.get(e,function(e){var t=m(e);n(t.objects,t.options)}):new t.util.request(e,{method:"get",onComplete:i})})}function m(e){var n=e.objects,i=e.options;return n=n.map(function(e){return t[r(e.type)].fromObject(e)}),{objects:n,options:i}}function g(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)}function y(e){var t="";for(var n=0,r=e.length;n",'",""].join("")),t}var t=e.fabric||(e.fabric={}),n=t.util.object.extend,r=t.util.string.capitalize,i=t.util.object.clone,s={cx:"left",x:"left",cy:"top",y:"top",r:"radius","fill-opacity":"opacity","fill-rule":"fillRule","stroke-width":"strokeWidth",transform:"transformMatrix","text-decoration":"textDecoration","font-size":"fontSize","font-weight":"fontWeight","font-style":"fontStyle","font-family":"fontFamily"};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 t(e,t){var n=t[0],r=t.length===2?t[1]:t[0];e[0]=n,e[3]=r}function n(e,t){e[2]=t[0]}function r(e,t){e[1]=t[0]}function i(e,t){e[4]=t[0],t.length===2&&(e[5]=t[1])}var s=[1,0,0,1,0,0],o="(?:[-+]?\\d+(?:\\.\\d+)?(?:e[-+]?\\d+)?)",u="(?:\\s+,?\\s*|,\\s*)",a="(?:(skewX)\\s*\\(\\s*("+o+")\\s*\\))",f="(?:(skewY)\\s*\\(\\s*("+o+")\\s*\\))",l="(?:(rotate)\\s*\\(\\s*("+o+")(?:"+u+"("+o+")"+u+"("+o+"))?\\s*\\))",c="(?:(scale)\\s*\\(\\s*("+o+")(?:"+u+"("+o+"))?\\s*\\))",h="(?:(translate)\\s*\\(\\s*("+o+")(?:"+u+"("+o+"))?\\s*\\))",p="(?:(matrix)\\s*\\(\\s*("+o+")"+u+"("+o+")"+u+"("+o+")"+u+"("+o+")"+u+"("+o+")"+u+"("+o+")"+"\\s*\\))",d="(?:"+p+"|"+h+"|"+c+"|"+l+"|"+a+"|"+f+")",v="(?:"+d+"(?:"+u+d+")*"+")",m="^\\s*(?:"+v+"?)\\s*$",g=new RegExp(m),y=new RegExp(d);return function(o){var u=s.concat();return!o||o&&!g.test(o)?u:(o.replace(y,function(s){var o=(new RegExp(d)).exec(s).filter(function(e){return e!==""&&e!=null}),a=o[1],f=o.slice(2).map(parseFloat);switch(a){case"translate":i(u,f);break;case"rotate":e(u,f);break;case"scale":t(u,f);break;case"skewX":n(u,f);break;case"skewY":r(u,f);break;case"matrix":u=f}}),u)}}(),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+)?(?: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){f=n.selectNodes("//*[name(.)!='svg']");var l=[];for(var c=0,p=f.length;c0&&this.init(e,t)}var t=e.fabric||(e.fabric={});if(t.Point){t.warn("fabric.Point is already defined");return}t.Point=n,n.prototype={constructor:n,init:function(e,t){this.x=e,this.y=t},add:function(e){return new n(this.x+e.x,this.y+e.y)},addEquals:function(e){return this.x+=e.x,this.y+=e.y,this},scalarAdd:function(e){return new n(this.x+e,this.y+e)},scalarAddEquals:function(e){return this.x+=e,this.y+=e,this},subtract:function(e){return new n(this.x-e.x,this.y-e.y)},subtractEquals:function(e){return this.x-=e.x,this.y-=e.y,this},scalarSubtract:function(e){return new n(this.x-e,this.y-e)},scalarSubtractEquals:function(e){return this.x-=e,this.y-=e,this},multiply:function(e){return new n(this.x*e,this.y*e)},multiplyEquals:function(e){return this.x*=e,this.y*=e,this},divide:function(e){return new n(this.x/e,this.y/e)},divideEquals:function(e){return this.x/=e,this.y/=e,this},eq:function(e){return this.x===e.x&&this.y===e.y},lt:function(e){return this.xe.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)},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){arguments.length>0&&this.init(e)}var t=e.fabric||(e.fabric={});if(t.Intersection){t.warn("fabric.Intersection is already defined");return}t.Intersection=n,t.Intersection.prototype={init:function(e){this.status=e,this.points=[]},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("No Intersection")}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("No Intersection"),s=r.length;for(var o=0;o0&&(i.status="Intersection"),i},t.Intersection.intersectPolygonPolygon=function(e,t){var r=new n("No Intersection"),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("No Intersection");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])}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=n.sourceFromHex(e);t||(t=n.sourceFromRgb(e)),t&&this.setSource(t)},getSource:function(){return this._source},setSource:function(e){this._source=e},toRgb:function(){var e=this.getSource();return"rgb("+e[0]+","+e[1]+","+e[2]+")"},toRgba:function(){var e=this.getSource();return"rgba("+e[0]+","+e[1]+","+e[2]+","+e[3]+")"},toHex:function(){var e=this.getSource(),t=e[0].toString(16);t=t.length===1?"0"+t:t;var n=e[1].toString(16);n=n.length===1?"0"+n:n;var r=e[2].toString(16);return r=r.length===1?"0"+r:r,t.toUpperCase()+n.toUpperCase()+r.toUpperCase()},getAlpha:function(){return this.getSource()[3]},setAlpha:function(e){var t=this.getSource();return t[3]=e,this.setSource(t),this},toGrayscale:function(){var e=this.getSource(),t=parseInt((e[0]*.3+e[1]*.59+e[2]*.11).toFixed(0),10),n=e[3];return this.setSource([t,t,t,n]),this},toBlackWhite:function(e){var t=this.getSource(),n=(t[0]*.3+t[1]*.59+t[2]*.11).toFixed(0),r=t[3];return e=e||127,n=Number(n)','',"',"Created with Fabric.js ",fabric.version,"",fabric.createSVGFontFacesMarkup(this.getObjects())];this.backgroundImage&&e.push(''),this.overlayImage&&e.push('');for(var t=0,n=this.getObjects(),r=n.length;t"),e.join("")},isEmpty:function(){return this._objects.length===0},remove:function(e){return n(this._objects,e),this.getActiveObject()===e&&(this.fire("before:selection:cleared",{target:e}),this.discardActiveObject(),this.fire("selection:cleared")),this.renderAll(),e},sendToBack:function(e){return n(this._objects,e),this._objects.unshift(e),this.renderAll()},bringToFront:function(e){return n(this._objects,e),this._objects.push(e),this.renderAll()},sendBackwards:function(e){var t=this._objects.indexOf(e),r=t;if(t!==0){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}}n(this._objects,e),this._objects.splice(r,0,e)}return this.renderAll()},bringForward:function(e){var t=this.getObjects(),r=t.indexOf(e),i=r;if(r!==t.length-1){for(var s=r+1,o=this._objects.length;s"},e(fabric.StaticCanvas,{EMPTY_JSON:'{"objects": [], "background": "white"}',toGrayscale:function(e){var t=e.getContext("2d"),n=t.getImageData(0,0,e.width,e.height),r=n.data,i=n.width,s=n.height,o,u,a,f;for(a=0;a0&&(t>this.targetFindTolerance?t-=this.targetFindTolerance:t=0,n>this.targetFindTolerance?n-=this.targetFindTolerance:n=0);var o=!0,u=r.getImageData(t,n,this.targetFindTolerance*2||1,this.targetFindTolerance*2||1);for(var a=3;a0?0:-n),t.ey-(r>0?0:-r),i,s),e.lineWidth=this.selectionLineWidth,e.strokeStyle=this.selectionBorderColor;if(this.selectionDashArray.length>1){var o=t.ex+v-(n>0?0:i),u=t.ey+v-(r>0?0:s);e.beginPath(),this.drawDashedLine(e,o,u,o+i,u,this.selectionDashArray),this.drawDashedLine(e,o,u+s-1,o+i,u+s-1,this.selectionDashArray),this.drawDashedLine(e,o,u,o,u+s,this.selectionDashArray),this.drawDashedLine(e,o+i-1,u,o+i-1,u+s,this.selectionDashArray),e.closePath(),e.stroke()}else e.strokeRect(t.ex+v-(n>0?0:i),t.ey+v-(r>0?0:s),i,s)},drawDashedLine:function(e,t,n,r,i,s){var o=r-t,u=i-n,a=Math.sqrt(o*o+u*u),f=Math.atan2(u,o),l=s.length,c=0,h=!0;e.save(),e.translate(t,n),e.moveTo(0,0),e.rotate(f),t=0;while(a>t)t+=s[c++%l],t>a&&(t=a),e[h?"lineTo":"moveTo"](t,0),h=!h;e.restore()},_findSelectedObjects:function(e){var t=[],n=this._groupSelector.ex,r=this._groupSelector.ey,i=n+this._groupSelector.left,s=r+this._groupSelector.top,o,u=new fabric.Point(p(n,i),p(r,s)),a=new fabric.Point(d(n,i),d(r,s));for(var f=0,l=this._objects.length;f1&&(t=new fabric.Group(t),this.setActiveGroup(t),t.saveCoords(),this.fire("selection:created",{target:t})),this.renderAll()},findTarget:function(e,t){var n,r=this.getPointer(e);if(this.controlsAboveOverlay&&this.lastRenderedObjectWithControlsAboveOverlay&&this.containsPoint(e,this.lastRenderedObjectWithControlsAboveOverlay))return n=this.lastRenderedObjectWithControlsAboveOverlay,n;var i=this.getActiveGroup();if(i&&!t&&this.containsPoint(e,i))return n=i,n;var s=[];for(var o=this._objects.length;o--;)if(this._objects[o]&&this.containsPoint(e,this._objects[o])){if(!this.perPixelTargetFind&&!this._objects[o].perPixelTargetFind){n=this._objects[o],this.relatedTarget=n;break}s[s.length]=this._objects[o]}for(var u=0,a=s.length;u"},set:function(e,t){if(typeof e=="object")for(var n in e)this._set(n,e[n]);else typeof t=="function"?this._set(e,t(this.get(e))):this._set(e,t);return this},_set:function(e,n){var r=(e==="scaleX"||e==="scaleY")&&n1?this.strokeWidth:0,t=this.padding,n=o(this.angle);this.currentWidth=(this.width+e)*this.scaleX+t*2,this.currentHeight=(this.height+e)*this.scaleY+t*2,this.currentWidth<0&&(this.currentWidth=Math.abs(this.currentWidth));var r=Math.sqrt(Math.pow(this.currentWidth/2,2)+Math.pow(this.currentHeight/2,2)),i=Math.atan(this.currentHeight/this.currentWidth),s=Math.cos(i+n)*r,u=Math.sin(i+n)*r,a=Math.sin(n),f=Math.cos(n),l={x:this.left-s,y:this.top-u},c={x:l.x+this.currentWidth*f,y:l.y+this.currentWidth*a},h={x:c.x-this.currentHeight*a,y:c.y+this.currentHeight*f},p={x:l.x-this.currentHeight*a,y:l.y+this.currentHeight*f},d={x:l.x-this.currentHeight/2*a,y:l.y+this.currentHeight/2*f},v={x:l.x+this.currentWidth/2*f,y:l.y+this.currentWidth/2*a},m={x:c.x-this.currentHeight/2*a,y:c.y+this.currentHeight/2*f},g={x:p.x+this.currentWidth/2*f,y:p.y+this.currentWidth/2*a},y={x:l.x+this.currentWidth/2*f,y:l.y+this.currentWidth/2*a};return this.oCoords={tl:l,tr:c,br:h,bl:p,ml:d,mt:v,mr:m,mb:g,mtr:y},this._setCornerCoords(),this},getBoundingRectWidth:function(){this.oCoords||this.setCoords();var e=[this.oCoords.tl.x,this.oCoords.tr.x,this.oCoords.br.x,this.oCoords.bl.x],n=t.util.array.min(e),r=t.util.array.max(e);return Math.abs(n-r)},getBoundingRectHeight:function(){this.oCoords||this.setCoords();var e=[this.oCoords.tl.y,this.oCoords.tr.y,this.oCoords.br.y,this.oCoords.bl.y],n=t.util.array.min(e),r=t.util.array.max(e);return Math.abs(n-r)},drawBorders:function(e){if(!this.hasBorders)return;var n=t.Object.MIN_SCALE_LIMIT,r=this.padding,i=r*2,s=this.strokeWidth>1?this.strokeWidth:0;e.save(),e.globalAlpha=this.isMoving?this.borderOpacityWhenMoving:1,e.strokeStyle=this.borderColor;var o=1/(this.scaleXc&&(l=f-c),u?n+=h*u-(l*u||0):r+=h*a-(l*a||0),e[1&t?"moveTo":"lineTo"](n,r),t>=o&&(t=0)}}1&this.strokeDashArray.length&&this.strokeDashArray.push.apply(this.strokeDashArray,this.strokeDashArray);var t=0,n=-this.width/2,r=-this.height/2,i=this,s=this.padding,o=this.strokeDashArray.length;e.save(),e.beginPath(),u(1,0),u(0,1),u(-1,0),u(0,-1),e.stroke(),e.closePath(),e.restore()},drawCorners:function(e){if(!this.hasControls)return;var t=this.cornersize,n=t/2,r=this.strokeWidth/2,i=-(this.width/2),s=-(this.height/2),o,u,a=t/this.scaleX,f=t/this.scaleY,l=this.padding/this.scaleX,c=this.padding/this.scaleY,h=n/this.scaleY,p=n/this.scaleX,d=(n-t)/this.scaleX,v=(n-t)/this.scaleY,m=this.height,g=this.width,y=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,o=i-p-r-l,u=s-h-r-c,e.clearRect(o,u,a,f),e[y](o,u,a,f),o=i+g-p+r+l,u=s-h-r-c,e.clearRect(o,u,a,f),e[y](o,u,a,f),o=i-p-r-l,u=s+m+v+r+c,e.clearRect(o,u,a,f),e[y](o,u,a,f),o=i+g+d+r+l,u=s+m+v+r+c,e.clearRect(o,u,a,f),e[y](o,u,a,f),this.lockUniScaling||(o=i+g/2-p,u=s-h-r-c,e.clearRect(o,u,a,f),e[y](o,u,a,f),o=i+g/2-p,u=s+m+v+r+c,e.clearRect(o,u,a,f),e[y](o,u,a,f),o=i+g+d+r+l,u=s+m/2-h,e.clearRect(o,u,a,f),e[y](o,u,a,f),o=i-p-r-l,u=s+m/2-h,e.clearRect(o,u,a,f),e[y](o,u,a,f)),this.hasRotatingPoint&&(o=i+g/2-p,u=this.flipY?s+m+this.rotatingPointOffset/this.scaleY-f/2+r+c:s-this.rotatingPointOffset/this.scaleY-f/2-r-c,e.clearRect(o,u,a,f),e[y](o,u,a,f)),e.restore(),this},clone:function(e,n){return this.constructor.fromObject?this.constructor.fromObject(this.toObject(n),e):new t.Object(this.toObject(n))},cloneAsImage:function(e){if(t.Image){var n=new Image;n.onload=function(){e&&e(new t.Image(n),r),n=n.onload=null};var r={angle:this.get("angle"),flipX:this.get("flipX"),flipY:this.get("flipY")};this.set("angle",0).set("flipX",!1).set("flipY",!1),this.toDataURL(function(e){n.src=e})}return this},toDataURL:function(e){function i(t){t.left=n.width/2,t.top=n.height/2,t.setActive(!1),r.add(t);var i=r.toDataURL("png");r.dispose(),r=t=null,e&&e(i)}var n=t.document.createElement("canvas");!n.getContext&&typeof G_vmlCanvasManager!="undefined"&&G_vmlCanvasManager.initElement(n),n.width=this.getBoundingRectWidth(),n.height=this.getBoundingRectHeight(),t.util.wrapElement(n,"div");var r=new t.Canvas(n);r.backgroundColor="transparent",r.renderAll(),this.constructor.async?this.clone(i):i(this.clone())},hasStateChanged:function(){return this.stateProperties.some(function(e){return this[e]!==this.originalState[e]},this)},saveState:function(){return this.stateProperties.forEach(function(e){this.originalState[e]=this.get(e)},this),this},setupState:function(){this.originalState={},this.saveState()},intersectsWithRect:function(e,n){var r=this.oCoords,i=new t.Point(r.tl.x,r.tl.y),s=new t.Point(r.tr.x,r.tr.y),o=new t.Point(r.bl.x,r.bl.y),u=new t.Point(r.br.x,r.br.y),a=t.Intersection.intersectPolygonRectangle([i,s,u,o],e,n);return a.status==="Intersection"},intersectsWithObject:function(e){function n(e){return{tl:new t.Point(e.tl.x,e.tl.y),tr:new t.Point(e.tr.x,e.tr.y),bl:new t.Point(e.bl.x,e.bl.y),br:new t.Point(e.br.x,e.br.y)}}var r=n(this.oCoords),i=n(e.oCoords),s=t.Intersection.intersectPolygonPolygon([r.tl,r.tr,r.br,r.bl],[i.tl,i.tr,i.br,i.bl]);return s.status==="Intersection"},isContainedWithinObject:function(e){return this.isContainedWithinRect(e.oCoords.tl,e.oCoords.br)},isContainedWithinRect:function(e,n){var r=this.oCoords,i=new t.Point(r.tl.x,r.tl.y),s=new t.Point(r.tr.x,r.tr.y),o=new t.Point(r.bl.x,r.bl.y);return i.x>e.x&&s.xe.y&&o.y=t&&l.d.y>=t)continue;l.o.x===l.d.x&&l.o.x>=e?(u=l.o.x,a=t):(r=0,i=(l.d.y-l.o.y)/(l.d.x-l.o.x),s=t-r*e,o=l.o.y-i*l.o.x,u=-(s-o)/(r-i),a=s+r*u),u>=e&&(f+=1);if(f===2)break}return f},_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}}},_setCornerCoords:function(){var e=this.oCoords,t=o(this.angle),n=o(45-this.angle),r=Math.sqrt(2*Math.pow(this.cornersize,2))/2,i=r*Math.cos(n),s=r*Math.sin(n),u=Math.sin(t),a=Math.cos(t);e.tl.corner={tl:{x:e.tl.x-s,y:e.tl.y-i},tr:{x:e.tl.x+i,y:e.tl.y-s},bl:{x:e.tl.x-i,y:e.tl.y+s},br:{x:e.tl.x+s,y:e.tl.y+i}},e.tr.corner={tl:{x:e.tr.x-s,y:e.tr.y-i},tr:{x:e.tr.x+i,y:e.tr.y-s},br:{x:e.tr.x+s,y:e.tr.y+i},bl:{x:e.tr.x-i,y:e.tr.y+s}},e.bl.corner={tl:{x:e.bl.x-s,y:e.bl.y-i},bl:{x:e.bl.x-i,y:e.bl.y+s},br:{x:e.bl.x+s,y:e.bl.y+i},tr:{x:e.bl.x+i,y:e.bl.y-s}},e.br.corner={tr:{x:e.br.x+i,y:e.br.y-s},bl:{x:e.br.x-i,y:e.br.y+s},br:{x:e.br.x+s,y:e.br.y+i},tl:{x:e.br.x-s,y:e.br.y-i}},e.ml.corner={tl:{x:e.ml.x-s,y:e.ml.y-i},tr:{x:e.ml.x+i,y:e.ml.y-s},bl:{x:e.ml.x-i,y:e.ml.y+s},br:{x:e.ml.x+s,y:e.ml.y+i}},e.mt.corner={tl:{x:e.mt.x-s,y:e.mt.y-i},tr:{x:e.mt.x+i,y:e.mt.y-s},bl:{x:e.mt.x-i,y:e.mt.y+s},br:{x:e.mt.x+s,y:e.mt.y+i}},e.mr.corner={tl:{x:e.mr.x-s,y:e.mr.y-i},tr:{x:e.mr.x+i,y:e.mr.y-s},bl:{x:e.mr.x-i,y:e.mr.y+s},br:{x:e.mr.x+s,y:e.mr.y+i}},e.mb.corner={tl:{x:e.mb.x-s,y:e.mb.y-i},tr:{x:e.mb.x+i,y:e.mb.y-s},bl:{x:e.mb.x-i,y:e.mb.y+s},br:{x:e.mb.x+s,y:e.mb.y+i}},e.mtr.corner={tl:{x:e.mtr.x-s+u*this.rotatingPointOffset,y:e.mtr.y-i-a*this.rotatingPointOffset},tr:{x:e.mtr.x+i+u*this.rotatingPointOffset,y:e.mtr.y-s-a*this.rotatingPointOffset},bl:{x:e.mtr.x-i+u*this.rotatingPointOffset,y:e.mtr.y+s-a*this.rotatingPointOffset},br:{x:e.mtr.x+s+u*this.rotatingPointOffset,y:e.mtr.y+i-a*this.rotatingPointOffset}}},toGrayscale:function(){var e=this.get("fill");return e&&this.set("overlayFill",(new t.Color(e)).toGrayscale().toRgb()),this},complexity:function(){return 0},toJSON:function(e){return this.toObject(e)},setGradientFill:function(e){this.set("fill",t.Gradient.forObject(this,e))},animate:function(){if(arguments[0]&&typeof arguments[0]=="object")for(var e in arguments[0])this._animate(e,arguments[0][e],arguments[1]);else this._animate.apply(this,arguments);return this},_animate:function(e,n,r){var i=this;r||(r={}),"from"in r||(r.from=this.get(e)),/[+\-]/.test((n+"").charAt(0))&&(n=this.get(e)+parseFloat(n)),t.util.animate({startValue:r.from,endValue:n,byValue:r.by,easing:r.easing,duration:r.duration,onChange:function(t){i.set(e,t),r.onChange&&r.onChange()},onComplete:function(){i.setCoords(),r.onComplete&&r.onComplete()}})},centerH:function(){return this.canvas.centerObjectH(this),this},centerV:function(){return this.canvas.centerObjectV(this),this},center:function(){return this.centerH().centerV()},remove:function(){return this.canvas.remove(this)},sendToBack:function(){return this.canvas.sendToBack(this),this},bringToFront:function(){return this.canvas.bringToFront(this),this},sendBackwards:function(){return this.canvas.sendBackwards(this),this},bringForward:function(){return this.canvas.bringForward(this),this}});var u=t.Object.prototype;for(var a=u.stateProperties.length;a--;){var f=u.stateProperties[a],l=f.charAt(0).toUpperCase()+f.slice(1),c="set"+l,h="get"+l;u[h]||(u[h]=function(e){return new Function('return this.get("'+e+'")')}(f)),u[c]||(u[c]=function(e){return new Function("value",'return this.set("'+e+'", value)')}(f))}t.Object.prototype.rotate= -t.Object.prototype.setAngle,n(t.Object.prototype,t.Observable),n(t.Object,{NUM_FRACTION_DIGITS:2,MIN_SCALE_LIMIT:.1})}(typeof exports!="undefined"?exports:this),function(e){"use strict";var t=e.fabric||(e.fabric={}),n=t.util.object.extend,r={x1:1,x2:1,y1:1,y2:1};if(t.Line){t.warn("fabric.Line is already defined");return}t.Line=t.util.createClass(t.Object,{type:"line",initialize:function(e,t){t=t||{},e||(e=[0,0,0,0]),this.callSuper("initialize",t),this.set("x1",e[0]),this.set("y1",e[1]),this.set("x2",e[2]),this.set("y2",e[3]),this._setWidthHeight(t)},_setWidthHeight:function(e){e||(e={}),this.set("width",this.x2-this.x1||1),this.set("height",this.y2-this.y1||1),this.set("left","left"in e?e.left:this.x1+this.width/2),this.set("top","top"in e?e.top:this.y1+this.height/2)},_set:function(e,t){return this[e]=t,e in r&&this._setWidthHeight(),this},_render:function(e){e.beginPath(),this.group&&e.translate(-this.group.width/2+this.left,-this.group.height/2+this.top),e.moveTo(this.width===1?0:-this.width/2,this.height===1?0:-this.height/2),e.lineTo(this.width===1?0:this.width/2,this.height===1?0:this.height/2),e.lineWidth=this.strokeWidth;var t=e.strokeStyle;e.strokeStyle=e.fillStyle,e.stroke(),e.strokeStyle=t},complexity:function(){return 1},toObject:function(e){return n(this.callSuper("toObject",e),{x1:this.get("x1"),y1:this.get("y1"),x2:this.get("x2"),y2:this.get("y2")})},toSVG:function(){return[""].join("")}}),t.Line.ATTRIBUTE_NAMES="x1 y1 x2 y2 stroke stroke-width transform".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",initialize:function(e){e=e||{},this.set("radius",e.radius||0),this.callSuper("initialize",e);var t=this.get("radius")*2;this.set("width",t).set("height",t)},toObject:function(e){return r(this.callSuper("toObject",e),{radius:this.get("radius")})},toSVG:function(){return'"},_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),e.closePath(),this.fill&&e.fill(),this.stroke&&e.stroke()},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="cx cy r fill fill-opacity opacity stroke stroke-width transform".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");return"left"in s&&(s.left-=n.width/2||0),"top"in s&&(s.top-=n.height/2||0),new t.Circle(r(s,n))},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.fill&&e.fill(),this.stroke&&e.stroke()},complexity:function(){return 1},toSVG:function(){var e=this.width/2,t=this.height/2,n=[-e+" "+t,"0 "+ -t,e+" "+t].join(",");return'"}}),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",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(){return[""].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,this.transformMatrix&&this.group&&e.translate(this.cx,this.cy),e.transform(1,0,0,this.ry/this.rx,0,0),e.arc(t?this.left:0,t?this.top:0,this.rx,0,n,!1),this.stroke&&e.stroke(),this.fill&&e.fill(),e.restore()},complexity:function(){return 1}}),t.Ellipse.ATTRIBUTE_NAMES="cx cy rx ry fill fill-opacity opacity stroke stroke-width transform".split(" "),t.Ellipse.fromElement=function(e,n){n||(n={});var i=t.parseAttributes(e,t.Ellipse.ATTRIBUTE_NAMES),s=i.left,o=i.top;"left"in i&&(i.left-=n.width/2||0),"top"in i&&(i.top-=n.height/2||0);var u=new t.Ellipse(r(i,n));return u.cx=s||0,u.cy=o||0,u},t.Ellipse.fromObject=function(e){return new t.Ellipse(e)}}(typeof exports!="undefined"?exports:this),function(e){"use strict";function r(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}t.Rect=t.util.createClass(t.Object,{type:"rect",rx:0,ry:0,initialize:function(e){e=e||{},this._initStateProperties(),this.callSuper("initialize",e),this._initRxRy()},_initStateProperties:function(){this.stateProperties=this.stateProperties.concat(["rx","ry"])},_initRxRy:function(){this.rx&&!this.ry?this.ry=this.rx:this.ry&&!this.rx&&(this.rx=this.ry)},_render:function(e){var t=this.rx||0,n=this.ry||0,r=-this.width/2,i=-this.height/2,s=this.width,o=this.height;e.beginPath(),e.globalAlpha=this.group?e.globalAlpha*this.opacity:this.opacity,this.transformMatrix&&this.group&&e.translate(this.width/2+this.x,this.height/2+this.y),!this.transformMatrix&&this.group&&e.translate(-this.group.width/2+this.width/2+this.x,-this.group.height/2+this.height/2+this.y),e.moveTo(r+t,i),e.lineTo(r+s-t,i),e.quadraticCurveTo(r+s,i,r+s,i+n,r+s,i+n),e.lineTo(r+s,i+o-n),e.quadraticCurveTo(r+s,i+o,r+s-t,i+o,r+s-t,i+o),e.lineTo(r+t,i+o),e.quadraticCurveTo(r,i+o,r,i+o-n,r,i+o-n),e.lineTo(r,i+n),e.quadraticCurveTo(r,i,r+t,i,r+t,i),e.closePath(),this.fill&&e.fill(),this.strokeDashArray?this._renderDashedStroke(e):this.stroke&&e.stroke()},_normalizeLeftTopProperties:function(e){return e.left&&this.set("left",e.left+this.getWidth()/2),this.set("x",e.left||0),e.top&&this.set("top",e.top+this.getHeight()/2),this.set("y",e.top||0),this},complexity:function(){return 1},toObject:function(e){return n(this.callSuper("toObject",e),{rx:this.get("rx")||0,ry:this.get("ry")||0})},toSVG:function(){return'"}}),t.Rect.ATTRIBUTE_NAMES="x y width height rx ry fill fill-opacity opacity stroke stroke-width transform".split(" "),t.Rect.fromElement=function(e,i){if(!e)return null;var s=t.parseAttributes(e,t.Rect.ATTRIBUTE_NAMES);s=r(s);var o=new t.Rect(n(i?t.util.object.clone(i):{},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",initialize:function(e,t){t=t||{},this.set("points",e),this.callSuper("initialize",t),this._calcDimensions()},_calcDimensions:function(){return t.Polygon.prototype._calcDimensions.call(this)},toObject:function(e){return t.Polygon.prototype.toObject.call(this,e)},toSVG:function(){var e=[];for(var t=0,r=this.points.length;t"].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"].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;n1&&(g=Math.sqrt(g),n*=g,i*=g);var y=d/n,b=p/n,w=-p/i,E=d/i,S=y*l+b*c,x=w*l+E*c,T=y*e+b*t,N=w*e+E*t,C=(T-S)*(T-S)+(N-x)*(N-x),k=1/C-.25;k<0&&(k=0);var L=Math.sqrt(k);a===u&&(L=-L);var A=.5*(S+T)-L*(N-x),O=.5*(x+N)+L*(T-S),M=Math.atan2(x-O,S-A),_=Math.atan2(N-O,T-A),D=_-M;D<0&&a===1?D+=2*Math.PI:D>0&&a===0&&(D-=2*Math.PI);var P=Math.ceil(Math.abs(D/(Math.PI*.5+.001))),H=[];for(var B=0;B"},toObject:function(e){var t=h(this.callSuper("toObject",e),{path:this.path});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(){var e=[];for(var t=0,n=this.path.length;t',"',""].join("")},complexity:function(){return this.path.length},_parsePath:function(){var e=[],n,r,i;for(var s=0,o,u=this.path.length;sc)for(var h=1,p=o.length;h"];for(var n=0,r=e.length;n"),t.join("")},toString:function(){return"#"},isSameColor:function(){var e=this.getObjects()[0].get("fill");return this.getObjects().every(function(t){return t.get("fill")===e})},complexity:function(){return this.paths.reduce(function(e,t){return e+(t&&t.complexity?t.complexity():0)},0)},toGrayscale:function(){var e=this.paths.length;while(e--)this.paths[e].toGrayscale();return this},getObjects:function(){return this.paths}}),t.PathGroup.fromObject=function(e){var n=u(e.paths);return new t.PathGroup(n,e)}}(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,o=t.util.removeFromArray;if(t.Group)return;t.Group=t.util.createClass(t.Object,{type:"group",initialize:function(e,t){t=t||{},this.objects=e||[],this.originalState={},this.callSuper("initialize"),this._calcBounds(),this._updateObjectsCoords(),t&&n(this,t),this._setOpacityIfSame(),this.setCoords(!0),this.saveCoords()},_updateObjectsCoords:function(){var e=this.left,t=this.top;this.forEachObject(function(n){var r=n.get("left"),i=n.get("top");n.set("originalLeft",r),n.set("originalTop",i),n.set("left",r-e),n.set("top",i-t),n.setCoords(),n.hideCorners=!0},this)},toString:function(){return"#"},getObjects:function(){return this.objects},addWithUpdate:function(e){return this._restoreObjectsState(),this.objects.push(e),this._calcBounds(),this._updateObjectsCoords(),this},removeWithUpdate:function(e){return this._restoreObjectsState(),o(this.objects,e),e.setActive(!1),this._calcBounds(),this._updateObjectsCoords(),this},add:function(e){return this.objects.push(e),this},remove:function(e){return o(this.objects,e),this},size:function(){return this.getObjects().length},_set:function(e,t){if(e==="fill"||e==="opacity"){var n=this.objects.length;this[e]=t;while(n--)this.objects[n].set(e,t)}else this[e]=t},contains:function(e){return this.objects.indexOf(e)>-1},toObject:function(e){return n(this.callSuper("toObject",e),{objects:s(this.objects,"toObject",e)})},render:function(e,t){e.save(),this.transform(e);var n=Math.max(this.scaleX,this.scaleY);for(var r=this.objects.length;r>0;r--){var i=this.objects[r-1],s=i.borderScaleFactor,o=i.hasRotatingPoint;i.borderScaleFactor=n,i.hasRotatingPoint=!1,i.render(e),i.borderScaleFactor=s,i.hasRotatingPoint=o}!t&&this.active&&(this.drawBorders(e),this.hideCorners||this.drawCorners(e)),e.restore(),this.setCoords()},item:function(e){return this.getObjects()[e]},complexity:function(){return this.getObjects().reduce(function(e,t){return e+=typeof t.complexity=="function"?t.complexity():0,e},0)},_restoreObjectsState:function(){return this.objects.forEach(this._restoreObjectState,this),this},_restoreObjectState:function(e){var t=this.get("left"),n=this.get("top"),r=this.getAngle()*(Math.PI/180),i=Math.cos(r)*e.get("top")+Math.sin(r)*e.get("left"),s=-Math.sin(r)*e.get("top")+Math.cos(r)*e.get("left");return e.setAngle(e.getAngle()+this.getAngle()),e.set("left",t+s*this.get("scaleX")),e.set("top",n+i*this.get("scaleY")),e.set("scaleX",e.get("scaleX")*this.get("scaleX")),e.set("scaleY",e.get("scaleY")*this.get("scaleY")),e.setCoords(),e.hideCorners=!1,e.setActive(!1),e.setCoords(),this},destroy:function(){return this._restoreObjectsState()},saveCoords:function(){return this._originalLeft=this.get("left"),this._originalTop=this.get("top"),this},hasMoved:function(){return this._originalLeft!==this.get("left")||this._originalTop!==this.get("top")},setObjectsCoords:function(){return this.forEachObject(function(e){e.setCoords()}),this},activateAllObjects:function(){return this.forEachObject(function(e){e.setActive()}),this},forEachObject:t.StaticCanvas.prototype.forEachObject,_setOpacityIfSame:function(){var e=this.getObjects(),t=e[0]?e[0].get("opacity"):1,n=e.every(function(e){return e.get("opacity")===t});n&&(this.opacity=t)},_calcBounds:function(){var e=[],t=[],n,s,o,u,a,f,l,c=0,h=this.objects.length;for(;ce.x&&i-ne.y},toGrayscale:function(){var e=this.objects.length;while(e--)this.objects[e].toGrayscale()},toSVG:function(){var e=[];for(var t=0,n=this.objects.length;t'+e.join("")+""}}),t.Group.fromObject=function(e,n){t.util.enlivenObjects(e.objects,function(r){delete e.objects,n&&n(new t.Group(r,e))})},t.Group.async=!0}(typeof exports!="undefined"?exports:this),function(e){"use strict";var t=fabric.util.object.extend;e.fabric||(e.fabric={});if(e.fabric.Image){fabric.warn("fabric.Image is already defined.");return}fabric.Image=fabric.util.createClass(fabric.Object,{active:!1,type:"image",initialize:function(e,t){t||(t={}),this.callSuper("initialize",t),this._initElement(e),this._originalImage=this.getElement(),this._initConfig(t),this.filters=[],t.filters&&(this.filters=t.filters,this.applyFilters())},getElement:function(){return this._element},setElement:function(e){return this._element=e,this._initConfig(),this},getOriginalSize:function(){var e=this.getElement();return{width:e.width,height:e.height}},render:function(e,t){e.save();var n=this.transformMatrix;this._resetWidthHeight(),this.group&&e.translate(-this.group.width/2+this.width/2,-this.group.height/2+this.height/2),n&&e.transform(n[0],n[1],n[2],n[3],n[4],n[5]),t||this.transform(e),this._render(e),this.active&&!t&&(this.drawBorders(e),this.hideCorners||this.drawCorners(e)),e.restore()},toObject:function(e){return t(this.callSuper("toObject",e),{src:this._originalImage.src||this._originalImage._src,filters:this.filters.concat()})},toSVG:function(){return''+'"+""},getSrc:function(){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.filters.length===0){this.setElement(this._originalImage),e&&e();return}var t=typeof Buffer!="undefined"&&typeof window=="undefined",n=this._originalImage,r=fabric.document.createElement("canvas"),i=t?new(require("canvas").Image):fabric.document.createElement("img"),s=this;!r.getContext&&typeof G_vmlCanvasManager!="undefined"&&G_vmlCanvasManager.initElement(r),r.width=n.width,r.height=n.height,r.getContext("2d").drawImage(n,0,0,n.width,n.height),this.filters.forEach(function(e){e&&e.applyTo(r)}),i.onload=function(){s._element=i,e&&e(),i.onload=r=n=null},i.width=n.width,i.height=n.height;if(t){var o=r.toDataURL("image/png").replace(/data:image\/png;base64,/,"");i.src=new Buffer(o,"base64"),s._element=i,e&&e()}else i.src=r.toDataURL("image/png");return this},_render:function(e){e.drawImage(this.getElement(),-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)},_initFilters:function(e){e.filters&&e.filters.length&&(this.filters=e.filters.map(function(e){return e&&fabric.Image.filters[e.type].fromObject(e)}))},_setWidthHeight:function(e){this.width="width"in e?e.width:this.getElement().width||0,this.height="height"in e?e.height:this.getElement().height||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){var n=fabric.document.createElement("img"),r=e.src;e.width&&(n.width=e.width),e.height&&(n.height=e.height),n.onload=function(){fabric.Image.prototype._initFilters.call(e,e);var r=new fabric.Image(n,e);t&&t(r),n=n.onload=null},n.src=r},fabric.Image.fromURL=function(e,t,n){var r=fabric.document.createElement("img");r.onload=function(){t&&t(new fabric.Image(r,n)),r=r.onload=null},r.src=e},fabric.Image.ATTRIBUTE_NAMES="x y width height fill fill-opacity opacity stroke stroke-width transform xlink:href".split(" "),fabric.Image.fromElement=function(e,n,r){r||(r={});var i=fabric.parseAttributes(e,fabric.Image.ATTRIBUTE_NAMES);fabric.Image.fromURL(i["xlink:href"],n,t(i,r))},fabric.Image.async=!0}(typeof exports!="undefined"?exports:this),fabric.util.object.extend(fabric.Object.prototype,{_getAngleValueForStraighten:function(){var e=this.get("angle");return e>-225&&e<=-135?-180:e>-135&&e<=-45?-90:e>-45&&e<=45?0:e>45&&e<=135?90:e>135&&e<=225?180:e>225&&e<=315?270:e>315?360:0},straighten:function(){var e=this._getAngleValueForStraighten();return this.setAngle(e),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.setActive(!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.Grayscale=fabric.util.createClass({type:"Grayscale",applyTo:function(e){var t=e.getContext("2d"),n=t.getImageData(0,0,e.width,e.height),r=n.data,i=n.width,s=n.height,o,u,a,f;for(a=0;ao&&f>o&&l>o&&u(a-f)0&&(r[s]=a,r[s+1]=f,r[s+2]=l);t.putImageData(n,0,0)},toJSON:function(){return{type:this.type,color:this.color}}}),fabric.Image.filters.Tint.fromObject=function(e){return new fabric.Image.filters.Tint(e)},fabric.Image.filters.Convolute=fabric.util.createClass({type:"Convolute",initialize:function(e){e||(e={}),this.opaque=e.opaque,this.matrix=e.matrix||[0,0,0,0,1,0,0,0,0],this.tmpCtx=fabric.document.createElement("canvas").getContext("2d")},_createImageData:function(e,t){return this.tmpCtx.createImageData(e,t)},applyTo:function(e){var t=this.matrix,n=e.getContext("2d"),r=n.getImageData(0,0,e.width,e.height),i=Math.round(Math.sqrt(t.length)),s=Math.floor(i/2),o=r.data,u=r.width,a=r.height,f=u,l=a,c=this._createImageData(f,l),h=c.data,p=this.opaque?1:0;for(var d=0;d=0&&N=0&&C'},_render:function(e){typeof Cufon=="undefined"||this.useNative===!0?this._renderViaNative(e):this._renderViaCufon(e)},_renderViaCufon:function(e){var t=Cufon.textOptions||(Cufon.textOptions={});t.left=this.left,t.top=this.top,t.context=e,t.color=this.fill;var n=this._initDummyElementForCufon();this.transform(e),Cufon.replaceElement(n,{engine:"canvas",separate:"none",fontFamily:this.fontFamily,fontWeight:this.fontWeight,textDecoration:this.textDecoration,textShadow:this.textShadow,textAlign:this.textAlign,fontStyle:this.fontStyle,lineHeight:this.lineHeight,strokeStyle:this.strokeStyle,strokeWidth:this.strokeWidth,backgroundColor:this.backgroundColor,textBackgroundColor:this.textBackgroundColor}),this.width=t.width,this.height=t.height,this._totalLineHeight=t.totalLineHeight,this._fontAscent=t.fontAscent,this._boundaries=t.boundaries,this._shadowOffsets=t.shadowOffsets,this._shadows=t.shadows||[],n=null,this.setCoords()},_renderViaNative:function(e){this.transform(e),this._setTextStyles(e);var t=this.text.split(/\r?\n/);this.width=this._getTextWidth(e,t),this.height=this._getTextHeight(e,t),this._renderTextBackground(e,t),this.textAlign!=="left"&&(e.save(),e.translate(this.textAlign==="center"?this.width/2:this.width,0)),this._setTextShadow(e),this._renderTextFill(e,t),this.textShadow&&e.restore(),this._renderTextStroke(e,t),this.textAlign!=="left"&&e.restore(),this._renderTextDecoration(e,t),this._setBoundaries(e,t),this._totalLineHeight=0,this.setCoords()},_setBoundaries:function(e,t){this._boundaries=[];for(var n=0,r=t.length;nn&&(n=s)}return n},_setTextShadow:function(e){if(this.textShadow){var t=/\s+(-?\d+)(?:px)?\s+(-?\d+)(?:px)?\s+(\d+)(?:px)?\s*/,n=this.textShadow,r=t.exec(this.textShadow),i=n.replace(t,"");e.save(),e.shadowColor=i,e.shadowOffsetX=parseInt(r[1],10),e.shadowOffsetY=parseInt(r[2],10),e.shadowBlur=parseInt(r[3],10),this._shadows=[{blur:e.shadowBlur,color:e.shadowColor,offX:e.shadowOffsetX,offY:e.shadowOffsetY}],this._shadowOffsets=[[parseInt(e.shadowOffsetX,10),parseInt(e.shadowOffsetY,10)]]}},_renderTextFill:function(e,t){this._boundaries=[];for(var n=0,r=t.length;n-1&&i(this.fontSize),this.textDecoration.indexOf("line-through")>-1&&i(this.fontSize/2),this.textDecoration.indexOf("overline")>-1&&i(0)},_getFontDeclaration:function(){return[this.fontStyle,this.fontWeight,this.fontSize+"px",t.isLikelyNode?'"'+this.fontFamily+'"':this.fontFamily].join(" ")},_initDummyElementForCufon:function(){var e=t.document.createElement("pre"),n=t.document.createElement("div");return n.appendChild(e),typeof G_vmlCanvasManager=="undefined"?e.innerHTML=this.text:e.innerText=this.text.replace(/\r?\n/gi,"\r"),e.style.fontSize=this.fontSize+"px",e.style.letterSpacing="normal",e},render:function(e,t){e.save(),this._render(e),!t&&this.active&&(this.drawBorders(e),this.hideCorners||this.drawCorners(e)),e.restore()},toObject:function(e){return 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,textShadow:this.textShadow,textAlign:this.textAlign,path:this.path,strokeStyle:this.strokeStyle,strokeWidth:this.strokeWidth,backgroundColor:this.backgroundColor,textBackgroundColor:this.textBackgroundColor,useNative:this.useNative})},toSVG:function(){var e=this.text.split(/\r?\n/),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,s=this._getSVGTextAndBg(t,n,e),o=this._getSVGShadows(t,e);return r+=this._fontAscent?this._fontAscent/5*this.lineHeight:0,['',s.textBgRects.join(""),"',o.join(""),s.textSpans.join(""),"",""].join("")},_getSVGShadows:function(e,n){var r=[],s,o,u,a,f=1;if(!this._shadows||!this._boundaries)return r;for(s=0,u=this._shadows.length;s",t.util.string.escapeXml(n[o]),""),f=1}else f++;return r},_getSVGTextAndBg:function(e,n,r){var s=[],o=[],u,a,f,l=1;this.backgroundColor&&this._boundaries&&o.push("');for(u=0,f=r.length;u",t.util.string.escapeXml(r[u]),""),l=1):l++;if(!this.textBackgroundColor||!this._boundaries)continue;o.push("')}return{textSpans:s,textBgRects:o}},_getFillAttributes:function(e){var n=e?new t.Color(e):"";return!n||!n.getSource()||n.getAlpha()===1?'fill="'+e+'"':'opacity="'+n.getAlpha()+'" fill="'+n.setAlpha(1).toRgb()+'"'},setColor:function(e){return this.set("fill",e),this},setFontsize:function(e){return this.set("fontSize",e),this._initDimensions(),this.setCoords(),this},getText:function(){return this.text},setText:function(e){return this.set("text",e),this._initDimensions(),this.setCoords(),this},_set:function(e,t){e==="fontFamily"&&this.path&&(this.path=this.path.replace(/(.*?)([^\/]*)(\.font\.js)/,"$1"+t+"$3")),this.callSuper("_set",e,t)}}),t.Text.ATTRIBUTE_NAMES="x y fill fill-opacity opacity stroke stroke-width transform font-family font-style font-weight font-size text-decoration".split(" "),t.Text.fromObject=function(e){return new t.Text(e.text,r(e))},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);var i=new t.Text(e.textContent,n);return i.set({left:i.getLeft()+i.getWidth()/2,top:i.getTop()-i.getHeight()/2}),i}}(typeof exports!="undefined"?exports:this),function(){function request(e,t,n){var r=URL.parse(e),i=HTTP.createClient(r.port,r.hostname),s=i.request("GET",r.pathname,{host:r.hostname});i.addListener("error",function(e){e.errno===process.ECONNREFUSED?fabric.log("ECONNREFUSED: connection refused to "+i.host+":"+i.port):fabric.log(e.message)}),s.end(),s.on("response",function(e){var r="";t&&e.setEncoding(t),e.on("end",function(){n(r)}),e.on("data",function(t){e.statusCode===200&&(r+=t)})})}if(typeof document!="undefined"&&typeof window!="undefined")return;var DOMParser=(new require("xmldom")).DOMParser,URL=require("url"),HTTP=require("http"),Canvas=require("canvas"),Image=require("canvas").Image;fabric.util.loadImage=function(e,t){request(e,"binary",function(n){var r=new Image;r.src=new Buffer(n,"binary"),r._src=e,t(r)})},fabric.loadSVGFromURL=function(e,t){e=e.replace(/^\n\s*/,"").replace(/\?.*$/,"").trim(),request(e,"",function(e){fabric.loadSVGFromString(e,t)})},fabric.loadSVGFromString=function(e,t){var n=(new DOMParser).parseFromString(e);fabric.parseSVGDocument(n.documentElement,function(e,n){t(e,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),t(r)})},fabric.createCanvasForNode=function(e,t){var n=fabric.document.createElement("canvas"),r=new Canvas(e||600,t||600);n.style={},n.width=r.width,n.height=r.height;var i=fabric.Canvas||fabric.StaticCanvas,s=new i(n);return s.contextContainer=r.getContext("2d"),s.nodeCanvas=r,s},fabric.StaticCanvas.prototype.createPNGStream=function(){return this.nodeCanvas.createPNGStream()};var origSetWidth=fabric.StaticCanvas.prototype.setWidth;fabric.StaticCanvas.prototype.setWidth=function(e){return origSetWidth.call(this),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),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` *//*! Fabric.js Copyright 2008-2012, Printio (Juriy Zaytsev, Maxim Chernyak) */var fabric=fabric||{version:"0.9.27"};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";var Cufon=function(){function r(e){var t=this.face=e.face;this.glyphs=e.glyphs,this.w=e.w,this.baseSize=parseInt(t["units-per-em"],10),this.family=t["font-family"].toLowerCase(),this.weight=t["font-weight"],this.style=t["font-style"]||"normal",this.viewBox=function(){var e=t.bbox.split(/\s+/),n={minX:parseInt(e[0],10),minY:parseInt(e[1],10),maxX:parseInt(e[2],10),maxY:parseInt(e[3],10)};return n.width=n.maxX-n.minX,n.height=n.maxY-n.minY,n.toString=function(){return[this.minX,this.minY,this.width,this.height].join(" ")},n}(),this.ascent=-parseInt(t.ascent,10),this.descent=-parseInt(t.descent,10),this.height=-this.ascent+this.descent}function i(){var e={},t={oblique:"italic",italic:"oblique"};this.add=function(t){(e[t.style]||(e[t.style]={}))[t.weight]=t},this.get=function(n,r){var i=e[n]||e[t[n]]||e.normal||e.italic||e.oblique;if(!i)return null;r={normal:400,bold:700}[r]||parseInt(r,10);if(i[r])return i[r];var s={1:1,99:0}[r%100],o=[],u,a;s===undefined&&(s=r>400),r==500&&(r=400);for(var f in i){f=parseInt(f,10);if(!u||fa)a=f;o.push(f)}return ra&&(r=a),o.sort(function(e,t){return(s?e>r&&t>r?et:et:e=i.length+e?r():setTimeout(arguments.callee,10)}),function(t){e?t():n.push(t)}}(),supports:function(e,t){var n=fabric.document.createElement("span").style;return n[e]===undefined?!1:(n[e]=t,n[e]===t)},textAlign:function(e,t,n,r){return t.get("textAlign")=="right"?n>0&&(e=" "+e):nk&&(k=N),A.push(N),N=0;continue}var O=t.glyphs[T[b]]||t.missingGlyph;if(!O)continue;N+=C=Number(O.w||t.w)+h}A.push(N),N=Math.max(k,N);var M=[];for(var b=A.length;b--;)M[b]=N-A[b];if(C===null)return null;d+=l.width-C,m+=l.minX;var _,D;if(f)_=u,D=u.firstChild;else{_=fabric.document.createElement("span"),_.className="cufon cufon-canvas",_.alt=n,D=fabric.document.createElement("canvas"),_.appendChild(D);if(i.printable){var P=fabric.document.createElement("span");P.className="cufon-alt",P.appendChild(fabric.document.createTextNode(n)),_.appendChild(P)}}var H=_.style,B=D.style||{},j=c.convert(l.height-p+v),F=Math.ceil(j),I=F/j;D.width=Math.ceil(c.convert(N+d-m)*I),D.height=F,p+=l.minY,B.top=Math.round(c.convert(p-t.ascent))+"px",B.left=Math.round(c.convert(m))+"px";var q=Math.ceil(c.convert(N*I)),R=q+"px",U=c.convert(t.height),z=(i.lineHeight-1)*c.convert(-t.ascent/5)*(L-1);Cufon.textOptions.width=q,Cufon.textOptions.height=U*L+z,Cufon.textOptions.lines=L,Cufon.textOptions.totalLineHeight=z,e?(H.width=R,H.height=U+"px"):(H.paddingLeft=R,H.paddingBottom=U-1+"px");var W=Cufon.textOptions.context||D.getContext("2d"),X=F/l.height;Cufon.textOptions.fontAscent=t.ascent*X,Cufon.textOptions.boundaries=null;for(var V=Cufon.textOptions.shadowOffsets,b=y.length;b--;)V[b]=[y[b][0]*X,y[b][1]*X];W.save(),W.scale(X,X),W.translate(-m-1/X*D.width/2+(Cufon.fonts[t.family].offsetLeft||0),-p-Cufon.textOptions.height/X/2+(Cufon.fonts[t.family].offsetTop||0)),W.lineWidth=t.face["underline-thickness"],W.save();var J=Cufon.getTextDecoration(i),K=i.fontStyle==="italic";W.save(),Q();if(g)for(var b=0,w=g.length;b.cufon-vml-canvas{text-indent:0}@media screen{cvml\\:shape,cvml\\:shadow{behavior:url(#default#VML);display:block;antialias:true;position:absolute}.cufon-vml-canvas{position:absolute;text-align:left}.cufon-vml{display:inline-block;position:relative;vertical-align:middle}.cufon-vml .cufon-alt{position:absolute;left:-10000in;font-size:1px}a .cufon-vml{cursor:pointer}}@media print{.cufon-vml *{display:none}.cufon-vml .cufon-alt{display:inline}}'),function(e,t,i,s,o,u,a){var f=t===null;f&&(t=o.alt);var l=e.viewBox,c=i.computedFontSize||(i.computedFontSize=new Cufon.CSS.Size(n(u,i.get("fontSize"))+"px",e.baseSize)),h=i.computedLSpacing;h==undefined&&(h=i.get("letterSpacing"),i.computedLSpacing=h=h=="normal"?0:~~c.convertFrom(r(u,h)));var p,d;if(f)p=o,d=o.firstChild;else{p=fabric.document.createElement("span"),p.className="cufon cufon-vml",p.alt=t,d=fabric.document.createElement("span"),d.className="cufon-vml-canvas",p.appendChild(d);if(s.printable){var v=fabric.document.createElement("span");v.className="cufon-alt",v.appendChild(fabric.document.createTextNode(t)),p.appendChild(v)}a||p.appendChild(fabric.document.createElement("cvml:shape"))}var m=p.style,g=d.style,y=c.convert(l.height),b=Math.ceil(y),w=b/y,E=l.minX,S=l.minY;g.height=b,g.top=Math.round(c.convert(S-e.ascent)),g.left=Math.round(c.convert(E)),m.height=c.convert(e.height)+"px";var x=Cufon.getTextDecoration(s),T=i.get("color"),N=Cufon.CSS.textTransform(t,i).split(""),C=0,k=0,L=null,A,O,M=s.textShadow;for(var _=0,D=0,P=N.length;_r?n:i-t;s(u(f,a,c,n));if(i>r||o()){e.onComplete&&e.onComplete();return}l(h)}()}function c(e,t,n){if(e){var r=new Image;r.onload=function(){t&&t.call(n,r),r=r.onload=null},r.src=e}else t&&t.call(n,e)}function h(e,t){function n(e){return fabric[fabric.util.string.camelize(fabric.util.string.capitalize(e))]}function r(){++s===o&&t&&t(i)}var i=[],s=0,o=e.length;e.forEach(function(e,t){if(!e.type)return;var s=n(e.type);s.async?s.fromObject(e,function(e){i[t]=e,r()}):(i[t]=s.fromObject(e),r())})}function p(e,t,n){var r=e.length>1?new fabric.PathGroup(e,t):e[0];return typeof n!="undefined"&&r.setSourcePath(n),r}function d(e,t,n){if(n&&Object.prototype.toString.call(n)==="[object Array]")for(var r=0,i=n.length;r=r&&(r=e[n][t]);else while(n--)e[n]>=r&&(r=e[n]);return r}function r(e,t){if(!e||e.length===0)return undefined;var n=e.length-1,r=t?e[n][t]:e[n];if(t)while(n--)e[n][t]>>0;if(n===0)return-1;var r=0;arguments.length>0&&(r=Number(arguments[1]),r!==r?r=0:r!==0&&r!==1/0&&r!==-1/0&&(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?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.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){var t=0,n=0;do t+=e.offsetTop||0,n+=e.offsetLeft||0,e=e.offsetParent;while(e);return{left:n,top:t}}var e=Array.prototype.slice,n=function(t){return e.call(t,0)},r;try{r=n(fabric.document.childNodes)instanceof Array}catch(i){}r||(n=function(e){var t=new Array(e.length),n=e.length;while(n--)t[n]=e[n];return t});var f;fabric.document.defaultView&&fabric.document.defaultView.getComputedStyle?f=function(e){return fabric.document.defaultView.getComputedStyle(e,null).position}:f=function(e){var t=e.style.position;return!t&&e.currentStyle&&(t=e.currentStyle.position),t},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.type="text/javascript",r.setAttribute("runat","server"),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=n,fabric.util.makeElement=s,fabric.util.addClass=o,fabric.util.wrapElement=u,fabric.util.getElementOffset=a,fabric.util.getElementPosition=f}(),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}(),function(){function e(e,t,n,r){return n*(e/=r)*e+t}function t(e,t,n,r){return-n*(e/=r)*(e-2)+t}function n(e,t,n,r){return e/=r/2,e<1?n/2*e*e+t:-n/2*(--e*(e-2)-1)+t}function r(e,t,n,r){return n*(e/=r)*e*e+t}function i(e,t,n,r){return n*((e=e/r-1)*e*e+1)+t}function s(e,t,n,r){return e/=r/2,e<1?n/2*e*e*e+t:n/2*((e-=2)*e*e+2)+t}function o(e,t,n,r){return n*(e/=r)*e*e*e+t}function u(e,t,n,r){return-n*((e=e/r-1)*e*e*e-1)+t}function a(e,t,n,r){return e/=r/2,e<1?n/2*e*e*e*e+t:-n/2*((e-=2)*e*e*e-2)+t}function f(e,t,n,r){return n*(e/=r)*e*e*e*e+t}function l(e,t,n,r){return n*((e=e/r-1)*e*e*e*e+1)+t}function c(e,t,n,r){return e/=r/2,e<1?n/2*e*e*e*e*e+t:n/2*((e-=2)*e*e*e*e+2)+t}function h(e,t,n,r){return-n*Math.cos(e/r*(Math.PI/2))+n+t}function p(e,t,n,r){return n*Math.sin(e/r*(Math.PI/2))+t}function d(e,t,n,r){return-n/2*(Math.cos(Math.PI*e/r)-1)+t}function v(e,t,n,r){return e===0?t:n*Math.pow(2,10*(e/r-1))+t}function m(e,t,n,r){return e===r?t+n:n*(-Math.pow(2,-10*e/r)+1)+t}function g(e,t,n,r){return e===0?t:e===r?t+n:(e/=r/2,e<1?n/2*Math.pow(2,10*(e-1))+t:n/2*(-Math.pow(2,-10*--e)+2)+t)}function y(e,t,n,r){return-n*(Math.sqrt(1-(e/=r)*e)-1)+t}function b(e,t,n,r){return n*Math.sqrt(1-(e=e/r-1)*e)+t}function w(e,t,n,r){return e/=r/2,e<1?-n/2*(Math.sqrt(1-e*e)-1)+t:n/2*(Math.sqrt(1-(e-=2)*e)+1)+t}function E(e,t,n,r){var i=1.70158,s=0,o=n;return e===0?t:(e/=r,e===1?t+n:(s||(s=r*.3),o-1;e=e.split(/\s+/);var n=[],r,i;if(t){r=0,i=e.length;for(;r/i,"")));if(!s.documentElement)return;t.parseSVGDocument(s.documentElement,function(r,i){d.set(e,{objects:t.util.array.invoke(r,"toObject"),options:i}),n(r,i)},r)}e=e.replace(/^\n\s*/,"").trim(),d.has(e,function(r){r?d.get(e,function(e){var t=m(e);n(t.objects,t.options)}):new t.util.request(e,{method:"get",onComplete:i})})}function m(e){var n=e.objects,i=e.options;return n=n.map(function(e){return t[r(e.type)].fromObject(e)}),{objects:n,options:i}}function g(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)}function y(e){var t="";for(var n=0,r=e.length;n",'",""].join("")),t}var t=e.fabric||(e.fabric={}),n=t.util.object.extend,r=t.util.string.capitalize,i=t.util.object.clone,s={cx:"left",x:"left",cy:"top",y:"top",r:"radius","fill-opacity":"opacity","fill-rule":"fillRule","stroke-width":"strokeWidth",transform:"transformMatrix","text-decoration":"textDecoration","font-size":"fontSize","font-weight":"fontWeight","font-style":"fontStyle","font-family":"fontFamily"};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 t(e,t){var n=t[0],r=t.length===2?t[1]:t[0];e[0]=n,e[3]=r}function n(e,t){e[2]=t[0]}function r(e,t){e[1]=t[0]}function i(e,t){e[4]=t[0],t.length===2&&(e[5]=t[1])}var s=[1,0,0,1,0,0],o="(?:[-+]?\\d+(?:\\.\\d+)?(?:e[-+]?\\d+)?)",u="(?:\\s+,?\\s*|,\\s*)",a="(?:(skewX)\\s*\\(\\s*("+o+")\\s*\\))",f="(?:(skewY)\\s*\\(\\s*("+o+")\\s*\\))",l="(?:(rotate)\\s*\\(\\s*("+o+")(?:"+u+"("+o+")"+u+"("+o+"))?\\s*\\))",c="(?:(scale)\\s*\\(\\s*("+o+")(?:"+u+"("+o+"))?\\s*\\))",h="(?:(translate)\\s*\\(\\s*("+o+")(?:"+u+"("+o+"))?\\s*\\))",p="(?:(matrix)\\s*\\(\\s*("+o+")"+u+"("+o+")"+u+"("+o+")"+u+"("+o+")"+u+"("+o+")"+u+"("+o+")"+"\\s*\\))",d="(?:"+p+"|"+h+"|"+c+"|"+l+"|"+a+"|"+f+")",v="(?:"+d+"(?:"+u+d+")*"+")",m="^\\s*(?:"+v+"?)\\s*$",g=new RegExp(m),y=new RegExp(d);return function(o){var u=s.concat();return!o||o&&!g.test(o)?u:(o.replace(y,function(s){var o=(new RegExp(d)).exec(s).filter(function(e){return e!==""&&e!=null}),a=o[1],f=o.slice(2).map(parseFloat);switch(a){case"translate":i(u,f);break;case"rotate":e(u,f);break;case"scale":t(u,f);break;case"skewX":n(u,f);break;case"skewY":r(u,f);break;case"matrix":u=f}}),u)}}(),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+)?(?: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){f=n.selectNodes("//*[name(.)!='svg']");var l=[];for(var c=0,p=f.length;c0&&this.init(e,t)}var t=e.fabric||(e.fabric={});if(t.Point){t.warn("fabric.Point is already defined");return}t.Point=n,n.prototype={constructor:n,init:function(e,t){this.x=e,this.y=t},add:function(e){return new n(this.x+e.x,this.y+e.y)},addEquals:function(e){return this.x+=e.x,this.y+=e.y,this},scalarAdd:function(e){return new n(this.x+e,this.y+e)},scalarAddEquals:function(e){return this.x+=e,this.y+=e,this},subtract:function(e){return new n(this.x-e.x,this.y-e.y)},subtractEquals:function(e){return this.x-=e.x,this.y-=e.y,this},scalarSubtract:function(e){return new n(this.x-e,this.y-e)},scalarSubtractEquals:function(e){return this.x-=e,this.y-=e,this},multiply:function(e){return new n(this.x*e,this.y*e)},multiplyEquals:function(e){return this.x*=e,this.y*=e,this},divide:function(e){return new n(this.x/e,this.y/e)},divideEquals:function(e){return this.x/=e,this.y/=e,this},eq:function(e){return this.x===e.x&&this.y===e.y},lt:function(e){return this.xe.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)},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){arguments.length>0&&this.init(e)}var t=e.fabric||(e.fabric={});if(t.Intersection){t.warn("fabric.Intersection is already defined");return}t.Intersection=n,t.Intersection.prototype={init:function(e){this.status=e,this.points=[]},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("No Intersection")}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("No Intersection"),s=r.length;for(var o=0;o0&&(i.status="Intersection"),i},t.Intersection.intersectPolygonPolygon=function(e,t){var r=new n("No Intersection"),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("No Intersection");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])}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=n.sourceFromHex(e);t||(t=n.sourceFromRgb(e)),t&&this.setSource(t)},getSource:function(){return this._source},setSource:function(e){this._source=e},toRgb:function(){var e=this.getSource();return"rgb("+e[0]+","+e[1]+","+e[2]+")"},toRgba:function(){var e=this.getSource();return"rgba("+e[0]+","+e[1]+","+e[2]+","+e[3]+")"},toHex:function(){var e=this.getSource(),t=e[0].toString(16);t=t.length===1?"0"+t:t;var n=e[1].toString(16);n=n.length===1?"0"+n:n;var r=e[2].toString(16);return r=r.length===1?"0"+r:r,t.toUpperCase()+n.toUpperCase()+r.toUpperCase()},getAlpha:function(){return this.getSource()[3]},setAlpha:function(e){var t=this.getSource();return t[3]=e,this.setSource(t),this},toGrayscale:function(){var e=this.getSource(),t=parseInt((e[0]*.3+e[1]*.59+e[2]*.11).toFixed(0),10),n=e[3];return this.setSource([t,t,t,n]),this},toBlackWhite:function(e){var t=this.getSource(),n=(t[0]*.3+t[1]*.59+t[2]*.11).toFixed(0),r=t[3];return e=e||127,n=Number(n)','',"',"Created with Fabric.js ",fabric.version,"",fabric.createSVGFontFacesMarkup(this.getObjects())];this.backgroundImage&&e.push(''),this.overlayImage&&e.push('');for(var t=0,n=this.getObjects(),r=n.length;t"),e.join("")},isEmpty:function(){return this._objects.length===0},remove:function(e){return n(this._objects,e),this.getActiveObject()===e&&(this.fire("before:selection:cleared",{target:e}),this.discardActiveObject(),this.fire("selection:cleared")),this.renderAll(),e},sendToBack:function(e){return n(this._objects,e),this._objects.unshift(e),this.renderAll()},bringToFront:function(e){return n(this._objects,e),this._objects.push(e),this.renderAll()},sendBackwards:function(e){var t=this._objects.indexOf(e),r=t;if(t!==0){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}}n(this._objects,e),this._objects.splice(r,0,e)}return this.renderAll()},bringForward:function(e){var t=this.getObjects(),r=t.indexOf(e),i=r;if(r!==t.length-1){for(var s=r+1,o=this._objects.length;s"},e(fabric.StaticCanvas,{EMPTY_JSON:'{"objects": [], "background": "white"}',toGrayscale:function(e){var t=e.getContext("2d"),n=t.getImageData(0,0,e.width,e.height),r=n.data,i=n.width,s=n.height,o,u,a,f;for(a=0;a0&&(t>this.targetFindTolerance?t-=this.targetFindTolerance:t=0,n>this.targetFindTolerance?n-=this.targetFindTolerance:n=0);var o=!0,u=r.getImageData(t,n,this.targetFindTolerance*2||1,this.targetFindTolerance*2||1);for(var a=3;a0?0:-n),t.ey-(r>0?0:-r),i,s),e.lineWidth=this.selectionLineWidth,e.strokeStyle=this.selectionBorderColor;if(this.selectionDashArray.length>1){var o=t.ex+d-(n>0?0:i),u=t.ey+d-(r>0?0:s);e.beginPath(),this.drawDashedLine(e,o,u,o+i,u,this.selectionDashArray),this.drawDashedLine(e,o,u+s-1,o+i,u+s-1,this.selectionDashArray),this.drawDashedLine(e,o,u,o,u+s,this.selectionDashArray),this.drawDashedLine(e,o+i-1,u,o+i-1,u+s,this.selectionDashArray),e.closePath(),e.stroke()}else e.strokeRect(t.ex+d-(n>0?0:i),t.ey+d-(r>0?0:s),i,s)},drawDashedLine:function(e,t,n,r,i,s){var o=r-t,u=i-n,a=f(o*o+u*u),c=l(u,o),h=s.length,p=0,d=!0;e.save(),e.translate(t,n),e.moveTo(0,0),e.rotate(c),t=0;while(a>t)t+=s[p++%h],t>a&&(t=a),e[d?"lineTo":"moveTo"](t,0),d=!d;e.restore()},_findSelectedObjects:function(e){var t=[],n=this._groupSelector.ex,r=this._groupSelector.ey,i=n+this._groupSelector.left,s=r+this._groupSelector.top,o,u=new fabric.Point(h(n,i),h(r,s)),a=new fabric.Point(p(n,i),p(r,s));for(var f=0,l=this._objects.length;f1&&(t=new fabric.Group(t),this.setActiveGroup(t),t.saveCoords(),this.fire("selection:created",{target:t})),this.renderAll()},findTarget:function(e,t){var n,r=this.getPointer(e);if(this.controlsAboveOverlay&&this.lastRenderedObjectWithControlsAboveOverlay&&this.containsPoint(e,this.lastRenderedObjectWithControlsAboveOverlay))return n=this.lastRenderedObjectWithControlsAboveOverlay,n;var i=this.getActiveGroup();if(i&&!t&&this.containsPoint(e,i))return n=i,n;var s=[];for(var o=this._objects.length;o--;)if(this._objects[o]&&this.containsPoint(e,this._objects[o])){if(!this.perPixelTargetFind&&!this._objects[o].perPixelTargetFind){n=this._objects[o],this.relatedTarget=n;break}s[s.length]=this._objects[o]}for(var u=0,a=s.length;u"},_constrainScale:function(e){return Math.abs(e)1?this.strokeWidth:0,t=this.padding,n=o(this.angle);this.currentWidth=(this.width+e)*this.scaleX+t*2,this.currentHeight=(this.height+e)*this.scaleY+t*2,this.currentWidth<0&&(this.currentWidth=Math.abs(this.currentWidth));var r=Math.sqrt(Math.pow(this.currentWidth/2,2)+Math.pow(this.currentHeight/2,2)),i=Math.atan(this.currentHeight/this.currentWidth),s=Math.cos(i+n)*r,u=Math.sin(i+n)*r,a=Math.sin(n),f=Math.cos(n),l=this.getCenterPoint(),c={x:l.x-s,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:c.x+this.currentWidth/2*f,y:c.y+this.currentWidth/2*a};return this.oCoords={tl:c,tr:h,br:p,bl:d,ml:v,mt:m,mr:g,mb:y,mtr:b},this._setCornerCoords(),this},getBoundingRectWidth:function(){this.oCoords||this.setCoords();var e=[this.oCoords.tl.x,this.oCoords.tr.x,this.oCoords.br.x,this.oCoords.bl.x],n=t.util.array.min(e),r=t.util.array.max(e);return Math.abs(n-r)},getBoundingRectHeight:function(){this.oCoords||this.setCoords();var e=[this.oCoords.tl.y,this.oCoords.tr.y,this.oCoords.br.y,this.oCoords.bl.y],n=t.util.array.min(e),r=t.util.array.max(e);return Math.abs(n-r)},drawBorders:function(e){if(!this.hasBorders)return;var t=this.padding,n=t*2,r=this.strokeWidth>1?this.strokeWidth:0;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),~~(u+n+r*this.scaleY));if(this.hasRotatingPoint&&!this.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},_renderDashedStroke:function(e){function u(u,a){var f=0,l=0,c=(a?i.height:i.width)+s*2;while(fc&&(l=f-c),u?n+=h*u-(l*u||0):r+=h*a-(l*a||0),e[1&t?"moveTo":"lineTo"](n,r),t>=o&&(t=0)}}1&this.strokeDashArray.length&&this.strokeDashArray.push.apply(this.strokeDashArray,this.strokeDashArray);var t=0,n=-this.width/2,r=-this.height/2,i=this,s=this.padding,o=this.strokeDashArray.length;e.save(),e.beginPath(),u(1,0),u(0,1),u(-1,0),u(0,-1),e.stroke(),e.closePath(),e.restore()},drawCorners:function(e){if(!this.hasControls)return;var t=this.cornersize,n=t/2,r=this.strokeWidth/2,i=-(this.width/2),s=-(this.height/2),o,u,a=t/this.scaleX,f=t/this.scaleY,l=this.padding/this.scaleX,c=this.padding/this.scaleY,h=n/this.scaleY,p=n/this.scaleX,d=(n-t)/this.scaleX,v=(n-t)/this.scaleY,m=this.height,g=this.width,y=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,o=i-p-r-l,u=s-h-r-c,e.clearRect(o,u,a,f),e[y](o,u,a,f),o=i+g-p+r+l,u=s-h-r-c,e.clearRect(o,u,a,f),e[y](o,u,a,f),o=i-p-r-l,u=s+m+v+r+c,e.clearRect(o,u,a,f),e[y](o,u,a,f),o=i+g+d+r+l,u=s+m+v+r+c,e.clearRect(o,u,a,f),e[y](o,u,a,f),this.lockUniScaling||(o=i+g/2-p,u=s-h-r-c,e.clearRect(o,u,a,f),e[y](o,u,a,f),o=i+g/2-p,u=s+m+v+r+c,e.clearRect(o,u,a,f),e[y](o,u,a,f),o=i+g+d+r+l,u=s+m/2-h,e.clearRect(o,u,a,f),e[y](o,u,a,f),o=i-p-r-l,u=s+m/2-h,e.clearRect(o,u,a,f),e[y](o,u,a,f)),this.hasRotatingPoint&&(o=i+g/2-p,u=this.flipY?s+m+this.rotatingPointOffset/this.scaleY-f/2+r+c:s-this.rotatingPointOffset/this.scaleY-f/2-r-c,e.clearRect(o,u,a,f),e[y](o,u,a,f)),e.restore(),this},clone:function(e,n){return this.constructor.fromObject?this.constructor.fromObject(this.toObject(n),e):new t.Object(this.toObject(n))},cloneAsImage:function(e){if(t.Image){var n=new Image;n.onload=function(){e&&e(new t.Image(n),r),n=n.onload=null};var r={angle:this.get("angle"),flipX:this.get("flipX"),flipY:this.get("flipY")};this.set("angle",0).set("flipX",!1).set("flipY",!1),this.toDataURL(function(e){n.src=e})}return this},toDataURL:function(e){function i(t){t.left=n.width/2,t.top=n.height/2,t.setActive(!1),r.add(t);var i=r.toDataURL("png");r.dispose(),r=t=null,e&&e(i)}var n=t.document.createElement("canvas");!n.getContext&&typeof G_vmlCanvasManager!="undefined"&&G_vmlCanvasManager.initElement(n),n.width=this.getBoundingRectWidth(),n.height=this.getBoundingRectHeight(),t.util.wrapElement(n,"div");var r=new t.Canvas(n);r.backgroundColor="transparent",r.renderAll(),this.constructor.async?this.clone(i):i(this.clone())},hasStateChanged:function(){return this.stateProperties.some(function(e){return this[e]!==this.originalState[e]},this)},saveState:function(){return this.stateProperties.forEach(function(e){this.originalState[e]=this.get(e)},this),this},setupState:function(){this.originalState={},this.saveState()},intersectsWithRect:function(e,n){var r=this.oCoords,i=new t.Point(r.tl.x,r.tl.y),s=new t.Point(r +.tr.x,r.tr.y),o=new t.Point(r.bl.x,r.bl.y),u=new t.Point(r.br.x,r.br.y),a=t.Intersection.intersectPolygonRectangle([i,s,u,o],e,n);return a.status==="Intersection"},intersectsWithObject:function(e){function n(e){return{tl:new t.Point(e.tl.x,e.tl.y),tr:new t.Point(e.tr.x,e.tr.y),bl:new t.Point(e.bl.x,e.bl.y),br:new t.Point(e.br.x,e.br.y)}}var r=n(this.oCoords),i=n(e.oCoords),s=t.Intersection.intersectPolygonPolygon([r.tl,r.tr,r.br,r.bl],[i.tl,i.tr,i.br,i.bl]);return s.status==="Intersection"},isContainedWithinObject:function(e){return this.isContainedWithinRect(e.oCoords.tl,e.oCoords.br)},isContainedWithinRect:function(e,n){var r=this.oCoords,i=new t.Point(r.tl.x,r.tl.y),s=new t.Point(r.tr.x,r.tr.y),o=new t.Point(r.bl.x,r.bl.y);return i.x>e.x&&s.xe.y&&o.y=t&&l.d.y>=t)continue;l.o.x===l.d.x&&l.o.x>=e?(u=l.o.x,a=t):(r=0,i=(l.d.y-l.o.y)/(l.d.x-l.o.x),s=t-r*e,o=l.o.y-i*l.o.x,u=-(s-o)/(r-i),a=s+r*u),u>=e&&(f+=1);if(f===2)break}return f},_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}}},_setCornerCoords:function(){var e=this.oCoords,t=o(this.angle),n=o(45-this.angle),r=Math.sqrt(2*Math.pow(this.cornersize,2))/2,i=r*Math.cos(n),s=r*Math.sin(n),u=Math.sin(t),a=Math.cos(t);e.tl.corner={tl:{x:e.tl.x-s,y:e.tl.y-i},tr:{x:e.tl.x+i,y:e.tl.y-s},bl:{x:e.tl.x-i,y:e.tl.y+s},br:{x:e.tl.x+s,y:e.tl.y+i}},e.tr.corner={tl:{x:e.tr.x-s,y:e.tr.y-i},tr:{x:e.tr.x+i,y:e.tr.y-s},br:{x:e.tr.x+s,y:e.tr.y+i},bl:{x:e.tr.x-i,y:e.tr.y+s}},e.bl.corner={tl:{x:e.bl.x-s,y:e.bl.y-i},bl:{x:e.bl.x-i,y:e.bl.y+s},br:{x:e.bl.x+s,y:e.bl.y+i},tr:{x:e.bl.x+i,y:e.bl.y-s}},e.br.corner={tr:{x:e.br.x+i,y:e.br.y-s},bl:{x:e.br.x-i,y:e.br.y+s},br:{x:e.br.x+s,y:e.br.y+i},tl:{x:e.br.x-s,y:e.br.y-i}},e.ml.corner={tl:{x:e.ml.x-s,y:e.ml.y-i},tr:{x:e.ml.x+i,y:e.ml.y-s},bl:{x:e.ml.x-i,y:e.ml.y+s},br:{x:e.ml.x+s,y:e.ml.y+i}},e.mt.corner={tl:{x:e.mt.x-s,y:e.mt.y-i},tr:{x:e.mt.x+i,y:e.mt.y-s},bl:{x:e.mt.x-i,y:e.mt.y+s},br:{x:e.mt.x+s,y:e.mt.y+i}},e.mr.corner={tl:{x:e.mr.x-s,y:e.mr.y-i},tr:{x:e.mr.x+i,y:e.mr.y-s},bl:{x:e.mr.x-i,y:e.mr.y+s},br:{x:e.mr.x+s,y:e.mr.y+i}},e.mb.corner={tl:{x:e.mb.x-s,y:e.mb.y-i},tr:{x:e.mb.x+i,y:e.mb.y-s},bl:{x:e.mb.x-i,y:e.mb.y+s},br:{x:e.mb.x+s,y:e.mb.y+i}},e.mtr.corner={tl:{x:e.mtr.x-s+u*this.rotatingPointOffset,y:e.mtr.y-i-a*this.rotatingPointOffset},tr:{x:e.mtr.x+i+u*this.rotatingPointOffset,y:e.mtr.y-s-a*this.rotatingPointOffset},bl:{x:e.mtr.x-i+u*this.rotatingPointOffset,y:e.mtr.y+s-a*this.rotatingPointOffset},br:{x:e.mtr.x+s+u*this.rotatingPointOffset,y:e.mtr.y+i-a*this.rotatingPointOffset}}},toGrayscale:function(){var e=this.get("fill");return e&&this.set("overlayFill",(new t.Color(e)).toGrayscale().toRgb()),this},complexity:function(){return 0},toJSON:function(e){return this.toObject(e)},setGradientFill:function(e){this.set("fill",t.Gradient.forObject(this,e))},animate:function(){if(arguments[0]&&typeof arguments[0]=="object")for(var e in arguments[0])this._animate(e,arguments[0][e],arguments[1]);else this._animate.apply(this,arguments);return this},_animate:function(e,n,r){var i=this;r||(r={}),"from"in r||(r.from=this.get(e)),/[+\-]/.test((n+"").charAt(0))&&(n=this.get(e)+parseFloat(n)),t.util.animate({startValue:r.from,endValue:n,byValue:r.by,easing:r.easing,duration:r.duration,onChange:function(t){i.set(e,t),r.onChange&&r.onChange()},onComplete:function(){i.setCoords(),r.onComplete&&r.onComplete()}})},centerH:function(){return this.canvas.centerObjectH(this),this},centerV:function(){return this.canvas.centerObjectV(this),this},center:function(){return this.centerH().centerV()},remove:function(){return this.canvas.remove(this)},sendToBack:function(){return this.canvas.sendToBack(this),this},bringToFront:function(){return this.canvas.bringToFront(this),this},sendBackwards:function(){return this.canvas.sendBackwards(this),this},bringForward:function(){return this.canvas.bringForward(this),this}});var u=t.Object.prototype;for(var a=u.stateProperties.length;a--;){var f=u.stateProperties[a],l=f.charAt(0).toUpperCase()+f.slice(1),c="set"+l,h="get"+l;u[h]||(u[h]=function(e){return new Function('return this.get("'+e+'")')}(f)),u[c]||(u[c]=function(e){return new Function("value",'return this.set("'+e+'", value)')}(f))}t.Object.prototype.rotate=t.Object.prototype.setAngle,n(t.Object.prototype,t.Observable),n(t.Object,{NUM_FRACTION_DIGITS:2})}(typeof exports!="undefined"?exports:this),function(e){"use strict";var t=e.fabric||(e.fabric={}),n=t.util.object.extend,r={x1:1,x2:1,y1:1,y2:1};if(t.Line){t.warn("fabric.Line is already defined");return}t.Line=t.util.createClass(t.Object,{type:"line",initialize:function(e,t){t=t||{},e||(e=[0,0,0,0]),this.callSuper("initialize",t),this.set("x1",e[0]),this.set("y1",e[1]),this.set("x2",e[2]),this.set("y2",e[3]),this._setWidthHeight(t)},_setWidthHeight:function(e){e||(e={}),this.set("width",this.x2-this.x1||1),this.set("height",this.y2-this.y1||1),this.set("left","left"in e?e.left:this.x1+this.width/2),this.set("top","top"in e?e.top:this.y1+this.height/2)},_set:function(e,t){return this[e]=t,e in r&&this._setWidthHeight(),this},_render:function(e){e.beginPath(),this.group&&e.translate(-this.group.width/2+this.left,-this.group.height/2+this.top),e.moveTo(this.width===1?0:-this.width/2,this.height===1?0:-this.height/2),e.lineTo(this.width===1?0:this.width/2,this.height===1?0:this.height/2),e.lineWidth=this.strokeWidth;var t=e.strokeStyle;e.strokeStyle=e.fillStyle,e.stroke(),e.strokeStyle=t},complexity:function(){return 1},toObject:function(e){return n(this.callSuper("toObject",e),{x1:this.get("x1"),y1:this.get("y1"),x2:this.get("x2"),y2:this.get("y2")})},toSVG:function(){return[""].join("")}}),t.Line.ATTRIBUTE_NAMES="x1 y1 x2 y2 stroke stroke-width transform".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",initialize:function(e){e=e||{},this.set("radius",e.radius||0),this.callSuper("initialize",e);var t=this.get("radius")*2;this.set("width",t).set("height",t)},toObject:function(e){return r(this.callSuper("toObject",e),{radius:this.get("radius")})},toSVG:function(){return'"},_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),e.closePath(),this.fill&&e.fill(),this.stroke&&e.stroke()},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="cx cy r fill fill-opacity opacity stroke stroke-width transform".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");return"left"in s&&(s.left-=n.width/2||0),"top"in s&&(s.top-=n.height/2||0),new t.Circle(r(s,n))},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.fill&&e.fill(),this.stroke&&e.stroke()},complexity:function(){return 1},toSVG:function(){var e=this.width/2,t=this.height/2,n=[-e+" "+t,"0 "+ -t,e+" "+t].join(",");return'"}}),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",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(){return[""].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,this.transformMatrix&&this.group&&e.translate(this.cx,this.cy),e.transform(1,0,0,this.ry/this.rx,0,0),e.arc(t?this.left:0,t?this.top:0,this.rx,0,n,!1),this.stroke&&e.stroke(),this.fill&&e.fill(),e.restore()},complexity:function(){return 1}}),t.Ellipse.ATTRIBUTE_NAMES="cx cy rx ry fill fill-opacity opacity stroke stroke-width transform".split(" "),t.Ellipse.fromElement=function(e,n){n||(n={});var i=t.parseAttributes(e,t.Ellipse.ATTRIBUTE_NAMES),s=i.left,o=i.top;"left"in i&&(i.left-=n.width/2||0),"top"in i&&(i.top-=n.height/2||0);var u=new t.Ellipse(r(i,n));return u.cx=s||0,u.cy=o||0,u},t.Ellipse.fromObject=function(e){return new t.Ellipse(e)}}(typeof exports!="undefined"?exports:this),function(e){"use strict";function r(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}t.Rect=t.util.createClass(t.Object,{type:"rect",rx:0,ry:0,initialize:function(e){e=e||{},this._initStateProperties(),this.callSuper("initialize",e),this._initRxRy()},_initStateProperties:function(){this.stateProperties=this.stateProperties.concat(["rx","ry"])},_initRxRy:function(){this.rx&&!this.ry?this.ry=this.rx:this.ry&&!this.rx&&(this.rx=this.ry)},_render:function(e){var t=this.rx||0,n=this.ry||0,r=-this.width/2,i=-this.height/2,s=this.width,o=this.height;e.beginPath(),e.globalAlpha=this.group?e.globalAlpha*this.opacity:this.opacity,this.transformMatrix&&this.group&&e.translate(this.width/2+this.x,this.height/2+this.y),!this.transformMatrix&&this.group&&e.translate(-this.group.width/2+this.width/2+this.x,-this.group.height/2+this.height/2+this.y),e.moveTo(r+t,i),e.lineTo(r+s-t,i),e.quadraticCurveTo(r+s,i,r+s,i+n,r+s,i+n),e.lineTo(r+s,i+o-n),e.quadraticCurveTo(r+s,i+o,r+s-t,i+o,r+s-t,i+o),e.lineTo(r+t,i+o),e.quadraticCurveTo(r,i+o,r,i+o-n,r,i+o-n),e.lineTo(r,i+n),e.quadraticCurveTo(r,i,r+t,i,r+t,i),e.closePath(),this.fill&&e.fill(),this.strokeDashArray?this._renderDashedStroke(e):this.stroke&&e.stroke()},_normalizeLeftTopProperties:function(e){return e.left&&this.set("left",e.left+this.getWidth()/2),this.set("x",e.left||0),e.top&&this.set("top",e.top+this.getHeight()/2),this.set("y",e.top||0),this},complexity:function(){return 1},toObject:function(e){return n(this.callSuper("toObject",e),{rx:this.get("rx")||0,ry:this.get("ry")||0})},toSVG:function(){return'"}}),t.Rect.ATTRIBUTE_NAMES="x y width height rx ry fill fill-opacity opacity stroke stroke-width transform".split(" "),t.Rect.fromElement=function(e,i){if(!e)return null;var s=t.parseAttributes(e,t.Rect.ATTRIBUTE_NAMES);s=r(s);var o=new t.Rect(n(i?t.util.object.clone(i):{},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",initialize:function(e,t){t=t||{},this.set("points",e),this.callSuper("initialize",t),this._calcDimensions()},_calcDimensions:function(){return t.Polygon.prototype._calcDimensions.call(this)},toObject:function(e){return t.Polygon.prototype.toObject.call(this,e)},toSVG:function(){var e=[];for(var t=0,r=this.points.length;t"].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"].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;n1&&(g=Math.sqrt(g),n*=g,i*=g);var y=d/n,b=p/n,w=-p/i,E=d/i,S=y*l+b*c,x=w*l+E*c,T=y*e+b*t,N=w*e+E*t,C=(T-S)*(T-S)+(N-x)*(N-x),k=1/C-.25;k<0&&(k=0);var L=Math.sqrt(k);a===u&&(L=-L);var A=.5*(S+T)-L*(N-x),O=.5*(x+N)+L*(T-S),M=Math.atan2(x-O,S-A),_=Math.atan2(N-O,T-A),D=_-M;D<0&&a===1?D+=2*Math.PI:D>0&&a===0&&(D-=2*Math.PI);var P=Math.ceil(Math.abs(D/(Math.PI*.5+.001))),H=[];for(var B=0;B"},toObject:function(e){var t=h(this.callSuper("toObject",e),{path:this.path});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(){var e=[];for(var t=0,n=this.path.length;t',"',""].join("")},complexity:function(){return this.path.length},_parsePath:function(){var e=[],n,r,i;for(var s=0,o,u=this.path.length;sc)for(var h=1,p=o.length;h"];for(var n=0,r=e.length;n"),t.join("")},toString:function(){return"#"},isSameColor:function(){var e=this.getObjects()[0].get("fill");return this.getObjects().every(function(t){return t.get("fill")===e})},complexity:function(){return this.paths.reduce(function(e,t){return e+(t&&t.complexity?t.complexity():0)},0)},toGrayscale:function(){var e=this.paths.length;while(e--)this.paths[e].toGrayscale();return this},getObjects:function(){return this.paths}}),t.PathGroup.fromObject=function(e){var n=u(e.paths);return new t.PathGroup(n,e)}}(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,o=t.util.removeFromArray;if(t.Group)return;t.Group=t.util.createClass(t.Object,{type:"group",initialize:function(e,t){t=t||{},this.objects=e||[],this.originalState={},this.callSuper("initialize"),this._calcBounds(),this._updateObjectsCoords(),t&&n(this,t),this._setOpacityIfSame(),this.setCoords(!0),this.saveCoords()},_updateObjectsCoords:function(){var e=this.left,t=this.top;this.forEachObject(function(n){var r=n.get("left"),i=n.get("top");n.set("originalLeft",r),n.set("originalTop",i),n.set("left",r-e),n.set("top",i-t),n.setCoords(),n.hideCorners=!0},this)},toString:function(){return"#"},getObjects:function(){return this.objects},addWithUpdate:function(e){return this._restoreObjectsState(),this.objects.push(e),this._calcBounds(),this._updateObjectsCoords(),this},removeWithUpdate:function(e){return this._restoreObjectsState(),o(this.objects,e),e.setActive(!1),this._calcBounds(),this._updateObjectsCoords(),this},add:function(e){return this.objects.push(e),this},remove:function(e){return o(this.objects,e),this},size:function(){return this.getObjects().length},_set:function(e,t){if(e==="fill"||e==="opacity"){var n=this.objects.length;this[e]=t;while(n--)this.objects[n].set(e,t)}else this[e]=t},contains:function(e){return this.objects.indexOf(e)>-1},toObject:function(e){return n(this.callSuper("toObject",e),{objects:s(this.objects,"toObject",e)})},render:function(e,t){e.save(),this.transform(e);var n=Math.max(this.scaleX,this.scaleY);for(var r=this.objects.length;r>0;r--){var i=this.objects[r-1],s=i.borderScaleFactor,o=i.hasRotatingPoint;i.borderScaleFactor=n,i.hasRotatingPoint=!1,i.render(e),i.borderScaleFactor=s,i.hasRotatingPoint=o}!t&&this.active&&(this.drawBorders(e),this.hideCorners||this.drawCorners(e)),e.restore(),this.setCoords()},item:function(e){return this.getObjects()[e]},complexity:function(){return this.getObjects().reduce(function(e,t){return e+=typeof t.complexity=="function"?t.complexity():0,e},0)},_restoreObjectsState:function(){return this.objects.forEach(this._restoreObjectState,this),this},_restoreObjectState:function(e){var t=this.get("left"),n=this.get("top"),r=this.getAngle()*(Math.PI/180),i=Math.cos(r)*e.get("top")+Math.sin(r)*e.get("left"),s=-Math.sin(r)*e.get("top")+Math.cos(r)*e.get("left");return e.setAngle(e.getAngle()+this.getAngle()),e.set("left",t+s*this.get("scaleX")),e.set("top",n+i*this.get("scaleY")),e.set("scaleX",e.get("scaleX")*this.get("scaleX")),e.set("scaleY",e.get("scaleY")*this.get("scaleY")),e.setCoords(),e.hideCorners=!1,e.setActive(!1),e.setCoords(),this},destroy:function(){return this._restoreObjectsState()},saveCoords:function(){return this._originalLeft=this.get("left"),this._originalTop=this.get("top"),this},hasMoved:function(){return this._originalLeft!==this.get("left")||this._originalTop!==this.get("top")},setObjectsCoords:function(){return this.forEachObject(function(e){e.setCoords()}),this},activateAllObjects:function(){return this.forEachObject(function(e){e.setActive()}),this},forEachObject:t.StaticCanvas.prototype.forEachObject,_setOpacityIfSame:function(){var e=this.getObjects(),t=e[0]?e[0].get("opacity"):1,n=e.every(function(e){return e.get("opacity")===t});n&&(this.opacity=t)},_calcBounds:function(){var e=[],t=[],n,s,o,u,a,f,l,c=0,h=this.objects.length;for(;ce.x&&i-ne.y},toGrayscale:function(){var e=this.objects.length;while(e--)this.objects[e].toGrayscale()},toSVG:function(){var e=[];for(var t=0,n=this.objects.length;t'+e.join("")+""}}),t.Group.fromObject=function(e,n){t.util.enlivenObjects(e.objects,function(r){delete e.objects,n&&n(new t.Group(r,e))})},t.Group.async=!0}(typeof exports!="undefined"?exports:this),function(e){"use strict";var t=fabric.util.object.extend;e.fabric||(e.fabric={});if(e.fabric.Image){fabric.warn("fabric.Image is already defined.");return}fabric.Image=fabric.util.createClass(fabric.Object,{active:!1,type:"image",initialize:function(e,t){t||(t={}),this.callSuper("initialize",t),this._initElement(e),this._originalImage=this.getElement(),this._initConfig(t),this.filters=[],t.filters&&(this.filters=t.filters,this.applyFilters())},getElement:function(){return this._element},setElement:function(e){return this._element=e,this._initConfig(),this},getOriginalSize:function(){var e=this.getElement();return{width:e.width,height:e.height}},render:function(e,t){e.save();var n=this.transformMatrix;this._resetWidthHeight(),this.group&&e.translate(-this.group.width/2+this.width/2,-this.group.height/2+this.height/2),n&&e.transform(n[0],n[1],n[2],n[3],n[4],n[5]),t||this.transform(e),this._render(e),this.active&&!t&&(this.drawBorders(e),this.hideCorners||this.drawCorners(e)),e.restore()},toObject:function(e){return t(this.callSuper("toObject",e),{src:this._originalImage.src||this._originalImage._src,filters:this.filters.concat()})},toSVG:function(){return''+'"+""},getSrc:function(){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.filters.length===0){this.setElement(this._originalImage),e&&e();return}var t=typeof Buffer!="undefined"&&typeof window=="undefined",n=this._originalImage,r=fabric.document.createElement("canvas"),i=t?new(require("canvas").Image):fabric.document.createElement("img"),s=this;!r.getContext&&typeof G_vmlCanvasManager!="undefined"&&G_vmlCanvasManager.initElement(r),r.width=n.width,r.height=n.height,r.getContext("2d").drawImage(n,0,0,n.width,n.height),this.filters.forEach(function(e){e&&e.applyTo(r)}),i.onload=function(){s._element=i,e&&e(),i.onload=r=n=null},i.width=n.width,i.height=n.height;if(t){var o=r.toDataURL("image/png").replace(/data:image\/png;base64,/,"");i.src=new Buffer(o,"base64"),s._element=i,e&&e()}else i.src=r.toDataURL("image/png");return this},_render:function(e){e.drawImage(this.getElement(),-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)},_initFilters:function(e){e.filters&&e.filters.length&&(this.filters=e.filters.map(function(e){return e&&fabric.Image.filters[e.type].fromObject(e)}))},_setWidthHeight:function(e){this.width="width"in e?e.width:this.getElement().width||0,this.height="height"in e?e.height:this.getElement().height||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){var n=fabric.document.createElement("img"),r=e.src;e.width&&(n.width=e.width),e +.height&&(n.height=e.height),n.onload=function(){fabric.Image.prototype._initFilters.call(e,e);var r=new fabric.Image(n,e);t&&t(r),n=n.onload=null},n.src=r},fabric.Image.fromURL=function(e,t,n){var r=fabric.document.createElement("img");r.onload=function(){t&&t(new fabric.Image(r,n)),r=r.onload=null},r.src=e},fabric.Image.ATTRIBUTE_NAMES="x y width height fill fill-opacity opacity stroke stroke-width transform xlink:href".split(" "),fabric.Image.fromElement=function(e,n,r){r||(r={});var i=fabric.parseAttributes(e,fabric.Image.ATTRIBUTE_NAMES);fabric.Image.fromURL(i["xlink:href"],n,t(i,r))},fabric.Image.async=!0}(typeof exports!="undefined"?exports:this),fabric.util.object.extend(fabric.Object.prototype,{_getAngleValueForStraighten:function(){var e=this.get("angle");return e>-225&&e<=-135?-180:e>-135&&e<=-45?-90:e>-45&&e<=45?0:e>45&&e<=135?90:e>135&&e<=225?180:e>225&&e<=315?270:e>315?360:0},straighten:function(){var e=this._getAngleValueForStraighten();return this.setAngle(e),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.setActive(!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.Grayscale=fabric.util.createClass({type:"Grayscale",applyTo:function(e){var t=e.getContext("2d"),n=t.getImageData(0,0,e.width,e.height),r=n.data,i=n.width,s=n.height,o,u,a,f;for(a=0;ao&&f>o&&l>o&&u(a-f)0&&(r[s]=a,r[s+1]=f,r[s+2]=l);t.putImageData(n,0,0)},toJSON:function(){return{type:this.type,color:this.color}}}),fabric.Image.filters.Tint.fromObject=function(e){return new fabric.Image.filters.Tint(e)},fabric.Image.filters.Convolute=fabric.util.createClass({type:"Convolute",initialize:function(e){e||(e={}),this.opaque=e.opaque,this.matrix=e.matrix||[0,0,0,0,1,0,0,0,0],this.tmpCtx=fabric.document.createElement("canvas").getContext("2d")},_createImageData:function(e,t){return this.tmpCtx.createImageData(e,t)},applyTo:function(e){var t=this.matrix,n=e.getContext("2d"),r=n.getImageData(0,0,e.width,e.height),i=Math.round(Math.sqrt(t.length)),s=Math.floor(i/2),o=r.data,u=r.width,a=r.height,f=u,l=a,c=this._createImageData(f,l),h=c.data,p=this.opaque?1:0;for(var d=0;d=0&&N=0&&C'},_render:function(e){typeof Cufon=="undefined"||this.useNative===!0?this._renderViaNative(e):this._renderViaCufon(e)},_renderViaCufon:function(e){var t=Cufon.textOptions||(Cufon.textOptions={});t.left=this.left,t.top=this.top,t.context=e,t.color=this.fill;var n=this._initDummyElementForCufon();this.transform(e),Cufon.replaceElement(n,{engine:"canvas",separate:"none",fontFamily:this.fontFamily,fontWeight:this.fontWeight,textDecoration:this.textDecoration,textShadow:this.textShadow,textAlign:this.textAlign,fontStyle:this.fontStyle,lineHeight:this.lineHeight,strokeStyle:this.strokeStyle,strokeWidth:this.strokeWidth,backgroundColor:this.backgroundColor,textBackgroundColor:this.textBackgroundColor}),this.width=t.width,this.height=t.height,this._totalLineHeight=t.totalLineHeight,this._fontAscent=t.fontAscent,this._boundaries=t.boundaries,this._shadowOffsets=t.shadowOffsets,this._shadows=t.shadows||[],n=null,this.setCoords()},_renderViaNative:function(e){this.transform(e),this._setTextStyles(e);var t=this.text.split(/\r?\n/);this.width=this._getTextWidth(e,t),this.height=this._getTextHeight(e,t),this._renderTextBackground(e,t),this.textAlign!=="left"&&(e.save(),e.translate(this.textAlign==="center"?this.width/2:this.width,0)),this._setTextShadow(e),this._renderTextFill(e,t),this.textShadow&&e.restore(),this._renderTextStroke(e,t),this.textAlign!=="left"&&e.restore(),this._renderTextDecoration(e,t),this._setBoundaries(e,t),this._totalLineHeight=0,this.setCoords()},_setBoundaries:function(e,t){this._boundaries=[];for(var n=0,r=t.length;nn&&(n=s)}return n},_setTextShadow:function(e){if(this.textShadow){var t=/\s+(-?\d+)(?:px)?\s+(-?\d+)(?:px)?\s+(\d+)(?:px)?\s*/,n=this.textShadow,r=t.exec(this.textShadow),i=n.replace(t,"");e.save(),e.shadowColor=i,e.shadowOffsetX=parseInt(r[1],10),e.shadowOffsetY=parseInt(r[2],10),e.shadowBlur=parseInt(r[3],10),this._shadows=[{blur:e.shadowBlur,color:e.shadowColor,offX:e.shadowOffsetX,offY:e.shadowOffsetY}],this._shadowOffsets=[[parseInt(e.shadowOffsetX,10),parseInt(e.shadowOffsetY,10)]]}},_renderTextFill:function(e,t){this._boundaries=[];for(var n=0,r=t.length;n-1&&i(this.fontSize),this.textDecoration.indexOf("line-through")>-1&&i(this.fontSize/2),this.textDecoration.indexOf("overline")>-1&&i(0)},_getFontDeclaration:function(){return[this.fontStyle,this.fontWeight,this.fontSize+"px",t.isLikelyNode?'"'+this.fontFamily+'"':this.fontFamily].join(" ")},_initDummyElementForCufon:function(){var e=t.document.createElement("pre"),n=t.document.createElement("div");return n.appendChild(e),typeof G_vmlCanvasManager=="undefined"?e.innerHTML=this.text:e.innerText=this.text.replace(/\r?\n/gi,"\r"),e.style.fontSize=this.fontSize+"px",e.style.letterSpacing="normal",e},render:function(e,t){e.save(),this._render(e),!t&&this.active&&(this.drawBorders(e),this.hideCorners||this.drawCorners(e)),e.restore()},toObject:function(e){return 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,textShadow:this.textShadow,textAlign:this.textAlign,path:this.path,strokeStyle:this.strokeStyle,strokeWidth:this.strokeWidth,backgroundColor:this.backgroundColor,textBackgroundColor:this.textBackgroundColor,useNative:this.useNative})},toSVG:function(){var e=this.text.split(/\r?\n/),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,s=this._getSVGTextAndBg(t,n,e),o=this._getSVGShadows(t,e);return r+=this._fontAscent?this._fontAscent/5*this.lineHeight:0,['',s.textBgRects.join(""),"',o.join(""),s.textSpans.join(""),"",""].join("")},_getSVGShadows:function(e,n){var r=[],s,o,u,a,f=1;if(!this._shadows||!this._boundaries)return r;for(s=0,u=this._shadows.length;s",t.util.string.escapeXml(n[o]),""),f=1}else f++;return r},_getSVGTextAndBg:function(e,n,r){var s=[],o=[],u,a,f,l=1;this.backgroundColor&&this._boundaries&&o.push("');for(u=0,f=r.length;u",t.util.string.escapeXml(r[u]),""),l=1):l++;if(!this.textBackgroundColor||!this._boundaries)continue;o.push("')}return{textSpans:s,textBgRects:o}},_getFillAttributes:function(e){var n=e?new t.Color(e):"";return!n||!n.getSource()||n.getAlpha()===1?'fill="'+e+'"':'opacity="'+n.getAlpha()+'" fill="'+n.setAlpha(1).toRgb()+'"'},setColor:function(e){return this.set("fill",e),this},setFontsize:function(e){return this.set("fontSize",e),this._initDimensions(),this.setCoords(),this},getText:function(){return this.text},setText:function(e){return this.set("text",e),this._initDimensions(),this.setCoords(),this},_set:function(e,t){e==="fontFamily"&&this.path&&(this.path=this.path.replace(/(.*?)([^\/]*)(\.font\.js)/,"$1"+t+"$3")),this.callSuper("_set",e,t)}}),t.Text.ATTRIBUTE_NAMES="x y fill fill-opacity opacity stroke stroke-width transform font-family font-style font-weight font-size text-decoration".split(" "),t.Text.fromObject=function(e){return new t.Text(e.text,r(e))},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);var i=new t.Text(e.textContent,n);return i.set({left:i.getLeft()+i.getWidth()/2,top:i.getTop()-i.getHeight()/2}),i}}(typeof exports!="undefined"?exports:this),function(){function request(e,t,n){var r=URL.parse(e),i=HTTP.createClient(r.port,r.hostname),s=i.request("GET",r.pathname,{host:r.hostname});i.addListener("error",function(e){e.errno===process.ECONNREFUSED?fabric.log("ECONNREFUSED: connection refused to "+i.host+":"+i.port):fabric.log(e.message)}),s.end(),s.on("response",function(e){var r="";t&&e.setEncoding(t),e.on("end",function(){n(r)}),e.on("data",function(t){e.statusCode===200&&(r+=t)})})}if(typeof document!="undefined"&&typeof window!="undefined")return;var DOMParser=(new require("xmldom")).DOMParser,URL=require("url"),HTTP=require("http"),Canvas=require("canvas"),Image=require("canvas").Image;fabric.util.loadImage=function(e,t){request(e,"binary",function(n){var r=new Image;r.src=new Buffer(n,"binary"),r._src=e,t(r)})},fabric.loadSVGFromURL=function(e,t){e=e.replace(/^\n\s*/,"").replace(/\?.*$/,"").trim(),request(e,"",function(e){fabric.loadSVGFromString(e,t)})},fabric.loadSVGFromString=function(e,t){var n=(new DOMParser).parseFromString(e);fabric.parseSVGDocument(n.documentElement,function(e,n){t(e,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),t(r)})},fabric.createCanvasForNode=function(e,t){var n=fabric.document.createElement("canvas"),r=new Canvas(e||600,t||600);n.style={},n.width=r.width,n.height=r.height;var i=fabric.Canvas||fabric.StaticCanvas,s=new i(n);return s.contextContainer=r.getContext("2d"),s.nodeCanvas=r,s},fabric.StaticCanvas.prototype.createPNGStream=function(){return this.nodeCanvas.createPNGStream()};var origSetWidth=fabric.StaticCanvas.prototype.setWidth;fabric.StaticCanvas.prototype.setWidth=function(e){return origSetWidth.call(this),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),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/all.min.js.gz b/dist/all.min.js.gz index e8f75a9ba875c52a841861e56ab3d5b0fda56637..79de63bf88ffc8a11b3b811cea5c15d4f830e61d 100644 GIT binary patch delta 36857 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

IfuZ&5ka%mVhuORnu>@5abxt zT|B;G-&DL5z^&@;;I?Sv5&L8z z3Jr@iTCoi)D`1P)#_-O19*NeW(b{MhI^F=H1%C@AW2{OACs^(Cckih8(N%~y93WnJ zwfgDp>*z)g;OGmNA=ACZP~!DwY4v?l{<>a88w3Q|;V)>)10#mQ*1`iCB0aZgU2$

zEBb=vV> znDhpNcPst-Mg6|b|KR18Jbl!>K$NM0M$?Tgw)eY^=|ZGTD* zG1&qXJyzRW!klUC5WB|;MkAq`w9-Y8#�muaaBXCe=@~7d{BWxQ2}zNEg6lsA z;+G&Aw4IaLmU-42dlek}$C8Lu!G9ELjt~tCv076YT{M8UiM%4D(t67;;SdcqC}+7u zaBSANMmG3&Lo0Pn%M|~b3lrh0Lg<;j;8V?zFDKJ8+IAG~tTfk+>n(mF&JWYC;Ag)J zUsS?UG3nn$|e@OtF>=X&U_o<_K|tZ|;*Wb<@iea9l>G1kZO?5piq)^;pwOaIxP9#L}# zw|rA>=xehLm(Dq0IZm|nCp@*YD?GVg{s}Aoa!2t`wd7BE>K(;D)r)`1Tc4IIYe%~_ z4iK8#KKmVXYq1+3bi+b75K80D40-X2;5gg0Ex~cnXj2HP1tqtRf<&M!NJ7sw4S4uqp`Tfnhc0fvobD%?kPOF+ zNU+gNkyerdHf`0XWYs#ra&RZk+}JxrMu4vz?j>JxN!xXl?LEj2I>x?3oRBJ|QX8k4 z9=YdG)04v4W(Md7oqu(-@sUU4xpgI`YDG8Z`0N~xE3%txnJ<=(DV!lW(h^r~sbf8- z0QN+`Kvt78@qr97{-+~bluSX1#Ie9F`ncON+_JP&Gg!cVzv92Tw5KsPOk%%e`_f2R z@-s_Ixrnv=B2QndN8}-)+7U_9n3!yRya;D;a=e%fPvYf+2Y<_xc=X@_{GL5{FoWNu zaZj7k)BB5$@y2+vS8?W*2P*F^RXcD=vv1Z0_`gUN`ljfZ<+7JyQr^11PsmO{CVmdZ z&$2mP9#s)PCS|f*rc1?*7Q3hCM<#r208etBzolV1be@LyG$~Fh0(lauD+rR6z#qTp zje>u#P-yO09)DCPs(VhdfxZs?1s_&@k8cbDVrx~0C! z)r}_ANv3p+ia13d4r}=1SJ?Fo$H6`HK5T;!Jz1H3Pwc*zj=q;|eJ}U+{Vkfn=a)-+ za|-2#k`Aa0B}gS5F&S$7=}Wr+l8wh|m>9uG-3ttE%zw4$a0MMsgK*gvzYYm1Zq`0v z3C3Tw#V2qXh4@wL9E!cMYFTcf6|roKn6*V*X%Wq7TeVHw>W?_=Q-=?>y zp;RNLnST-S_VR-H5a$QG>SfKO*X*l}Mf%7}BDTj)DNaS6CQgy#g8KBb*h?2BlXc05 zORt2+c|Cl!Cr%8X;rWm8Ili9q0+Y`wG1*Zh{dgqHhEdyJbO`fLl4Q-r>7>?G5Ju$h zzK&|)v4upZq)whLGJjVYm7xW0-^;D<()^}beukJ-ZIi5Z z76ymr+DdP-t<7=o)Tna7c`tp5@w-}Gd{ZVHddEFzz~!5gk3-)bJfey04xap#CbByi zjg+gtVL&fYIPQ-Wc96BD;U(fG*|d(_VI5dT-owxT`CGTESGCR5sM0K=2$nUVT5 z5OyGE=fXFLSOlb0Ja{4;ap-+4n3!J9tvJ`$aIUXU9!=Kh+l=vc%w1#wG}*7t*5_S+ zgjRh8{?r`6)2b-jR>fA*y)u3K&DTkM{C{`czS9rB|6zVN3LkAzQ95K$eeQ4Osh0-{ zZ@>899ZWyq6S=AYwmOvmr>W1q3ZLJ7wY`_Wp{Rd5&SdfhBb+X%sGK5sPaK3+b;^ix zB1Ew_*qnEtKasI|&g2fL#fz*KGH!(M*Vy{(@%hwvX?lDfM5FVq-8JOG_)jAWhkxmF zdd{RP}m<>hRNAdF<$EzoQz#_1R0DKScjy zm7aK{B_5fH$KhjQ?^NQkmUwI?ejG~rtmY^SfoiMisLaoTK4B8fSzx2t0+=SvqHAsA z5USi4KGhnG5#IP1n}T38+3Y#J%YP`ReL5qfr`XNU7?4^HWli%r%|-}P5UwuIehN#< z0e%~@8yfee{k&K&=bgN$JL-|H^AGm)^p8%;>hvVcirzo#2E@22

$eW63E#bd)ei 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"; }, + /** + * Makes sure the scale is valid and modifies it if necessary + * @private + * @method _constrainScale + * @param {Number} value + * @return {Number} + */ + _constrainScale: function(value) { + if (Math.abs(value) < this.minScaleLimit) { + if (value < 0) + return -this.minScaleLimit; + else + return this.minScaleLimit; + } + + return value; + }, + /** * Sets property to a given value * @method set @@ -454,13 +515,26 @@ }, _set: function(key, value) { - var shouldConstrainValue = (key === 'scaleX' || key === 'scaleY') && - value < fabric.Object.MIN_SCALE_LIMIT; + var shouldConstrainValue = (key === 'scaleX' || key === 'scaleY'); if (shouldConstrainValue) { - value = fabric.Object.MIN_SCALE_LIMIT; + value = this._constrainScale(value); } + if (key === 'scaleX' && value < 0) { + this.flipX = !this.flipX; + value *= -1; + } + else if (key === 'scaleY' && value < 0) { + this.flipY = !this.flipY; + value *= -1; + } + else if (key === 'width' || key === 'height') { + this.minScaleLimit = Math.min(0.1, 1/Math.max(this.width, this.height)); + } + this[key] = value; + + return this; }, /** @@ -566,6 +640,162 @@ return this.height * this.scaleY; }, + /** + * Translates the coordinates from origin to center coordinates (based on the object's dimensions) + * @method translateToCenterPoint + * @param {fabric.Point} point The point which corresponds to the originX and originY params + * @param {string} enum('left', 'center', 'right') Horizontal origin + * @param {string} enum('top', 'center', 'bottom') Vertical origin + * @return {fabric.Point} + */ + translateToCenterPoint: function(point, originX, originY) { + var cx = point.x, cy = point.y; + + if ( originX === "left" ) { + cx = point.x + this.getWidth() / 2; + } + else if ( originX === "right" ) { + cx = point.x - this.getWidth() / 2; + } + + if ( originY === "top" ) { + cy = point.y + this.getHeight() / 2; + } + else if ( originY === "bottom" ) { + cy = point.y - this.getHeight() / 2; + } + + // Apply the reverse rotation to the point (it's already scaled properly) + return fabric.util.rotatePoint(new fabric.Point(cx, cy), point, degreesToRadians(this.angle)); + }, + + /** + * Translates the coordinates from center to origin coordinates (based on the object's dimensions) + * @method translateToOriginPoint + * @param {fabric.Point} point The point which corresponds to center of the object + * @param {string} enum('left', 'center', 'right') Horizontal origin + * @param {string} enum('top', 'center', 'bottom') Vertical origin + * @return {fabric.Point} + */ + translateToOriginPoint: function(center, originX, originY) { + var x = center.x, y = center.y; + + // Get the point coordinates + if ( originX === "left" ) { + x = center.x - this.getWidth() / 2; + } + else if ( originX === "right" ) { + x = center.x + this.getWidth() / 2; + } + if ( originY === "top" ) { + y = center.y - this.getHeight() / 2; + } + else if ( originY === "bottom" ) { + y = center.y + this.getHeight() / 2; + } + + // Apply the rotation to the point (it's already scaled properly) + return fabric.util.rotatePoint(new fabric.Point(x, y), center, degreesToRadians(this.angle)); + }, + + /** + * Returns the real center coordinates of the object + * @method getCenterPoint + * @return {fabric.Point} + */ + getCenterPoint: function() { + return this.translateToCenterPoint( + new fabric.Point(this.left, this.top), this.originX, this.originY); + }, + + /** + * Returns the coordinates of the object based on center coordinates + * @method getOriginPoint + * @param {fabric.Point} point The point which corresponds to the originX and originY params + * @return {fabric.Point} + */ + getOriginPoint: function(center) { + return this.translateToOriginPoint(center, this.originX, this.originY); + }, + + /** + * Returns the coordinates of the object as if it has a different origin + * @method getPointByOrigin + * @param {string} enum('left', 'center', 'right') Horizontal origin + * @param {string} enum('top', 'center', 'bottom') Vertical origin + * @return {fabric.Point} + */ + getPointByOrigin: function(originX, originY) { + var center = this.getCenterPoint(); + + return this.translateToOriginPoint(center, originX, originY); + }, + + /** + * Returns the point in local coordinates + * @method toLocalPoint + * @param {fabric.Point} The point relative to the global coordinate system + * @return {fabric.Point} + */ + toLocalPoint: function(point, originX, originY) { + var center = this.getCenterPoint(); + + var x, y; + if (originX !== undefined && originY !== undefined) { + if ( originX === "left" ) { + x = center.x - this.getWidth() / 2; + } + else if ( originX === "right" ) { + x = center.x + this.getWidth() / 2; + } + else { + x = center.x; + } + + if ( originY === "top" ) { + y = center.y - this.getHeight() / 2; + } + else if ( originY === "bottom" ) { + y = center.y + this.getHeight() / 2; + } + else { + y = center.y; + } + } + else { + x = this.left; + y = this.top; + } + + return fabric.util.rotatePoint(new fabric.Point(point.x, point.y), center, -degreesToRadians(this.angle)).subtractEquals(new fabric.Point(x, y)); + }, + + /** + * Returns the point in global coordinates + * @method toGlobalPoint + * @param {fabric.Point} The point relative to the local coordinate system + * @return {fabric.Point} + */ + toGlobalPoint: function(point) { + return fabric.util.rotatePoint(point, this.getCenterPoint(), degreesToRadians(this.angle)).addEquals(new fabric.Point(this.left, this.top)); + }, + + /** + * Sets the position of the object taking into consideration the object's origin + * @method setPositionByOrigin + * @param {fabric.Point} point The new position of the object + * @param {string} enum('left', 'center', 'right') Horizontal origin + * @param {string} enum('top', 'center', 'bottom') Vertical origin + * @return {void} + */ + setPositionByOrigin: function(pos, originX, originY) { + var center = this.translateToCenterPoint(pos, originX, originY); + var position = this.translateToOriginPoint(center, this.originX, this.originY); + + this.set('left', position.x); + this.set('top', position.y); + }, + /** * Scales an object (equally by x and y) * @method scale @@ -574,6 +804,14 @@ * @chainable */ scale: function(value) { + value = this._constrainScale(value); + + if (value < 0) { + this.flipX = !this.flipX; + this.flipY = !this.flipY; + value *= -1; + } + this.scaleX = value; this.scaleY = value; this.setCoords(); @@ -638,9 +876,10 @@ sinTh = Math.sin(theta), cosTh = Math.cos(theta); + var coords = this.getCenterPoint(); var tl = { - x: this.left - offsetX, - y: this.top - offsetY + x: coords.x - offsetX, + y: coords.y - offsetY }; var tr = { x: tl.x + (this.currentWidth * cosTh), @@ -736,8 +975,7 @@ drawBorders: function(ctx) { if (!this.hasBorders) return; - var MIN_SCALE_LIMIT = fabric.Object.MIN_SCALE_LIMIT, - padding = this.padding, + var padding = this.padding, padding2 = padding * 2, strokeWidth = this.strokeWidth > 1 ? this.strokeWidth : 0; @@ -746,8 +984,8 @@ ctx.globalAlpha = this.isMoving ? this.borderOpacityWhenMoving : 1; ctx.strokeStyle = this.borderColor; - var scaleX = 1 / (this.scaleX < MIN_SCALE_LIMIT ? MIN_SCALE_LIMIT : this.scaleX), - scaleY = 1 / (this.scaleY < MIN_SCALE_LIMIT ? MIN_SCALE_LIMIT : this.scaleY); + var scaleX = 1 / this._constrainScale(this.scaleX), + scaleY = 1 / this._constrainScale(this.scaleY); ctx.lineWidth = 1 / this.borderScaleFactor; @@ -1704,15 +1942,7 @@ * @constant * @type Number */ - NUM_FRACTION_DIGITS: 2, - - /** - * @static - * @constant - * @type Number - */ - MIN_SCALE_LIMIT: 0.1 - + NUM_FRACTION_DIGITS: 2 }); })(typeof exports !== 'undefined' ? exports : this); diff --git a/src/util/misc.js b/src/util/misc.js index 11566edc..29efd0cc 100644 --- a/src/util/misc.js +++ b/src/util/misc.js @@ -62,6 +62,28 @@ return radians / PiBy180; } + /** + * Rotates `point` around `origin` with `radians` + * @static + * @method rotatePoint + * @memberOf fabric.util + * @param {fabric.Point} The point to rotate + * @param {fabric.Point} The origin of the rotation + * @param {Number} The radians of the angle for the rotation + * @return {fabric.Point} The new rotated point + */ + function rotatePoint(point, origin, radians) { + var sin = Math.sin(radians), + cos = Math.cos(radians); + + point.subtractEquals(origin); + + var rx = point.x * cos - point.y * sin; + var ry = point.x * sin + point.y * cos; + + return new fabric.Point(rx, ry).addEquals(origin); + } + /** * A wrapper around Number#toFixed, which contrary to native method returns number, not string. * @static @@ -245,6 +267,7 @@ fabric.util.removeFromArray = removeFromArray; fabric.util.degreesToRadians = degreesToRadians; fabric.util.radiansToDegrees = radiansToDegrees; + fabric.util.rotatePoint = rotatePoint; fabric.util.toFixed = toFixed; fabric.util.getRandomInt = getRandomInt; fabric.util.falseFunction = falseFunction;