繁体   English   中英

使用 react-three-fiber 在 React 中大量导入和加载图像

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM