p5.js
p5.js copied to clipboard
orbitControl needs an unnecessary first touch on Mobile
orbitControl on Mobile didn't work until you make a first touch. This just happen on Mobile. Is there a bug ? or a browser limitation? Events like touchStart, Click, pressed, etc. Just works without needs of a first touch.
Steps to reproduce this: Go to orbitControl example on a Mobile Device (or browser device view), and try to use it. https://p5js.org/reference/#/p5/orbitControl
P5 Version: 1.3.1
Welcome! 👋 Thanks for opening your first issue here! And to ensure the community is able to respond to your issue, be sure to follow the issue template if you haven't already.
I think this is causing the conflict.
https://github.com/processing/p5.js/blob/3f32cbf4d3ac05773f91922bd9e0e881307a1937/src/webgl/interaction.js#L59
== UPDATE
Actually I found the problem. The conflict is with the Right/Left Click conditional. (Not sure how its handle on mobile)
https://github.com/processing/p5.js/blob/3f32cbf4d3ac05773f91922bd9e0e881307a1937/src/webgl/interaction.js#L105
If I comment the RightClick conditional, and just left the left click behavior. It works as expected. Of course this is not the expected behavior on Desktop. Maybe a param for allow/disable right click ? or Mobile ?
src/webgl/interaction.js
p5.prototype.orbitControl = function(sensitivityX, sensitivityY, sensitivityZ) {
this._assert3d('orbitControl');
p5._validateParameters('orbitControl', arguments);
// If the mouse is not in bounds of the canvas, disable all behaviors:
const mouseInCanvas =
this.mouseX < this.width &&
this.mouseX > 0 &&
this.mouseY < this.height &&
this.mouseY > 0;
if (!mouseInCanvas) return;
const cam = this._renderer._curCamera;
if (typeof sensitivityX === 'undefined') {
sensitivityX = 1;
}
if (typeof sensitivityY === 'undefined') {
sensitivityY = sensitivityX;
}
if (typeof sensitivityZ === 'undefined') {
sensitivityZ = 0.5;
}
// default right-mouse and mouse-wheel behaviors (context menu and scrolling,
// respectively) are disabled here to allow use of those events for panning and
// zooming
// disable context menu for canvas element and add 'contextMenuDisabled'
// flag to p5 instance
if (this.contextMenuDisabled !== true) {
this.canvas.oncontextmenu = () => false;
this._setProperty('contextMenuDisabled', true);
}
// disable default scrolling behavior on the canvas element and add
// 'wheelDefaultDisabled' flag to p5 instance
if (this.wheelDefaultDisabled !== true) {
this.canvas.onwheel = () => false;
this._setProperty('wheelDefaultDisabled', true);
}
const scaleFactor = this.height < this.width ? this.height : this.width;
// ZOOM if there is a change in mouseWheelDelta
if (this._mouseWheelDeltaY !== this._pmouseWheelDeltaY) {
// zoom according to direction of mouseWheelDeltaY rather than value
if (this._mouseWheelDeltaY > 0) {
this._renderer._curCamera._orbit(0, 0, sensitivityZ * scaleFactor);
} else {
this._renderer._curCamera._orbit(0, 0, -sensitivityZ * scaleFactor);
}
}
if (this.mouseIsPressed) {
const deltaTheta =
-sensitivityX * (this.mouseX - this.pmouseX) / scaleFactor;
const deltaPhi =
sensitivityY * (this.mouseY - this.pmouseY) / scaleFactor;
this._renderer._curCamera._orbit(deltaTheta, deltaPhi, 0);
}
return this;
};
orbitControl on Mobile didn't work until you make a first touch. This just happen on Mobile. Is there a bug ? or a browser limitation? Events like touchStart, Click, pressed, etc. Just works without needs of a first touch.
Steps to reproduce this: Go to orbitControl example on a Mobile Device (or browser device view), and try to use it. https://p5js.org/reference/#/p5/orbitControl
P5 Version: 1.3.1
Highlights:
The need for 1st touch is because of line https://github.com/processing/p5.js/blob/3f32cbf4d3ac05773f91922bd9e0e881307a1937/src/webgl/interaction.js#L103 To use the orbiting and panning functionality we have to click on the canvas, just bringing the cursor within the boundaries is not enough. It makes sure that it tracks the mouse/finger when the canvas is selected, which is done by mouse click/ finger tap.
Not sure if this qualifies to be called a bug.
Details:
There is only a finger tap/swipe and no left or right mouse click like on desktops. This means we can't configure different functionalities to it. And currently on a mobile browser, the orbitcontrol function only allows camera orbiting and not camera panning. Since finger tap activates https://github.com/processing/p5.js/blob/3f32cbf4d3ac05773f91922bd9e0e881307a1937/src/webgl/interaction.js#L105 .
So if the possibilities are only finger taps and swipes then we can either configure orbit behavior or pan behavior. Then for 3D interaction with the object, if we choose to configure it to the orbit behavior, that would mean, the check of
if (this.mouseButton === this. LEFT) and
else if (this.mouseButton === this. RIGHT)
conditions don't matter for mobile and can be removed. Only the function call to _orbit is needed, which are lines
https://github.com/processing/p5.js/blob/3f32cbf4d3ac05773f91922bd9e0e881307a1937/src/webgl/interaction.js#L106-#L110.
And the unnecessary first touch on the mobile is due to if (this.mouseIsPressed). After removing this conditional, everything works fine in the mobile browser, is no need for 1st touch. Another outcome of this is, whenever we bring our finger from outside the canvas to inside the canvas on mobile, the 3D object will move. Further, this breaks the functionality in the desktop, as now the 3D object will move whenever the cursor is in the canvas, which leads to unwanted movement.
So to solve this, there is need of different code for desktop and mobile browsers. As currently, the pan and also the zoom in/out functionality which is done by mouse wheel up/down are completely missing .