Android的4 + HTML5的画布不会重绘画布、Android

2023-09-06 13:42:06 作者:悲歡自飲

我目前正在开发使用PhoneGap的Andr​​oid应用程序。我有一个HTML5的画布,我绘画和动画对象上。它的伟大工程在Android 2.3,但在Android 4+它不会重新绘制在画布上。我试图同时使用kinetic.js和easel.js / tween.js我的动画和不清除画布上发生了这两个库的问题。我经历了一些成功,显示和隐藏一个div在画布上,但它不工作,所有的时间。我只能假设这是一个机器人4+特定的错误或某种类型的功能,提升HTML5的Canvas性能。

I am currently developing an android application using phonegap. I have an html5 canvas that I am drawing and animating objects on. It works great on android 2.3, but on android 4+ it is not redrawing the canvas. I tried using both kinetic.js and easel.js/tween.js for my animations and the problem with not clearing the canvas occurred for both of these libraries. I experienced some success showing and hiding a div over the canvas but it does not work all the time. I can only assume that this is an android 4+ specific bug or some type of feature to enhance the html5 canvas performance.

有谁知道,如果有一些设置,我可以改变或方法,我可以在安卓4.0或javascript调用哪个可以让我在动画逼我HTML5画布的重绘?

Does anyone know if there is some setting I can change or method I can call in android 4 or javascript which would allow me to force the redraw of my html5 canvas during animations?

还应当指出的是,动画似乎与在4.1谷歌API模拟器easel.js / tween.js(画布清除,并重新绘制)工作,而不是在手机上运行4.1.1。

It should also be noted that the animations seem to work with easel.js/tween.js in the 4.1 google api emulator (the canvas clears and redraws), but not on phones running 4.1.1.

我已经做了一些进一步的研究发生了什么。本质上,它看起来在动画的最开始的形状留下的神器,它clearRect不明确。我有我缩小到一个小圈一大圈。动画仍然发生,但大圈不受在画布上调用clearRect。

I've done some further research into what is happening. Essentially it appears that the shape at the very beginning of an animation is leaving an artifact, which clearRect does not clear. I have a big circle that i am shrinking to a small circle. The animation still happens but the big circle is not affected by calling clearRect on the canvas.

推荐答案

我没有根问题的修复下去,但我已经想出了另一种不完美的解决办法,不延迟添加到您的$ C $℃。先画一个虚拟对象到画布。然后绘制动画对象(或拖动对象。因为它发生在阻力以及)。似乎绘制的第一个目的是持久的(即,不能正确地清除)。与KineticJs,我执行下列... 1.)创建阶段,2。)绘制的对象(如矩形的阶段作为背景的​​尺寸。另外,该对象可以是透明),3。)该层添加到舞台,和4)运行layer.draw()。

I don't have a fix for the root problem either, but I've come up with another imperfect workaround that doesn't add a delay to your code. Draw a a dummy object to the canvas first. Then draw your animation objects (or draggable objects. Since it happens on drag as well). It seems that the first object drawn is persistent (that is, can't be properly cleared). With KineticJs, I do the following... 1.) create the stage, 2.) draw an object (like a rectangle the size of the stage as a background. Note that the object can't be transparent), 3.) add the layer to the stage, and 4.) run layer.draw().

在我可以画任何东西到画布上,并可以正常工作的机器人。 (见下面的例子。如果没有对象dubplicated首次拖累的背景。为了测试它,只需将背景设置为0的不透明度)。

After that I can draw anything to the canvas and it behaves normally in Android. (see example below. Without the background the object is dubplicated on first drag. To test it, just set the opacity of the background to 0).

有一点要注意:根据我的经验,到目前为止,这是发生在第一个对象在任何给定的层。所以,我必须调整的阶段,每一层。根据你的应用程序可能会或可能不会比增加时间延迟至code更好。

One caution: In my experience so far, this is happening to the first object in any given layer. So I have to tweak each layer in the stage. Depending on your application it might or might not be better than adding timing delays to the code.

这似乎是一个Android的错误开始与Android 4.1.x的,它不会发生在4.0.x的而且它没有被固定在近期升级到4.1.2送出这个星期。类似的问题已经被拴在溢出-x属性的CSS中的设置(请参阅http://$c$c.google.com/p/android/issues/detail?can=2&start=0&num=100&q=&colspec=ID%20Type%20Status%20Owner%20Summary%20Stars&groupby=&sort=&id=35474).

This seems to be an Android bug starting with Android 4.1.x It does not occur in 4.0.x. And it has not been fixed in the recent upgrade to 4.1.2 sent out this week. Similar problems have been tied to the setting of 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>