JSFiddle - React, Tailwind, and code Playground

by Andrea Bogazzi

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/5.3.1/fabric.min.js"></script>
<button type="button" id="addText">Add Text</button>
<button type="button" id="addJsonText">Add Text (From JSON)</button>
<canvas id="c" width="600" height="600"></canvas>

JavaScript

const canvas = new fabric.Canvas('c');

fabric.RoundedText = fabric.util.createClass(fabric.IText, {
  type: 'roundedText',
  _renderBackground: function(ctx) {
    if (!this.backgroundColor) {
      return
    }

    const dim = this._getNonTransformedDimensions()

    ctx.fillStyle = this.backgroundColor
    ctx.roundRect(
      -dim.x / 2 - this.padding,
      -dim.y / 2 - this.padding,
      dim.x + this.padding * 2,
      dim.y + this.padding * 2,
      15
    )
    ctx.fill()
  },
})

// Referebced here: https://github.com/fabricjs/fabric.js/issues/5949#issuecomment-558603616
fabric.RoundedText.fromObject = function(object, callback) {
  return fabric.Object._fromObject('RoundedText', object, callback, 'text');
};

document.getElementById('addText').addEventListener('click', () => {
  const text = new fabric.RoundedText('Tap and Type', {
    top: 100,
    left: 100,
    fontFamily: 'Roboto',
    fill: '#000',
    stroke: '#fff',
    strokeWidth: 0.1,
    fontSize: 45,
    backgroundColor: 'gray',
    padding: 10,
  })

  canvas.add(text)
})

document.getElementById('addJsonText').addEventListener('click', () => {
  canvas.loadFromJSON(textJson);
  canvas.renderAll();
})

// Add roundRect support for CanvasRenderingContext2D
CanvasRenderingContext2D.prototype.roundRect = function(x, y, width, height, radius = 5) {
  this.beginPath()
  this.moveTo(x + radius, y)
  this.lineTo(x + width - radius, y)
  this.quadraticCurveTo(x + width, y, x + width, y + radius)
  this.lineTo(x + width, y + height - radius)
  this.quadraticCurveTo(x + width, y + height, x + width - radius, y + height)
  this.lineTo(x + radius, y + height)
  this.quadraticCurveTo(x, y + height, x, y + height - radius)
  this.lineTo(x, y + radius)
  this.quadraticCurveTo(x, y, x + radius, y)
  this.closePath()
}

const textJson = {
  objects: [{
    type: "roundedText", // Also tried RoundedText
    left: 100,
    top: 100,
    width: 200,
    height: 30,
    shadow: null,
    visible: true,
   ...