JSFiddle - React, Tailwind, and code Playground

by Mark Lane

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/3.4.0/fabric.js"></script>

<b>PLACE:</b>
<input class="switch" name="iconOn" type="radio" id="on" />
<b>ICON</b>
<input class="switch" name="iconOn" type="radio" id="off" />
<b>LINK</b>
<br>

<input class="switch" checked name="iconType" type="radio" id="green" />Green
<input class="tally" disabled id="greentally" type="text" value="0">
<br>
<input class="switch" name="iconType" type="radio" id="yellow" /> Yellow
<input class="tally" disabled id="yellowtally" type="text" value="0">
<br>
<input class="switch" name="iconType" type="radio" id="red" /> red
<input class="tally" disabled id="redtally" type="text" value="0">
<canvas id="c" width="600" height="300"></canvas>

CSS

canvas {
  border: 1px solid #ccc;
}

.tally {
  position: fixed;
  width: 50px;
  left: 255px;
}

JavaScript

var canvas = new fabric.Canvas('c');
var currentColor;
var defaultIcon = {
  width: 40,
  height: 30,
  originX: 'center',
  originY: 'center',
  hasControls: false,
};
var iconTriangle = new fabric.Triangle(defaultIcon);
setColor('green');
canvas.add(iconTriangle);
//disable icon & hide when hovering over existing icon
canvas.on('mouse:over', function(obj) {
  iconTriangle.set('opacity', 0);
  canvas.renderAll();
});
//restor icon & unhide
canvas.on('mouse:out', function(e) {
  if (document.getElementById("on").checked == true) {
    // if 'target' is null, means mouse is out of canvas
    if (e.target) {
      iconTriangle.set('opacity', 1);
    } else {
      iconTriangle.left = -100;
      iconTriangle.top = -100;
    }
    canvas.renderAll();
  };
});
//move pointer icon
canvas.on('mouse:move', function(obj) {
  iconTriangle.top = obj.e.y - 100;
  iconTriangle.left = obj.e.x - 10;
  canvas.renderAll();
});

//count each by type and place new icon
canvas.on('mouse:up', function(e) {
  if (e.target) {
    return
  }
  var red = getObjectsBy((obj) => obj.fill === 'red').length;
  var green = getObjectsBy((obj) => obj.fill === 'green').length;
  var yellow = getObjectsBy((obj) => obj.fill === 'yellow').length;
  document.getElementById("greentally").value = green;
  document.getElementById("yellowtally").value = yellow;
  document.getElementById("redtally").value = red;
  addIcon(e.e.x - 10, e.e.y - 100, currentColor);
});

function setColor(color) {
  currentColor = color;
  iconTriangle.setColor(currentColor);
  canvas.renderAll();
}

function getObjectsBy(fn) {
  return canvas.getObjects().filter(fn)
}

function addIcon(x, y, color) {
  var icon = new fabric.Triangle(defaultIcon);
  if (document.getElementById("on").checked == true) {
    icon.setColor(color);
    icon.left = x;
    icon.top = y;
    canvas.add(icon);
  } else if (document.getElementById("off").checked == true) {
    iconTriangle.set('opacity', 0);
    icon = null;
  };
 ...