Search code examples
fabricjserase

Display cursor line in place of erased character when iText erase in fabric js


I am using fabric js version 1.7.22 I am working on one project in which I need to add text and it's editing. When I add new iText in canvas and write some text and erase it. It shows me old cursor line in place of erased character,

I Can't generate this issue in fiddle So please check GIF. I don't know where I am wrong. Please Help Me.

enter image description here

My Itext added code is like this:

var text = new fabric.IText('Example heading', {
        left: 10,
        top: 10,
        fontFamily: 'Roboto-Regular',
        angle: 0,
        fontSize: fontSize,
        fill: '#000000',
        fontWeight: '',
        charSpacing: 0,
        shadow: {
            "color": "#000000",
            "blur": 0,
            "offsetX": 0,
            "offsetY": 0,
            "affectStroke": false
        },
        hasRotatingPoint: true
    });
    canvas.add(text);

this issue is caused due to text scaling. the solution is also applied in a fiddle. but if the canvas is in zoom-out mode then the issue will regenerate. I have Attach one fiddle for that :

https://jsfiddle.net/Mark_1998/ro8gc3zh/5/


Solution

  • When the IText cursor moves, fabric calls text._clearTextArea() to clear the canvas that draws the cursor. One possible solution would be to extend this area a little bit - just enough to remove the traces of the blinking cursor in all possible cases - by patching the fabric.IText.prototype._clearTextArea() method:

    fabric.IText.prototype._clearTextArea =  function(ctx) {
      // was 'this.width + 4'
      var width = this.width + this.fontSize * this.scaleX, height = this.height + 4;
      ctx.clearRect(-width / 2, -height / 2, width, height);
    }
    

    Here's your example with the patch applied:

    fabric.IText.prototype._clearTextArea =  function(ctx) {
      var width = this.width + this.fontSize * this.scaleX, height = this.height + 4;
      ctx.clearRect(-width / 2, -height / 2, width, height);
    }
    
    var canvas = window._canvas = new fabric.Canvas('c');
    
    var text = new fabric.IText('this is example text', {
      left: 20,
      top: 50,
      fill: 'red',
      scaleX: 0.5,
      fontFamily: 'verdana'
    });
    canvas.add(text);
    canvas.setActiveObject(text);
    canvas.getActiveObject().enterEditing();
    canvas.renderAll();
    <script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.22/fabric.js"></script>
    <h1>
      Try to erase text from end
    </h1>
    <canvas id="c" width="300" height="150"></canvas>

    This looks somewhat hacky, but it does the trick, for the lack of a better solution. A better way would be to back-port the IText from fabric v2 - this bug is fixed there.