QR code kubussen/cylinders

QR code van de 8 kubussen en 3 cylinders 
in fullscreen
 

 

 

 

 

controls

 
 
 
 
kubuspositie =  -0.16 alfa = 0.62
kubuspositie =  -0.16 alfa = 0.62
 
 
 
 
de kubussen met grid en alfa = 1

de kubussen met ruitjespap en alpha = 1

 

 tussen het groene en blauwe vlak bevindt zich het camera frustum

 
tussen het groene en blauwe vlak bevindt zich
het camera frustum

 

 

three.js assenstelsel

 het three.js assenstelsel

 

 

 

 

 

 

 

 

 De animatie is  in x, y en z richting verplaatst
 

 \

 

 

 

 

materials en boxen worden samengevoegd tot meshes

materials en boxen worden samengevoegd tot meshes
In de groep functie (regel 180) worden de meshes
als groep aan de scene toegevoegd
 
 
 
 
renderer

 

groep van 8 kubussen en 3 cylinders.                    terug naar de inleiding 

                                                                                                                  naar de animatie in fullscreen  

Een animatie met 2 standaardvormen: BoxGeometry, en CylinderGeometrie
Het bijbehorende materials is:  MeshPhongMaterial omdat deze material het licht zo mooi reflecteerd
en  het ruitjespapier Gridhelper, zie de functie  createGrid (regel 96)
De lichtbronnen zijn AmbientLight en DirectionalLight. zie de functie createAmbientLight (regel 102) en de functie createDirectionalLights (regel 107)
De vormen , materials , gridhelper en lichtbronnen zijn classes van de three.module.js lib
Alle libs zijn javaScript ES6 modules. Dit zijn scripts opgebouwd uit modules wat een forse verbetering van de codeer stijl betekend.
 
addon libs
De muis en pijltjestoets bewegingen worden gerealiseerd met de addon lib OrbitControls, zie de functie createControl (regel 184)
De GUI (grafische user interface) wordt gerealiseerd met de addon lib lil-gui-module.min.js  zie de functie createGUI (regel 190)
 

Met muisbewegingen en li of re muisknop ingedrukt roteer je de  animatie met het muiswiel verplaatst de animatie in z richting.

Met de pijltjes toetsen verplaatst de animatie in x of y richting

Voor het overzicht  is alle code in functies gezet die worden aangeroepen in  function init()  (regel 43)

de acht kubussen en 3 cylinders vormen een groep die aan de scene zijn toegevoegd (regel 179 t/m 184)

Met data.kubuspositie verplaats je de kubussen tussen de -2 en + 2 (regel 135) en de kubuspositie verandert in de functie boxPosChange (regel 215 t/m 224)

 

<html>
  <head>
    <title>groep van 8 kubussen en 3 cylinders</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta charset="UTF-8" />
    <style> body { margin: 0;} </style>
  </head>
 
  <body>
      <script type="importmap">
          {
            "imports": {
              "three": "../build/three.module.js",
              "three/addons/": "../jsm/"
          }
    }
      </script>
 
      <script type="module">
          import * as THREE from 'three';
          import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
          import { GUI } from 'three/addons/libs/lil-gui.module.min.js';
 
          let camera, renderer, scene, groep, gridHelper;
          let wolken_achtergrond = false,  ruitjespap = true;
//boxen publiek declareren omdat ze ook in opacityChange() en boxPosChange() worden gebruikt
          let box1M,  box2M,  box3M,  box4M,  box5M,  box6M,  box7M,  box8M;
          let box1G,  box2G,  box3G,  box4G,  box5G,  box6G,  box7G,  box8G;
          let boxMat1,boxMat2,boxMat3,boxMat4,boxMat5,boxMat6,boxMat7,boxMat8;
           //data tbv de GUI control
          const data = {
           X_rotatie: 0.085, Y_rotatie: 0.01,  Z_rotatie: 0.085,
           alpha: 0.5, kubuspositie: 0.8,
           start_stop_rotatie: true, //true is aangevinkt
           wolken_achtergrond: false,
           ruitjespap: false }
 
          init();
          play(); //waarin de setAnimationLoop tbv render en animate worden aangeroepen
          //Dus render en animate zijn de functies die in de animatieloop zitten
 
          function init() {
          scene = new THREE.Scene();
            //als de gebruiker de grootte van het window aangepast
          //zal addEventListener onWindowResize aaanroepen
          window.addEventListener( 'resize', onWindowResize );
          createBackground();
          //createCamera, createRenderer, en onWindowResize zijn de basisfuncties
          createCamera();
          createRenderer();
          onWindowResize();
          createGrid(); //is het ruitjespapier
          createAmbientLight();
          createDirectionalLights();// voor 4 puntlichtjes
          createGui(); //voor het controlvenster rechts boven
          createGeomMatMesh(); //voor de boxen, cylinders en hun materials, samengevoegd in de groep
          createControls();  //voor de muiscontrols
          }
 
      function createBackground() {
            if (wolken_achtergrond==false)
         {const bgColor = new THREE.Color( 0xE6FBFF );
          scene.background = bgColor;
          wolken_achtergrond = true;}
            else
          {const loader = new THREE.TextureLoader();
          const bgTexture = loader.load('../textures/cloud.jpg');
          scene.background = bgTexture;
          wolken_achtergrond = false;}
      }
 
      function createCamera() {
          camera = new THREE.PerspectiveCamera(
          35, // FOV
          window.innerWidth / window.innerHeight, // aspect ratio
          0.1, // near clipping plane
          100, // far clipping plane
            );
          camera.position.set( 0, 0, 7 );
      }
 
      function createRenderer() {
          renderer = new THREE.WebGLRenderer( { antialias: true} );
          renderer.setPixelRatio( window.devicePixelRatio );
          renderer.setSize( window.innerWidth, window.innerHeight );
          document.body.appendChild( renderer.domElement );
          }
 
      function onWindowResize() {
          camera.aspect = window.innerWidth/ window.innerHeight;
          camera.updateProjectionMatrix(); //met updateProjectionMatrix wordt her camera frustrum aangepast
          renderer.setSize(window.innerWidth, window.innerHeight);
        }
 
      function createGrid() {
          gridHelper = new THREE.GridHelper( 10, 10);
          gridHelper.rotation.x = Math.PI / 2;
          scene.remove( gridHelper );
      }
 
      function createAmbientLight() {
            const ambientLight = new THREE.AmbientLight(0xffffff, 0.6);
            scene.add(ambientLight);
          }
 
      function createDirectionalLights(x,y,z) {
          const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
          directionalLight.position.set(x,y,z);
          scene.add(directionalLight);
          }
          //geeft 4 Directionallights
          createDirectionalLights(-2, 0, -5);
          createDirectionalLights(2,  2, 5);
          createDirectionalLights(-2,-2, -5);
          createDirectionalLights(2,  2, 5);
 
      function createGeomMatMesh() {
          boxMat1 = new THREE.MeshPhongMaterial( {color: 0xff3333, opacity: 0.5, transparent: true, shininess: 400,flatShading: true} );
          boxMat2 = new THREE.MeshPhongMaterial( {color: 0xffd700, opacity: 0.5, transparent: true, shininess: 400,flatShading: true} );
          boxMat3 = new THREE.MeshPhongMaterial( {color: 0x00ff00, opacity: 0.5, transparent: true, shininess: 400,flatShading: true} );
          boxMat4 = new THREE.MeshPhongMaterial( {color: 0xff00ff, opacity: 0.5, transparent: true, shininess: 400,flatShading: true} );
          boxMat5 = new THREE.MeshPhongMaterial( {color: 0xcd853f, opacity: 0.5, transparent: true, shininess: 400,flatShading: true} );
          boxMat6 = new THREE.MeshPhongMaterial( {color: 0x00ffff, opacity: 0.5, transparent: true, shininess: 400,flatShading: true} );
          boxMat7 = new THREE.MeshPhongMaterial( {color: 0xff1493, opacity: 0.5, transparent: true, shininess: 400,flatShading: true} );
          boxMat8 = new THREE.MeshPhongMaterial( {color: 0x0000ff, opacity: 0.5, transparent: true, shininess: 400,flatShading: true} );
          const cylinderMatx = new THREE.MeshPhongMaterial( {color: 0xcd853f, opacity: 0.5, transparent: true, shininess: 400,flatShading: true} );
          const cylinderMaty = new THREE.MeshPhongMaterial( {color: 0x0000ff, opacity: 0.5, transparent: true, shininess: 400,flatShading: true} );
          const cylinderMatz = new THREE.MeshPhongMaterial( {color: 0x00fa9a, opacity: 0.5, transparent: true, shininess: 400,flatShading: true} );
 
            //parameters van de BoxGeometry constructor
            //1) breedte, 2) hoogte 3) diepte
          box1G = new THREE.BoxGeometry( 1, 1, 1);
          box1M = new THREE.Mesh( box1G, boxMat1 );
          let s = data.kubuspositie;
          box1M.position.set( -s, -s, -s );
 
          box2G = new THREE.BoxGeometry( 1, 1, 1);
          box2M = new THREE.Mesh( box2G, boxMat2 );
          box2M.position.set( -s, -s, s );
 
          box3G = new THREE.BoxGeometry( 1, 1, 1);
          box3M = new THREE.Mesh( box3G, boxMat3 );
          box3M.position.set( -s, s, -s );
 
          box4G = new THREE.BoxGeometry( 1, 1, 1);
          box4M = new THREE.Mesh( box4G, boxMat4 );
          box4M.position.set( -s, s, s );
 
          box5G = new THREE.BoxGeometry( 1, 1, 1);
          box5M = new THREE.Mesh( box5G, boxMat5 );
          box5M.position.set( s, -s, -s );
 
          box6G = new THREE.BoxGeometry( 1, 1, 1);
          box6M = new THREE.Mesh( box6G, boxMat6 );
          box6M.position.set( s, -s, s );
 
          box7G = new THREE.BoxGeometry( 1, 1, 1, 1 );
          box7M = new THREE.Mesh( box7G, boxMat7 );
          box7M.position.set( s,  s, -s );
 
          box8G = new THREE.BoxGeometry( 1, 1, 1, 1 );
          box8M = new THREE.Mesh( box8G, boxMat8 );
          box8M.position.set( s,  s,  s );
 
            //parameters van de CylinderBufferGeometry constructor
            //1) radiusTop, 2) radiusBottom, 3) hoogte 4) radiale segmenten
          const cylinderGx = new THREE.CylinderGeometry( 0.2, 0.2, 2.6, 10 );
          const cylinderMx = new THREE.Mesh( cylinderGx, cylinderMatx );
          cylinderMx.rotation.z = Math.PI / 2;
 
          const cylinderGy = new THREE.CylinderGeometry( 0.2, 0.2, 2.6, 10 );
          const cylinderMy = new THREE.Mesh( cylinderGy, cylinderMaty );
 
          const cylinderGz = new THREE.CylinderGeometry( 0.2, 0.2, 2.6, 10 );
          const cylinderMz = new THREE.Mesh( cylinderGz, cylinderMatz );
          cylinderMz.rotation.x = Math.PI / 2;
            //de meshes in een groep plaatsen
          groep = new THREE.Group();
          groep.add(box1M,box2M,box3M,box4M,box5M,box6M,box7M,box8M,cylinderMx,cylinderMy,cylinderMz);
          scene.add(groep); //de groep komt in de scene die in animate gaat draaien
        }
          //de functie voor de muis en pijltjestoetsen controls
      function createControls() {
          const controls = new OrbitControls( camera , renderer.domElement);
          controls.listenToKeyEvents( window );
           //als default wordt er naar de pijltjestoetsen geluister
      }
 
      function createGui() {
          let gui = new GUI({width: 250});
          gui.add(data, 'X_rotatie', -0.2, 0.2);
          gui.add(data, 'Y_rotatie', -0.2, 0.2);
          gui.add(data, 'Z_rotatie', -0.2, 0.2);
          gui.add(data, 'alpha', 0.5,1).onChange( opacityChange );
          gui.add(data, 'kubuspositie', -2,2).onChange( boxPosChange );
          gui.add(data, 'start_stop_rotatie');
          gui.add(data, 'ruitjespap').onChange( gridOnOf);
          gui.add(data, 'wolken_achtergrond').onChange( createBackground);
          gui.open();
      }
 
       function gridOnOf(){
            if (ruitjespap) {scene.add(gridHelper), ruitjespap = false;}
            else {scene.remove(gridHelper), ruitjespap = true;}
         }
 
       function opacityChange() {
          boxMat1.opacity = data.alpha;  boxMat2.opacity = data.alpha;
          boxMat3.opacity = data.alpha;  boxMat4.opacity = data.alpha;
          boxMat5.opacity = data.alpha;  boxMat6.opacity = data.alpha;
          boxMat7.opacity = data.alpha;  boxMat8.opacity = data.alpha;
      }
 
       function boxPosChange() {
         box1M.position.set(-data.kubuspositie, -data.kubuspositie, -data.kubuspositie);
         box2M.position.set(-data.kubuspositie, -data.kubuspositie,  data.kubuspositie);
         box3M.position.set(-data.kubuspositie,  data.kubuspositie, -data.kubuspositie);
         box4M.position.set(-data.kubuspositie,  data.kubuspositie,  data.kubuspositie);
         box5M.position.set( data.kubuspositie, -data.kubuspositie, -data.kubuspositie);
         box6M.position.set( data.kubuspositie, -data.kubuspositie,  data.kubuspositie);
         box7M.position.set( data.kubuspositie,  data.kubuspositie, -data.kubuspositie);
         box8M.position.set( data.kubuspositie,  data.kubuspositie,  data.kubuspositie);
    }
 
    function render() {
         renderer.render( scene, camera );
      }
 
      function animate() {
        if (data.start_stop_rotatie) {
            scene.rotation.z += data.Z_rotatie;
            scene.rotation.x += data.X_rotatie;
            scene.rotation.y += data.Y_rotatie;
          }
    }
 
    function play() {
            renderer.setAnimationLoop( () => {
              animate();
              render();
            } );
          }
      </script>

  </body>
</html>