在vue项目中操作元素ref案例;

该博客介绍了一个Vue.js组件,用于创建动态的词云效果。作者通过创建多个span元素,赋予不同的颜色和字体大小,然后利用requestAnimationFrame实现词云的移动动画。词云会在容器内边界处改变运动方向,提供了一种视觉上吸引人的展示词汇的方式。
摘要由CSDN通过智能技术生成

在这里插入图片描述

原博主链接

<!--
 * @Description:会动的词云
 * @Author: Vergil
 * @Date: 2021-08-25 14:17:45
 * @LastEditTime: 2021-08-25 17:08:15
 * @LastEditors: Vergil
-->
<template>
  <div class="wordCloud" ref="wordCloud">
  </div>
</template>
<script>
export default {
  name: 'word-cloud',
  data () {
    return {
      hotWord: ['万事如意', '事事如意 ', '万事亨通', '一帆风顺', '万事大吉', '吉祥如意', '步步高升', '步步登高', '三羊开泰', '得心应手', '财源广进', '陶未媲美',
        '阖家安康', '龙马精神', '锦绣前程', '吉祥如意', '生龙活虎', '神采奕奕', '五谷丰登', '马到成功', '飞黄腾达', ' 步步高升', '福禄寿禧'
      ],
      color: [
        '#a18cd1', '#fad0c4', '#ff8177',
        '#fecfef', '#fda085', '#f5576c',
        '#fe9a8b', '#30cfd0', '#38f9d7'
      ],
      wordArr: [],
      timer: null,
      resetTime: 10,
      ContainerSize: ''
    }
  },
  mounted () {
    this.init()
  },
  methods: {
    init () {
      this.dealSpan()
      this.initWordPos()
      this.render()
    },
    dealSpan () {
      const wordArr = []
      this.hotWord.forEach((value) => {
        // 根据词云数量生成span数量设置字体颜色和大小
        const spanDom = document.createElement('span')
        spanDom.style.position = 'relative'
        spanDom.style.display = 'inline-block'
        spanDom.style.color = this.randomColor()
        spanDom.style.fontSize = this.randomNumber(15, 30) + 'px'
        spanDom.innerHTML = value
        spanDom.local = {
          position: {
            // 位置
            x: 0,
            y: 0
          },
          direction: {
            // 方向 正数往右 负数往左
            x: 1,
            y: 1
          },
          velocity: {
            // 每次位移初速度
            x: -0.5 + Math.random(),
            y: -0.5 + Math.random()
          }
        }
        this.$refs.wordCloud.appendChild(spanDom)
        wordArr.push(spanDom)
      })
      this.wordArr = wordArr
    },
    randomColor () {
      // 获取随机颜色
      var colorIndex = Math.floor(this.color.length * Math.random())
      return this.color[colorIndex]
    },
    randomNumber (lowerInteger, upperInteger) {
      // 获得一个包含最小值和最大值之间的随机数。
      const choices = upperInteger - lowerInteger + 1
      return Math.floor(Math.random() * choices + lowerInteger)
    },
    render () {
      if (this.resetTime < 100) {
        this.resetTime = this.resetTime + 1
        this.timer = requestAnimationFrame(this.render.bind(this))
        // setInterval(() => {
        //   console.log(1)
        //   this.render.bind(this)
        // }, 10)
        this.resetTime = 0
      }
      this.wordFly()
    },
    wordFly () {
      this.wordArr.forEach((value) => {
        // 设置运动方向 大于边界或者小于边界的时候换方向
        if (value.local.realPos.minx + value.local.position.x < this.ContainerSize.leftPos.x || value.local
          .realPos.maxx + value.local.position.x > this.ContainerSize.rightPos.x) {
          value.local.direction.x = -value
            .local.direction.x
        }
        if (value.local.realPos.miny + value.local.position.y < this.ContainerSize.leftPos.y || value.local
          .realPos.maxy + value.local.position.y > this.ContainerSize.rightPos.y) {
          value.local.direction.y = -value
            .local.direction.y
        }
        value.local.position.x += value.local.velocity.x * value.local.direction.x
        value.local.position.y += value.local.velocity.y * value.local.direction.y
        // 给每个词云加动画过渡
        value.style.transform = 'translateX(' + value.local.position.x + 'px) translateY(' + value.local.position
          .y + 'px)'
      })
    },
    initWordPos () {
      // 计算每个词的真实位置和容器的位置
      this.wordArr.forEach((value) => {
        value.local.realPos = {
          minx: value.offsetLeft,
          maxx: value.offsetLeft + value.offsetWidth,
          miny: value.offsetTop,
          maxy: value.offsetTop + value.offsetHeight
        }
      })
      this.ContainerSize = this.getContainerSize()
    },
    getContainerSize () {
      // 判断容器大小控制词云位置
      const el = this.$refs.wordCloud
      return {
        leftPos: {
          // 容器左侧的位置和顶部位置
          x: el.offsetLeft,
          y: el.offsetTop
        },
        rightPos: {
          // 容器右侧的位置和底部位置
          x: el.offsetLeft + el.offsetWidth,
          y: el.offsetTop + el.offsetHeight
        }
      }
    }
  },
  destroyed () {
    // 组件销毁,关闭定时执行
    cancelAnimationFrame(this.timer)
  }
}
</script>
<style lang="less" scoped>
.wordCloud {
  width: 100%;
  // height: 100%;
  height: 400px;
}
</style>

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值