Fabric.js文本间距 [英] Fabricjs text spacing

查看:212
本文介绍了Fabric.js文本间距的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有重写fabricjs文本对象来使字母间距

I have override fabricjs Text object to make letter spacing

fabric.util.object.extend(fabric.Text.prototype, {
    letterSpace: 0,
    _renderChars: function(method, ctx, chars, left, top) {
        if(!this.letterSpace){
            ctx[method](chars, left, top);
            return;
        }
        var charShift = 0;
        for(var i = 0; i < chars.length; i++){
            if(i > 0){
                charShift += this.letterSpace + ctx.measureText(chars.charAt(i-1)).width;
           }
           ctx[method](chars.charAt(i), left+charShift, top);
       }
    },
    _getLineWidth: function(ctx, lineIndex) {
        if (this.__lineWidths[lineIndex]) {
            return this.__lineWidths[lineIndex];
        }
        var lineLength = this._textLines[lineIndex].length;
        var additionalSpaceSum = 0
        if(lineLength > 0){
            additionalSpaceSum = this.letterSpace * (lineLength - 1);
        }
        this.__lineWidths[lineIndex] = ctx.measureText(this._textLines[lineIndex]).width + additionalSpaceSum;
        return this.__lineWidths[lineIndex];
    }
});

间距很好,但是宽度不正确,如何改善宽度计算?

Spacing works good, but width is not correct, how to improve width calculation?

我已经在此问题中改进了代码,现在可以正常工作))

I have improve my code in this question and now it work fine))

很抱歉,没有显示以前的错误,但是在这里很难说明清楚的鳕鱼,我在这个问题上有正确的前面.

Sorry for not show previous mistake, but here is too difficult to make clear cod, and I have correct previous in this question.

但是我已经将其写为左对齐,如果您使用其他对齐方式,则需要对其进行更正.对我来说足够了

But I have write it for left text align, if you use different align you need correct it. For me it was enough

推荐答案

我尝试实现此功能,并提出了

I tried implementing this feature and came up with this https://jsfiddle.net/ghazaltaimur/bx0f4qpg/1/ by extending _renderChar. I have made a couple of additions. The code allows letter spacing to be applied on the selected text instead of only on the whole object.Plus itext selection ,bounding box and cursor position have to be taken into account if letter spacing is to be added. I have tried to cover these aspects as well. There might be a couple of issues which still need to be fixed.


    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);
        }

这篇关于Fabric.js文本间距的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆