editor icon indicating copy to clipboard operation
editor copied to clipboard

On iOS devices, the canvas is selectable

Open yaustar opened this issue 4 years ago • 15 comments

So far, only tested on iPhone X and XR, in Safari and Chrome

It is possible to select the canvas on PlayCanvas published apps. Eg: https://playcanv.as/e/p/w8Hhxovk/

Holding the finger on the canvas causes the selects the canvas and brings up the menu to 'copy'.

An end user is able to fix this by adding the following CSS

-webkit-touch-callout: none;
-webkit-user-select: none;
-webkit-tap-highlight-color: rgba(255, 255, 255, 0); /* mobile webkit */
canvas

{ -webkit-touch-callout: none; -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none;' -ms-user-select: none; user-select: none; outline: none; -webkit-tap-highlight-color: rgba(255, 255, 255, 0); /* mobile webkit */ }
'body

{, background-color: #FFFFFF; -webkit-touch-callout: none; -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; outline: none; -webkit-tap-highlight-color: rgba(255, 255, 255, 0); /* mobile webkit */ }

yaustar avatar Sep 24 '20 11:09 yaustar

This also resolves the same issue for P5.JS

Thank you.

JackkBurn avatar Aug 04 '21 04:08 JackkBurn

Suggestion: We make this an option for users in the project settings to use/disable

yaustar avatar Aug 10 '21 10:08 yaustar

Workaround: https://playcanvas.com/project/722923/overview/ios-select-canvas-fix

Code to include in the project:

(function() {
var style = document.createElement('style');
document.head.appendChild(style);
style.innerHTML = 
"canvas{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;outline:0;-webkit-tap-highlight-color:rgba(255,255,255,0)}" +
"body{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;outline:0}";
})();

yaustar avatar Aug 25 '21 16:08 yaustar

I'm starting to warm to the idea that we enable this behavior by default.

willeastcott avatar Aug 25 '21 20:08 willeastcott

I've tried to see if I can restrict this behaviour to the canvas only rather than applying this to the document body. The best I got was to wrap a div around the canvas element and put the CSS rules on the wrapper.

Unfortunately, long touching on the canvas seems to highlight the first bit of HTML text on the document.

https://user-images.githubusercontent.com/16639049/132735758-da05d9bd-4325-4b1a-8ce6-4855727d116d.mp4

It is starting to feel like we need to put this on the body which is frustrating :(

yaustar avatar Sep 09 '21 17:09 yaustar

Current thinking is that we add this as an Editor option which is true by default. Users can disable it if they require users to be able to select HTML elements via long press.

Thoughts @willeastcott and @vkalpias ?

yaustar avatar Nov 10 '21 12:11 yaustar

Sounds reasonable to me.

willeastcott avatar Nov 10 '21 12:11 willeastcott

Would be great if it will be a simple css/js in index.html file, so when build is made, it will be easy to identify and remove. Similar to the was CSS is added for canvas scaling.

Maksims avatar Nov 10 '21 12:11 Maksims

We would still need the option in the Editor for that people who host on playcanv.as :)

yaustar avatar Nov 10 '21 13:11 yaustar

We would still need the option in the Editor f

Sure, index.html is built same way for build either to download or publish on playcanv.as, as mentioned before, just like embedding CSS for scaling canvas based on project settings.

Maksims avatar Nov 10 '21 14:11 Maksims

According to this you can also do:

canvas.onselectstart = function () { return false; }

I tried it locally and seemed to work fine. If there aren't any downsides, perhaps this is a neater solution to modifying CSS?

slimbuck avatar Feb 25 '22 19:02 slimbuck

I'm good with that!

willeastcott avatar Feb 25 '22 19:02 willeastcott

As long as it doesn't affect any other input for the engine (eg an orbit camera script) I'm good with that

yaustar avatar Feb 25 '22 20:02 yaustar

I've tried it in this project: https://playcanv.as/e/p/8qGM8Y0q/

via code:

    this.app.graphicsDevice.canvas.onselectstart = function () { return false; };

And on my iOS 15 device, I'm still able to select the canvas

yaustar avatar Feb 25 '22 22:02 yaustar

According to this you can also do:

canvas.onselectstart = function () { return false; }

I tried it locally and seemed to work fine. If there aren't any downsides, perhaps this is a neater solution to modifying CSS?

This worked for my project in ios 15.6 safari iphone 12 mini I just put canvas.onselectstart = function () { return false; }; into an abitrary script to test it. voila.

phiLyken avatar Aug 17 '22 16:08 phiLyken

Actually on iOS 16 onselectstart didn't work for me and according to this doesn't work on iOS.

The following did however:

canvas.style['-webkit-user-select'] = 'none';

slimbuck avatar Nov 14 '22 16:11 slimbuck

A PR with this fix has been merged and should be released in the next week or two.

slimbuck avatar Nov 15 '22 11:11 slimbuck

Released in 1.23.2

yaustar avatar Nov 16 '22 10:11 yaustar

hi all, I am trying to solve this issue on iOS 16 Chrome. It works alright on Safari (the scope/bubble shows occasionally but doesn't hamper gameplay), but on chrome it will impact gameplay. As soon as I double-tap and drag it starts a selection. I tried all the options mentioned above. Any ideas?

andri-iamlab avatar Mar 16 '23 12:03 andri-iamlab

@andri-iamlab You need to call preventDefault on the touch start event to prevent that browser behaviour.

Example: https://playcanvas.com/project/1051540/overview/ios-16-select-issue

(function() {
    const app = pc.Application.getApplication();
    if (app.touch) {
        app.touch.on(pc.EVENT_TOUCHSTART, (e) => {
            e.event.preventDefault();
        });
    }
})();

yaustar avatar Mar 17 '23 14:03 yaustar

That solved it, thanks a lot!

andri-iamlab avatar Mar 20 '23 14:03 andri-iamlab