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>