# Create a Draggable Element in JavaScript

**URL:** <https://forum.kirupa.com/t/create-a-draggable-element-in-javascript/638149>\
**Category:** programming\
**Created:** [April 28, 2018, 5:27am UTC](https://forum.kirupa.com/t/create-a-draggable-element-in-javascript/638149 "2018-04-28T05:27:37Z")\
**Posts on this page:** 20\
**Page:** 3

<div class="post-metadata">

**Author:** ![kirupa](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/kirupa/32/11616_2.png) [@kirupa](https://forum.kirupa.com/u/kirupa)\
**Post date:** [March 6, 2019, 8:49pm UTC](https://forum.kirupa.com/t/create-a-draggable-element-in-javascript/638149/42 "2019-03-06T20:49:26Z")

</div>

What gesture are you planning to use to rotate the element? The rotation is something that can be done by using a `rotate` CSS transform.

---

<div class="post-metadata">

**Author:** ![jmacky](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/jmacky/32/12021_2.png) [@jmacky](https://forum.kirupa.com/u/jmacky)\
**Post date:** [March 6, 2019, 10:29pm UTC](https://forum.kirupa.com/t/create-a-draggable-element-in-javascript/638149/43 "2019-03-06T22:29:42Z")

</div>

The game should be for mouse and touch as in your drag tutorial. I am assuming that touch or click plus drag would move the shape (existing code), whereas touch or click plus lift the pointer would rotate the shape. So you move the shape over the pattern then rotate the shape so it will fit in place and then move the shape to final position. The pattern will be a white outline that can be selected from a group of patterns on the right side of the screen and then appear in the center work space. I am suggesting a rotation of 22.5 degree increments so that the kids have more options to make their own objects if they don’t want to use a pattern. Separating the drag and rotate functions with similar pointer actions is a problem. The users will be occupational therapy patients, parents, and therapists. How would the CSS rotate transform be incorporated into the existing code and identify the existing items? Thanks, Jack

---

<div class="post-metadata">

**Author:** ![kirupa](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/kirupa/32/11616_2.png) [@kirupa](https://forum.kirupa.com/u/kirupa)\
**Post date:** [March 7, 2019, 12:51am UTC](https://forum.kirupa.com/t/create-a-draggable-element-in-javascript/638149/44 "2019-03-07T00:51:00Z")

</div>

> [@jmacky](#):
>
> Separating the drag and rotate functions with similar pointer actions is a problem.

This is the part I was worried about, but I think we can differentiate between a drag and click. Check out the following snippet:

```
<!DOCTYPE html>
<html>

<head>
  <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no" />
  <title>Drag Multiple Images</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: #EEE;
      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;
    }

    .item img {
      pointer-events: none;
    }

    .one {
      width: 100px;
      height: 100px;
      top: 0px;
      left: 0px;
    }

    .two {
      width: 60px;
      height: 60px;
      top: 30%;
      left: 10%;
    }

    .three {
      width: 40px;
      height: 40px;
      top: -40%;
      left: -10%;
    }

    .four {
      width: 80px;
      height: 80px;
      top: -10%;
      left: 5%;
    }

    .item:active {
      opacity: .75;
    }

    .item:hover {
      cursor: pointer;
    }

    h1 {
      margin-bottom: 10px;
    }
  </style>
</head>

<body>
  <h1>Drag Multiple Images</h1>
  <div id="outerContainer">
    <div id="container">
      <div class="item one">
        <img src="https://www.kirupa.com/icon/1f6a7.svg">
      </div>
      <div class="item two">
        <img src="https://www.kirupa.com/icon/1f680.svg">
      </div>
      <div class="item three">
        <img src="https://www.kirupa.com/icon/1f35d.svg">
      </div>
      <div class="item four">
        <img src="https://www.kirupa.com/icon/1f5fa.svg">
      </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="http://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;
    var dragging = 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);

    container.addEventListener("click", rotateElement, false);

    function dragStart(e) {
      if (e.target !== e.currentTarget) {
        active = true;
        dragging = false;

        // this is the item we are interacting with
        activeItem = e.target;

        if (activeItem.degrees === undefined) {
          activeItem.degrees = 0;
        }

        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 {
            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) {

        dragging = true;

        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 rotateElement(e) {
      if (dragging === false) {

        if (activeItem === null) {
          activeItem = e.target;
        }

        console.log(activeItem.degrees);

        activeItem.degrees += 22.5;
        
        activeItem.querySelector("img").style.transform = `rotate(${activeItem.degrees}deg)`;
      }
    }

    function setTranslate(xPos, yPos, el) {
      el.style.transform = `translate3d(${xPos}px, ${yPos}px, 0)`;
      //el.querySelector("img").style.transform = `rotate(${degrees}deg)`;
    }
  </script>
</body>

</html>

```

Does this work for your needs? The way this example work is by using a `dragging` variable to differentiate between a regular click and a drag operation. If the click was indeed a click, I rotate the child image by 22.5 degrees. The repositioning logic deals with the parent element, and the rotation deals with the child image element. This is a silly trick dealing with how transforms work and figuring out a way to set two different transform values.

🏃‍♂️

---

<div class="post-metadata">

**Author:** ![jmacky](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/jmacky/32/12021_2.png) [@jmacky](https://forum.kirupa.com/u/jmacky)\
**Post date:** [March 7, 2019, 4:36pm UTC](https://forum.kirupa.com/t/create-a-draggable-element-in-javascript/638149/45 "2019-03-07T16:36:52Z")

</div>

Your solution works great! How can I thank you? Jack

---

<div class="post-metadata">

**Author:** ![kirupa](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/kirupa/32/11616_2.png) [@kirupa](https://forum.kirupa.com/u/kirupa)\
**Post date:** [March 7, 2019, 5:51pm UTC](https://forum.kirupa.com/t/create-a-draggable-element-in-javascript/638149/46 "2019-03-07T17:51:41Z")

</div>

Glad to hear it!

> [@jmacky](#):
>
> How can I thank you?

Help someone else out one day who has a strange technical problem 😛

---

<div class="post-metadata">

**Author:** ![jmacky](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/jmacky/32/12021_2.png) [@jmacky](https://forum.kirupa.com/u/jmacky)\
**Post date:** [March 27, 2019, 6:07pm UTC](https://forum.kirupa.com/t/create-a-draggable-element-in-javascript/638149/47 "2019-03-27T18:07:46Z")

</div>

Kirupa, My previous problem was with dragging and rotating shapes in a Tangram game. That can now be done, but when dragging the user must be careful not to accidentally rotate the shape when stopping drag. Also when dragging the user must have the cursor on the shape when they stop dragging. If cursor is not on the shape when they click or lift finger to stop dragging, the dragging action is not stopped (though the shape may not be moving at the moment) when they move the cursor near the shape it starts moving again without any new click, and until they get the cursor on the shape (not easy on small shapes) they cannot stop the dragging function. “Make a Face” (a therapy program I am doing to help children identify and locate facial parts) has the same problems. Any help would be appreciated. The problems can be easily seen by viewing [https://www.therapygames.online/face/face.html](https://www.therapygames.online/face/face.html) and trying to move a face component rapidly. The part does not always stay with the cursor. Thanks, Jack

---

<div class="post-metadata">

**Author:** ![jmacky](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/jmacky/32/12021_2.png) [@jmacky](https://forum.kirupa.com/u/jmacky)\
**Post date:** [March 27, 2019, 6:27pm UTC](https://forum.kirupa.com/t/create-a-draggable-element-in-javascript/638149/48 "2019-03-27T18:27:11Z")

</div>

Also above does not appear to be a problem using a finger on a touch pad but is a problem on a touch pad using a mouse. Thanks, Jack

---

<div class="post-metadata">

**Author:** ![kirupa](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/kirupa/32/11616_2.png) [@kirupa](https://forum.kirupa.com/u/kirupa)\
**Post date:** [March 28, 2019, 5:39am UTC](https://forum.kirupa.com/t/create-a-draggable-element-in-javascript/638149/49 "2019-03-28T05:39:07Z")

</div>

I totally see the problem, but I’m a bit swamped to look into this right now. I’ll do my best to get back to you on this soon. This might be a really simple fix or something that will involve some complicated tricks, and I don’t have a guess on where in that range the right answer will fall 🚑

---

<div class="post-metadata">

**Author:** ![jmacky](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/jmacky/32/12021_2.png) [@jmacky](https://forum.kirupa.com/u/jmacky)\
**Post date:** [March 28, 2019, 4:40pm UTC](https://forum.kirupa.com/t/create-a-draggable-element-in-javascript/638149/50 "2019-03-28T16:40:13Z")

</div>

Thank you. I have research the issues between mouse and touch and have not found any kind of a fix, just a lot of discussion about the issues.

---

<div class="post-metadata">

**Author:** ![Cezary](https://avatars.discourse-cdn.com/v4/letter/c/e19adc/32.png) [@Cezary](https://forum.kirupa.com/u/Cezary)\
**Post date:** [April 3, 2019, 5:19pm UTC](https://forum.kirupa.com/t/create-a-draggable-element-in-javascript/638149/51 "2019-04-03T17:19:50Z")

</div>

Hello,  
The script works perfectly !  
but I have one question, how to prevent element from disappearing when i drag him through the border line?, how to stop him inside to not let him pass the container shape

Thanks in advance 🙂

---

<div class="post-metadata">

**Author:** ![Ozyris](https://avatars.discourse-cdn.com/v4/letter/o/13edae/32.png) [@Ozyris](https://forum.kirupa.com/u/Ozyris)\
**Post date:** [June 6, 2019, 1:10pm UTC](https://forum.kirupa.com/t/create-a-draggable-element-in-javascript/638149/52 "2019-06-06T13:10:55Z")

</div>

Hi Kirupa!  
Don’t know if you remember me - doing well with your book!  
I am currently making a simulated cassette player for my website, including a “fake” range slider as a volume control, using your excellent “dragging” technique. I have limited it to the horizontal direction only, but I need to restrict the left-right movement to between two fixed points. Suggestions?

---

<div class="post-metadata">

**Author:** ![Ozyris](https://avatars.discourse-cdn.com/v4/letter/o/13edae/32.png) [@Ozyris](https://forum.kirupa.com/u/Ozyris)\
**Post date:** [June 6, 2019, 1:16pm UTC](https://forum.kirupa.com/t/create-a-draggable-element-in-javascript/638149/53 "2019-06-06T13:16:17Z")

</div>

Hi jmacky - don’t know if this will be your answer, but while Kirupa is busy (it’s a difficult life being so popular!) you could check it out.

The dragging function is cancelled when you release the mouse over the dragged item. The “mouseup” event won’t fire if the pointer is not over it. Try also making the dragEnd() function run on “mouseout” - when it leaves the dragged item.

Unless the dragging function is cancelled the item will keep following the mouse pointer.

---

<div class="post-metadata">

**Author:** ![kirupa](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/kirupa/32/11616_2.png) [@kirupa](https://forum.kirupa.com/u/kirupa)\
**Post date:** [June 7, 2019, 7:23pm UTC](https://forum.kirupa.com/t/create-a-draggable-element-in-javascript/638149/54 "2019-06-07T19:23:54Z")

</div>

I can fiddle with that and see if I can provide you with some code.

For what you are trying to do, have you thought about using an actual slider element? That way you get some of the dragging for free, and you also get accessibility, keyboard shortcuts, and more as well.

---

<div class="post-metadata">

**Author:** ![Ozyris](https://avatars.discourse-cdn.com/v4/letter/o/13edae/32.png) [@Ozyris](https://forum.kirupa.com/u/Ozyris)\
**Post date:** [June 7, 2019, 8:08pm UTC](https://forum.kirupa.com/t/create-a-draggable-element-in-javascript/638149/55 "2019-06-07T20:08:09Z")

</div>

Hi Mr K!! Long time no chat!!  
I managed to come up with a solution already. I did think of using a range slider but I wanted a custom old fashioned image for the knob to match an old cassette. The “thumb” does not seem to be consistently implemented yet and accessing it to style it seems a bit of a mission. It was easier to use your brilliant “translate3d” idea, limit it to one axis, and use an “if…else if…else” to impose a minimum and maximum value to the slider. I’ll send you a link once I have the rest of it performing correctly. Getting very excited here!

Once I’m done you might tell me if my code is clumsy or inefficient or whatever so I can learn some more from the master!

Thanks for being out there for us all!

---

<div class="post-metadata">

**Author:** ![Ozyris](https://avatars.discourse-cdn.com/v4/letter/o/13edae/32.png) [@Ozyris](https://forum.kirupa.com/u/Ozyris)\
**Post date:** [June 9, 2019, 9:51pm UTC](https://forum.kirupa.com/t/create-a-draggable-element-in-javascript/638149/56 "2019-06-09T21:51:28Z")

</div>

Greetings again O Awesome JS Guru!  
I’m all excited now I have the Cassette Player working completely as I want it! Here’s a link:  
[http://www.smooth-operator.co.uk/SmoothCassette.html](http://www.smooth-operator.co.uk/SmoothCassette.html)  
It will next be integrated into our website. Looking forward to your feedback!  
Have a great week!

---

<div class="post-metadata">

**Author:** ![Ozyris](https://avatars.discourse-cdn.com/v4/letter/o/13edae/32.png) [@Ozyris](https://forum.kirupa.com/u/Ozyris)\
**Post date:** [June 9, 2019, 9:55pm UTC](https://forum.kirupa.com/t/create-a-draggable-element-in-javascript/638149/57 "2019-06-09T21:55:21Z")

</div>

BTW - you will notice it only loads the tracks when you select them. The main images will also be loaded while the construction is invisible offscreen. What I am also excited about is that if I want to add tracks, which of course I will, I have only to edit the external js file, which is basically just a list. Everything else is automatic.

Felicitations once more Mr K!  
The Cassette Player is now intregrated into our main site.  
[http://www.smooth-operator.co.uk/](http://www.smooth-operator.co.uk/)  
So the draggable element here is the volume control. Hope my code is pleasing to you!

---

<div class="post-metadata">

**Author:** ![gwgwpl](https://avatars.discourse-cdn.com/v4/letter/g/e56c9b/32.png) [@gwgwpl](https://forum.kirupa.com/u/gwgwpl)\
**Post date:** [June 22, 2019, 8:13am UTC](https://forum.kirupa.com/t/create-a-draggable-element-in-javascript/638149/58 "2019-06-22T08:13:23Z")

</div>

Hello,is it poosible to change particle moving path on the canvas on events such us touch or mousemove?  
I mean, i have particle that needs to move from point a to b,c,d(…) so along predefinied path of x and y coordinates, can i distort points of this path on touch or when pointer is near the path point?

---

<div class="post-metadata">

**Author:** ![Sarvinstyle\_Taba](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/sarvinstyle_taba/32/10446_2.png) [@Sarvinstyle\_Taba](https://forum.kirupa.com/u/Sarvinstyle_Taba)\
**Post date:** [November 25, 2019, 12:35pm UTC](https://forum.kirupa.com/t/create-a-draggable-element-in-javascript/638149/59 "2019-11-25T12:35:11Z")

</div>

Thank you so much for such a greet tutorial.  
I just need a help  
I want to drag and clone image from one div to another  
can you please help me ??

---

<div class="post-metadata">

**Author:** ![rajeshm](https://avatars.discourse-cdn.com/v4/letter/r/c57346/32.png) [@rajeshm](https://forum.kirupa.com/u/rajeshm)\
**Post date:** [November 27, 2019, 2:09am UTC](https://forum.kirupa.com/t/create-a-draggable-element-in-javascript/638149/60 "2019-11-27T02:09:45Z")

</div>

Thanks for a great tutorial. Clearly explained what I wanted to know.

---

<div class="post-metadata">

**Author:** ![never](https://avatars.discourse-cdn.com/v4/letter/n/e95f7d/32.png) [@never](https://forum.kirupa.com/u/never)\
**Post date:** [December 9, 2019, 1:10pm UTC](https://forum.kirupa.com/t/create-a-draggable-element-in-javascript/638149/61 "2019-12-09T13:10:22Z")

</div>

How to have this remember each dragged-to location, and for these to be updated in a database, so that positions would get remembered when you revisit the page?

[Previous page](https://forum.kirupa.com/t/create-a-draggable-element-in-javascript/638149.md?page=2)

[Next page](https://forum.kirupa.com/t/create-a-draggable-element-in-javascript/638149.md?page=4)
