[英]Mass import and loading of images in React with react-three-fiber
我目前正在尝试在我的 React 项目中导入和使用约 300 张图像(.png 文件)。 它们应该显示在 3D 视图中,并使用 react-three-fiber 的加载器加载。
因此,我将文件复制到了一个名为images
的文件夹中,并创建了一个index.js
文件,该文件按如下方式导出图像:
export { default as image_0 } from './0.png';
export { default as image_1 } from './1.png';
[...]
我以前也尝试过像这样导出图像:
import image_0 from './0.png';
import image_1 from './1.png'
[...]
export {
image_0,
image_1,
[...]
}
然后将图像加载到另一个文件中:
import * as imageArray from "../../../assets/textures/images"
try {
texture = useLoader(THREE.TextureLoader, imageArray['sign_' + imageNumber]);
} catch (e) {
console.log("Image for number " + imageNumber + " not found.");
}
在没有 try/catch 的情况下测试此工作流程时,我总是在开发人员工具控制台中收到以下错误:
Uncaught Could not load undefined: undefined
我已经仔细检查了相应的图像是否存在于images
中并且没有命名错误。 之后,我还尝试将所有纹理设置为一个文件,该文件已被声明为丢失,但肯定位于文件夹内,因此可加载:
texture = useLoader(THREE.TextureLoader, imageArray['sign_x']);
我再次遇到同样的错误,无法加载图像。
我的猜测是这是由太多导入的图像引起的问题,但我找不到任何其他解决方案来在项目中导入如此大量的文件。 我真的很感激任何帮助。 非常感谢您!
我认为问题不在于大量进口。 我认为(我不确定)它是导入还是需要的东西。 在expo-three
的文档中,他们使用了 require。 我还注意到,对于图像需要返回一个 id 而不是文件本身,这可能是解决您的问题的关键。
这是一个演示,我使用 require 获取 130 张图像,使用 ExpoTHREE.TextureLoader 加载它们,然后将它们作为threejs 立方体的可选纹理提供:
import React, { useEffect, useState } from 'react';
import {
Text,
useWindowDimensions,
StyleSheet,
Platform,
Image,
} from 'react-native';
import * as Progress from 'react-native-progress';
import { Asset } from 'expo-asset';
import { TextureLoader, loadAsync, THREE } from 'expo-three';
import Constants from 'expo-constants';
import ThreeWrapper from './components/ThreeWrapper';
import SafeAreaView from './components/SafeAreaView'
import imageArray from './assets/images/index';
global.THREE = global.THREE || THREE;
export default function App({ onComplete, ...props }) {
const [progress, setProgress] = useState(0.0);
const [textures, setTextures] = useState([]);
const { width, height } = useWindowDimensions();
const loadTextures = async () => {
const values = Object.entries(imageArray);
const total = values.length;
const imgs = await Promise.all(
values.map(async ([currentKey, requiredId]) => {
try {
let [{ uri, localUri }] = await Asset.loadAsync(requiredId);
const url = Platform.OS == 'android'
// android needs this?
? uri
:localUri
const texture = new TextureLoader().load(url);
setProgress((prev) => prev + 1 / total);
return texture;
} catch (err) {
console.log(err);
}
})
);
setTextures(imgs);
};
useEffect(() => {
loadTextures();
}, []);
if (Math.round(progress * 1000) / 1000 < 1)
return (
<SafeAreaView style={styles.container}>
<Text style={{ fontSize: 38, fontWeight: 'bold' }}>Loading...</Text>
<Progress.Bar
progress={progress}
width={width * 0.8}
height={36}
borderRadius={50}
/>
<Text
style={{
fontSize: 24,
fontWeight: '300',
textAlign: 'center',
width: '100%',
}}>
{(progress * 100).toFixed(2) + '%'}
</Text>
</SafeAreaView>
);
return (
<SafeAreaView style={styles.container}>
<ThreeWrapper textures={textures} />
</SafeAreaView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.