Home > Back-end >  How to draw on mobile devices with jQuery
How to draw on mobile devices with jQuery

Time:11-30

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?

CodePudding user response:

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

CodePudding user response:

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.

  • Related