【问题标题】:Cannot read property 'rotation' of undefined - Three.js无法读取未定义的属性“旋转”-Three.js
【发布时间】:2017-01-07 13:57:00
【问题描述】:

代码正在执行它应该做的事情,但我在控制台中收到 2 个错误:“无法读取未定义的属性‘旋转’”。由于这两个变量被定义为全局变量,因此对为什么会引发错误感到困惑。我错过了什么吗? (使用 TextureLoader(),因为 ImageUtils.loadTexture() 已被弃用)。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Three.js</title>
    <style>
        body{
            margin: 0;
            width: 100%;
            height: 100%;
            overflow: hidden;
        }
    </style>
</head>
<body>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r80/three.js"></script>
    <script src="js/OrbitControls.js"></script>
    <script>

        //GLOBAL VARIABLES
        var scene, camera, renderer, cameraControl, earthMesh, cloudMesh;

        function init(){

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

            //renderer
            renderer = new THREE.WebGLRenderer();
            renderer.setSize(window.innerWidth, window.innerHeight);
            renderer.setClearColor('#000', 1.0);
            renderer.shadowMap.enabled = true;

            //camera
            camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 1, 1000);
            camera.position.x = 35;
            camera.position.y = 36;
            camera.position.z = 33;
            camera.lookAt(scene.position);

            //earth mesh
            var sphereGeometry = new THREE.SphereGeometry(10, 60, 60);
            var sphereMaterial;
            var sphereMaterialLoader = new THREE.TextureLoader();
            sphereMaterialLoader.load(
                'images/earth.jpg',
                function(earthImage){
                    sphereMaterial = new THREE.MeshBasicMaterial({
                        map: earthImage
                    });
                    earthMesh = new THREE.Mesh(sphereGeometry, sphereMaterial);
                    earthMesh.name = 'earth';
                    scene.add(earthMesh);
                    render();   
                }
            );

            //cloud mesh
            var cloudGeometry = new THREE.SphereGeometry(sphereGeometry.parameters.radius * 1.02, 
                sphereGeometry.parameters.widthSegments, sphereGeometry.parameters.heightSegments);
            var cloudMaterial;
            var cloudMaterialLoader = new THREE.TextureLoader();
            cloudMaterialLoader.load(
                'images/clouds.png',
                function(cloudImage){
                    cloudMaterial = new THREE.MeshBasicMaterial({
                        map: cloudImage
                    });
                    cloudMaterial.transparent = true;
                    cloudMesh = new THREE.Mesh(cloudGeometry, cloudMaterial);
                    cloudMesh.name = 'cloud';
                    scene.add(cloudMesh);
                    render();
                }
            );

            //camera control
            cameraControl = new THREE.OrbitControls(camera);

            document.body.appendChild(renderer.domElement);
            render();
        }

        function render(){
            renderer.render(scene, camera);
            earthMesh.rotation.y += -0.001;
            cloudMesh.rotation.y += 0.0005;
            cameraControl.update();
            requestAnimationFrame(render);
        }

        //initialize scene/render
        window.onload = init;

    </script>
</body>
</html>

【问题讨论】:

    标签: javascript three.js


    【解决方案1】:

    看起来earthMesh 正在你的 cloudMaterialLoader.load() 函数中异步初始化——你需要小心,因为当你第一次调用 render() 时 earthMesh 可能尚未加载,在这种情况下它将仍然是未定义的。

    解决这个问题的一些方法是在加载 earthMesh 之前不调用 render(),或者检查是否在 render() 调用中加载了 earthMesh,或者任何你想像的事情。

    【讨论】:

    • 在第一次调用渲染函数之前,有没有办法检查所有纹理是否已经加载?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-06-16
    • 1970-01-01
    • 2023-03-19
    • 1970-01-01
    • 2016-09-12
    • 2018-04-05
    • 2013-01-04
    相关资源
    最近更新 更多