Search code examples
javascriptvertical-scrollingpointer-events

onpointermove called with +/- values when trying to simulate scrolling


I'm trying to scroll using pointer events. I realize this isn't the proper way to do scrolling. I'm creating a game with a 'variable' scrolling experience.

The code 'scrolls' but it's very wobbly and jerky. The console.log shows something curious: scrollBy() is called with a -6 (for example) and then immediately called again with a 6. It appears that calling scrollBy() causes onpointermove to be called again?

I'm guessing I'm making a noob mistake, triggering a duplicate event.

I'm willing to try a very different approach. I assumed using pointer-events was the right way to do this as it should work with both mouse and finger events.

<!doctype html>
<html>

<head>
  <meta charset="utf-8">
  <title>Scroll Guesture</title>
  <meta name="description" content="">
  <meta name="viewport" content="width=device-width, initial-scale=1">

  <style>
    #target {
      touch-action: pan-x;
     }
  </style>
</head>
<script>
  var lastY;
  var thisY;

   function down_handler(event) { 
    lastY = Math.trunc(event.offsetY);
    console.log("down_handler " + lastY);
  }
  function move_handler(event) { 
    thisY = Math.trunc(event.offsetY);
    deltaY = lastY - thisY;
    console.log("move_handler " + deltaY);
    window.scrollBy(0, deltaY);
    lastY = thisY;
 }

  function init() {
    var el=document.getElementById("target");
    el.onpointerdown = down_handler;
    el.onpointermove = move_handler;
  }
</script>

<body onload="init();">
  <div id="target">
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Placerat vestibulum lectus mauris ultrices eros. Interdum velit euismod in pellentesque massa placerat. Fermentum leo vel orci porta. Scelerisque mauris pellentesque pulvinar pellentesque habitant morbi tristique senectus et. Duis ut diam quam nulla porttitor massa. Nisl pretium fusce id velit ut tortor pretium viverra suspendisse. Sit amet cursus sit amet dictum sit amet justo. Lectus quam id leo in vitae. Posuere urna nec tincidunt praesent semper feugiat nibh sed pulvinar. Elit eget gravida cum sociis natoque penatibus. Tortor condimentum lacinia quis vel eros donec ac. Lectus mauris ultrices eros in cursus. Elit at imperdiet dui accumsan sit amet nulla.</p>
    <p>Parturient montes nascetur ridiculus mus mauris. Aliquam faucibus purus in massa tempor nec. A arcu cursus vitae congue mauris rhoncus aenean vel elit. In arcu cursus euismod quis viverra. Dolor sit amet consectetur adipiscing elit. Enim nec dui nunc mattis enim ut tellus elementum. In aliquam sem fringilla ut. Eget arcu dictum varius duis at consectetur lorem. In ornare quam viverra orci sagittis eu volutpat odio facilisis. Blandit massa enim nec dui. Justo eget magna fermentum iaculis eu non diam phasellus. Phasellus vestibulum lorem sed risus ultricies tristique.</p>
    <p>Odio facilisis mauris sit amet massa vitae. Feugiat in ante metus dictum. Commodo viverra maecenas accumsan lacus. Tristique risus nec feugiat in fermentum posuere. Praesent semper feugiat nibh sed pulvinar proin gravida hendrerit. Adipiscing bibendum est ultricies integer. Dignissim suspendisse in est ante in. Aenean pharetra magna ac placerat vestibulum. Netus et malesuada fames ac turpis egestas sed tempus. Egestas sed tempus urna et pharetra pharetra massa massa. Dictum non consectetur a erat nam. A iaculis at erat pellentesque adipiscing commodo. Odio aenean sed adipiscing diam donec adipiscing. Eget velit aliquet sagittis id consectetur purus ut faucibus pulvinar. Tortor pretium viverra suspendisse potenti. Risus ultricies tristique nulla aliquet. </p>
  </div>
</body>
</html>

Solution

  • Original Answer

    Your issue stems from this little piece right here: event.offsetY

    In short it should be event.clientY

    As for why this works:

    • offsetX and offsetY are relative to the parent container - which shifts from being a <p> tag to being <body> or any other tag.
    • clientX and clientY are relative to the viewport - i.e. the top left corner of your screen
    • For more info here is a good explanation of pageX/Y, screenX/Y, and clientX/Y: Stackoverflow answer

    Edit

    @ScottJenson also asked:

    I'm confused as to why move_handler() would be called with a deltaY of -10 followed by 10 (when using offsetY).

    Answer:

    try making the text boxes bigger like so:

        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Placerat vestibulum lectus mauris ultrices eros. Interdum velit euismod in pellentesque massa placerat. Fermentum leo vel orci porta. Scelerisque mauris pellentesque pulvinar pellentesque habitant morbi tristique senectus et. Duis ut diam quam nulla porttitor massa. Nisl pretium fusce id velit ut tortor pretium viverra suspendisse. Sit amet cursus sit amet dictum sit amet justo. Lectus quam id leo in vitae. Posuere urna nec tincidunt praesent semper feugiat nibh sed pulvinar. Elit eget gravida cum sociis natoque penatibus. Tortor condimentum lacinia quis vel eros donec ac. Lectus mauris ultrices eros in cursus. Elit at imperdiet dui accumsan sit amet nulla.
            Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Placerat vestibulum lectus mauris ultrices eros. Interdum velit euismod in pellentesque massa placerat. Fermentum leo vel orci porta. Scelerisque mauris pellentesque pulvinar pellentesque habitant morbi tristique senectus et. Duis ut diam quam nulla porttitor massa. Nisl pretium fusce id velit ut tortor pretium viverra suspendisse. Sit amet cursus sit amet dictum sit amet justo. Lectus quam id leo in vitae. Posuere urna nec tincidunt praesent semper feugiat nibh sed pulvinar. Elit eget gravida cum sociis natoque penatibus. Tortor condimentum lacinia quis vel eros donec ac. Lectus mauris ultrices eros in cursus. Elit at imperdiet dui accumsan sit amet nulla.
            Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Placerat vestibulum lectus mauris ultrices eros. Interdum velit euismod in pellentesque massa placerat. Fermentum leo vel orci porta. Scelerisque mauris pellentesque pulvinar pellentesque habitant morbi tristique senectus et. Duis ut diam quam nulla porttitor massa. Nisl pretium fusce id velit ut tortor pretium viverra suspendisse. Sit amet cursus sit amet dictum sit amet justo. Lectus quam id leo in vitae. Posuere urna nec tincidunt praesent semper feugiat nibh sed pulvinar. Elit eget gravida cum sociis natoque penatibus. Tortor condimentum lacinia quis vel eros donec ac. Lectus mauris ultrices eros in cursus. Elit at imperdiet dui accumsan sit amet nulla.
            Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Placerat vestibulum lectus mauris ultrices eros. Interdum velit euismod in pellentesque massa placerat. Fermentum leo vel orci porta. Scelerisque mauris pellentesque pulvinar pellentesque habitant morbi tristique senectus et. Duis ut diam quam nulla porttitor massa. Nisl pretium fusce id velit ut tortor pretium viverra suspendisse. Sit amet cursus sit amet dictum sit amet justo. Lectus quam id leo in vitae. Posuere urna nec tincidunt praesent semper feugiat nibh sed pulvinar. Elit eget gravida cum sociis natoque penatibus. Tortor condimentum lacinia quis vel eros donec ac. Lectus mauris ultrices eros in cursus. Elit at imperdiet dui accumsan sit amet nulla.
            Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Placerat vestibulum lectus mauris ultrices eros. Interdum velit euismod in pellentesque massa placerat. Fermentum leo vel orci porta. Scelerisque mauris pellentesque pulvinar pellentesque habitant morbi tristique senectus et. Duis ut diam quam nulla porttitor massa. Nisl pretium fusce id velit ut tortor pretium viverra suspendisse. Sit amet cursus sit amet dictum sit amet justo. Lectus quam id leo in vitae. Posuere urna nec tincidunt praesent semper feugiat nibh sed pulvinar. Elit eget gravida cum sociis natoque penatibus. Tortor condimentum lacinia quis vel eros donec ac. Lectus mauris ultrices eros in cursus. Elit at imperdiet dui accumsan sit amet nulla.
            Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Placerat vestibulum lectus mauris ultrices eros. Interdum velit euismod in pellentesque massa placerat. Fermentum leo vel orci porta. Scelerisque mauris pellentesque pulvinar pellentesque habitant morbi tristique senectus et. Duis ut diam quam nulla porttitor massa. Nisl pretium fusce id velit ut tortor pretium viverra suspendisse. Sit amet cursus sit amet dictum sit amet justo. Lectus quam id leo in vitae. Posuere urna nec tincidunt praesent semper feugiat nibh sed pulvinar. Elit eget gravida cum sociis natoque penatibus. Tortor condimentum lacinia quis vel eros donec ac. Lectus mauris ultrices eros in cursus. Elit at imperdiet dui accumsan sit amet nulla.
            Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Placerat vestibulum lectus mauris ultrices eros. Interdum velit euismod in pellentesque massa placerat. Fermentum leo vel orci porta. Scelerisque mauris pellentesque pulvinar pellentesque habitant morbi tristique senectus et. Duis ut diam quam nulla porttitor massa. Nisl pretium fusce id velit ut tortor pretium viverra suspendisse. Sit amet cursus sit amet dictum sit amet justo. Lectus quam id leo in vitae. Posuere urna nec tincidunt praesent semper feugiat nibh sed pulvinar. Elit eget gravida cum sociis natoque penatibus. Tortor condimentum lacinia quis vel eros donec ac. Lectus mauris ultrices eros in cursus. Elit at imperdiet dui accumsan sit amet nulla.
            Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Placerat vestibulum lectus mauris ultrices eros. Interdum velit euismod in pellentesque massa placerat. Fermentum leo vel orci porta. Scelerisque mauris pellentesque pulvinar pellentesque habitant morbi tristique senectus et. Duis ut diam quam nulla porttitor massa. Nisl pretium fusce id velit ut tortor pretium viverra suspendisse. Sit amet cursus sit amet dictum sit amet justo. Lectus quam id leo in vitae. Posuere urna nec tincidunt praesent semper feugiat nibh sed pulvinar. Elit eget gravida cum sociis natoque penatibus. Tortor condimentum lacinia quis vel eros donec ac. Lectus mauris ultrices eros in cursus. Elit at imperdiet dui accumsan sit amet nulla.
        </p>
    

    and put three or four boxes.

    Changed clientY back to offsetY

    If you try to scroll on the block itself you'll notice it's smooth but as soon as you cross the line from one box to another the value jumps by the height of the text box. The reason this happens is because the mouse pointer is calculated in reference of the top left corner of the individual <p> tags. i.e. if you're 50px down from the <p> tag you are hovering over that is the value of offsetY

    clientY on the other hand always has the same reference point - the top left corner of the screen. So there are no points where one box has a wildly different value.