/**
 *@author liuhaixiao
 *@createTime 2018-12-18 10:48
 *@description 流场特效
 */
let particles = [];
let phase = Math.random() * Math.PI;

export default class FlowField {

  random(min, max) {
    return Math.random() * (max - min) + min;
  }

  constructor(select) {
    this.oC = select;
    this.widthCanvas = this.oC.width;
    this.heightCanvas = this.oC.height;
    this.oGc = this.oC.getContext('2d');
  }

  getValue(x, y) {
    const { a, b, c, d } = {a: -0.99,
      b: 1,
      c: 1.34,
      d: -1.7};
    const scale = 0.008;
    x = (x - this.widthCanvas / 2) * scale;
    y = (y - this.heightCanvas / 2) * scale;
    const x1 = Math.sin(a * y) - Math.cos(b * x);
    const y1 = Math.sin(c * x) - Math.cos(d * y);
    return Math.atan2(y1 - y, x1 - x);
  }

  render(ctx, p, phase) {
    const value = this.getValue(p.x, p.y);
    const hue = 180 + (180 * Math.sin(phase));
    const a = particles.length / (p.index + 1);
    ctx.save();
    ctx.lineWidth = 0.25;
    ctx.strokeStyle = `hsla(${hue}, 50%, 50%, ${a})`;
    ctx.beginPath();
    ctx.moveTo(p.x, p.y);
    p.update(value);
    ctx.lineTo(p.x, p.y);
    ctx.stroke();
    ctx.closePath();
    ctx.restore();
  }

  reset() {
    this.oGc.clearRect(0, 0, this.widthCanvas, this.heightCanvas);

    particles = [];

    let y = this.heightCanvas * 0.125;

    for (let i = 0; i < this.heightCanvas * 0.75; i += 2) {
      particles.push({
        x: 0,
        y: y + i,
        vx: 0,
        vy: 0,
        index: i,
        update(noiseValue) {
          this.vx += Math.cos(noiseValue) * 0.3;
          this.vy += Math.sin(noiseValue) * 0.3;

          this.x += this.vx;
          this.y += this.vy;

          this.vx *= 0.99;
          this.vy *= 0.99;
        },
      });
    }

    phase = Math.random() * Math.PI;

  }

  clear() {
    this.oGc.fillStyle = 'hsla(0, 0%, 100%, 0.00009)';
    this.oGc.fillRect(0, 0, this.widthCanvas, this.heightCanvas);
  }

  run() {
    this.clear();
    particles.forEach(p => this.render(this.oGc, p, phase));
    phase += 0.001;
    requestAnimationFrame(()=>{
      this.run()
    });
  }

  draw() {

  }

  process() {
    this.reset();
    this.run();
  }
}
