HTML5 canvas drawing board - touch support

Viewed 464

I am using this simple script to enable users to enter their signatures. Unfortunately, this does not work on mobile devices.

var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');

var container = document.getElementById('container');
var container_style = getComputedStyle(container);
canvas.width = 400;
canvas.height = 300;

var mouse = {x: 0, y: 0};

canvas.addEventListener('mousemove', function(e) {
mouse.x = e.pageX - this.offsetLeft;
mouse.y = e.pageY - this.offsetTop;
}, false);

ctx.lineJoin = 'round';
ctx.lineCap = 'round';
ctx.strokeStyle = "black";

function getSize(size){ctx.lineWidth = size;}

canvas.addEventListener('mousedown', function(e) {
    ctx.beginPath();
    ctx.moveTo(mouse.x, mouse.y);
    canvas.addEventListener('mousemove', onPaint, false);
}, false);

canvas.addEventListener('mouseup', function() {
    canvas.removeEventListener('mousemove', onPaint, false);
}, false);

var onPaint = function() {
    ctx.lineTo(mouse.x, mouse.y);
    ctx.stroke();
};
#canvas {
  border: 1px solid rgba(0,0,0,.5);
}
<div id="container">
  <canvas id="canvas"></canvas>
</div>

Is there an easy way to add touch support to this script?

1 Answers

Make these changes to your code:

  1. Use pointer events (instead of mouse events): pointerdown, pointerup, and pointermove. Pointer events work for both mouse and touch interactions.
  2. Add touch-action: none to your canvas CSS. This prevents the dragging of your finger from triggering the device's panning action (which stops your drawing).
  3. Set your "mouse" coordinates upon pointerdown. This will stop previous lines from being connected to new ones.

var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');

var container = document.getElementById('container');
canvas.width = 400;
canvas.height = 300;

var mouse = {x: 0, y: 0};

canvas.addEventListener('pointermove', function(e) {
  mouse.x = e.pageX - this.offsetLeft;
  mouse.y = e.pageY - this.offsetTop;
}, false);

ctx.lineJoin = 'round';
ctx.lineCap = 'round';
ctx.strokeStyle = 'black';

canvas.addEventListener('pointerdown', function(e) {
  mouse.x = e.pageX - this.offsetLeft;
  mouse.y = e.pageY - this.offsetTop;
  ctx.beginPath();
  ctx.moveTo(mouse.x, mouse.y);
  canvas.addEventListener('pointermove', onPaint, false);
}, false);

canvas.addEventListener('pointerup', function() {
  canvas.removeEventListener('pointermove', onPaint, false);
}, false);

var onPaint = function() {
  ctx.lineTo(mouse.x, mouse.y);
  ctx.stroke();
};
#canvas {
  border: 1px solid rgba(0,0,0,.5);
  touch-action: none;
}
<div id="container">
  <canvas id="canvas"></canvas>
</div>

Related