Canvas 没有画布填充,HTML5画布蒸汽效果无法正确显示

Canvas 没有画布填充,HTML5画布蒸汽效果无法正确显示,canvas,html5-canvas,Canvas,Html5 Canvas,我希望我的画布蒸汽效果覆盖我的页面内容的其余部分,但如果我不给画布一个填充,它会以后期的方式显示蒸汽 如预期,Un注释行24和25将填充画布和steam显示 c.fillStyle = '#000'; c.fillRect(0,0,w,h); 下面的代码片段的完整演示 var canvas=document.createElement('canvas'); var w=canvas.width=800; var h=canvas.height=700; var c=canvas.getCon

我希望我的画布蒸汽效果覆盖我的页面内容的其余部分,但如果我不给画布一个填充,它会以后期的方式显示蒸汽

如预期,Un注释行24和25将填充画布和steam显示

c.fillStyle = '#000';
c.fillRect(0,0,w,h);
下面的代码片段的完整演示

var canvas=document.createElement('canvas');
var w=canvas.width=800;
var h=canvas.height=700;
var c=canvas.getContext('2d');
var img=新图像();
img.src=”http://wightfield.com/_temp/smoke_600-60.png";
变量位置={x:450,y:410};
var-mugPosition={x:w/3,y:500};
document.body.appendChild(画布);
var粒子=[];
var随机=函数(最小值、最大值){
返回Math.random()*(max-min)*min;
};
var draw=function(){
位置x;
位置y;
var p=新粒子(位置x,位置y);
粒子推(p);
而(particles.length>500)particles.shift();
//c、 fillStyle='#000';
//c、 fillRect(0,0,w,h);
对于(var i=0;i
正文{
背景:绿色;
}
帆布{
边框:1px点黑色;
}
使用
ctx.clearRect(0,0,w,h)
获得所需的透明背景

我也做了一些改变

如果每帧创建一个新粒子,随着时间的推移,这将导致大量GC。重置现有粒子更好,因此我为粒子添加了重置功能,添加新粒子,然后通过计数器重置它们

您设置转换效率低下,因此我添加了一种直接设置转换的更快方法。现在,您不必为每个粒子保存和恢复画布状态,这在许多机器/设备上可能会很慢

我还检查了一个alpha值,该值太低,无法显示任何内容,无法绘制图像,从而节省了一点时间

不要使用
setInterval
,它只是一个bug,没有理由等待一台速度慢的机器成为一种痛苦。我已经添加了
requestAnimationFrame
,这将提供一个非常平滑的60Fps同步到屏幕刷新和浏览器渲染

更新

刚刚意识到粒子的数量可以减少,以适应粒子α低于阈值
c=1/255(c表示截止)所需的帧数

你总是在代码<α=0.4 < /代码>开始,衰变率<代码> d=0.9 < /代码>如果你把每个帧步看作时间<代码> t>代码>,它可以表示为<代码> CTX.Alpha=a*Maq.PoW(d,t)< /c> < /p> 因此,如果我们想要帧数,直到alpha值低于
c
,我们需要为t求解
alpha=a*Math.pow(d,t)-c
,即
t=Math.log(c/a)/Math.log(d)

衰减的结果是44,因此浪费了456个数组条目

更新#2

我已经更新了答案,包括我之前错过的图像加载。您可以在下面的脚本中找到所有详细信息,因为我已经对我添加和更改的所有内容进行了注释

“严格使用”//这是一个javascript指令,必须位于
//脚本(如果包括但不是要求)。
//它迫使更多的代码在更严格的规则下运行。优势
//很多,包括使代码运行更快。
var imageLoadCount=0;//统计图像加载的次数,加载时倒计时
var readyToAnimate=false;//指示资源可用的标志
//图像数组中的图像索引,以在动画中获得正确的图像。
常数粒子图像指数=0;
常量背景图像索引=1;
var images=[];//一组图像
//下面是一个自激活功能,它将把加载的内容与
//脚本的其余部分,因为它在开始时只需要一次,所以保留对它的引用毫无意义
//自调用函数是
//(函数(){…代码体})()
//末尾的()强制javascript运行前面()中的内容。
(函数(){
函数imageLoaded(){//image onload函数“this”是对图像的引用
imageLoadCount-=1;//对加载的图像进行计数
//如果计数为零,则已加载所有图像
如果(imageLoadCount==0){
readyToAnimate=true;
}
}
//需要加载的图像URL的列表。
常量imageURLs=[
"http://wightfield.com/_temp/smoke_600-60.png",
"http://wightfield.com/_temp/smoke_600-60.png“,//重复图像,如示例所示
];
forEach(函数(url){//对于每个图像url,启动加载过程
var img=新图像();
img.src=url;
img.onload=imageLoaded;//设置图像onload函数
imageLoadCount+=1;//计算加载的图像数
图像推送(img);
});
})();  // 运行函数
var canvas=document.createElement('canvas');
var w=canvas.width=800;
var h=canvas.height=700;
var c=canvas.getContext('2d');
document.body.appendChild(画布);
变量位置={
x:450,
y:410
};
变量位置={
x:w/3,
y:500
};
var粒子=[];
var随机=函数(最小值、最大值){
//你有Math.random()*(max-min)*min;我有屁股