React 封装标签云滚动组件 (希望看到的大佬给出优化意见^ ^)

import React from 'react';
  /**
   *  option: [
        {content:"标签",href:"###"},
      ],
      }
   */
class TagCloud extends React.Component {

  constructor(props) {
    super(props)
    this.state = {  
      option: this.props.TagCloudData,
      timer: null,
      
    }
  }

  config = () => {
    let tagContainer = document.getElementById('tag');
    let tags = [];
    let tagGroup = document.createDocumentFragment();
    let settings = [];

    if (this.state.option.length > 0) {
      settings = this.state.option;
    } else {
      for (let i = 0; i < 10; i++) {
        settings.push({
          content: '暂无数据',
        })
      }    
    }
    
    for (let i = 0, length = settings.length; i < length; i++) {
      let tag = document.createElement("a");
      tag.innerText = settings[i].content;
      // tag.setAttribute("href",settings[i].href);
      tag.setAttribute("class","tag");
      tag.style.cssText += "position: absolute; left: 0; top: 0; text-decoration: none; font-weight: bolder;"
      tagGroup.appendChild(tag);
      tags.push(tag);
    };
    tagContainer.appendChild(tagGroup);

    //让标签元素相对标签云元素绝对定位
    tagContainer.style.position = "relative";
    
    let setting = {
      radius: 200,
      maxFont: 30,
      color: true, //设置标签颜色,设置为true为随机颜色,也可以设置其他色值
      rotateAngleXbase: 300,//默认旋转速度基数,数越小速度越快
      rotateAngleYbase: 300,
      hover: true,//是否开启悬浮联动
    }

    // //合并传入的参数和默认参数,最终参数为setting
    // let setting={};
    // for(prop in options){
    //   setting[prop]=options[prop];
    // }
   
    let allTag = [];//标签数组
    let rotateAngleX = Math.PI / setting.rotateAngleXbase;
    let rotateAngleY = Math.PI / setting.rotateAngleYbase;

    function init(r) {
      for (let i = 0, length = tags.length; i < length; i++) {
        if (setting.color === true) {
          tags[i].style.color = "rgb(" + Math.round(255 * Math.random()) + "," + Math.round(255 * Math.random()) + "," + Math.round(255 * Math.random()) + ")";
        } else {
          tags[i].style.color = setting.color;
        }

        // 获取球面上均匀的点的经纬度 θ = arccos( ((2*num)-1)/all - 1); Φ = θ*sqrt(all * π);
        let angleX = Math.acos((2 * (i + 1) - 1) / length - 1);
        let angleY = angleX * Math.sqrt(length * Math.PI);
        //根据经纬度获取点的坐标,球中心的点坐标是 (0,0,0) x=r*sinθ*cosΦ   y=r*sinθ*sinΦ   z=r*cosθ;
        let x = r * Math.sin(angleX) * Math.cos(angleY);
        let y = r * Math.sin(angleX) * Math.sin(angleY);
        let z = r * Math.cos(angleX);
        //每个标签对象都有四对值
        let tag={
          x: x,
          y: y,
          z: z,
          ele: tags[i]
        };
        allTag.push(tag);
      }
    }

    //设置每个标签的坐标位置和字体大小以及透明度
    function setPosition(tag, r, maxFont) {
      tag.ele.style.transform = "translate(" + (tag.x + tagContainer.offsetWidth / 2 - tag.ele.offsetWidth / 2) + "px," + (tag.y + tagContainer.offsetHeight / 2 - tag.ele.offsetHeight / 2) + "px)";
      tag.ele.style.opacity = tag.z / r / 2 + 0.7;
      tag.ele.style.fontSize = (tag.z / r / 2 + 0.5) * maxFont + "px";
    }

    //绕x轴旋转的函数
    function rotateX(tag){
      let cos = Math.cos(rotateAngleX);
      let sin = Math.sin(rotateAngleX);
      let y1 = tag.y * cos - tag.z * sin;
      let z1 = tag.y * sin + tag.z * cos;
      tag.y = y1;
      tag.z = z1;
    }

    //绕y轴旋转的函数
    function rotateY(tag){
      let cos = Math.cos(rotateAngleY);
      let sin = Math.sin(rotateAngleY);
      let x1 = tag.z * sin + tag.x * cos;
      let z1 = tag.z * cos - tag.x * sin;
      tag.x = x1;
      tag.z = z1;
    }

    //鼠标悬浮改变转速和方向
    // if(setting.hover){
    //   tagContainer.onmousemove=function(e){
    //     rotateAngleY=(e.pageX-this.offsetLeft-this.offsetWidth/2)/10000;
    //     rotateAngleX=-(e.pageY-this.offsetTop-this.offsetHeight/2)/10000;
    //   }
    // }else{
    //   tagContainer.onmousemove=null;
    // }

    init(setting.radius);
    //开始转动的函数
    this.setState({
      timer: setInterval(function(){
        for (let i = 0; i < tags.length; i++){
          rotateX(allTag[i]);
          rotateY(allTag[i]);
          setPosition(allTag[i], setting.radius, setting.maxFont);
        }
      },100)
    })
  }
  
  componentDidMount = () => {  
    this.config();
    if (this.state.timer) {
      clearInterval(this.state.timer)   
    }
  }

  render() {
    return (
      
) } } export default TagCloud;

你可能感兴趣的:(React 封装标签云滚动组件 (希望看到的大佬给出优化意见^ ^))