react 加载动态词云

index.js

import React, { Component } from 'react'
import styles from './index.css'

var width = 300
var height = 300
var direction = '-1' //方向  -1 横向顺时针 1 横向逆时针  -2 纵向顺时针 2 纵向逆时针
var speed = 600 //速度
var color = ['#2D4DB6', '#04B67C', '#D1AF07', '#E27914', '#CB4A4D', '#B02690']
export default class index extends Component {
    state = {
        contentEle: [],
        timer: null,
        data: ['云图', '是个啥', '他啥都不是', '他就是词云', '就是他呆子', '傻子和疯子', '营养快线', '哈哈哈到家', '瑞士军刀', 'DW情侣对表', '清风抽纸', '这一刻更清晰', '债券评级', '呵呵旧宫style', '云图', '是个啥', '他啥都不是', '他就是词云', '就是他呆子', '傻子和疯子', '营养快线', '哈哈哈到家', '瑞士军刀', 'DW情侣对表', '清风抽纸', '这一刻更清晰', '债券评级', '呵呵旧宫style']
    }
    render() {
        const { data } = this.state
        return (
            <div id="main">
                <div className={styles.wordCloud__tagBall}>
                    {
                        data.map((it, idx) => this.renderContent(it, idx))
                    }
                </div>
            </div>
        )
    }
    // 内容
    renderContent = (it, idx) => {
        const { contentEle } = this.state
        if (contentEle[idx]) {
            return (
                <span className={styles.wordCloud__tag}
                    key={idx}
                    style={{
                        color: color[idx % color.length],
                        opacity: contentEle[idx].style.opacity,
                        transform: contentEle[idx].style.transform,
                        zIndex: contentEle[idx].style.zIndex
                    }}>
                    {it}</span>
            )
        } else {
            return (
                <span className={styles.wordCloud__tag} key={idx}> ss</span>
            )
        }
    }
    // 初始位点
    renderInit = () => {
        const { contentEle, data } = this.state
        const RADIUSX = (width - 50) / 2
        const RADIUSY = (height - 50) / 2
        for (let i = 0; i < data.length; i += 1) {
            const k = -1 + (2 * (i + 1) - 1) / data.length
            const a = Math.acos(k)
            const b = a * Math.sqrt(data.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: {},
            }
            contentEle.push(singleEle)
            this.setState({
                contentEle: contentEle
            })
        }
      
        this.animate()
    }
    // 动画
    animate = () => {
        this.rotateX()
        this.rotateY()
        this.move()
        // window.requestAnimationFrame(this.animate)
    }
    // X轴
    rotateX = () => {
        const angleX = ['-1', '1'].includes(direction)
            ? Math.PI / Infinity
            : Math.PI / ((Number(direction) / 2) * Number(speed))
        const cos = Math.cos(angleX)
        const sin = Math.sin(angleX)
        let contentEle = this.state.contentEle.map((t) => {
            const y1 = t.y * cos - t.z * sin
            const z1 = t.z * cos + t.y * sin
            return {
                ...t,
                y: y1,
                z: z1,
            }
        })
        this.setState({
            contentEle: contentEle
        })
    }
    // y轴
    rotateY = () => {
        const angleY = ['-2', '2'].includes(direction)
            ? Math.PI / Infinity
            : Math.PI / (Number(direction) * Number(speed))
        const cos = Math.cos(angleY)
        const sin = Math.sin(angleY)
        let contentEle = this.state.contentEle.map((t) => {
            const x1 = t.x * cos - t.z * sin
            const z1 = t.z * cos + t.x * sin
            return {
                ...t,
                x: x1,
                z: z1,
            }
        })
        this.setState({
            contentEle: contentEle
        })
    }
    // 样式
    move = () => {
        const CX = width / 2
        const CY = height / 2
        let contentEle = this.state.contentEle.map((singleEle) => {
            const { x, y, z } = singleEle
            const fallLength = 500
            const RADIUS = (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(scale * 100, 10),
                transform,
            }
            return {
                x,
                y,
                z,
                style,
            }
        })
        this.setState({
            contentEle: contentEle
        })
    }
    // 定时器
    iTimer = () => {
        const { data } = this.state
        this.setState({
            timer: setInterval(() => {
                this.renderInit()
                data.map((it, idx) => this.renderContent(it, idx))
            }, 50),
        });
    };
    
    componentDidMount() {
        this.renderInit()
        setTimeout(this.iTimer, 0);
    }

    componentWillUnmount() {
        this.state.timer && clearTimeout(this.state.timer);
    }

}

index.css

.wordCloud__tagBall {
  width: 300px;
  height: 300px;
  margin: 50px auto;
  position: relative;
}

.wordCloud__tag {
  display: block;
  position: absolute;
  left: 0px;
  top: 0px;
  color: green;
  text-decoration: none;
  font-size: 15px;
  font-family: '微软雅黑';
  font-weight: bold;
  cursor: pointer;
}

.wordCloud__tag:hover {
  color: red !important;
}

在这里插入图片描述

参考: js 转换为react

[转]插件链接:
https://github.com/jyoketsu/3d-tag-cloud-for-react-withclick
https://github.com/mcc108/TagCloud
https://github.com/crazylxr/3d-tag-cloud-for-react

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值