当特殊格式未应用于文本时,如何强制fabricjs IText对象生成单个文本fabric.IText()
?
使用初始文本值创建新的 var textObject = new fabric.IText('{{variable2}}', {
left: options.e.layerX,
top: options.e.layerY,
fontFamily: 'helvetica',
fontSize: 10,
angle: 0,
fill: '#000000',
scaleX: 1,
scaleY: 1,
fontWeight: '',
originX: 'left',
hasRotatingPoint: true,
centerTransform: true
});
canvas.add(textObject);
对象实例时,svg输出符合预期。
例如:
canvas.toSVG()
调用<text font-family="helvetica" ...>
<tspan x="-27" y="2.246" fill="#000000">{{variable2}}</tspan>
</text>
后生成以下输出,这是我所期望的。
<text xmlns="http://www.w3.org/2000/svg" font-family="helvetica" font-size="10" style="stroke: none; stroke-width: 1; stroke-dasharray: ; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: #000000; fill-rule: nonzero; opacity: 1;">
<tspan x="-37" y="2.2459999999999996" style="stroke: none; stroke-width: 0; stroke-dasharray: ; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: #000000; fill-rule: ; opacity: 1;">t</tspan>
<tspan x="-34" y="2.2459999999999996" style="stroke: none; stroke-width: 0; stroke-dasharray: ; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: #000000; fill-rule: ; opacity: 1;">e</tspan>
<tspan x="-28" y="2.2459999999999996" style="stroke: none; stroke-width: 0; stroke-dasharray: ; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: #000000; fill-rule: ; opacity: 1;">s</tspan>
<tspan x="-23" y="2.2459999999999996" style="stroke: none; stroke-width: 0; stroke-dasharray: ; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: #000000; fill-rule: ; opacity: 1;">t</tspan>
<tspan x="-20" y="2.2459999999999996" style="stroke: none; stroke-width: 0; stroke-dasharray: ; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: #000000; fill-rule: ; opacity: 1;"/>
<tspan x="-17" y="2.2459999999999996" style="stroke: none; stroke-width: 0; stroke-dasharray: ; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: #000000; fill-rule: ; opacity: 1;">{</tspan>
<tspan x="-14" y="2.2459999999999996" style="stroke: none; stroke-width: 0; stroke-dasharray: ; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: #000000; fill-rule: ; opacity: 1;">{</tspan>
<tspan x="-11" y="2.2459999999999996" style="stroke: none; stroke-width: 0; stroke-dasharray: ; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: #000000; fill-rule: ; opacity: 1;">v</tspan>
<tspan x="-6" y="2.2459999999999996" style="stroke: none; stroke-width: 0; stroke-dasharray: ; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: #000000; fill-rule: ; opacity: 1;">a</tspan>
<tspan x="0" y="2.2459999999999996" style="stroke: none; stroke-width: 0; stroke-dasharray: ; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: #000000; fill-rule: ; opacity: 1;">r</tspan>
<tspan x="3" y="2.2459999999999996" style="stroke: none; stroke-width: 0; stroke-dasharray: ; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: #000000; fill-rule: ; opacity: 1;">i</tspan>
<tspan x="5" y="2.2459999999999996" style="stroke: none; stroke-width: 0; stroke-dasharray: ; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: #000000; fill-rule: ; opacity: 1;">a</tspan>
<tspan x="11" y="2.2459999999999996" style="stroke: none; stroke-width: 0; stroke-dasharray: ; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: #000000; fill-rule: ; opacity: 1;">b</tspan>
<tspan x="17" y="2.2459999999999996" style="stroke: none; stroke-width: 0; stroke-dasharray: ; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: #000000; fill-rule: ; opacity: 1;">l</tspan>
<tspan x="19" y="2.2459999999999996" style="stroke: none; stroke-width: 0; stroke-dasharray: ; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: #000000; fill-rule: ; opacity: 1;">e</tspan>
<tspan x="25" y="2.2459999999999996" style="stroke: none; stroke-width: 0; stroke-dasharray: ; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: #000000; fill-rule: ; opacity: 1;">2</tspan>
<tspan x="31" y="2.2459999999999996" style="stroke: none; stroke-width: 0; stroke-dasharray: ; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: #000000; fill-rule: ; opacity: 1;">}</tspan>
<tspan x="34" y="2.2459999999999996" style="stroke: none; stroke-width: 0; stroke-dasharray: ; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: #000000; fill-rule: ; opacity: 1;">}</tspan>
</text>
但是,当您编辑IText文本值时,它会生成一个文本对象,每个字符都有一个tspan。
将画布编辑器中的textObject文本修改为&#34; test {{variable2}}&#34; 生成以下svg输出:
$scope.addVariable = function() {
var activeObject = $scope.getSelected();
if (activeObject.isEditing) {
activeObject.insertChars('{{name}}');
}
};
修改:即使以编程方式插入字符,仍然会遇到此问题。
activeObject.insertStyleObjects(_chars, isEndOfLine, activeObject.copiedStyles);
编辑:我认为它与插入字符时插入的复制样式有关。见fabric.js
具体做法是:
Remote Java Application
有没有办法在不添加样式的情况下插入字符?
答案 0 :(得分:5)
我修改了fabric.js中的_setSVGTextLineChars以满足我的需求。
修改后的方法按样式对所有字符进行分组。如果当前样式与先前样式不同,则定义新分组。
对于每个组,使用相关样式创建tspan。
我发布下面的代码片段,直到其他人可以提供更好的答案。
/**
* @private
*/
_setSVGTextLineChars: function (lineIndex, textSpans, height, textLeftOffset, textBgRects) {
var chars = this._textLines[lineIndex].split(''),
lineLeftOffset = this._getSVGLineLeftOffset(lineIndex) - this.width / 2,
lineOffset = this._getSVGLineTopOffset(lineIndex),
heightOfLine = this._getHeightOfLine(this.ctx, lineIndex);
var previousStyleDecl = undefined;
var groups = [];
var currentGroup = undefined;
for (var i = 0, len = chars.length; i < len; i++) {
var styleDecl = this.styles[lineIndex][i] || {};
var a = JSON.stringify(previousStyleDecl), b = JSON.stringify(styleDecl);
if (!a) a = '';
if (!b) b = '';
var areEqualStyles = (a.split('').sort().join('') == b.split('').sort().join(''));
var charWidth = this._getWidthOfChar(this.ctx, chars[i], lineIndex, i);
// If the previous style is not defined,
// or, the current style does not match the previous style, then
// create a new grouping
if (previousStyleDecl == undefined || !areEqualStyles) {
var prevCharOffset = 0;
if (currentGroup != undefined) {
prevCharOffset = currentGroup.charWidth;
}
currentGroup = {
style: styleDecl,
text: chars[i],
charWidth: charWidth,
charOffset: prevCharOffset
}
groups.push(currentGroup);
}
// if the styles are equal, then add the current character to the group
if (areEqualStyles) {
if (currentGroup) {
currentGroup.text += chars[i];
currentGroup.charWidth += charWidth;
}
}
previousStyleDecl = styleDecl;
}
var charOffset = 0;
for (var j = 0; j < groups.length; j++) {
var group = groups[j];
charOffset += group.charOffset;
textSpans.push(this._createTextCharSpan(group.text, group.style, lineLeftOffset, lineOffset.lineTop + lineOffset.offset, charOffset));
if (group.style.textBackgroundColor) {
textBgRects.push(this._createTextCharBg(group.style, lineLeftOffset, lineOffset.lineTop, heightOfLine, group.charOffset, charOffset));
}
}
},