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">
<form id="knob-form-0">
<legend>Position</legend>
<input type="text" class="drag-x" name="dragItemPositionX[]" id="dragItemPositionX-0" />
<input type="text" class="drag-y" name="dragItemPositionY[]" id="dragItemPositionY-0" />
<fieldset>
<input type="button" id="saveKnob-0" value="Save Knob" />
<input type="button" id="removeKnob-0" value="Remove Knob" />
</fieldset>
</form>
</div>
</body>
CSS
html {
overflow: -moz-scrollbars-vertical;
overflow-y: scroll;
}
.dial {
cursor: pointer;
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 auto;
}
#result {
...
JavaScript
$(function() {
function getId() {
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;
}
function makeKnobDrag(item) {
return $(item).draggable({
containment: "#droppable",
drag: function(event, ui) {
$("#knob-form-" + $(item).data("form") + " .drag-x").val(ui.position.left);
$("#knob-form-" + $(item).data("form") + " .drag-y").val(ui.position.top);
}
});
}
function getActiveKnobPosition() {
return $(".active_knob").closest(".jqx-knob").position();
}
function makeForm(target, uuid) {
var c = $(".active_knob").closest(".jqx-knob").data("form");
var form = $("<form>", {
class: "pure-form knob",
name: uuid,
"data-id": uuid,
id: "knob-form-" + c
}).appendTo(target);
form.append($("#template form").children().clone());
form.find('input').each(function(i, el) {
$(el).attr({
name: $(el).attr("name") + "[]",
"data-id": uuid,
id: $(el).attr("id").substring(0, $(el).attr("id").indexOf("-")) + c
});
});
$("form.knob").hide();
var kPos = getActiveKnobPosition();
$(".drag-x", form).val(kPos.left);
$(".drag-y", form).val(kPos.top);
form.show();
}
// 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...