首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JS clearRect未清除整个画布

问JS clearRect未清除整个画布
EN

Stack Overflow用户
提问于 2020-06-08 00:45:47
回答 1查看 54关注 0票数 0

我是js的新手,遇到了一个问题。我正在尝试创建一个星空中的动画。我这样做是通过在画布上随机创建小圆圈,然后随机选择闪烁的星星(不透明度改变)。然后我意识到网站在缩放时不工作,所以我决定实现一个onevent来调整窗口大小,当窗口调整大小时,我再次运行相同的函数来重新创建相同的过程,但同时清除所有以前的星号,这样它们就不会成倍增加。这里的问题是,clearRect方法似乎没有为我清除之前绘制的星星。在这方面的任何帮助都将非常感谢:)。这是我的代码。

代码语言:javascript
复制
let starCollection  = [];
let randomStars     = [];
let numberofStars   = 100;
let flickeringStars = 50;

class Star{
    constructor(x,y,color,radius){
        this._canvas        = document.querySelector('canvas');
        this._canvas.width  = window.innerWidth;
        this._canvas.height = window.innerHeight; 
        this._c             = this._canvas.getContext('2d');
        this._radius        = radius;

        this._x       = x;
        this._y       = y;
        this._color   = color;     
    }

    //drawing individual stars
    draw(){
        //Drawing
        this._c.beginPath();
        this._c.arc(this._x,this._y,this._radius,0,Math.PI * 2,false);
        this._c.fillStyle   = this._color;
        this._c.strokeStyle = 'black';
        this._c.stroke();
        this._c.fill();
        this._c.closePath();
    }
    //Fade in and out for stars
    flicker(){

        setTimeout(()=>{this._color='#EBEBEB';},300);
        setTimeout(()=>{this._color='#D9D9D9';},600);
        setTimeout(()=>{this._color='#B6B6B6';},900);
        setTimeout(()=>{this._color='#898787';},1200);
        setTimeout(()=>{this._color='#4F4F4F';},1500);

        setTimeout(()=>{this._color='black';},1800);
        setTimeout(()=>{this._color='#4F4F4F';},2100);
        setTimeout(()=>{this._color='#898787';},2400);
        setTimeout(()=>{this._color='#B6B6B6';},2700);
        setTimeout(()=>{this._color='#D9D9D9';},3000);
        setTimeout(()=>{this._color='#EBEBEB';},3300);
        setTimeout(()=>{this._color='#FFFFFF';},3600);

        setTimeout(()=>{this.draw();},300);
        setTimeout(()=>{this.draw();},600);
        setTimeout(()=>{this.draw();},900);
        setTimeout(()=>{this.draw();},1200);
        setTimeout(()=>{this.draw();},1500);
        setTimeout(()=>{this.draw();},1800);
        setTimeout(()=>{this.draw();},2100);

        setTimeout(()=>{this.draw();},2400);
        setTimeout(()=>{this.draw();},2700);
        setTimeout(()=>{this.draw();},3000);
        setTimeout(()=>{this.draw();},3300);
        setTimeout(()=>{this.draw();},3600);

    }

}

window.addEventListener("showStars", ()=>{
    //Stars animation
    //Adding the stars to the array as objects
    for(let i=0;i<numberofStars;i++){
        let x           = Math.floor(Math.random()*window.innerWidth);
        let y           = Math.floor(Math.random()*window.innerHeight);
        let starSize    = (Math.random()+1)-0.7;
        starCollection.push(new Star(x,y,"white",starSize));
    }
    //Drawing all the stars on the screen
    for(let i=0;i<starCollection.length;i++){
        starCollection[i].draw();
    }
    //Storing random stars  
    const shuffleStars = ()=>{
        randomStars = [];
        for(let i=0;i<flickeringStars;i++){
            randomStars.push(Math.floor(Math.random()*starCollection.length))
        }
    }
    shuffleStars();


   //Flickering stars randomly
   const starflicker = ()=>{
    console.log(starCollection);
    console.log(randomStars);
            setTimeout(()=>{
                requestAnimationFrame(starflicker);
                for(let i=0;i<randomStars.length;i++){
                    starCollection[randomStars[i]].flicker();
                }
                shuffleStars();
            },500);
        }
        starflicker();
    })

    window.addEventListener("resize", ()=>{


        let canvas     = document.querySelector("canvas");
        let context    = canvas.getContext("2d");
        canvas.width   = window.innerWitdh;
        canvas.height  = window.innerHeight;
        context.clearRect(0,0,window.innerWidth, window.innerHeight);

        starCollection = [];
        randomStars    = [];

        let event      = new CustomEvent("showStars");
        dispatchEvent(event); 
    });

​

代码语言:javascript
复制
let starCollection = [];
let randomStars = [];
let numberofStars = 100;
let flickeringStars = 50;

class Star {
  constructor(x, y, color, radius) {
    this._canvas = document.querySelector('canvas');
    this._canvas.width = window.innerWidth;
    this._canvas.height = window.innerHeight;
    this._c = this._canvas.getContext('2d');
    this._radius = radius;

    this._x = x;
    this._y = y;
    this._color = color;
  }

  //drawing individual stars
  draw() {
    //Drawing
    this._c.beginPath();
    this._c.arc(this._x, this._y, this._radius, 0, Math.PI * 2, false);
    this._c.fillStyle = this._color;
    this._c.strokeStyle = 'black';
    this._c.stroke();
    this._c.fill();
    this._c.closePath();
  }
  //Fade in and out for stars
  flicker() {

    setTimeout(() => {
      this._color = '#EBEBEB';
    }, 300);
    setTimeout(() => {
      this._color = '#D9D9D9';
    }, 600);
    setTimeout(() => {
      this._color = '#B6B6B6';
    }, 900);
    setTimeout(() => {
      this._color = '#898787';
    }, 1200);
    setTimeout(() => {
      this._color = '#4F4F4F';
    }, 1500);

    setTimeout(() => {
      this._color = 'black';
    }, 1800);
    setTimeout(() => {
      this._color = '#4F4F4F';
    }, 2100);
    setTimeout(() => {
      this._color = '#898787';
    }, 2400);
    setTimeout(() => {
      this._color = '#B6B6B6';
    }, 2700);
    setTimeout(() => {
      this._color = '#D9D9D9';
    }, 3000);
    setTimeout(() => {
      this._color = '#EBEBEB';
    }, 3300);
    setTimeout(() => {
      this._color = '#FFFFFF';
    }, 3600);

    setTimeout(() => {
      this.draw();
    }, 300);
    setTimeout(() => {
      this.draw();
    }, 600);
    setTimeout(() => {
      this.draw();
    }, 900);
    setTimeout(() => {
      this.draw();
    }, 1200);
    setTimeout(() => {
      this.draw();
    }, 1500);
    setTimeout(() => {
      this.draw();
    }, 1800);
    setTimeout(() => {
      this.draw();
    }, 2100);

    setTimeout(() => {
      this.draw();
    }, 2400);
    setTimeout(() => {
      this.draw();
    }, 2700);
    setTimeout(() => {
      this.draw();
    }, 3000);
    setTimeout(() => {
      this.draw();
    }, 3300);
    setTimeout(() => {
      this.draw();
    }, 3600);

  }

}

window.addEventListener("showStars", () => {
  //Stars animation
  //Adding the stars to the array as objects
  for (let i = 0; i < numberofStars; i++) {
    let x = Math.floor(Math.random() * window.innerWidth);
    let y = Math.floor(Math.random() * window.innerHeight);
    let starSize = (Math.random() + 1) - 0.7;
    starCollection.push(new Star(x, y, "white", starSize));
  }
  //Drawing all the stars on the screen
  for (let i = 0; i < starCollection.length; i++) {
    starCollection[i].draw();
  }
  //Storing random stars  
  const shuffleStars = () => {
    randomStars = [];
    for (let i = 0; i < flickeringStars; i++) {
      randomStars.push(Math.floor(Math.random() * starCollection.length))
    }
  }
  shuffleStars();


  //Flickering stars randomly
  const starflicker = () => {
    console.log(starCollection);
    console.log(randomStars);
    setTimeout(() => {
      requestAnimationFrame(starflicker);
      for (let i = 0; i < randomStars.length; i++) {
        starCollection[randomStars[i]].flicker();
      }
      shuffleStars();
    }, 500);
  }
  starflicker();
})

window.addEventListener("resize", () => {


  let canvas = document.querySelector("canvas");
  let context = canvas.getContext("2d");
  canvas.width = window.innerWitdh;
  canvas.height = window.innerHeight;
  context.clearRect(0, 0, window.innerWidth, window.innerHeight);

  starCollection = [];
  randomStars = [];

  let event = new CustomEvent("showStars");
  dispatchEvent(event);
});
代码语言:javascript
复制
body{
background-color:black;
}
代码语言:javascript
复制
<html>
<body>
<canvas></canvas>
</body>
</html>

​

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-06-09 00:13:49

您的问题出在flicker函数中。即使在调整大小函数之后,这些setTimeouts仍然会触发。所以他们调用this.draw(),即使那些星星已经从你的数组中移除了。这个函数仍然记得'this‘是什么。

您可以像这样清除所有超时:

代码语言:javascript
复制
  window.addEventListener("resize", () => {
    let canvas = document.querySelector("canvas");
    let context = canvas.getContext("2d");
    canvas.width = window.innerWitdh;
    canvas.height = window.innerHeight;
    context.clearRect(0, 0, window.innerWidth, window.innerHeight);
    starCollection = [];
    randomStars = [];

    var id = window.setTimeout(function () { }, 0);
    while (id--) {
      window.clearTimeout(id); // will do nothing if no timeout with id is present
    }

    let event = new CustomEvent("showStars");
    dispatchEvent(event);
});

这是一个有10颗星的例子,其中5颗是闪烁的。我把星星做得更大,这样更容易看得见。

​

代码语言:javascript
复制
<html>

<head>
    <style>
        body {
            background: black;
        }
    </style>
</head>

<body>
    <canvas></canvas>

    <script>

        let starCollection = [];
        let randomStars = [];
        let numberofStars = 10;
        let flickeringStars = 5;

        class Star {
            constructor(x, y, color, radius) {
                this._canvas = document.querySelector('canvas');
                this._canvas.width = window.innerWidth;
                this._canvas.height = window.innerHeight;
                this._c = this._canvas.getContext('2d');
                this._radius = radius;

                this._x = x;
                this._y = y;
                this._color = color;
            }

            //drawing individual stars
            draw() {
                //Drawing
                this._c.beginPath();
                this._c.arc(this._x, this._y, this._radius, 0, Math.PI * 2, false);
                this._c.fillStyle = this._color;
                this._c.strokeStyle = 'black';
                this._c.stroke();
                this._c.fill();
                this._c.closePath();
            }
            //Fade in and out for stars
            flicker() {

                setTimeout(() => {
                    this._color = '#EBEBEB';
                }, 300);
                setTimeout(() => {
                    this._color = '#D9D9D9';
                }, 600);
                setTimeout(() => {
                    this._color = '#B6B6B6';
                }, 900);
                setTimeout(() => {
                    this._color = '#898787';
                }, 1200);
                setTimeout(() => {
                    this._color = '#4F4F4F';
                }, 1500);

                setTimeout(() => {
                    this._color = 'black';
                }, 1800);
                setTimeout(() => {
                    this._color = '#4F4F4F';
                }, 2100);
                setTimeout(() => {
                    this._color = '#898787';
                }, 2400);
                setTimeout(() => {
                    this._color = '#B6B6B6';
                }, 2700);
                setTimeout(() => {
                    this._color = '#D9D9D9';
                }, 3000);
                setTimeout(() => {
                    this._color = '#EBEBEB';
                }, 3300);
                setTimeout(() => {
                    this._color = '#FFFFFF';
                }, 3600);

                setTimeout(() => {
                    this.draw();
                }, 300);
                setTimeout(() => {
                    this.draw();
                }, 600);
                setTimeout(() => {
                    this.draw();
                }, 900);
                setTimeout(() => {
                    this.draw();
                }, 1200);
                setTimeout(() => {
                    this.draw();
                }, 1500);
                setTimeout(() => {
                    this.draw();
                }, 1800);
                setTimeout(() => {
                    this.draw();
                }, 2100);

                setTimeout(() => {
                    this.draw();
                }, 2400);
                setTimeout(() => {
                    this.draw();
                }, 2700);
                setTimeout(() => {
                    this.draw();
                }, 3000);
                setTimeout(() => {
                    this.draw();
                }, 3300);
                setTimeout(() => {
                    this.draw();
                }, 3600);

            }

        }

        window.addEventListener("showStars", () => {
            //Stars animation
            //Adding the stars to the array as objects
            for (let i = 0; i < numberofStars; i++) {
                let x = Math.floor(Math.random() * window.innerWidth);
                let y = Math.floor(Math.random() * window.innerHeight);
                // let starSize = (Math.random() + 1) - 0.7;
                let starSize = 10;
                starCollection.push(new Star(x, y, "white", starSize));
            }
            //Drawing all the stars on the screen
            for (let i = 0; i < starCollection.length; i++) {
                starCollection[i].draw();
            }
            //Storing random stars  
            const shuffleStars = () => {
                randomStars = [];
                for (let i = 0; i < flickeringStars; i++) {
                    randomStars.push(Math.floor(Math.random() * starCollection.length))
                }
            }
            shuffleStars();


            //Flickering stars randomly
            const starflicker = () => {
                console.log(starCollection);
                console.log(randomStars);
                setTimeout(() => {
                    requestAnimationFrame(starflicker);
                    for (let i = 0; i < randomStars.length; i++) {
                        starCollection[randomStars[i]].flicker();
                    }
                    shuffleStars();
                }, 500);
            }
            starflicker();
        })

        window.addEventListener("resize", () => {


            let canvas = document.querySelector("canvas");
            let context = canvas.getContext("2d");
            canvas.width = window.innerWitdh;
            canvas.height = window.innerHeight;
            context.clearRect(0, 0, window.innerWidth, window.innerHeight);

            starCollection = [];
            randomStars = [];
            var id = window.setTimeout(function () { }, 0);
            while (id--) {
                window.clearTimeout(id); // will do nothing if no timeout with id is present
            }

            let event = new CustomEvent("showStars");
            dispatchEvent(event);
        });
        dispatchEvent(new CustomEvent("showStars"))
    </script>

</body>

</html>

​

有关超时清除代码如何工作的更多信息,请查看此帖子:javascript: Clear all timeouts?

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62248583

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档