TagCanvas 在 vue 项目中使用(动态 3D 词云)

最近支撑别的部门做了一个大屏(Vue项目),大屏上面有一个词云的展示,需要让词动起来,经同事介绍用了一下 TagCanvas来实现:链接地址: TagCanvas - HTML5 Canvas Tag Cloud
最终做的效果如下图所示:

res1.gif

使用步骤分为三部

  1. 在index.html 文件中 利用script 标签引入 tagcanvas.js(或 tagcanvas.min.js) 文件 或者 在子应用中直接通过
import './tagcanvas.js';
export default {
  ....
}
  1. 新建子应用
<template>
  <div class="world-cloud-3d">
    <div class="world-cloud-canvas-wrapper">
      <canvas
        id="world-cloud-canvas"
        width="400"
        height="200"
        style="width: 100%; max-width: 400px"
      >
      </canvas>
    </div>
    <div style="display: none" id="weightTags"></div>
  </div>
</template>

<script>
export default {
  data: function () {
    return {};
  },
  props: {
    wordArr: {
      type: Array,
      default: [],
    },
  },
  methods: {
    // 启动词云
    startWorldCloud: function (updateFlag) {
      this.createTagListDom();
      let o = {
        maxSpeed: 0.01, // 添加最大的运动速度
        minSpeed: 0.01, // 添加最小的运动速度这样就可以保证一直运动,不会停止
        textHeight: 25,
        outlineMethod: "colour", // tag hover 之后的 轮廓效果
        fadeIn: 800,
        outlineColour: "#fff456aa",
        outlineOffset: 0,
        depth: 0.97,
        minBrightness: 0.2,
        wheelZoom: false,
        reverse: true, // 运动方向与鼠标移动方向相反
        shadowBlur: 2,
        shuffleTags: true,
        shadowOffset: [1, 1],
        stretchX: 1.7, // Stretch or compress the cloud horizontally. 水平拉伸词云
        initial: [0.1, 0.1], // 给词云添加一个初始的运动方向
        textFont: null, // 字体设置为 null 就会继承 每个 tag的a 标签的字体
        textColour: null, // 字体颜色设置为 null 就会继承 每个 tag的a 标签的字体颜色
        weight: true, // weight 打开,就可以根据默认的字体的大小作为权重,对tag 的样式进行调整
        weightMode: "size", // 样式调整的方式
        weightSize: 0.5, // 调整 tag 字体的大小,加个 权重
      };
      try {
        // 如果不是更新,说明是第一次渲染,就启动 tagcanvas, 否则就代表更新
        if (!updateFlag) {
          TagCanvas.Start("world-cloud-canvas", "weightTags", o);
        } else {
          TagCanvas.Update("world-cloud-canvas");
        }
      } catch (e) {}
    },
    // 根据父组件传过来的 wordArr 创建 TagList Dom列表,放到页面中供,canvas 渲染
    // 这里后端的数组中的数据结构是一个对象 { name: 要展示的tag名字, light: true/false 据定是否要加重展示}
    createTagListDom: function () {
      let res = [...this.wordArr];
      let fragment = new DocumentFragment();
      for (let i = 0; i < res.length; i++) {
        let a = document.createElement("a");
        // 字符串长度大于10就要换行
        if (res[i].name.length > 10) {
          let charArr = res[i].name.split("");
          charArr.splice(10, 0, "<br>");
          res[i].name = charArr.join("");
        }
        a.innerHTML = res[i].name;
        a.href = "javascript:void(0)";
        // 如果是要加重展示就 设置属性为 huge 或large, 否则就设置属性为 medium 或small
        if (res[i].light) {
          let readomValue = Math.random();
          a.className = readomValue > 0.5 ? "huge" : "large";
        } else {
          let readomValue = Math.random();
          a.className = readomValue > 0.5 ? "medium" : "small";
        }
        fragment.append(a);
      }
      // 更新 tagContainer中的 tag元素
      let tagsContainer = document.querySelector("#weightTags");
      tagsContainer.innerHTML = "";
      tagsContainer.append(fragment);
    },
  },
  watch: {
    // 如果词云发生变化就要 重绘 tagcanvas
    wordArr: function () {
      this.startWorldCloud(true);
    },
  },
  mounted() {
    // 组件装载成果 绘制 tagcanvas
    this.startWorldCloud();
  },
};
</script>
// 这里 style 不能加scope属性不然就不会成功
<style lang="less">
.world-cloud-3d {
  .world-cloud-canvas-wrapper {
    width: 400px;
    height: 200px;
    max-width: 400px;
    max-height: 200px;
  }
  #weightTags {
    font-size: 12px;
    .huge {
      font-size: 30px;
      color: #f5576caa;
    }
    .large {
      font-size: 25px;
      color: #38f9d7aa;
    }
    .medium {
      font-size: 20px;
      color: #a18cd1aa;
    }
    .small {
      font-size: 15px;
      color: #a18cd1aa;
    }
  }
}
</style>
  1. 在父应用中引入子应用, 绑定 wordArr 属性
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容