6

我目前正在使用phonegap 开发一个android 应用程序。我有一个 html5 画布,我在上面绘制和动画对象。它在 android 2.3 上运行良好,但在 android 4+ 上它不会重绘画布。我尝试将 kinetic.js 和 easel.js/tween.js 用于我的动画,并且这两个库都出现了不清除画布的问题。我在画布上显示和隐藏 div 时取得了一些成功,但它并不总是有效。我只能假设这是一个 android 4+ 特定的错误或某种类型的功能,以增强 html5 画布性能。

有谁知道是否有一些我可以更改的设置或我可以在 android 4 或 javascript 中调用的方法,这将允许我在动画期间强制重绘我的 html5 画布?

还应该注意的是,动画似乎可以在 4.1 google api 模拟器中使用 easel.js/tween.js(画布清除和重绘),但不适用于运行 4.1.1 的手机。

我对正在发生的事情做了一些进一步的研究。从本质上讲,动画一开始的形状似乎留下了一个工件,而 clearRect 并没有清除它。我有一个大圆圈,我正在缩小到一个小圆圈。动画仍然发生,但大圆圈不受在画布上调用 clearRect 的影响。

4

3 回答 3

7

我也没有解决根本问题,但我想出了另一个不完美的解决方法,它不会给你的代码增加延迟。首先在画布上绘制一个虚拟对象。然后绘制您的动画对象(或可拖动对象。因为它也发生在拖动时)。似乎第一个绘制的对象是持久的(即无法正确清除)。使用 KineticJs,我执行以下操作... 1.) 创建舞台,2.) 绘制对象(如舞台大小的矩形作为背景。注意对象不能是透明的),3.)将图层添加到舞台,然后 4.) 运行 layer.draw()。

之后,我可以在画布上绘制任何东西,并且它在 Android 中表现正常。(见下面的例子。没有背景,对象在第一次拖动时被复制。要测试它,只需将背景的不透明度设置为 0)。

一个警告:根据我目前的经验,这发生在任何给定层中的第一个对象上。所以我必须调整舞台中的每一层。根据您的应用程序,它可能会或可能不会比在代码中添加时间延迟更好。

这似乎是从 Android 4.1.x 开始的 Android 错误它在 4.0.x 中不会出现。并且在本周发出的最近升级到 4.1.2 中也没有修复。类似的问题与 CSS 中的 overflow-x 属性的设置有关(参见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>
于 2012-10-13T17:48:51.143 回答
1
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);
    };
});

奇迹般有效

于 2012-11-27T16:55:10.267 回答
1

我今天在 Android 4.1.1 上遇到了同样的问题,只是我的问题更令人讨厌。我尝试了setTimeout其他答案中建议的“绘制虚拟对象”解决方法,但问题仍然存在。经过更多的尝试和错误,我发现如果我为前几帧绘制虚拟对象(前两帧对我来说已经足够了),之后可以成功清除画布。

另一个相关问题是,如果我在画布顶部显示一个弹出框,然后将其关闭,画布清除错误将再次发生。而这次为几帧绘制虚拟对象不再起作用,对我有用的是先调整画布大小,然后再为几帧绘制虚拟对象。

显然,这些都是丑陋的解决方法,但可能对遇到相同问题的其他人有用。

于 2012-10-30T16:55:36.327 回答