skip to Main Content

I have application with drawing option using jQuery. On Desktop everything works well but lines are not drawn on mobile devices. On touchmove and touchstart I can trigger console logs but line is not show. Here is my code so far:

<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script>

    var mousePressed = false;
    var lastX, lastY;
    var ctx;
    var ctxtwo;
    var color;

    ctx = document.getElementById('myCanvas').getContext("2d");
    ctxtwo = document.getElementById('myCanvasTwo').getContext("2d");

    $('#skinModal').click(function () {
        $(".spectrum-input").change(function () {
            color = $(this).val();
        });
    })

    $("#skin-condition-save").click(function () {
        document.getElementById('right_side_face_canvas').value = document.getElementById('myCanvas').toDataURL('image/png');
        document.getElementById('left_side_face_canvas').value = document.getElementById('myCanvasTwo').toDataURL('image/png');
    });

    $('#myCanvas, #myCanvasTwo').mousedown(function (e) {
        var second = false;
        if (e.target.id == 'myCanvasTwo') {
            second = true;
        }
        mousePressed = true;
        Draw(e.pageX - $(this).offset().left, e.pageY - $(this).offset().top, false, second);
    });

    $('#myCanvas, #myCanvasTwo').on("touchstart", function (e) {
        console.log('first');
        var second = false;
        if (e.target.id == 'myCanvasTwo') {
            console.log('second');
            second = true;
        }
        mousePressed = true;
        Draw(e.pageX - $(this).offset().left, e.pageY - $(this).offset().top, false, second);
    });


    $('#myCanvas, #myCanvasTwo').mousemove(function (e) {
        var second = false;
        if (e.target.id == 'myCanvasTwo') {
            second = true;
        }
        if (mousePressed) {
            Draw(e.pageX - $(this).offset().left, e.pageY - $(this).offset().top, true, second);
        }
    });

    $('#myCanvas, #myCanvasTwo').on("touchmove", function (e) {
        console.log('111');
        var second = false;
        if (e.target.id == 'myCanvasTwo') {
            console.log('222');
            second = true;
        }
        if (mousePressed) {
            Draw(e.pageX - $(this).offset().left, e.pageY - $(this).offset().top, true, second);
        }
    });

    $('#myCanvas, #myCanvasTwo').mouseup(function (e) {
        mousePressed = false;
    });

    $('#myCanvas, #myCanvasTwo').mouseleave(function (e) {
        mousePressed = false;
    });

    function Draw(x, y, isDown, isSecond) {
        if (isDown) {


            if (isSecond) {
                ctxtwo.beginPath();
                ctxtwo.strokeStyle = color;
                ctxtwo.lineWidth = $('#selWidth').val();
                ctxtwo.lineJoin = "round";
                ctxtwo.moveTo(lastX, lastY);
                ctxtwo.lineTo(x, y);
                ctxtwo.closePath();
                ctxtwo.stroke();
            } else {
                ctx.beginPath();
                ctx.strokeStyle = color;
                ctx.lineWidth = $('#selWidth').val();
                ctx.lineJoin = "round";
                ctx.moveTo(lastX, lastY);
                ctx.lineTo(x, y);
                ctx.closePath();
                ctx.stroke();
            }
        }
        lastX = x;
        lastY = y;
    }


    function clearArea() {
// Use the identity matrix while clearing the canvas
        ctx.setTransform(1, 0, 0, 1, 0, 0);
        ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
    }


    function clearAreaTwo() {
// Use the identity matrix while clearing the canvas
        ctxtwo.setTransform(1, 0, 0, 1, 0, 0);
        ctxtwo.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
    }
</script>

What code modifications would I need to make to be able to draw on mobile devices?

2

Answers


  1. Chosen as BEST ANSWER

    Resolved my problem when changed code from

    Draw(e.pageX - $(this).offset().left, e.pageY - $(this).offset().top, true, second);
    

    To

    Draw(e.originalEvent.touches[0].pageX - $(this).offset().left, e.originalEvent.touches[0].pageY - $(this).offset().top, false, second);
    

    As on mobile devices pageX and pageY getting a little bit different


  2. The primary issue is that Touch events can accept multiple touch points. You cannot simply use event.pageX like with Mouse events.

    See More: https://developer.mozilla.org/en-US/docs/Web/API/Touch/pageX

    Desktop Example: https://jsfiddle.net/Twisty/8q49gu5x/

    Mobile Example: https://jsfiddle.net/Twisty/8q49gu5x/show

    JavaScript

    $(function() {
      var mousePressed = false;
      var lastX, lastY;
      var ctx;
      var ctxtwo;
      var color;
    
      ctx = $('#myCanvas').get(0).getContext("2d");
      ctxtwo = $('#myCanvasTwo').get(0).getContext("2d");
    
      function log(str) {
        $(".status").html("<div>" + str + "<div>");
      }
    
      /*
      $('#skinModal').click(function() {
        $(".spectrum-input").change(function() {
          color = $(this).val();
        });
      })
    
      $("#skin-condition-save").click(function() {
        document.getElementById('right_side_face_canvas').value = document.getElementById('myCanvas').toDataURL('image/png');
        document.getElementById('left_side_face_canvas').value = document.getElementById('myCanvasTwo').toDataURL('image/png');
      });
      */
    
      function getCoords(evt) {
        var coords = {
          x: 0,
          y: 0
        };
        if (evt.type.indexOf("touch") != -1) {
          coords.x = evt.changedTouches[0].pageX;
          coords.y = evt.changedTouches[0].pageY;
        } else {
          coords.x = evt.pageX;
          coords.y = evt.pageY;
        }
        return coords;
      }
    
      $('.wrapper').on("mousedown touchstart", "canvas", function(e) {
        e.preventDefault();
        log(e.type);
        var second = $(e.target).attr("id") === "myCanvasTwo";
        mousePressed = true;
        var c = getCoords(e);
        Draw(c.x - $(this).offset().left, c.y - $(this).offset().top, false, second);
      });
    
    
      $('.wrapper').on("mousemove touchmove", "canvas", function(e) {
        e.preventDefault();
        log(e.type);
        var second = $(e.target).attr("id") === "myCanvasTwo";
        var c = getCoords(e);
        if (mousePressed) {
          Draw(c.x - $(this).offset().left, c.y - $(this).offset().top, true, second);
        }
      });
    
      $('.wrapper').on("mouseup mouseleave touchstop", "canvas", function(e) {
        log(e.type);
        mousePressed = false;
      });
    
      function Draw(x, y, isDown, isSecond) {
        if (isDown) {
          if (isSecond) {
            ctxtwo.beginPath();
            ctxtwo.strokeStyle = color;
            ctxtwo.lineWidth = $('#selWidth').val();
            ctxtwo.lineJoin = "round";
            ctxtwo.moveTo(lastX, lastY);
            ctxtwo.lineTo(x, y);
            ctxtwo.closePath();
            ctxtwo.stroke();
          } else {
            ctx.beginPath();
            ctx.strokeStyle = color;
            ctx.lineWidth = $('#selWidth').val();
            ctx.lineJoin = "round";
            ctx.moveTo(lastX, lastY);
            ctx.lineTo(x, y);
            ctx.closePath();
            ctx.stroke();
          }
        }
        lastX = x;
        lastY = y;
      }
    
      function clearArea() {
        // Use the identity matrix while clearing the canvas
        ctx.setTransform(1, 0, 0, 1, 0, 0);
        ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
      }
    
      function clearAreaTwo() {
        // Use the identity matrix while clearing the canvas
        ctxtwo.setTransform(1, 0, 0, 1, 0, 0);
        ctxtwo.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
      }
    });
    

    This looks at the event type and if it is a Touch event, gets the proper coordinates.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search