美文网首页
移动的词云

移动的词云

作者: 江河不渡 | 来源:发表于2021-12-28 13:44 被阅读0次

    移动的词云。

    <template>
      <div>
        <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],
              fontSize: fontSizes[index],
              ...contentEle[index].style,
            }"
            :title="item.name + '\n' + item.value"
            @click="handleClick(item)"
            >{{ item.name }}</span
          >
        </div>
      </div>
    </template>
    <script>
    export default {
      name: "cloudWork",
      props: {
        width: {
          type: Number,
          default: 300,
        },
        height: {
          type: Number,
          default: 300,
        },
        // 测试数据
        data: {
          type: Array,
          default: () => [
     
            {
              name: "建议",
              value: 72,
            },
          
          ],
        },
      },
      data: () => ({
        color: ["#37A2DA", "#23517E"], // 字体颜色
        fontSizes: ["30px", "29px", "28px"], // 字体大小
        contentEle: [],
        direction: "-1", // 运动方向 |x|<1水平方向   1<|x|<2 垂直方向
        speed: 500, // 运动速度
        animateID: null,
      }),
      created() {
        this.data = this.data.sort(this.compare("value")); // 按value值的大小排序
        this.contentEle = this.data.map(() => ({
          x: 0,
          y: 0,
          z: 0,
          style: {},
        }));
      },
      mounted() {
        this.innit();
      },
      methods: {
        handleClick(item) {
          // console.log("item===>", item);
        },
        // 排序
        compare(property) {
          return function (a, b) {
            const value1 = a[property];
            const value2 = b[property];
            return value2 - value1;
          };
        },
        // 初始化
        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 = 700;
            const RADIUS = (this.width - 50) / 2;
            const scale = fallLength / (fallLength - z);
            const alpha = (z + RADIUS) / (2 * RADIUS);
            const left = `${x + CX - 30}px`;
            const top = `${y + CY - 15}px`;
            // const transform = `translate(${left}, ${top}) scale(${scale})`
            const transform = `translate(${left}, ${top}) `;
            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__tagBall {
      margin: 20px auto;
      margin-left: 0px;
      position: relative;
      width: 100%;
      height: 220px;
    }
    
    .wordCloud__tag {
      display: block;
      position: absolute;
      left: 0px;
      top: 0px;
      color: green;
      text-decoration: none;
      font-size: 18px;
      font-family: "微软雅黑";
      font-weight: bold;
      cursor: pointer;
    }
    
    .wordCloud__home {
      display: flex;
      justify-content: center;
    }
    </style>
    

    相关文章

      网友评论

          本文标题:移动的词云

          本文链接:https://www.haomeiwen.com/subject/eespqrtx.html