mobomo/sketch.js

Eraser on iPad

Closed this issue · 2 comments

A while ago, I had opened an issue here on GitHub, about making sketch.js work on the iPad. @leonth was kind enough to provide a workaround to this issue, but I only found out now, that this workaround makes the eraser not work. Anyone knows what to do?

My previous opened issue: #1

Thanks

Dandoen,

I ran into the same issues you opened up on your previous issue (#1), but found a different workaround that seems to fix the iPad compatibility problem without messing up other behavior.

The Fix

I changed the following code in Sketch.prototype.onEvent:

99      if (e.originalEvent && e.originalEvent.targetTouches) {
100        e.pageX = e.originalEvent.targetTouches[0].pageX;
101        e.pageY = e.originalEvent.targetTouches[0].pageY;
102      }

to:

99      if (e.originalEvent && e.originalEvent.targetTouches && e.originalEvent.targetTouches.length > 0) {
100        e.pageX = e.originalEvent.targetTouches[0].pageX;
101        e.pageY = e.originalEvent.targetTouches[0].pageY;
102      }

What's Happening

When you draw on the canvas, touchstart, touchmove, and touchend events are fired. Since the iPad and other tablet devices are multi-touch devices, the triggered event e doesn't have pageX or pageY attributes (since there could be multiple points on the screen that are being touched). Instead, the triggered event contains a TouchEvent object in e.originalEvent, which hold all of the relevant information about the touch state of the page.

The code block above is trying to parse out pageX and pageY values for the touch event so that it can draw on the canvas at that location. What the code does is get the pageX and pageY data for the first multitouch point (e.originalEvent.targetTouches[0]). The issue arises because the touchend event fires when the user takes their fingers off the screen. In this case, the TouchList targetTouches is empty, so the attempt to select pageX and pageY values from the first Touch object throws an undefined error.

The corrected block of code simply checks to make sure that there is at least 1 touch point on the screen before parsing pageX and pageY out of the TouchEvent. You could alternatively check to make sure that e.type is a touchstart or touchmove event.

You can read more about Touch Events on the W3C site (https://dvcs.w3.org/hg/webevents/raw-file/tip/touchevents.html/#touch-interface)

Hello There:

well that worked perfectly for iPad. Im also developing this for android, and before this fix, android coloring was showing a single diagonal line per color, per touch. what your fix did was allow the android touch to actually paint. dont ask me how. Now, the only issue with android is it doesnt erase. any thoughts?