Javascript JS画布动画,我的效果正在加速和积累,但效果的速度在控制台中是一样的吗?

Javascript JS画布动画,我的效果正在加速和积累,但效果的速度在控制台中是一样的吗?,javascript,html,canvas,html5-canvas,Javascript,Html,Canvas,Html5 Canvas,我试着用焰火创造一个画布效果,但是你点击的越多,它得到的速度就越快,而且它似乎在自己身上积累。当我列出速度时,它是相似的,与那里发生的情况不一致。我还试图取消画,如果它离开了画布,但它没有帮助。 这里是链接 var fireAr=[]; var-expAr=[]; 功能烟花(x,y,maxY,maxX,cn,s,w,en){ 这个.x=x; 这个。y=y; this.maxY=maxY; this.maxX=maxX; this.cn=cn; 这个.s=s; 这个.w=w; this.en=en

我试着用焰火创造一个画布效果,但是你点击的越多,它得到的速度就越快,而且它似乎在自己身上积累。当我列出速度时,它是相似的,与那里发生的情况不一致。我还试图取消画,如果它离开了画布,但它没有帮助。 这里是链接

var fireAr=[];
var-expAr=[];
功能烟花(x,y,maxY,maxX,cn,s,w,en){
这个.x=x;
这个。y=y;
this.maxY=maxY;
this.maxX=maxX;
this.cn=cn;
这个.s=s;
这个.w=w;
this.en=en;
这个。i=0;
this.explosion=函数(){
对于(;this.i

在我看来,我删除了一些不必要的部分,但如果我错了,并且遗漏了一些内容,我将尝试修复它

以下是一些可以提高性能的简单方法:

  • 注释掉阴影模糊可以显著提高效果。如果需要阴影,请参见哪个演示了预渲染
  • 尝试使用and
    ctx.rotate()
    而不是绘制路径。保存/旋转/恢复画布可能是禁止的,因此可以使用非旋转矩形
  • 考虑使用更小的画布,它比可能填满整个窗口的画布重新绘制更快
另一个问题更为微妙:
Firework
s和
Exp
s正在被创建(制作对象很昂贵!)并被推到阵列上。但是这些数组永远不会被修剪,对象在离开可见画布后也永远不会被重用。最终,渲染循环因更新和渲染
fireAr
expAr
数组中的每个对象的所有计算而陷入困境

一个简单的解决方案是检查是否有对象退出画布,以及是否有对象从
expAr
中退出。以下是伪代码:

for (let i = expAr.length - 1; i >= 0; i--) {
  if (!inBounds(expAr[i], canvas)) {
    expAr.splice(i, 1);
  }
}
function inBounds(obj, canvas) {
  return obj.x >= 0 && obj.x <= canvas.width &&
         obj.y >= 0 && obj.y <= canvas.height;
}
向后迭代,因为这会改变数组的长度
inBounds
是一个函数,用于检查
Exp
对象的
x
y
属性及其大小和画布宽度和高度,以确定其是否已通过边缘。更多伪代码:

for (let i = expAr.length - 1; i >= 0; i--) {
  if (!inBounds(expAr[i], canvas)) {
    expAr.splice(i, 1);
  }
}
function inBounds(obj, canvas) {
  return obj.x >= 0 && obj.x <= canvas.width &&
         obj.y >= 0 && obj.y <= canvas.height;
}
这些名字对外部读者来说几乎没有意义,如果你花几个月的时间阅读代码,它们对你来说也不太可能有什么意义。使用完整的单词,如“大小”、“宽度”等

另一个侧重点是,调整窗口大小是一个好主意

下面是一个概念的快速证明,它演示了
shadowBlur
和修剪死元素的影响

const rnd=n=>~~(Math.random()*n);
const mouse={pressed:false,x:0,y:0};
让烟花=[];
让shouldSplice=false;
const canvas=document.createElement(“canvas”);
const ctx=canvas.getContext(“2d”);
document.body.appendChild(画布);
document.body.style.margin=0;
canvas.style.background=“#111”;
canvas.width=document.body.scrollWidth;
canvas.height=document.body.clientHeight;
ctx.shadowBlur=0;
const fireworksAmt=document.querySelector(“#fireworksAmt”);
document.querySelector(“输入[type=range]”)。addEventListener(“更改”,e=>{
ctx.shadowBlur=e.target.value;
document.querySelector(“#shadow amt”).textContent=ctx.shadowBlur;
});
document.querySelector(“输入[type=checkbox]”)。addEventListener(“更改”,e=>{
shouldplice=!shouldplice;
});
常量createFireworks=(x,y)=>{
const color=`hsl(${rnd(360)},100%,60%)`;
返回数组(rnd(20)+1).fill().map(=>({
x:x,
y:y,
vx:Math.random()*6-3,
vy:Math.random()*6-3,
尺寸:rnd(4)+2,
颜色:颜色
}));
}
(函数render(){
如果(鼠标按下){
推(…创建焰火(mouse.x,mouse.y));
}
clearRect(0,0,canvas.width,canvas.height);
用于(烟花的常数){
e、 x+=e.vx;
e、 y+=e.vy;
e、 vy+=0.03;
ctx.beginPath();
ctx.fillStyle=ctx.shadowColor=e.color;
ctx.arc(e.x,e.y,e.size,0,Math.PI*2);
ctx.fill();
如果(应拼接){
e、 尺寸-=0.03;