最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript + html5 canvas: drawing instead of draggingscrolling on mobile devices? - Stack Overflow

programmeradmin6浏览0评论

I'm using a html5 canvas + some javascript (onmousedown/move/up) to create simple draw pad on a webpage.

Works OK in Opera, Firefox, Chrome, etc (tried on desktop PCs). But if I visit this page with an iPhone, when trying to draw on the canvas, instead it drags or scrolls the page.

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

For your reference, here's a minimalisic 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 some special style or event I have to add to the canvas, in order to avoid dragging/scrolling the page when swiping in the canvas?

I'm using a html5 canvas + some javascript (onmousedown/move/up) to create simple draw pad on a webpage.

Works OK in Opera, Firefox, Chrome, etc (tried on desktop PCs). But if I visit this page with an iPhone, when trying to draw on the canvas, instead it drags or scrolls the page.

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

For your reference, here's a minimalisic 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 some special style or event I have to add to the canvas, in order to avoid dragging/scrolling the page when swiping in the canvas?

Share Improve this question edited Jul 21, 2019 at 3:41 user128511 asked Apr 2, 2012 at 11:12 Sheldon PinkmanSheldon Pinkman 1,1064 gold badges15 silver badges21 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 12

iPad / iPhone doesn't have mouse* events. You need to use touchstart, touchmove and touchend. This events can have multiple touches so you need to get first one like this:

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

It's important to return false in touch start method because otherwise page scroll is triggered.

I'm going to add to Grassator's answer by adding a link to this answer that goes more in-depth with the code required to make this solution work: https://stackoverflow./a/16630678/5843693.

Before I continue, please note that Apple has changed the way iOS handles scrolling on more recent devices. To handle this change, it is necessary to add a few extra functions; 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);
}

The methods for canvas are all called upon in a drawer fashion like so:

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, EventListeners are specifically ordered so that touch inputs are taken 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, the "elastic" scrolling is prevented by adding one more EventListener near the end of the code.

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

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

发布评论

评论列表(0)

  1. 暂无评论