【问题标题】:Canvas animation doesnt work fluently. What can i do?画布动画不能流畅地工作。我能做些什么?
【发布时间】:2014-01-02 23:36:48
【问题描述】:

由于我添加了o: Math.random()*(1 - 0.1) + 0.1 //opacity 用于随机不透明度值,因此动画无法流畅运行。我能做些什么来防止这种情况发生?如何使我的脚本更有效地提高性能?

window.onload = function () {
    var canvas = document.getElementById('canvas');
    var ctx = canvas.getContext('2d');
    var W = canvas.width = window.innerWidth;
    var H = 550;
    var mp = 45; //max particles
    var particles = [];
    //var rotate = 180;

    reqAnimFrame = window.requestAnimationFrame ||
                   window.mozRequestAnimationFrame    ||
                   window.webkitRequestAnimationFrame ||
                   window.msRequestAnimationFrame     ||
                   window.oRequestAnimationFrame;

    for ( var i = 0; i < mp; i++ )
        {
            particles.push({
                x: Math.floor(Math.random()*W), //x-coordinate
                y: Math.floor(Math.random()*H), //y-coordinate
                d: Math.floor(Math.random()*(12 - 1) + 1), //density
                r: Math.floor(Math.random()*(70 - 10) + 10), //radius
                o: Math.random()*(1 - 0.1) + 0.1 //opacity
            })
        }



    function animate() {
        reqAnimFrame(animate);
        for ( var i = 0; i < mp; i++ )
            {
                var p = particles[i];
                p.x += p.d;


                if(p.x >= W + p.r){
                    p.x = -300;
                    p.y = Math.floor(Math.random()*H);
                }
                draw();
            }
    }

    function draw() {
        ctx.clearRect(0, 0, W, H);
        for ( var i = 0; i < mp; i++ )
            {
                var p = particles[i];
                ctx.fillStyle = "rgba(51,51,51," + p.o + ")";
                ctx.beginPath();
                ctx.arc(p.x, p.y, p.r, 0, Math.PI * 2, false);
                ctx.fill();
                //ctx.moveTo(p.x,p.y);
                //ctx.lineTo(p.x + 150, p.y + (-180));
                //ctx.lineTo(p.x + 300, p.y);
            }    
    }
    animate();
    };//onload function

【问题讨论】:

    标签: javascript html animation canvas


    【解决方案1】:

    我制作了 jsfiddles onetwo

    first fiddle 中没有closePath 函数调用,在second fiddle 它调用。

    first fiddle devtools 时间轴中显示每秒 7 MB 的额外内存使用量(在您的情况下调用 CG 1 秒后,恕我直言):从 10 MB 到 17 MB

    second fiddle 时间轴中显示从beginPathclosePath 函数(接近130 毫秒)的额外内存使用2 MB:从10 MB 到12 MB。但在这种情况下,CG 不会调用。

    我认为最好添加closePath函数,以防止GC调用。并且对旧浏览器使用较少数量的粒子,因为对我来说(MacBook Pro、Chrome)一切正常,fps 为 60(最大值)。

    【讨论】:

    • 有趣。我真的很惊讶。我认为 beginPath 意味着你正在关闭以前的路径......似乎我错了!
    • 关于beginPath:它只启动子路径。每个新的 beginPath 只会再创建一个子路径。但是closePath将当前子路径添加到主路径并关闭子路径,即释放一些内存。
    • added globalAlpha 喜欢 GameAlchemist 回答...而且内存额外使用量为 0.1MB :)
    【解决方案2】:

    您在更新循环中为每个粒子调用一次 draw,这会导致 mp*mp 成本而不是 mp 成本。
    首先要做的是每个粒子只调用一次draw,所以不要在更新循环中调用它,而是在更新结束时调用一次。

    请注意,您可以通过更改上下文的 globalAlpha 而不是创建新颜色来获得一些性能。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-04-07
      • 2014-08-07
      • 1970-01-01
      • 1970-01-01
      • 2019-07-23
      • 2014-10-30
      • 2010-11-07
      • 2017-07-01
      相关资源
      最近更新 更多