元素表源码注解

<!DOCTYPE html>
<html>
  <head>
    <title>three.js css3d - periodic table</title>
    <meta charset="utf-8" />
    <!-- 控制网页为全屏幕大小,手机页面常用 -->
    <!-- 属性效果分别为 device-width :设备的宽度 user-scalable:是否可对页面进行缩放,no 禁止缩放-->
    <!-- minimum-scale 允许用户缩放到的最小比例 maximum-scale - 允许用户缩放到的最大比例 -->
    <meta
      name="viewport"
      content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"
    />
    
  </head>

  <body>
    <script src="build/three.js"></script>
    <script src="examples/js/libs/tween.min.js"></script>
    <script src="examples/js/controls/TrackballControls.js"></script>
    <script src="examples/js/renderers/CSS3DRenderer.js"></script>

    <div id="info">
      <a href="http://threejs.org" target="_blank" rel="noopener"
        >three.js css3d</a
      >
      - periodic table.
      <a
        href="https://plus.google.com/113862800338869870683/posts/QcFk5HrWran"
        target="_blank"
        rel="noopener"
        >info</a
      >.
    </div>
    <div id="container"></div>
    <div id="menu">
      <button id="table">TABLE</button>
      <button id="sphere">SPHERE</button>
      <button id="helix">HELIX</button>
      <button id="grid">GRID</button>
    </div>

    <script>
      var table = [
        "H",
        "Hydrogen",
        "1.00794",
        1,
        1,
        "He",
        "Helium",
        "4.002602",
        18,
        1,
        "Li",
        "Lithium",
        "6.941",
        1,
        2,
        "Be",
        "Beryllium",
        "9.012182",
        2,
        2,
        "B",
        "Boron",
        "10.811",
        13,
        2,
        "C",
        "Carbon",
        "12.0107",
        14,
        2,
        "N",
        "Nitrogen",
        "14.0067",
        15,
        2,
        "O",
        "Oxygen",
        "15.9994",
        16,
        2,
        "F",
        "Fluorine",
        "18.9984032",
        17,
        2,
        "Ne",
        "Neon",
        "20.1797",
        18,
        2,
        "Na",
        "Sodium",
        "22.98976...",
        1,
        3,
        "Mg",
        "Magnesium",
        "24.305",
        2,
        3,
        "Al",
        "Aluminium",
        "26.9815386",
        13,
        3,
        "Si",
        "Silicon",
        "28.0855",
        14,
        3,
        "P",
        "Phosphorus",
        "30.973762",
        15,
        3,
        "S",
        "Sulfur",
        "32.065",
        16,
        3,
        "Cl",
        "Chlorine",
        "35.453",
        17,
        3,
        "Ar",
        "Argon",
        "39.948",
        18,
        3,
        "K",
        "Potassium",
        "39.948",
        1,
        4,
        "Ca",
        "Calcium",
        "40.078",
        2,
        4,
        "Sc",
        "Scandium",
        "44.955912",
        3,
        4,
        "Ti",
        "Titanium",
        "47.867",
        4,
        4,
        "V",
        "Vanadium",
        "50.9415",
        5,
        4,
        "Cr",
        "Chromium",
        "51.9961",
        6,
        4,
        "Mn",
        "Manganese",
        "54.938045",
        7,
        4,
        "Fe",
        "Iron",
        "55.845",
        8,
        4,
        "Co",
        "Cobalt",
        "58.933195",
        9,
        4,
        "Ni",
        "Nickel",
        "58.6934",
        10,
        4,
        "Cu",
        "Copper",
        "63.546",
        11,
        4,
        "Zn",
        "Zinc",
        "65.38",
        12,
        4,
        "Ga",
        "Gallium",
        "69.723",
        13,
        4,
        "Ge",
        "Germanium",
        "72.63",
        14,
        4,
        "As",
        "Arsenic",
        "74.9216",
        15,
        4,
        "Se",
        "Selenium",
        "78.96",
        16,
        4,
        "Br",
        "Bromine",
        "79.904",
        17,
        4,
        "Kr",
        "Krypton",
        "83.798",
        18,
        4,
        "Rb",
        "Rubidium",
        "85.4678",
        1,
        5,
        "Sr",
        "Strontium",
        "87.62",
        2,
        5,
        "Y",
        "Yttrium",
        "88.90585",
        3,
        5,
        "Zr",
        "Zirconium",
        "91.224",
        4,
        5,
        "Nb",
        "Niobium",
        "92.90628",
        5,
        5,
        "Mo",
        "Molybdenum",
        "95.96",
        6,
        5,
        "Tc",
        "Technetium",
        "(98)",
        7,
        5,
        "Ru",
        "Ruthenium",
        "101.07",
        8,
        5,
        "Rh",
        "Rhodium",
        "102.9055",
        9,
        5,
        "Pd",
        "Palladium",
        "106.42",
        10,
        5,
        "Ag",
        "Silver",
        "107.8682",
        11,
        5,
        "Cd",
        "Cadmium",
        "112.411",
        12,
        5,
        "In",
        "Indium",
        "114.818",
        13,
        5,
        "Sn",
        "Tin",
        "118.71",
        14,
        5,
        "Sb",
        "Antimony",
        "121.76",
        15,
        5,
        "Te",
        "Tellurium",
        "127.6",
        16,
        5,
        "I",
        "Iodine",
        "126.90447",
        17,
        5,
        "Xe",
        "Xenon",
        "131.293",
        18,
        5,
        "Cs",
        "Caesium",
        "132.9054",
        1,
        6,
        "Ba",
        "Barium",
        "132.9054",
        2,
        6,
        "La",
        "Lanthanum",
        "138.90547",
        4,
        9,
        "Ce",
        "Cerium",
        "140.116",
        5,
        9,
        "Pr",
        "Praseodymium",
        "140.90765",
        6,
        9,
        "Nd",
        "Neodymium",
        "144.242",
        7,
        9,
        "Pm",
        "Promethium",
        "(145)",
        8,
        9,
        "Sm",
        "Samarium",
        "150.36",
        9,
        9,
        "Eu",
        "Europium",
        "151.964",
        10,
        9,
        "Gd",
        "Gadolinium",
        "157.25",
        11,
        9,
        "Tb",
        "Terbium",
        "158.92535",
        12,
        9,
        "Dy",
        "Dysprosium",
        "162.5",
        13,
        9,
        "Ho",
        "Holmium",
        "164.93032",
        14,
        9,
        "Er",
        "Erbium",
        "167.259",
        15,
        9,
        "Tm",
        "Thulium",
        "168.93421",
        16,
        9,
        "Yb",
        "Ytterbium",
        "173.054",
        17,
        9,
        "Lu",
        "Lutetium",
        "174.9668",
        18,
        9,
        "Hf",
        "Hafnium",
        "178.49",
        4,
        6,
        "Ta",
        "Tantalum",
        "180.94788",
        5,
        6,
        "W",
        "Tungsten",
        "183.84",
        6,
        6,
        "Re",
        "Rhenium",
        "186.207",
        7,
        6,
        "Os",
        "Osmium",
        "190.23",
        8,
        6,
        "Ir",
        "Iridium",
        "192.217",
        9,
        6,
        "Pt",
        "Platinum",
        "195.084",
        10,
        6,
        "Au",
        "Gold",
        "196.966569",
        11,
        6,
        "Hg",
        "Mercury",
        "200.59",
        12,
        6,
        "Tl",
        "Thallium",
        "204.3833",
        13,
        6,
        "Pb",
        "Lead",
        "207.2",
        14,
        6,
        "Bi",
        "Bismuth",
        "208.9804",
        15,
        6,
        "Po",
        "Polonium",
        "(209)",
        16,
        6,
        "At",
        "Astatine",
        "(210)",
        17,
        6,
        "Rn",
        "Radon",
        "(222)",
        18,
        6,
        "Fr",
        "Francium",
        "(223)",
        1,
        7,
        "Ra",
        "Radium",
        "(226)",
        2,
        7,
        "Ac",
        "Actinium",
        "(227)",
        4,
        10,
        "Th",
        "Thorium",
        "232.03806",
        5,
        10,
        "Pa",
        "Protactinium",
        "231.0588",
        6,
        10,
        "U",
        "Uranium",
        "238.02891",
        7,
        10,
        "Np",
        "Neptunium",
        "(237)",
        8,
        10,
        "Pu",
        "Plutonium",
        "(244)",
        9,
        10,
        "Am",
        "Americium",
        "(243)",
        10,
        10,
        "Cm",
        "Curium",
        "(247)",
        11,
        10,
        "Bk",
        "Berkelium",
        "(247)",
        12,
        10,
        "Cf",
        "Californium",
        "(251)",
        13,
        10,
        "Es",
        "Einstenium",
        "(252)",
        14,
        10,
        "Fm",
        "Fermium",
        "(257)",
        15,
        10,
        "Md",
        "Mendelevium",
        "(258)",
        16,
        10,
        "No",
        "Nobelium",
        "(259)",
        17,
        10,
        "Lr",
        "Lawrencium",
        "(262)",
        18,
        10,
        "Rf",
        "Rutherfordium",
        "(267)",
        4,
        7,
        "Db",
        "Dubnium",
        "(268)",
        5,
        7,
        "Sg",
        "Seaborgium",
        "(271)",
        6,
        7,
        "Bh",
        "Bohrium",
        "(272)",
        7,
        7,
        "Hs",
        "Hassium",
        "(270)",
        8,
        7,
        "Mt",
        "Meitnerium",
        "(276)",
        9,
        7,
        "Ds",
        "Darmstadium",
        "(281)",
        10,
        7,
        "Rg",
        "Roentgenium",
        "(280)",
        11,
        7,
        "Cn",
        "Copernicium",
        "(285)",
        12,
        7,
        "Nh",
        "Nihonium",
        "(286)",
        13,
        7,
        "Fl",
        "Flerovium",
        "(289)",
        14,
        7,
        "Mc",
        "Moscovium",
        "(290)",
        15,
        7,
        "Lv",
        "Livermorium",
        "(293)",
        16,
        7,
        "Ts",
        "Tennessine",
        "(294)",
        17,
        7,
        "Og",
        "Oganesson",
        "(294)",
        18,
        7
      ];

      var camera, scene, renderer;
      var controls;

      var objects = [];
      var targets = {
        table: [],
        sphere: [],
        helix: [],
        grid: []
      };

      init();
      animate();

      function init() {
        // PerspectiveCamera(fov, aspect, near, far)
        // Fov – 相机的视锥体的垂直视野角 越大越远
        // 我们把视角由45度变为60度,发现立方体变小了,很容易理解,视角变大之后,可以看到的范围变大了
        // Aspect – 相机视锥体的长宽比 通常设置为canvas元素的高宽比。
        // Near – 相机视锥体的近平面
        // Far – 相机视锥体的远平面
        // 只有离相机的距离大于near值,小于far值,且在相机的可视角度之内,才能被相机投影到
        camera = new THREE.PerspectiveCamera(
          40,
          window.innerWidth / window.innerHeight,
          1,
          10000
        );
        //相机得位置  在(0,0,3000)
        camera.position.z = 3000;

        //得到一个场景
        //场景就是一个三维空间
        scene = new THREE.Scene();

        // table

        for (var i = 0; i < table.length; i += 5) {
          //得到一个div
          var element = document.createElement("div");
          //给她class值
          element.className = "element";
          //给他一个背景颜色
          element.style.backgroundColor =
            "rgba(0,127,127," + (Math.random() * 0.5 + 0.25) + ")";

          var number = document.createElement("div");
          number.className = "number";
          //给一个文本内容
          //元素的排序
          number.textContent = i / 5 + 1;
          //将这个div加入到上面的div
          element.appendChild(number);

          var symbol = document.createElement("div");
          symbol.className = "symbol";
          //从上面数组拿到元素的缩写
          //textContent类似于innerHTML
          symbol.textContent = table[i];
          //也加到上面
          element.appendChild(symbol);

          var details = document.createElement("div");
          details.className = "details";
          //得到元素的全拼  和  序号
          //<br>换行符
          details.innerHTML = table[i + 1] + "<br>" + table[i + 2];
          element.appendChild(details);

          //一个完整的元素块
          var object = new THREE.CSS3DObject(element);
          object.position.x = Math.random() * 4000 - 2000;
          object.position.y = Math.random() * 4000 - 2000;
          object.position.z = Math.random() * 4000 - 2000;
          //这边x,y,z坐标随机  是刚进入时元素块会随机出现
          //添加到场景
          scene.add(object);

          //将object保存下来
          //方便找到
          //并且把所以的耽搁元素都已经做好的    保存到objects里面方便后面用到
          objects.push(object);

          //得到一个3D对象吧  和上面类似  只不过上面那个更精确
          //正常排列
          var object = new THREE.Object3D();
          object.position.x = table[i + 3] * 140 - 1330;
          object.position.y = -(table[i + 4] * 180) + 990;

          //保存到table标签里  点击回到正常排列
          targets.table.push(object);
        }

        // sphere

        //获得一个3维向量
        var vector = new THREE.Vector3();

        for (var i = 0, l = objects.length; i < l; i++) {
          //acos() 方法可返回一个数的反余弦
          var phi = Math.acos(-1 + (2 * i) / l);
          //sqrt() 方法可返回一个数的平方根。
          var theta = Math.sqrt(l * Math.PI) * phi;

          var object = new THREE.Object3D();

          //球坐标  利用球坐标  表示一个点 p 在三维空间的位置的三维正交坐标系
          object.position.setFromSphericalCoords(800, phi, theta);

          //猜测所有属性乘2    multiply 相乘  scalar 数量
          vector.copy(object.position).multiplyScalar(2);

          //将对想看向该目标点
          //应该是通过循环将每个元素块的3维向量更改  而且好像是连属性改  上面坐标3维坐标  下面为球坐标  类型都换了
          object.lookAt(vector);

          //每一个循环  将坐标放入
          targets.sphere.push(object);
        }

        // helix

        var vector = new THREE.Vector3();

        for (var i = 0, l = objects.length; i < l; i++) {
          var theta = i * 0.175 + Math.PI;
          var y = -(i * 8) + 450;

          var object = new THREE.Object3D();

          //柱坐标  r、φ、z    x=rcosφ  y=rsinφ    z=z
          object.position.setFromCylindricalCoords(900, theta, y);

          //存入的是柱坐标  取x,y,z取得是转化后的x,y,z还是柱坐标
          //但是如果是柱坐标 就没有必要乘2 直接给好   所以推断  应该是转化后的 x,y,z
          //那为什么废那么大劲求柱坐标呢?
          vector.x = object.position.x * 2;
          vector.y = object.position.y;
          vector.z = object.position.z * 2;

          object.lookAt(vector);

          targets.helix.push(object);
        }

        // grid

        for (var i = 0; i < objects.length; i++) {
          var object = new THREE.Object3D();

          object.position.x = (i % 5) * 400 - 800;
          //Math.floor() 返回小于或等于一个给定数字的最大整数。
          object.position.y = -(Math.floor(i / 5) % 5) * 400 + 800;
          object.position.z = Math.floor(i / 25) * 1000 - 2000;

          targets.grid.push(object);
        }

        //

        //渲染器
        renderer = new THREE.CSS3DRenderer();
        renderer.setSize(window.innerWidth, window.innerHeight);
        //把渲染器的所以结点添加到container(第二个div)里面
        document.getElementById("container").appendChild(renderer.domElement);

        //

        //THREE.TrackballControls()轨迹球控件,最常用的控件,可以使用鼠标轻松的移动、平移,缩放场景。
        controls = new THREE.TrackballControls(camera, renderer.domElement);
        //rotateSpeed  旋转速度
        //zoomSpeed 缩放速度
        //minDistance 最小视角
        //maxDistance 最大视角 Infinity 无穷大
        //controls.staticMoving 默认false   静止移动,为 true 则没有惯性
        ///controls.dynamicDampingFactor  阻尼系数 越小 则滑动越大
        controls.rotateSpeed = 0.5;
        controls.minDistance = 500;
        controls.maxDistance = 6000;
        //添加方法 渲染
        controls.addEventListener("change", render);

        //给table点击方法
        var button = document.getElementById("table");
        button.addEventListener(
          "click",
          function() {
            //让每个元素移到达个数组里保存的坐标
            transform(targets.table, 2000);
          },
          false
        );

        var button = document.getElementById("sphere");
        button.addEventListener(
          "click",
          function() {
            transform(targets.sphere, 2000);
          },
          false
        );

        var button = document.getElementById("helix");
        button.addEventListener(
          "click",
          function() {
            transform(targets.helix, 2000);
          },
          false
        );

        var button = document.getElementById("grid");
        button.addEventListener(
          "click",
          function() {
            transform(targets.grid, 2000);
          },
          false
        );

        //这个应该是才开始将位置从随机乱序变成正常的位置
        transform(targets.table, 2000);

        //

        window.addEventListener("resize", onWindowResize, false);
      }

      function transform(targets, duration) {
        //清除所有东西
        TWEEN.removeAll();

        for (var i = 0; i < objects.length; i++) {
          var object = objects[i];
          var target = targets[i];

          //tween.js是一款可生成平滑动画效果的js动画库。
          //只需要给她一个起点和终点  过程自己会生成
          new TWEEN.Tween(object.position)
            .to(
              {
                x: target.position.x,
                y: target.position.y,
                z: target.position.z
              },
              Math.random() * duration + duration
            )
            //为了平滑动画效果,你需要在同一个循环动画中调用TWEEN.update方法。
            //easing函数仅在每个tween每次被更新时调用,而不管有多少属性被改变。结果随后会被用于初始值:
            .easing(TWEEN.Easing.Exponential.InOut)
            .start();

          //rotation 旋转
          new TWEEN.Tween(object.rotation)
            .to(
              {
                x: target.rotation.x,
                y: target.rotation.y,
                z: target.rotation.z
              },
              Math.random() * duration + duration
            )
            .easing(TWEEN.Easing.Exponential.InOut)
            .start();
        }

        //上面是单个元素块
        new TWEEN.Tween(this)
          .to({}, duration * 2)
          .onUpdate(render)
          .start();
      }

      function onWindowResize() {
        camera.aspect = window.innerWidth / window.innerHeight;
        camera.updateProjectionMatrix();
        //时刻保持渲染器大小
        renderer.setSize(window.innerWidth, window.innerHeight);

        render();
      }

      //应该是优化动画
      function animate() {
        //requestAnimationFrame的方式的优势如下:

        // 1.经过浏览器优化,动画更流畅

        // 2.窗口没激活时,动画将停止,省计算资源
        requestAnimationFrame(animate);

        TWEEN.update();

        controls.update();
      }

      //轨迹球控件的方法
      //render(file,option),模板引擎就能自己渲染出视图,将视图模板的文件位置放入file,将传入的模板数据放入option对象中,
      function render() {
        renderer.render(scene, camera);
      }
    </script>
  </body>
</html>

 

posted @ 2019-03-22 15:36  源月  阅读(141)  评论(0编辑  收藏  举报