【问题标题】:HTML Canvas animation wont run on mobile devicesHTML Canvas 动画无法在移动设备上运行
【发布时间】:2015-01-28 16:34:32
【问题描述】:

画布动画在网络浏览器上有效运行,但在使用 iPad 和 iPhone 在移动浏览器上进行测试时,动画永远不会启动。它只是简单地显示背景图像。没有给出错误消息。

动画基本上是一个图像,它从画布左侧的屏幕外移动,并在达到画布宽度的 75% 时停止。

这是代码

  <script>

  window.addEventListener("load", eventWindowLoaded, false);
        function eventWindowLoaded () {
        start();
    }

    function canvasSupport () {
        return Modernizr.canvas;
    }  

    var canvas = document.getElementById("canvas"); 
    var ctx=canvas.getContext("2d");    
    var cw=canvas.width;
    var ch=canvas.height;

    var image1 = new Image();
    image1.onload = function() {
        ctx.clearRect(0, 0, 600, 400);
        ctx.drawImage(image1, 0, 0);
    }
    image1.src="images/oven.jpg";   
    ctx.fillStyle = image1;

    var currentX=cw;
    var continueAnimating=true;
    var nextMoveTime,maxMoves;
    var expX = 50;
    var expY = 200;


    var image2 = new Image();
    image2.onload=start;
    image2.src="images/pies.png"; 

    var image = new Image();
    image.onload=start;
    image.src="images/pies.png"; 



    function start(){

      maxMoves=(cw+image.width)*0.5;

      nextMoveTime=performance.now();

      requestAnimationFrame(animate);




    function animate(currentTime){

      if(continueAnimating){ requestAnimationFrame(animate); }

      if(currentTime<nextMoveTime){return;}

      nextMoveTime=currentTime; // + delay;


      ctx.drawImage(image,currentX,193);

      if(--currentX<-image.width){ currentX=cw; }

      if(--maxMoves<0){continueAnimating=false;}
}
}

</script>

【问题讨论】:

  • performance.now 在 ipad/iphone 上不受支持。见这里:caniuse.com/#search=navigation
  • @GameAlchemist 感谢您告诉我,您知道有没有其他合适的替代方案?

标签: javascript html mobile canvas html5-canvas


【解决方案1】:

所以问题出在您对 performance.now 的使用上,它并不总是被实现,尤其是在精确计时器的功耗过高的移动设备上。
只需使用 requestAnimationFrame 提供的时间:在精确的浏览器/设备上,它将使用亚毫秒精度,否则只有毫秒精度。
(准确 = Chrome 桌面,... 其他 ???)

我将在下面让您看到我如何使用 rAF 的时间来构建当前的 'dt' = 自上一帧以来经过的时间,而 'applicationTime' = 应用程序中经过的时间(不是计算当你退出应用程序时)。

此方法的第二个好处是您可以轻松地将应用程序速度更改为“子弹时间”或加速(如果速度为

小提琴在这里:

http://jsfiddle.net/gamealchemist/KVDsc/

// current application time, in milliseconds.
var applicationTime = 0;    
// scale applied to time. 
// 1 means no scale, <1 is slower, >1 faster.
var timeSpeed = 1;

// after launchAnimation is called, 
//  draw/handleInput/update will get called on each rAF
function launchAnimation() {
    requestAnimationFrame(_launchAnimation);
}

// ------------- Private methods ----------------

function _launchAnimation(now) {
    _lastTime = now;
    applicationTime = 0
    requestAnimationFrame(_animate);
}

// ----------------------------------------------
// Animation.
//   Use launchAnimate() to start the animation.
//     draw, handleInput, update will be called every frame.
// ----------------------------------------------
function _animate(now) {
    requestAnimationFrame(_animate);
    // _______________________
    var dt = now - _lastTime;
    if (dt < 12) return; // 60 HZ max
    if (dt > 200) dt = 16; // consider 1 frame elapse on tab-out 
    _lastTime = now;
    dt *= timeSpeed;
    applicationTime += dt;
    // _______________________
    handleInput(); // ...
    // update everything with this frame time step.
    update(dt);
    // draw everything    
    draw();
}
var _lastTime = 0;

((请注意,要最优雅地处理制表符,您必须处理模糊事件,取消 rAF,然后再次将其设置为焦点。))

【讨论】:

  • 知道为什么在动画的“中间”更改画布的背景颜色会导致画布出现故障并似乎停止绘图或不删除帧吗?我可能不得不给你看一个视频,这样才有意义(尽管我已经通过不改变画布中间动画的背景颜色来修复它,并且没有时间制作视频并发布一个新问题)
【解决方案2】:
var now =
    ( typeof performance === 'object' && 'now' in performance )
    ? function() { return performance.now(); }
    : function() { return ( new Date ).getTime(); };

【讨论】:

  • var now = (performance && performance.now) ? performance.now.bind(performance) : Date.now ;好多了。
猜你喜欢
  • 2019-09-02
  • 1970-01-01
  • 2016-12-18
  • 1970-01-01
  • 2014-08-30
  • 2017-01-28
  • 2016-08-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多