Javascript 如何在addEventListener(';单击';)上以SetInterval对函数进行乘法;

Javascript 如何在addEventListener(';单击';)上以SetInterval对函数进行乘法;,javascript,Javascript,所以我编写了这段代码(在教程的帮助下),我想在任何地方单击都能产生效果 代码执行它必须执行的操作,但每次我再次单击并调用“drawParticle”函数时,过程都会加快,显示的粒子也会减少。 我认为这是因为我一次调用多个setInterval,而JavaScript是单线程的。但是我怎样才能修复它呢 var canvas, c, particles, particleIndex, particleNum, w, h;

所以我编写了这段代码(在教程的帮助下),我想在任何地方单击都能产生效果

代码执行它必须执行的操作,但每次我再次单击并调用“drawParticle”函数时,过程都会加快,显示的粒子也会减少。 我认为这是因为我一次调用多个setInterval,而JavaScript是单线程的。但是我怎样才能修复它呢

var   canvas,
      c,
      particles,
      particleIndex,
      particleNum,
      w,
      h;

window.onload =function(){

    canvas = document.createElement("canvas");
    c = canvas.getContext("2d");
    particles = {};
    particleIndex = 0;
    particleNum = 3;
    w = window.innerWidth;
    h = window.innerHeight;

    canvas.width = w;
    canvas.height = h;

    document.body.appendChild(canvas);

    c.fillStyle ="black";
    c.fillRect(0,0,canvas.width,canvas.height);

    canvas.addEventListener('click', drawParticle, false);
};

function drawParticle(e){

    function Particle(){
        this.x = e.clientX;
        this.y = e.clientY;
        this.vx = Math.random() * 10 - 5;
        this.vy = Math.random() * 10 - 5;
        this.gravity = 0.2;
        particleIndex++;
        particles[particleIndex] = this;
        this.id = particleIndex;
        this.life = 0;
        this.maxLife = Math.random() * 30 + 50;
        this.color = "rgb("+parseInt(Math.random()*255,10)+",0,0)";

      }

    Particle.prototype.draw = function(){

        this.x += this.vx;
        this.y += this.vy;

        if(Math.random() < 0.1 ){
           this.vx = Math.random() * 10 - 5;
           this.vy = Math.random() * 10 - 5;

        }


        //this.vy += this.gravity;
        this.life++;

        if(this.life >= this.maxLife){
         delete particles[this.id];
        }

        c.fillStyle = this.color;
        c.fillRect(this.x,this.y,10,10);
      };

    interval = setInterval(function(){
        //c.globalCompositeOperation ="source-over";
        c.fillStyle ="rgba(0,0,0,0.3)";
        c.fillRect(0,0,canvas.width,canvas.height);

        for (var i = 0; i < particleNum; i++){
         new Particle();
        }
        //c.globalCompositeOperation ="lighter";
        for (var i in particles){

           particles[i].draw();
        }
    },30);

};
var画布,
C
粒子,
particleIndex,
微粒,
W
H
window.onload=函数(){
canvas=document.createElement(“canvas”);
c=canvas.getContext(“2d”);
粒子={};
particleIndex=0;
颗粒数=3;
w=窗宽;
h=窗内高度;
画布宽度=w;
canvas.height=h;
document.body.appendChild(画布);
c、 fillStyle=“黑色”;
c、 fillRect(0,0,canvas.width,canvas.height);
canvas.addEventListener('click',drawParticle,false);
};
功能粒子(e){
函数粒子(){
this.x=e.clientX;
this.y=e.clientY;
this.vx=Math.random()*10-5;
this.vy=Math.random()*10-5;
这是重力=0.2;
particleIndex++;
粒子[particleIndex]=这个;
this.id=particleIndex;
这就是生命=0;
this.maxLife=Math.random()*30+50;
this.color=“rgb(“+parseInt(Math.random()*255,10)+”,0,0)”;
}
Particle.prototype.draw=函数(){
this.x+=this.vx;
this.y+=this.vy;
if(Math.random()<0.1){
this.vx=Math.random()*10-5;
this.vy=Math.random()*10-5;
}
//this.vy+=this.gravity;
这就是生活;
如果(this.life>=this.maxLife){
删除粒子[this.id];
}
c、 fillStyle=this.color;
c、 fillRect(this.x,this.y,10,10);
};
间隔=设置间隔(函数(){
//c、 globalCompositeOperation=“源代码结束”;
c、 fillStyle=“rgba(0,0,0,0.3)”;
c、 fillRect(0,0,canvas.width,canvas.height);
对于(var i=0;i
我认为你关于间隔的说法是正确的。我不确定这是否是你想要的反应,但如果你在重画之前清除了间隔,事情就不会加快。尝试以下方法:

var interval = null;
function drawParticle(e){

  if (interval) { 
    clearInterval(interval)
  }

  function Particle(){
    ...
这里有一个密码笔

更新:

我已将代码笔更改为包含下面包含的新代码。主要更改是创建一个
粒子
对象,该对象将保存每次单击所绘制的粒子集。通过移动这组粒子及其
particleIndex
似乎解决了这个问题。我怀疑将每个元素添加到全局
粒子
列表中会有些奇怪。现在,
Particles
实例只管理与该组关联的粒子

我还取出了
particleId
,因为它似乎没有必要,不过如果它对代码之外的其他内容有用的话,您可能需要把它放回去

以下是我的更新代码:

var   canvas,
c,
particleNum,
w,
h;

window.onload =function(){

  canvas = document.createElement("canvas");
  c = canvas.getContext("2d");
  particleNum = 3;
  w = window.innerWidth;
  h = window.innerHeight;

  canvas.width = w;
  canvas.height = h;

  document.body.appendChild(canvas);

  c.fillStyle ="black";
  c.fillRect(0,0,canvas.width,canvas.height);

  canvas.addEventListener('click', drawParticles, false);
};

function Particles() {
  this.particles = {};
  this.particleIndex = 0;
}

Particles.prototype.addParticle = function(particle) {
  this.particles[++this.particleIndex] = particle;
}

Particles.prototype.killDeadParticles = function() {
  for (var i in this.particles) {
    var particle = this.particles[i];
    if (particle.isDead()) {
      delete this.particles[i]
    }
  }
}

Particles.prototype.draw = function() {
  // draw particles
  for (var i in this.particles){
    this.particles[i].draw();
  }
  this.killDeadParticles();
}


function Particle(e){
  this.x = e.clientX;
  this.y = e.clientY;
  this.vx = Math.random() * 10 - 5;
  this.vy = Math.random() * 10 - 5;
  this.gravity = 0.2;
  this.life = 0;
  this.maxLife = Math.random() * 30 + 50;
  this.color = "rgb("+parseInt(Math.random()*255,10)+",0,0)";
  // console.log('new particle', particleIndex);
}

Particle.prototype.isDead = function() {
  return (this.life >= this.maxLife);
}

Particle.prototype.draw = function(){

  this.x += this.vx;
  this.y += this.vy;

  if(Math.random() < 0.1 ){
    this.vx = Math.random() * 10 - 5;
    this.vy = Math.random() * 10 - 5;

  }

  //this.vy += this.gravity;
  this.life++;

  c.fillStyle = this.color;
  c.fillRect(this.x,this.y,10,10);
};

function drawParticles(e){

  var particles = new Particles(e);

  setInterval(function(){
    //c.globalCompositeOperation ="source-over";
    c.fillStyle ="rgba(0,0,0,0.3)";
    c.fillRect(0,0,canvas.width,canvas.height);

    for (var i = 0; i < particleNum; i++){
      var particle = new Particle(e);
      particles.addParticle(particle);
    }
    //c.globalCompositeOperation ="lighter";
    particles.draw();
  },30);

};
var画布,
C
微粒,
W
H
window.onload=函数(){
canvas=document.createElement(“canvas”);
c=canvas.getContext(“2d”);
颗粒数=3;
w=窗宽;
h=窗内高度;
画布宽度=w;
canvas.height=h;
document.body.appendChild(画布);
c、 fillStyle=“黑色”;
c、 fillRect(0,0,canvas.width,canvas.height);
canvas.addEventListener('click',drawParticles,false);
};
函数粒子(){
this.particles={};
此.particleIndex=0;
}
Particles.prototype.addParticle=函数(粒子){
this.particles[++this.particleIndex]=粒子;
}
Particles.prototype.killDeadParticles=函数(){
for(此.particles中的变量i){
var particle=this.particles[i];
if(particle.isDead()){
删除此项。粒子[i]
}
}
}
Particles.prototype.draw=函数(){
//画粒子
for(此.particles中的变量i){
this.particles[i].draw();
}
这个。killDeadParticles();
}
函数粒子(e){
this.x=e.clientX;
this.y=e.clientY;
this.vx=Math.random()*10-5;
this.vy=Math.random()*10-5;
这是重力=0.2;
这就是生命=0;
this.maxLife=Math.random()*30+50;
this.color=“rgb(“+parseInt(Math.random()*255,10)+”,0,0)”;
//console.log(“新粒子”,particleIndex);
}
Particle.prototype.isDead=函数(){
return(this.life>=this.maxLife);
}
Particle.prototype.draw=函数(){
this.x+=this.vx;
this.y+=this.vy;
if(Math.random()<0.1){
this.vx=Math.random()*10-5;
this.vy=Math.random()*10-5;
}
//this.vy+=this.gravity;
这就是生活;
c、 fillStyle=this.color;
c、 fillRect(this.x,this.y,10,10);
};
功能粒子(e){
var粒子=新粒子(e);
setInterval(函数(){
//c、 globalCompositeOperation=“源代码结束”;
c、 fillStyle=“rgba(0,0,0,0.3)”;
c、 fillRect(0,0,canvas.width,canvas.height);
对于(var i=0;i
这是朝着正确方向迈出的一步,但是否有可能在每次单击时都保持间隔?让粒子继续被吸引?我再试一次。因此,您希望它按照初始代码的工作方式运行,只是它不会随着每次单击而加速,对吗?