javascript - 使用 setTimeout 在 Canvas 中设置动画时出现问题

标签 javascript html animation canvas settimeout

我正在尝试为重复出现的垂直行圆圈设置动画,一次一行。每行圆圈从浏览器底部开始一直到顶部。但我在使用 setTimeout 来保持它一次只出现一行新的圆圈时遇到了麻烦。我当前的代码有重复出现的圆圈线,但它每次都会添加一条额外的圆圈线,并且每次也会加快动画速度。如何避免加速和添加额外的圆行?

这是fiddle

var newLine = function(){
        var posX = Math.random() * canvas.width;
            posY = canvas.height;

        setInterval(function() {
            posY -= 40;

            c.fillStyle = "rgba(23, 23, 23, 0.05)";
            c.fillRect(0, 0, canvas.width, canvas.height);

            c.fillStyle = "white";
            c.beginPath();
            c.arc(posX, posY, Math.random() * 20, 0, twoPi, false);
            c.fill();

        }, 30);
        setTimeout(newLine, 2000);
    };  
    newLine();

最佳答案

问题是,每次调用 newLine() 时,它都会创建一个新的间隔计时器。因此,在多次调用该函数后,您会同时运行多个间隔计时器。

修复方法只是在开始新的间隔计时器之前清除间隔计时器:

    var timer;

    var newLine = function(){
        clearInterval( timer );
        var posX = Math.random() * canvas.width;
            posY = canvas.height;

        timer = setInterval(function() {
            posY -= 40;

            c.fillStyle = "rgba(23, 23, 23, 0.05)";
            c.fillRect(0, 0, canvas.width, canvas.height);

            c.fillStyle = "white";
            c.beginPath();
            c.arc(posX, posY, Math.random() * 20, 0, twoPi, false);
            c.fill();

        }, 30);
        setTimeout(newLine, 2000);
    };  
    newLine();

Updated fiddle

关于评论中的问题...您遇到的一个问题是一个非常微妙的 JavaScript 陷阱。在进行一些调试之前我也没有注意到它。

仔细看看这些行:

        var posX = Math.random() * canvas.width;
            posY = canvas.height;

现在问自己这些问题:posX 是局部变量吗? posY 是局部变量吗?您确定它们都是局部变量吗?

如果您在测试中看到一些结果,其中两个或多个线条动画同步向上移动,这将解释原因。

你问题的另一部分很简单。请忽略我之前关于将 timer 变量移到 newLine() 函数之外的建议,这样您就可以取消它!相反,将 timer 设为 newLine() 内的本地变量,并让 newLine() 的每个实例取消其完成后有自己的计时器。

完成此操作后,其余代码就可以正常工作:

    var newLine = function(){
        var posX = Math.random() * canvas.width;
        var posY = canvas.height;

        var timer = setInterval(function() {
            posY -= 10;
            if( posY <= 0 ) {
                clearInterval( timer );
                return;
            }

            c.fillStyle = "rgba(23, 23, 23, 0.05)";
            c.fillRect(0, 0, canvas.width, canvas.height);

            c.fillStyle = "white";
            c.beginPath();
            c.arc(posX, posY, Math.random() * 5, 0, twoPi, false);
            c.fill();

        }, 30);

        setTimeout( newLine, Math.random() * 2000 );
    };

    newLine();

New fiddle

关于javascript - 使用 setTimeout 在 Canvas 中设置动画时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27198999/

相关文章:

javascript - 我可以防止两个宽度为 50% 的 div 以奇数宽度下降吗?

ios - 当嵌入 View 尺寸改变时,如何用动画改变容器 View 尺寸?

javascript - 如何从 jquery 中的警报弹出窗口重定向到新页面?

javascript - 如何使todolist在使用本地存储重新加载后保留

javascript - Google Cal API 返回不完整的事件资源

javascript - 李:odd li:even not working

html - CSS 不随变化更新

ios - 使用 Swift 从底部向上推 View Controller

animation - SpriteKit : run code or block when action removed?

javascript - html5视频将黑框(空)绘制到 Canvas 上