简体   繁体   中英

Three.js “webgl-template.html:69 Uncaught TypeError: Cannot read property 'domElement' of undefined" error

I'm trying to run this code I downloaded from https://www.benzedrine.ch/3D-ODRPP.html

<!DOCTYPE html>
<!-- saved from url=(0056)https://www.benzedrine.ch/vistaprint/webgl-template.html -->
<html>

<head>
    <meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
    <style>
        body {
            margin: 0px;
            background-color: #000000;
            overflow: hidden;
        }

        canvas {
            position: fixed;
            top: 0;
            left: 0;
        }
    </style>
</head>

<body>

    <div id="container"></div>
    <div id="info">info</div>

    <script src="/js/three.min.js"></script>
    <script src="/js/TrackballControls.js"></script>
    <script type="x-shader/x-vertex" id="vertexShader">
            varying vec3 vWorldPosition;
            void main() {
                vec4 worldPosition = modelMatrix * vec4( position, 1.0 );
                vWorldPosition = worldPosition.xyz;
                gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
            }
        </script>
    <script type="x-shader/x-fragment" id="fragmentShader">
            uniform vec3 topColor;
            uniform vec3 bottomColor;
            uniform float offset;
            uniform float exponent;
            varying vec3 vWorldPosition;
            void main() {
                float h = normalize( vWorldPosition + offset ).y;
                gl_FragColor = vec4( mix( bottomColor, topColor, max( pow( max( h , 0.0), exponent ), 0.0 ) ), 1.0 );
            }
        </script>
    <script>

        var container, camera, controls, scene, renderer;
        var mesh;

        function animate() {

            requestAnimationFrame(animate);
            controls.update();

        }

        function init() {

            camera = new THREE.PerspectiveCamera(30, window.innerWidth / window.innerHeight, 1, 5000);
            camera.position.set(411, 218, 559);

            /*
                            controls = new THREE.OrbitControls( camera );
                            controls.damping = 1.0;
            */
            controls = new THREE.TrackballControls(camera, renderer.domElement);
            controls.rotateSpeed = 1.0;
            controls.zoomSpeed = 1.2;
            controls.panSpeed = 0.8;
            controls.noZoom = false;
            controls.noPan = false;
            controls.staticMoving = true;
            controls.dynamicDampingFactor = 0.15;
            controls.addEventListener('change', render);

            scene = new THREE.Scene();
            scene.fog = new THREE.Fog(0xffffff, 1, 5000);
            scene.fog.color.setHSL(0.6, 0, 1);

            var geometry;
            var material = new THREE.MeshLambertMaterial({ color: 0x1ec876 });

            //XXX

            var hemiLight = new THREE.HemisphereLight(0xffffff, 0xffffff, 0.6);
            hemiLight.color.setHSL(0.6, 1, 0.6);
            hemiLight.groundColor.setHSL(0.095, 1, 0.75);
            hemiLight.position.set(0, 500, 0);
            scene.add(hemiLight);

            var dirLight = new THREE.DirectionalLight(0xffffff, 1);
            dirLight.color.setHSL(0.1, 1, 0.95);
            dirLight.position.set(-1, 1.75, 1);
            dirLight.position.multiplyScalar(50);
            scene.add(dirLight);

            var groundGeo = new THREE.PlaneBufferGeometry(10000, 10000);
            var groundMat = new THREE.MeshPhongMaterial({ ambient: 0xffffff, color: 0xffffff, specular: 0x050505 });
            groundMat.color.setHSL(0.095, 1, 0.75);

            var ground = new THREE.Mesh(groundGeo, groundMat);
            ground.rotation.x = -Math.PI / 2;
            ground.position.y = -0.1;
            scene.add(ground);

            var vertexShader = document.getElementById('vertexShader').textContent;
            var fragmentShader = document.getElementById('fragmentShader').textContent;
            var uniforms = {
                topColor: { type: "c", value: new THREE.Color(0x0077ff) },
                bottomColor: { type: "c", value: new THREE.Color(0xffffff) },
                offset: { type: "f", value: 33 },
                exponent: { type: "f", value: 0.6 }
            }
            uniforms.topColor.value.copy(hemiLight.color);

            scene.fog.color.copy(uniforms.bottomColor.value);

            var skyGeo = new THREE.SphereGeometry(4000, 32, 15);
            var skyMat = new THREE.ShaderMaterial({ vertexShader: vertexShader, fragmentShader: fragmentShader, uniforms: uniforms, side: THREE.BackSide });

            var sky = new THREE.Mesh(skyGeo, skyMat);
            scene.add(sky);

            renderer = new THREE.WebGLRenderer({ antialias: true });
            renderer.setSize(window.innerWidth, window.innerHeight);
            renderer.setClearColor(scene.fog.color, 1);

            container = document.getElementById('container');
            container.appendChild(renderer.domElement);

            window.addEventListener('resize', onWindowResize, false);
            animate();

        }

        function onWindowResize() {

            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();

            renderer.setSize(window.innerWidth, window.innerHeight);
            render();

        }

        function render() {

            renderer.render(scene, camera);
        }

        init();
        render();
    </script>

</body>

</html>

And I got this error

webgl-template.html:69 Uncaught TypeError: Cannot read property 'domElement' of undefined at init (webgl-template.html:69) at webgl-template.html:154

this is the code in line 69

controls = new THREE.TrackballControls(camera, renderer.domElement);

Please help me. Thank you all in advance!

The reason it doesn't work is you are using the variables before you actually initialize them, so you get an error that says can not read property of undefined . In javascript the variables will have a value of undefined if you don't initialize them.

var foo; 
foo.bar; // You can't do this because foo is undefined

In your example you have to do initialization of the renderer variable before you use it. And since you use the variable scene , you also have to initialize it.

So that's the working code:

function init() {

    scene = new THREE.Scene();
    scene.fog = new THREE.Fog(0xffffff, 1, 5000);
    scene.fog.color.setHSL(0.6, 0, 1);

    renderer = new THREE.WebGLRenderer({ antialias: true });
    renderer.setSize(window.innerWidth, window.innerHeight);
    renderer.setClearColor(scene.fog.color, 1);

    camera = new THREE.PerspectiveCamera(30, window.innerWidth / window.innerHeight, 1, 5000);
    camera.position.set(411, 218, 559);

        
    controls = new THREE.TrackballControls(camera, renderer.domElement);
    ...

Remember if you don't have THREE.js locally you have to download it or use the url for the libraries. Like this:

<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r71/three.min.js"></script>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM