在画布上绘图时,滚动导致页面滞后的概率为1/10

时间:2016-09-14 23:14:32

标签: javascript canvas

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

以下是滞后的示例: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();
    }

1 个答案:

答案 0 :(得分:4)

在制作自定义动画时,您应该使用requestAnimationFrame代替setIntervalsetTimeout。这样浏览器就知道你正在尝试制作动画,并且能够满足滚动,背景窗口等方面的需求。

根据文档:

  

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