【问题标题】:While drawing on canvas, there is a 1/10 chance that scrolling causes page to lag在画布上绘图时,滚动有 1/10 的机会导致页面滞后
【发布时间】:2016-09-14 23:14:31
【问题描述】:

我发现有时当我使用滚轮时,我的画布会停止绘制。我试图禁用滚动,但问题仍然存在。

以下是延迟的示例:https://gyazo.com/8cc175a09ac3961ad59ebb46dca24d48

代码如下:

        var c = document.getElementById("myCanvas");
    var ctx = c.getContext("2d");
    c.width = getWidth();
    c.height = getHeight();

    var iconNames = ['android', 'github', 'google-plus', 'instagram', 'linkedin', 'pinterest', 'reddit', 'skype', 'snapchat', 'soundcloud', 'tumblr', 'twitter', 'vimeo', 'youtube'];
    var iconsDropped = 0, max = 7;
    var drops = [];

    for (var i = 0; i < iconNames.length; i++) {
        var image = new Image();
        image.src = "images/landing/" + iconNames[i] + ".png";
    }

    pickRandom();
    function pickRandom() {
        var wait = Math.floor(Math.random() * 2500);
        setTimeout(pickRandom, wait);

        if (iconNames.length < 1 || iconsDropped >= max) {
            return;
        }

        var img = new Image();
        var index = Math.floor(Math.random() * iconNames.length);
        var name = iconNames[index];
        iconNames.splice(index, 1);

        img.onload = function () {
            drops.push({
                image: img,
                width: Math.floor(Math.random() * getWidth()),
                height: -50,
                name: name,
                speed: Math.random() + .5,
                cycle: 0
            });

            iconsDropped++;
        };

        img.src = "images/landing/" + name + ".png";
    }

    function draw() {
        c.width = getWidth();
        c.height = getHeight() - c.offsetTop;
        clearCanvas();

        for (var i = 0; i < drops.length; i++) {
            var drop = drops[i];
            drop.height = drop.height + drop.speed;

            if (drop.height > getHeight() - c.offsetTop) {
                drop.cycle++;

                if (drop.cycle == 3) {
                    var name = drop.name;
                    drops.splice(i, 1);
                    iconNames.push(name);
                    iconsDropped--;
                    i--;
                    continue;
                } else {
                    drop.height = -50;
                    drop.width = Math.floor(Math.random() * getWidth());
                }
            }

            ctx.drawImage(drop.image, drop.width, drop.height, 50, 50);
        }

        console.log("ASD")
    }
    setInterval(draw, 2);

    function clearCanvas() {
        ctx.clearRect(0, 0, c.width, c.height);
        ctx.beginPath();
    }

【问题讨论】:

  • 你试过用requestAnimationFrame代替setInterval吗?
  • @MattWay 实际上似乎已经修复了它。非常感谢!
  • 刚刚添加了一个真实的答案,以防其他人发现这个问题有用。
  • 好的!非常感谢!

标签: javascript canvas


【解决方案1】:

在制作自定义动画时,您应该使用requestAnimationFrame 而不是setIntervalsetTimeout。这是为了让浏览器知道您正在尝试制作动画,并且能够在滚动、将窗口置于后台等方面迎合这一点。

根据文档:

您应该在准备好更新屏幕上的动画时调用此方法。这将要求在浏览器执行下一次重绘之前调用您的动画函数。回调次数通常为每秒 60 次,但通常会根据 W3C 的建议与大多数 Web 浏览器中的显示刷新率相匹配。在后台标签或隐藏s中运行时,回调率可能会降低到较低的频率,以提高性能和电池寿命。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-29
    • 1970-01-01
    • 2016-06-19
    • 2020-05-17
    • 2012-10-17
    • 1970-01-01
    相关资源
    最近更新 更多