JSFiddle - React, Tailwind, and code Playground

by Eugene Vilder

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/3.6.1/fabric.min.js"></script>
<canvas id="paper" width="400" height="400" style="border:1px solid #ccc"></canvas>

CSS

#paper {
  border: solid 1px red;
}

JavaScript

const canvas = new fabric.Canvas('paper');
var clone = fabric.util.object.clone;

fabric.DdpTextParagraph = fabric.util.createClass(fabric.Textbox, {
    xxx: [],
  	initialize: function (element, options) {
    	options || (options = {});
      this.callSuper('initialize', element, options);
  	},
    ddpX: function(){
    	this.xxx = this._text.map((char, i)=>{
      	return {
        	char,
          style: this.getStyleAtPosition(i)
        }
      });
    },
    ddpRebuildStyles: function(){
      this.xxx.map(({style}, i)=>{
      	this.setSelectionStyles(style, i, i+1);
      });
    },
    renderCursor: function(boundaries, ctx) {
      var cursorLocation = this.get2DCursorLocation(),
          lineIndex = cursorLocation.lineIndex,
          charIndex = cursorLocation.charIndex > 0 ? cursorLocation.charIndex - 1 : 0,
          multiplier = this.scaleX * this.canvas.getZoom(),
          cursorWidth = this.cursorWidth / multiplier,
          topOffset = boundaries.topOffset,
          dy = this.getValueOfPropertyAt(lineIndex, charIndex, 'deltaY');
          
      const selectionStart = this.selectionStart === this.xxx.length ? this.selectionStart - 1 : this.selectionStart;
      const {style} = this.xxx[selectionStart] || {};
      const charHeight = (style && style.fontSize) || this.getValueOfPropertyAt(lineIndex, charIndex, 'fontSize');

      topOffset += (1 - this._fontSizeFraction) * this.getHeightOfLine(lineIndex) / this.lineHeight
        - charHeight * (1 - this._fontSizeFraction);

      if (this.inCompositionMode) {
        this.renderSelection(boundaries, ctx);
      }

      ctx.fillStyle = (style && style.fill) || this.getValueOfPropertyAt(lineIndex, charIndex, 'fill');
      ctx.globalAlpha = this.__isMousedown ? 1 : this._currentCursorOpacity;
      ctx.fillRect(
        boundaries.left + boundaries.leftOffset - cursorWidth / 2,
        topOffset + boundaries.top + dy,
        cursorWidth,
        charHeight);
    },
    
	onInput:...