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.