首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >fabric.IText到SVG为每个字符生成TSPAN

fabric.IText到SVG为每个字符生成TSPAN
EN

Stack Overflow用户
提问于 2015-08-12 14:57:33
回答 1查看 747关注 0票数 1

当没有对文本应用特殊格式时,我如何强迫IText对象生成单个文本<tspan>

当创建具有初始文本值的新fabric.IText()对象实例时,svg输出将如预期的那样。

例如:

代码语言:javascript
复制
    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);

一旦canvas.toSVG()被调用,将产生以下输出,这正是我所期望的。

代码语言:javascript
复制
<text font-family="helvetica" ...>
     <tspan x="-27" y="2.246" fill="#000000">{{variable2}}</tspan>
</text>

但是,当您编辑IText文本值时,它会生成一个文本对象,每个字符都有一个tspan。

将textObject在画布编辑器中的文本修改为"test {variable2}“会产生以下svg输出:

代码语言:javascript
复制
<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>

编辑:即使是以编程方式插入字符,这种行为仍然存在。

代码语言:javascript
复制
$scope.addVariable = function() {
    var activeObject = $scope.getSelected();
    if (activeObject.isEditing) {
        activeObject.insertChars('{{name}}');
    }
};

编辑:我认为这与插入字符时插入的复制样式有关。请参阅fabric.js

具体来说:activeObject.insertStyleObjects(_chars, isEndOfLine, activeObject.copiedStyles);

是否有一种方法可以插入字符而不添加样式?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-08-12 22:34:50

我修改了_setSVGTextLineChars in fabric.js以满足我的需要。

修改后的方法将所有字符按样式分组。如果当前样式与以前的样式不同,则定义新的分组。

对于每个组,使用相关的样式创建一个tspan。

我将在下面发布代码片段,直到其他人能够提供更好的答案为止。

代码语言:javascript
复制
    /**
     * @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));
            }
        }
    },
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31968814

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档