<template>
  <div class="wordcloud">
    <div
      class="wordCloud__tagBall"
      :style="{width:`${this.width}px`,height:`${this.height}px`}"
      @mouseenter="stop"
      @mouseleave="start"
    >
      <span
        class="wordCloud__tag"
        v-for="(item, index) of data"
        :key="index"
        :style="{color:color[index % color.length],...contentEle[index].style}"
        :title="item.name+item.value"
      >{{item.name}}</span>
    </div>
  </div>
</template>


<script>
export default {
  name: 'cloudWork',
  props: {
    width: {
      type: Number,
      default: 129
    },
    height: {
      type: Number,
      default: 129
    },
    // 测试数据
    data: {
      type: Array,
      default: () => [
        {
          name: '测试一类',
          value: 30
        },
        {
          name: '测试二类',
          value: 30
        },
        {
          name: '测试三类',
          value: 30
        },
        {
          name: '测试四类',
          value: 30
        },
        
      ]
    }
  },
  data: () => ({
    color: ['#0054FF', '#B9B9B9', '#D1AF07', '#E27914', '#CB4A4D', '#B02690'],
    contentEle: [],
    direction: '-1',
    speed: 400,
    animateID: null
  }),
  created() {
    this.contentEle = this.data.map(() => ({
      x: 0,
      y: 0,
      z: 0,
      style: {}
    }));
  },
  mounted() {
    this.innit();
  },
  methods: {
    innit() {
      const RADIUSX = (this.width - 50) / 2;
      const RADIUSY = (this.height - 50) / 2;
      this.contentEle = [];
      for (let i = 0; i < this.data.length; i += 1) {
        const k = -1 + (2 * (i + 1) - 1) / this.data.length;
        const a = Math.acos(k);
        const b = a * Math.sqrt(this.data.length * Math.PI);
        const x = RADIUSX * Math.sin(a) * Math.cos(b);
        const y = RADIUSY * Math.sin(a) * Math.sin(b);
        const z = RADIUSX * Math.cos(a);
        const singleEle = {
          x,
          y,
          z,
          style: {}
        };
        this.contentEle.push(singleEle);
      }
      this.animate();
    },
    animate() {
      this.rotateX();
      this.rotateY();
      this.move();
      this.animateID = window.requestAnimationFrame(this.animate);
    },
    rotateX() {
      const angleX = ['-1', '1'].includes(this.direction)
        ? Math.PI / Infinity
        : Math.PI / ((Number(this.direction) / 2) * Number(this.speed));
      const cos = Math.cos(angleX);
      const sin = Math.sin(angleX);

      this.contentEle = this.contentEle.map((t) => {
        const y1 = t.y * cos - t.z * sin;
        const z1 = t.z * cos + t.y * sin;
        return {
          ...t,
          y: y1,
          z: z1
        };
      });
    },
    rotateY() {
      const angleY = ['-2', '2'].includes(this.direction)
        ? Math.PI / Infinity
        : Math.PI / (Number(this.direction) * Number(this.speed));
      const cos = Math.cos(angleY);
      const sin = Math.sin(angleY);
      this.contentEle = this.contentEle.map((t) => {
        const x1 = t.x * cos - t.z * sin;
        const z1 = t.z * cos + t.x * sin;
        return {
          ...t,
          x: x1,
          z: z1
        };
      });
    },
    move() {
      const CX = this.width / 2;
      const CY = this.height / 2;
      this.contentEle = this.contentEle.map((singleEle) => {
        const { x, y, z } = singleEle;
        const fallLength = 500;
        const RADIUS = (this.width - 50) / 2;
        const scale = fallLength / (fallLength - z);
        const alpha = (z + RADIUS) / (2 * RADIUS);
        const left = `${x + CX - 15}px`;
        const top = `${y + CY - 15}px`;
        const transform = `translate(${left}, ${top}) scale(${scale})`;
        const style = {
          ...singleEle.style,
          opacity: alpha + 0.5,
          zIndex: parseInt(scale * 100, 10),
          transform
        };
        return {
          x,
          y,
          z,
          style
        };
      });
    },
    // 鼠标移入暂停
    stop() {
      window.cancelAnimationFrame(this.animateID);
    },
    // 鼠标离开恢复
    start() {
      this.animate();
    }
  }
};
</script>


<style  scoped>
button {
  margin: 20px;
}
.wordcloud {
    width: 100%;
    height: 100%;
    overflow: hidden;
}
.wordCloud__tagBall {
    width: 100%;
    height: 100%;
    position: relative;
}

.wordCloud__tag {
  display: block;
  position: absolute;
  left: 0px;
  top: 0px;
  color: green;
  text-decoration: none;
  font-size: 12px;
  font-family: '微软雅黑';
  font-weight: bold;
}
.wordCloud__tag :hover {
  color: red;
}

.wordCloud__home {
  display: flex;
  justify-content: center;
}
</style>