My favorites | Sign in
Project Home Issues
New issue   Search
for
  Advanced search   Search tips   Subscriptions
Issue 35474: WebView: animation issues with Java Script, JQuery Mobile and Phonegap
61 people starred this issue and may be notified of changes. Back to list
Status:  Obsolete
Owner:  ----
Closed:  Sep 21


Sign in to add a comment
 
Reported by fluxi...@googlemail.com, Jul 24, 2012
Hi,

after the update from Android 4.0.4 to 4.1.1 on my Samsung Galaxy Nexus I have some strange Java Script issues.

I try to do an animation with the function setIntervall() and draw something on the canvas. The result is not one animation, it's two. Looks like a render or caching problem.

This only happens with Android 4.1.1 if I start the App as an apk with Phonegap. I use JQuery Mobile 1.1.1 for some stuff and Phonegap 2.0.

There are no problems if I run the HTML5 pages inside a browser on a PC or my Nexus. I can run the App with Phonegap on the simulator with Android 4.0 without issues.

So I'm pretty sure it's because Android 4.1.1 maybe the new JS V8 Engine.

The two files contain my full sourcecode to reproduce the problem.
You can add the JQuery Mobile and Phonegap files, but I think you don't have to, to see the bug.

I'll hope someone can reproduce and report the same bug.
batteryStatus.html
1.7 KB   View   Download
battery.js
1.3 KB   View   Download
Aug 1, 2012
#2 muhammad...@handmademobile.com
I am also having the similar problem after upgrading to 4.1.1. Some weird events are getting fired twice which ends up executing the code twice.

I am also not seeing this issue in phone browser. It only appears when used within WebView or in my case PhoneGap.

It was working fine prior to 4.1.1 release.
Sep 5, 2012
#4 wcald...@gmail.com
We see the same issue with an HTML5 application in the browser as well using a canvas widget. In android 4.1 and earlier we would see only one of the widgets displayed. With 4.1.1 we see 2 now. We reproduced this with several different model phones which leads us to believe that its not "vendor" or display driver specific.
Sep 5, 2012
#5 wcald...@gmail.com
How do we get this issue addressed? This problem clearly prevents anyone from using a JS Canvas element in Android 4.1.1's browser/webkit.

Sep 5, 2012
#6 gchar...@smartmobilesoftware.com
We also have the same issue on our html5 game.
Sep 25, 2012
#7 silverg...@gmail.com
Same problem here. No solution yet. Problem appears in stock browser and also in Phonegap 2.0.0. Problem doesn't occur in Android 4.0.x. Problem also doesn't occur in Andoid 4.1 using Chrome Mobile browser.

Surprisingly most (or all?) websites using canvas render correctly (no canvas duplication) - so it might be a problem occuring only in combination with JQuery Mobile or a bug in my prototype application / in fluxis "batteryStatus"-App. Will do some investigation next week...

Information:
* JQuery Mobile Alpha 1.2
* Android 4.1.1
* Asus Transformer Pad

Attachments:
* battery1: Screenshot batteryStatus.html
* battery2: Screenshot batteryStatus.html
* prototype1: Screenshot: Duplication of the signature-pad ("Unterschrift"). Signature pad is drawn using canvas.
* prototype2: Screenshot.
battery1.jpg
182 KB   View   Download
battery2.jpg
194 KB   View   Download
prototype1.jpg
90.5 KB   View   Download
prototype2.jpg
93.9 KB   View   Download
Oct 10, 2012
#8 silverg...@gmail.com
Possible solution:

Removing the following line from jquery-mobile-css eliminates the problem:
"
/*content area*/
.ui-content { border-width: 0; overflow: visible; overflow-x: hidden; padding: 15px; }
"
(removing "overflow-x: hidden" is sufficient).

A better solution is to override the "overflow-x" attribute on the surrounding div-element (not the canvas-element itself).

Example (for battery-status):

<div data-role="content" align="center" data-theme="a" style="overflow-x: visible">
 <canvas id="myBatteryCanvas" width="device-width" height="device-height">                        
    Sorry, your browser doesn't support canvas technology        
 </canvas>
</div>
Oct 10, 2012
#9 wolfg...@decatur.de
There are more issues with canvas on Android 4.1.1.
If I give the canvas a css width then the canvas is only partially painted:

<div data-role="content" style="overflow-x: visible">	
  <canvas style="width:330px;height:330px;display:block;" width="200" height="200">
  </canvas>
</div>

When navigating to a different page, the browser display full canvas for a moment before leaving the page.

See http://decatur.de/colorgraph/bug-index.html.

@silverg... Thanks for the workaround.


Oct 10, 2012
#10 scott.ca...@gmail.com
Strangely, I can't repeat the OPs error in his example files, they work fine for me.

However, I see the same problems in lots of canvas applications completely unrelated to jquery mobile.  For example, this shape dragging example from Eric Rowell's html5 canvas tutorials works fine in Android Chrome and Android Firefox, but when compiled into the webkit using Phonegap 2.0, the shape being dragged is duplicated on first drag.  It works fine in phonegap/Android up until 4.1x.

Anyone else experiencing this independent of jquery mobile?

(for reference, the code came from here... http://www.html5canvastutorials.com/kineticjs/html5-canvas-drag-and-drop-events-tutorial/)  
index.html
1.6 KB   View   Download
kinetic-v4.0.0.js
190 KB   View   Download
cordova-2.0.0.js
176 KB   View   Download
Oct 10, 2012
#11 scott.ca...@gmail.com
Update...  

This looks like a cordova issue that is resolved in cordova-2.1.0.  I just did the upgrade and, fingers crossed, everything looks like it's working fine now.
Oct 11, 2012
#12 wolfg...@decatur.de
@scott: Well, it fixed your problem. Other reporters indicate jquery mobile triggering the bug. I'm not using cordova.
Oct 11, 2012
#13 silverg...@gmail.com
Reply to Comment 10:

I can reproduce the duplication on first drag on the Asus Transformer running Android 4.1.1 - on my Galaxy Note (running Android 4.0.4) no duplication occurs.

Btw.: The problem / solution I describe in comment 8 has nothing to do with jquery mobile directly. The problem is the "overflow-x" attribute. Since jquery mobile sets this attribute on every "ui-element" class element, the bug occurs (but other frameworks / css-files might also set this attribute and the bug will occur).

Strangely enough ther's no parent div-element with "overflow" set to hidden in http://www.html5canvastutorials.com/kineticjs/html5-canvas-drag-and-drop-events-tutorial/ ...

If I remember correctly I read an android issue here on google code about a bug in the canvas clear method.
"
messageLayer.clear();
"
(Code from drag-and-drop tutorial)
Oct 11, 2012
#15 joel.bag...@gmail.com
This problem doesn't appear directly related to jQuery Mobile other than maybe the fact that jQuery Mobile specifies overflow-x: hidden on the ui-content class applied to the content body.  These problems can also be duplicated on a standard HTML5 page by applying the overflow-x: hidden attribute to the parent container element.  See http://jsbin.com/olocal
Oct 11, 2012
#16 scott.ca...@gmail.com
I apologize and retract comment 11.  The cordova upgrade did not remove the duplication on first drag bug, after all.  It is back.  

Thanks to @silverg and @joel for the clarification on the jQuery Mobile relationship.  I'll research messageLayer.clear() and see what I find.
Oct 22, 2012
#17 rikkyc...@gmail.com
Has anyone resolved this issue? We seem to be having the same problem

We use PhoneGap Build, without jQuery in the source
Oct 22, 2012
#19 rikkyc...@gmail.com
Specifically, our problem is that we have a bunch of pages that move across a horizontal plane (through an app bar). That link seems to apply to us, but even if we're not having that specific issue I'd be hesitant to say that they're unrelated

Three of the pages have canvas elements, and on our Android 4.1.1 device those elements "pin" themselves to the top left of the screen. They also perform poorly and fail to update under the hood - generally, canvas is unusably buggy on this version of Android

We're just about to test a new build with the "overflow-x" thing deeper in the page, and also this potential fix: http://community.createjs.com/discussions/easeljs/404-android-4-html5-canvas-not-redrawing-with-easel
Oct 23, 2012
#20 darky...@gmail.com
Had this issue when canvas was duplicated on Samsung Galaxy Nexus with Android 4.1.1, spent almost 7 hours debugging canvas and in the end reading this bug. For my case I had only JS without any libraries.

Problem for me was that parent element for canvas had:
"overflow:hidden;"
commented/removed that line and issue fixed.
Nov 27, 2012
#21 lukesnow...@gmail.com
I'm not using JQ mobile an still had the same problem. Fixed by using the following loop method:

http://pastebin.com/KzEf5VnU


Dec 11, 2012
#22 greg.bal...@gmail.com
Yes, we are also seeing this issue in our app; both in webView and in browser. 
Can replicate the sample given in Comment 15 by joel.bag...@gmail.com, (thanks joel!) 

Problem is, we cannot remove the overflow:hidden... 
Dec 12, 2012
#23 greg.bal...@gmail.com
everyone, please "vote" on https://code.google.com/p/android/issues/detail?id=41312 which is a duplicate of this issue but it is clearly presented as an android bug, not jquery mobile or phonegap bug like this report suggests. 
Jan 15, 2013
#24 terrence...@gmail.com
For anyone experiencing this problem despite removing the overflow:hidden I've found that the native Android browser still requires the old way of clearing canvas by setting the width. This is my clearCanvas() function which solved the issue:

function clearCanvas(){
   canvas.context.clearRect(0, 0, canvas.width, canvas.height);
   if(STX.isAndroid && !STX.is_chrome){
      var w=canvas.width;
      canvas.width=1;
      canvas.width=w;
   }
}

Jan 15, 2013
#25 bgshop....@gmail.com
Instead of setting the width to 1 and then back to normal, you can just do this:

canvas.width = canvas.width;

By the way, this bug also exists in Android 4.1.2 .
Jan 16, 2013
#26 greg.bal...@gmail.com
thanks terrence and bgshop!!

canvas.width = canvas.width; 

does work however, if you are using css3 transitions to move the canvas around, this issue reappears.

I cannot believe this issue persists....its not a small bug!
Jan 23, 2013
#27 dadas...@gmail.com
I have encountered the issues described above, and based on my experience there are 2 problems:
1. The canvas clearRect(x,y,w,h) method does not clear the full canvas, leaving a copy of the drawing on the canvas. "canvas.width = canvas.width;" does solve this and in my case it was required to run only once - I could use clearRect afterwards, which has better performance.
2. The second issue is related to double canvases displaying (drawing appearing outside the actual canvas). This issue showed only on a real device and I wasn't able to replicate it on an emulator. In my case it was solved by setting the layerTypeMethod on the webview to LAYER_TYPE_SOFTWARE just the same way as is done to enable a transparent webview:
try {
		    Method setLayerTypeMethod = webview.getClass().getMethod("setLayerType", new Class[] {int.class, Paint.class});
		    setLayerTypeMethod.invoke(webview, new Object[] {View.LAYER_TYPE_SOFTWARE, null});
		} catch (NoSuchMethodException e) {
		    // Older OS, no HW acceleration anyway
		} catch (IllegalArgumentException e) {
		    e.printStackTrace();
		} catch (IllegalAccessException e) {
		    e.printStackTrace();
		} catch (InvocationTargetException e) {
		    e.printStackTrace();
		}

In some cases LAYER_TYPE_SOFTWARE might not be an option due to performance.
I hope this helps.

Jan 31, 2013
#28 molecul...@gmail.com
Same problem here with a canvas animation creatJS performed with phonegap for android. Canvas shows duplicates. dadas, Where do you implement the layerTypeMethod solution?

thanx......
Feb 6, 2013
#29 a...@enchroma.com
This horrible bug cost me 2 days of work and countless pissed-off users complaining that my HTML5/Canvas app was broken on their shiny new Androids.

The overflow-x stuff did not work for me.  My workaround is:

1. Create an invisible "dummy" <div> to stand in where the canvas was, having the same width and height as what the canvas is supposed to have
2. Find out what the x,y coordinates of the dummy div are
3. Create a canvas element with position:absolute and then set its top: and left: to the dummy's x,y pixel coordinates.  Now the canvas will be positioned where desired.
4. Use the canvas clear "fix" shown in comment #24 above.

Finally--it works correctly and the canvas has exactly the same positioning behavior as desired.


Mar 1, 2013
#30 leenatmo...@gmail.com
I also suffer from this bug. And I found that skyfire seem affected by this bug as well.
A quick fix, just for contribution:
if (/android/i.test(navigator.userAgent)) {
   //this is for phonegap in android
   jQuery('canvas').parent().css('overflow', 'visible');
}
It will work if you have a "overflow:hidden" wrapper div. Luckily, in mobile browser scrollbar often invisible, so it resolved my problem.
Good luck.
Apr 4, 2013
#31 roumani....@gmail.com
It seems there are multiple problems here.  I may have encountered a variant of what was posted above.

I noticed after an orientation change (e.g. portrait to landscape) on the native android browser, clearRect(...) was no longer clearing, rather it seemed to revert the contents to some buffered value.

During the resize event that I handle I re-draw my canvas (to adjust for the new size), it seems the act of drawing during the resize event causes the problem, this becomes what the browser considers the empty / buffered version of the canvas.  When a clearRect event follows it actually reverts back to what I drew during the resize event !

To get around this, something along these lines did the trick for me:
resizeEventHandler(e)
{
   ...

   // This is only needed for native android browser (the check below will
   // catch chrome as well ... should improve ...).
   // Need to defer the drawing until after the event.
   if (navigator.userAgent.toLowerCase().indexOf("android") > -1)
   {
      setTimeout(redrawGridContent, 1);
   }
   else
   {
      redrawGridContent();
   }
}


So during the resize I do nothing other then set my background (which I never clear so the browser can feel free to buffer).

This seems to do the trick.  I've tested this application on many other browsers and only encountered this on android's native browser (e.g. mobile chrome had no problems).
Apr 18, 2013
#32 lior.avi...@gmail.com
I found giving the canvas's parent a z-index helps wonderfully....but this bug needs to be corrected as it hinders major Webview functionality.
Apr 23, 2013
#33 roumani....@gmail.com
z-index didn't seem to help in my case, do you mind posting an example ?
Thanks !
May 6, 2013
#35 sami.taipaleenmaki
Android browser seems have poor performance example with Kineticjs. This scrollbar example is very slow with Samsung Galaxy S II

http://www.html5canvastutorials.com/labs/html5-canvas-simple-scrollbars-with-kineticjs/

There was also similar errors open in KineticJS but those are cloed by reason that problem is in Android not KineticJS.

https://github.com/ericdrowell/KineticJS/issues/search?q=android

We have project ongoing which is using Phonegap/KineticJS and we try found some solution for this. 
Since we are now done everyting with this compination it's not anymore possible to change framework for Android devices. Thanks about any help for solve this scrolling/performance issue.
May 13, 2013
#36 e.mathia...@gmail.com
I got this working by applying the following steps:

1) Set overflow-x to "visible" on all parents of the canvas.

2) After first frame is drawn, execute "canvas.width = canvas.width".

3) Set z-index (to w/e you want) on canvas parent.

It works well for me now on Android 4.1.2 and lower versions.
Hope that this helps!
XOXO
Jun 4, 2013
#37 kdzwinel@gmail.com
I'm drawing a single frame using canvas (overlay with arrows and instructions to show on the top of the app's interface). Fix with 'overflow' works fine for me (be sure to check all parents) but if someone really needs to have overflow:hidden, as I do, he/she needs to find another way around.

I found two - setting all parents to overflow:visible just before drawing on canvas and then turning everything back to overflow:hidden couple milliseconds after canvas was drawn OR hiding (e.g. with jQuery .hide()) canvas and showing it back (.show()) after it was drawn:

                                // draw canvas before the code bellow 
				tipOverlayElement.hide();
				setTimeout(function(){
					tipOverlayElement.show();
				}, 15);
Jun 23, 2013
#38 jbq@android.com
(No comment was entered for this change.)
Summary: WebView: animation issues with Java Script, JQuery Mobile and Phonegap (was: [4.1.1] animation issues with Java Script, JQuery Mobile and Phonegap)
Labels: Version-4.1 Component-Framework
Jul 15, 2013
#39 redn...@gmail.com
I had this issue and changing the overflow of the parent was not an option. The only solution that worked for me was to DISABLE hardware acceleration on the webview as described at https://coderwall.com/p/9prh-w

if (Build.VERSION.SDK_INT >= 11)
        webview.setLayerType(View.LAYER_TYPE_SOFTWARE, null);

This seems to fix a number of other issues, such as https://code.google.com/p/android/issues/detail?id=35288
Aug 5, 2013
#40 mcfar...@gmail.com
I would like to add that disabling hardware acceleration has fixed my canvas rendering issues using Cordova/PhoneGap. I have noticed that rendering is a bit slower though when compared to the stock Android browser. In my case though I did it in the AndroidManifest.

android:hardwareAccelerated="false"


Aug 29, 2013
#41 m...@wininup.com
Well I had exactly the same problem (Android version > 4). I tried many "tricks" listed on this page, but none worked out. The only way to make it work on these devices is to "play" with opacity : (jQuery syntax)

$canvas.css('opacity', 0.99);
setTimeout(function() {
    $canvas.css('opacity', 1);
}, 0);


Sep 3, 2013
#42 darky...@gmail.com
Now this can be reproduced on applications that use android shell with web views on Nexus 7 device having Android 4.2.2 and/or 4.3

For me what worked is to remove all overflow: hidden from application. Now I'm looking for better solution. 
Sep 27, 2013
#43 kanishk...@eyepax.com
I set the overflow attribute to visible for all the parent elements surrounding the canvas element using jquery. And it worked.

$("#canvas").parents("*").css("overflow", "visible");

The other solution is setting the hardware acceleration off for your application using Android manifest.
Sep 30, 2013
#44 punter...@gmail.com
here is another drag drop Tutorials, complete demo step by step. http://www.tutorialspark.com/html5/HTML5_Drag_Drop_Api.php

You can also drag drop files from local system to web page using the HTML5 fileAPI, http://www.tutorialspark.com/html5/HTML5_Drag_Drop_Apps.php
Oct 10, 2013
#45 denis.ra...@gmail.com
Bloody Android... Opacity on every frame seems only working trick
Oct 31, 2013
#46 makc.the...@gmail.com
Same here :) As with Denis, overflow: hidden somehow helps to trigger the bug, but removing it does not help, only opacity hack does.
Nov 3, 2013
#47 dhash...@gmail.com
I found a solution to the canvas clearRect bug. See https://medium.com/p/ffcb939af758


Nov 3, 2013
#49 denis.ra...@gmail.com
As I already mentioned in parallel issue - display:none hack is much slower than opacity one. Here is jsPerf for this to be more convincing http://jsperf.com/android-4-1-canvas-clearrect-fixes-comparsion
Nov 12, 2013
#50 anthonyl...@gmail.com
I had the same issue - canvas was being duplicated in upper left corner of screen on a 10" Samsung Galaxy Tab 2 (Android 4.2.2) and a Asus Memo Pad HD 7" (Android 4.2.2).  'overflow-x: visible' didn't work for me but putting the canvas inside a div and then setting 'position: absolute' on the canvas while positioning the div worked great!
Feb 4, 2014
#51 Adrian...@gmail.com
I had the same annoying issue and this solution worked fine for me even after orientation changes(e.g. portrait to landscape).

Solution: 
style="position:relative; overflow-y:scroll;"
(apply this to the parent/container)
Feb 5, 2014
#52 n3v3rf...@gmail.com
I had the same issue and setting overflow: visible fixed the problem. It seems to differ from device to device. I could easily replicate it on lower-end devices and the opposite on high-end.
Feb 10, 2014
#53 stepan...@gmail.com
Setting 'overflow-x: visible' to *all* parent divs works for me.
Feb 19, 2014
#54 rustyga...@googlemail.com
Literally none of these hacks have worked for me. The closest was putting the canvas in a container, setting it's position to relative, moving it off screen, then setting the canvas position to absolute and positioning that where desired. This works until you change orientation, then it comes back.

I literally cannot believe this has not been patched. It is a plain as day bug with the browser which is easily reproducible...
Feb 19, 2014
#55 denis.ra...@gmail.com
How about this one on every frame?

setTimeout(function() {
    $canvas.css('opacity', 1);
}, 0);
Feb 19, 2014
#56 rustyga...@googlemail.com
Just tried that, no luck either :(
Feb 19, 2014
#57 roumani....@gmail.com
Does this happen only when the page initially loads / or you resize the canvas ?

I find the solution is just (on android) to delay drawing to the canvas on initial load / resize - i.e. create a blank canvas of whatever dimension - set a timeout of X ms and then do your drawing.
Feb 19, 2014
#58 rustyga...@googlemail.com
Delaying the draw on load and on a screen orientation does strangely seem to fix it (just tested for a little while but I haven't seen it yet). Thanks for the advice!
Feb 19, 2014
#59 roumani....@gmail.com
Yep !  I agree this is extremely frustrating, I my self (in the past) tried all the other hacks / tricks suggested to no avail, only the delay mechanism I suggested seemed to work in all scenarios.

Depending on your application this shouldn't be too bad as resize / orientation changes are rare.
May 14, 2014
#61 zcq4...@gmail.com
THX for #47, the method u list resolved my problem, i'm free now!
Jun 23, 2014
#62 w4hns1...@googlemail.com
The only think that worked for me on Phone Gap is:
Setting in the Android Manifest:

android:hardwareAccelerated="false"

Aug 19, 2014
#64 dreamx...@gmail.com
kanishk's solution worked for me!

$("#canvas").parents("*").css("overflow", "visible");

Sep 21, 2014
Project Member #65 al...@android.com
WebView is now backed by Chromium. Please report all issues with Chromium to http://crbug.com/.
Status: Obsolete
Sign in to add a comment

Powered by Google Project Hosting