Wrong swipe direction js

Issue

Please tell me, if you start touchmove from the middle of the page and move to the right, then console.log() goes right, but if you move to the left and cross the middle of the screen, console.log() will show the opposite direction, although the swipe goes in the same direction. As I understand it, this is due to the fact that touchstart coordinates are fixed from where touchmove started. How to fix this error. (see video).

https://youtu.be/_pB49S2BR2o

var initialX = null;
var initialY = null;
$("#content, .menu").on("touchstart", function(e) {
  initialX = e.touches[0].clientX;
  initialY = e.touches[0].clientY;
});
$("#content, .menu").on("touchmove", function(e) {
  var diffX = initialX - e.touches[0].clientX;
  var diffY = initialY - e.touches[0].clientY;

  if (Math.abs(diffX) > Math.abs(diffY)) {
    if (diffX > 0) {
      console.log("Right");
    } else {
      console.log("Left");
    }
  } else {
    return;
  }
  var width = parseInt($("body").css("width"));
  clientX = e.touches[0].clientX;
  width = width - clientX;
  if (width >= 0 || width <= 375) {
    $(".menu").css("left", "-" + width + "px");
  } else {}
})
body {
  margin: 0px;
  overflow: hidden;
  font-family: Helvetica Neue, Helvetica, Arial, sans-serif;
}

.menu {
  background: blue;
  width: 100%;
  height: 100%;
  z-index: 1;
  position: absolute;
  left: -100%;
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
}

#content {
  width: 100%;
  height: 100vh;
  color: #000;
  display: flex;
  align-items: center;
  justify-content: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1">

<body>
  <div class="menu" style="transition-duration: 0ms;">Menu slide</div>
  <div id="content">
    Content slide
  </div>
</body>
const text = document.querySelector('#direction');
const cursorEl = document.querySelector('#cursorDir');

let lastX = null;
let active = false;
$("#content, .menu").on("touchstart", function(evt) {
    active = true; 
});
$("#content, .menu").on("touchend", function(evt) {
    active = false; 
});

$("#content, .menu").on("touchmove", function(evt) {
    if (!active) return; // Run only on mousedown
    if (lastX === null) {
      // Set first value
      lastX = evt.clientX;
      return;
    }
    const diff = lastX - evt.clientX;
    if (diff === 0) return; // Break if there's 0 pixels difference
    console.log("direction: " + (diff > 0 ? "Left" : "Right"));
    lastX = evt.clientX; // Set next value to check the difference
});

Solution

Is this what you are looking for?

Note: For the purpose of running this in a browser, touchstart and touchmove are replaced by mousedown and mousemove

const text = document.querySelector('#direction');
const cursorEl = document.querySelector('#cursorDir');

let lastX = null;
let active = false;
cursorEl.addEventListener('mousedown', () => { active = true; });
document.documentElement.addEventListener('mouseup', () => { active = false; });

cursorEl.addEventListener('mousemove', (evt) => {
    if (!active) return; // Run only on mousedown
    if (lastX === null) {
      // Set first value
      lastX = evt.clientX;
      return;
    }
    const diff = lastX - evt.clientX;
    if (diff === 0) return; // Break if there's 0 pixels difference
    text.innerHTML = "direction: " + (diff > 0 ? "Left" : "Right");
    lastX = evt.clientX; // Set next value to check the difference
});
#cursorDir {
  display: block;
  width: 150px;
  height: 150px;
}
#cursorDir {
  background: blue;
}
Click and hold to activate
<div id="cursorDir"></div>
<div id="direction"><div>

Answered By – savageGoat

Answer Checked By – Katrina (AngularFixing Volunteer)

Leave a Reply

Your email address will not be published.