I am having a redraw issue, when you are scrolling the canvas will not redraw until you release your touch. The problem with that is I depend on "ontouchmove" to move my character around. So until the touch is release, the canvas will not redraw.
Another problem is when ever the canvas is touched it is focus, or activated. It develops a focus ring around it. I tried setting both the :focus and :active pseudo's borders and outlines to nothing. Also I saw "drawFocusRing" for the context of the canvas, however that didn't seem to resolve the issue.
Currently I tested on Android stock browser 2.2 (MyTouch 3G)
I believe the orange focus ring is more in relation to the WebView you are using to view the canvas maybe? I know I had a similar issue with js drawing on a canvas.
myWebView.setFocusable(false)
myWebView.setFocusableInTouchMode(false)
Should solve the focus problem.
I don't know about Android specifically, but in mobile Safari you can prevent scrolling using the event.preventDefault() method. If your application requires scrolling, it might be possible to implement your own scrolling mechanism whilst still preventing the default behaviour, maybe by combining touch events with CSS positioning on a page wrapper div?
Related
I have this tetris game I programmed with the intention of learning a bit more on javascript: elcodedocle.github.io/tetrominos
I can play it in most tablet/smartphone browsers, but on my Android 2.3.6 stock browser (Samsung Galaxy Ace ST5830) it has two problems:
Zoom events are not exactly canceled by user-scalable=no viewport property: double click and two-finger zooming still work. Sometimes.
The canvas freezes, also sometimes (I'm going mad trying to determine the cause: How the heck you debug a web app running on an android browser??). I'm guessing because of a swipe or drag event triggered that shouldn't be, so it's somehow related to the above. Tapping out of the canvas makes it work again.
I'm using Kineticjs to manipulate the canvas and bind the touch events, on top of jquery-ui for the dialogs and jQuery (not jQuery mobile).
Any suggestions/ideas?
the problem is with the device's processing speed.. evrery device has its own processing speed. canvas animations are based on javascript's setInterval and setTimeout methods..which performs as per the device's processing speed..thats why canvas games are sometimes laggy on handhelds.
This is a weird issue that I am only experiencing on a Native browser on Samsung Galaxy Tab 2 and Galaxy S2 in the native browser.
This has also been tested on other android phones and tablets such as the Nexus 7 & Galaxy S4 but their native browser is chrome, so it appears fine. This issue is also not present on any IOS browsers, Windows Desktop browsers or Mac Desktop browsers.
It's almost asif the webpage is loaded twice ontop of itself!
As there is a duplicate canvas element, that updates as the main canvas does.
Here it appears asthough it only happens when rotated in landscape mode, but I beleive that in portrait mode, the canvas' are perfectly aligned over the top.
What is even weirder, the menu button that you see is a toggle button, tap to open menu, tap to close menu. On this device when you tap it, it opens and closes instantly. the same happens for the mute button toggle.
I'm completely at a loss.
I have done some javascript debugging throwing in a few alerts here and there, and the initialisation functions that create references to the canvas and so on are only called once.
I have read and heard about hardware acceleration causing issues, but solutions i've potentially found are only relative to building native apps! not HTML5 Canvas webpages.
Any insight on this could be would be great!
Thanks in advance.
--EDIT
I also put in this test alert(document.getElementsByTagName('canvas').length); to see if there was 2 canvas in the DOM but it returns 1!
I ran into this same issue. I was able to fix this by running the following code after making a change to my canvas:
// If Samsung android browser is detected
if (window.navigator && window.navigator.userAgent.indexOf('534.30') > 0) {
// Tweak the canvas opacity, causing it to redraw
$('canvas').css('opacity', '0.99');
// Set the canvas opacity back to normal after 5ms
setTimeout(function() {
$('canvas').css('opacity', '1');
}, 5);
}
By tweaking the opacity, this forced the canvas to redraw and removed the duplicate shapes. It's a dumb fix but it works. Hopefully this helps someone.
Also you may look at this collections of such tips: http://slash-system.com/en/how-to-fix-android-html5-canvas-issues/
For double canvas issue there is a bug logged https://code.google.com/p/android/issues/detail?id=35474 you may want to check suggested solutions.
In my case this issue appeared only if I had Force GPU rendering enabled.
Issue usually appears if you have some parent element for canvas that has CSS overflow: hidden
remove overflow property from all canvas parents,probably we don’t need this property on touch devices:
$("canvas").parents("*").css("overflow", "visible");
It is well explained at http://slash-system.com/en/how-to-fix-android-html5-canvas-issues/
I've created a website with a parallax street scene. See here for an archived version.
It works just fine on all major desktop browsers, and Safari Mobile. It works fine in Mobile Firefox and Chrome for Android Beta also. However the default Android browser has issues with the scroll event. Let me be clear. Scrolling is not the issue. The div scrolls as required. The scroll event doesn't fire. This issue I experience on Honeycomb as well as ICS.
I'm not concerned about other mobile browsers because for mobile screen sizes one usually does not see the parallax scene; mediaqueries and conditional JavaScript loading take care of that. Responsive design and all that jazz.
Basically, I've written a parallise() jQuery plugin that positions each image based on its position and 'depth'. This function is bound to the scroll event.
On Android Browser, this event only fires at the start of the next touch, instead of continuously.
OK, so I thought that perhaps if I bound the function to touchstart, touchmove, and touchend events I would solve my issue. No cigar. Other touch events are also bugged. Applying the suggested workaround causes the events to fire, but as I have to e.preventDefault(), scrolling (the whole point of the exercise) is disabled.
What if I just poll the position of the stage div relative to the window div? Turns out that the position information is only updated at the start of the next touch.
I am at the end of my tether. Any help would be much appreciated.
Even if the touch events worked correctly on the bugged versions of Android, and you were then effectively able to track the native scroll position during a drag, this would be prone to error. For example, it wouldn't account for the momentum animation which happens after the touching has finished.
iOS and Android make sacrifices to improve the performance of scrolling. On both platforms, it's not possible to get the accurate scroll position until the scroll has completed. The scroll event (on the <body>) doesn't fire until the momentum animation is finished. So while your original question is about scroll events on an overflowing <div>, fixing this might not be totally helpful for you anyway.
If you want an animation to update in time with the scroll, then you need to perform the scroll programatically rather than using the browser's native scroll. The best library to do this is iScroll. You can achieve parallax effects very easily as seen in this demo.
If you need more complex effects (the walking character, in your example), you can opt for the "probe" version of iScroll which allows pixel-perfect polling of scroll position in return for reduced performance.
However, there are many downsides to using iScroll:
You may need to change your markup and styling
It is unnecessary overhead for desktop browsers, but due to markup changes may be difficult to use only as a fallback
The scrolling will not feel perfect - on iOS, with its usually excellent scrolling performance - the slight difference in momentum calculation can feel jarring. On Android, the scrolling can become more laggy than usual.
Swipe shim that doesn't need preventdefault on touchstart: https://github.com/TNT-RoX/android-swipe-shim
While attempting to make a game using Canvas I noticed a few quirks on tablet / phone browsers.
1) How do I disable the Canvas from being selectable? It seems like when the user touches it, it highlights the canvas, and almost makes an attempt to select it. This is undesired.
2) Browser slide gestures. Some browser have slide gestures that override any movement capturing done in the canvas or webpage. This is extremely annoying and undesired as well.
3) Canvas control with HTML UI elements. I noticed when there is a canvas present with fellow ui elements (such as text) sometimes clicking or dragging in the canvas will highlight a part of the HTML and instead drags the HTML elements instead of hitting the canvas.
Any help is greatly appreciated! I was hoping HTML5 would be mature enough to allow for good compatibility on mobile as well as desktop. The idea is to be able to code once and play everywhere....thanks!
This should fix your issues relating to #1 and #3:
canvas.addEventListener('selectstart', function(e) { e.preventDefault(); return false; }, false);
#2 seems like an awfully separate question, but I've never had a problem with slide gestures overriding any of my canvas stuff. Try using e.preventDefault(); at the beginning of your touch events.
I've been testing out the new functionality of html5 and js to create a sketching site. I've been looking into this for a possible client that wants their site to be ipad accessible, but also have drawing features on it.
So i created a rough experiment where you can drag your mouse across a screen to draw lines. I went to test it on an ipad and realized this doesn't work. Why? because dragging on an ipad is reserved for actually dragging the screen around.
Is there something you can do to get around this? I'm sure this could be done if made for an app, but what about just a normal website.
In your code, replace your events like that:
onmousedown => ontouchstart
onmousemove => ontouchmove
onmouseup => ontouchend
At least that is how it works on iPhones. Further reading: http://www.sitepen.com/blog/2008/07/10/touching-and-gesturing-on-the-iphone/
Shameless self promotion - I developed a jQuery plugin for drawing on a website via HTML5 for the purpose of collecting signatures on the iPad screen. http://www.crowdsavings.com/open-source/drawbox