kramann.info
© Guido Kramann

Login: Passwort:










kramann.info
© Guido Kramann

Login: Passwort:




Dreidimensionale Animationen mit Hilfe der Library three.js

(EN google-translate)

(PL google-translate)

Es existieren verschiedene Libraries, die die Fähifkeiten von Javascript um die Möglichkeit 3D-Objekte darzustellen und zu animieren erweitern.

Exemplarisch soll hier die Library "Three" verwendet werden, da diese mit Hilfe der Methoden zu Generierung von Primitiven relativ einfach benutzt werden kann und auch eine gute Dokumentation (API) bietet.

Siehe insbesondere: https://threejs.org/

Die komplette Library und die Dokumentation lassen sich über den Download offline verfügbar machen:

Download von three.js: https://github.com/mrdoob/three.js/archive/master.zip

Zur Motivation: Einige interessante Beispiele von threejs.org

Die nachfolgenden Beispiele stehen auch alle im Ordner examples in master.zip zur Verfügung.

Alle Beispiele: https://threejs.org/examples/index.html
Erde: canvas_geometry_earth.html
Wüfel in 3D-Raum einfügen: canvas_interactive_voxelpainter.html
Kugelhaufen: webgl_postprocessing_msaa_unbiased.html
Molekülmodelle: css3d_molecules.html
Periodensystem anordnen: css3d_periodictable.html
Innenraum als Hintergrund mit spiegelnden Objekten darin: webgl_materials_cubemap_dynamic2.html
Meer: webgl_shaders_ocean.html
Seifenblasen: webgl_materials_shaders_fresnel.html
Vogelschwärme: canvas_geometry_birds.html
Stereoskopische Darstellung, z.B. zur Benutzeung mit einer VR-Brille, in die ein Smartphone eingesetzt wird: webgl_effects_stereo.html

Text darstellen:

Text1: webgl_geometry_text.html
Text2: webgl_geometry_text_earcut.html
Text3: webgl_geometry_text_pnltri.html

Stimmung / Wetter / Schatten

Schatten: webgl_shadowmap.html
Nebel: webgl_postprocessing_godrays.html

Getting Started

Die nachfolgenden Beispiele funktionieren unter der Voraussetzung, dass unterhalb von htdocs auf dem (XAMPP-) Server der Inhalt des Ordners ..../three.js-master in techne/three abgelegt wurde.

Eine Einführung in Beispielen

Beispiel 1:


<html>
    <head lang="de">
        <meta charset="iso-8859-1">
        <script src="http://localhost/techne/three/build/three.js"></script>
        <script src="http://localhost/techne/three/examples/js/renderers/Projector.js"></script>
        <script src="http://localhost/techne/three/examples/js/renderers/CanvasRenderer.js"></script>
        <script src="http://localhost/techne/three/examples/js/libs/stats.min.js"></script>
        <script language:javascript>

        function KUBUSANIMATION()
        {
                        const BREITE = 400;
                        const HOEHE  = 300;

                        var kubus;

                        var renderer,scene,camera;

                        function erzeugeKubus()
                        {
				var geometry = new THREE.BoxGeometry( 200, 200, 200 );

				for ( var i = 0; i < geometry.faces.length; i += 2 ) {

					var hex = Math.random() * 0xffffff;
					geometry.faces[ i ].color.setHex( hex );
					geometry.faces[ i + 1 ].color.setHex( hex );

				}

				var material = new THREE.MeshBasicMaterial( { vertexColors: THREE.FaceColors, overdraw: 0.5 } );

				var cube = new THREE.Mesh( geometry, material );
				cube.position.y = 150;
                                return cube;
                        }

                        function erzeugeSceneInID(ID)
                        {
				camera = new THREE.PerspectiveCamera( 70, BREITE / HOEHE, 1, 1000 );
				camera.position.y = 150;
				camera.position.z = 500;

				scene = new THREE.Scene();

				renderer = new THREE.CanvasRenderer();
				renderer.setClearColor( 0xf0f0f0 );
				renderer.setPixelRatio( window.devicePixelRatio );
				renderer.setSize( BREITE, HOEHE );

				document.getElementById(ID).appendChild( renderer.domElement );

                                return scene;
                        }

			this.init = function() 
                        {
                                scene = erzeugeSceneInID("container");

                                kubus = erzeugeKubus();
				scene.add( kubus );


                                animate();
			}

			function animate() 
                        {
				requestAnimationFrame( animate );
				render();
			}

			function render() 
                        {
                                kubus.rotation.y+=0.02;
				renderer.render( scene, camera );
			}
        }       

        var kubusanimation = new KUBUSANIMATION();

        </script>
    </head>
    <body>
        <input style="width:200px" type="button" id="snap" value="malen" onclick="javascript:kubusanimation.init()"/>
        <div id="container"></div>
    </body>
</html>

Code 0-1: Quelltext zu obigem Beispiel.

Beispiel 2:

<html>
    <head lang="de">
        <meta charset="iso-8859-1">
        <script src="http://localhost/techne/three/build/three.js"></script>
        <script src="http://localhost/techne/three/examples/js/renderers/Projector.js"></script>
        <script src="http://localhost/techne/three/examples/js/renderers/CanvasRenderer.js"></script>
        <script src="http://localhost/techne/three/examples/js/libs/stats.min.js"></script>
        <script language:javascript>

            const SPEED = 10;

            let HEXA = ["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"];

            var muenzwurf_x = 0.901;

            function muenzwurf()
            {
                muenzwurf_x = 3.92*muenzwurf_x*(1.0-muenzwurf_x);
                return (Math.round(muenzwurf_x*1000.0))%2;
            }

            function zufall(max)
            {
                var x = 0;
                var y = 0;
                var z = 0;
                for(var i=0;i<1000;i++)
                {
                    x+=muenzwurf();
                    y+=muenzwurf();
                    z+=muenzwurf();
                }
                return (x+y*103+z*911)%max;
            }

            //Farbbeispiele: http://html-color-codes.com/rgb.html
            function farbe(r,g,b)
            {
                return "#"+HEXA[Math.floor(r/16)]+HEXA[r%16]+HEXA[Math.floor(g/16)]+HEXA[g%16]+HEXA[Math.floor(b/16)]+HEXA[b%16];         
            }


        function KUGELANIMATION()
        {
                        const BREITE = 400;
                        const HOEHE  = 300;

                        var kugel = new Array();
                        var kugelxyz = new Array();

                        var renderer,scene,camera;


                        var xz    = [0,0];
                        var xzrot = [0,0];
                        var phi   = 0.0;

                        function dreheUmYachse(xz,phi,xzrot)
                        {
                            xzrot[0] =  Math.cos(phi)*xz[0] + Math.sin(phi)*xz[1];
                            xzrot[1] = -Math.sin(phi)*xz[0] + Math.cos(phi)*xz[1];
                        }
                        

                        function erzeugeSphere(RADIUS,ROT,GRUEN,BLAU,X,Y,Z,rotX,rotY,rotZ)
                        {
				var geometry = new THREE.SphereGeometry( RADIUS, 32, 32 );
                                var hex = Math.random() * 0xffffff;
				for ( var i = 0; i < geometry.faces.length; i += 2 ) {

					geometry.faces[ i ].color.setHex( hex );
					geometry.faces[ i + 1 ].color.setHex( hex );

				}


				var material = new THREE.MeshBasicMaterial( { vertexColors: THREE.FaceColors, overdraw: 0.5 } );

				var sphere = new THREE.Mesh( geometry, material );
                                sphere.position.x=X;
                                sphere.position.y=Y;
                                sphere.position.z=Z;

                                sphere.rotation.x=rotX;
                                sphere.rotation.y=rotY;
                                sphere.rotation.z=rotZ;

                                return sphere;
                        }

                        function erzeugeSceneInID(ID)
                        {
				camera = new THREE.PerspectiveCamera( 70, BREITE / HOEHE, 1, 1000 );
				camera.position.y = 150;
				camera.position.z = 500;

				scene = new THREE.Scene();

				renderer = new THREE.CanvasRenderer();
				renderer.setClearColor( 0xf0f0f0 );
				renderer.setPixelRatio( window.devicePixelRatio );
				renderer.setSize( BREITE, HOEHE );

				document.getElementById(ID).appendChild( renderer.domElement );

                                return scene;
                        }

                        function erzeugeZufallskugel()
                        {
                            var r = 10+zufall(20);

                            var rot   = zufall(256);
                            var gruen = zufall(256);
                            var blau  = zufall(256);

                            return erzeugeSphere(r,rot,gruen,blau,0,0,0,0,0,0);
                        }

			this.init = function() 
                        {
                                scene = erzeugeSceneInID("container_kugel");


                                for(var i=0;i<10;i++)
                                {
                                    var kneu = erzeugeZufallskugel();
                                    scene.add( kneu );
                                    kugel[kugel.length]=kneu;

                                    var xyz = new Array(0,0,0);
                                    xyz[0] = zufall(200)-100;
                                    xyz[1] = zufall(200)-100 + 200;
                                    xyz[2] = zufall(200)-100;
                                    kugelxyz[kugelxyz.length] = xyz;
                                }
                                animate();
			}

			function animate() 
                        {
				requestAnimationFrame( animate );
				render();
			}

			function render() 
                        {
 
                            for(var i=0;i<5;i++)
                            {
                                var nr = zufall(kugel.length);      
                                var aktion = zufall(6);
                                var xyz = kugelxyz[nr];
                                if(aktion==0)
                                    xyz[0]+=SPEED;
                                else if(aktion==1)
                                    xyz[0]-=SPEED;
                                else if(aktion==2)
                                    xyz[1]+=SPEED;
                                else if(aktion==3)
                                    xyz[1]-=SPEED;
                                else if(aktion==4)
                                    xyz[2]+=SPEED;
                                else //if(aktion==5)
                                    xyz[2]-=SPEED;
                            }

                                for(var i=0;i<kugel.length;i++)
                                {
                                    xz[0] = kugelxyz[i][0];  
                                    xz[1] = kugelxyz[i][2];  

                                    dreheUmYachse(xz,phi,xzrot);

                                    kugel[i].position.x = xzrot[0];
                                    kugel[i].position.y = kugelxyz[i][1];
                                    kugel[i].position.z = xzrot[1];
                                }
                                
				renderer.render( scene, camera );

                                phi+=0.03;
			}
        }       

        var kugelanimation = new KUGELANIMATION();

        </script>
    </head>
    <body>
        <input style="width:200px" type="button" id="snap" value="malen" onclick="javascript:kugelanimation.init()"/>
        <div id="container_kugel"></div>
    </body>
</html>

Code 0-1: Quelltext zu obigem Beispiel.

Reengineering

Zur Einarbeitung in three.js wurde das Beispiel canvas_geometry_cube.html so lange vereinfacht und umgeschrieben, bis der entstandene Code sich in dem Autor vertrauten Strukturen darbot.

reengineering.zip - Alle Varianten, die im Verlauf dieser Arbeit entstanden sind.