/**
 *@author liuhaixiao
 *@createTime 2018-12-18 10:01
 *@description 圆圈动画
 */
const settings = {
  pointCount: 50,
  startSpeed: 1.3,
  availableColors: ["#aaa01f", "#bba301", "#eaf2a1", "#aacccc", "#faf3aa"]
};

let objects = [];
let mousePos = {};

export default class Circle {

  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');
  }

  init() {
    for (let i = 0; i <= settings.pointCount; i++) {
      let plusOrMinusX = Math.random() < 0.5 ? -1 : 1;
      let plusOrMinusY = Math.random() < 0.5 ? -1 : 1;

      const x = Math.random() * this.widthCanvas;
      const y = Math.random() * this.heightCanvas;
      const z = Math.random() * - 150;

      const v = {
        x: plusOrMinusX * Math.random() * settings.startSpeed,
        y: plusOrMinusY * Math.random() * settings.startSpeed,
        z: Math.random() * settings.startSpeed * 4,
      };

      const colorIndex = Math.floor(
        Math.random() * settings.availableColors.length
      );

      objects.push(
        new Point(this.oC, settings.availableColors[colorIndex], x, y, z, v)
      );
    }
    requestAnimationFrame(this.draw.bind(this));
  }

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

    objects.forEach(object => {
      object.calculatePosition();

      if (mousePos) {
        const xDiff = object.x - mousePos.x;
        const yDiff = object.y - mousePos.y;

        const pointDist = Math.sqrt(Math.pow(xDiff, 2) + Math.pow(yDiff, 2));

        if (pointDist < (150 + object.radius)) {
          object.adjustTowardsMouse(pointDist, mousePos.x, mousePos.y);
        }
      }

      object.draw(this.oGc);
    });
    requestAnimationFrame(this.draw.bind(this));

  }

  process() {
    this.init();
  }
}

class Point {
  constructor(canvas, color, x, y, z, v) {
    this.canvas = canvas;
    this.color = color;
    this.x = x;
    this.y = y;
    this.z = z;
    this.v = v;
    this.radius = this.calulateRadius();
  }

  calulateRadius() {
    return Math.abs(this.z / 120);
  }

  calculatePosition() {
    const diameter = 2 * this.radius;

    if (
      this.x > this.canvas.width ||
      this.y > this.canvas.height ||
      this.x + diameter < 0 ||
      this.y + diameter < 0
    ) {
      this.x = this.canvas.width / 2;
      this.y = this.canvas.height / 2;
      this.z = -40;
    }

    this.radius = this.calulateRadius();

    this.x += this.v.x;
    this.y += this.v.y;
    this.z += this.v.z;
  }

  adjustTowardsMouse(distToMouse, mouseX, mouseY) {
    if (mouseX > this.x) {
      this.v.x += 10 / distToMouse;
    }
    if (mouseY > this.y) {
      this.v.y += 10 / distToMouse;
    }

    if (mouseX <= this.x) {
      this.v.x -= 10 / distToMouse;
    }
    if (mouseY <= this.y) {
      this.v.y -= 10 / distToMouse;
    }
  }

  draw(context) {
    context.beginPath();
    context.strokeStyle = this.color;
    context.fillStyle = this.color;
    context.arc(this.x, this.y, this.radius, 0, 2 * Math.PI);
    context.fill();
  }
}
