使用 React 导入 LOCAL .obj 以使用 Three.js OBJLoader 加载
import LOCAL .obj to load with Three.js OBJLoader using React
我正在尝试导入一个本地 .obj 以使用 THREE.OBJLoader().load()
函数加载,我知道它有效,因为当我传递一个非本地 URL(例如 'http://downloadOBJfromHere.com') 它完美地加载了它,我的主要问题是每次我加载它时,它都必须下载 obj 并且需要很长时间。
我正在使用 React 进行服务器端渲染。
import * as THREE from 'three';
import * as OBJLoader from 'three-obj-loader';
import obj from '../../../assets/obj/scene.obj';
在ComponentDidMount()
中:
const loader = new THREE.OBJLoader();
loader.load( obj,
object => {
scene.add(object);
},
xhr => {
console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );
},
error => {
console.log("Error! ", error);
}
);
当我这样做时,我在 Chrome 控制台中收到错误消息:
Unexpected line: '<!doctype html><html lang="en" data-reactroot="" data-reactid="1" data-react-checksum="1415239080"><head data-reactid="2"><meta charset="utf-8" data-reactid="3"/><meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0" data-reactid="4"/><title data-reactid="5">TITLE</title><link rel="stylesheet" href="/client/style.css" data-reactid="6"/></head><body data-reactid="7"><div id="root" data-reactid="8"><!-- react-empty: 1 --></div><script type="text/javascript" src="/client/vendor.js" data-reactid="9"></script><script type="text/javascript" src="/client/client.js" data-reactid="10"></script></body></html>'
(请记住,URL 可以正常加载)。它向我显示了服务的根 html。
所以我猜它与一些用于导入文件的 webpack 配置有关,我正在使用 file-loader
加载 .obj 文件:
这是我的 webpack 配置的一部分:
const paths = {
source: path.join(__dirname, '../source'),
javascript: path.join(__dirname, '../source/js'),
images: path.join(__dirname, '../source/assets/img'),
svg: path.join(__dirname, '../source/assets/svg'),
obj: path.join(__dirname, '../source/assets/obj'),
build: path.join(__dirname, '../build'),
};
const rules = [
{
test: /\.mtl$/,
loader: 'mtl-loader'
},
{ test: /\.obj$/,
loader: 'file-loader',
include: paths.obj
},
{
test: /\.(png|gif|jpg|svg)$/,
include: paths.images,
use: [{
loader: 'file-loader',
options: {
name: 'client/assets/[name]-[hash].[ext]',
}
}]
}
];
编辑
添加图像加载器以显示我如何提供图像。
这是我的服务器配置的一部分
const app = express();
const hostname = 'localhost';
const port = 8080;
app.use('/client', express.static('build/client'));
app.use((req, res) => {
const { persistor, store } = configureStore();
const context = {};
const appHtml = ReactDOMServer.renderToString(
<Provider store={ store }>
<PersistGate persistor={ persistor }>
<StaticRouter location={ req.url } context={ context }>
<App />
</StaticRouter>
</PersistGate>
</Provider>
);
const serverHtml = getServerHtml(appHtml, 'dehydratedState');
if (context.url) {
res.redirect(301, context.url);
} else {
res.status(context.status || 200).send(serverHtml);
}
});
app.listen(port, err => callback);
我想通了。
在 webpack 配置中,我更改了 .obj 加载器,从 'file-loader' 到 'url-loader'
const rules = [
{
test: /\.mtl$/,
loader: 'mtl-loader'
},
{ test: /\.obj$/,
// CHANGE HERE
loader: 'url-loader',
include: paths.obj
},
{
test: /\.(png|gif|jpg|svg)$/,
include: paths.images,
use: [{
loader: 'file-loader',
options: {
name: 'client/assets/[name]-[hash].[ext]',
}
}]
}
];
注意:我在导入 npm 中不存在的名为 OutlinePass(针对 THREE.js)的脚本时也遇到了问题,我设法以这种方式导入它:
const script = document.createElement("script");
script.src = require('!!url-loader!../../../assets/webgl/js/OutlinePass.js');
script.async = true;
document.body.appendChild(script);
脚本本身不起作用,但我设法导入了它(我们在这里谈论的内容 :))
我正在尝试导入一个本地 .obj 以使用 THREE.OBJLoader().load()
函数加载,我知道它有效,因为当我传递一个非本地 URL(例如 'http://downloadOBJfromHere.com') 它完美地加载了它,我的主要问题是每次我加载它时,它都必须下载 obj 并且需要很长时间。
我正在使用 React 进行服务器端渲染。
import * as THREE from 'three';
import * as OBJLoader from 'three-obj-loader';
import obj from '../../../assets/obj/scene.obj';
在ComponentDidMount()
中:
const loader = new THREE.OBJLoader();
loader.load( obj,
object => {
scene.add(object);
},
xhr => {
console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );
},
error => {
console.log("Error! ", error);
}
);
当我这样做时,我在 Chrome 控制台中收到错误消息:
Unexpected line: '<!doctype html><html lang="en" data-reactroot="" data-reactid="1" data-react-checksum="1415239080"><head data-reactid="2"><meta charset="utf-8" data-reactid="3"/><meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0" data-reactid="4"/><title data-reactid="5">TITLE</title><link rel="stylesheet" href="/client/style.css" data-reactid="6"/></head><body data-reactid="7"><div id="root" data-reactid="8"><!-- react-empty: 1 --></div><script type="text/javascript" src="/client/vendor.js" data-reactid="9"></script><script type="text/javascript" src="/client/client.js" data-reactid="10"></script></body></html>'
(请记住,URL 可以正常加载)。它向我显示了服务的根 html。
所以我猜它与一些用于导入文件的 webpack 配置有关,我正在使用 file-loader
加载 .obj 文件:
这是我的 webpack 配置的一部分:
const paths = {
source: path.join(__dirname, '../source'),
javascript: path.join(__dirname, '../source/js'),
images: path.join(__dirname, '../source/assets/img'),
svg: path.join(__dirname, '../source/assets/svg'),
obj: path.join(__dirname, '../source/assets/obj'),
build: path.join(__dirname, '../build'),
};
const rules = [
{
test: /\.mtl$/,
loader: 'mtl-loader'
},
{ test: /\.obj$/,
loader: 'file-loader',
include: paths.obj
},
{
test: /\.(png|gif|jpg|svg)$/,
include: paths.images,
use: [{
loader: 'file-loader',
options: {
name: 'client/assets/[name]-[hash].[ext]',
}
}]
}
];
编辑 添加图像加载器以显示我如何提供图像。
这是我的服务器配置的一部分
const app = express();
const hostname = 'localhost';
const port = 8080;
app.use('/client', express.static('build/client'));
app.use((req, res) => {
const { persistor, store } = configureStore();
const context = {};
const appHtml = ReactDOMServer.renderToString(
<Provider store={ store }>
<PersistGate persistor={ persistor }>
<StaticRouter location={ req.url } context={ context }>
<App />
</StaticRouter>
</PersistGate>
</Provider>
);
const serverHtml = getServerHtml(appHtml, 'dehydratedState');
if (context.url) {
res.redirect(301, context.url);
} else {
res.status(context.status || 200).send(serverHtml);
}
});
app.listen(port, err => callback);
我想通了。
在 webpack 配置中,我更改了 .obj 加载器,从 'file-loader' 到 'url-loader'
const rules = [
{
test: /\.mtl$/,
loader: 'mtl-loader'
},
{ test: /\.obj$/,
// CHANGE HERE
loader: 'url-loader',
include: paths.obj
},
{
test: /\.(png|gif|jpg|svg)$/,
include: paths.images,
use: [{
loader: 'file-loader',
options: {
name: 'client/assets/[name]-[hash].[ext]',
}
}]
}
];
注意:我在导入 npm 中不存在的名为 OutlinePass(针对 THREE.js)的脚本时也遇到了问题,我设法以这种方式导入它:
const script = document.createElement("script");
script.src = require('!!url-loader!../../../assets/webgl/js/OutlinePass.js');
script.async = true;
document.body.appendChild(script);
脚本本身不起作用,但我设法导入了它(我们在这里谈论的内容 :))