-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>
dcromley
  • 1,373
  • 1
  • 8
  • 23
  • (After "several hours") By putting in the CSS style statement < br /> `canvas { touch-action: none; } `, it works. @gsharew – dcromley Jan 31 '23 at 04: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: – Kaiido Feb 01 '23 at 05: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. – Kaiido Feb 01 '23 at 05:09
  • This question is [discussed on meta](https://meta.stackoverflow.com/q/422963). @Kaiido – Bill Tür stands with Ukraine Feb 01 '23 at 06:35

1 Answers1

0

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> -->
gsharew
  • 263
  • 1
  • 12
  • And `('pointerenter', ptrEnter)` is better than `('pointerenter', function() { ptrEnter(); } )` Thanks. – dcromley Jan 30 '23 at 22:04