Search code examples
javascripthtmlcsscanvasfabricjs

Fabric JS line height and char spacing on individual character


Is there a way to add char spacing and line height on individual characters? I have something working here for reference but not able to replicate same under development: https://www.papier.com/customise/spring-wildflowers-8451

Here is fiddle link: https://jsfiddle.net/tLy9eqj6/

var canvas=new fabric.Canvas('canv');

var iTextSample = new fabric.IText('hello\nworld', {
  left: 50,
  top: 50,
  fontFamily: 'Helvetica',
  fill: '#333',
  lineHeight: 1.1,
  styles: {
    0: {
      0: { textDecoration: 'underline', fontSize: 80 },
      1: { textBackgroundColor: 'red' }
    },
    1: {
      0: { textBackgroundColor: 'rgba(0,255,0,0.5)' },
      4: { fontSize: 20 }
    }
  }
});

canvas.add(iTextSample);
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/3.4.0/fabric.js"></script>

<canvas id="canv" width="250" height="300" style="border: 1px solid rgb(204, 204, 204); width: 400px; height: 400px; -webkit-user-select: none;"></canvas>


Solution

  • Here is fiddle link for individual charSpacing and lineHeight: https://jsfiddle.net/5tjoyazk/7/

    var canvas=new fabric.Canvas('canv');
    var i = 0
    var j=0
    var l=0
    fabric.Text.prototype.getStyleAtPosition=function(position, complete) {
    
          var loc = this.get2DCursorLocation(position),
              style = complete ? this.getCompleteStyleDeclaration(loc.lineIndex, loc.charIndex) :
                this._getStyleDeclaration(loc.lineIndex, loc.charIndex);
          return style || {};
        }
    
    function getStyle(object, styleName) {
      return (object.getStyleAtPosition && object.isEditing) ?
        object.getStyleAtPosition(object.selectionStart)[styleName] : object[styleName];
    }
    
    fabric.Text.prototype._getWidthOfCharSpacing= function() {
                //console.log("test",this.text.length)
                char=this.getStyleAtPosition(i)['charSp']
          if (typeof char !== 'undefined') {
                    if(this.text.length==i){
            i=0;
            }
            else
             i++;
            return char;
            //return this.fontSize * char / 1000;
            
          
            }  
                    if(this.text.length==i){
                i=0;
                }
              else
                        i++;
      
              return 0;
              
        };
    
    fabric.Text.prototype.getHeightOfLine=function(lineIndex) {
                lineh=this.getStyleAtPosition(i)['lheight']
          i++;
          if (this.__lineHeights[lineIndex]) {
            j++
            return this.__lineHeights[lineIndex];
          }
    
          var line = this._textLines[lineIndex],
              // char 0 is measured before the line cycle because it nneds to char
              // emptylines
              maxHeight = this.getHeightOfChar(lineIndex, 0);
              maxLheight=1
              
          for (var i = 0, len = line.length; i < len; i++) {
            maxHeight = Math.max(this.getHeightOfChar(lineIndex, i), maxHeight);
            if (typeof this.getStyleAtPosition(j)['lheight'] !=="undefined"){
            maxLheight=Math.max(this.getStyleAtPosition(j)['lheight'],maxLheight)}
            k=lineIndex;
            if( k!==l){
            j++
            
            }
    
            l=lineIndex;
            if (this.text.length == j){
            j=0;
            }
    
            j++;
    
          }
    
          return this.__lineHeights[lineIndex] =( maxHeight+maxLheight) * this.lineHeight * this._fontSizeMult;
        }
    
    var iTextSample = new fabric.IText('hello\nworld\nhello', {
      left: 50,
      top: 50,
      fontFamily: 'Helvetica',
      fill: '#333',
      lineHeight: 1,
      charSpacing:300,
      styles: {
        0: {
          0: { textDecoration: 'underline',fontSize:80,charSp:22,lheight:1 },
          1: { textBackgroundColor: 'red',fontSize: 75,charSp:10 },
          2: { textBackgroundColor: 'red',fontSize: 75,charSp:10,lheight:1 }
        },
        1: {
          0: { textBackgroundColor: 'rgba(0,255,0,0.5)',charSp:20 },
          1: { fontSize: 10,charSp:30 },
          4: { fontSize: 20,charSp:30,lheight:10}
        },
        2: {
          0: { textBackgroundColor: 'rgba(0,255,0,0.5)',charSp:20 },
          1: { fontSize: 10,charSp:30 },
          4: { fontSize: 20,charSp:30,lheight:20}
        }
      }
    });
    canvas.add(iTextSample);
    <script src="https://rawgit.com/kangax/fabric.js/master/dist/fabric.js"></script>
    <canvas id='canv' width=400 height=400></canvas>
    
    
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>