Enable touch actions on mobile over the p5js canvas itself

Hello! I have an issue both on ios and android where all touch actions like scrolling, zooming, moving around while zoomed in, seem to be disabled when doing them over the canvas. They work fine on the outside edges.

I’ve tried adding this to my css :

canvas {
    touch-action: pinch-zoom;
    touch-action: manipulation;
}

As well as this in my js :

function touchMoved() {
  return true;
}

To no avail.

Here is my current css (centers the canvas and avoids mistakingly selecting it while trying touch controls) :

body {
    display: flex;
    justify-content: center;
}

canvas {
    user-select: none;
    -webkit-user-select: none;
}

My js simply creates a canvas at 0.8 window size, and my html links to both files.

You can access everything on github : https://github.com/dandandandan-dan/p5js-touch-canvas/ or try it out for yourself at https://fatigue.plus/p5js .

Thanks a lot for anyone taking the time to look into this :slight_smile:

Welcome to the forum :grinning:

The answer is to add your own event listeners to the canvas object and your own event handlers to the sketch as shown here.

let p5canvas;
let events = [];

function setup() {
  p5canvas = createCanvas(640, 440);
  addMouseEventHandlers();
  addTouchEventHandlers();
  addKeyEventHandlers();
}

function draw() {
  background(240, 240, 255);
  textSize(18);
  textFont('monospace')
  fill(0, 192);
  events.forEach(function(evt, idx){ text(evt, 20, 40 + idx * 24) });
}

function addMouseEventHandlers() {
  const cvs = p5canvas.canvas;
  cvs.addEventListener('mousedown', (e) => { processMouseEvent(e) });
  cvs.addEventListener('mouseup', (e) => { processMouseEvent(e) });
  cvs.addEventListener('mousemove', (e) => { processMouseEvent(e) });
  cvs.addEventListener('wheel', (e) => { processMouseEvent(e) });
  // Leave and enter canvas
  cvs.addEventListener('mouseout', (e) => { processMouseEvent(e) });
  cvs.addEventListener('mouseenter', (e) => { processMouseEvent(e); });
}

function addTouchEventHandlers() {
  const cvs = p5canvas.canvas;
  cvs.addEventListener('touchstart', (e) => { processTouchEvent(e); });
  cvs.addEventListener('touchend', (e) => { processTouchEvent(e); });
  cvs.addEventListener('touchmove', (e) => { processTouchEvent(e); });
  cvs.addEventListener('touchcancel', (e) => { processTouchEvent(e); });
}

function addKeyEventHandlers() {
  const cvs = p5canvas.canvas;
  const keyTarget = document.getElementById(cvs.id);
  keyTarget.setAttribute('tabindex', '0');
  keyTarget.focus();
  keyTarget.addEventListener('keydown', (e) => { processKeyEvent(e); return false });
  keyTarget.addEventListener('keyup', (e) => { processKeyEvent(e); return false });
}

function processMouseEvent(e){
  const bcr = p5canvas.canvas.getBoundingClientRect();
  processEvent(e, e.clientX - bcr.left, e.clientY - bcr.top);  
}

function processTouchEvent(e){
  const bcr = p5canvas.canvas.getBoundingClientRect();
  const te = e.changedTouches[0];
  processEvent(e, te.clientX - bcr.left, te.clientY - bcr.top);
}

function processEvent(e, x, y){
  events.unshift(`Time: ${nfs(millis(), 6, 0)}  Type: ${e.type}  at [${x}, ${y}]`);
  while(events.length > 16) events.pop();
}


function processKeyEvent(e, x, y){
  events.unshift(`Time: ${nfs(millis(), 6, 0)}  Type: ${e.type}`);
  while(events.length > 16) events.pop();
}

The sketch in action :grin: The code can be found here

tysm for your answer, and your welcome :slight_smile:

this is a “handle inputs locally” type of approach, and while it’d allow to create custom functions for zooming and scrolling within the canvas, it wouldn’t help with browser-based gestures like pull to refresh, or scroll to make the url bar disappear (which I admittedly didn’t mention as something I’m after, my bad).

the reason I asked here is specifically because I’ve found posts that ask the exact opposite question, meaning how to disable all of these touch controls, like this one, this other one, or even a third one (that I can’t link because my account is too recent) which is called “Restricting touches to be used by P5.js and not the browser: possible?”.

these posts are all from 2020-2023, so could this possibly have something to do with the V2 of p5js?

thanks again!

edit : converted my js to p5js v1 and now it all works fine, so I guess that’s one way to get it done, but now gotta deal with v1 issues that were fixed in v2 :upside_down_face: