Would it be possible to stop an element from dragging once it reaches the edge of the screen? I have been trying for the past hour with no luck. Here is my code so far:
dragElement(document.getElementById("mp3Audio")); function dragElement(elmnt) { var pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0; elmnt.onmousedown = dragMouseDown; function dragMouseDown(e) { e = e || window.event; e.preventDefault(); // get the mouse cursor position at startup: pos3 = e.clientX; pos4 = e.clientY; document.onmouseup = closeDragElement; // call a function whenever the cursor moves: document.onmousemove = elementDrag; } function elementDrag(e) { e = e || window.event; e.preventDefault(); // calculate the new cursor position: pos1 = pos3 - e.clientX; pos2 = pos4 - e.clientY; pos3 = e.clientX; pos4 = e.clientY; // && elmnt.offsetTop - pos2 - Math.max(document.documentElement.clientHeight || 0, window.innerHeight || 0) >= 0 // set the element's new position: if (!(elmnt.style.top - document.documentElement.clientHeight <= 0) && !(elmnt.style.left - document.documentElement.clientWidth <= 0) && !(elmnt.style.top >= document.documentElement.clientHeight) && !(elmnt.style.left >= document.documentElement.clientWidth)){ elmnt.style.top = (elmnt.offsetTop - pos2) + "px"; elmnt.style.left = (elmnt.offsetLeft - pos1) + "px"; } } function closeDragElement() { // stop moving when mouse button is released: document.onmouseup = null; document.onmousemove = null; } }
audio{ background: #D6D6D6; border-radius: 0px; border: none; width: 100%; height: 10%; font-variant-numeric: oldstyle-nums; -webkit-text-stroke: thin; color: #FFFFFF; transition: 0.5s; } audio::-webkit-media-controls-panel{ background: #A1A1A1; border: none; }
<div id="mp3Audio" style="background: #FFFFFF; position: fixed; border: 5px solid #800000; border-radius: 10px; overflow: hidden; left: 0px; top: 0px; height: 240px; width: 426px; bottom: 1em; right: 4em;"> <img src="graphics/HighResIcon.png" style="object-fit: contain;" height="90%" width="100%"> <audio type="audio/mpeg" controlsList='nodownload' controls><source src="songs/amhere.mp3"></source></audio> </div> <button id="playbutton">e</button>
I thought I could use the clientHeight
and clientWidth
, but so far I have been unsuccessful. Any help would be much appreciated.
Advertisement
Answer
I renamed var pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
to
xPosDiff = 0, yPosDiff = 0, xPosOld = 0, yPosOld = 0;
so it were easier for me to understand them. 🙂
getBoundingClientRect()
is pretty calculation heavy but I think it’s needed for your problem. From that method, you can extract the top, right, bottom, left
from the element that you want to drag, and then I just compared it to 0, window.innerWidth, window.innerHeight, 0
, but I also added the new X and Y difference for the cursor to that comparison. So if I predict that the new movement will make the element to cross any of the boundries (top, right…), I won’t move the element.
I had to resize #mp3Audio
so it would fit inside the snippet. I also added a dashed border to better showcase the boundries.
PS. The code from W3Schools had the wrong thinking when doing the calculations IMHO, so I changed that as well. They had xPosDiff = xPosOld - e.clientX
, which seems wrong because then you need to subtract that value from the old position: elmnt.offsetTop - yPosDiff
. It seems backwards, where I prefer to add the difference instead. DS,
dragElement(document.getElementById("mp3Audio")); function dragElement(elmnt) { var xPosDiff = 0, yPosDiff = 0, xPosOld = 0, yPosOld = 0; /* ADDED */ var elmntRect; var insideTop, insideBottom, insideLeft, insideRight; elmnt.onmousedown = dragMouseDown; function dragMouseDown(e) { e = e || window.event; e.preventDefault(); // get the mouse cursor position at startup: posXOld = e.clientX; posYOld = e.clientY; document.onmouseup = closeDragElement; // call a function whenever the cursor moves: document.onmousemove = elementDrag; } function elementDrag(e) { e = e || window.event; e.preventDefault(); // calculate the new cursor position: xPosDiff = e.clientX - xPosOld; yPosDiff = e.clientY - yPosOld; xPosOld = e.clientX; yPosOld = e.clientY; /* ADDED */ elementRect = elmnt.getBoundingClientRect(); insideTop = elementRect.top + yPosDiff >= 0; insideBottom = elementRect.bottom + yPosDiff < window.innerHeight; insideLeft = elementRect.left + xPosDiff >= 0; insideRight = elementRect.right + xPosDiff < window.innerWidth; // set the element's new position: if (insideTop && insideBottom && insideLeft && insideRight) { elmnt.style.top = (elmnt.offsetTop + yPosDiff) + "px"; elmnt.style.left = (elmnt.offsetLeft + xPosDiff) + "px"; } } function closeDragElement() { // stop moving when mouse button is released: document.onmouseup = null; document.onmousemove = null; } }
html, body { margin: 0px; padding: 0px; } body { border: 2px dashed #000; height: 95vh; } audio{ background: #D6D6D6; border-radius: 0px; border: none; width: 100%; height: 10%; font-variant-numeric: oldstyle-nums; -webkit-text-stroke: thin; color: #FFFFFF; transition: 0.5s; } audio::-webkit-media-controls-panel{ background: #A1A1A1; border: none; } #mp3Audio { position: fixed; left: 0px; top: 0px; /* bottom: 1em; */ /* right: 4em; */ height: 120px; /* 240px */ width: 213px; /* 426px */ overflow: hidden; border: 5px solid #800000; border-radius: 10px; background: #FFFFFF; box-sizing: border-box; /* ADDED */ }
<div id="mp3Audio"> <img src="graphics/HighResIcon.png" style="object-fit: contain;" height="90%" width="100%"> <audio type="audio/mpeg" controlsList='nodownload' controls><source src="songs/amhere.mp3"></source></audio> </div>