当前位置:编程学习 > > 正文

vue界面自动生成(Vue中实现3D标签云的详细代码)

时间:2021-10-02 01:09:05类别:编程学习

vue界面自动生成

Vue中实现3D标签云的详细代码

预览:

vue界面自动生成(Vue中实现3D标签云的详细代码)

代码:
页面部分:

  • <template>
      <li class="tagcloud-all"
           ref="tagcloudall">
        <a v-for="item in tagList" :href="item.url" rel="external nofollow"  :style="'color:' + item.color + ';top: 0;left: 0;filter:none;'">{{item.name}}</a>
      </li>
    </template>
    
    
  • CSS部分:

  • // 标签云
    .tagcloud-all {
      position: relative;
      a {
        position: absolute;
        top: 0px;
        left: 0px;
        color: #fff;
        font-weight: bold;
        text-decoration: none;
        padding: 3px 6px;
        &:hover {
          color: #FF0000;
          letter-spacing: 2px;
        }
      }
    }
    
    
  • JS部分:

  • export default {
      name: "tagcloud",
      data() {
        return {
          tagList: [],
          radius: 120,
          dtr: Math.PI / 180,
          d: 300,
          mcList: [],
          active: false,
          lasta: 1,
          lastb: 1,
          distr: true,
          tspeed: 10,
          size: 250,
          mouseX: 0,
          mouseY: 0,
          howElliptical: 1,
          oList: null,
          oA: null,
          sa: 0,
          ca: 0,
          sb: 0,
          cb: 0,
          sc: 0,
          cc: 0
        }
      },
      methods: {
        // 生成随机数
        getRandomNum() {
          return Math.floor(Math.random() * (255 + 1));
        },
        // 三角函数角度计算
        sineCosine(a, b, c) {
          this.sa = Math.sin(a * this.dtr);
          this.ca = Math.cos(a * this.dtr);
          this.sb = Math.sin(b * this.dtr);
          this.cb = Math.cos(b * this.dtr);
          this.sc = Math.sin(c * this.dtr);
          this.cc = Math.cos(c * this.dtr);
        },
        // 设置初始定位
        positionAll() {
          this.$nextTick(() => {      // 注意: 所有的在onReady方法中执行的方法都需要$nextTick确保所有的标签都已经渲染
            var phi = 0;
            var theta = 0;
            var max = this.mcList.length;
            var aTmp = [];
            var oFragment = document.createDocumentFragment();
            // 随机排序
            for (let i = 0; i < this.tagList.length; i++) {
              aTmp.push(this.oA[i]);
            }
            aTmp.sort(() => {
              return Math.random() < 0.5 ? 1 : -1;
            });
            for (let i = 0; i < aTmp.length; i++) {
              oFragment.appendChild(aTmp[i]);
            }
            this.oList.appendChild(oFragment);
            for (let i = 1; i < max + 1; i++) {
              if (this.distr) {
                phi = Math.acos(-1 + (2 * i - 1) / max);
                theta = Math.sqrt(max * Math.PI) * phi;
              } else {
                phi = Math.random() * (Math.PI);
                theta = Math.random() * (2 * Math.PI);
              }
              // 坐标变换
              this.mcList[i - 1].cx = this.radius * Math.cos(theta) * Math.sin(phi);
              this.mcList[i - 1].cy = this.radius * Math.sin(theta) * Math.sin(phi);
              this.mcList[i - 1].cz = this.radius * Math.cos(phi);
              this.oA[i - 1].style.left = this.mcList[i - 1].cx + this.oList.offsetWidth / 2 - this.mcList[i - 1].offsetWidth / 2 + 'px';
              this.oA[i - 1].style.top = this.mcList[i - 1].cy + this.oList.offsetHeight / 2 - this.mcList[i - 1].offsetHeight / 2 + 'px';
            }
          })
        },
        // 坐标更新 让标签动起来
        update() {
          this.$nextTick(() => {           // 注意: 所有的在onReady方法中执行的方法都需要$nextTick确保所有的标签都已经渲染
            var a;
            var b;
            if (this.active) {
              a = (-Math.min(Math.max(-this.mouseY, -this.size), this.size) / this.radius) * this.tspeed;
              b = (Math.min(Math.max(-this.mouseX, -this.size), this.size) / this.radius) * this.tspeed;
            } else {
              a = this.lasta * 0.98;
              b = this.lastb * 0.98;
            }
            this.lasta = a;
            this.lastb = b;
            if (Math.abs(a) <= 0.01 && Math.abs(b) <= 0.01) {
              return
            }
            var c = 0;
            this.sineCosine(a, b, c);
            for (var j = 0; j < this.mcList.length; j++) {
              var rx1 = this.mcList[j].cx;
              var ry1 = this.mcList[j].cy * this.ca + this.mcList[j].cz * (-this.sa);
              var rz1 = this.mcList[j].cy * this.sa + this.mcList[j].cz * this.ca;
              var rx2 = rx1 * this.cb + rz1 * this.sb;
              var ry2 = ry1;
              var rz2 = rx1 * (-this.sb) + rz1 * this.cb;
              var rx3 = rx2 * this.cc + ry2 * (-this.sc);
              var ry3 = rx2 * this.sc + ry2 * this.cc;
              var rz3 = rz2;
              this.mcList[j].cx = rx3;
              this.mcList[j].cy = ry3;
              this.mcList[j].cz = rz3;
              var per = this.d / (this.d + rz3);
              this.mcList[j].x = (this.howElliptical * rx3 * per) - (this.howElliptical * 2);
              this.mcList[j].y = ry3 * per;
              this.mcList[j].scale = per;
              this.mcList[j].alpha = per;
              this.mcList[j].alpha = (this.mcList[j].alpha - 0.6) * (10 / 6);
            }
            this.doPosition();
            this.depthSort();
          })
        },
        //
        doPosition() {
          this.$nextTick(() => {            // 注意: 所有的在onReady方法中执行的方法都需要$nextTick确保所有的标签都已经渲染
            var l = this.oList.offsetWidth / 2;
            var t = this.oList.offsetHeight / 2;
            for (var i = 0; i < this.mcList.length; i++) {
              this.oA[i].style.left = this.mcList[i].cx + l - this.mcList[i].offsetWidth / 2 + 'px';
              this.oA[i].style.top = this.mcList[i].cy + t - this.mcList[i].offsetHeight / 2 + 'px';
              this.oA[i].style.fontSize = Math.ceil(12 * this.mcList[i].scale / 2) + 8 + 'px';
              // this.oA[i].style.filter = "alpha(opacity=" + 100 * this.mcList[i].alpha + ")";
              this.oA[i].style.opacity = this.mcList[i].alpha;
            }
          })
        },
        //
        depthSort() {
          this.$nextTick(() => {            // 注意: 所有的在onReady方法中执行的方法都需要$nextTick确保所有的标签都已经渲染
            var aTmp = [];
            for (let i = 0; i < this.oA.length; i++) {
              aTmp.push(this.oA[i]);
            }
            aTmp.sort(function (vItem1, vItem2) {
              if (vItem1.cz > vItem2.cz) {
                return -1;
              } else if (vItem1.cz < vItem2.cz) {
                return 1;
              } else {
                return 0;
              }
            });
            for (let i = 0; i < aTmp.length; i++) {
              aTmp[i].style.zIndex = i;
            }
          })
        },
        // 网络请求 拿到tagList
        query() {
          // 假装从接口拿回来的数据
          let tagListOrg = [
            { name: '标签1', url: 'www.baidu.com' },
            { name: '标签2', url: 'www.baidu.com' },
            { name: '标签3', url: 'www.baidu.com' },
            { name: '标签4', url: 'www.baidu.com' },
            { name: '标签5', url: 'www.baidu.com' },
            { name: '标签6', url: 'www.baidu.com' },
            { name: '标签7', url: 'www.baidu.com' },
            { name: '标签8', url: 'www.baidu.com' },
            { name: '标签9', url: 'www.baidu.com' },
            { name: '标签10', url: 'www.baidu.com' },
            { name: '标签11', url: 'www.baidu.com' },
            { name: '标签12', url: 'www.baidu.com' },
            { name: '标签13', url: 'www.baidu.com' },
            { name: '标签14', url: 'www.baidu.com' },
            { name: '标签15', url: 'www.baidu.com' },
            { name: '标签16', url: 'www.baidu.com' },
            { name: '标签16', url: 'www.baidu.com' },
            { name: '标签16', url: 'www.baidu.com' },
            { name: '标签16', url: 'www.baidu.com' },
            { name: '标签16', url: 'www.baidu.com' },
            { name: '标签16', url: 'www.baidu.com' },
            { name: '标签16', url: 'www.baidu.com' },
            { name: '标签16', url: 'www.baidu.com' },
            { name: '标签16', url: 'www.baidu.com' },
            { name: '标签16', url: 'www.baidu.com' },
            { name: '标签16', url: 'www.baidu.com' },
            { name: '标签16', url: 'www.baidu.com' },
            { name: '标签16', url: 'www.baidu.com' },
            { name: '标签16', url: 'www.baidu.com' },
            { name: '标签17', url: 'www.baidu.com' }
          ];
          // 给tagList添加随机颜色
          tagListOrg.forEach(item => {
            item.color = "rgb(" + this.getRandomNum() + "," + this.getRandomNum() + "," + this.getRandomNum() + ")";
          })
          this.tagList = tagListOrg;
          this.onReady();
        },
        // 生成标签云
        onReady() {
          this.$nextTick(() => {
            this.oList = this.$refs.tagcloudall;
            this.oA = this.oList.getElementsByTagName('a')
            var oTag = null;
            for (var i = 0; i < this.oA.length; i++) {
              oTag = {};
              oTag.offsetWidth = this.oA[i].offsetWidth;
              oTag.offsetHeight = this.oA[i].offsetHeight;
              this.mcList.push(oTag);
            }
            this.sineCosine(0, 0, 0);
            this.positionAll();
            this.oList.onmouseover = () => {
              this.active = true;
            }
            this.oList.onmouseout = () => {
              this.active = false;
            }
            this.oList.onmousemove = (event) => {
              var oEvent = window.event || event;
    
              this.mouseX = oEvent.clientX - (this.oList.offsetLeft + this.oList.offsetWidth / 2);
              this.mouseY = oEvent.clientY - (this.oList.offsetTop + this.oList.offsetHeight / 2);
              this.mouseX /= 5;
              this.mouseY /= 5;
            }
            setInterval(() => {
              this.update()
            }, 30);            // 定时器执行 不能写setInterval(this.update(), 30)
          })
        }
      },
      created() {
        this.$nextTick(() => {
          this.query();
        })
      }
    }
    
  • 到此这篇关于Vue中实现3D标签云的文章就介绍到这了,更多相关Vue 3D标签云内容请搜索开心学习网以前的文章或继续浏览下面的相关文章希望大家以后多多支持开心学习网!

    标签:
    上一篇下一篇

    猜您喜欢

    热门推荐