Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/87.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 为什么canvas2d上下文不再填充省略号?_Javascript_Html_Html5 Canvas - Fatal编程技术网

Javascript 为什么canvas2d上下文不再填充省略号?

Javascript 为什么canvas2d上下文不再填充省略号?,javascript,html,html5-canvas,Javascript,Html,Html5 Canvas,我正在开发一个模拟重力的javascript游戏。它使用HTML5画布元素为行星绘制二维椭圆。我用谷歌浏览器测试我的游戏。以下是游戏的链接: 直到5月24日,一切都很顺利。然而,在Chrome从26.0.1410.64升级到27.0.1453.94后,填充椭圆有时不会绘制。这并不是每次我加载游戏时都会发生,而且我从来没有在本地运行时让它中断 以下是游戏运行的屏幕截图: 这是一个屏幕截图,显示它没有填充省略号: 我不知道发生了什么事。我将包括绘制所有行星的环的部分。为了便于阅读,我修改了它

我正在开发一个模拟重力的javascript游戏。它使用HTML5画布元素为行星绘制二维椭圆。我用谷歌浏览器测试我的游戏。以下是游戏的链接:

直到5月24日,一切都很顺利。然而,在Chrome从26.0.1410.64升级到27.0.1453.94后,填充椭圆有时不会绘制。这并不是每次我加载游戏时都会发生,而且我从来没有在本地运行时让它中断

以下是游戏运行的屏幕截图:

这是一个屏幕截图,显示它没有填充省略号:

我不知道发生了什么事。我将包括绘制所有行星的环的部分。为了便于阅读,我修改了它

    var i = bodies.length;
    while(i--){
    var I = bodies[i];
    var planetRad = (I.width/2)*_scale;
    if(_showTrails){
        //draw the planet's trail
    }
    if(//the planet is completely off the screen){
        //draw a red planet on the edge of the screen
        ctx.beginPath();
        ctx.arc(nX, nY, 2.5, 0, TWOPI);
        ctx.fillStyle = offScreenColor;
        ctx.fill();
        ctx.strokeStyle = offScreenOutline;
        ctx.stroke();
    }
    else{
        //draw planet
        ctx.beginPath();
        ctx.arc(nX, nY, (I.width/2)*_scale, 0, TWOPI);
        ctx.closePath();
        ctx.fillStyle = I.bodyColor;
        ctx.fill();     
    }
    if(_showMotionVector){
        //draw a line from the center of a planet showing the direction and speed it's travelling
        ctx.strokeStyle = motionColor;
        ctx.beginPath();
        ctx.moveTo(I.getScX(), I.getScY());
        ctx.lineTo(I.motion.x * _scale * 12 + I.getScX(), I.motion.y * _scale * 12 + I.getScY());
        ctx.stroke();
    }
}

为什么有时会突然中断?

我查看了您的在线代码,发现您正在使用
setInterval
进行动画循环

这很可能是代码无法完成调用CALC等的原因。您可能会面临堆叠调用的风险-对于上下文,这意味着您可以拥有相互重置的路径

首先尝试将
setInterval
替换为
setTimeout
。当然,您需要从代码中重新触发它-更好的是,将所有内容放在一个函数中,该函数末尾有一个setTimeout,即:

function animate() {
    //... calcs and redraws which you have in setInterval
    setTimeout(animate, 0);
}
animate();
我使用0表示此测试的超时<代码>设置超时/设置间隔在任何情况下都不会与屏幕刷新率同步

如果这样行的话,你就知道原因了。下一步是将其替换为
requestAnimationFrame
,但请告诉我它是如何运行的

为了说明问题,我们可以看下面的插图:

每个块表示循环中的一个函数,一个循环是一种颜色。请记住,
setInterval
以固定的间隔调用,而
setTimeout
相对于调用时间调用。在本例中,函数在时间预算内执行,因此一切顺利

在下图中:

支出超出预算,因此会再次调用
setInterval
,并在第一个循环完成之前将下一个调用排入第二个循环的队列。当在两次调用之间处理队列时,您最终可能会面临两个函数“同时”处理上下文的风险(或者以不同于预期的顺序出现)

Javascript当然是单线程的,因此它们不会同时执行,但其中一个处于等待状态-如果在调用最后一个块之前调用下一个队列的第一个块,那么第一个块将修改上下文,甚至可能在调用前一个调用的最后一个调用之前更改路径。随着时间的推移,延迟将增加,并且随着堆叠的增加,延迟可能会变得越来越严重(除非一些额外的可用处理资源时不时地解析队列-在繁忙的系统上,这种情况不太可能发生)

也就是说,在这种情况下,您可以在
arc
填充之前使用
beginPath()
将行添加到上下文中

(希望有意义……)

使用
setTimeout
将阻止此操作,因为在动画循环中的所有调用返回之前,不会执行此操作。更好的选择是使用,因为这将在可能的情况下与屏幕刷新率同步调用。它更低级,因此也更高效


另一条路径(没有双关语)是用于进行计算。这将是多线程的,并且可以提高总体性能,因为web工作人员不会影响UI线程。

我在IE中遇到了类似的问题,所以这里是一个尝试。如果添加ctx.closePath(),它是否已修复;在示例代码中的第一个弧之后?这不起作用。每隔一段时间,我仍然能够让它加载,而行星不会显示。无法在Chrome或Canary(+其他浏览器)中复制(顺便说一句,FF平移对我不起作用)。如何触发动画循环?它在setInterval()函数中。(我知道FF中的平移问题。我还在努力解决这个问题。)我对setTimeout()的初始测试似乎有效。不过,在我确信之前,我必须在几台电脑上试用一下。我会告诉你结果的。到目前为止看起来不错。除了从setInterval切换到setTimeout之外,我还必须进行您在第一条评论中提到的更改。