无插件实现词云动效

效果如下:
在这里插入图片描述
主要替换的数据为:

wordData:词云数据(图示效果为20词,每个词的长度在4-5效果最好)

colorList:颜色组

html

<div class="wordCloudTagBall">
  <span
    class="wordCloudTag"
    v-for="(item, index) of wordData"
    :key="index"
    :style="{
      color: colorList[index % colorList.length],
      ...contentEle[index].style,
    }"
    :title="item">{{ item }}</span>
</div>

ts

 // 词云数据
 private wordData: any = [
   '高新企业',
   '100.9万',
   '怀柔区国家',
   '一核四区',
   '实验室挂牌',
   '高新企业',
   '企业入驻',
   '一核四区',
 ];
  // 颜色组
 private colorList: any = [
   '#FF7866',
   '#5DEC6B',
   '#ff646f',
   '#00F6FF',
   '#2eccff',
   '#E2CE22',
   '#0090FF',
   '#1BDA87',
 ];
 private contentEle: any = []; // 词云的位置信息
 private direction: string = '-1'; // 方向 (-1 从左到右 1 从右到左 2从下到上 -2从上到下)
 private speed: number = 1000; // 速度
 private width: number = 360; // 词云宽
 private height: number = 200; // 词云高
 // @author: 奥特蛋 @date: 2022-05-11 18:51:35 @description:初始化
 private init() {
   const RADIUSX = (this.width - 50) / 2;
   const RADIUSY = (this.height - 50) / 2;
   this.contentEle = [];
   for (let i = 0; i < this.currentData.wordData.length; i += 1) {
     const k = -1 + (2 * (i + 1) - 1) / this.currentData.wordData.length;
     const a = Math.acos(k);
     const b = a * Math.sqrt(this.currentData.wordData.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();
 }
 // @author: 奥特蛋 @date: 2022-05-12 09:20:49 @description: 词云运动效果添加
 private animate() {
   this.rotateX();
   this.rotateY();
   this.move();
   window.requestAnimationFrame(this.animate);
 }
 // @author: 奥特蛋 @date: 2022-05-11 18:52:02 @description: 设置X轴旋转
 private 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: any) => {
     const y1 = t.y * cos - t.z * sin;
     const z1 = t.z * cos + t.y * sin;
     return {
       ...t,
       y: y1,
       z: z1,
     };
   });
 }
 // @author: 奥特蛋 @date: 2022-05-11 18:52:02 @description: 设置Y轴旋转
 
 private 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: any) => {
     const x1 = t.x * cos - t.z * sin;
     const z1 = t.z * cos + t.x * sin;
     return {
       ...t,
       x: x1,
       z: z1,
     };
   });
 }
 // @author: 奥特蛋 @date: 2022-05-11 18:52:02 @description: 移动
 private move() {
   const CX = this.width / 2;
   const CY = this.height / 2;
   this.contentEle = this.contentEle.map((singleEle: any) => {
     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(String(scale * 100), 10),
       transform,
     };
     return {
       x,
       y,
       z,
       style,
     };
   });
 }
 private created() {
   this.init();
 }

css

.wordCloudTagBall {
  position: relative;
  overflow: hidden;
  width: 360px;
  height: 200px;
}
.wordCloudTag {
  display: block;
  position: absolute;
  left: 0px;
  top: 0px;
  text-decoration: none;
  font-size: 18px;
  font-weight: bold;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值