The purpose
JavaScript code that works with a mouse failed to work with a pen tablet.
This article summarizes the changes made by me.
The modified application is a painting app on a Canvas. I will only introduce the sections that were changed to add support for a pen tablet (so that the app works with both a pen tablet and a mouse).
Regarding smartphone/tablet compatibility
Support for smartphones and tablets should be similar to that for pen tablets, but I haven’t tested it yet.
Issues and Fixes
Mouse-related events are not being received
When I used a pen tablet, I did not receive events for mousedown
, mousemove
, and mouseup
. This is because pen tablets send touch events, not mouse events.
Each event needs to be replaced as follows:
Before (mouse) | After(touch) |
mousedown | touchstart |
mousemove | touchmove |
mouseup | touchend |
In order to make both the mouse and pen tablet operate in the same way, I actually made the following changes. I made it so that the same function is called for both mouse operations and pen tablet operations.
Before:
canvas.addEventListener('mousedown', startDrag, false);
canvas.addEventListener('mousemove', whileDrag, false);
canvas.addEventListener('mouseup', endDrag, false);
After:
canvas.addEventListener('mousedown', startDrag, false);
canvas.addEventListener('touchstart', startDrag, false);
canvas.addEventListener('mousemove', whileDrag, false);
canvas.addEventListener('touchmove', whileDrag, false);
canvas.addEventListener('mouseup', endDrag, false);
canvas.addEventListener('touchend', endDrag, false);
The click
event is also received from a pen tablet, so no fix is needed.
Cannot get offsetX/offsetY from an event
The fix above will allow you to receive events, but you still won’t be able to get event.offsetX
and event.offsetY
from the event
argument in the callback.
This is because touch and mouse events are different, and touch events do not have offsetX
or offsetY
properties. Therefore, you need to calculate these values yourself, as shown below.
element
refers to the base element (e.g., the canvas). You can get it using a method like document.getElementById
.
const offsetX = event.touches[0].clientX - element.getBoundingClientRect().left
const offsetY = event.touches[0].clientY - element.getBoundingClientRect().top
I created the following function to work with both a mouse and a pen tablet.
If event.offsetX/Y
exists, it returns them as is; otherwise, it calculates and returns them.
function getOffesetX(event,id) {
if (event.offsetX != undefined) return event.offsetX;
return event.touches[0].clientX - document.getElementById(id).getBoundingClientRect().left
}
function getOffesetY(event,id) {
if (event.offsetY != undefined) return event.offsetY;
return event.touches[0].clientY - document.getElementById(id).getBoundingClientRect().top
}
While I’ve mentioned offsetX/Y
here, coordinate information such as clientX
and clientY
is also not available directly on the event
object in a touch event. Instead, this information is stored under event.touches[0]
. (The touches
property is an array because multiple touches can occur simultaneously on smartphones and other devices.) For more details, please refer to the following page.

Scrolling during pen movement (drag)
When I moved the pen up and down, the app worked as expected, but the browser also started to scroll.
You can prevent this by stopping the browser’s default behavior during a drag using the following method.
Use preventDefault
You can stop the default behavior by calling event.preventDefault()
inside the function that is called by the touchmove
event, as shown below.
Notice:
I found an interesting point on the following page: Depending on the browser, preventDefault
might not work.
If the app doesn’t work as you expect, the following fix might solve the issue.
Before:
canvas.addEventListener('mousemove', whileDrag, false);
After:
canvas.addEventListener('mousemove', whileDrag, {passive:false});

canvas.addEventListener('touchmove', whileDrag, false);
function whileDrag(event) {
event.preventDefault()
Result
By making the changes mentioned above, the target app now works with a pen tablet as well.
comment