* ver 166
This commit is contained in:
Andrea Bogazzi 2016-10-16 23:40:02 +02:00 committed by GitHub
parent ddc8a028de
commit 28c2654a23
10 changed files with 386 additions and 101 deletions

View file

@ -1,3 +1,10 @@
**Version 1.6.6**
- Add: Contrast and Saturate filters [#3341](https://github.com/kangax/fabric.js/pull/3341)
- Fix: Correct registering and removal of events to handle iText objects. [#3349](https://github.com/kangax/fabric.js/pull/3349)
- Fix: Corrected 2 regression of 1.6.5 (dataurl export and itext clicks)
- Fix: Corrected path boundaries calculation for Arcs ( a and A ) [#3347](https://github.com/kangax/fabric.js/pull/3347)
**Version 1.6.5**
- Fix: charspacing, do not get subzero with charwidth.

View file

@ -1,6 +1,6 @@
/*! Fabric.js Copyright 2008-2015, Printio (Juriy Zaytsev, Maxim Chernyak) */
var fabric = fabric || { version: "1.6.5" };
var fabric = fabric || { version: "1.6.6" };
if (typeof exports !== 'undefined') {
exports.fabric = fabric;
}

286
dist/fabric.js vendored
View file

@ -1,7 +1,7 @@
/* build: `node build.js modules=ALL exclude=json,gestures minifier=uglifyjs` */
/*! Fabric.js Copyright 2008-2015, Printio (Juriy Zaytsev, Maxim Chernyak) */
var fabric = fabric || { version: "1.6.5" };
var fabric = fabric || { version: "1.6.6" };
if (typeof exports !== 'undefined') {
exports.fabric = fabric;
}
@ -1174,18 +1174,13 @@ fabric.Collection = {
*/
fabric.util.getBoundsOfArc = function(fx, fy, rx, ry, rot, large, sweep, tx, ty) {
var fromX = 0, fromY = 0, bound = [], bounds = [],
segs = arcToSegments(tx - fx, ty - fy, rx, ry, large, sweep, rot),
boundCopy = [[], []];
var fromX = 0, fromY = 0, bound, bounds = [],
segs = arcToSegments(tx - fx, ty - fy, rx, ry, large, sweep, rot);
for (var i = 0, len = segs.length; i < len; i++) {
bound = getBoundsOfCurve(fromX, fromY, segs[i][0], segs[i][1], segs[i][2], segs[i][3], segs[i][4], segs[i][5]);
boundCopy[0].x = bound[0].x + fx;
boundCopy[0].y = bound[0].y + fy;
boundCopy[1].x = bound[1].x + fx;
boundCopy[1].y = bound[1].y + fy;
bounds.push(boundCopy[0]);
bounds.push(boundCopy[1]);
bounds.push({ x: bound[0].x + fx, y: bound[0].y + fy });
bounds.push({ x: bound[1].x + fx, y: bound[1].y + fy });
fromX = segs[i][4];
fromY = segs[i][5];
}
@ -1549,7 +1544,6 @@ fabric.Collection = {
(function() {
/**
* Copies all enumerable properties of one object to another
* @memberOf fabric.util.object
@ -1557,12 +1551,17 @@ fabric.Collection = {
* @param {Object} source Where to copy from
* @return {Object}
*/
function extend(destination, source, deep) {
// JScript DontEnum bug is not taken care of
// the deep clone is for internal use, is not meant to avoid
// javascript traps or cloning html element or self referenced objects.
if (deep) {
if (source instanceof Array) {
if (!fabric.isLikelyNode && source instanceof Element) {
// avoid cloning deep images, canvases,
destination = source;
}
else if (source instanceof Array) {
destination = source.map(function(v) {
return clone(v, deep)
})
@ -6779,6 +6778,13 @@ fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */
this.overlayImage = null;
this.backgroundColor = '';
this.overlayColor = ''
if (this._hasITextHandlers) {
this.off('selection:cleared', this._canvasITextSelectionClearedHanlder);
this.off('object:selected', this._canvasITextSelectionClearedHanlder);
this.off('mouse:up', this._mouseUpITextHandler);
this._iTextInstances = null;
this._hasITextHandlers = false;
}
this.clearContext(this.contextContainer);
this.fire('canvas:cleared');
this.renderAll();
@ -10958,7 +10964,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
var origWidth = this.getWidth(),
origHeight = this.getHeight(),
scaledWidth = (cropping.width || this.getWidth()) * multiplier,
scaledHeight = (cropping.width || this.getHeight()) * multiplier,
scaledHeight = (cropping.height || this.getHeight()) * multiplier,
zoom = this.getZoom(),
newZoom = zoom * multiplier,
vp = this.viewportTransform,
@ -13897,7 +13903,11 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot
}
function _isEqual(origValue, currentValue) {
if (origValue instanceof Array) {
if (!fabric.isLikelyNode && origValue instanceof Element) {
// avoid checking deep html elements
return origValue === currentValue;
}
else if (origValue instanceof Array) {
if (origValue.length !== currentValue.length) {
return false
}
@ -18944,7 +18954,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag
* Constructor
* @memberOf fabric.Image.filters.Brightness.prototype
* @param {Object} [options] Options object
* @param {Number} [options.brightness=0] Value to brighten the image up (0..255)
* @param {Number} [options.brightness=0] Value to brighten the image up (-255..255)
*/
initialize: function(options) {
options = options || { };
@ -20746,6 +20756,180 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag
})(typeof exports !== 'undefined' ? exports : this);
(function(global) {
'use strict';
var fabric = global.fabric || (global.fabric = { }),
extend = fabric.util.object.extend,
filters = fabric.Image.filters,
createClass = fabric.util.createClass;
/**
* Contrast filter class
* @class fabric.Image.filters.Contrast
* @memberOf fabric.Image.filters
* @extends fabric.Image.filters.BaseFilter
* @see {@link fabric.Image.filters.Contrast#initialize} for constructor definition
* @see {@link http://fabricjs.com/image-filters|ImageFilters demo}
* @example
* var filter = new fabric.Image.filters.Contrast({
* contrast: 40
* });
* object.filters.push(filter);
* object.applyFilters(canvas.renderAll.bind(canvas));
*/
filters.Contrast = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Contrast.prototype */ {
/**
* Filter type
* @param {String} type
* @default
*/
type: 'Contrast',
/**
* Constructor
* @memberOf fabric.Image.filters.Contrast.prototype
* @param {Object} [options] Options object
* @param {Number} [options.contrast=0] Value to contrast the image up (-255...255)
*/
initialize: function(options) {
options = options || { };
this.contrast = options.contrast || 0;
},
/**
* Applies filter to canvas element
* @param {Object} canvasEl Canvas element to apply filter to
*/
applyTo: function(canvasEl) {
var context = canvasEl.getContext('2d'),
imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height),
data = imageData.data,
contrastF = 259 * (this.contrast + 255) / (255 * (259 - this.contrast));
for (var i = 0, len = data.length; i < len; i += 4) {
data[i] = contrastF * (data[i] - 128) + 128;
data[i + 1] = contrastF * (data[i + 1] - 128) + 128;
data[i + 2] = contrastF * (data[i + 2] - 128) + 128;
}
context.putImageData(imageData, 0, 0);
},
/**
* Returns object representation of an instance
* @return {Object} Object representation of an instance
*/
toObject: function() {
return extend(this.callSuper('toObject'), {
contrast: this.contrast
});
}
});
/**
* Returns filter instance from an object representation
* @static
* @param {Object} object Object to create an instance from
* @return {fabric.Image.filters.Contrast} Instance of fabric.Image.filters.Contrast
*/
fabric.Image.filters.Contrast.fromObject = function(object) {
return new fabric.Image.filters.Contrast(object);
};
})(typeof exports !== 'undefined' ? exports : this);
(function(global) {
'use strict';
var fabric = global.fabric || (global.fabric = { }),
extend = fabric.util.object.extend,
filters = fabric.Image.filters,
createClass = fabric.util.createClass;
/**
* Saturate filter class
* @class fabric.Image.filters.Saturate
* @memberOf fabric.Image.filters
* @extends fabric.Image.filters.BaseFilter
* @see {@link fabric.Image.filters.Saturate#initialize} for constructor definition
* @see {@link http://fabricjs.com/image-filters|ImageFilters demo}
* @example
* var filter = new fabric.Image.filters.Saturate({
* saturate: 100
* });
* object.filters.push(filter);
* object.applyFilters(canvas.renderAll.bind(canvas));
*/
filters.Saturate = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Saturate.prototype */ {
/**
* Filter type
* @param {String} type
* @default
*/
type: 'Saturate',
/**
* Constructor
* @memberOf fabric.Image.filters.Saturate.prototype
* @param {Object} [options] Options object
* @param {Number} [options.contrast=0] Value to saturate the image (-255...255)
*/
initialize: function(options) {
options = options || { };
this.saturate = options.saturate || 0;
this.loadProgram();
},
/**
* Applies filter to canvas element
* @param {Object} canvasEl Canvas element to apply filter to
*/
applyTo: function(canvasEl) {
var context = canvasEl.getContext('2d'),
imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height),
data = imageData.data,
max, adjust = -this.saturate * 0.01;
for (var i = 0, len = data.length; i < len; i += 4) {
max = Math.max(data[i], data[i + 1], data[i + 2]);
data[i] += max !== data[i] ? (max - data[i]) * adjust : 0;
data[i + 1] += max !== data[i + 1] ? (max - data[i + 1]) * adjust : 0;
data[i + 2] += max !== data[i + 2] ? (max - data[i + 2]) * adjust : 0;
}
context.putImageData(imageData, 0, 0);
},
/**
* Returns object representation of an instance
* @return {Object} Object representation of an instance
*/
toObject: function() {
return extend(this.callSuper('toObject'), {
saturate: this.saturate
});
}
});
/**
* Returns filter instance from an object representation
* @static
* @param {Object} object Object to create an instance from
* @return {fabric.Image.filters.Saturate} Instance of fabric.Image.filters.Saturate
*/
fabric.Image.filters.Saturate.fromObject = function(object) {
return new fabric.Image.filters.Saturate(object);
};
})(typeof exports !== 'undefined' ? exports : this);
(function(global) {
'use strict';
@ -23132,6 +23316,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag
this.initRemovedHandler();
this.initCursorSelectionHandlers();
this.initDoubleClickSimulation();
this.mouseMoveHandler = this.mouseMoveHandler.bind(this);
},
/**
@ -23153,18 +23338,14 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag
initAddedHandler: function() {
var _this = this;
this.on('added', function() {
if (this.canvas && !this.canvas._hasITextHandlers) {
this.canvas._hasITextHandlers = true;
this._initCanvasHandlers();
}
// Track IText instances per-canvas. Only register in this array once added
// to a canvas; we don't want to leak a reference to the instance forever
// simply because it existed at some point.
// (Might be added to a collection, but not on a canvas.)
if (_this.canvas) {
_this.canvas._iTextInstances = _this.canvas._iTextInstances || [];
_this.canvas._iTextInstances.push(_this);
var canvas = _this.canvas;
if (canvas) {
if (!canvas._hasITextHandlers) {
canvas._hasITextHandlers = true;
_this._initCanvasHandlers(canvas);
}
canvas._iTextInstances = canvas._iTextInstances || [];
canvas._iTextInstances.push(_this);
}
});
},
@ -23172,35 +23353,46 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag
initRemovedHandler: function() {
var _this = this;
this.on('removed', function() {
// (Might be removed from a collection, but not on a canvas.)
if (_this.canvas) {
_this.canvas._iTextInstances = _this.canvas._iTextInstances || [];
fabric.util.removeFromArray(_this.canvas._iTextInstances, _this);
var canvas = _this.canvas;
if (canvas) {
canvas._iTextInstances = canvas._iTextInstances || [];
fabric.util.removeFromArray(canvas._iTextInstances, _this);
if (canvas._iTextInstances.length === 0) {
canvas._hasITextHandlers = false;
_this._removeCanvasHandlers(canvas);
}
}
});
},
/**
* register canvas event to manage exiting on other instances
* @private
*/
_initCanvasHandlers: function() {
var _this = this;
this.canvas.on('selection:cleared', function() {
fabric.IText.prototype.exitEditingOnOthers(_this.canvas);
});
this.canvas.on('mouse:up', function() {
if (_this.canvas._iTextInstances) {
_this.canvas._iTextInstances.forEach(function(obj) {
_initCanvasHandlers: function(canvas) {
canvas._canvasITextSelectionClearedHanlder = (function() {
fabric.IText.prototype.exitEditingOnOthers(canvas);
}).bind(this);
canvas._mouseUpITextHandler = (function() {
if (canvas._iTextInstances) {
canvas._iTextInstances.forEach(function(obj) {
obj.__isMousedown = false;
});
}
});
}).bind(this);
canvas.on('selection:cleared', canvas._canvasITextSelectionClearedHanlder);
canvas.on('object:selected', canvas._canvasITextSelectionClearedHanlder);
canvas.on('mouse:up', canvas._mouseUpITextHandler);
},
this.canvas.on('object:selected', function() {
fabric.IText.prototype.exitEditingOnOthers(_this.canvas);
});
/**
* remove canvas event to manage exiting on other instances
* @private
*/
_removeCanvasHandlers: function(canvas) {
canvas.off('selection:cleared', canvas._canvasITextSelectionClearedHanlder);
canvas.off('object:selected', canvas._canvasITextSelectionClearedHanlder);
canvas.off('mouse:up', canvas._mouseUpITextHandler);
},
/**
@ -23487,8 +23679,8 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag
return this;
}
this.canvas.fire('text:editing:entered', { target: this });
this.canvas.renderAll();
this.initMouseMoveHandler();
this.canvas.renderAll();
return this;
},
@ -23507,7 +23699,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag
* Initializes "mousemove" event handler
*/
initMouseMoveHandler: function() {
this.canvas.on('mouse:move', this.mouseMoveHandler.bind(this));
this.canvas.on('mouse:move', this.mouseMoveHandler);
},
/**

16
dist/fabric.min.js vendored

File diff suppressed because one or more lines are too long

BIN
dist/fabric.min.js.gz vendored

Binary file not shown.

154
dist/fabric.require.js vendored
View file

@ -1,5 +1,5 @@
var fabric = fabric || {
version: "1.6.5"
version: "1.6.6"
};
if (typeof exports !== "undefined") {
@ -551,15 +551,17 @@ fabric.Collection = {
}
};
fabric.util.getBoundsOfArc = function(fx, fy, rx, ry, rot, large, sweep, tx, ty) {
var fromX = 0, fromY = 0, bound = [], bounds = [], segs = arcToSegments(tx - fx, ty - fy, rx, ry, large, sweep, rot), boundCopy = [ [], [] ];
var fromX = 0, fromY = 0, bound, bounds = [], segs = arcToSegments(tx - fx, ty - fy, rx, ry, large, sweep, rot);
for (var i = 0, len = segs.length; i < len; i++) {
bound = getBoundsOfCurve(fromX, fromY, segs[i][0], segs[i][1], segs[i][2], segs[i][3], segs[i][4], segs[i][5]);
boundCopy[0].x = bound[0].x + fx;
boundCopy[0].y = bound[0].y + fy;
boundCopy[1].x = bound[1].x + fx;
boundCopy[1].y = bound[1].y + fy;
bounds.push(boundCopy[0]);
bounds.push(boundCopy[1]);
bounds.push({
x: bound[0].x + fx,
y: bound[0].y + fy
});
bounds.push({
x: bound[1].x + fx,
y: bound[1].y + fy
});
fromX = segs[i][4];
fromY = segs[i][5];
}
@ -795,7 +797,9 @@ fabric.Collection = {
(function() {
function extend(destination, source, deep) {
if (deep) {
if (source instanceof Array) {
if (!fabric.isLikelyNode && source instanceof Element) {
destination = source;
} else if (source instanceof Array) {
destination = source.map(function(v) {
return clone(v, deep);
});
@ -3437,6 +3441,13 @@ fabric.Pattern = fabric.util.createClass({
this.overlayImage = null;
this.backgroundColor = "";
this.overlayColor = "";
if (this._hasITextHandlers) {
this.off("selection:cleared", this._canvasITextSelectionClearedHanlder);
this.off("object:selected", this._canvasITextSelectionClearedHanlder);
this.off("mouse:up", this._mouseUpITextHandler);
this._iTextInstances = null;
this._hasITextHandlers = false;
}
this.clearContext(this.contextContainer);
this.fire("canvas:cleared");
this.renderAll();
@ -5577,7 +5588,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, {
return this.__toDataURLWithMultiplier(format, quality, cropping, multiplier);
},
__toDataURLWithMultiplier: function(format, quality, cropping, multiplier) {
var origWidth = this.getWidth(), origHeight = this.getHeight(), scaledWidth = (cropping.width || this.getWidth()) * multiplier, scaledHeight = (cropping.width || this.getHeight()) * multiplier, zoom = this.getZoom(), newZoom = zoom * multiplier, vp = this.viewportTransform, translateX = (vp[4] - cropping.left) * multiplier, translateY = (vp[5] - cropping.top) * multiplier, newVp = [ newZoom, 0, 0, newZoom, translateX, translateY ], originalInteractive = this.interactive;
var origWidth = this.getWidth(), origHeight = this.getHeight(), scaledWidth = (cropping.width || this.getWidth()) * multiplier, scaledHeight = (cropping.height || this.getHeight()) * multiplier, zoom = this.getZoom(), newZoom = zoom * multiplier, vp = this.viewportTransform, translateX = (vp[4] - cropping.left) * multiplier, translateY = (vp[5] - cropping.top) * multiplier, newVp = [ newZoom, 0, 0, newZoom, translateX, translateY ], originalInteractive = this.interactive;
this.viewportTransform = newVp;
this.interactive && (this.interactive = false);
if (origWidth !== scaledWidth || origHeight !== scaledHeight) {
@ -6680,7 +6691,9 @@ fabric.util.object.extend(fabric.Object.prototype, {
extend(origin[destination], tmpObj, deep);
}
function _isEqual(origValue, currentValue) {
if (origValue instanceof Array) {
if (!fabric.isLikelyNode && origValue instanceof Element) {
return origValue === currentValue;
} else if (origValue instanceof Array) {
if (origValue.length !== currentValue.length) {
return false;
}
@ -9833,6 +9846,66 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass({
};
})(typeof exports !== "undefined" ? exports : this);
(function(global) {
"use strict";
var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend, filters = fabric.Image.filters, createClass = fabric.util.createClass;
filters.Contrast = createClass(filters.BaseFilter, {
type: "Contrast",
initialize: function(options) {
options = options || {};
this.contrast = options.contrast || 0;
},
applyTo: function(canvasEl) {
var context = canvasEl.getContext("2d"), imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height), data = imageData.data, contrastF = 259 * (this.contrast + 255) / (255 * (259 - this.contrast));
for (var i = 0, len = data.length; i < len; i += 4) {
data[i] = contrastF * (data[i] - 128) + 128;
data[i + 1] = contrastF * (data[i + 1] - 128) + 128;
data[i + 2] = contrastF * (data[i + 2] - 128) + 128;
}
context.putImageData(imageData, 0, 0);
},
toObject: function() {
return extend(this.callSuper("toObject"), {
contrast: this.contrast
});
}
});
fabric.Image.filters.Contrast.fromObject = function(object) {
return new fabric.Image.filters.Contrast(object);
};
})(typeof exports !== "undefined" ? exports : this);
(function(global) {
"use strict";
var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend, filters = fabric.Image.filters, createClass = fabric.util.createClass;
filters.Saturate = createClass(filters.BaseFilter, {
type: "Saturate",
initialize: function(options) {
options = options || {};
this.saturate = options.saturate || 0;
this.loadProgram();
},
applyTo: function(canvasEl) {
var context = canvasEl.getContext("2d"), imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height), data = imageData.data, max, adjust = -this.saturate * .01;
for (var i = 0, len = data.length; i < len; i += 4) {
max = Math.max(data[i], data[i + 1], data[i + 2]);
data[i] += max !== data[i] ? (max - data[i]) * adjust : 0;
data[i + 1] += max !== data[i + 1] ? (max - data[i + 1]) * adjust : 0;
data[i + 2] += max !== data[i + 2] ? (max - data[i + 2]) * adjust : 0;
}
context.putImageData(imageData, 0, 0);
},
toObject: function() {
return extend(this.callSuper("toObject"), {
saturate: this.saturate
});
}
});
fabric.Image.filters.Saturate.fromObject = function(object) {
return new fabric.Image.filters.Saturate(object);
};
})(typeof exports !== "undefined" ? exports : this);
(function(global) {
"use strict";
var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend, clone = fabric.util.object.clone, toFixed = fabric.util.toFixed, NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS, MIN_TEXT_WIDTH = 2;
@ -10875,6 +10948,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass({
this.initRemovedHandler();
this.initCursorSelectionHandlers();
this.initDoubleClickSimulation();
this.mouseMoveHandler = this.mouseMoveHandler.bind(this);
},
initSelectedHandler: function() {
this.on("selected", function() {
@ -10887,40 +10961,50 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass({
initAddedHandler: function() {
var _this = this;
this.on("added", function() {
if (this.canvas && !this.canvas._hasITextHandlers) {
this.canvas._hasITextHandlers = true;
this._initCanvasHandlers();
}
if (_this.canvas) {
_this.canvas._iTextInstances = _this.canvas._iTextInstances || [];
_this.canvas._iTextInstances.push(_this);
var canvas = _this.canvas;
if (canvas) {
if (!canvas._hasITextHandlers) {
canvas._hasITextHandlers = true;
_this._initCanvasHandlers(canvas);
}
canvas._iTextInstances = canvas._iTextInstances || [];
canvas._iTextInstances.push(_this);
}
});
},
initRemovedHandler: function() {
var _this = this;
this.on("removed", function() {
if (_this.canvas) {
_this.canvas._iTextInstances = _this.canvas._iTextInstances || [];
fabric.util.removeFromArray(_this.canvas._iTextInstances, _this);
var canvas = _this.canvas;
if (canvas) {
canvas._iTextInstances = canvas._iTextInstances || [];
fabric.util.removeFromArray(canvas._iTextInstances, _this);
if (canvas._iTextInstances.length === 0) {
canvas._hasITextHandlers = false;
_this._removeCanvasHandlers(canvas);
}
}
});
},
_initCanvasHandlers: function() {
var _this = this;
this.canvas.on("selection:cleared", function() {
fabric.IText.prototype.exitEditingOnOthers(_this.canvas);
});
this.canvas.on("mouse:up", function() {
if (_this.canvas._iTextInstances) {
_this.canvas._iTextInstances.forEach(function(obj) {
_initCanvasHandlers: function(canvas) {
canvas._canvasITextSelectionClearedHanlder = function() {
fabric.IText.prototype.exitEditingOnOthers(canvas);
}.bind(this);
canvas._mouseUpITextHandler = function() {
if (canvas._iTextInstances) {
canvas._iTextInstances.forEach(function(obj) {
obj.__isMousedown = false;
});
}
});
this.canvas.on("object:selected", function() {
fabric.IText.prototype.exitEditingOnOthers(_this.canvas);
});
}.bind(this);
canvas.on("selection:cleared", canvas._canvasITextSelectionClearedHanlder);
canvas.on("object:selected", canvas._canvasITextSelectionClearedHanlder);
canvas.on("mouse:up", canvas._mouseUpITextHandler);
},
_removeCanvasHandlers: function(canvas) {
canvas.off("selection:cleared", canvas._canvasITextSelectionClearedHanlder);
canvas.off("object:selected", canvas._canvasITextSelectionClearedHanlder);
canvas.off("mouse:up", canvas._mouseUpITextHandler);
},
_tick: function() {
this._currentTickState = this._animateCursor(this, 1, this.cursorDuration, "_onTickComplete");
@ -11091,8 +11175,8 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass({
this.canvas.fire("text:editing:entered", {
target: this
});
this.canvas.renderAll();
this.initMouseMoveHandler();
this.canvas.renderAll();
return this;
},
exitEditingOnOthers: function(canvas) {
@ -11106,7 +11190,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass({
}
},
initMouseMoveHandler: function() {
this.canvas.on("mouse:move", this.mouseMoveHandler.bind(this));
this.canvas.on("mouse:move", this.mouseMoveHandler);
},
mouseMoveHandler: function(options) {
if (!this.__isMousedown || !this.isEditing) {

View file

@ -2,7 +2,7 @@
"name": "fabric",
"description": "Object model for HTML5 canvas, and SVG-to-canvas parser. Backed by jsdom and node-canvas.",
"homepage": "http://fabricjs.com/",
"version": "1.6.5",
"version": "1.6.6",
"author": "Juriy Zaytsev <kangax@gmail.com>",
"contributors": [
{

View file

@ -14,7 +14,11 @@
}
function _isEqual(origValue, currentValue) {
if (origValue instanceof Array) {
if (!fabric.isLikelyNode && origValue instanceof Element) {
// avoid checking deep html elements
return origValue === currentValue;
}
else if (origValue instanceof Array) {
if (origValue.length !== currentValue.length) {
return false
}

View file

@ -1,5 +1,4 @@
(function() {
/**
* Copies all enumerable properties of one object to another
* @memberOf fabric.util.object
@ -7,12 +6,17 @@
* @param {Object} source Where to copy from
* @return {Object}
*/
function extend(destination, source, deep) {
// JScript DontEnum bug is not taken care of
// the deep clone is for internal use, is not meant to avoid
// javascript traps or cloning html element or self referenced objects.
if (deep) {
if (source instanceof Array) {
if (!fabric.isLikelyNode && source instanceof Element) {
// avoid cloning deep images, canvases,
destination = source;
}
else if (source instanceof Array) {
destination = source.map(function(v) {
return clone(v, deep)
})

View file

@ -375,7 +375,6 @@
equal(boundingRect.top, 0);
equal(boundingRect.width, 0);
equal(boundingRect.height, 0);
cObj.set('width', 123).setCoords();
boundingRect = cObj.getBoundingRect();
equal(boundingRect.left, 0);
@ -803,19 +802,14 @@
var onChange = function(){ onChangeFired = true; };
var callbacks = { onComplete: onComplete, onChange: onChange };
ok(typeof object.fxStraighten == 'function');
equal(object.fxStraighten(callbacks), object, 'should be chainable');
equal(fabric.util.toFixed(object.get('angle'), 0), 43);
setTimeout(function(){
ok(onCompleteFired);
ok(onChangeFired);
equal(object.get('angle'), 0, 'angle should be set to 0 by the end of animation');
equal(object.fxStraighten(), object, 'should work without callbacks');
start();
}, 1000);
});