原博主链接
<!--* @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 = valuespanDom.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 + 1return Math.floor(Math.random() * choices + lowerInteger)},render () {if (this.resetTime < 100) {this.resetTime = this.resetTime + 1this.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.xvalue.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.wordCloudreturn {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>