Carol.Kar
Carol.Kar

Reputation: 5355

Click on an fabricjs element is not recognized

I am trying to build a simple editor using fabricjs.

I did the following:

<!DOCTYPE html>
<html lang="en">

<head>
  <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" />
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/font/bootstrap-icons.css" />
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/all.min.css">
  <style>
    html,
    body {
      height: 100%;
      width: 100%;
      padding: 0;
      margin: 0;
    }
    
    body {
      touch-action: none;
      background-image: linear-gradient(to bottom left, rgb(214, 240, 201) 10%, rgba(255, 231, 191, 1) 80%);
      -webkit-user-select: none;
      -moz-user-select: -moz-none;
      -ms-user-select: none;
      user-select: none;
    }
    
    .input-group {
      padding: 4px;
    }
    
    .canvas-container {
      margin: 0 auto;
      width: 100%;
      overflow: hidden;
      background: url(./transparent.png);
      background-size: 15px 15px;
      box-shadow: rgba(60, 64, 67, 0.3) 0px 1px 2px 0px, rgba(60, 64, 67, 0.15) 0px 1px 3px 1px;
    }
    
    .actived {
      background: #fff9a8;
    }
    
    .list-group {
      line-height: 35px;
    }
    
    .svg-icon {
      width: 1em;
      height: 1em;
    }
    
    .svg-icon path,
    .svg-icon polygon,
    .svg-icon rect {
      fill: #4691f6;
    }
    
    .svg-icon circle {
      stroke: #4691f6;
      stroke-width: 1;
    }
    
    .fl {
      float: left;
    }
    
    .fr {
      float: right;
    }
    
    .input-group-text {
      background-color: #f4f4f4;
    }
    
    .list-group-item {
      padding: 2px 10px;
      ;
      cursor: pointer;
    }
    
    .list-group {
      border-radius: 0;
      text-align: left;
    }
  </style>
</head>

<body>
  <div class="container-fluid h-100">
    <div class="row h-100">
      <div class="col-sm-3 border-end text-center h-100 overflow-scroll bg-light py-3">
        <hr>
        <div class="form-floating w-100 mb-3 tour5">
          <h6 class="mb-3">Add Element</h6>
          <button class="btn btn-outline-primary" onclick="addText();" data-toggle="tooltip" data-placement="top" title="" data-bs-original-title="Add Text" aria-label="Add Text"><i
                            class="fa fa-font"></i></button>
          <button class="btn btn-outline-primary" data-toggle="tooltip" data-placement="top" title="" onclick="  canvas.add(new fabric.Circle({ name: genNextName(), originX:'center', originY:'center',  radius: 30, fill: '#000', top: 100, left: 100 }));" data-bs-original-title="Add Circle"
            aria-label="Add Circle"><i
                            class="fa fa-circle"></i></button>
          <button class="btn btn-outline-primary" data-toggle="tooltip" data-placement="top" title="" onclick="  canvas.add(new fabric.Triangle({  name: genNextName(),  originX:'center', originY:'center', height:100, width:100, fill: '#000', top: 100, left: 100 }));"
            data-bs-original-title="Add Triangle">
                        <svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="triangle" role="img"
                            xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" class=""
                            style="height: 16px;top: 9px;">
                            <path fill="currentColor"
                                d="M329.6 24c-18.4-32-64.7-32-83.2 0L6.5 440c-18.4 31.9 4.6 72 41.6 72H528c36.9 0 60-40 41.6-72l-240-416z"
                                class=""></path>
                        </svg>
                    </button>
        </div>
        <hr>
      </div>
      <div class="col-sm-6 my-auto py-4 overflow-hidden">
        <div class="canvas-container" style="width: 329px; height: 329px; position: relative; user-select: none;"><canvas id="c" class="lower-canvas" width="329" height="329" style="position: absolute; width: 329px; height: 329px; left: 0px; top: 0px; touch-action: none; user-select: none;"></canvas><canvas class="upper-canvas " width="329" height="329" style="position: absolute; width: 329px; height: 329px; left: 0px; top: 0px; touch-action: manipulation; user-select: none; cursor: default;"></canvas>
        </div>
      </div>
      <div class="col-sm-3 border-start py-3 h-100 overflow-scroll bg-light text-center">
        <form class="form-inline pt-4" id="f" onsubmit="return false;" style="display: none;">
          <div class="form-floating w-100 mb-4" style="">
            <textarea type="text" class="form-control form-control-sm" name="text" oninput="canvas.getActiveObject().set({'text':this.value}); canvas.renderAll();" onmouseover="this.style.height = (this.scrollHeight)+'px';" rows="10" autocomplete="off"></textarea>
            <label for="floatingInput" class="lable-sm">Text</label>
          </div>
          <div class="input-group input-group-sm mb-3 w-100 tour13">
            <span class="input-group-text" id="inputGroup-sizing-sm">MaxHeight to Fit Text</span>
            <input type="number" class="form-control" name="maxHeight" onkeyup="hide_mh_box(); show_mh_box();" onblur="hide_mh_box();" onfocus="show_mh_box();" autocomplete="off">
          </div>
        </form>
      </div>
    </div>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
  <script src="https://code.jquery.com/jquery-3.6.0.js"></script>
  <script src="https://code.jquery.com/ui/1.13.1/jquery-ui.js"></script>
  <script src="https://unpkg.com/[email protected]/dist/fabric.min.js"></script>
  <script src="https://rawcdn.githack.com/lyzerk/fabric-history/8c223cbdc8305307b4a8f8710f97da54d9146ffa/src/index.js"></script>
  <script src="https://rawgit.com/fabricjs/fabric.js/master/lib/centering_guidelines.js"></script>
  <script src="https://rawgit.com/fabricjs/fabric.js/master/lib/aligning_guidelines.js"></script>

  <script src="https://ajax.googleapis.com/ajax/libs/webfont/1.5.10/webfont.js"></script>

  <script>
    var canvas;
    var apiUrl;
    var startedLoadingFamilies = false;
    var to;
    var scale;

    fabric.Text.prototype.set({
      _getNonTransformedDimensions() {
        return new fabric.Point(this.width, this.height).scalarAdd(this.padding);
      },
      _calculateCurrentDimensions() {
        return fabric.util.transformPoint(this._getTransformedDimensions(), this.getViewportTransform(), true);
      }
    });

    function fitCanvas(w, h) {
      var scaleW = (document.querySelectorAll(".col-sm-6")[0].offsetWidth - 100) / w;
      var scaleH = (document.querySelectorAll("body")[0].offsetHeight - 100) / h;
      scale = Math.min(scaleH, scaleW);

      if (scale > 1) {
        scale = 1;
      }


      canvas.setZoom(scale);
      canvas.setWidth(w * scale);
      canvas.setHeight(h * scale);

      initAligningGuidelines(canvas);
      initCenteringGuidelines(canvas);

      canvas.renderAll();
      console.log("finished!!");

    }

    (function() {
      canvas = new fabric.Canvas('c', {
        allowTouchScrolling: true
      });
      WebFont.load({
        google: {
          families: ["Inter:200"]
        },
        active: function() {
          canvas.loadFromJSON({
            "height": "500",
            "width": "500",
            "edit": "yes",
            "objects": [],
            "backgroundImage": {
              "crossOrigin": "anonymous"
            }
          }, function() {
            fitCanvas(500, 500);
          })
        }
      });

      canvas.on('before:render', function(opt) {
        canvas.getObjects().map(function(o, i) {
          if (o.type.toLowerCase() == "textbox") {
            var maxH = (o.maxHeight) ? (o.maxHeight) : (canvas.height);
            o.set({
              'maxHeight': maxH
            });
            if (o.fontSize > 0 && (maxH > o.fontSize)) {
              while (o.height > maxH) {
                o.set({
                  'fontSize': o.fontSize - 1
                });
              }
            }
          }

          if (o.circleFrame) {
            o.set({
              clipPath: new fabric.Circle({
                radius: o.width / 2,
                originX: 'center',
                originY: 'center'
              })
            });

          }

          if ((o.rx || o.ry) && o.type == "image") {

            let rx = (o.rx || 0);
            let ry = (o.ry || 0);

            o.set({
              clipPath: new fabric.Rect({
                rx: rx,
                ry: ry,
                height: o.height,
                width: o.width,
                originX: 'center',
                originY: 'center'
              })
            });

          }
        });
      });

    })();
  </script>
  <script>
    fabric.Object.prototype.objectCaching = false;

    function changeDim() {
      fitCanvas($("#widthC").val(), $("#heightC").val());
    }

    function setCanvasBI(src, o = "1") {
      if (!src) {
        src = $("#canvasBI").val();
      }
      if (src.length == 0) {
        src = new fabric.Image('');
      }
      canvas.setBackgroundImage(src, canvas.renderAll.bind(canvas), {
        opacity: o
      });
    }

    (function() {

      $(document).on("mouseenter", "[data-label]", function() {
        $("#font-search").val($(this).data("label"));
        loadFont($(this).data("label"));
      });

      fabric.Canvas.prototype.getItemByAttr = function(attr, name) {
        var object = null,
          objects = this.getObjects();
        for (var i = 0, len = this.size(); i < len; i++) {
          if (objects[i][attr] && objects[i][attr] == name) {
            object = objects[i];
            break;
          }
        }
        return object;
      };

      $("form#f").hide();

      var activeObject;

      $("#f input, #f select").on("input", function() {
        if (["height", "width", "top", "left", "strokeWidth", "charSpacing"].includes(this.name)) {
          canvas.getActiveObject().set(this.name, parseFloat(this.value)).setCoords();
        } else {
          canvas.getActiveObject().set(this.name, this.value).setCoords();
        }
        canvas.renderAll();
      });

      canvas.preserveObjectStacking = true;

      fabric.Object.prototype.toObject = (function(toObject) {
        return function() {
          return fabric.util.object.extend(toObject.call(this), {
            name: this.name,
            text: this.text
          });
        };
      })(fabric.Object.prototype.toObject);

      canvas.on('object:scaling', function(e) {
        if (e.target.toObject().type != "image" && e.target.toObject().type != "circle") {
          e.target.set({
            width: e.target.width * e.target.scaleX,
            height: e.target.height * e.target.scaleY,
            scaleX: 1,
            scaleY: 1
          })
        }
      });

      canvas.on('object:modified', function(opt) {
        document.body.style.cursor = 'progress';
      });

      canvas.on("after:render", function() {

        canvas.includeDefaultValues = false;
        canvas.toObject().objects.forEach(function(layer, id) {

          if (typeof layer.name !== 'undefined') {
            canvas.getItemByAttr(`name`, layer.name).set({
              "name": String.fromCharCode(65 + id).toLowerCase()
            })
            var actived = '';
            if (canvas.getActiveObject()) {
              actived = (canvas.getActiveObject().name == layer.name) ? " actived" : "";
            }
          }
        });
        document.body.style.cursor = 'default'
      });

      canvas.on("selection:created", function(obj) {
        if ("image" == obj.target.type) {
          canvas.getActiveObject().setControlsVisibility({
            mb: false,
            ml: false,
            mt: false,
            mr: false
          });
        }
        $("form#f input[type!='hidden'], #f select").parent().hide();
        $("form#f").hide();
        canvas.renderAll();
        showForm();
      });

      canvas.on("selection:updated", function(obj) {
        if ("image" == obj.target.type) {
          canvas.getActiveObject().setControlsVisibility({
            mb: false,
            ml: false,
            mt: false,
            mr: false
          });
        }
        canvas.renderAll();
        $("form#f").hide();
        $("form#f input[type!='hidden'] , #f select, #f textarea").parent().hide();
        showForm();
      });

      canvas.on("selection:cleared", function() {
        canvas.renderAll();
        $("form#f").hide();
        $("form#f input[type!='hidden'], #f select, #f textarea").parent().hide();
      });

      canvas.hoverCursor = 'default';
      canvas.on('mouse:over', function(e) {
        if (e.target) {
          e.target._renderControls(canvas.contextTop, {
            hasControls: false
          })
        }
      });

      canvas.on('mouse:out', function(e) {
        canvas.clearContext(canvas.contextTop);
      });
      canvas.on('mouse:down', function(e) {
        canvas.clearContext(canvas.contextTop);
      });

      function showForm() {

        $("form#f").show();
        activeObject = canvas.getActiveObject();
        var v;
        for (i in activeObject) {
          v = activeObject[i];

          if (typeof v != "undefined") {
            $("textarea[name='" + i + "']").val(v).parent().show();
            $("input[name='" + i + "']").val(v).parent().show();
            $("select[name='" + i + "']").val(v).parent().show();
          }
        }
      }

      addText = function() {
        var text = new fabric.Textbox("Edit this Text", {
          name: genNextName(),
          left: canvas.getWidth() / canvas.getZoom() / 2,
          top: canvas.getHeight() / canvas.getZoom() / 2,
          width: (canvas.getWidth() / canvas.getZoom()) / 2,
          fill: "#000000",
          originX: "center",
          originY: "center",
          fontFamily: "Inter",
          fontWeight: 400,
          fontSize: 60,
          padding: 20
        });
        text.setControlsVisibility({
          mt: false,
          mb: false,
          ml: true,
          mr: true,
          tl: true,
          tr: true,
          bl: true,
          br: true
        });

        canvas.add(text);
        canvas.setActiveObject(text);
        canvas.renderAll();
      };

    })();

    function hide_mh_box() {
      canvas.remove(canvas.getItemByAttr("isBB", true));
    }

    function show_mh_box() {
      var h = parseInt($("[name=maxHeight]").val());
      var n = new fabric.Rect({
        top: canvas.getActiveObject().get('top'),
        left: canvas.getActiveObject().get('left'),
        width: canvas.getActiveObject().get('width'),
        height: h,
        originX: canvas.getActiveObject().get('originX'),
        originY: canvas.getActiveObject().get('originY'),
        angle: canvas.getActiveObject().get('angle'),
        opacity: 1,
        strokeWidth: 2,
        stroke: "#FF00FF",
        fill: "rgba(0,0,0,0)",
        evented: !1,
        isBB: true
      });
      canvas.add(n);
      canvas.renderAll();
    }

    var visited = [];
  </script>

  <script>
    function genNextName() {
      canvas.renderAll();
      var total = canvas.getObjects().length;
      return String.fromCharCode(65 + total).toLowerCase()
    }
  </script>
</body>

</html>

When I click on an element f.ex. the triangle it is added to the canvas. When I click on the added triangle a menu on the right should go up. However, the element does not get selected.

enter image description here

Any suggestions what I am doing wrong?

I appreciate your replies!

Upvotes: 1

Views: 352

Answers (1)

Mike
Mike

Reputation: 831

you have second canvas element next to your canvas, it prevents from clicking on first canvas element, removing this second canvas solves this issue

<canvas class="upper-canvas " width="329" height="329" style="position: absolute; width: 329px; height: 329px; left: 0px; top: 0px; touch-action: manipulation; user-select: none; cursor: default;"></canvas>

<!DOCTYPE html>
<html lang="en">

<head>
  <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" />
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/font/bootstrap-icons.css" />
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/all.min.css">
  <style>
    html,
    body {
      height: 100%;
      width: 100%;
      padding: 0;
      margin: 0;
    }
    
    body {
      touch-action: none;
      background-image: linear-gradient(to bottom left, rgb(214, 240, 201) 10%, rgba(255, 231, 191, 1) 80%);
      -webkit-user-select: none;
      -moz-user-select: -moz-none;
      -ms-user-select: none;
      user-select: none;
    }
    
    .input-group {
      padding: 4px;
    }
    
    .canvas-container {
      margin: 0 auto;
      width: 100%;
      overflow: hidden;
      background: url(./transparent.png);
      background-size: 15px 15px;
      box-shadow: rgba(60, 64, 67, 0.3) 0px 1px 2px 0px, rgba(60, 64, 67, 0.15) 0px 1px 3px 1px;
    }
    
    .actived {
      background: #fff9a8;
    }
    
    .list-group {
      line-height: 35px;
    }
    
    .svg-icon {
      width: 1em;
      height: 1em;
    }
    
    .svg-icon path,
    .svg-icon polygon,
    .svg-icon rect {
      fill: #4691f6;
    }
    
    .svg-icon circle {
      stroke: #4691f6;
      stroke-width: 1;
    }
    
    .fl {
      float: left;
    }
    
    .fr {
      float: right;
    }
    
    .input-group-text {
      background-color: #f4f4f4;
    }
    
    .list-group-item {
      padding: 2px 10px;
      ;
      cursor: pointer;
    }
    
    .list-group {
      border-radius: 0;
      text-align: left;
    }
  </style>
</head>

<body>
  <div class="container-fluid h-100">
    <div class="row h-100">
      <div class="col-sm-3 border-end text-center h-100 overflow-scroll bg-light py-3">
        <hr>
        <div class="form-floating w-100 mb-3 tour5">
          <h6 class="mb-3">Add Element</h6>
          <button class="btn btn-outline-primary" onclick="addText();" data-toggle="tooltip" data-placement="top" title="" data-bs-original-title="Add Text" aria-label="Add Text"><i
                            class="fa fa-font"></i></button>
          <button class="btn btn-outline-primary" data-toggle="tooltip" data-placement="top" title="" onclick="  canvas.add(new fabric.Circle({ name: genNextName(), originX:'center', originY:'center',  radius: 30, fill: '#000', top: 100, left: 100 }));" data-bs-original-title="Add Circle"
            aria-label="Add Circle"><i
                            class="fa fa-circle"></i></button>
          <button class="btn btn-outline-primary" data-toggle="tooltip" data-placement="top" title="" onclick="  canvas.add(new fabric.Triangle({  name: genNextName(),  originX:'center', originY:'center', height:100, width:100, fill: '#000', top: 100, left: 100 }));"
            data-bs-original-title="Add Triangle">
                        <svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="triangle" role="img"
                            xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" class=""
                            style="height: 16px;top: 9px;">
                            <path fill="currentColor"
                                d="M329.6 24c-18.4-32-64.7-32-83.2 0L6.5 440c-18.4 31.9 4.6 72 41.6 72H528c36.9 0 60-40 41.6-72l-240-416z"
                                class=""></path>
                        </svg>
                    </button>
        </div>
        <hr>
      </div>
      <div class="col-sm-6 my-auto py-4 overflow-hidden">
        <div class="canvas-container" style="width: 329px; height: 329px; position: relative; user-select: none;"><canvas id="c" class="lower-canvas" width="329" height="329" style="position: absolute; width: 329px; height: 329px; left: 0px; top: 0px; touch-action: none; user-select: none;"></canvas>
        </div>
      </div>
      <div class="col-sm-3 border-start py-3 h-100 overflow-scroll bg-light text-center">
        <form class="form-inline pt-4" id="f" onsubmit="return false;" style="display: none;">
          <div class="form-floating w-100 mb-4" style="">
            <textarea type="text" class="form-control form-control-sm" name="text" oninput="canvas.getActiveObject().set({'text':this.value}); canvas.renderAll();" onmouseover="this.style.height = (this.scrollHeight)+'px';" rows="10" autocomplete="off"></textarea>
            <label for="floatingInput" class="lable-sm">Text</label>
          </div>
          <div class="input-group input-group-sm mb-3 w-100 tour13">
            <span class="input-group-text" id="inputGroup-sizing-sm">MaxHeight to Fit Text</span>
            <input type="number" class="form-control" name="maxHeight" onkeyup="hide_mh_box(); show_mh_box();" onblur="hide_mh_box();" onfocus="show_mh_box();" autocomplete="off">
          </div>
        </form>
      </div>
    </div>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
  <script src="https://code.jquery.com/jquery-3.6.0.js"></script>
  <script src="https://code.jquery.com/ui/1.13.1/jquery-ui.js"></script>
  <script src="https://unpkg.com/[email protected]/dist/fabric.min.js"></script>
  <script src="https://rawcdn.githack.com/lyzerk/fabric-history/8c223cbdc8305307b4a8f8710f97da54d9146ffa/src/index.js"></script>
  <script src="https://rawgit.com/fabricjs/fabric.js/master/lib/centering_guidelines.js"></script>
  <script src="https://rawgit.com/fabricjs/fabric.js/master/lib/aligning_guidelines.js"></script>

  <script src="https://ajax.googleapis.com/ajax/libs/webfont/1.5.10/webfont.js"></script>

  <script>
    var canvas;
    var apiUrl;
    var startedLoadingFamilies = false;
    var to;
    var scale;

    fabric.Text.prototype.set({
      _getNonTransformedDimensions() {
        return new fabric.Point(this.width, this.height).scalarAdd(this.padding);
      },
      _calculateCurrentDimensions() {
        return fabric.util.transformPoint(this._getTransformedDimensions(), this.getViewportTransform(), true);
      }
    });

    function fitCanvas(w, h) {
      var scaleW = (document.querySelectorAll(".col-sm-6")[0].offsetWidth - 100) / w;
      var scaleH = (document.querySelectorAll("body")[0].offsetHeight - 100) / h;
      scale = Math.min(scaleH, scaleW);

      if (scale > 1) {
        scale = 1;
      }


      canvas.setZoom(scale);
      canvas.setWidth(w * scale);
      canvas.setHeight(h * scale);

      initAligningGuidelines(canvas);
      initCenteringGuidelines(canvas);

      canvas.renderAll();
      console.log("finished!!");

    }

    (function() {
      canvas = new fabric.Canvas('c', {
        allowTouchScrolling: true
      });
      WebFont.load({
        google: {
          families: ["Inter:200"]
        },
        active: function() {
          canvas.loadFromJSON({
            "height": "500",
            "width": "500",
            "edit": "yes",
            "objects": [],
            "backgroundImage": {
              "crossOrigin": "anonymous"
            }
          }, function() {
            fitCanvas(500, 500);
          })
        }
      });

      canvas.on('before:render', function(opt) {
        canvas.getObjects().map(function(o, i) {
          if (o.type.toLowerCase() == "textbox") {
            var maxH = (o.maxHeight) ? (o.maxHeight) : (canvas.height);
            o.set({
              'maxHeight': maxH
            });
            if (o.fontSize > 0 && (maxH > o.fontSize)) {
              while (o.height > maxH) {
                o.set({
                  'fontSize': o.fontSize - 1
                });
              }
            }
          }

          if (o.circleFrame) {
            o.set({
              clipPath: new fabric.Circle({
                radius: o.width / 2,
                originX: 'center',
                originY: 'center'
              })
            });

          }

          if ((o.rx || o.ry) && o.type == "image") {

            let rx = (o.rx || 0);
            let ry = (o.ry || 0);

            o.set({
              clipPath: new fabric.Rect({
                rx: rx,
                ry: ry,
                height: o.height,
                width: o.width,
                originX: 'center',
                originY: 'center'
              })
            });

          }
        });
      });

    })();
  </script>
  <script>
    fabric.Object.prototype.objectCaching = false;

    function changeDim() {
      fitCanvas($("#widthC").val(), $("#heightC").val());
    }

    function setCanvasBI(src, o = "1") {
      if (!src) {
        src = $("#canvasBI").val();
      }
      if (src.length == 0) {
        src = new fabric.Image('');
      }
      canvas.setBackgroundImage(src, canvas.renderAll.bind(canvas), {
        opacity: o
      });
    }

    (function() {

      $(document).on("mouseenter", "[data-label]", function() {
        $("#font-search").val($(this).data("label"));
        loadFont($(this).data("label"));
      });

      fabric.Canvas.prototype.getItemByAttr = function(attr, name) {
        var object = null,
          objects = this.getObjects();
        for (var i = 0, len = this.size(); i < len; i++) {
          if (objects[i][attr] && objects[i][attr] == name) {
            object = objects[i];
            break;
          }
        }
        return object;
      };

      $("form#f").hide();

      var activeObject;

      $("#f input, #f select").on("input", function() {
        if (["height", "width", "top", "left", "strokeWidth", "charSpacing"].includes(this.name)) {
          canvas.getActiveObject().set(this.name, parseFloat(this.value)).setCoords();
        } else {
          canvas.getActiveObject().set(this.name, this.value).setCoords();
        }
        canvas.renderAll();
      });

      canvas.preserveObjectStacking = true;

      fabric.Object.prototype.toObject = (function(toObject) {
        return function() {
          return fabric.util.object.extend(toObject.call(this), {
            name: this.name,
            text: this.text
          });
        };
      })(fabric.Object.prototype.toObject);

      canvas.on('object:scaling', function(e) {
        if (e.target.toObject().type != "image" && e.target.toObject().type != "circle") {
          e.target.set({
            width: e.target.width * e.target.scaleX,
            height: e.target.height * e.target.scaleY,
            scaleX: 1,
            scaleY: 1
          })
        }
      });

      canvas.on('object:modified', function(opt) {
        document.body.style.cursor = 'progress';
      });

      canvas.on("after:render", function() {

        canvas.includeDefaultValues = false;
        canvas.toObject().objects.forEach(function(layer, id) {

          if (typeof layer.name !== 'undefined') {
            canvas.getItemByAttr(`name`, layer.name).set({
              "name": String.fromCharCode(65 + id).toLowerCase()
            })
            var actived = '';
            if (canvas.getActiveObject()) {
              actived = (canvas.getActiveObject().name == layer.name) ? " actived" : "";
            }
          }
        });
        document.body.style.cursor = 'default'
      });

      canvas.on("selection:created", function(obj) {
        if ("image" == obj.target?.type) {
          canvas.getActiveObject().setControlsVisibility({
            mb: false,
            ml: false,
            mt: false,
            mr: false
          });
        }
        $("form#f input[type!='hidden'], #f select").parent().hide();
        $("form#f").hide();
        canvas.renderAll();
        showForm();
      });

      canvas.on("selection:updated", function(obj) {
        if ("image" == obj.target?.type) {
          canvas.getActiveObject().setControlsVisibility({
            mb: false,
            ml: false,
            mt: false,
            mr: false
          });
        }
        canvas.renderAll();
        $("form#f").hide();
        $("form#f input[type!='hidden'] , #f select, #f textarea").parent().hide();
        showForm();
      });

      canvas.on("selection:cleared", function() {
        canvas.renderAll();
        $("form#f").hide();
        $("form#f input[type!='hidden'], #f select, #f textarea").parent().hide();
      });

      canvas.hoverCursor = 'default';
      canvas.on('mouse:over', function(e) {
        if (e.target) {
          e.target._renderControls(canvas.contextTop, {
            hasControls: false
          })
        }
      });

      canvas.on('mouse:out', function(e) {
        canvas.clearContext(canvas.contextTop);
      });
      canvas.on('mouse:down', function(e) {
        canvas.clearContext(canvas.contextTop);
      });

      function showForm() {

        $("form#f").show();
        activeObject = canvas.getActiveObject();
        var v;
        for (i in activeObject) {
          v = activeObject[i];

          if (typeof v != "undefined") {
            $("textarea[name='" + i + "']").val(v).parent().show();
            $("input[name='" + i + "']").val(v).parent().show();
            $("select[name='" + i + "']").val(v).parent().show();
          }
        }
      }

      addText = function() {
        var text = new fabric.Textbox("Edit this Text", {
          name: genNextName(),
          left: canvas.getWidth() / canvas.getZoom() / 2,
          top: canvas.getHeight() / canvas.getZoom() / 2,
          width: (canvas.getWidth() / canvas.getZoom()) / 2,
          fill: "#000000",
          originX: "center",
          originY: "center",
          fontFamily: "Inter",
          fontWeight: 400,
          fontSize: 60,
          padding: 20
        });
        text.setControlsVisibility({
          mt: false,
          mb: false,
          ml: true,
          mr: true,
          tl: true,
          tr: true,
          bl: true,
          br: true
        });

        canvas.add(text);
        canvas.setActiveObject(text);
        canvas.renderAll();
      };

    })();

    function hide_mh_box() {
      canvas.remove(canvas.getItemByAttr("isBB", true));
    }

    function show_mh_box() {
      var h = parseInt($("[name=maxHeight]").val());
      var n = new fabric.Rect({
        top: canvas.getActiveObject().get('top'),
        left: canvas.getActiveObject().get('left'),
        width: canvas.getActiveObject().get('width'),
        height: h,
        originX: canvas.getActiveObject().get('originX'),
        originY: canvas.getActiveObject().get('originY'),
        angle: canvas.getActiveObject().get('angle'),
        opacity: 1,
        strokeWidth: 2,
        stroke: "#FF00FF",
        fill: "rgba(0,0,0,0)",
        evented: !1,
        isBB: true
      });
      canvas.add(n);
      canvas.renderAll();
    }

    var visited = [];
  </script>

  <script>
    function genNextName() {
      canvas.renderAll();
      var total = canvas.getObjects().length;
      return String.fromCharCode(65 + total).toLowerCase()
    }
  </script>
</body>

</html>

Upvotes: 1

Related Questions