JSFiddle - React, Tailwind, and code Playground

by Vijay Gujar

HTML

<script src="https://rawgit.com/fabricjs/fabric.js/master/dist/fabric.js"></script>
<canvas id="c" width="600" height="300"></canvas>
<div>
  <div>
    <input type="text" id="textInput" value="" placeholder="Enter text here">
  </div>
  <div>
    <span>Start Offset: </span>
    <input type="range" id="startOffsetInput" step="01" min="-200" max="200">
    <h2 id="offsetAmount">0</h2>
  </div>
  <div>
    <span>Character Spacing: </span>
    <input type="range" id="charSpacingInput" step="1" min="-100" max="200">
    <h2 id="spacingAmount">0</h2>
  </div>
  <div>
    <span>Font Size: </span>
    <input type="range" id="fontSizeInput" step="1" min="10" max="100">
    <h2 id="fontSize">0</h2>
  </div>
  <div>
    <span>Text Align: </span>
    <button onclick="setProp('textAlign','left')">
      Left
    </button>
    <button onclick="setProp('textAlign','center')">
      Center
    </button>
    <button onclick="setProp('textAlign','right')">
      Right
    </button>
  </div>
  <div>
    <span>Side: </span>
    <button onclick="setProp('pathSide','left')">
      Left
    </button>
    <button onclick="setProp('pathSide','right')">
      Right
    </button>
  </div>
</div>

JavaScript

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

fabric.Object.prototype.noScaleCache = false;

var pathString = "M 75 0 A 10 10 0 0 1 75 -150 A 1 1 0 0 1 75 0 Z";
var path = new fabric.Path(pathString, {
  strokeWidth: 2,
  stroke: 'red',
  left: 100,
  top: 50,
  fill: 'transparent',
  scaleX: 1,
  strokeUniform: true
});

var path2 = new fabric.Path('M 0 0 Q 180 0 180 -101.25 Q 180 -180 90 -180 Q 0 -180 0 -112.5 Q 0 -45 78.75 -45 Q 135 -45 146.25 -90', {
  strokeWidth: 2,
  stroke: 'red',
  left: 300,
  top: 50,
  fill: 'transparent'
});

var text = new fabric.Text('Text on a Path', {
  path: path,
  fontSize: 30,
  left: 50,
  top: 50,
  textAlign: 'center',
  pathStartOffset: 0,
  pathSide: 'left'
});

var text2 = new fabric.Text('Text on a Path', {
  path: path2,
  fontSize: 30,
  left: 300,
  top: 50,
  pathStartOffset: 0,
  textAlign: 'center',
  pathSide: 'left'
});

canvas.add(text);
canvas.add(text2);
console.log(text2.path)
document.getElementById('startOffsetInput').addEventListener("input", function() {
  setProp('pathStartOffset', parseInt(this.value));
  document.getElementById('offsetAmount').innerHTML = this.value;
});

document.getElementById('charSpacingInput').addEventListener("input", function() {
  setProp('charSpacing', parseInt(this.value));
  document.getElementById('spacingAmount').innerHTML = this.value;
});

document.getElementById('fontSizeInput').addEventListener("input", function() {
  setProp('fontSize', parseInt(this.value));
  document.getElementById('fontSize').innerHTML = this.value;
});

document.getElementById('textInput').addEventListener("input", function() {
  setProp('text', this.value);
});

function setProp(prop, value) {
  var objects = canvas.getObjects();
  objects.forEach(function(obj) {
    obj.set(prop, value);
    canvas.renderAll();
  });
}

canvas.on({
  'object:scaling': function(e) {
    applyScaling(e.target);
  }
})

function applyScaling(obj) {
  if (obj.type === "text" && obj.path) {
    path = obj.path;
   ...