-1

I am just trying to draw on my phone using "pointer" events.

This works on my desktop with my mouse, but not on my (android) phone. I should be able to draw curved lines, but dragging with my finger on my phone results in an "enter" and a few "moves" but then it "leave"s.

It has to be online: https://dbarc.net/SOtest.html

<!DOCTYPE html>
<html>
<!-- works on desktop, leaves on phone (dbarc.net/SOtest.html) -->
  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <style>
body { width:400px; }
#canvas { background:#eee; }    
    </style>
    <script>
  "use strict";
  let canvas, ctx, xx, yy, infodiv;
window.onload = function() {
  infodiv = document.getElementById("infodiv"); // info output
  canvas = document.getElementById("canvas");
  ctx = canvas.getContext("2d");
//  canvas.addEventListener('pointerenter', function() { ptrEnter(); } );
  canvas.addEventListener('pointerenter', ptrEnter); // better
  canvas.addEventListener('pointerleave', ptrLeave);
  canvas.addEventListener('pointermove', ptrMove);
}
function ptrEnter() { // shows an enter
  infodiv.innerHTML += "ENTER ";
}
function ptrLeave() { // shows a leave
  infodiv.innerHTML += "LEAVE ";
}
function ptrMove(ev) { // draws (no pen up/down)
  infodiv.innerHTML += "m ";
  let x0 = canvas.offsetLeft, y0 = canvas.offsetTop;
  let xold = xx, yold = yy;
  xx = Math.floor(ev.clientX) - x0; 
  yy = Math.floor(ev.clientY) - y0;
  ctx.beginPath();
  ctx.moveTo(xold,yold);
  ctx.lineTo(xx, yy);
  ctx.stroke(); 
}
    </script>
  </head>
  <body>
    <canvas id="canvas" width="400" height="300"></canvas>  
    <div id="infodiv">Events: </div>
  </body>
</html>
4
  • (After "several hours") By putting in the CSS style statement < br /> canvas { touch-action: none; } , it works. @gsharew Commented Jan 31, 2023 at 4:27
  • I did close your question as a duplicate, you can tag me in your comments using @Kaiido since I did interact with it. I stand by my decision. I'm sorry if the relation between this Q/A and the other one wasn't as obvious to you as it was to me. I should have posted the following comment when closing your question, but lacked time then: Commented Feb 1, 2023 at 5:09
  • 1
    Your core problem is that your page did scroll and thus the pointermove event got overridden by that default scrolling operation. To prevent that from happening, you need to set the touch-action: none rule. The answer you gave the bounty to did avoid your problem entirely by not using the pointermove event at all, that hardly answers the question you did ask. Commented Feb 1, 2023 at 5:09
  • This question is discussed on meta. @Kaiido Commented Feb 1, 2023 at 6:35

1 Answer 1

0
+50

After spending several hours I came to the right solution for this problem. First the event should be touchmove not "mousemove" for the device which are not desktop. Second to get the values for clientX and clientY you have to use event.targetTouchs[0].clientX or .clientY. The full code is like below.

<!-- <!DOCTYPE html>
<html>
<!-- works on desktop, leaves on phone (dbarc.net/SOtest.html) -->

<head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <style>
        body {
            width: 400px;
        }

        #canvas {
            background: #eee;
        }
    </style>
    <script>
        "use strict";
        let canvas, ctx, xx, yy, infodiv;
        let isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile/i.test(navigator.userAgent);
        window.onload = function () {
            infodiv = document.getElementById("infodiv"); // info output
            canvas = document.getElementById("canvas");
            ctx = canvas.getContext("2d");
            canvas.addEventListener('pointerenter', function () { ptrEnter(); });
            canvas.addEventListener('pointerleave', function () { ptrLeave(); });
            canvas.addEventListener(isMobile ? 'touchmove' : "mousemove", function (ev) { ptrMove(ev); });
        }
        function ptrEnter() { // shows an enter
            infodiv.innerHTML += "ENTER ";
        }
        function ptrLeave() { // shows a leave
            infodiv.innerHTML += "LEAVE ";
        }
        function ptrMove(ev) { // draws (no pen up/down)
            infodiv.innerHTML += "m ";
            let x0 = canvas.offsetLeft, y0 = canvas.offsetTop;
            let xold = xx, yold = yy;

            if (isMobile) {
                xx = Math.floor(ev.targetTouches[0].clientX) - x0;
                yy = Math.floor(ev.targetTouches[0].clientY) - y0;
            } else {
                xx = ev.clientX - x0;
                yy = ev.clientY - y0;
            }

            ctx.beginPath();
            ctx.moveTo(xold, yold);
            ctx.lineTo(xx, yy);
            ctx.stroke();
        }
    </script>
</head>

<body>
    <canvas id="canvas" width="400" height="300"></canvas>
    <div id="infodiv">Events: </div>
</body>

</html> -->
Sign up to request clarification or add additional context in comments.

1 Comment

And ('pointerenter', ptrEnter) is better than ('pointerenter', function() { ptrEnter(); } ) Thanks.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.