How to edit a FabricJS IText and apply new styles (e.g. highlighting, etc...)

17,585

Usually answers without a description of what you tried and what didn't work are completely ignored here, i'm answering this time because the fabricjs library is quite complex and the documentation is a bit lacking sometimes...

That page has samples for the IText object, text that can be edited in place (the content of the basic fabricjs text object can be modified only from outside via javascript).

Building a static IText object with different styles applied it's simple:

HTML:

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

Javascript:

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

Link to JSFiddle

As you can see you just specify the style for every character of each for each line (first for the hello line, then for the world line).

If you want something dynamic with the ability to select some text and change the appearance/style there is some work to do, you'll need to:

  1. Add a button or a clickable element for each style (bold,italic,change color, change background,etc...) that you want to apply dynamically;
  2. Add a click listener to each button with some code that changes the style of the selected text inside the IText.

You'll need a basic function that add handlers that you will reuse for every style button:

function addHandler(id, fn, eventName) {
  document.getElementById(id)[eventName || 'onclick'] = function() {
    var el = this;
    if (obj = canvas.getActiveObject()) {
      fn.call(el, obj);
      canvas.renderAll();
    }
  };
}

And some helper functions to change the styles:

function setStyle(object, styleName, value) {
  if (object.setSelectionStyles && object.isEditing) {
    var style = { };
    style[styleName] = value;
    object.setSelectionStyles(style);
  }
  else {
    object[styleName] = value;
  }
}

function getStyle(object, styleName) {
  return (object.getSelectionStyles && object.isEditing)
    ? object.getSelectionStyles()[styleName]
    : object[styleName];
}


addHandler('underline', function(obj) {
  var isUnderline = (getStyle(obj, 'textDecoration') || '').indexOf('underline') > -1;
  setStyle(obj, 'textDecoration', isUnderline ? '' : 'underline');
});

Link to working JSFiddle with a working underline button.

A bit of coding is involved as you can see, but it's not that complex, for the full list of available style options you can check the fabricjs documentation.

Share:
17,585

Related videos on Youtube

Joker
Author by

Joker

Updated on June 04, 2022

Comments

  • Joker
    Joker almost 2 years

    I want to edit the highlighted characters in a text in canvas using fabric.js, like change its color, font, style etc.

    just like this http://fabricjs.com/test/misc/itext.html

    to @user43250937 hey uhm. I tried it and it works! :D thanks. I tried Underline, Bold, Italic, but I have a problem changing the color of the text, I tried :

    // "cinput" is the id of the color picker.
    
    
    addHandler('cinput', function(obj) {
        var color =  $("#cinput").val();
    
        var isColor = (getStyle(obj, 'fill') || '').indexOf(color) > -1;
    
         setStyle(obj, 'fill', isColor ? '' : color);
    
    });
    
    • Joker
      Joker almost 9 years
      @user43250937 thanks for the help! :D
    • uraimo
      uraimo almost 9 years
      Why setStyle with fontWeight? for the text color is fill while for the background color use textBackgroundColor.
    • Joker
      Joker almost 9 years
      @user43250937 EDITED* wrong paste sorry. When I run the code, the text is gone.
    • uraimo
      uraimo almost 9 years
      You don't need the isColor line (that was to understand if it had underline or not, it's sort of a boolean value, as bold,italics,etc...), simply use setStyle(obj, 'fill', color);
    • Joker
      Joker almost 9 years
      @user43250937 thanks man. It worked! but I have a problem when I click the color picker, the text color will not change, It will only change after I clicked the color picker again , what I did was I added a handler with "onchange" instead of "onclick". function addHandler(id, fn, eventName) { document.getElementById(id)[eventName || 'onchange'] = function() { var el = this; if (obj = canvas.getActiveObject()) { fn.call(el, obj); canvas.renderAll(); } }; }
    • uraimo
      uraimo almost 9 years
      Only one problem for each question :D
    • Joker
      Joker almost 9 years
      yes. I was about to say thanks earlier but I cant post codes in here. lol
    • uraimo
      uraimo almost 9 years
      No problem, i recommend to open a new question, so that other people can help as well.
    • Joker
      Joker almost 9 years
      okay :D I'm new here btw. thanks again!
  • mrcoder
    mrcoder about 6 years
    object[styleName] = value; in setStyle function, did not work but object.set(styleName, value) worked. But Thank you very much.
  • Flemming
    Flemming about 6 years
    In fabricjs version 2 you have to use getStyleAtPosition(object.selectionStart) instead of getSelectionStyles() in the getStyle() function. stackoverflow.com/questions/49995602/…
  • Istiaque Ahmed
    Istiaque Ahmed almost 6 years
    your JSFiddle code does not work if I use with Fabric version 2.3.3. Even the comment from @Flemming cannot make it work.
  • Flemming
    Flemming almost 6 years
    @Istiaque i have just updated my project to work with ver. 2.3.3 and it still works. I used the cdnjs library: cdnjs.cloudflare.com/ajax/libs/fabric.js/2.3.3/fabric.min.js