<main>
    <a href="/"><img src="https://threejs-plactice.vercel.app/fontloader/img/logo.png"></a>
  </main>
  <canvas id="myCanvas"></canvas>
    body {
      margin: 0;
      background-color: white;
    }
    main {
      position: relative;
      height: 100vh;
    }
    main:after {
      content: '';
      background: linear-gradient(to bottom right, rgba(255,255,255,0) 50%, #F0F0F0 50.5%) no-repeat top left/100% 100%;
      width: 100%;
      height: 20%;
      display: block;
      bottom: 0;
      position: absolute;
    }
    main img {
      position: absolute;
      top: 50%;
      left: 25%;
      z-index: 1000;
      transform: translate(-50%, -50%);
      width: 15vw;
    }
    canvas {
      position: absolute;
      transform: translate(50%, 0);
      top: 0;
    }
  window.addEventListener('load', Resize);
  window.addEventListener('resize', Resize);
  
  let width = 100, height = 100;

  function getRandomArbitrary(min, max) {
    return Math.random() * (max - min) + min;
  }


  function Resize() {

    let width = window.innerWidth,
        height = window.innerHeight;

    /**
    * renderer
    **/
    let renderer = new THREE.WebGLRenderer({
                      canvas: document.querySelector('#myCanvas'),
                      alpha: true
                   });
    renderer.setPixelRatio(window.devicePixelRatio);
    renderer.setSize(width, height);

    /**
    * scene
    **/
    let scene = new THREE.Scene();

    /**
    * camera
    **/
    let camera = new THREE.PerspectiveCamera(45, width / height);
    camera.position.set(0, 0, 1000);

    /**
    * controls
    **/
    let controls = new THREE.OrbitControls(
                       camera,
                       document.querySelector('#myCanvas')
                   );

    /**
    * BoxGeometry
    **/
    let circle_size = 1400;
    let circle = new THREE.BoxGeometry(
                          circle_size,
                          circle_size,
                          circle_size
                        );
    let circle_mat = new THREE.MeshPhongMaterial( {
                          transparent: true,
                          opacity: 0.1,
                          color: 0x000000
                        } );

    circle_box = new THREE.Mesh(circle, circle_mat);
    circle_box.position.x = 0;
    scene.add(circle_box);

    /**
    * texts
    **/
    let loader = new THREE.FontLoader();
    loader.load( 'https://threejs-plactice.vercel.app/fontloader/fonts/helvetiker_regular.typeface.json', function ( font ) {
      let matDark = new THREE.LineBasicMaterial( {
        color: 0x000000,
        opacity: .7,
        side: THREE.DoubleSide
      } );
      let matLite = new THREE.MeshBasicMaterial( {
        color: 0x000000,
        transparent: true,
        opacity: .7,
        side: THREE.DoubleSide
      } );

      for (let i = 0; i < 120; i++) {
        let message = ['html','css','Javascript','php','jQuery','vue.js','React.js','node.js','gulp.js','SCSS','Wordpress','Movable type','micro cms','typescript', 'go', 'nuxt.js', 'next.js'],
            christalNo = Math.floor( Math.random() * message.length),
            shapes = font.generateShapes( message[christalNo], 30 ),
            text_geometry = new THREE.ShapeGeometry( shapes ),
            size = 1000;
        
        text_geometry.computeBoundingBox();

        switch (true) {
          case ( i % 8 == 0 ):
            xcode = getRandomArbitrary( circle_size / 1.5, -circle_size / 1.5 );
            ycode = getRandomArbitrary( circle_size / 1.5, -circle_size / 1.5 );
            zcode = getRandomArbitrary( circle_size / 1.5, -circle_size / 1.5 );
          break;
          case ( i % 8 == 1 ):
            xcode = -getRandomArbitrary( circle_size / 1.5, -circle_size / 1.5 );
            ycode = getRandomArbitrary( circle_size / 1.5, -circle_size / 1.5 );
            zcode = getRandomArbitrary( circle_size / 1.5, -circle_size / 1.5 );
          break;
          case ( i % 8 == 2 ):
            xcode = getRandomArbitrary( circle_size / 1.5, -circle_size / 1.5 );
            ycode = -getRandomArbitrary( circle_size / 1.5, -circle_size / 1.5 );
            zcode = getRandomArbitrary( circle_size / 1.5, -circle_size / 1.5 );
          break;
          case ( i % 8 == 3 ):
            xcode = getRandomArbitrary( circle_size / 1.5, -circle_size / 1.5 );
            ycode = getRandomArbitrary( circle_size / 1.5, -circle_size / 1.5 );
            zcode = -getRandomArbitrary( circle_size / 1.5, -circle_size / 1.5 );
          break;
          case ( i % 8 == 4 ):
            xcode = -getRandomArbitrary( circle_size / 1.5, -circle_size / 1.5 );
            ycode = getRandomArbitrary( circle_size / 1.5, -circle_size / 1.5 );
            zcode = -getRandomArbitrary( circle_size / 1.5, -circle_size / 1.5 );
          break;
          case ( i % 8 == 5 ):
            xcode = getRandomArbitrary( circle_size / 1.5, -circle_size / 1.5 );
            ycode = -getRandomArbitrary( circle_size / 1.5, -circle_size / 1.5 );
            zcode = -getRandomArbitrary( circle_size / 1.5, -circle_size / 1.5 );
          break;
          case ( i % 8 == 6 ):
            xcode = -getRandomArbitrary( circle_size / 1.5, -circle_size / 1.5 );
            ycode = -getRandomArbitrary( circle_size / 1.5, -circle_size / 1.5 );
            zcode = getRandomArbitrary( circle_size / 1.5, -circle_size / 1.5 );
          break;
          default:
            xcode = -getRandomArbitrary( circle_size / 1.5, -circle_size / 1.5 );
            ycode = -getRandomArbitrary( circle_size / 1.5, -circle_size / 1.5 );
            zcode = -getRandomArbitrary( circle_size / 1.5, -circle_size / 1.5 );              
          break;
        }

        text_geometry.translate(
          xcode,
          ycode,
          zcode,
        );

        let text = new THREE.Mesh( text_geometry, matLite );
            text.position.z = -5;
            scene.add( text );

            let holeShapes = [];

            for ( let i = 0; i < shapes.length; i ++ ) {
              let shape = shapes[ i ];
              if ( shape.holes && shape.holes.length > 0 ) {
                for ( let j = 0; j < shape.holes.length; j ++ ) {
                  let hole = shape.holes[ j ];
                  holeShapes.push( hole );
                }
              }
            }
            shapes.push.apply( shapes, holeShapes );
            let lineText = new THREE.Object3D();
            for ( let i = 0; i < shapes.length; i ++ ) {
              let shape = shapes[ i ],
                  points = shape.getPoints(),
                  text_geometry = new THREE.BufferGeometry().setFromPoints( points );

              text_geometry.translate(
                xcode,
                ycode,
                zcode
              );
              let lineMesh = new THREE.Line( text_geometry, matDark );
              lineText.add( lineMesh );
            }
            scene.add( lineText );
        }
    } );

    tick();

    function tick() {
      scene.rotation.x += 0.005;
      scene.rotation.y += 0.005;
      scene.rotation.z += 0.005;
      renderer.render(scene, camera);
      requestAnimationFrame(tick);
    }
  }

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://unpkg.com/three@0.131.3/build/three.min.js
  2. https://unpkg.com/three@0.131.3/examples/js/controls/OrbitControls.js