JSFiddle - React, Tailwind, and code Playground

by swesh

HTML

<script src="https://rawgit.com/kangax/fabric.js/master/dist/fabric.js"></script>
<script src="https://code.jquery.com/jquery-1.11.3.js"></script>
<div style="width:370px;height:300px; float:left; border: 2px solid">
    Admin's Area
    <canvas id="adminArea" width=350 height=250 style="border: 2px solid red ; margin-left: 7px;">
    </canvas>
</div>
<div style="width:370px;height:300px;float:left; margin-left:5px; border: 2px solid">
    User's Area
    <canvas id="userArea" width=350 height=250 style="border: 2px solid red;  margin-left: 7px;">
    </canvas>
</div>
<div style="width:370px;height:400px; float:left; margin-top:10px;">
    
    <div style="margin-top: 2px;">
    Set text
    <textArea id="adminText" rows=5 cols=30>Default</textArea>
    </div>
    <div style="margin-top: 2px;">
    Font size
        <input type="number" id="fontSize" min=10 max=70 value = 15  />
    </div>
    <div style="margin-top: 2px;">
     Line spacing
    <input type="number" id="lineSpacing" min=0 value=1 step="0.1" />
    </div>
    
</div>

<div style="width:370px;height:400px; float:left;">
     <div style="margin-top: 2px;">
    Set text
    <textArea id="userText" rows=5 cols=30>Default</textArea>
    </div>
</div>

JavaScript

(function() {
        var clone = fabric.util.object.clone;
        fabric.Textbox = fabric.util.createClass(fabric.IText, fabric.Observable,  {
        /**
        * Type of an object
        * @type String
        * @default
        */
       type: 'textbox',

       /**
      * Constructor
       * @param {String} text Text string
      * @param {Object} [options] Options object
      * @return {fabric.Textbox} thisArg
      */
      initialize: function(text, options) {
        this.styles = options ? (options.styles || { }) : { };
        options.originY = "top";
        this.callSuper('initialize', text, options);      
    },
    /**
     * Break the text accordingly to the width of Textbox. Based on the code of Darren Nolan (@darrennolan)
     * @method _wrapText
     * @param {CanvasRenderingContext2D} ctx Context to render on
     * @param {String} Text to wrap
     * @return {Array} Array with the lines of the text
     */
    _wrapText: function (ctx, text) {
      var scaleX = (this.originalScales ? this.originalScales[0] : this.scaleX);
      var maxWidth = (this.width * scaleX),
        lines = text.split(this._reNewline),
        wrapped_text = [];

      var maximum=0;

      for (var l = 0; l < lines.length; l++) {
        var line = "";
        var words = lines[l].split(" ");
        for (var w = 0; w < words.length; w++) {
          var testLine = line + words[w] + " ";
          var metrics = ctx.measureText(testLine);
          var testWidth = metrics.width;
          if (testWidth > (maxWidth )) {
            wrapped_text.push(line);
            line = words[w] + " ";
          } else {
            line = testLine;
            maximum = Math.max(testWidth, maximum);
          }
        }
        wrapped_text.push(line.trim());
      }

      return wrapped_text;
    },
    /**
     * @private
     * @param {CanvasRenderingContext2D} ctx Context to render on
     */
    _renderViaNative: function(ctx) {

      this._setTextStyles(ctx);

   ...