mirror of
https://github.com/Hopiu/fabric.js.git
synced 2026-05-09 22:34:43 +00:00
Textbox implementaion from Jaffer Haider, with one minor change in textbox_key_behavior
This commit is contained in:
parent
697d17bd70
commit
a1e578b137
8 changed files with 110 additions and 5 deletions
5
build.js
5
build.js
|
|
@ -244,6 +244,11 @@ var filesToInclude = [
|
|||
ifSpecifiedInclude('itext', 'src/mixins/itext_key_behavior.mixin.js'),
|
||||
ifSpecifiedInclude('itext', 'src/mixins/itext.svg_export.js'),
|
||||
|
||||
ifSpecifiedInclude('textbox', 'src/shapes/textbox.class.js'),
|
||||
ifSpecifiedInclude('textbox', 'src/mixins/textbox_behavior.mixin.js'),
|
||||
ifSpecifiedInclude('textbox', 'src/mixins/textbox_click_behavior.mixin.js'),
|
||||
ifSpecifiedInclude('textbox', 'src/mixins/textbox_key_behavior.mixin.js'),
|
||||
|
||||
ifSpecifiedInclude('node', 'src/node.js'),
|
||||
|
||||
ifSpecifiedAMDInclude(amdLib)
|
||||
|
|
|
|||
0
build.sh
Executable file → Normal file
0
build.sh
Executable file → Normal file
0
build_all
Executable file → Normal file
0
build_all
Executable file → Normal file
22
src/mixins/texbox_key_behavior.mixin.js
Normal file
22
src/mixins/texbox_key_behavior.mixin.js
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
fabric.util.object.extend(fabric.Textbox.prototype, /** @lends fabric.Textbox.prototype */ {
|
||||
/**
|
||||
* Overrides superclass function and adjusts cursor offset value because
|
||||
* lines do not necessarily end with a newline in Textbox.
|
||||
* @param {Event} e
|
||||
* @param {Boolean} isRight
|
||||
* @returns {Number}
|
||||
*/
|
||||
getDownCursorOffset: function(e, isRight) {
|
||||
return fabric.IText.prototype.getDownCursorOffset.apply(this, [e, isRight]) - 1;
|
||||
},
|
||||
/**
|
||||
* Overrides superclass function and adjusts cursor offset value because
|
||||
* lines do not necessarily end with a newline in Textbox.
|
||||
* @param {Event} e
|
||||
* @param {Boolean} isRight
|
||||
* @returns {Number}
|
||||
*/
|
||||
getUpCursorOffset: function(e, isRight) {
|
||||
return fabric.IText.prototype.getUpCursorOffset.apply(this, [e, isRight]) - 1;
|
||||
}
|
||||
});
|
||||
41
src/mixins/textbox_behavior.mixin.js
Normal file
41
src/mixins/textbox_behavior.mixin.js
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
(function() {
|
||||
|
||||
/**
|
||||
* Override _setObjectScale and add Textbox specific resizing behavior. Resizing
|
||||
* a Textbox doesn't scale text, it only changes width and makes text wrap automatically.
|
||||
*/
|
||||
var setObjectScaleOverridden = fabric.Canvas.prototype._setObjectScale;
|
||||
fabric.Canvas.prototype._setObjectScale = function(localMouse, transform,
|
||||
lockScalingX, lockScalingY, by, lockScalingFlip) {
|
||||
|
||||
var t = transform.target;
|
||||
if (t instanceof fabric.Textbox) {
|
||||
var w = t.width * ((localMouse.x / transform.scaleX) / (t.width + t.strokeWidth));
|
||||
if (w >= t.minWidth) {
|
||||
t.set('width', w);
|
||||
}
|
||||
}
|
||||
else {
|
||||
setObjectScaleOverridden.call(fabric.Canvas.prototype, localMouse, transform,
|
||||
lockScalingX, lockScalingY, by, lockScalingFlip);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets controls of this group to the Textbox's special configuration if
|
||||
* one is present in the group. Deletes _controlsVisibility otherwise, so that
|
||||
* it gets initialized to default value at runtime.
|
||||
*/
|
||||
fabric.Group.prototype._refreshControlsVisibility = function() {
|
||||
if (typeof fabric.Textbox === 'undefined') {
|
||||
return;
|
||||
}
|
||||
for (var i = this._objects.length; i--; ) {
|
||||
if (this._objects[i] instanceof fabric.Textbox) {
|
||||
this.setControlsVisibility(fabric.Textbox.getTextboxControlVisibility());
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
})();
|
||||
22
src/mixins/textbox_click_behavior.mixin.js
Normal file
22
src/mixins/textbox_click_behavior.mixin.js
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
(function() {
|
||||
var getNewSelectionStartFromOffsetOverriden = fabric.IText.prototype._getNewSelectionStartFromOffset;
|
||||
/**
|
||||
* Overrides the IText implementation and always sends lineIndex as 0 for Textboxes.
|
||||
* @param {Number} mouseOffset
|
||||
* @param {Number} prevWidth
|
||||
* @param {Number} width
|
||||
* @param {Number} index
|
||||
* @param {Number} lineIndex
|
||||
* @param {Number} jlen
|
||||
* @returns {Number}
|
||||
*/
|
||||
fabric.IText.prototype._getNewSelectionStartFromOffset = function(mouseOffset,
|
||||
prevWidth, width, index, lineIndex, jlen) {
|
||||
if (this instanceof fabric.Textbox) {
|
||||
lineIndex = 0;
|
||||
}
|
||||
return getNewSelectionStartFromOffsetOverriden
|
||||
.call(this, mouseOffset,
|
||||
prevWidth, width, index, lineIndex, jlen);
|
||||
};
|
||||
})();
|
||||
|
|
@ -59,14 +59,14 @@
|
|||
|
||||
/**
|
||||
* Index where text selection starts (or where cursor is when there is no selection)
|
||||
* @type Nubmer
|
||||
* @type Number
|
||||
* @default
|
||||
*/
|
||||
selectionStart: 0,
|
||||
|
||||
/**
|
||||
* Index where text selection ends
|
||||
* @type Nubmer
|
||||
* @type Number
|
||||
* @default
|
||||
*/
|
||||
selectionEnd: 0,
|
||||
|
|
@ -932,7 +932,7 @@
|
|||
* @param {CanvasRenderingContext2D} ctx Context to render on
|
||||
*/
|
||||
_getWidthOfChar: function(ctx, _char, lineIndex, charIndex) {
|
||||
if (this.textAlign === 'justify' && /\s/.test(_char)) {
|
||||
if (this.textAlign === 'justify' && this._reSpacesAndTabs.test(_char)) {
|
||||
return this._getWidthOfSpace(ctx, lineIndex);
|
||||
}
|
||||
|
||||
|
|
@ -1008,7 +1008,7 @@
|
|||
var line = this._textLines[lineIndex],
|
||||
wordsWidth = this._getWidthOfWords(ctx, line, lineIndex),
|
||||
widthDiff = this.width - wordsWidth,
|
||||
numSpaces = line.length - line.replace(/\s+/g, '').length,
|
||||
numSpaces = line.length - line.replace(this._reSpacesAndTabs, '').length,
|
||||
width = widthDiff / numSpaces;
|
||||
this.__widthOfSpace[lineIndex] = width;
|
||||
return width;
|
||||
|
|
|
|||
|
|
@ -59,6 +59,13 @@
|
|||
*/
|
||||
_reNewline: /\r?\n/,
|
||||
|
||||
/**
|
||||
* Use this regular expression to filter for whitespace that is not a new line.
|
||||
* Mostly used when text is 'justify' aligned.
|
||||
* @private
|
||||
*/
|
||||
_reSpacesAndTabs: /[ \t\r]+/g,
|
||||
|
||||
/**
|
||||
* Retrieves object's fontSize
|
||||
* @method getFontSize
|
||||
|
|
@ -329,7 +336,7 @@
|
|||
ctx = fabric.util.createCanvasElement().getContext('2d');
|
||||
this._setTextStyles(ctx);
|
||||
}
|
||||
this._textLines = this.text.split(this._reNewline);
|
||||
this._textLines = this._splitTextIntoLines();
|
||||
this._clearCache();
|
||||
var currentTextAlign = this.textAlign;
|
||||
this.textAlign = 'left';
|
||||
|
|
@ -798,6 +805,14 @@
|
|||
ctx.restore();
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the text as an array of lines.
|
||||
* @returns {Array} Lines in the text
|
||||
*/
|
||||
_splitTextIntoLines: function() {
|
||||
return this.text.split(this._reNewline);
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns object representation of an instance
|
||||
* @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output
|
||||
|
|
|
|||
Loading…
Reference in a new issue