Android 4+ html5 canvas not redrawing

I am currently developing an Android application using phonegap. I have an html5 canvas on which I draw and animate objects. It works fine on Android 2.3, but on Android 4+ it does not redraw the canvas. I tried to use both kinetic.js and easel.js / tween.js for my animations, and the problem is to clear the canvas of both libraries. I experienced some success by showing and hiding the div over the canvas, but it doesn't work all the time. I can only assume that this is a special error of android 4+ or some type of function to increase the performance of the html5 canvas.

Does anyone know if there is some kind of setting that I can change, or a method that I can call in android 4 or javascript that will allow me to force redraw my html5 canvas during the animation?

It should also be noted that the animation seems to work with easel.js / tween.js in the google api 4.1 emulator (the canvas is cleared and redrawn), but not on phones running 4.1.1.

I did some research on what is happening. Essentially, it seems that the form at the very beginning of the animation leaves an artifact that clearRect does not clear. I have a big circle, which I squeeze to a small circle. Animation is still happening, but the big circle is not affected by calling clearRect on the canvas.

+6
source share
3 answers

I also do not have a fix for the root problem, but I came up with another incorrect workaround that does not add delay to your code. First draw a dummy object on the canvas. Then draw animation objects (or drag objects, as this also happens when dragging and dropping). It seems that the first object drawn is permanent (that is, it cannot be cleaned correctly). With KineticJs, I do the following ... 1.) create a scene, 2.) draw an object (for example, a rectangle the size of the scene as a background. Note that the object cannot be transparent), 3.) add a layer to the scene and 4. ) run layer.draw ().

After that, I can draw anything on the canvas, and it works fine on Android. (see example below). Without a background, the object is duplicated the first time you drag it. To test it, just set the background opacity to 0).

One caveat: in my experience, this happens to the first object in any given layer. Therefore, I have to adjust each level on the stage. Depending on your application, this may or may not be better than adding time delays to the code.

This seems to be an Android bug starting with Android 4.1.x. This does not happen in 4.0.x. And this has not been fixed in a recent update to 4.1.2 posted this week. Similar problems were associated with setting the overflow-x property in CSS (see http://code.google.com/p/android/issues/detail?can=2&start=0&num=100&q=&colspec=ID%20Type%20Status%20Owner % 20Summary% 20Stars & groupby = & sort = & id = 35474 ).

<script> window.onload = function() { var stage = new Kinetic.Stage({ container: "container", width: 578, height: 200 }); var boxLayer = new Kinetic.Layer(); stage.add(boxLayer); var background = new Kinetic.Rect({ x: rectX, y: rectY, width: 578, height: 200, fill: "white", stroke: "white", strokeWidth: 4, draggable: false }); boxLayer.add(background) boxLayer.draw(); var rectX = stage.getWidth() / 2 - 50; var rectY = stage.getHeight() / 2 - 25; var box = new Kinetic.Rect({ x: rectX, y: rectY, width: 100, height: 50, fill: "#00D2FF", stroke: "black", strokeWidth: 4, draggable: true, opacity: 1.0 }); boxLayer.add(box); boxLayer.draw(); }; </script> 
+7
source

Today I ran into the same issue on Android 4.1.1, only that my issue was even more disgusting. I tried the setTimeout and "draw dummy object" workarounds suggested in other answers, but the problem still persists. After several trial and error, I found that if I draw a dummy object for the first few frames (the first two frames were enough for me), the canvas can be successfully deleted after that.

Another related issue is that if I show a popover on top of the canvas and then release it, the canvas cleaning error will reoccur. And this time, drawing dummy objects for multiple frames no longer works, and what works for me is to resize the canvas first, and then draw the dummy objects into multiple frames.

Obviously, these are ugly workarounds, but may be useful to others who are experiencing the same problem.

+1
source
 function drawImage(imageObj) { var stage = new Kinetic.Stage({ container: "container", width: wW, height: wH }), timer = null, dummys = 1, layer = new Kinetic.Layer(); timer = setInterval( function() { if( dummys >= 2 ) { clearInterval(timer); layer.clear(); var darthVaderImg = new Kinetic.Image({ image: imageObj, x: stage.getWidth() / 2 - 200 / 2, y: stage.getHeight() / 2 - 137 / 2, draggable: true }); layer.add(darthVaderImg); stage.add(layer); }else{ var background = new Kinetic.Rect({ x: 0, y: 0, width: wW, height: wH, fill: "white", draggable: false }); layer.add(background) layer.draw(); dummys++; } }, 10 ); } var wH = window.innerHeight, wW = window.innerWidth, mCanvas = document.getElementById('container'), imageObj = new Image(); $(document).ready(function(){ mCanvas.style.width = wW; mCanvas.style.height = wH; imageObj.src = 'img/darth-vader.jpg'; imageObj.onload = function() { drawImage(this); }; }); 

works like a charm

+1
source

Source: https://habr.com/ru/post/927275/


All Articles