Hi, Kirupa @kirupa
Thanks for the great tutorial.
Please help me I only want to make a draggable player div miniplayer
when change the class with jquary
Example: https://codepen.io/xvids/pen/KKdMrOq
Thanks…
Hi, Kirupa @kirupa
Thanks for the great tutorial.
Please help me I only want to make a draggable player div miniplayer
when change the class with jquary
Example: https://codepen.io/xvids/pen/KKdMrOq
Thanks…
Hi, I expanded on this example to include mouse scrolling. However, I have to move the mouse after the scroll action, in order for the element position to be rendered. Is there a way to update and render the position on scroll alone?
Here is an example fiddle of what I have. Thanks.
https://jsfiddle.net/n2fole00/Lxdjf15h/
Hi @kirupa
This tutorial helped me a lot and is so well explained!
Thank you for sharing it!
I noticed that the draggable element goes outside its container on mobile. How can I prevent this behaviour? I would like it to move only inside the container and stop just before the edges of the container (as it already happens on desktop).
Thanks in advance
Hi @icuccia! Welcome to the forums
Even on desktop, the draggable element goes outside the container. At least when I tested, holding a circle at the edge and dragging it towards an opposing side:
Do you still want to stop the circle from hitting the edge, or are you interested in having consistent behavior between mobile and desktop?
Cheers,
Kirupa
Hi @kirupa
Thanks for your quick response!
I would like to stop the circle to go outside the container on both desktop and mobile.
Is there a way to do so?
Thanks
Yes - there is a way to do that, but I have been too busy with work this week to fiddle with this
One approach that would work is having a boolean value for moving up, down, left, and right and stopping movement in a particular direction if the edge of a circle hits an appropriate edge. I was thinking IntersectionObserver could help with that.
The other approach is that we know the size of the circle and the size of the container. We can mathematically calculate the boundary and restrict movement that way.
I don’t know how helpful this is, but these are the things running through my mind on how I would potentially implement this.
Cheers,
Kirupa
Hi Kirupa! Thanks a lot for your tutorial!
In a program I’m working on, I’d like to cancel the drag and drop effect once a button has been clicked on, meaning that you cannot drag or drop once that button has been pressed. I was thinking of maybe using element.onclick and cancel all the eventListeners for dragging and dropping, how can I achieve that?
Thanks again for sharing!
Is it bad for the mousemove eventlistener to be called every time that the mouse moves even when it’s not dragging anything? I know there is an if statement but doesn’t the function still have to check the if statement every time it is moved? can you add eventlistener when it’s needed and remove it on mouse up?
That is a great observation. I did some benchmarking on this a short while ago, and the differences aren’t that noticeable for this particular case since the calculations performed for a drag aren’t computationally intensive. One optimization that I have done in other implementations of this is to use requestAnimationFrame
to throttle chatty events like our mousemove.
The techniques outlined there may help
Cheers,
Kirupa
Hi I am new here but have been learning various aspects of JS for a few years. I loved this tutorial and made my own working example. My question is how do I create a radial boundry? I created a square one easy enough as you can see, but that makes the element drag a bit choppy on the corners.
Here is the src (forgive me if It does not fornat right. I am new to posting code)
#boundry { width: 25vh; height: 25vh; background: grey; border-radius: 100%; position: absolute; bottom: 0vh; } #pad{ width: 15vh; height: 15vh; background: lightgrey; border-radius: 100%; position: relative; }ActiveInitial X ValueInitial Y ValueCurrent X ValueCurrent Y ValueX OffsetY Offset<script type="text/javascript" charset="utf-8"> (function app(){ //ui for controller const boundry = document.getElementById("boundry"); const pad = document.getElementById("pad"); //ui for data const startingX = document.getElementById("initialX"); const startingY = document.getElementById("initialY"); const activeX = document.getElementById("currentX"); const activeY = document.getElementById("currentY"); const offSetX = document.getElementById("xOffset"); const offSetY = document.getElementById("yOffset"); //init variables let activeState = false; let currentX, currentY, initialX, initialY, xOffset = 0, yOffset = 0, bOffsetWidth = boundry.offsetWidth, bOffsetHeight = boundry.offsetHeight; padOffsetWidth = pad.offsetWidth; padOffsetHeight = pad.offsetHeight; const log = console.log; //Create event listeners pad.addEventListener("touchstart", dragStart, false); pad.addEventListener("touchend", dragEnd, false); pad.addEventListener("touchmove", drag, false); pad.addEventListener("mousedown", dragStart, false); pad.addEventListener("mouseup", dragEnd, false); pad.addEventListener("mousemove", drag, false); //function triggers on touchstart or mousedown function dragStart(e) { if (e.type === "touchstart") { initialX = e.touches[0].clientX - xOffset; initialY = e.touches[0].clientY - yOffset; //ui code startingX.value = initialX; startingY.value = initialY; offSetX.value = xOffset; offSetY.value = yOffset; } else { initialX = e.clientX - xOffset; initialY = e.clientY - yOffset; } if (e.target === pad) { activeState = true; //ui code isActive.value = activeState; } } //function triggers on touchend or mouseup function dragEnd(e) { initialX = currentX; initialY = currentY; activeState = false; //ui code isActive.value = activeState; } //function triggers on touchmove or mousemove function drag(e) { if (activeState) { e.preventDefault(); if (e.type === "touchmove") { currentX = e.touches[0].clientX - initialX; currentY = e.touches[0].clientY - initialY; //boundry code if(currentX > bOffsetWidth - padOffsetWidth){ currentX = bOffsetWidth - padOffsetWidth; } else if(currentX < 0) { currentX = 0; } if(currentY > bOffsetHeight - padOffsetHeight){ currentY = bOffsetHeight - padOffsetHeight; } else if(currentY < 0){ currentY = 0; } //ui code activeX.value = currentX; activeY.value = currentY; } else { currentX = e.clientX - initialX; currentY = e.clientY - initialY; } xOffset = currentX; yOffset = currentY; setTranslate(currentX, currentY, pad); } } function setTranslate(xPos, yPos, el) { el.style.transform = "translate3d(" + xPos + "px, " + yPos + "px, 0)"; } })(); </script>
I don’t have a non-d3 solution, but this may help you: https://stackoverflow.com/questions/25620544/limit-drag-movements-to-a-circular-svg-boundary
A SVG boundary might be the easiest way to do this, but I haven’t tried it to know what gotchas you may run into
Thank you Kirupa. Ill play around with it. I did some research and found that you can mathimatically define an imaginary circle inaide a square. If I get it working Ill post an update.
A nice addition to this program would be too include element.setPointerCapture so that dragging outside of the window still gets touch events.
Good idea! I will add it to my notes when updating this article shortly
Thanks, these are helpful for me
Hi, I am using your code and trying to add items via document.createElement, and it works really well, except the fact that when I create the element it keeps going to the left, infinitively, wich is like when I create a element it creates its div, and as I move the element (or not) the div is still created that place so the “display:flex” will keep trying to add next to the div, and the thing keeps growing and hiding the other elements… Anyone got any ideas?
Try centering the flex box of divs. Look up the CSS for coding the layout of the actual flex box.
You may also want to center the actual div as well as it’s content.
So aparently, setting the Item as absolute works fine… Wich is weird since last time I tried it went everywhere…
Dear all,
I am trying to add some boundary on this code but I fail. Let’ s say something like the element cannot be dragged over 200px upwards. Any idea someone. Thank all the community a lot
Hi Kirupa, thank you for this excellent description!
I am creating a game with letters and I would like that when I move a letter, it should snap to a position relative to a grid. Could you please tell me how can I correct the end position in the dragEnd () function, I have tried using el.style.top and el.style.left but it does not give satisfactory results.
:: Copyright KIRUPA 2024 //--