Mobile Input Stops Working After Hiding the Canvas

I can’t share code/project because it is client work, but I will do my best to describe the situation.

I have a game that I have developed in PlayCanvas. Very simple. UI Button Elements and a swipe input for launching a projectile using ammo.js for physics.

We have the game on a microsite and the game is part of a modal that appears. The game is never destroyed or unloaded or the page refreshed.

When the modal appears the game is made visible and when the modal is hidden the game hides with it.

On mobile (can replicate on device and in chrome tools) when the game is shown for the first time everything works fine. Once it is hidden and then shown again all touch input stops working.

Is there a way to refresh/reload the game or re-enable touch input? We had tried destroying the game and reloading it but ammo.js causes problems.

On my phone at the moment so can’t check the engine codebase:

The touch device uses the canvas for events. When the app makes the canvas visible again, you may have to reattach it to the touch device: https://developer.playcanvas.com/en/api/pc.TouchDevice.html#attach

this.app.touch.attach(canvasDom)
1 Like

Thanks for the quick response, but unfortunately same results.

I’m attaching the dom every time the game is unhidden in the modal, even the first time that always worked before. The first time still works but all subsequent attempts don’t receive touch input.

When I test with ipad in chrome dev tools the ipad functions properly, but I think I had read before that the ipad handles input differently? I could be wrong

Without a repro, it’s a bit hard to tell what is going on. Is there a invisible DOM object in front of the canvas the second time round?

I apologize that I can’t get you code due to the nature of what we are doing.

We’ve gone through everything and double checked looking for anything that might intercept touches.

The weird part of the repro for me is this:
I have 5 “pages” for lack of better term. Really just game entities that i turn on and off in sequence. The first “page” has a button to start. The second “page” does a quick tween animation between text and images. The third “page” has another button to advance. The fourth page has no buttons but requires swiping to launch projectiles and after time it advances to the 5th “page” that loops back to the first page

The first time the canvas is made visible all touches work at all times. Can go through the game as many times as we like.
If we hide the game before we get to swiping input, when we unhide the the canvas everything works fine. But the moment we do a single swipe the next time we unhide no touch input works.

Nothing unusual going on within the code. Registering for mouse down and touch events in the swipe. Determing swipe by touch/mouse down and touch/mouse up delta. Using the UI Button Elements for the buttons. Really weird situation and we’re pulling our already thinnomg hair out :smiley:

Just to check, what do you mean by ‘canvas’? Do you mean the DOM object or an in game UI screen/entity?

By canvas I meant game/playcanvas. I’m not a web dev :confused:

Ahh, in which case ignore my earlier reply about attaching.

Thoughts about what could be the issue without seeing the project:

Are you calling stopPropagation() anywhere? The order of registering the touch event for UI elements could be the problem.

I would also be tempted to add a breakpoint to the touchevent handlers in the engine and walk through all the listener list(s) to see where it could be going wrong.

Are the swipes listening for app.touch events? Does it unlisten at any point such as on disable?

Beyond that advice, we will need a reproducible project. Any chance you would be able to a take a fork a strip it right down to the bare essentials that reproduces the issue?

Use http://www.fillmurray.com/ for placeholder images if you need to

Just went through all code. stopPropegation is not being called anywhere. Also the swipe is adding handlers for the touch and mouse events in Initialize and letting it run from there

I don’t have an easy way to get you something to repro w/ due to the website code and the game code being two different things. Too many things in the website to strip out.

I don’t think it is anything unique to this playcanvas game, but more of a product of the hide/visible toggle of the playcanvas game in the modal. There are two html buttons on the same modal that work in all scenarios always so touch events do still occur. The playcanvas game simply stops processing touches but handles mouse input just fine.

Only thing I can think beyond the above is that there is a HTML DOM blocking touch input.

Can you share a link to the site where it’s hosted? And if so, the repro steps/video on how to reproduce?

About the setup @derek9nine, is the can you show the code when the game/PlayCanvas is hidden please?

Ok, so I finally got to the bottom of the problem.

In the SwipeInput.js the following code existed:

SwipeInput.prototype.onTouchDown = function (e) {
    this.setInitialPos(e.changedTouches[0].x, e.changedTouches[0].y);
    e.event.preventDefault();
};
SwipeInput.prototype.onTouchUp = function (e) {
    this.updateSwipeDirection(e.changedTouches[0].x, e.changedTouches[0].y);
    e.event.preventDefault();
};

This is simply saving the position and then the updateSwipeDirection calculates the length of the swipe and the angle of the vector on the screen.

Once I commented out the e.event.preventDefault(); line everything works as expected. This is a copy/paste line from an example but I’m not sure why this particular element would stop all future input and only do so once the playcanvas game was hidden and made visible again.

This was a real head scratcher. I had to narrow down the moment it broke and start changing things.Thanks for the help @yaustar! I’ll share the link of the live project tomorrow :slight_smile:

That’s interesting. Not sure why preventDefault() would stop something from input from working again :thinking:

Happy to hear that you got to the bottom of it though!