【问题标题】:SyntaxError when loading a gltf-file via Three.js in React在 React 中通过 Three.js 加载 gltf 文件时出现语法错误
【发布时间】:2020-09-27 06:30:20
【问题描述】:

我正在尝试在网站中实现 3D 模型。当我使用网站上的 3D 模型进行尝试时,一切正常,但是当我使用自己的模型尝试时,我收到此控制台错误:SyntaxError: "JSON.parse: unexpected character at line 1 column 1 of the JSON data "

我在 react 中编程并使用 three.js 将模型实现为 gltf 文件。

import ReactDOM from "react-dom";
import * as THREE from "three";
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader.js';
import { MTLLoader } from 'three/examples/jsm/loaders/MTLLoader.js';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';

class App extends Component {
    componentDidMount() {
        var scene = new THREE.Scene();

        var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );

        //Camera fixieren
        camera.position.set(0,12,20);

        var renderer = new THREE.WebGLRenderer();
        renderer.setClearColor("#e5e5e5");
        renderer.setSize(window.innerWidth, window.innerHeight);

        //automatische Fensteranpassung
        window.addEventListener('resize', () => {
            renderer.setSize( window.innerWidth, window.innerHeight );
            camera.aspect = window.innerWidth / window.innerHeight;

            camera.updateProjectionMatrix();
        })
        document.body.appendChild( renderer.domElement );
        // use ref as a mount point of the Three.js scene instead of the document.body
        this.mount.appendChild( renderer.domElement );



        var light = new THREE.AmbientLight(0xffffff);
        scene.add(light);

        var hlight = new THREE.PointLight(0xffffff, 1, 100);
        light.position.set(50,50,50);
        scene.add(hlight);

        var controls = new OrbitControls(camera, renderer.domElement);


        function frameArea(sizeToFitOnScreen, boxSize, boxCenter, camera) {
            const halfSizeToFitOnScreen = sizeToFitOnScreen * 0.5;
            const halfFovY = THREE.MathUtils.degToRad(camera.fov * .5);
            const distance = halfSizeToFitOnScreen / Math.tan(halfFovY);
            // compute a unit vector that points in the direction the camera is now
            // in the xz plane from the center of the box
            const direction = (new THREE.Vector3())
                .subVectors(camera.position, boxCenter)
                .multiply(new THREE.Vector3(1, 0, 1))
                .normalize();

            // move the camera to a position distance units way from the center
            // in whatever direction the camera was from the center already
            camera.position.copy(direction.multiplyScalar(distance).add(boxCenter));

            // pick some near and far values for the frustum that
            // will contain the box.
            camera.near = boxSize / 100;
            camera.far = boxSize * 100;

            camera.updateProjectionMatrix();

            // point the camera to look at the center of the box
            camera.lookAt(boxCenter.x, boxCenter.y, boxCenter.z);
        }


        //GLTFLoader
        const gltfLoader = new GLTFLoader();
        gltfLoader.load('prototype/public/test.gltf', (gltf) => {
            const root = gltf.scene;
            scene.add(root);

            // compute the box that contains all the stuff
            // from root and below
            const box = new THREE.Box3().setFromObject(root);

            const boxSize = box.getSize(new THREE.Vector3()).length();
            const boxCenter = box.getCenter(new THREE.Vector3());

            // set the camera to frame the box
            frameArea(boxSize * 0.5, boxSize, boxCenter, camera);

            // update the Trackball controls to handle the new size
            controls.maxDistance = boxSize * 10;
            controls.target.copy(boxCenter);
            controls.update();
        });





        //Objektloader der net funzt -- leere Seite wird angezeigt
        /*
        loader.load('public/test.obj', function ( obj ){

            var box = new THREE.Box3().setFromObject(obj);
            var center = new THREE.Vector3();
            box.getCenter(center);
            obj.position.sub(center);

            scene.add(obj);
        })*/


        //Objektloader der net funzt -- leere Seite wird angezeigt
        /*var mtlLoader = new MTLLoader();
        mtlLoader.load("/public/TechnicLEGO_CAR_1.mtl", function(materials){

            materials.preload();

            var objLoader = new OBJLoader();
            objLoader.setMaterials(materials);

            objLoader.load("/public/TechnicLEGO_CAR_1.obj", function(mesh){
                const ab = new THREE.Box3().setFromObject(mesh);
                const center = ab.getCenter( new THREE.Vector3());

                mesh.position.x += (mesh.position.x - center.x);
                mesh.position.y += (mesh.position.y - center.y);
                mesh.position.z += (mesh.position.z - center.z);

                scene.add(mesh);


            });
        });*/


        //Würfel
        /*
        var geometry = new THREE.BoxGeometry( 1, 1, 1 );
        //var material = new THREE.MeshBasicMaterial( { color: 0xff00ff } );
        var material = new THREE.MeshNormalMaterial();
        var cube = new THREE.Mesh( geometry, material );
        scene.add( cube );*/


        var animate = function () {
            requestAnimationFrame( animate );
            //cube.rotation.x += 0.01;
            //cube.rotation.y += 0.01;
            renderer.render( scene, camera );
        };
        animate();
    }


    //muss so bleiben, da rendern sonst nix wird
    render() {
        return (
            <div ref={ref => (this.mount = ref)} />
        )
    }
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

这是我要加载的 gltf:https://drive.google.com/drive/folders/1mZhyYRBmN8FVac9d3c2T1dN1TpUXPM5Q?usp=sharing

如您所见,我也尝试使用 .obj-Files,但这也不起作用。

希望 smb 可以帮助我:)

【问题讨论】:

    标签: reactjs three.js gltf


    【解决方案1】:

    您的文件实际上可以在 three.js editor 中加载。所以这个问题很可能不是GLTFLoader 的问题,而是您的网络服务器的问题。错误信息

    JSON.parse:JSON 数据的第 1 行第 1 列出现意外字符

    如果glTF 清单文件未作为 JSON 提供,通常会弹出。我建议您在从后端请求 glTF 资产时使用浏览器的开发者工具来确保正确的 HTTP 响应。

    【讨论】:

    • 我在网络编程方面不是那么好,那我应该怎么做呢?什么是正确的 HTTP 响应?
    • 也许最好花点时间熟悉浏览器的开发工具。这将允许您自己调查此类问题。在three.js forum阅读以下相关主题也可能会有所帮助。
    • 谢谢,但正如我所说,我是网络开发方面的菜鸟,这个链接对我没有帮助。如果尝试从在线存储库加载文件并且它可以工作,但为什么我的本地文件不能工作?
    【解决方案2】:

    我遇到了类似的问题,看起来 parcel 没有将静态文件复制到 dist 文件夹。您可以安装parcel-plugin-static-files-copy 并按照此链接parcel-plugin-static-files-copy 中该软件包的自述文件中的指导声明静态文件。然后文件将成功加载

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-23
      • 2018-10-09
      • 2018-10-27
      • 1970-01-01
      • 1970-01-01
      • 2019-02-16
      • 2021-11-10
      • 1970-01-01
      相关资源
      最近更新 更多