阻止雨水下降

时间:2017-02-10 00:47:18

标签: javascript jquery reactjs canvas

我正在尝试将粒子发射器切换为打开或关闭。 我有一些Reactjs代码,用canvas元素创建雨/雪粒子。 我想出的正确杀死动画的每个概念仍会导致内存泄漏(在这种情况下,我认为它只是在旧的上投影一个新的画布并且仍然在内存中运行原始动画)。 这是Codepen.

以下是页面代码:

class CanvasComponent extends React.Component {
    componentDidMount() {

   this.BtnOnOff();
}  
constructor() {
    super();
    this.toggleState = this.toggleState.bind(this);
    this.state = {
      isActive : false

    }
  }

  toggleState() {
    this.setState({isActive:!this.state.isActive});
    this.BtnOnOff();
   //console.log(this.state.isActive);
  }  


snowMaker() {
    // Ref canvas & get context
    const canvas = document.getElementById('canvas');
    const ctx = canvas.getContext('2d');

     // Weather Types/////////////
     var liteSnow = 13;     //code 13 for snow light fluries.  
     var snow = 16;         //code 13 for snow fluries. 
     var hevySnow = 41;     //code 41 for Heavy snow. 
     var hevySnow2 = 43;    //code 43 for Heavy snow.  
     var DRain = 9;          //code 9 for drizzel
     var HRain = 3;          //code 3/4 for Thunderstorms/severe thunderstorms

     var Code = 43; // Code will take in the current weather code.

    // Resize canvas
    let width = canvas.width = window.innerWidth;
    let height = canvas.height = window.innerHeight;

    // Variables

         if (Code === 13) {                       /// Make it snow (light fluries)
            var drops = [];
            var dropColour = "rgba(255,255,255,1)";
            var dropLengths = [3, 3, 3, 3, 3, 3, 3];
            var dropSkews = [-2, -1, 0, 1, 2];
            var maxDrops = 100;
            var velocity = 8;
            var flutter = 5;

          }  
            else if (Code === 16){                  /// Make it snow (fluries)
            var drops = [];
            var dropColour = "rgba(255,255,255,1)";
            var dropLengths = [3, 3, 3, 3, 3, 3, 3];
            var dropSkews = [-2, -1, 0, 1, 2];
            var maxDrops = 500;
            var velocity = 7;
            var flutter = 5;

          }
             else if (Code === 41||Code === 43){                  /// Make it Heavy snow
            var drops = [];
            var dropColour = "rgba(255,255,255,1)";
            var dropLengths = [3, 2, 3, 2, 3, 2, 3];
            var dropSkews = [-3, -1, 0, 1, 3];
            var maxDrops = 800;
            var velocity = .5;
            var flutter = 8;

          }
            else if (Code === 9){                  /// Make it rain
            var drops = [];
            var dropColour = "rgba(255,255,255,0.41)";
            var dropLengths = [4, 5, 3, 6, 2, 3, 3];
            var dropSkews = [0, 0.2, 0, 0, 0.1];
            var maxDrops = 100;
            var velocity =1;
            var flutter = 1;   
          }
             else if (Code === 3||Code === 4){                  /// Make it ThunderStorms
            var drops = [];
            var dropColour = "rgba(255,255,255,0.5)";
            var dropLengths = [10, 8, 8, 8, 7, 15, 9];
            var dropSkews = [-0.2, -0.3, -0.2, -0.2, 0.1];
            var maxDrops = 1000;
            var velocity = .8;
            var flutter = .1;   
          }



    // Raindrop class
    class Droplet {
      constructor(x, y, length, skew) {
        this.x = x;
        this.y = y;
        this.length = length;
        this.skew = skew;
      }
      // Move method
      move() {
        // Increment x & y 
        this.y += this.length / velocity;
        this.x += this.skew / flutter;
        // Set limits
        if (this.y > height) {
          this.y = 0;
        }
        if (this.x > width || this.x < 0) {
          this.y = 0;
          this.x = Math.floor(Math.random() * width);
        }
      }
        // Draw method
        draw(ctx) {
          ctx.beginPath();
          ctx.moveTo(this.x, this.y);
          ctx.lineTo(this.x + this.skew, this.y + this.length);
          ctx.strokeStyle = dropColour;
          ctx.stroke();
        }
      }

      // Create drops and push to array
      for (let i = 0; i < maxDrops; i++) {
        let instance = new Droplet(
          Math.floor(Math.random() * width),
          Math.floor(Math.random() * height),
          randVal(dropLengths),
          randVal(dropSkews)
        );
        drops.push(instance);
      }

        // Animation loop
        function loop() {
          // Clear Canvas  
          ctx.clearRect(0, 0, width, height);
          // Draw / Move drops
          for (let drop of drops) {
            drop.move();
            drop.draw(ctx);
          }
          // Animation Frame
          requestAnimationFrame(loop)
        }
          // Begin animation
          loop();

      // Resize canvas - responsive
   window.addEventListener('resize', resize);
      function resize() {
        width = canvas.width = window.innerWidth;
        height = canvas.height = window.innerHeight;
      }

      // Function for random array values
      function randVal(array) {
        return array[Math.floor(Math.random() * array.length)];
      } 


}////////End of update canvas
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

snowKiller() {
    // Ref canvas & get context
    const canvas = document.getElementById('canvas');
    const ctx = canvas.getContext('2d');

     var Code = 13; 

    // Resize canvas
    let width = canvas.width = window.innerWidth;
    let height = canvas.height = window.innerHeight;

    // Variables

         if (Code === 13) {                       /// Make it snow (light fluries)
            var drops = [];
            var dropColour = "";
            var dropLengths = [0];
            var dropSkews = [0];
            var maxDrops = 0;
            var velocity = 0;
            var flutter = 0;

          }  

    // Raindrop class
    class Droplet {
      constructor(x, y, length, skew) {
        this.x = x;
        this.y = y;
        this.length = length;
        this.skew = skew;
      }
      // Move method
      move() {
        // Increment x & y 
        this.y += this.length / velocity;
        this.x += this.skew / flutter;
        // Set limits
        if (this.y > height) {
          this.y = 0;
        }
        if (this.x > width || this.x < 0) {
          this.y = 0;
          this.x = Math.floor(Math.random() * width);
        }
      }
        // Draw method
        draw(ctx) {
          ctx.beginPath();
          ctx.moveTo(this.x, this.y);
          ctx.lineTo(this.x + this.skew, this.y + this.length);
          ctx.strokeStyle = dropColour;
          ctx.stroke();
        }
      }

      // Create drops and push to array
      for (let i = 0; i < maxDrops; i++) {
        let instance = new Droplet(
          Math.floor(Math.random() * width),
          Math.floor(Math.random() * height),
          randVal(dropLengths),
          randVal(dropSkews)
        );
        drops.push(instance);
      }

        // Animation loop
        function loop() {
          // Clear Canvas  
          ctx.clearRect(0, 0, width, height);
          // Draw / Move drops
          for (let drop of drops) {
            drop.move();
            drop.draw(ctx);
          }
          // Animation Frame
          requestAnimationFrame(loop)
        }
          // Begin animation
          loop();

      // Resize canvas - responsive
   window.addEventListener('resize', resize);
      function resize() {
        width = canvas.width = window.innerWidth;
        height = canvas.height = window.innerHeight;
      }

      // Function for random array values
      function randVal(array) {
        return array[Math.floor(Math.random() * array.length)];
      } 


}////////End of update canvas

 BtnOnOff(){
     const OnOff =$('#Button').attr('class');

     if(OnOff=== "active"){
       // alert('this is on!')

       this.snowMaker();
        }else {

           this.snowKiller();
         // alert('this is off!');
        }
     console.log(OnOff); 

  } 


    render() {    
        return (
          <div>

           <button id="Button" className={this.state.isActive ? 'inactive' : 'active'} onClick ={this.toggleState}>{this.state.isActive ? 'STOP' : 'START'}</button>

           <canvas id="canvas"/>

          </div>
        );
    }
}

ReactDOM.render(<CanvasComponent/>, document.getElementById('app'));

理想情况下解决方案就像清除requestAnimationFrame,但我似乎无法弄明白。 帮助将非常渺茫。 感谢

1 个答案:

答案 0 :(得分:0)

(Code tl; dr)您始终可以使用requestAnimationFrame()返回的请求ID,如下所示:

var reqID;

function loop() {
  // rain
  reqID = requestAnimationFrame(loop);
}

// start loop same way
reqID = requestAnimationFrame(loop);

然后当你想要阻止它时:

cancelAnimationFrame(reqID);

使用空“reqID”调用它是安全的。