You can't: as there are legacy touch-based devices that does not support this API (for example, iOS 12 and below), you need to bind events for ontouchdown
, ontouchmove
, and ontouchend
separately. You can check browser support for the pointer event API here.
You can use window.PointerEvent
to detect browser support for this API, and then return the correct event name you want to bind to:
const hasPointerEvent = !!window.PointerEvent;
const pointerEventNames = {
start: window.PointerEvent ? 'pointerdown' : 'touchstart',
move: window.PointerEvent ? 'pointermove' : 'touchmove',
end: window.PointerEvent ? 'pointerup' : 'touchend',
};
If you want to support IE10, you will need to add an additional check for window.MSPointerEvent
, because IE10 only supports events prefixed with MS
(and they are also PascalCased):
function getPointerEventNames() {
const o = {
start: 'pointerdown',
move: 'pointermove',
end: 'pointerup'
};
if (!window.PointerEvent) {
o.start = 'touchstart';
o.move = 'touchmove';
o.end = 'touchend';
} else if (!!window.MSPointerEvent) {
o.start = 'MSPointerDown';
o.move = 'MSPointerMove';
o.end = 'MSPointerUp';
}
}
const pointerEventNames = getPointerEventNames();
Instead of doing canvas.onpointerdown = ...
and then repeating the same logic for canvas.ontouchstart
, you can use canvas.addEventListener
instead. The advantage of this is that you can then leverage on the dictionary pointerEventNames
above, which will return the supported event names for the device you are on:
// Define common handler
const onDown = (e) => {
const { pageX, pageY } = e
down = true
x = pageX
y = pageY
}
canvas.addEventListener(pointerEventNames.start, onDown);
And you repeat these for the other two events... see a proof of concept below:
const hasPointerEvent = !!window.PointerEvent;
const pointerEventNames = {
start: window.PointerEvent ? 'pointerdown' : 'touchstart',
move: window.PointerEvent ? 'pointermove' : 'touchmove',
end: window.PointerEvent ? 'pointerup' : 'touchend',
};
const canvas = document.querySelector('canvas')
const ctx = canvas.getContext('2d')
// Same window dimensions
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
// We need to track mouse/finger position and down/up
let x, y, down
// Start
const onStart = (e) => {
const {
pageX,
pageY
} = e
down = true
x = pageX
y = pageY
}
canvas.addEventListener(pointerEventNames.start, onStart);
// End
const onEnd = () => down = false;
canvas.addEventListener(pointerEventNames.end, onEnd);
// Move
const onMove = (e) => {
// Return if we havent finish yet
if (!down) return
const {
pageX,
pageY
} = (e.touches && e.touches[0]) || e
// Draw line
ctx.beginPath()
ctx.moveTo(x, y)
ctx.lineTo(pageX, pageY)
ctx.lineWidth = 1
ctx.stroke()
// Update
x = pageX
y = pageY
}
canvas.addEventListener(pointerEventNames.move, onMove);
body {
margin: 0;
padding: 0;
background-color: #bbb;
width: 100vw;
height: 100vh;
overflow: hidden;
}
<canvas></canvas>