我想實現這個功能,並通過擴展_renderChar本https://jsfiddle.net/ghazaltaimur/bx0f4qpg/1/想出了。我做了一些補充。該代碼允許在所選文本上應用字母間距,而不是僅在整個對象上應用字母間距。如果要添加字母間距,則必須考慮迭代文本選擇,邊界框和光標位置。我也試圖涵蓋這些方面。可能有幾個問題仍然需要解決。
fabric.util.object.extend(fabric.IText.prototype, {
letterSpace: 0,
_renderChar: function(method, ctx, lineIndex, i, _char, left, top, lineHeight) {
var decl, charWidth, charHeight,
offset = this._fontSizeFraction * lineHeight/this.lineHeight;
if (this.styles && this.styles[lineIndex] && (decl = this.styles[lineIndex][i])) {
var shouldStroke = decl.stroke || this.stroke,
shouldFill = decl.fill || this.fill;
ctx.save();
charWidth = this._applyCharStylesGetWidth(ctx, _char, lineIndex, i, decl);
charHeight = this._getHeightOfChar(ctx, _char, lineIndex, i);
var chars = _char;
var characters = String.prototype.split.call(chars, '');
var charShift = 0;
var leftcharShift = 0;
var letterSpace;
for (var i = 0; i < chars.length; i++) {
var style = this.getCurrentCharStyle(lineIndex, i + 1);
letterSpace = style.letterSpace;
if (i > 0) {
charShift += parseInt(letterSpace) + parseInt(ctx.measureText(chars.charAt(i - 1)).width);
}
if (this.text.indexOf(chars) !== 0 && charShift === 0) {
charShift = this.text.indexOf(chars) * parseInt(letterSpace);
}
leftcharShift = parseInt(left) + parseInt(charShift);
if (shouldFill) {
ctx.fillText(chars.charAt(i), leftcharShift, top);
}
if (shouldStroke) {
ctx.strokeText(chars.charAt(i), leftcharShift, top);
}
}
this._renderCharDecoration(ctx, decl, left, top, offset, charWidth, charHeight);
ctx.restore();
ctx.translate(charWidth, 0);
} else {
charWidth = this._applyCharStylesGetWidth(ctx, _char, lineIndex, i);
var chars = _char;
var characters = String.prototype.split.call(chars, '');
var charShift = 0;
var leftcharShift = 0;
var letterSpace;
for (var i = 0; i < chars.length; i++) {
var style = this.getCurrentCharStyle(lineIndex, i + 1);
letterSpace = style.letterSpace;
if (i > 0) {
charShift += parseInt(letterSpace) + parseInt(ctx.measureText(chars.charAt(i - 1)).width);
}
if (this.text.indexOf(chars) !== 0 && charShift === 0) {
charShift = this.text.indexOf(chars) * parseInt(letterSpace);
}
leftcharShift = parseInt(left) + parseInt(charShift);
if (method === 'strokeText' && this.stroke) {
ctx[method](chars.charAt(i), leftcharShift, top);
}
if (method === 'fillText' && this.fill) {
ctx[method](chars.charAt(i), leftcharShift, top);
}
}
this._renderCharDecoration(ctx, null, left, top, offset, charWidth, this.fontSize);
ctx.translate(ctx.measureText(_char).width, 0);
}},
getCurrentCharStyle: function(lineIndex, charIndex) {
var style = this.styles[lineIndex] && this.styles[lineIndex][charIndex === 0 ? 0 : (charIndex - 1)];
return {
fontSize: style && style.fontSize || this.fontSize,
fill: style && style.fill || this.fill,
textBackgroundColor: style && style.textBackgroundColor || this.textBackgroundColor,
textDecoration: style && style.textDecoration || this.textDecoration,
fontFamily: style && style.fontFamily || this.fontFamily,
fontWeight: style && style.fontWeight || this.fontWeight,
fontStyle: style && style.fontStyle || this.fontStyle,
stroke: style && style.stroke || this.stroke,
strokeWidth: style && style.strokeWidth || this.strokeWidth,
letterSpace: style && style.letterSpace || this.letterSpace
};
},
_renderTextLine: function(method, ctx, line, left, top, lineIndex) {
// to "cancel" this.fontSize subtraction in fabric.Text#_renderTextLine
// the adding 0.05 is just to align text with itext by overlap test
if (!this.isEmptyStyles()) {
top += this.fontSize * (this._fontSizeFraction + 0.05);
}
this.callSuper('_renderTextLine', method, ctx, line, left, top, lineIndex);
},
_getWidthOfChar: function(ctx, _char, lineIndex, charIndex) {
if (this.textAlign === 'justify' && /\s/.test(_char)) {
return this._getWidthOfSpace(ctx, lineIndex);
}
var styleDeclaration = this._getStyleDeclaration(lineIndex, charIndex);
this._applyFontStyles(styleDeclaration);
var cacheProp = this._getCacheProp(_char, styleDeclaration);
var style = this.getCurrentCharStyle(lineIndex, charIndex);
var letterSpace = style.letterSpace;
if (this._charWidthsCache[cacheProp] && this.caching) {
return parseInt(this._charWidthsCache[cacheProp]) + parseInt(letterSpace);
} else if (ctx) {
ctx.save();
var width = this._applyCharStylesGetWidth(ctx, _char, lineIndex, charIndex);
width = parseInt(width) + parseInt(letterSpace);
ctx.restore();
return width;
}
},
});
// fabric js code
var canvas = new fabric.Canvas('fabric_canvas');
// add text
fabric.util.addListener(document.getElementById('addText'), 'click', function() {
var itext = new fabric.IText("Add text", {
left: 50,
top: 50
});
canvas.add(itext);
canvas.setActiveObject(itext);
var obj = canvas.getActiveObject();
var seletedText = obj.getSelectedText();
itext.selectAll();
itext.enterEditing();
if (obj.setSelectionStyles && obj.isEditing)
obj.setSelectionStyles({
letterSpace: 1
});
if (seletedText === "") {
obj.exitEditing();
}
canvas.renderAll();
});
// add letter spacing
fabric.util.addListener(document.getElementById('addLetterSpacing'), 'click', function() {
var activeObject = canvas.getActiveObject();
var seletedText = activeObject.getSelectedText();
if (seletedText === "") {
activeObject.selectAll();
activeObject.enterEditing();
}
if (activeObject.setSelectionStyles && activeObject.isEditing)
activeObject.setSelectionStyles({
letterSpace: 30
});
if (seletedText === "") {
activeObject.exitEditing();
}
var ctx = activeObject.ctx;
var textLines = activeObject.text.split(activeObject._reNewline);
var letterSpace = (activeObject.getSelectionStyles && activeObject.isEditing && activeObject.evented === true) ? activeObject.getSelectionStyles()["letterSpace"] : activeObject["letterSpace"];
activeObject.width = activeObject._getTextWidth(ctx, textLines, activeObject) + (activeObject.text.length * letterSpace);
activeObject.height = activeObject._getTextHeight(ctx, textLines, activeObject);
activeObject.callSuper('setCoords');
canvas.renderAll();
});
</code></pre>
[1]: https://jsfiddle.net/ghazaltaimur/bx0f4qpg/1/
你會告訴我如何使用擴展屬性。 –
正如我寫的,我改進了我的代碼。但是現在我已經在我的答案上覆制了它。但它爲我工作!我沒有使用不同的顏色 – webmak10
實際上我試圖在我的項目中使用我的代碼。但我不明白我將如何在客戶端使用它。 –