JSFiddle - React, Tailwind, and code Playground

by RobertWStewart

HTML

<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<script src="https://unpkg.com/fabric@latest/dist/fabric.js"></script>
  <canvas id="canvas" class="" width="640" height="512" style="border:1px solid black"></canvas>
  <div id="debug" style="width: 640px; padding: 5px 0 0 5px;">debug:</div>

CSS

/* To see a full editor that can draw, resize, move, rotate, whatever, multiple polygons see codepen.

http://codepen.io/Rstewart/details/VwNBZwJ

*/

JavaScript

$(document).ready(function() {
  var canvas,points,shape,matrix,nodeNum=0,mouse,orgLeft=0,orgTop=0,nodeX,nodeY,nodes;
  canvas = new fabric.Canvas($('canvas')[0],{ objectCaching:false,preserveObjectStacking:true,perPixelTargetFind:true });

canvas.on('mouse:move', function(e){
  mouse = canvas.getPointer(e);
  $('#debug').text('x:'+parseInt(mouse.x)+' y:'+parseInt(mouse.y));
});

canvas.on('object:moving', function (e) {
  if (e.target && e.target.get('type')=='circle') {
    var node = e.target;
    nodeX = node.getCenterPoint().x; nodeY = node.getCenterPoint().y;
    shape.points[node.nodeNum] = {x:nodeX, y:nodeY};
  }
});

canvas.on('mouse:up', function(e) {
  if (e.target && e.target.get('type')=='circle') { resetPoints(); }
});

points = [{"x":60,"y":40},{"x":100,"y":60},{"x":100,"y":100},{"x":60,"y":120},{"x":20,"y":100},{"x":20,"y":60}];
makePolygon();

function resetPoints() {
  points.forEach((point, i) => { points[i]={x:nodes[i].left,y:nodes[i].top}; });
  makePolygon(); 
}

function makePolygon(e) {
  shape = new fabric.Polygon(points,{selectable:true,objectCaching:false});
  addNodes(shape);
  
  nodes.forEach((node, i) => {
    node.on('mouseover', function(e) { node.selectable = true; node.set('fill','green'); canvas.renderAll(); });
    node.on('mouseout', function(e) { node.selectable = false; node.set('fill','red'); canvas.renderAll(); });
  });
  
  shape.on('mousedown', function(e) {nodes.forEach((node, i) => { canvas.remove(node); })});
  shape.on('modified', function() { addNodes(this); resetPoints() });
}

function addNodes(shape) {
  matrix = shape.calcTransformMatrix(); nodeNum=0;
  var transformedPoints = shape.get("points").map(function(p){
    return new fabric.Point( p.x - shape.pathOffset.x, p.y - shape.pathOffset.y);
    }).map(function(p){ return fabric.util.transformPoint(p, matrix); });
  
  nodes = transformedPoints.map(function(p){
    return new...