mirror of
https://github.com/Hopiu/fabric.js.git
synced 2026-04-29 01:34:42 +00:00
commit
935c1c3cd3
10 changed files with 206 additions and 227 deletions
|
|
@ -763,12 +763,12 @@
|
|||
_fireOverOutEvents: function(target, e) {
|
||||
if (target) {
|
||||
if (this._hoveredTarget !== target) {
|
||||
this.fire('mouse:over', { target: target, e: e });
|
||||
target.fire('mouseover');
|
||||
if (this._hoveredTarget) {
|
||||
this.fire('mouse:out', { target: this._hoveredTarget, e: e });
|
||||
this._hoveredTarget.fire('mouseout');
|
||||
}
|
||||
this.fire('mouse:over', { target: target, e: e });
|
||||
target.fire('mouseover');
|
||||
this._hoveredTarget = target;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,114 +1,119 @@
|
|||
/* _TO_SVG_START_ */
|
||||
fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.prototype */ {
|
||||
(function() {
|
||||
var toFixed = fabric.util.toFixed,
|
||||
NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS;
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_setSVGTextLineText: function(lineIndex, textSpans, height, textLeftOffset, textTopOffset, textBgRects) {
|
||||
if (!this.styles[lineIndex]) {
|
||||
this.callSuper('_setSVGTextLineText',
|
||||
lineIndex, textSpans, height, textLeftOffset, textTopOffset);
|
||||
}
|
||||
else {
|
||||
this._setSVGTextLineChars(
|
||||
lineIndex, textSpans, height, textLeftOffset, textBgRects);
|
||||
}
|
||||
},
|
||||
/* _TO_SVG_START_ */
|
||||
fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.prototype */ {
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_setSVGTextLineChars: function(lineIndex, textSpans, height, textLeftOffset, textBgRects) {
|
||||
|
||||
var chars = this._textLines[lineIndex].split(''),
|
||||
charOffset = 0,
|
||||
lineLeftOffset = this._getSVGLineLeftOffset(lineIndex) - this.width / 2,
|
||||
lineOffset = this._getSVGLineTopOffset(lineIndex),
|
||||
heightOfLine = this._getHeightOfLine(this.ctx, lineIndex);
|
||||
|
||||
for (var i = 0, len = chars.length; i < len; i++) {
|
||||
var styleDecl = this.styles[lineIndex][i] || { };
|
||||
|
||||
textSpans.push(
|
||||
this._createTextCharSpan(
|
||||
chars[i], styleDecl, lineLeftOffset, lineOffset.lineTop + lineOffset.offset, charOffset));
|
||||
|
||||
var charWidth = this._getWidthOfChar(this.ctx, chars[i], lineIndex, i);
|
||||
|
||||
if (styleDecl.textBackgroundColor) {
|
||||
textBgRects.push(
|
||||
this._createTextCharBg(
|
||||
styleDecl, lineLeftOffset, lineOffset.lineTop, heightOfLine, charWidth, charOffset));
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_setSVGTextLineText: function(lineIndex, textSpans, height, textLeftOffset, textTopOffset, textBgRects) {
|
||||
if (!this.styles[lineIndex]) {
|
||||
this.callSuper('_setSVGTextLineText',
|
||||
lineIndex, textSpans, height, textLeftOffset, textTopOffset);
|
||||
}
|
||||
else {
|
||||
this._setSVGTextLineChars(
|
||||
lineIndex, textSpans, height, textLeftOffset, textBgRects);
|
||||
}
|
||||
},
|
||||
|
||||
charOffset += charWidth;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_setSVGTextLineChars: function(lineIndex, textSpans, height, textLeftOffset, textBgRects) {
|
||||
|
||||
var chars = this._textLines[lineIndex],
|
||||
charOffset = 0,
|
||||
lineLeftOffset = this._getSVGLineLeftOffset(lineIndex) - this.width / 2,
|
||||
lineOffset = this._getSVGLineTopOffset(lineIndex),
|
||||
heightOfLine = this._getHeightOfLine(this.ctx, lineIndex);
|
||||
|
||||
for (var i = 0, len = chars.length; i < len; i++) {
|
||||
var styleDecl = this.styles[lineIndex][i] || { };
|
||||
|
||||
textSpans.push(
|
||||
this._createTextCharSpan(
|
||||
chars[i], styleDecl, lineLeftOffset, lineOffset.lineTop + lineOffset.offset, charOffset));
|
||||
|
||||
var charWidth = this._getWidthOfChar(this.ctx, chars[i], lineIndex, i);
|
||||
|
||||
if (styleDecl.textBackgroundColor) {
|
||||
textBgRects.push(
|
||||
this._createTextCharBg(
|
||||
styleDecl, lineLeftOffset, lineOffset.lineTop, heightOfLine, charWidth, charOffset));
|
||||
}
|
||||
|
||||
charOffset += charWidth;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_getSVGLineLeftOffset: function(lineIndex) {
|
||||
return fabric.util.toFixed(this._getLineLeftOffset(this.__lineWidths[lineIndex]), 2);
|
||||
},
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_getSVGLineTopOffset: function(lineIndex) {
|
||||
var lineTopOffset = 0, lastHeight = 0;
|
||||
for (var j = 0; j < lineIndex; j++) {
|
||||
lineTopOffset += this._getHeightOfLine(this.ctx, j);
|
||||
}
|
||||
lastHeight = this._getHeightOfLine(this.ctx, j);
|
||||
return {
|
||||
lineTop: lineTopOffset,
|
||||
offset: (this._fontSizeMult - this._fontSizeFraction) * lastHeight / (this.lineHeight * this._fontSizeMult)
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_createTextCharBg: function(styleDecl, lineLeftOffset, lineTopOffset, heightOfLine, charWidth, charOffset) {
|
||||
return [
|
||||
//jscs:disable validateIndentation
|
||||
'<rect fill="', styleDecl.textBackgroundColor,
|
||||
'" x="', toFixed(lineLeftOffset + charOffset, NUM_FRACTION_DIGITS),
|
||||
'" y="', toFixed(lineTopOffset - this.height/2, NUM_FRACTION_DIGITS),
|
||||
'" width="', toFixed(charWidth, NUM_FRACTION_DIGITS),
|
||||
'" height="', toFixed(heightOfLine / this.lineHeight, NUM_FRACTION_DIGITS),
|
||||
'"></rect>'
|
||||
//jscs:enable validateIndentation
|
||||
].join('');
|
||||
},
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_createTextCharSpan: function(_char, styleDecl, lineLeftOffset, lineTopOffset, charOffset) {
|
||||
|
||||
var fillStyles = this.getSvgStyles.call(fabric.util.object.extend({
|
||||
visible: true,
|
||||
fill: this.fill,
|
||||
stroke: this.stroke,
|
||||
type: 'text'
|
||||
}, styleDecl));
|
||||
|
||||
return [
|
||||
//jscs:disable validateIndentation
|
||||
'<tspan x="', lineLeftOffset + charOffset, '" y="',
|
||||
lineTopOffset - this.height/2, '" ',
|
||||
(styleDecl.fontFamily ? 'font-family="' + styleDecl.fontFamily.replace(/"/g, '\'') + '" ': ''),
|
||||
(styleDecl.fontSize ? 'font-size="' + styleDecl.fontSize + '" ': ''),
|
||||
(styleDecl.fontStyle ? 'font-style="' + styleDecl.fontStyle + '" ': ''),
|
||||
(styleDecl.fontWeight ? 'font-weight="' + styleDecl.fontWeight + '" ': ''),
|
||||
(styleDecl.textDecoration ? 'text-decoration="' + styleDecl.textDecoration + '" ': ''),
|
||||
'style="', fillStyles, '">',
|
||||
fabric.util.string.escapeXml(_char),
|
||||
'</tspan>'
|
||||
//jscs:enable validateIndentation
|
||||
].join('');
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_getSVGLineLeftOffset: function(lineIndex) {
|
||||
return fabric.util.toFixed(this._getLineLeftOffset(this.__lineWidths[lineIndex]), 2);
|
||||
},
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_getSVGLineTopOffset: function(lineIndex) {
|
||||
var lineTopOffset = 0, lastHeight = 0;
|
||||
for (var j = 0; j < lineIndex; j++) {
|
||||
lineTopOffset += this._getHeightOfLine(this.ctx, j);
|
||||
}
|
||||
lastHeight = this._getHeightOfLine(this.ctx, j);
|
||||
return {
|
||||
lineTop: lineTopOffset,
|
||||
offset: (this._fontSizeMult - this._fontSizeFraction) * lastHeight / (this.lineHeight * this._fontSizeMult)
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_createTextCharBg: function(styleDecl, lineLeftOffset, lineTopOffset, heightOfLine, charWidth, charOffset) {
|
||||
return [
|
||||
//jscs:disable validateIndentation
|
||||
'<rect fill="', styleDecl.textBackgroundColor,
|
||||
'" x="', lineLeftOffset + charOffset,
|
||||
'" y="', lineTopOffset - this.height/2,
|
||||
'" width="', charWidth,
|
||||
'" height="', heightOfLine / this.lineHeight,
|
||||
'"></rect>'
|
||||
//jscs:enable validateIndentation
|
||||
].join('');
|
||||
},
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_createTextCharSpan: function(_char, styleDecl, lineLeftOffset, lineTopOffset, charOffset) {
|
||||
|
||||
var fillStyles = this.getSvgStyles.call(fabric.util.object.extend({
|
||||
visible: true,
|
||||
fill: this.fill,
|
||||
stroke: this.stroke,
|
||||
type: 'text'
|
||||
}, styleDecl));
|
||||
|
||||
return [
|
||||
//jscs:disable validateIndentation
|
||||
'<tspan x="', lineLeftOffset + charOffset, '" y="',
|
||||
lineTopOffset - this.height/2, '" ',
|
||||
(styleDecl.fontFamily ? 'font-family="' + styleDecl.fontFamily.replace(/"/g, '\'') + '" ': ''),
|
||||
(styleDecl.fontSize ? 'font-size="' + styleDecl.fontSize + '" ': ''),
|
||||
(styleDecl.fontStyle ? 'font-style="' + styleDecl.fontStyle + '" ': ''),
|
||||
(styleDecl.fontWeight ? 'font-weight="' + styleDecl.fontWeight + '" ': ''),
|
||||
(styleDecl.textDecoration ? 'text-decoration="' + styleDecl.textDecoration + '" ': ''),
|
||||
'style="', fillStyles, '">',
|
||||
fabric.util.string.escapeXml(_char),
|
||||
'</tspan>'
|
||||
//jscs:enable validateIndentation
|
||||
].join('');
|
||||
}
|
||||
});
|
||||
/* _TO_SVG_END_ */
|
||||
});
|
||||
/* _TO_SVG_END_ */
|
||||
})();
|
||||
|
|
|
|||
|
|
@ -41,7 +41,6 @@
|
|||
// 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 || [];
|
||||
|
|
@ -279,8 +278,8 @@
|
|||
var selectedText = this.getSelectedText(),
|
||||
numNewLines = 0;
|
||||
|
||||
for (var i = 0, chars = selectedText.split(''), len = chars.length; i < len; i++) {
|
||||
if (chars[i] === '\n') {
|
||||
for (var i = 0, len = selectedText.length; i < len; i++) {
|
||||
if (selectedText[i] === '\n') {
|
||||
numNewLines++;
|
||||
}
|
||||
}
|
||||
|
|
@ -504,28 +503,21 @@
|
|||
* @private
|
||||
*/
|
||||
_removeCharsFromTo: function(start, end) {
|
||||
|
||||
var i = end;
|
||||
while (i !== start) {
|
||||
|
||||
var prevIndex = this.get2DCursorLocation(i).charIndex;
|
||||
i--;
|
||||
|
||||
var index = this.get2DCursorLocation(i).charIndex,
|
||||
isNewline = index > prevIndex;
|
||||
|
||||
if (isNewline) {
|
||||
this.removeStyleObject(isNewline, i + 1);
|
||||
}
|
||||
else {
|
||||
this.removeStyleObject(this.get2DCursorLocation(i).charIndex === 0, i);
|
||||
}
|
||||
|
||||
while (end !== start) {
|
||||
this._removeSingleCharAndStyle(start + 1);
|
||||
end--;
|
||||
}
|
||||
this.setSelectionStart(start);
|
||||
},
|
||||
|
||||
this.text = this.text.slice(0, start) +
|
||||
this.text.slice(end);
|
||||
this._clearCache();
|
||||
_removeSingleCharAndStyle: function(index) {
|
||||
var isBeginningOfLine = this.text[index - 1] === '\n',
|
||||
indexStyle = isBeginningOfLine ? index : index - 1;
|
||||
this.removeStyleObject(isBeginningOfLine, indexStyle);
|
||||
this.text = this.text.slice(0, index - 1) +
|
||||
this.text.slice(index);
|
||||
|
||||
this._textLines = this.text.split(this._reNewline);
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
@ -533,22 +525,17 @@
|
|||
* @param {String} _chars Characters to insert
|
||||
*/
|
||||
insertChars: function(_chars, useCopiedStyle) {
|
||||
var isEndOfLine = this.text.slice(this.selectionStart, this.selectionStart + 1) === '\n';
|
||||
|
||||
this.text = this.text.slice(0, this.selectionStart) +
|
||||
_chars +
|
||||
this.text.slice(this.selectionEnd);
|
||||
|
||||
if (this.selectionStart === this.selectionEnd) {
|
||||
this.insertStyleObjects(_chars, isEndOfLine, useCopiedStyle);
|
||||
if (this.selectionEnd - this.selectionStart > 1) {
|
||||
this._removeCharsFromTo(this.selectionStart, this.selectionEnd);
|
||||
this.setSelectionEnd(this.selectionStart);
|
||||
}
|
||||
// else if (this.selectionEnd - this.selectionStart > 1) {
|
||||
// TODO: replace styles properly
|
||||
// console.log('replacing MORE than 1 char');
|
||||
// }
|
||||
var isEndOfLine = this.text[this.selectionStart] === '\n';
|
||||
this.text = this.text.slice(0, this.selectionStart) +
|
||||
_chars + this.text.slice(this.selectionEnd);
|
||||
this.insertStyleObjects(_chars, isEndOfLine, useCopiedStyle);
|
||||
this.setSelectionStart(this.selectionStart + _chars.length);
|
||||
this.setSelectionEnd(this.selectionStart);
|
||||
this._clearCache();
|
||||
|
||||
this.canvas && this.canvas.renderAll();
|
||||
|
||||
this.setCoords();
|
||||
|
|
@ -683,6 +670,7 @@
|
|||
this.styles[numericLine + offset] = clonedStyles[numericLine];
|
||||
}
|
||||
}
|
||||
//TODO: evaluate if delete old style lines with offset -1
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
@ -713,14 +701,14 @@
|
|||
}
|
||||
|
||||
this.shiftLineStyles(lineIndex, -1);
|
||||
|
||||
}
|
||||
else {
|
||||
var currentLineStyles = this.styles[lineIndex];
|
||||
|
||||
if (currentLineStyles) {
|
||||
var offset = this.selectionStart === this.selectionEnd ? -1 : 0;
|
||||
delete currentLineStyles[charIndex + offset];
|
||||
// console.log('deleting', lineIndex, charIndex + offset);
|
||||
delete currentLineStyles[charIndex];
|
||||
//console.log('deleting', lineIndex, charIndex + offset);
|
||||
}
|
||||
|
||||
var currentLineStylesCloned = clone(currentLineStyles);
|
||||
|
|
|
|||
|
|
@ -188,7 +188,7 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot
|
|||
line;
|
||||
|
||||
for (var i = 0, len = this._textLines.length; i < len; i++) {
|
||||
line = this._textLines[i].split('');
|
||||
line = this._textLines[i];
|
||||
height += this._getHeightOfLine(this.ctx, i) * this.scaleY;
|
||||
|
||||
var widthOfLine = this._getLineWidth(this.ctx, i),
|
||||
|
|
@ -198,15 +198,15 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot
|
|||
|
||||
if (this.flipX) {
|
||||
// when oject is horizontally flipped we reverse chars
|
||||
// we should reverse also style or do not revers at all.
|
||||
this._textLines[i] = line.reverse().join('');
|
||||
}
|
||||
|
||||
for (var j = 0, jlen = line.length; j < jlen; j++) {
|
||||
|
||||
var _char = line[j];
|
||||
prevWidth = width;
|
||||
|
||||
width += this._getWidthOfChar(this.ctx, _char, i, this.flipX ? jlen - j : j) *
|
||||
width += this._getWidthOfChar(this.ctx, line[j], i, this.flipX ? jlen - j : j) *
|
||||
this.scaleX;
|
||||
|
||||
if (height <= mouseOffset.y || width <= mouseOffset.x) {
|
||||
|
|
|
|||
|
|
@ -170,28 +170,23 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot
|
|||
*/
|
||||
getDownCursorOffset: function(e, isRight) {
|
||||
var selectionProp = isRight ? this.selectionEnd : this.selectionStart,
|
||||
_char, lineLeftOffset,
|
||||
textBeforeCursor = this.text.slice(0, selectionProp),
|
||||
textAfterCursor = this.text.slice(selectionProp),
|
||||
|
||||
textOnSameLineBeforeCursor = textBeforeCursor.slice(textBeforeCursor.lastIndexOf('\n') + 1),
|
||||
textOnSameLineAfterCursor = textAfterCursor.match(/(.*)\n?/)[1],
|
||||
textOnNextLine = (textAfterCursor.match(/.*\n(.*)\n?/) || { })[1] || '',
|
||||
|
||||
cursorLocation = this.get2DCursorLocation(selectionProp);
|
||||
cursorLocation = this.get2DCursorLocation(selectionProp),
|
||||
_char, lineLeftOffset, lineIndex = cursorLocation.lineIndex,
|
||||
textOnSameLineBeforeCursor = this._textLines[lineIndex].slice(0, cursorLocation.charIndex),
|
||||
textOnSameLineAfterCursor = this._textLines[lineIndex].slice(cursorLocation.charIndex),
|
||||
textOnNextLine = this._textLines[lineIndex + 1] || '';
|
||||
|
||||
// if on last line, down cursor goes to end of line
|
||||
if (cursorLocation.lineIndex === this._textLines.length - 1 || e.metaKey || e.keyCode === 34) {
|
||||
if (lineIndex === this._textLines.length - 1 || e.metaKey || e.keyCode === 34) {
|
||||
|
||||
// move to the end of a text
|
||||
return this.text.length - selectionProp;
|
||||
}
|
||||
|
||||
var widthOfSameLineBeforeCursor = this._getLineWidth(this.ctx, cursorLocation.lineIndex);
|
||||
var widthOfSameLineBeforeCursor = this._getLineWidth(this.ctx, lineIndex);
|
||||
lineLeftOffset = this._getLineLeftOffset(widthOfSameLineBeforeCursor);
|
||||
|
||||
var widthOfCharsOnSameLineBeforeCursor = lineLeftOffset,
|
||||
lineIndex = cursorLocation.lineIndex;
|
||||
var widthOfCharsOnSameLineBeforeCursor = lineLeftOffset;
|
||||
|
||||
for (var i = 0, len = textOnSameLineBeforeCursor.length; i < len; i++) {
|
||||
_char = textOnSameLineBeforeCursor[i];
|
||||
|
|
@ -314,20 +309,19 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot
|
|||
*/
|
||||
getUpCursorOffset: function(e, isRight) {
|
||||
var selectionProp = isRight ? this.selectionEnd : this.selectionStart,
|
||||
cursorLocation = this.get2DCursorLocation(selectionProp);
|
||||
cursorLocation = this.get2DCursorLocation(selectionProp),
|
||||
lineIndex = cursorLocation.lineIndex;
|
||||
// if on first line, up cursor goes to start of line
|
||||
if (cursorLocation.lineIndex === 0 || e.metaKey || e.keyCode === 33) {
|
||||
if (lineIndex === 0 || e.metaKey || e.keyCode === 33) {
|
||||
return selectionProp;
|
||||
}
|
||||
|
||||
var textBeforeCursor = this.text.slice(0, selectionProp),
|
||||
textOnSameLineBeforeCursor = textBeforeCursor.slice(textBeforeCursor.lastIndexOf('\n') + 1),
|
||||
textOnPreviousLine = (textBeforeCursor.match(/\n?(.*)\n.*$/) || {})[1] || '',
|
||||
var textOnSameLineBeforeCursor = this._textLines[lineIndex].slice(0, cursorLocation.charIndex),
|
||||
textOnPreviousLine = this._textLines[lineIndex - 1] || '',
|
||||
_char,
|
||||
widthOfSameLineBeforeCursor = this._getLineWidth(this.ctx, cursorLocation.lineIndex),
|
||||
lineLeftOffset = this._getLineLeftOffset(widthOfSameLineBeforeCursor),
|
||||
widthOfCharsOnSameLineBeforeCursor = lineLeftOffset,
|
||||
lineIndex = cursorLocation.lineIndex;
|
||||
widthOfCharsOnSameLineBeforeCursor = lineLeftOffset;
|
||||
|
||||
for (var i = 0, len = textOnSameLineBeforeCursor.length; i < len; i++) {
|
||||
_char = textOnSameLineBeforeCursor[i];
|
||||
|
|
@ -513,11 +507,6 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot
|
|||
else {
|
||||
this._selectionDirection = 'left';
|
||||
this._moveLeft(e, 'selectionStart');
|
||||
|
||||
// increase selection by one if it's a newline
|
||||
if (this.text.charAt(this.selectionStart) === '\n') {
|
||||
this.setSelectionStart(this.selectionStart - 1);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
|
@ -554,11 +543,6 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot
|
|||
else {
|
||||
this._selectionDirection = 'right';
|
||||
this._moveRight(e, 'selectionEnd');
|
||||
|
||||
// increase selection by one if it's a newline
|
||||
if (this.text.charAt(this.selectionEnd - 1) === '\n') {
|
||||
this.setSelectionEnd(this.selectionEnd + 1);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
|
@ -608,29 +592,26 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot
|
|||
* @param {Event} e Event object
|
||||
*/
|
||||
_removeCharsNearCursor: function(e) {
|
||||
if (this.selectionStart !== 0) {
|
||||
if (this.selectionStart === 0) {
|
||||
return;
|
||||
}
|
||||
if (e.metaKey) {
|
||||
// remove all till the start of current line
|
||||
var leftLineBoundary = this.findLineBoundaryLeft(this.selectionStart);
|
||||
|
||||
if (e.metaKey) {
|
||||
// remove all till the start of current line
|
||||
var leftLineBoundary = this.findLineBoundaryLeft(this.selectionStart);
|
||||
this._removeCharsFromTo(leftLineBoundary, this.selectionStart);
|
||||
this.setSelectionStart(leftLineBoundary);
|
||||
}
|
||||
else if (e.altKey) {
|
||||
// remove all till the start of current word
|
||||
var leftWordBoundary = this.findWordBoundaryLeft(this.selectionStart);
|
||||
|
||||
this._removeCharsFromTo(leftLineBoundary, this.selectionStart);
|
||||
this.setSelectionStart(leftLineBoundary);
|
||||
}
|
||||
else if (e.altKey) {
|
||||
// remove all till the start of current word
|
||||
var leftWordBoundary = this.findWordBoundaryLeft(this.selectionStart);
|
||||
|
||||
this._removeCharsFromTo(leftWordBoundary, this.selectionStart);
|
||||
this.setSelectionStart(leftWordBoundary);
|
||||
}
|
||||
else {
|
||||
var isBeginningOfLine = this.text.slice(this.selectionStart - 1, this.selectionStart) === '\n';
|
||||
this.removeStyleObject(isBeginningOfLine);
|
||||
this.setSelectionStart(this.selectionStart - 1);
|
||||
this.text = this.text.slice(0, this.selectionStart) +
|
||||
this.text.slice(this.selectionStart + 1);
|
||||
}
|
||||
this._removeCharsFromTo(leftWordBoundary, this.selectionStart);
|
||||
this.setSelectionStart(leftWordBoundary);
|
||||
}
|
||||
else {
|
||||
this._removeSingleCharAndStyle(this.selectionStart);
|
||||
this.setSelectionStart(this.selectionStart - 1);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -541,7 +541,7 @@
|
|||
var elements = descendants.filter(function(el) {
|
||||
reViewBoxTagNames.test(el.tagName) && addVBTransform(el, 0, 0);
|
||||
return reAllowedSVGTagNames.test(el.tagName) &&
|
||||
!hasAncestorWithNodeName(el, /^(?:pattern|defs|symbol)$/); // http://www.w3.org/TR/SVG/struct.html#DefsElement
|
||||
!hasAncestorWithNodeName(el, /^(?:pattern|defs|symbol|metadata)$/); // http://www.w3.org/TR/SVG/struct.html#DefsElement
|
||||
});
|
||||
|
||||
if (!elements || (elements && !elements.length)) {
|
||||
|
|
|
|||
|
|
@ -354,12 +354,19 @@
|
|||
if (typeof selectionStart === 'undefined') {
|
||||
selectionStart = this.selectionStart;
|
||||
}
|
||||
var textBeforeCursor = this.text.slice(0, selectionStart),
|
||||
linesBeforeCursor = textBeforeCursor.split(this._reNewline);
|
||||
|
||||
var len = this._textLines.length;
|
||||
for (var i = 0; i < len; i++) {
|
||||
if (selectionStart <= this._textLines[i].length) {
|
||||
return {
|
||||
lineIndex: i,
|
||||
charIndex: selectionStart
|
||||
};
|
||||
}
|
||||
selectionStart -= this._textLines[i].length + 1;
|
||||
}
|
||||
return {
|
||||
lineIndex: linesBeforeCursor.length - 1,
|
||||
charIndex: linesBeforeCursor[linesBeforeCursor.length - 1].length
|
||||
lineIndex: i - 1,
|
||||
charIndex: this._textLines[i - 1].length < selectionStart ? this._textLines[i - 1].length : selectionStart
|
||||
};
|
||||
},
|
||||
|
||||
|
|
@ -583,7 +590,6 @@
|
|||
// set proper line offset
|
||||
var lineHeight = this._getHeightOfLine(ctx, lineIndex),
|
||||
lineLeftOffset = this._getCachedLineOffset(lineIndex),
|
||||
chars = line.split(''),
|
||||
prevStyle,
|
||||
charsToRender = '';
|
||||
|
||||
|
|
@ -591,7 +597,7 @@
|
|||
|
||||
ctx.save();
|
||||
top -= lineHeight / this.lineHeight * this._fontSizeFraction;
|
||||
for (var i = 0, len = chars.length; i <= len; i++) {
|
||||
for (var i = 0, len = line.length; i <= len; i++) {
|
||||
prevStyle = prevStyle || this.getCurrentCharStyle(lineIndex, i);
|
||||
var thisStyle = this.getCurrentCharStyle(lineIndex, i + 1);
|
||||
|
||||
|
|
@ -600,7 +606,7 @@
|
|||
charsToRender = '';
|
||||
prevStyle = thisStyle;
|
||||
}
|
||||
charsToRender += chars[i];
|
||||
charsToRender += line[i];
|
||||
}
|
||||
|
||||
ctx.restore();
|
||||
|
|
|
|||
|
|
@ -6,7 +6,8 @@
|
|||
extend = fabric.util.object.extend,
|
||||
clone = fabric.util.object.clone,
|
||||
toFixed = fabric.util.toFixed,
|
||||
supportsLineDash = fabric.StaticCanvas.supports('setLineDash');
|
||||
supportsLineDash = fabric.StaticCanvas.supports('setLineDash'),
|
||||
NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS;
|
||||
|
||||
if (fabric.Text) {
|
||||
fabric.warn('fabric.Text is already defined');
|
||||
|
|
@ -889,9 +890,9 @@
|
|||
- textTopOffset + height - this.height / 2;
|
||||
textSpans.push(
|
||||
'<tspan x="',
|
||||
toFixed(textLeftOffset + this._getLineLeftOffset(this.__lineWidths[i]), 4), '" ',
|
||||
toFixed(textLeftOffset + this._getLineLeftOffset(this.__lineWidths[i]), NUM_FRACTION_DIGITS), '" ',
|
||||
'y="',
|
||||
toFixed(yPos, 4),
|
||||
toFixed(yPos, NUM_FRACTION_DIGITS),
|
||||
'" ',
|
||||
// doing this on <tspan> elements since setting opacity
|
||||
// on containing <text> one doesn't work in Illustrator
|
||||
|
|
@ -906,13 +907,13 @@
|
|||
'\t\t<rect ',
|
||||
this._getFillAttributes(this.textBackgroundColor),
|
||||
' x="',
|
||||
toFixed(textLeftOffset + this._getLineLeftOffset(this.__lineWidths[i]), 4),
|
||||
toFixed(textLeftOffset + this._getLineLeftOffset(this.__lineWidths[i]), NUM_FRACTION_DIGITS),
|
||||
'" y="',
|
||||
toFixed(height - this.height / 2, 4),
|
||||
toFixed(height - this.height / 2, NUM_FRACTION_DIGITS),
|
||||
'" width="',
|
||||
toFixed(this.__lineWidths[i], 4),
|
||||
toFixed(this.__lineWidths[i], NUM_FRACTION_DIGITS),
|
||||
'" height="',
|
||||
toFixed(this._getHeightOfLine(this.ctx, i) / this.lineHeight, 4),
|
||||
toFixed(this._getHeightOfLine(this.ctx, i) / this.lineHeight, NUM_FRACTION_DIGITS),
|
||||
'"></rect>\n');
|
||||
},
|
||||
|
||||
|
|
@ -922,13 +923,13 @@
|
|||
'\t\t<rect ',
|
||||
this._getFillAttributes(this.backgroundColor),
|
||||
' x="',
|
||||
toFixed(-this.width / 2, 4),
|
||||
toFixed(-this.width / 2, NUM_FRACTION_DIGITS),
|
||||
'" y="',
|
||||
toFixed(-this.height / 2, 4),
|
||||
toFixed(-this.height / 2, NUM_FRACTION_DIGITS),
|
||||
'" width="',
|
||||
toFixed(this.width, 4),
|
||||
toFixed(this.width, NUM_FRACTION_DIGITS),
|
||||
'" height="',
|
||||
toFixed(this.height, 4),
|
||||
toFixed(this.height, NUM_FRACTION_DIGITS),
|
||||
'"></rect>\n');
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -155,8 +155,6 @@
|
|||
createImageObject(function(image) {
|
||||
equal(image.crossOrigin, '', 'initial crossOrigin value should be set');
|
||||
|
||||
start();
|
||||
|
||||
var elImage = _createImageElement();
|
||||
elImage.crossOrigin = 'anonymous';
|
||||
image = new fabric.Image(elImage);
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@
|
|||
'globalCompositeOperation': 'source-over'
|
||||
};
|
||||
|
||||
var TEXT_SVG = '\t<g transform="translate(10 26.22)">\n\t\t<text font-family="Times New Roman" font-size="40" font-weight="normal" style="stroke: none; stroke-width: 1; stroke-dasharray: ; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;" ><tspan x="-10" y="8.984" fill="rgb(0,0,0)">x</tspan></text>\n\t</g>\n';
|
||||
var TEXT_SVG = '\t<g transform="translate(10 26.22)">\n\t\t<text font-family="Times New Roman" font-size="40" font-weight="normal" style="stroke: none; stroke-width: 1; stroke-dasharray: ; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;" ><tspan x="-10" y="8.98" fill="rgb(0,0,0)">x</tspan></text>\n\t</g>\n';
|
||||
|
||||
test('constructor', function() {
|
||||
ok(fabric.Text);
|
||||
|
|
|
|||
Loading…
Reference in a new issue