为什么我看不到粒子的动画?

时间:2017-08-08 07:29:49

标签: reactjs canvas

我是React的初学者。那么,为什么我看到帆布,但我看不到粒子的动画?这看起来好像代码不会创建我的粒子,我不知道为什么会发生这种情况。如果我有一个粒子并更新其运动,那么一切正常。我需要做些什么来制作粒子。 这是我的Particle.js:

export default class Particle {
  constructor(args) {
    this.position = args.position;
    this.velocity = args.velocity;
    this.radius = args.radius;
    this.lifeSpan = args.lifeSpan;
    this.color = args.color;
    this.inertia = args.inertia;
    this.create = args.create;
  }

  render(state) {
    // Move
    this.position.x += this.velocity.x * 0.15;
    this.position.y += this.velocity.y * 0.15;

    // Border
    if (this.position.x + this.radius > state.screen.width || 
        this.position.x - this.radius < 0) {
        this.velocity.x = -this.velocity.x;
    }
    if (this.position.y + this.radius > state.screen.height || 
        this.position.y - this.radius < 0) {
        this.velocity.y = -this.velocity.y;
    }
    this.position.x > state.screen.width ? this.position.x = state.screen.width : this.position.x;
    this.position.y > state.screen.height ? this.position.y = state.screen.height : this.position.y;
    this.position.x < 0 ? this.position.x = 0 : this.position.x;
    this.position.y < 0 ? this.position.y = 0 : this.position.y;

    // Draw
    const context = state.context;
    context.save();
    context.beginPath();
    context.fillStyle = this.color;
    context.arc(this.position.x, this.position.y, this.radius, 0, Math.PI * 2);
    context.closePath();
    context.fill();
    context.restore();
 }
}

我的Particles.js:

import React, { Component } from 'react';
import Particle from './Particle';

class Particles extends Component {
  constructor() {
    super();
    this.state = {
      screen: {
        width: this.w,
        height: window.innerHeight,
      },
        context: null,
        particleCount: 20
    };
    this.particles = [];
    this.w = null;
  }
  handleResize() {
    this.setState({
      screen: {
        width: this.w,
        height: window.innerHeight,
      }
     });
  }

  componentDidMount() {
    const w = document.querySelector('.home').offsetWidth;
    this.w = w;
    this.handleResize();
    window.addEventListener('resize', this.handleResize.bind(this, false));
    const context = this.refs.canvas.getContext('2d');
    this.setState({ context: context });
    this.particles = [];
    this.generateParticles(this.state.particleCount);
    requestAnimationFrame( () => {this.update()});
  }

  componentWillUnmount() {
    window.removeEventListener('resize', this.handleResize);
  }
  generateParticles(howMany) {
    let particles = [];
    for (let i = 0; i < howMany; i++ ) {
        let particle = new Particle({
            position: {
                x: Math.random() * this.state.screen.width,
                y: Math.random() * this.state.screen.height,
            },
            velocity: {
                x: (Math.random() - 0.5) * 5,
                y: (Math.random() - 0.5) * 5,
            },
            radius: 20,
            color: '#D3D3D3',
            inertia: 0.25,
        });
        this.createObject(particle);
    }
  }
  createObject(item){
    this.particles.push(item);
  }
  updateObjects() {
    for ( let i = 0; i < this.particleCount; i++ ) {
        this.particles[i].render(this.state);
    }
  }

  update() {
    const context = this.state.context;
    context.save();
    context.fillStyle = '#00BFFF';
    context.fillRect(0, 0, this.state.screen.width, this.state.screen.height);
    this.updateObjects();
    context.restore();
    requestAnimationFrame( () => {this.update()});
  }
  render() {
    return(
        <canvas ref='canvas' 
            width={this.state.screen.width} 
            height={this.state.screen.height}
        />
    );
  }
}

export default Particles;

1 个答案:

答案 0 :(得分:0)

您已经搞砸了如何处理宽度(w)和粒子数(particleCount)。 我可以给出的唯一建议是 - 尽量将所有内容保存在一个地方 - 最好是state,不要混合实例字段和状态。

以下是工作codepen

class Particle {
  constructor(args) {
    this.position = args.position;
    this.velocity = args.velocity;
    this.radius = args.radius;
    this.lifeSpan = args.lifeSpan;
    this.color = args.color;
    this.inertia = args.inertia;
    this.create = args.create;
  }

  render(state) {
    // Move
    this.position.x += this.velocity.x * 0.15;
    this.position.y += this.velocity.y * 0.15;

    // Border
    if (this.position.x + this.radius > state.screen.width || 
        this.position.x - this.radius < 0) {
        this.velocity.x = -this.velocity.x;
    }
    if (this.position.y + this.radius > state.screen.height || 
        this.position.y - this.radius < 0) {
        this.velocity.y = -this.velocity.y;
    }
    this.position.x > state.screen.width ? this.position.x = state.screen.width : this.position.x;
    this.position.y > state.screen.height ? this.position.y = state.screen.height : this.position.y;
    this.position.x < 0 ? this.position.x = 0 : this.position.x;
    this.position.y < 0 ? this.position.y = 0 : this.position.y;

    // Draw
    const context = state.context;
    context.save();
    context.beginPath();
    context.fillStyle = this.color;
    context.arc(this.position.x, this.position.y, this.radius, 0, Math.PI * 2);
    context.closePath();
    context.fill();
    context.restore();
 }
}

/*
 * A simple React component
 */
class Application extends React.Component 
{
  constructor() 
  {    
    super();

    var w = document.querySelector('#app').offsetWidth;

    this.state = {
      screen: {
        width: w,
        height: window.innerHeight,
      },
        context: null,
        particleCount: 20
    };
    this.particles = [];
  }
  handleResize() 
  {
    var w = document.querySelector('#app').offsetWidth;
    this.setState({
      screen: {
        width: w,
        height: window.innerHeight,
      }
     });
  }

  componentDidMount() 
  {
    this.handleResize();
    window.addEventListener('resize', this.handleResize.bind(this, false));
    const context = this.refs.canvas.getContext('2d');
    this.setState({ context: context });
    this.particles = [];
    this.generateParticles(this.state.particleCount);
    requestAnimationFrame( () => {this.update()});
  }

  componentWillUnmount() {
    window.removeEventListener('resize', this.handleResize);
  }
  generateParticles(howMany) {
    let particles = [];
    for (let i = 0; i < howMany; i++ ) {
        let particle = new Particle({
            position: {
                x: Math.random() * this.state.screen.width,
                y: Math.random() * this.state.screen.height,
            },
            velocity: {
                x: (Math.random() - 0.5) * 5,
                y: (Math.random() - 0.5) * 5,
            },
            radius: 20,
            color: '#D3D3D3',
            inertia: 0.25,
        });
        this.createObject(particle);
    }
  }
  createObject(item){
    this.particles.push(item);
  }
  updateObjects() 
  {
    for ( let i = 0; i < this.state.particleCount; i++ ) 
    {
      console.log("Render particle",  i);
      this.particles[i].render(this.state);
    }
  }

  update() {
    console.log("update");
    const context = this.state.context;
    context.save();
    context.fillStyle = '#00BFFF';
    context.fillRect(0, 0, this.state.screen.width, this.state.screen.height);
    this.updateObjects();
    context.restore();
    requestAnimationFrame( () => {this.update()});
  }
  render() {
    return(
        <canvas ref='canvas' 
            width={this.state.screen.width} 
            height={this.state.screen.height}
        />
    );
  }
}

/*
 * Render the above component into the div#app
 */
ReactDOM.render(<Application />, document.getElementById('app'));