update to rc4

This commit is contained in:
Asturur 2017-12-23 12:48:29 +01:00
parent 59ea40cde4
commit e5f28c1915
7 changed files with 224 additions and 95 deletions

View file

@ -1,4 +1,15 @@
**Version 2.0.0**
- rc3 and rc4
- more fixes to transformMatrix memoization
- Canvas.selectionFullyContained allows you to select objects just when full grabbed by the selections. [#4508](https://github.com/kangax/fabric.js/pull/4508)
- Remove some ouput of blank spaces from svg in order to avoid extra colored areas [#4524](https://github.com/kangax/fabric.js/pull/4524)
- Reinserted a performance shortcut for when there is no style at all [#4519](https://github.com/kangax/fabric.js/pull/4519)
- Manage canvas resize during a freedrawing brush without wiping the brush [#4527](https://github.com/kangax/fabric.js/pull/4527)
- Removed an extra closePath that was creating wrong visual on IntelIntegrated cards [#4549](https://github.com/kangax/fabric.js/pull/4549)
- Added a method to insert and remove text from command line [#4541](https://github.com/kangax/fabric.js/pull/4541)
- Some fixes around text styles management
- nodejs support changes: removed specific node code in order to use standard fabricjs code in nodejs.
- added fabric.util.getNodeCanvas that passed a JSDOM element allows you to get the node-canvas instance behind it and do what you need.
- rc2
- Fixed a transform matrix memoize missing width/height [#4491](https://github.com/kangax/fabric.js/pull/4491)
- Fix pattern drawing a point [#4492](https://github.com/kangax/fabric.js/pull/4492)

View file

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

190
dist/fabric.js vendored
View file

@ -1,7 +1,7 @@
/* build: `node build.js modules=ALL exclude=gestures,accessors minifier=uglifyjs` */
/*! Fabric.js Copyright 2008-2015, Printio (Juriy Zaytsev, Maxim Chernyak) */
var fabric = fabric || { version: '2.0.0-rc.3' };
var fabric = fabric || { version: '2.0.0-rc.4' };
if (typeof exports !== 'undefined') {
exports.fabric = fabric;
}
@ -20,6 +20,7 @@ else {
}
});
fabric.jsdomImplForWrapper = require('jsdom/lib/jsdom/living/generated/utils').implForWrapper;
fabric.nodeCanvas = require('jsdom/lib/jsdom/utils').Canvas;
fabric.window = fabric.document.defaultView;
DOMParser = require('xmldom').DOMParser;
}
@ -2395,8 +2396,7 @@ fabric.CommonMethods = {
top += element.scrollTop || 0;
}
if (element.nodeType === 1 &&
fabric.util.getElementStyle(element, 'position') === 'fixed') {
if (element.nodeType === 1 && element.style.position === 'fixed') {
break;
}
}
@ -2558,6 +2558,11 @@ fabric.CommonMethods = {
fabric.util.getScript = getScript;
})();
function getNodeCanvas(element) {
var impl = fabric.jsdomImplForWrapper(element);
return impl._canvas || impl._image;
};
fabric.util.getById = getById;
fabric.util.toArray = toArray;
fabric.util.makeElement = makeElement;
@ -2566,6 +2571,7 @@ fabric.CommonMethods = {
fabric.util.getScrollLeftTop = getScrollLeftTop;
fabric.util.getElementOffset = getElementOffset;
fabric.util.getElementStyle = getElementStyle;
fabric.util.getNodeCanvas = getNodeCanvas;
})();
@ -6887,6 +6893,9 @@ fabric.ElementsParser.prototype.checkIfDone = function() {
this._setCssDimension(prop, cssValue);
}
}
if (this._isCurrentlyDrawing) {
this.freeDrawingBrush && this.freeDrawingBrush._setBrushStyles();
}
this._initRetinaScaling();
this._setImageSmoothing();
this.calcOffset();
@ -7264,7 +7273,6 @@ fabric.ElementsParser.prototype.checkIfDone = function() {
/**
* Centers object horizontally in the canvas
* You might need to call `setCoords` on an object after centering, to update controls area.
* @param {fabric.Object} object Object to center horizontally
* @return {fabric.Canvas} thisArg
*/
@ -7274,7 +7282,6 @@ fabric.ElementsParser.prototype.checkIfDone = function() {
/**
* Centers object vertically in the canvas
* You might need to call `setCoords` on an object after centering, to update controls area.
* @param {fabric.Object} object Object to center vertically
* @return {fabric.Canvas} thisArg
* @chainable
@ -7285,7 +7292,6 @@ fabric.ElementsParser.prototype.checkIfDone = function() {
/**
* Centers object vertically and horizontally in the canvas
* You might need to call `setCoords` on an object after centering, to update controls area.
* @param {fabric.Object} object Object to center vertically and horizontally
* @return {fabric.Canvas} thisArg
* @chainable
@ -7298,7 +7304,6 @@ fabric.ElementsParser.prototype.checkIfDone = function() {
/**
* Centers object vertically and horizontally in the viewport
* You might need to call `setCoords` on an object after centering, to update controls area.
* @param {fabric.Object} object Object to center vertically and horizontally
* @return {fabric.Canvas} thisArg
* @chainable
@ -7311,7 +7316,6 @@ fabric.ElementsParser.prototype.checkIfDone = function() {
/**
* Centers object horizontally in the viewport, object.top is unchanged
* You might need to call `setCoords` on an object after centering, to update controls area.
* @param {fabric.Object} object Object to center vertically and horizontally
* @return {fabric.Canvas} thisArg
* @chainable
@ -7324,7 +7328,6 @@ fabric.ElementsParser.prototype.checkIfDone = function() {
/**
* Centers object Vertically in the viewport, object.top is unchanged
* You might need to call `setCoords` on an object after centering, to update controls area.
* @param {fabric.Object} object Object to center vertically and horizontally
* @return {fabric.Canvas} thisArg
* @chainable
@ -7355,6 +7358,7 @@ fabric.ElementsParser.prototype.checkIfDone = function() {
*/
_centerObject: function(object, center) {
object.setPositionByOrigin(center, 'center', 'center');
object.setCoords();
this.renderOnAddRemove && this.requestRenderAll();
return this;
},
@ -7941,12 +7945,15 @@ fabric.ElementsParser.prototype.checkIfDone = function() {
},
/**
* Clears a canvas element and removes all event listeners
* Clears a canvas element and dispose objects
* @return {fabric.Canvas} thisArg
* @chainable
*/
dispose: function () {
this._objects.length = 0;
this.forEachObject(function(object) {
object.dispose && object.dispose();
});
this._objects = [];
this.backgroundImage = null;
this.overlayImage = null;
this._iTextInstances = null;
@ -8043,11 +8050,11 @@ fabric.ElementsParser.prototype.checkIfDone = function() {
if (fabric.isLikelyNode) {
fabric.StaticCanvas.prototype.createPNGStream = function() {
var impl = fabric.jsdomImplForWrapper(this.lowerCanvasEl);
var impl = fabric.util.getNodeCanvas(this.lowerCanvasEl);
return impl && impl.createPNGStream();
};
fabric.StaticCanvas.prototype.createJPEGStream = function(opts) {
var impl = fabric.jsdomImplForWrapper(this.lowerCanvasEl);
var impl = fabric.util.getNodeCanvas(this.lowerCanvasEl);
return impl && impl.createJPEGStream(opts);
};
}
@ -8069,7 +8076,7 @@ fabric.BaseBrush = fabric.util.createClass(/** @lends fabric.BaseBrush.prototype
color: 'rgb(0, 0, 0)',
/**
* Width of a brush
* Width of a brush, has to be a Number, no string literals
* @type Number
* @default
*/
@ -8975,6 +8982,13 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
*/
selectionLineWidth: 1,
/**
* Select only shapes that are fully contained in the dragged selection rectangle.
* @type Boolean
* @default
*/
selectionFullyContained: false,
/**
* Default cursor value used when hovering over an object on canvas
* @type String
@ -9164,6 +9178,9 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
this.clearContext(this.contextTop);
this.contextTopDirty = false;
}
if (this.isDrawingMode && this._isCurrentlyDrawing) {
this.freeDrawingBrush && this.freeDrawingBrush._render();
}
var canvasToDrawOn = this.contextContainer;
this.renderCanvas(canvasToDrawOn, this._chooseObjectsToRender());
return this;
@ -10669,8 +10686,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
* @param {Event} e Event object fired on mousedown
*/
_onDoubleClick: function (e) {
var target;
this._handleEvent(e, 'dblclick', target);
this._handleEvent(e, 'dblclick');
},
/**
@ -10951,19 +10967,19 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
*/
__onMouseDown: function (e) {
var target = this.findTarget(e);
var target = this.findTarget(e) || null;
// if right click just fire events
if (checkClick(e, RIGHT_CLICK)) {
if (this.fireRightClick) {
this._handleEvent(e, 'down', target ? target : null, RIGHT_CLICK);
this._handleEvent(e, 'down', target, RIGHT_CLICK);
}
return;
}
if (checkClick(e, MIDDLE_CLICK)) {
if (this.fireMiddleClick) {
this._handleEvent(e, 'down', target ? target : null, MIDDLE_CLICK);
this._handleEvent(e, 'down', target, MIDDLE_CLICK);
}
return;
}
@ -11010,7 +11026,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
this._setupCurrentTransform(e, target);
}
}
this._handleEvent(e, 'down', target ? target : null);
this._handleEvent(e, 'down', target);
// we must renderAll so that we update the visuals
shouldRender && this.requestRenderAll();
},
@ -11101,7 +11117,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
this.renderTop();
}
else if (!this._currentTransform) {
target = this.findTarget(e);
target = this.findTarget(e) || null;
this._setCursorFromEvent(e, target);
this._fireOverOutEvents(target, e);
}
@ -11472,6 +11488,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
y2 = y1 + this._groupSelector.top,
selectionX1Y1 = new fabric.Point(min(x1, x2), min(y1, y2)),
selectionX2Y2 = new fabric.Point(max(x1, x2), max(y1, y2)),
allowIntersect = !this.selectionFullyContained,
isClick = x1 === x2 && y1 === y2;
// we iterate reverse order to collect top first in case of click.
for (var i = this._objects.length; i--; ) {
@ -11481,10 +11498,10 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
continue;
}
if (currentObject.intersectsWithRect(selectionX1Y1, selectionX2Y2) ||
if ((allowIntersect && currentObject.intersectsWithRect(selectionX1Y1, selectionX2Y2)) ||
currentObject.isContainedWithinRect(selectionX1Y1, selectionX2Y2) ||
currentObject.containsPoint(selectionX1Y1) ||
currentObject.containsPoint(selectionX2Y2)
(allowIntersect && currentObject.containsPoint(selectionX1Y1)) ||
(allowIntersect && currentObject.containsPoint(selectionX2Y2))
) {
group.push(currentObject);
@ -14355,8 +14372,8 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
prefix = this.group.transformMatrixKey(skipGroup) + sep;
};
return prefix + this.top + sep + this.left + sep + this.scaleX + sep + this.scaleY +
sep + this.skewX + sep + this.skewY + sep + this.angle + sep + this.flipX + sep + this.flipY +
sep + this.width + sep + this.height;
sep + this.skewX + sep + this.skewY + sep + this.angle +
sep + this.width + sep + this.height + sep + this.strokeWidth + this.flipX + this.flipY;
},
/**
@ -15055,7 +15072,6 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot
ctx.beginPath();
ctx.moveTo(0, rotateHeight);
ctx.lineTo(0, rotateHeight - rotatingPointOffset);
ctx.closePath();
ctx.stroke();
}
@ -15924,16 +15940,6 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot
cacheProperties: fabric.Object.prototype.cacheProperties.concat('radius'),
/**
* Constructor
* @param {Object} [options] Options object
* @return {fabric.Circle} thisArg
*/
initialize: function(options) {
this.callSuper('initialize', options);
this.set('radius', options && options.radius || 0);
},
/**
* @private
* @param {String} key
@ -16128,15 +16134,18 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot
type: 'triangle',
/**
* Constructor
* @param {Object} [options] Options object
* @return {Object} thisArg
* Width is set to 100 to compensate the old initialize code that was setting it to 100
* @type Number
* @default
*/
initialize: function(options) {
this.callSuper('initialize', options);
this.set('width', options && options.width || 100)
.set('height', options && options.height || 100);
},
width: 100,
/**
* Height is set to 100 to compensate the old initialize code that was setting it to 100
* @type Number
* @default
*/
height: 100,
/**
* @private
@ -18792,9 +18801,9 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot
initialize: function(element, options) {
options || (options = { });
this.filters = [];
this.cacheKey = 'texture' + fabric.Object.__uid++;
this.callSuper('initialize', options);
this._initElement(element, options);
this.cacheKey = 'texture' + fabric.Object.__uid++;
},
/**
@ -18832,6 +18841,21 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot
return this;
},
/**
* Delete cacheKey if we have a webGlBackend
* delete reference to image elements
*/
dispose: function() {
var backend = fabric.filterBackend;
if (backend && backend.evictCachesForKey) {
backend.evictCachesForKey(this.cacheKey);
backend.evictCachesForKey(this.cacheKey + '_filtered');
}
this._originalElement = undefined;
this._element = undefined;
this._filteredEl = undefined;
},
/**
* Sets crossOrigin value (on an instance and corresponding image element)
* @return {fabric.Image} thisArg
@ -21448,15 +21472,15 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) {
* @class fabric.Image.filters.RemoveColor
* @memberOf fabric.Image.filters
* @extends fabric.Image.filters.BaseFilter
* @see {@link fabric.Image.filters.RemoveWhite#initialize} for constructor definition
* @see {@link fabric.Image.filters.RemoveColor#initialize} for constructor definition
* @see {@link http://fabricjs.com/image-filters|ImageFilters demo}
* @example
* var filter = new fabric.Image.filters.RemoveColor({
* threshold: 40,
* distance: 140
* threshold: 0.2,
* });
* object.filters.push(filter);
* object.applyFilters(canvas.renderAll.bind(canvas));
* object.applyFilters();
* canvas.renderAll();
*/
filters.RemoveColor = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.RemoveColor.prototype */ {
@ -21467,6 +21491,11 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) {
*/
type: 'RemoveColor',
/**
* Color to remove, in any format understood by fabric.Color.
* @param {String} type
* @default
*/
color: '#FFFFFF',
/**
@ -24319,10 +24348,17 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) {
charsToRender = '',
charBox,
boxWidth = 0,
timeToRender;
timeToRender,
shortCut = !isJustify && this.isEmptyStyles(lineIndex);
ctx.save();
top -= lineHeight * this._fontSizeFraction / this.lineHeight;
if (shortCut) {
// render all the line in one pass without checking
this._renderChar(method, ctx, lineIndex, 0, this.textLines[lineIndex], left, top, lineHeight);
ctx.restore();
return;
}
for (var i = 0, len = line.length - 1; i <= len; i++) {
timeToRender = i === len || this.charSpacing;
charsToRender += line[i];
@ -26270,13 +26306,13 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) {
if (lineStart !== lineEnd) {
// step1 remove the trailing of lineStart
if (this.styles[lineStart]) {
for (i = charStart; i < this._textLines[lineStart].length; i++) {
for (i = charStart; i < this._unwrappedTextLines[lineStart].length; i++) {
delete this.styles[lineStart][i];
}
}
// step2 move the trailing of lineEnd to lineStart if needed
if (this.styles[lineEnd]) {
for (i = charEnd; i < this._textLines[lineEnd].length; i++) {
for (i = charEnd; i < this._unwrappedTextLines[lineEnd].length; i++) {
styleObj = this.styles[lineEnd][i];
if (styleObj) {
this.styles[lineStart] || (this.styles[lineStart] = { });
@ -26464,7 +26500,12 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) {
linesLenght && this.insertNewlineStyleObject(
cursorLoc.lineIndex, cursorLoc.charIndex + addedLines[0], linesLenght);
for (var i = 1; i < linesLenght; i++) {
this.insertCharStyleObject(cursorLoc.lineIndex + i, 0, addedLines[i], copiedStyle);
if (addedLines[i] > 0) {
this.insertCharStyleObject(cursorLoc.lineIndex + i, 0, addedLines[i], copiedStyle);
}
else if (copiedStyle) {
this.styles[cursorLoc.lineIndex + i][0] = copiedStyle[0];
}
copiedStyle = copiedStyle && copiedStyle.slice(addedLines[i] + 1);
}
// we use i outside the loop to get it like linesLength
@ -27353,11 +27394,42 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot
this._text.splice(start, end - start);
this.text = this._text.join('');
this.set('dirty', true);
this._removeExtraneousStyles();
if (this._shouldClearDimensionCache()) {
this.initDimensions();
this.setCoords();
}
this._removeExtraneousStyles();
},
/**
* insert characters at start position, before start position.
* start equal 1 it means the text get inserted between actual grapheme 0 and 1
* if style array is provided, it must be as the same length of text in graphemes
* if end is provided and is bigger than start, old text is replaced.
* start/end ar per grapheme position in _text array.
*
* @param {String} text text to insert
* @param {Array} style array of style objects
* @param {Number} start
* @param {Number} end default to start + 1
*/
insertChars: function(text, style, start, end) {
if (typeof end === 'undefined') {
end = start;
}
if (end > start) {
this.removeStyleFromTo(start, end);
}
var graphemes = fabric.util.string.graphemeSplit(text);
this.insertNewStyleBlock(graphemes, start, style);
this._text = [].concat(this._text.slice(0, start), graphemes, this._text.slice(end));
this.text = this._text.join('');
this.set('dirty', true);
if (this._shouldClearDimensionCache()) {
this.initDimensions();
this.setCoords();
}
this._removeExtraneousStyles();
},
});
@ -27412,9 +27484,9 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot
(this.fontStyle ? 'font-style="' + this.fontStyle + '" ' : ''),
(this.fontWeight ? 'font-weight="' + this.fontWeight + '" ' : ''),
(textDecoration ? 'text-decoration="' + textDecoration + '" ' : ''),
'style="', this.getSvgStyles(noShadow), '"', this.addPaintOrder(), ' >\n',
'style="', this.getSvgStyles(noShadow), '"', this.addPaintOrder(), ' >',
textAndBg.textSpans.join(''),
'\t\t</text>\n',
'</text>\n',
'\t</g>\n'
);
},
@ -27456,11 +27528,11 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot
fillStyles = styleProps ? 'style="' + styleProps + '"' : '';
return [
'\t\t\t<tspan x="', toFixed(left, NUM_FRACTION_DIGITS), '" y="',
'<tspan x="', toFixed(left, NUM_FRACTION_DIGITS), '" y="',
toFixed(top, NUM_FRACTION_DIGITS), '" ',
fillStyles, '>',
fabric.util.string.escapeXml(_char),
'</tspan>\n'
'</tspan>'
].join('');
},

2
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.

110
dist/fabric.require.js vendored
View file

@ -1,5 +1,5 @@
var fabric = fabric || {
version: "2.0.0-rc.3"
version: "2.0.0-rc.4"
};
if (typeof exports !== "undefined") {
@ -16,6 +16,7 @@ if (typeof document !== "undefined" && typeof window !== "undefined") {
}
});
fabric.jsdomImplForWrapper = require("jsdom/lib/jsdom/living/generated/utils").implForWrapper;
fabric.nodeCanvas = require("jsdom/lib/jsdom/utils").Canvas;
fabric.window = fabric.document.defaultView;
DOMParser = require("xmldom").DOMParser;
}
@ -1269,7 +1270,7 @@ fabric.CommonMethods = {
left += element.scrollLeft || 0;
top += element.scrollTop || 0;
}
if (element.nodeType === 1 && fabric.util.getElementStyle(element, "position") === "fixed") {
if (element.nodeType === 1 && element.style.position === "fixed") {
break;
}
}
@ -1367,6 +1368,10 @@ fabric.CommonMethods = {
}
fabric.util.getScript = getScript;
})();
function getNodeCanvas(element) {
var impl = fabric.jsdomImplForWrapper(element);
return impl._canvas || impl._image;
}
fabric.util.getById = getById;
fabric.util.toArray = toArray;
fabric.util.makeElement = makeElement;
@ -1375,6 +1380,7 @@ fabric.CommonMethods = {
fabric.util.getScrollLeftTop = getScrollLeftTop;
fabric.util.getElementOffset = getElementOffset;
fabric.util.getElementStyle = getElementStyle;
fabric.util.getNodeCanvas = getNodeCanvas;
})();
(function() {
@ -3551,6 +3557,9 @@ fabric.ElementsParser.prototype.checkIfDone = function() {
this._setCssDimension(prop, cssValue);
}
}
if (this._isCurrentlyDrawing) {
this.freeDrawingBrush && this.freeDrawingBrush._setBrushStyles();
}
this._initRetinaScaling();
this._setImageSmoothing();
this.calcOffset();
@ -3788,6 +3797,7 @@ fabric.ElementsParser.prototype.checkIfDone = function() {
},
_centerObject: function(object, center) {
object.setPositionByOrigin(center, "center", "center");
object.setCoords();
this.renderOnAddRemove && this.requestRenderAll();
return this;
},
@ -4079,7 +4089,10 @@ fabric.ElementsParser.prototype.checkIfDone = function() {
return this.renderOnAddRemove && this.requestRenderAll();
},
dispose: function() {
this._objects.length = 0;
this.forEachObject(function(object) {
object.dispose && object.dispose();
});
this._objects = [];
this.backgroundImage = null;
this.overlayImage = null;
this._iTextInstances = null;
@ -4130,11 +4143,11 @@ fabric.ElementsParser.prototype.checkIfDone = function() {
fabric.StaticCanvas.prototype.toJSON = fabric.StaticCanvas.prototype.toObject;
if (fabric.isLikelyNode) {
fabric.StaticCanvas.prototype.createPNGStream = function() {
var impl = fabric.jsdomImplForWrapper(this.lowerCanvasEl);
var impl = fabric.util.getNodeCanvas(this.lowerCanvasEl);
return impl && impl.createPNGStream();
};
fabric.StaticCanvas.prototype.createJPEGStream = function(opts) {
var impl = fabric.jsdomImplForWrapper(this.lowerCanvasEl);
var impl = fabric.util.getNodeCanvas(this.lowerCanvasEl);
return impl && impl.createJPEGStream(opts);
};
}
@ -4539,6 +4552,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, {
selectionDashArray: [],
selectionBorderColor: "rgba(255, 255, 255, 0.3)",
selectionLineWidth: 1,
selectionFullyContained: false,
hoverCursor: "move",
moveCursor: "move",
defaultCursor: "default",
@ -4593,6 +4607,9 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, {
this.clearContext(this.contextTop);
this.contextTopDirty = false;
}
if (this.isDrawingMode && this._isCurrentlyDrawing) {
this.freeDrawingBrush && this.freeDrawingBrush._render();
}
var canvasToDrawOn = this.contextContainer;
this.renderCanvas(canvasToDrawOn, this._chooseObjectsToRender());
return this;
@ -5477,8 +5494,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, {
return false;
},
_onDoubleClick: function(e) {
var target;
this._handleEvent(e, "dblclick", target);
this._handleEvent(e, "dblclick");
},
_onMouseDown: function(e) {
this.__onMouseDown(e);
@ -5635,16 +5651,16 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, {
this._handleEvent(e, "up");
},
__onMouseDown: function(e) {
var target = this.findTarget(e);
var target = this.findTarget(e) || null;
if (checkClick(e, RIGHT_CLICK)) {
if (this.fireRightClick) {
this._handleEvent(e, "down", target ? target : null, RIGHT_CLICK);
this._handleEvent(e, "down", target, RIGHT_CLICK);
}
return;
}
if (checkClick(e, MIDDLE_CLICK)) {
if (this.fireMiddleClick) {
this._handleEvent(e, "down", target ? target : null, MIDDLE_CLICK);
this._handleEvent(e, "down", target, MIDDLE_CLICK);
}
return;
}
@ -5681,7 +5697,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, {
this._setupCurrentTransform(e, target);
}
}
this._handleEvent(e, "down", target ? target : null);
this._handleEvent(e, "down", target);
shouldRender && this.requestRenderAll();
},
_beforeTransform: function(e, target) {
@ -5726,7 +5742,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, {
groupSelector.top = pointer.y - groupSelector.ey;
this.renderTop();
} else if (!this._currentTransform) {
target = this.findTarget(e);
target = this.findTarget(e) || null;
this._setCursorFromEvent(e, target);
this._fireOverOutEvents(target, e);
} else {
@ -5944,13 +5960,13 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, {
}
},
_collectObjects: function() {
var group = [], currentObject, x1 = this._groupSelector.ex, y1 = this._groupSelector.ey, x2 = x1 + this._groupSelector.left, y2 = y1 + this._groupSelector.top, selectionX1Y1 = new fabric.Point(min(x1, x2), min(y1, y2)), selectionX2Y2 = new fabric.Point(max(x1, x2), max(y1, y2)), isClick = x1 === x2 && y1 === y2;
var group = [], currentObject, x1 = this._groupSelector.ex, y1 = this._groupSelector.ey, x2 = x1 + this._groupSelector.left, y2 = y1 + this._groupSelector.top, selectionX1Y1 = new fabric.Point(min(x1, x2), min(y1, y2)), selectionX2Y2 = new fabric.Point(max(x1, x2), max(y1, y2)), allowIntersect = !this.selectionFullyContained, isClick = x1 === x2 && y1 === y2;
for (var i = this._objects.length; i--; ) {
currentObject = this._objects[i];
if (!currentObject || !currentObject.selectable || !currentObject.visible) {
continue;
}
if (currentObject.intersectsWithRect(selectionX1Y1, selectionX2Y2) || currentObject.isContainedWithinRect(selectionX1Y1, selectionX2Y2) || currentObject.containsPoint(selectionX1Y1) || currentObject.containsPoint(selectionX2Y2)) {
if (allowIntersect && currentObject.intersectsWithRect(selectionX1Y1, selectionX2Y2) || currentObject.isContainedWithinRect(selectionX1Y1, selectionX2Y2) || allowIntersect && currentObject.containsPoint(selectionX1Y1) || allowIntersect && currentObject.containsPoint(selectionX2Y2)) {
group.push(currentObject);
if (isClick) {
break;
@ -7174,7 +7190,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
if (!skipGroup && this.group) {
prefix = this.group.transformMatrixKey(skipGroup) + sep;
}
return prefix + this.top + sep + this.left + sep + this.scaleX + sep + this.scaleY + sep + this.skewX + sep + this.skewY + sep + this.angle + sep + this.flipX + sep + this.flipY + sep + this.width + sep + this.height;
return prefix + this.top + sep + this.left + sep + this.scaleX + sep + this.scaleY + sep + this.skewX + sep + this.skewY + sep + this.angle + sep + this.width + sep + this.height + sep + this.strokeWidth + this.flipX + this.flipY;
},
calcTransformMatrix: function(skipGroup) {
if (skipGroup) {
@ -7526,7 +7542,6 @@ fabric.util.object.extend(fabric.Object.prototype, {
ctx.beginPath();
ctx.moveTo(0, rotateHeight);
ctx.lineTo(0, rotateHeight - rotatingPointOffset);
ctx.closePath();
ctx.stroke();
}
ctx.restore();
@ -7919,10 +7934,6 @@ fabric.util.object.extend(fabric.Object.prototype, {
startAngle: 0,
endAngle: pi * 2,
cacheProperties: fabric.Object.prototype.cacheProperties.concat("radius"),
initialize: function(options) {
this.callSuper("initialize", options);
this.set("radius", options && options.radius || 0);
},
_set: function(key, value) {
this.callSuper("_set", key, value);
if (key === "radius") {
@ -7987,10 +7998,8 @@ fabric.util.object.extend(fabric.Object.prototype, {
}
fabric.Triangle = fabric.util.createClass(fabric.Object, {
type: "triangle",
initialize: function(options) {
this.callSuper("initialize", options);
this.set("width", options && options.width || 100).set("height", options && options.height || 100);
},
width: 100,
height: 100,
_render: function(ctx) {
var widthBy2 = this.width / 2, heightBy2 = this.height / 2;
ctx.beginPath();
@ -9251,9 +9260,9 @@ fabric.util.object.extend(fabric.Object.prototype, {
initialize: function(element, options) {
options || (options = {});
this.filters = [];
this.cacheKey = "texture" + fabric.Object.__uid++;
this.callSuper("initialize", options);
this._initElement(element, options);
this.cacheKey = "texture" + fabric.Object.__uid++;
},
getElement: function() {
return this._element;
@ -9275,6 +9284,16 @@ fabric.util.object.extend(fabric.Object.prototype, {
}
return this;
},
dispose: function() {
var backend = fabric.filterBackend;
if (backend && backend.evictCachesForKey) {
backend.evictCachesForKey(this.cacheKey);
backend.evictCachesForKey(this.cacheKey + "_filtered");
}
this._originalElement = undefined;
this._element = undefined;
this._filteredEl = undefined;
},
setCrossOrigin: function(value) {
this.crossOrigin = value;
this._element.crossOrigin = value;
@ -11627,9 +11646,14 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) {
ctx.restore();
},
_renderChars: function(method, ctx, line, left, top, lineIndex) {
var lineHeight = this.getHeightOfLine(lineIndex), isJustify = this.textAlign.indexOf("justify") !== -1, actualStyle, nextStyle, charsToRender = "", charBox, boxWidth = 0, timeToRender;
var lineHeight = this.getHeightOfLine(lineIndex), isJustify = this.textAlign.indexOf("justify") !== -1, actualStyle, nextStyle, charsToRender = "", charBox, boxWidth = 0, timeToRender, shortCut = !isJustify && this.isEmptyStyles(lineIndex);
ctx.save();
top -= lineHeight * this._fontSizeFraction / this.lineHeight;
if (shortCut) {
this._renderChar(method, ctx, lineIndex, 0, this.textLines[lineIndex], left, top, lineHeight);
ctx.restore();
return;
}
for (var i = 0, len = line.length - 1; i <= len; i++) {
timeToRender = i === len || this.charSpacing;
charsToRender += line[i];
@ -12717,12 +12741,12 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) {
var cursorStart = this.get2DCursorLocation(start, true), cursorEnd = this.get2DCursorLocation(end, true), lineStart = cursorStart.lineIndex, charStart = cursorStart.charIndex, lineEnd = cursorEnd.lineIndex, charEnd = cursorEnd.charIndex, i, styleObj;
if (lineStart !== lineEnd) {
if (this.styles[lineStart]) {
for (i = charStart; i < this._textLines[lineStart].length; i++) {
for (i = charStart; i < this._unwrappedTextLines[lineStart].length; i++) {
delete this.styles[lineStart][i];
}
}
if (this.styles[lineEnd]) {
for (i = charEnd; i < this._textLines[lineEnd].length; i++) {
for (i = charEnd; i < this._unwrappedTextLines[lineEnd].length; i++) {
styleObj = this.styles[lineEnd][i];
if (styleObj) {
this.styles[lineStart] || (this.styles[lineStart] = {});
@ -12856,7 +12880,11 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) {
}
linesLenght && this.insertNewlineStyleObject(cursorLoc.lineIndex, cursorLoc.charIndex + addedLines[0], linesLenght);
for (var i = 1; i < linesLenght; i++) {
this.insertCharStyleObject(cursorLoc.lineIndex + i, 0, addedLines[i], copiedStyle);
if (addedLines[i] > 0) {
this.insertCharStyleObject(cursorLoc.lineIndex + i, 0, addedLines[i], copiedStyle);
} else if (copiedStyle) {
this.styles[cursorLoc.lineIndex + i][0] = copiedStyle[0];
}
copiedStyle = copiedStyle && copiedStyle.slice(addedLines[i] + 1);
}
if (addedLines[i] > 0) {
@ -13386,11 +13414,29 @@ fabric.util.object.extend(fabric.IText.prototype, {
this._text.splice(start, end - start);
this.text = this._text.join("");
this.set("dirty", true);
this._removeExtraneousStyles();
if (this._shouldClearDimensionCache()) {
this.initDimensions();
this.setCoords();
}
this._removeExtraneousStyles();
},
insertChars: function(text, style, start, end) {
if (typeof end === "undefined") {
end = start;
}
if (end > start) {
this.removeStyleFromTo(start, end);
}
var graphemes = fabric.util.string.graphemeSplit(text);
this.insertNewStyleBlock(graphemes, start, style);
this._text = [].concat(this._text.slice(0, start), graphemes, this._text.slice(end));
this.text = this._text.join("");
this.set("dirty", true);
if (this._shouldClearDimensionCache()) {
this.initDimensions();
this.setCoords();
}
this._removeExtraneousStyles();
}
});
@ -13411,7 +13457,7 @@ fabric.util.object.extend(fabric.IText.prototype, {
},
_wrapSVGTextAndBg: function(markup, textAndBg) {
var noShadow = true, filter = this.getSvgFilter(), style = filter === "" ? "" : ' style="' + filter + '"', textDecoration = this.getSvgTextDecoration(this);
markup.push("\t<g ", this.getSvgId(), 'transform="', this.getSvgTransform(), this.getSvgTransformMatrix(), '"', style, ">\n", textAndBg.textBgRects.join(""), '\t\t<text xml:space="preserve" ', this.fontFamily ? 'font-family="' + this.fontFamily.replace(/"/g, "'") + '" ' : "", this.fontSize ? 'font-size="' + this.fontSize + '" ' : "", this.fontStyle ? 'font-style="' + this.fontStyle + '" ' : "", this.fontWeight ? 'font-weight="' + this.fontWeight + '" ' : "", textDecoration ? 'text-decoration="' + textDecoration + '" ' : "", 'style="', this.getSvgStyles(noShadow), '"', this.addPaintOrder(), " >\n", textAndBg.textSpans.join(""), "\t\t</text>\n", "\t</g>\n");
markup.push("\t<g ", this.getSvgId(), 'transform="', this.getSvgTransform(), this.getSvgTransformMatrix(), '"', style, ">\n", textAndBg.textBgRects.join(""), '\t\t<text xml:space="preserve" ', this.fontFamily ? 'font-family="' + this.fontFamily.replace(/"/g, "'") + '" ' : "", this.fontSize ? 'font-size="' + this.fontSize + '" ' : "", this.fontStyle ? 'font-style="' + this.fontStyle + '" ' : "", this.fontWeight ? 'font-weight="' + this.fontWeight + '" ' : "", textDecoration ? 'text-decoration="' + textDecoration + '" ' : "", 'style="', this.getSvgStyles(noShadow), '"', this.addPaintOrder(), " >", textAndBg.textSpans.join(""), "</text>\n", "\t</g>\n");
},
_getSVGTextAndBg: function(textTopOffset, textLeftOffset) {
var textSpans = [], textBgRects = [], height = textTopOffset, lineOffset;
@ -13431,7 +13477,7 @@ fabric.util.object.extend(fabric.IText.prototype, {
},
_createTextCharSpan: function(_char, styleDecl, left, top) {
var styleProps = this.getSvgSpanStyles(styleDecl, _char !== _char.trim()), fillStyles = styleProps ? 'style="' + styleProps + '"' : "";
return [ '\t\t\t<tspan x="', toFixed(left, NUM_FRACTION_DIGITS), '" y="', toFixed(top, NUM_FRACTION_DIGITS), '" ', fillStyles, ">", fabric.util.string.escapeXml(_char), "</tspan>\n" ].join("");
return [ '<tspan x="', toFixed(left, NUM_FRACTION_DIGITS), '" y="', toFixed(top, NUM_FRACTION_DIGITS), '" ', fillStyles, ">", fabric.util.string.escapeXml(_char), "</tspan>" ].join("");
},
_setSVGTextLineText: function(textSpans, lineIndex, textLeftOffset, textTopOffset) {
var lineHeight = this.getHeightOfLine(lineIndex), isJustify = this.textAlign.indexOf("justify") !== -1, actualStyle, nextStyle, charsToRender = "", charBox, style, boxWidth = 0, line = this._textLines[lineIndex], timeToRender;

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": "2.0.0-rc.3",
"version": "2.0.0-rc.4",
"author": "Juriy Zaytsev <kangax@gmail.com>",
"contributors": [
{
@ -47,7 +47,7 @@
"test": "node test.js",
"lint": "eslint --config .eslintrc.json src",
"lint_tests": "eslint test/unit --config .eslintrc_tests",
"export_dist_to_site": "cp dist/fabric.js ../fabricjs.com/lib/fabric.js && cp package.json ../fabricjs.com/lib/fabricinfo.json && cp -r src HEADER.js lib ../fabricjs.com/build/files/",
"export_dist_to_site": "cp dist/fabric.js ../fabricjs.com/lib/fabric.js && cp package.json ../fabricjs.com/lib/package.json && cp -r src HEADER.js lib ../fabricjs.com/build/files/",
"export_tests_to_site": "cp test/unit/*.js ../fabricjs.com/test/unit",
"all": "npm run build && npm run test && npm run lint && npm run lint_tests && npm run export_dist_to_site && npm run export_tests_to_site"
},