When I use Fabric.js to generate canvas, there is annoying flickering when tapped with finger in iPad (mini) and iPhone (4). The flickering is like canvas goes fast to black and then white again.
Steps to reproduce:
With iPad or iPhone surf to eg. this line drawing utility:
http://jsfiddle.net/fabricjs/URWru/
(function dummy{})
Put your finger on to the canvas and lift it then back. Do this fast, as you do when clicking with mouse. The flickering occurs when finger is up. If you hold your finger a second or more on the canvas and then lift back, the flickering doesn't occur.
Why the flickering occurs and what could be done to prevent it?
This is Q&A style answer.
The solution is simple. Add this to css:
canvas {
-webkit-tap-highlight-color:rgba(0,0,0,0);
}
Ryan Grove describes the reason in yuiblog.com:
"Unfortunately, Mobile Safari has no way to distinguish between normal click subscribers and delegated click subscribers, which is when the click event is attached to a container rather than to each child of that container. As a result, a delegated click will result in the entire container being highlighted rather than just the item that was tapped, and this can be both ugly and confusing for the user."
This trick is reported to work at least: Android based browsers, iPhone Safari, iPad Safari, iPad Chrome.
Related
I discovered that the chrome mobile emulator touch detection is not accurate.
The click event is also fired even If I click outside the target DOM.
According to my demo, the click event is fired unexpectedly when clicking between the red border and the green border.
I know it cannot be repeated in real mobile devices, but it is pretty confusing for the development
Any reason why?
Demo:
Only View: https://kdlmxn.csb.app/
Playground: https://codesandbox.io/s/optimistic-monad-kdlmxn?file=/src/App.vue
I am attempting to use the data received from DeviceOrientationEvents to animate (rotate) a camera in three.js using three's DeviceOrientationControls. The controls are updated upon every animation frame, and everything works as I would expect. However, if I begin to scroll, then no DeviceOrientationEvent is fired again until the inertia from the scrolling is complete.
I have confirmed that these events are not fired (or at least not dispatched) during the scroll by logging to the console from within the DeviceOrientationEvent handler. I can see the events fired regularly up until the moment I begin to scroll, then stop, and then resume firing from the moment the inertia from the scroll is complete.
Manually stopping the inertia mid-scroll (by touching the screen) also causes the deviceorientation events to resume.
I have disabled all other scroll event handlers in my script. I have made all touch event handlers passive, have tried making them non-passive as well, and have also tried disabling all touch event handlers in my script altogether.
I am fairly sure by this point that this may be a function of how the processing of the scroll thread (which operates separately to the main thread) and the processing of IMU data are scheduled/queued in the browser, so that there may be no good solution, but I'm asking here in case there is something I've overlooked in my own troubleshooting. This does not appear to be an issue with three.js or the DeviceOrientationControls in three.js, but I've tagged this as three.js just in case anybody has ever come across this problem when attempting something similar.
My unique case for having DeviceOrientationControls enabled while scrolling is that scroll drives the animation of a "camera rig" (of empty objects whose rotation and position are animated), while moving the phone around rotates the camera itself. (It's a bit like being able to turn your head to look around while moving in a railcar.)
My testing has been on an IPhone 11 Pro, with iOS 13.5.1, in Chrome iOS 84, and Safari. I have not tested on Android.
iOS has slowed down repetitive JavaScript functionality during scroll for many years now. This is to conserve battery consumption, since it has to re-render the page lots of times while scrolling, so it halts other secondary commands until scrolling is complete. See here for more.
You could create your own custom scrolling functionality without actually scrolling down an HTML page by capturing vertical swipe gestures via 'touchstart' and 'touchmove'. Or you could use a library like Hammer.js to help you.
I have a website that uses CreateJS and canvas. Some objects have associated a click event. Works well in browsers and mobile devices, except in windows surface.
If I zoom in windows surface the click event is lost when the screen moves. Only works well when matched (0,0) to the screen.
Example:
http://intelisen.com/apok/simple.html
Zooming and moving no longer works circle click event.
Any suggestions?
Thank You
I'm making a small full-screen canvas game to be played on mobile. It involves swiping around the screen with your finger. I have the canvas listening for touch events (down, move, up).
Unfortunately, the browser tries to interpret swipes left and right as browser tab navigation, and swipes up and down as hide/show URL. I don't care if the URL is hidden or not, I just want everything to stay still.
As a result of everything moving, it intermittently stops recognizing inputs to the canvas.
The way I have it set up is a canvas that takes the size of the screen, set its position to fixed at 0,0. This is to prevent scrolling (which works, except for the hide/show url thing).
If you want to see an example, here's where I'm hosting it:
http://phildogames.com/scratch/sust/index.html?game=window (you won't be able to interact on desktop because it's listening for touch events, but if you view it on mobile you should be able to open and close the windows).
tl;dr: I want to tell the browser to simply pass swipes (well, all touch events) to the dom and stop interpreting them as intents to scroll, switch tabs, hide/show URL, etc..
Thanks!
I was able to solve your problem by simply preventing touches on the body.
var myBody = document.getElementById('dabody');
myBody.addEventListener('touchstart', function(e){
e.preventDefault()
});
You can throw that in console to test. Tested on iOS Safari and Android Chrome.
I am working on a website which has an canvas on it. I have an image in the canvas, and what I want to do is pinch to zoom the image (the web page will eventually be on a touch screen). I am using jGestures for detecting pinch event. However, I wonder if there is a way to test on a Mac computer, because when I do pinch on mac trackpad, it zooms the webpage, not the canvas, which means that the pinch on trackpad does not apply to my canvas tag, it zooms my webpage (the font, the width, the height). I also wonder if magic trackpad or magic mouse can do it. Could anyone help?
If you have Xcode you could run the iOS simulator. The simulator would allow you to pinch. Hold down Option key and you should be able to mouse click to zoom in and out.
I got multitouch working on my MacBook's trackpad with npTUIOClient (see article) with an old version of Chrome. Think it was v.10 or so.