JSFiddle - React, Tailwind, and code Playground

by Twisty

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqwidgets/12.1.2/jqwidgets/jqx-all.js"></script>
<body>
  <div class="draggable" id="knob"></div>
  <div id="container">
    <div id="droppable">
      <img class='img_source' src="https://helpx.adobe.com/content/dam/help/en/photoshop/using/convert-color-image-black-white/jcr_content/main-pars/before_and_after/image-before/Landscape-Color.jpg" />
    </div>
  </div>
  <div id="info"></div>

  <div class="hide" id="template">
    <fieldset>
      <legend>Position</legend>
      <input type="text" name="dragItemPositionX" id="dragItemPositionX" />
      <input type="text" name="dragItemPositionY" id="dragItemPositionY" />
      <fieldset>
        <input type="button" id="saveKnob" value="Save Knob" />
        <input type="button" id="removeKnob" value="Remove Knob" />
      </fieldset>
      </form>
  </div>
</body>

CSS

html {
  overflow: -moz-scrollbars-vertical;
  overflow-y: scroll;
}

.dial {
  cursor: pointer;
}

.dial {
  width: 60px;
}

#container {
  Background: #fbfbfb;
  float: left;
  padding: 20px;
  margin-top: 20px;
  width: 100%;
  width: calc(100% - 40px);

}

#droppable {
  float: left;
}

.img_source {
  display: block;
  width: 200px;
}

.gear_grid {
  background: #f5f5f5;
  height: 600px;
}

#device {
  float: left;
  padding-top: 20px;
  width: 100%;

}

#info {
  padding: 20px;
  background: #f5f5f5;
  float: left;
  width: calc(100% - 40px);
  box-sizing: border-box;
  width: 100%;
}

#info form {
  display: none;
}

#drop_del {
  background: #FFF;
  height: 200px;
  position: relative;

}

.editable {
  position: absolute !important
}

.input_value {
  width: 60px;
  font-size: 11px;
  display: block;
  text-align: center;
  border: none;
  background: none;
}


#imagePreview {
  width: 180px;
  height: 180px;
  background-position: center center;
  background-size: cover;
  -webkit-box-shadow: 0 0 1px 1px rgba(0, 0, 0, .3);
  display: inline-block;
}

.upload-msg {
  text-align: center;
  padding-top: 70px;
  padding-left: 30px;
  padding-right: 30px;
  font-size: 22px;
  color: #aaa;
  width: 240px;
  height: 200px;
  margin: 10px auto;
  border: 1px solid #aaa;
}

.upload.ready #upload-section {
  display: block;

}

.upload.ready .buttons .upload-result,
.upload.ready .buttons .reset {
  display: inline;
}

.upload #upload-section,
.upload .buttons .upload-result,
.upload .buttons .reset,
.upload.ready .upload-msg {
  display: none;

}

#upload {
  position: absolute;
  top: -1000px;

}

.upload.ready {
  background: #f1f1f1;
  padding: 20px;
  border: 1px solid grey;
}

#btn {
  background-color: #189094;
  color: white;
  padding: 10px 15px;
  border-radius: 3px;
  border: 1px solid rgba(255, 255, 255, 0.5);
  font-size: 16px;
  cursor: pointer;
  text-decoration: none;
  text-shadow: none;
  cursor: pointer;
  width: auto;
  margin: 0...

JavaScript

$(function() {
  function uuid() {
    var dt = new Date().getTime();
    var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
      var r = (dt + Math.random() * 16) % 16 | 0;
      dt = Math.floor(dt / 16);
      return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16);
    });
    return uuid;
  }


  // Create default knob
  $('#knob').jqxKnob({
    width: 34,
    height: 34,
    disabled: true,
    value: 0,
    min: 0,
    max: 100,
    startAngle: 120,
    endAngle: 420,
    snapToStep: true,
    rotation: 'clockwise',
    style: {
      stroke: '#000',
      strokeWidth: 1,
      fill: {
        color: '#fff'
      }
    },
    pointer: {
      type: 'line',
      thickness: 4,
      style: {
        fill: "#00a4e1",
        stroke: "#00a4e1"
      },
      size: '70%',
      offset: '0%'
    }
  });

  //Drag default knob in #droppable div

  $(".draggable").draggable({
    containment: "#droppable",
    appendTo: "#droppable",
    helper: "clone"
  });

  // Drag&Drop default knob

  $("#droppable").droppable({
    drop: function(event, ui) {

      //Generate UUID
      var UUID = uuid();

      // Change class in order to stop the cloning in droppable div.

      if (ui.draggable.hasClass("draggable")) {
        var $item = $(ui.helper).clone();
        $item.toggleClass("draggable editable");
        $item.attr('data-id', UUID);
        $(this).append($item);
        $(".editable").draggable({
          containment: "#droppable",
          appendTo: "#droppable",
          drag: function(event, ui) {
            $("#dragItemPositionX[data-id=" + UUID + "]").val(ui.position.left);
            $("#dragItemPositionY[data-id=" + UUID + "]").val(ui.position.top);
          }
        });
        //Add a form  & fill some values

        $("#info").append("<form class='pure-form knob' name=" + UUID + " data-id=" + UUID + ">");
        $("form[data-id=" + UUID + "]").append($("#template").html());
        $("form[data-id=" + UUID +...