2

I'm trying to write some code to create a drag and drop minigame. So far I'm having a problem with the touchable part of the code. When I added the draggable option (with cursor only) it worked perfectly.

But I tried to add some touchable code (to allow people on phones or tablets to use it as well) using this tuto : https://www.kirupa.com/html5/drag.htm .

I have one major problem though : the dragged item is going faster than the cursor the further you go from the dragstart point.

You can see the problem here with the javascript below : http://jsfiddle.net/0n8x6gue/1/

var container = document.querySelector("#section");
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;

    // item avec lequel on interagit
    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) {
    e.preventDefault();
    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)";
}
#bloc_page {
  width: 75%;
  margin: auto;
  min-width: 900px;
}

#section {
  display: flex;
  height: 500px;
  border: solid 1px;
}

h1 {
  text-align: center;
}


/* Jeu */

.yobi.ui-draggable-dragging {
  border: dashed rgba(53, 187, 243, 0.9);
}

#propositions {
  height: 100%;
  width: 25%;
  display: flex;
  flex-wrap: wrap;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}

.yobi {
  border: solid rgba(53, 187, 243, 0.9);
  padding: 8px;
  margin: 10px;
  font-size: 24px;
  font-weight: bold;
  text-align: center;
  list-style-type: none;
  background-color: white;
  user-select: none;
}

 :hover {
  border-color: rgba(255, 134, 172, 0.9);
  cursor: pointer;
}

 :active {
  cursor: none;
}
<!DOCTYPE html>

<html lang="fr" xmlns="http://www.w3.org/1999/xhtml">

<head>
  <meta charset="utf-8" />
  <title>Test</title>
  <!--Titre de la page dans l'onglet en haut-->
  <link href="main.css" rel="stylesheet" />
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
  <script type="text/javascript" src="app.js" async></script>
  <script>
    (window.jQuery || document.write('<script src="/scripts/jquery-3.6.0.min.js"><\/script>'));
  </script>
  <!--Charger jQuery depuis fichier local si le CDN est indisponible-->
  <link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/smoothness/jquery-ui.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
</head>

<body>
  <div id="bloc_page">
    <header>
      <h1>Les Jours de la Semaine - 曜日</h1>
    </header>

    <section id="section">
      <div id="propositions">
        <ul>
          <li class="yobi">げつようび</li>
          <li class="yobi">かようび</li>
          <li class="yobi">すいようび</li>
          <li class="yobi">もくようび</li>
          <li class="yobi">きんようび</li>
          <li class="yobi">どようび</li>
          <li class="yobi">にちようび</li>
        </ul>
      </div>
    </section>
  </div>
</body>

</html>
General Grievance
  • 4,555
  • 31
  • 31
  • 45
Voctor
  • 47
  • 7

1 Answers1

0

Looks like the problem is in setTranslate function. Your block already moves by setting activeItem.currentX and activeItem.currentY variables and then translates its position.

In your case it leads to double movement: your block moves 2x faster than the cursor.

To fix your problem, you can change your drag function this way:

function drag(e) {
    if (active) {
        e.preventDefault();
        
        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;

        if (e.type === "touchmove") {
            setTranslate(activeItem.currentX, activeItem.currentY, activeItem);
        }
    }
}
Alexander Shkirkov
  • 3,527
  • 3
  • 17
  • 37
  • So it actually works (so thank you I understand better now) ! But there's another problem if I do so : it's not touchable anymore (can't drag with finger), any other idea why ? thanks a lot – Voctor Jan 12 '22 at 13:24
  • @RIVAUDVictor, well... I forgot about it :) i guess you can just wrap it into another `if` statement - see my update – Alexander Shkirkov Jan 12 '22 at 13:30
  • 1
    Well this solves everything. Thank you very much ! I hope one day I'll be able to see problems as quickly as you xD Have a great day ! :) – Voctor Jan 12 '22 at 13:35