Javascript + html5 canvas: drawing instead of drag and drop / scroll on mobile devices?

I am using html5 canvas + some javascript (onmousedown / move / up) to create a simple drawing panel on a web page.

It works fine in Opera, Firefox, Chrome, etc. (used on desktop PCs). But if I come to this page with the iPhone, trying to draw on the canvas, instead it drags or scrolls the page.

This is good for other page content, by moving the page up, you can navigate the page in a mobile browser, as usual. But is there a way to disable this behavior on the canvas so that mobile visitors can draw something on it?

For reference, here is a minimal example:

<html><head><script type='text/javascript'> function init() { var canvas = document.getElementById('MyCanvas'); var ctx = canvas.getContext('2d'); var x = null; var y; canvas.onmousedown = function(e) { x = e.pageX - canvas.offsetLeft; y = e.pageY - canvas.offsetTop; ctx.beginPath(); ctx.moveTo(x,y); } canvas.onmouseup = function(e) { x = null; } canvas.onmousemove = function(e) { if (x==null) return; x = e.pageX - canvas.offsetLeft; y = e.pageY - canvas.offsetLeft; ctx.lineTo(x,y); ctx.stroke(); } } </script></head><body onload='init()'> <canvas id='MyCanvas' width='500' height='500' style='border:1px solid #777'> </canvas></body></html> 

Is there any special style or event that I have to add to the canvas to avoid dragging / scrolling the page while scrolling through the canvas?

+7
source share
2 answers

iPad / iPhone has no mouse events. You need to use touchstart , touchmove and touchend . These events can have several touches, so you need to do the following first:

 canvas.ontouchstart = function(e) { if (e.touches) e = e.touches[0]; return false; } 

This is important for the touch return false method, because otherwise the page scrolls.

+7
source

I am going to add Grassator to the answer by adding a link to this answer, which describes in more detail the code necessary for this solution to work: fooobar.com/questions/1481563 / ....

Before continuing, note that Apple has changed the way iOS scrolls on newer devices. To handle this change, you need to add a few extra features; Thanks to Christopher Vickers for sharing this:

 function preventDefault(e) { e.preventDefault(); } function disableScroll() { document.body.addEventListener('touchmove', preventDefault, { passive: false }); } function enableScroll() { document.body.removeEventListener('touchmove', preventDefault); } 

All methods for canvas are called in the form of a box as follows:

 var drawer = { isDrawing: false, touchstart: function (coors) { ctx.beginPath(); ctx.moveTo(coors.x, coors.y); this.isDrawing = true; disableScroll(); // add for new iOS support }, touchmove: function (coors) { if (this.isDrawing) { ctx.lineTo(coors.x, coors.y); ctx.stroke(); } }, touchend: function (coors) { if (this.isDrawing) { this.touchmove(coors); this.isDrawing = false; } enableScroll(); // add for new iOS support } }; 

In addition, the EventListener specially ordered so that touch input is executed first:

 var touchAvailable = ('createTouch' in document) || ('onstarttouch' in window); if (touchAvailable) { canvas.addEventListener('touchstart', draw, false); canvas.addEventListener('touchmove', draw, false); canvas.addEventListener('touchend', draw, false); } else { canvas.addEventListener('mousedown', draw, false); canvas.addEventListener('mousemove', draw, false); canvas.addEventListener('mouseup', draw, false); } 

Finally, resilient scrolling is prevented by adding another EventListener near the end of the code.

 document.body.addEventListener('touchmove', function (event) { event.preventDefault(); }, false); 

All this is inside window.addEventListener('load', function () {}) .

+1
source

Source: https://habr.com/ru/post/912227/


All Articles