2017-02-10 26 views
0

我正在尝试将粒子发射器切换为开或关。 我有一些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')); 

Idealy的解决办法是像清除requestAnimationFrame,但我似乎无法推测出来。 帮助将非常令人失望。 感谢

+0

https://www.youtube.com/watch?v=m7jibFQ5Tno,HTH –

回答

0

(代码TL; DR),你可以随时使用由requestAnimationFrame()返回的请求ID,像这样:当你想停止它

var reqID; 

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

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

然后:

cancelAnimationFrame(reqID); 

呼叫它与一个空的“reqID”是安全的。