2017-02-10 8 views
0

Я пытаюсь включить или выключить излучатель частиц. У меня есть код Reactjs, который создает частицы дождя/снега с элементом холста. Каждое понятие, которое я придумал для надлежащего уничтожения анимации, все еще приводит к утечкам памяти (в этом случае я думаю, что это просто проецирование нового холста поверх старого и все еще запускающее оригинальную анимацию в памяти). Вот 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

(код Т.Л., др), вы всегда можете использовать запрос-ID возвращенное requestAnimationFrame(), как это:

var reqID; 

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

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

Затем, когда вы хотите, чтобы остановить его:

cancelAnimationFrame(reqID); 

Призвание он с пустым «reqID» безопасен.

 Смежные вопросы

  • Нет связанных вопросов^_^