【问题标题】:canvas is loading correctly on page reload only画布仅在页面重新加载时正确加载
【发布时间】:2018-09-19 18:17:38
【问题描述】:

我在画布中创建了涟漪效果,
为此,我使用了四个圆圈,它们在一定间隔后一个一个地绘制,并且它们的半径在每个循环中都会增加,
就像第一波然后是第二波然后是第三波和最后的第四波。

但问题是它没有像第一次那样被加载,直到我刷新/重新加载我的页面,它才显示为我需要的

附上截图

这是我的代码

 <canvas id="myCanvas" ></canvas>


var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
 var ww =   window.innerWidth; 
 var wh = window.innerHeight;
canvas.width = ww * 0.98;
canvas.height = wh * 0.98;
var CW = canvas.width;
var CH = canvas.height;


var radiusFirstWave = 20
var radiusSecondWave = 20
var radiusThirdWave = 20
var radiusFourthWave = 20

function FirstWave() {
//opacity = 1;

   ctx.clearRect(0, 0, CW, CH);
    ctx.beginPath();
    ctx.arc(0,0, radiusFirstWave, 0, 2 * Math.PI);


     ctx.lineWidth = 2;

       ctx.strokeStyle = "rgb(00,00,ff)" ;

    ctx.stroke();

    radiusFirstWave += (CW*speed)/3000;

    if (radiusFirstWave >(ww*FinalRadius)/100)
    {radiusFirstWave =  InitialRadius*ww/100;}


    requestAnimationFrame(function() {
        FirstWave();
    });
} 



FirstWave();    

 setTimeout(function SecondWave() {
// some code

    rAF = requestAnimationFrame(function() {
        SecondWave();
    });
    },  500);

 setTimeout(function ThirdWave() {
 //some code
    rAF = requestAnimationFrame(function() {
        ThirdWave();
    });
    }, 1000);

 setTimeout(function FourthWave() {
 //some code 

    rAF = requestAnimationFrame(function() {
        FourthWave();
    });
    }, 1500);

这是我第一次在浏览器中打开它时的输出,而不是出现在500 millisecond 之后它们被加载一次

但是当我刷新它显示的页面时,这正是我编写它的目的

圆圈之间的缝隙清晰可见

你有什么建议? 当我第一次在浏览器中绘制这些圆圈时,是否像画布没有完全加载?
重新加载页面后第二次从缓存中获取它? 任何形式的帮助将不胜感激

【问题讨论】:

  • 你能把你的代码简化为一个最小可验证的例子吗?最好还粘贴整个 HTML 文件(减少到可以复制的最低限度)。您可能在准备好之前使用canvas 元素。尝试在 Firefox 中打开页面并使用开发者控制台查看浏览器给您的任何错误。
  • @amn 我已经减少了我的代码,开发者控制台也没有错误。

标签: javascript html canvas html5-canvas


【解决方案1】:

不要像那样同时运行多个 requestAnimationFrame 循环。

您的调用将堆积到下一次屏幕刷新之前,因此这可能会起作用,并且不会产生太多的性能开销...但是在您的实现中您无法确定顺序它们被堆叠起来了,因为你是通过随机触发 setTimeout 来调用它们的。

我的意思是随机的,因为关于屏幕刷新顺序和 requestAnimationFrame 回调调用,它是随机的。已经运行的循环的下一次调用只会在下一次屏幕刷新之前被堆叠。你的超时很有可能在 => 它会首先被堆叠。

所以你很可能最终会调用 [FourthWave, ThirdWave, SecondWave, FirstWave]顺序,并且前三个调用都将被 FirstWave 中的clearRect 清除。

因此,与其运行这 4 个动画循环,最简单的方法是使用标志和单个动画循环:

var flags = [1,0,0,0];
function anim() {
  if(flags[0]) FirstWave();
  if(flags[1]) SecondWave();
  if(flags[2]) ThirdWave();
  if(flags[3]) FourthWave();
  requestAnimationFrame(anim);
}
setTimeout(function() {
  flags[1] = 1;
}, 500);
...

【讨论】:

  • flags[1] = 1 做什么?表示它将如何调用anim()
  • 它升起了我们的标志,因此在anim 的下一次迭代中,它将调用SecondWaveif(flags[1]) 将是真实的。)
  • 它的行为与我之前的输出相同
猜你喜欢
  • 1970-01-01
  • 2012-10-31
  • 1970-01-01
  • 2017-08-27
  • 2023-03-27
  • 2014-01-08
  • 2019-05-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多