Hello
Why is this .js SO-SLOW and Finicky (keeps loosing connection to cursor) :
https://vmars.us/Guitar/Drag-Drop-Clone-Working-Multiple-Elements-SO-SLOW.html
and this SO FAST :
https://www.kirupa.com/html5/examples/drag_multiple.htm
And how can I make SO-Slow Slow Fast
See Codes below :
SO-SLOW:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no" />
<title>
https://vmars.us/Guitar/Drag-Drop-Clone-Working-Multiple-Elements-SO-SLOW.html
</title>
<style>
body {
margin: 20px;
}
#imageContainer {
}
#container {
width: 1420px;
height: 430px;
background-color: #EEE;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
border-radius: 7px;
touch-action: none;
}
.item {
touch-action: none;
user-select: none;
position: relative;
}
.item img {
pointer-events: auto;
}
.item,
#elem1 {
width: 32px;
height: 32px;
/* top: 0px;
left: 0px;
stroke-opacity:0;
*/
z-index: 800;
}
.item,
#elem2 {
width: 28px;
height: 28px;
z-index: 500;
}
.item,
#elem3 {
width: 28px;
height: 28px;
z-index: 500;
}
.item,
#elem4 {
width: 28px;
height: 28px;
z-index: 500;
}
.item:active {
opacity: .75;
}
.item:hover {
cursor: pointer;
}
/* h1 {
margin-bottom: 10px;
}
*/
</style>
</head>
<body>
<h3>
<a href="https://vmars.us/Guitar/Drag-Drop-Clone-Working-Multiple-Elements-SO-SLOW.html">
https://vmars.us/Guitar/Drag-Drop-Clone-Working-Multiple-Elements-SO-SLOW.html</a>
<br>
</h3>
<div id="imageContainer" style="text-align:center">
<img class="item" id="elem1" src="https://vmars.us/Guitar/1-Red-Circle-Transp-32x32.png">
<img class="item" id="elem2" src="https://vmars.us/Guitar/flatAccidental-Grey-28x28.png">
<img class="item" id="elem3" src="https://vmars.us/Guitar/naturalAccidental-Grey-28x28.png">
<img class="item" id="elem4" src="https://vmars.us/Guitar/sharpAccidental-Grey-28x28.png">
<div style="text-align:center;">
<hr id="hr01">
</div>
</div> <!-- id="imageContainer" -->
<script>
var elemNumber = 1;
var clodeId;
var clonerID;
// =================================================
document.addEventListener('contextmenu', fireContextMenu);
// This function will be called whenever contextmenu event occurs
function fireContextMenu(event) {
event.preventDefault();
//console.log("function fireContextMenu(event)") ;
console.log("event.target.id = " + event.target.id)
// Create a copy of it
var clone = event.target.cloneNode(true); // 181
clone.addEventListener("dragstart", (event) => { drag(event); });
/*
if (clone.id == "elem1" || clone.id == "elem2" || clone.id == "elem3" || clone.id == "elem4" || clone.id == "elem5"
|| clone.id == "elem6" || clone.id == "elem7" || clone.id == "elem8" || clone.id == "elem9" || clone.id == "elem10")
{ console.log("Yep , " + clone.id + " is Clone-able !") ;
}else{
console.log("NOPE , " + clone.id + " is NOT Clone-able !") ;
return ;
}
*/
//Update the ID and add a class
clone.id = 'elem11' + elemNumber;
console.log("New clone.id = " + clone.id)
//
clone.draggable = 'true'; // 148
//clone.onclick = "helloConsole()"
clone.zIndex = elemNumber;
elemNumber = elemNumber + 1
// KIRUPA: This is to ensure whatever transform was initially applied doesn't carry over to the cloned element
clone.style.transform = "";
// Inject it into the DOM
// KIRUPA: Notice that I am adding it as a child of "container", for your drag code only listens
// to drag operations on the container element. The "draggable" attribute doesn't do much for you here.
container.appendChild(clone);
}
// =================================================
</script>
<script>
var container = document.querySelector("#imageContainer");
var activeItem = null;
var active = false;
container.addEventListener("touchstart", dragStart, false);
container.addEventListener("touchend", dragEnd, false);
container.addEventListener("touchmove", drag, false);
container.addEventListener("mousedown", dragStart, false);
container.addEventListener("mouseup", dragEnd, false);
container.addEventListener("mousemove", drag, false);
function dragStart(e) {
clonerID = e.target.id;
if (e.target !== e.currentTarget) {
active = true;
// this is the item we are interacting with
activeItem = e.target;
// console.log("activeItem = " + activeItem);
if (activeItem !== null) {
if (!activeItem.xOffset) {
activeItem.xOffset = 0;
}
if (!activeItem.yOffset) {
activeItem.yOffset = 0;
}
if (e.type === "touchstart") {
activeItem.initialX = e.touches[0].clientX - activeItem.xOffset;
activeItem.initialY = e.touches[0].clientY - activeItem.yOffset;
} else {
if (clonerID == "elem1" || clonerID == "elem2" || clonerID == "elem3" || clonerID == "elem4" || clonerID == "elem5"
|| clonerID == "elem6" || clonerID == "elem7" || clonerID == "elem8" || clonerID == "elem9" || clonerID == "elem10")
{ console.log("clonerID = " + clonerID);
return ; }
activeItem.initialX = e.clientX - activeItem.xOffset;
activeItem.initialY = e.clientY - activeItem.yOffset;
}
}
}
}
function dragEnd(e) {
if (activeItem !== null) {
activeItem.initialX = activeItem.currentX;
activeItem.initialY = activeItem.currentY;
}
active = false;
activeItem = null;
}
function drag(e) {
e.preventDefault();
if (active) {
if (e.type === "touchmove") {
activeItem.currentX = e.touches[0].clientX - activeItem.initialX;
activeItem.currentY = e.touches[0].clientY - activeItem.initialY;
} else {
activeItem.currentX = e.clientX - activeItem.initialX;
activeItem.currentY = e.clientY - activeItem.initialY;
}
activeItem.xOffset = activeItem.currentX;
activeItem.yOffset = activeItem.currentY;
setTranslate(activeItem.currentX, activeItem.currentY, activeItem);
}
}
function setTranslate(xPos, yPos, el) {
el.style.transform = "translate3d(" + xPos + "px, " + yPos + "px, 0)";
}
</script>
SO FAST :
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no" />
<title>Drag Multiple Elements</title>
<link href="https://www.kirupa.com/ssi/newDesign/kirupa_html5.css" rel="stylesheet" type="text/css">
<style>
body {
margin: 20px;
}
#container {
width: 600px;
height: 400px;
background-color: #333;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
border-radius: 7px;
touch-action: none;
}
.item {
border-radius: 50%;
touch-action: none;
user-select: none;
position: relative;
}
.one {
width: 100px;
height: 100px;
background-color: rgb(245, 230, 99);
border: 10px solid rgba(136, 136, 136, .5);
top: 0px;
left: 0px;
}
.two {
width: 60px;
height: 60px;
background-color: rgba(196, 241, 190, 1);
border: 10px solid rgba(136, 136, 136, .5);
top: 30%;
left: 10%;
}
.three {
width: 40px;
height: 40px;
background-color: rgb(0, 255, 231);
border: 10px solid rgba(136, 136, 136, .5);
top: -40%;
left: -10%;
}
.four {
width: 80px;
height: 80px;
background-color: rgb(233, 210, 244);
border: 10px solid rgba(136, 136, 136, .5);
top: -10%;
left: 5%;
}
.item:active {
opacity: .75;
}
.item:hover {
cursor: pointer;
}
h1 {
margin-bottom: 10px;
}
</style>
</head>
<body>
<h1>Drag Multiple Elements</h1>
<div id="outerContainer">
<div id="container">
<div class="item one">
</div>
<div class="item two">
</div>
<div class="item three">
</div>
<div class="item four">
</div>
</div>
<br>
<p class="callout">Check out the <a href="https://www.kirupa.com/html5/drag.htm" class="blueEmphasis">tutorial</a> or the <a href="https://forum.kirupa.com/t/create-a-draggable-element-in-javascript/638149/3" class="blueEmphasis">discussion</a> around this effect.</p>
</div>
<script>
var container = document.querySelector("#container");
var activeItem = null;
var active = false;
container.addEventListener("touchstart", dragStart, false);
container.addEventListener("touchend", dragEnd, false);
container.addEventListener("touchmove", drag, false);
container.addEventListener("mousedown", dragStart, false);
container.addEventListener("mouseup", dragEnd, false);
container.addEventListener("mousemove", drag, false);
function dragStart(e) {
if (e.target !== e.currentTarget) {
active = true;
// this is the item we are interacting with
activeItem = e.target;
if (activeItem !== null) {
if (!activeItem.xOffset) {
activeItem.xOffset = 0;
}
if (!activeItem.yOffset) {
activeItem.yOffset = 0;
}
if (e.type === "touchstart") {
activeItem.initialX = e.touches[0].clientX - activeItem.xOffset;
activeItem.initialY = e.touches[0].clientY - activeItem.yOffset;
} else {
console.log("doing something!");
activeItem.initialX = e.clientX - activeItem.xOffset;
activeItem.initialY = e.clientY - activeItem.yOffset;
}
}
}
}
function dragEnd(e) {
if (activeItem !== null) {
activeItem.initialX = activeItem.currentX;
activeItem.initialY = activeItem.currentY;
}
active = false;
activeItem = null;
}
function drag(e) {
if (active) {
if (e.type === "touchmove") {
e.preventDefault();
activeItem.currentX = e.touches[0].clientX - activeItem.initialX;
activeItem.currentY = e.touches[0].clientY - activeItem.initialY;
} else {
activeItem.currentX = e.clientX - activeItem.initialX;
activeItem.currentY = e.clientY - activeItem.initialY;
}
activeItem.xOffset = activeItem.currentX;
activeItem.yOffset = activeItem.currentY;
setTranslate(activeItem.currentX, activeItem.currentY, activeItem);
}
}
function setTranslate(xPos, yPos, el) {
el.style.transform = "translate3d(" + xPos + "px, " + yPos + "px, 0)";
}
</script>