【问题标题】:How to import a json object with objloader (three js) using react and express js如何使用react和express js通过objloader(三个js)导入json对象
【发布时间】:2019-03-14 20:49:38
【问题描述】:

我正在尝试使用 threejs OBJLoader 将大型 .json 模型导入我的项目, 但似乎我的服务器正在用我的主 HTML 文件替换 .json 模型,当它尝试解析并给出错误时注意到:

JSON.parse 中位置 0 处的 JSON 中的意外标记

尝试在我的 js 文件中使用简单的 require() 调用模型,并显示:

TypeError: url.lastIndexOf 不是函数

还尝试在所需模型中使用 stringify 并显示:

加载资源失败:net::ERR_CONNECTION_RESET

threejs 错误对象:

bubbles: false
cancelBubble: false
cancelable: false
composed: false
currentTarget: XMLHttpRequest {onreadystatechange: null, readyState: 4, timeout: 0, withCredentials: false, upload: XMLHttpRequestUpload, …}
defaultPrevented: false
eventPhase: 0
isTrusted: true
lengthComputable: false
loaded: 0
path: []
returnValue: true
srcElement: XMLHttpRequest {onreadystatechange: null, readyState: 4, timeout: 0, withCredentials: false, upload: XMLHttpRequestUpload, …}
target: XMLHttpRequest {onreadystatechange: null, readyState: 4, timeout: 0, withCredentials: false, upload: XMLHttpRequestUpload, …}
timeStamp: 1096.5999999898486
total: 0
type: "error"
__proto__: ProgressEvent

这是我试图加载模型的 js 文件

const THREE = require ('three');
const obj1 = require('../img/orig.json');
const orig = JSON.stringify(obj1);


export default canvas =>{
    const info = document.getElementById('three_origami');
    let camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 10000 ),
    scene = new THREE.Scene(), renderer=new THREE.WebGLRenderer( { antialias: true } );
    let group=new THREE.MeshNormalMaterial();
    let mouseX = 0, mouseY = 0;
    let windowHalfX = window.innerWidth / 2;
    let windowHalfY = window.innerHeight / 2;
    init();
    animate();
    function init() {
        camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 10000 );
        camera.position.z = 40;
        scene = new THREE.Scene();
        scene.background = new THREE.Color( 0xffffff );
        scene.fog = new THREE.Fog( 0xfffff, 1, 10000 );

        group = new THREE.Group();

        const objLoader = new THREE.ObjectLoader();


        objLoader.load(orig, (obj) => {
                for ( let i = 0; i <= 300; i ++ ) {
                    let mesh = new THREE.Mesh( obj.geometry, obj.material );
                    mesh.position.x = Math.random() * 2000 - 1000;
                    mesh.position.y = Math.random() * 2000 - 1000;
                    mesh.position.z = Math.random() * 2000 - 1000;
                    mesh.rotation.x = Math.random() * 2 * Math.PI;
                    mesh.rotation.y = Math.random() * 2 * Math.PI;
                    mesh.matrixAutoUpdate = false;
                    mesh.updateMatrix();
                    group.add(mesh);
                }
            },
            null,
            (err) => {
              console.error('Error', err);
            });

        scene.add( group );
        //
        renderer.setPixelRatio( window.devicePixelRatio );
        renderer.setSize( window.innerWidth, window.innerHeight );
        info.appendChild( renderer.domElement );
        //
        //
        document.addEventListener( 'mousemove', onDocumentMouseMove, false );
        //
        window.addEventListener( 'resize', onWindowResize, false );
    }
    function onWindowResize() {
        windowHalfX = window.innerWidth / 2;
        windowHalfY = window.innerHeight / 2;
        camera.aspect = window.innerWidth / window.innerHeight;
        camera.updateProjectionMatrix();
        renderer.setSize( window.innerWidth, window.innerHeight );
    }
    function onDocumentMouseMove( event ) {
        mouseX = ( event.clientX - windowHalfX ) * 10;
        mouseY = ( event.clientY - windowHalfY ) * 10;
    }
    //
    function animate() {
        requestAnimationFrame( animate );
        render();
    }
    function render() {
        let time = Date.now() * 0.001;
        let rx = Math.sin( time * 0.7 ) * 0.5,
            ry = Math.sin( time * 0.3 ) * 0.5,
            rz = Math.sin( time * 0.2 ) * 0.5;
        camera.position.x += ( mouseX - camera.position.x ) * 0.05;
        camera.position.y += ( - mouseY - camera.position.y ) * 0.05;
        camera.lookAt( scene.position );
        group.rotation.x = rx;
        group.rotation.y = ry;
        group.rotation.z = rz;
        renderer.render( scene, camera );
    }
}

这是我存储库中的 .json 文件:portfolio-final/orig.json

还有我的package.json

{
  "name": "portfolio-final",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@babel/core": "7.1.0",
    "@svgr/webpack": "2.4.1",
    "babel-core": "7.0.0-bridge.0",
    "babel-eslint": "9.0.0",
    "babel-jest": "23.6.0",
    "babel-loader": "8.0.4",
    "babel-plugin-named-asset-import": "^0.2.2",
    "babel-preset-react-app": "^5.0.3",
    "bfj": "6.1.1",
    "case-sensitive-paths-webpack-plugin": "2.1.2",
    "chalk": "2.4.1",
    "css-loader": "1.0.0",
    "dotenv": "6.0.0",
    "dotenv-expand": "4.2.0",
    "eslint": "5.6.0",
    "eslint-config-react-app": "^3.0.3",
    "eslint-loader": "2.1.1",
    "eslint-plugin-flowtype": "2.50.1",
    "eslint-plugin-import": "2.14.0",
    "eslint-plugin-jsx-a11y": "6.1.1",
    "eslint-plugin-react": "7.11.1",
    "express": "^4.16.3",
    "file-loader": "2.0.0",
    "fs-extra": "7.0.0",
    "gsap": "^2.0.2",
    "html-webpack-plugin": "4.0.0-alpha.2",
    "identity-obj-proxy": "3.0.0",
    "jest": "23.6.0",
    "jest-pnp-resolver": "1.0.1",
    "jest-resolve": "23.6.0",
    "mini-css-extract-plugin": "0.4.3",
    "node-sass": "^4.9.3",
    "optimize-css-assets-webpack-plugin": "5.0.1",
    "pnp-webpack-plugin": "1.1.0",
    "postcss-flexbugs-fixes": "4.1.0",
    "postcss-loader": "3.0.0",
    "postcss-preset-env": "6.0.6",
    "postcss-safe-parser": "4.0.1",
    "react": "^16.5.2",
    "react-app-polyfill": "^0.1.3",
    "react-dev-utils": "^6.0.4",
    "react-dom": "^16.5.2",
    "react-redux": "^5.0.7",
    "react-router-dom": "^4.3.1",
    "react-router-redux": "^4.0.8",
    "redux": "^4.0.0",
    "resolve": "1.8.1",
    "sass-loader": "^7.1.0",
    "style-loader": "0.23.0",
    "terser-webpack-plugin": "1.1.0",
    "three": "^0.97.0",
    "url-loader": "1.1.1",
    "webpack": "4.19.1",
    "webpack-dev-server": "3.1.9",
    "webpack-manifest-plugin": "2.0.4",
    "workbox-webpack-plugin": "3.6.2",
    "xhr": "^2.5.0"
  },
  "scripts": {
    "start": "node server/server.js",
    "start-dev": "node scripts/start.js",
    "build": "node scripts/build.js",
    "test": "node scripts/test.js",
    "heroku-postbuild": "yarn run build"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": [
    ">0.2%",
    "not dead",
    "not ie <= 11",
    "not op_mini all"
  ],
  "jest": {
    "collectCoverageFrom": [
      "src/**/*.{js,jsx}"
    ],
    "resolver": "jest-pnp-resolver",
    "setupFiles": [
      "react-app-polyfill/jsdom"
    ],
    "testMatch": [
      "<rootDir>/src/**/__tests__/**/*.{js,jsx}",
      "<rootDir>/src/**/?(*.)(spec|test).{js,jsx}"
    ],
    "testEnvironment": "jsdom",
    "testURL": "http://localhost",
    "transform": {
      "^.+\\.(js|jsx)$": "<rootDir>/node_modules/babel-jest",
      "^.+\\.css$": "<rootDir>/config/jest/cssTransform.js",
      "^(?!.*\\.(js|jsx|css|json)$)": "<rootDir>/config/jest/fileTransform.js"
    },
    "transformIgnorePatterns": [
      "[/\\\\]node_modules[/\\\\].+\\.(js|jsx)$",
      "^.+\\.module\\.(css|sass|scss)$"
    ],
    "moduleNameMapper": {
      "^react-native$": "react-native-web",
      "^.+\\.module\\.(css|sass|scss)$": "identity-obj-proxy"
    },
    "moduleFileExtensions": [
      "web.js",
      "js",
      "json",
      "web.jsx",
      "jsx",
      "node",
      "xhr"
    ]
  },
  "babel": {
    "presets": [
      "react-app"
    ]
  }
}

非常感谢!

【问题讨论】:

    标签: node.js json reactjs express three.js


    【解决方案1】:

    编辑:您收到 Unexpected token 的原因是您的服务器找不到该文件,因此它返回 404 页面。 Three.js 正在尝试将网站解析为 JSON 文件。

    默认情况下,当您需要 JSON 文件时,Webpack 在构建时将其包含在包中。在运行时它只会返回 JSON 对象而不是文件的路径,因为没有 JSON 文件,它与所有其他 Javascript 捆绑在一起。

    所以基本上require ('../img/orig.json'); 返回 JSON 对象。

    JSON.stringify 将 JSON 对象转换为字符串,这不是我们想要的。

    您可以使 Webpack 不将 JSON 文件包含到包中,将文件放在目标文件夹中并要求它返回路径,使用 file-loader。但是有一个更简单的方法。

    ObjectLoader.load 获取 JSON 文件的 URL 但是 ObjectLoader.parse 获取我们正在寻找的 JSON 对象

    您可以使用require ('../img/orig.json'); 捆绑json,然后使用ObjectLoader.parse 解析json:

    const THREE = require ('three');
    const orig = require ('../img/orig.json');
    
    
    
    export default canvas =>{
        const info = document.getElementById('three_origami');
        let camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 10000 ),
        scene = new THREE.Scene(), renderer=new THREE.WebGLRenderer( { antialias: true } );
        let group=new THREE.MeshNormalMaterial();
        let mouseX = 0, mouseY = 0;
        let windowHalfX = window.innerWidth / 2;
        let windowHalfY = window.innerHeight / 2;
                init();
                animate();
                function init() {
                    camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 10000 );
                    camera.position.z = 40;
                    scene = new THREE.Scene();
                    scene.background = new THREE.Color( 0xffffff );
                    scene.fog = new THREE.Fog( 0xfffff, 1, 10000 );
    
                    group = new THREE.Group();
    
    
                        const objLoader = new THREE.ObjectLoader();
    
    
                        objLoader.parse(orig, (obj) => {
                            for ( let i = 0; i <= 300; i ++ ) {
                                let mesh = new THREE.Mesh( obj.geometry, obj.material );
                                mesh.position.x = Math.random() * 2000 - 1000;
                                mesh.position.y = Math.random() * 2000 - 1000;
                                mesh.position.z = Math.random() * 2000 - 1000;
                                mesh.rotation.x = Math.random() * 2 * Math.PI;
                                mesh.rotation.y = Math.random() * 2 * Math.PI;
                                mesh.matrixAutoUpdate = false;
                                mesh.updateMatrix();
                                group.add(mesh);
                            }
                        });
    
                    scene.add( group );
                    //
                    renderer.setPixelRatio( window.devicePixelRatio );
                    renderer.setSize( window.innerWidth, window.innerHeight );
                    info.appendChild( renderer.domElement );
                    //
                    //
                    document.addEventListener( 'mousemove', onDocumentMouseMove, false );
                    //
                    window.addEventListener( 'resize', onWindowResize, false );
                }
                function onWindowResize() {
                    windowHalfX = window.innerWidth / 2;
                    windowHalfY = window.innerHeight / 2;
                    camera.aspect = window.innerWidth / window.innerHeight;
                    camera.updateProjectionMatrix();
                    renderer.setSize( window.innerWidth, window.innerHeight );
                }
                function onDocumentMouseMove( event ) {
                    mouseX = ( event.clientX - windowHalfX ) * 10;
                    mouseY = ( event.clientY - windowHalfY ) * 10;
                }
                //
                function animate() {
                    requestAnimationFrame( animate );
                    render();
                }
                function render() {
                    let time = Date.now() * 0.001;
                    let rx = Math.sin( time * 0.7 ) * 0.5,
                        ry = Math.sin( time * 0.3 ) * 0.5,
                        rz = Math.sin( time * 0.2 ) * 0.5;
                    camera.position.x += ( mouseX - camera.position.x ) * 0.05;
                    camera.position.y += ( - mouseY - camera.position.y ) * 0.05;
                    camera.lookAt( scene.position );
                    group.rotation.x = rx;
                    group.rotation.y = ry;
                    group.rotation.z = rz;
                    renderer.render( scene, camera );
                }
    }
    
    
    
    const THREE = require ('three');
    const orig = require ('../img/orig.json');
    
    
    
    export default canvas =>{
        const info = document.getElementById('three_origami');
        let camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 10000 ),
        scene = new THREE.Scene(), renderer=new THREE.WebGLRenderer( { antialias: true } );
        let group=new THREE.MeshNormalMaterial();
        let mouseX = 0, mouseY = 0;
        let windowHalfX = window.innerWidth / 2;
        let windowHalfY = window.innerHeight / 2;
                init();
                animate();
                function init() {
                    camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 10000 );
                    camera.position.z = 40;
                    scene = new THREE.Scene();
                    scene.background = new THREE.Color( 0xffffff );
                    scene.fog = new THREE.Fog( 0xfffff, 1, 10000 );
    
                    group = new THREE.Group();
    
    
                        const objLoader = new THREE.ObjectLoader();
    
    
                        objLoader.parse(orig, (obj) => {
                            for ( let i = 0; i <= 300; i ++ ) {
                                let mesh = new THREE.Mesh( obj.geometry, obj.material );
                                mesh.position.x = Math.random() * 2000 - 1000;
                                mesh.position.y = Math.random() * 2000 - 1000;
                                mesh.position.z = Math.random() * 2000 - 1000;
                                mesh.rotation.x = Math.random() * 2 * Math.PI;
                                mesh.rotation.y = Math.random() * 2 * Math.PI;
                                mesh.matrixAutoUpdate = false;
                                mesh.updateMatrix();
                                group.add(mesh);
                            }
                        });
    
                    scene.add( group );
                    //
                    renderer.setPixelRatio( window.devicePixelRatio );
                    renderer.setSize( window.innerWidth, window.innerHeight );
                    info.appendChild( renderer.domElement );
                    //
                    //
                    document.addEventListener( 'mousemove', onDocumentMouseMove, false );
                    //
                    window.addEventListener( 'resize', onWindowResize, false );
                }
                function onWindowResize() {
                    windowHalfX = window.innerWidth / 2;
                    windowHalfY = window.innerHeight / 2;
                    camera.aspect = window.innerWidth / window.innerHeight;
                    camera.updateProjectionMatrix();
                    renderer.setSize( window.innerWidth, window.innerHeight );
                }
                function onDocumentMouseMove( event ) {
                    mouseX = ( event.clientX - windowHalfX ) * 10;
                    mouseY = ( event.clientY - windowHalfY ) * 10;
                }
                //
                function animate() {
                    requestAnimationFrame( animate );
                    render();
                }
                function render() {
                    let time = Date.now() * 0.001;
                    let rx = Math.sin( time * 0.7 ) * 0.5,
                        ry = Math.sin( time * 0.3 ) * 0.5,
                        rz = Math.sin( time * 0.2 ) * 0.5;
                    camera.position.x += ( mouseX - camera.position.x ) * 0.05;
                    camera.position.y += ( - mouseY - camera.position.y ) * 0.05;
                    camera.lookAt( scene.position );
                    group.rotation.x = rx;
                    group.rotation.y = ry;
                    group.rotation.z = rz;
                    renderer.render( scene, camera );
                }
    }
    

    我将objLoader.load('/dist/orig.json') 更改为objLoader.parse(orig) 并删除了JSON.stringify

    希望这对你有用。

    【讨论】:

    • When you require a JSON file Webpack includes it in the bundle at build time 这是真的吗?如果 JSON 非常庞大,比您的应用程序大 100 倍或 1000 倍怎么办?
    • 我使用 1.31 MB JSON 文件进行了测试。情况似乎如此。您可以使用文件加载器来获取 URL。
    • 另外,我编辑了这篇文章,包括为什么你首先得到Unexpected token
    • 您配置 webpack 以使用各种加载器处理文件。由您决定何时以及是否内联 JSON。
    • When you require a JSON file Webpack includes it in the bundle at build time. 这在一般意义上是不正确的。这取决于 OPs webpack 配置。它也可能返回一个路径...
    猜你喜欢
    • 2019-01-28
    • 1970-01-01
    • 1970-01-01
    • 2017-11-16
    • 2017-02-12
    • 1970-01-01
    • 2015-09-01
    • 2014-02-16
    • 2017-01-04
    相关资源
    最近更新 更多