通过反应三纤维的道具传递纹理的URL

时间:2020-04-01 22:38:20

标签: reactjs three.js react-three-fiber

我最近开始使用react-three-fibre,发现this example是通过组件而不是直接在函数中加载svg映像的。我想使用这个想法,因为我想重用相同的组件,但是实现不同的URL来加载不同的纹理。

我试图复制此示例所做的操作,但它不断出现错误: 无法获取/未定义 这是我的代码:


import * as THREE from "three";
import ReactDOM from 'react-dom'
import React, { Suspense, useState, useRef, useEffect, useMemo } from 'react'
import { Canvas, extend, useLoader, useThree, useFrame } from 'react-three-fiber'



function Box(props, {url}) {
    const [texture] = useLoader(THREE.TextureLoader, url);

    const mesh = useRef()


    const [hover, setHover] = useState(false)


    return (

      <mesh
        {...props}
        ref={mesh}
        castShadow
        rotation={props.rotation} 
        scale={hover ? [1.2, 1, 1.2] : [1, 1, 1]}

        onPointerOver={e => setHover(true)}
        onPointerOut={e => setHover(false)}>

        <boxBufferGeometry attach="geometry" args={[130,.1,120]} />
        <meshStandardMaterial attach="material" map = {texture} transparent = {true} />
      </mesh>

    )
  }


function App() {
  return (
    <Canvas camera={{ position: [5,300,0],  
        fov:60, 
        aspect: window.innerWidth / window.innerHeight, 
        near:1, 
        far: 1000 }}>
        <Suspense fallback={null}>

            <Box position={[150, 10, -340]} rotation = {[0, Math.PI/2,0]} url = {['../../URL']}/>
            <Box position={[0, 0, 0]} />

      </Suspense>

       <directionalLight position = {[1,1,1]} intensity = {[1.7]}/>
    </Canvas>
  )
}


ReactDOM.render(<App />, document.getElementById('root'))



我还尝试过通过props.url传递网址,而不是仅使用url,但这也伴随着类似的错误,我不知道如何解决。我已经浏览了文档here中的“ react-three-fiber-fiber”,看来这仅适用于其他装载程序吗?例如Draco或GLTF。但是我不知道为什么它不适用于TextureLoader。

编辑: 完整错误: enter image description here enter image description here

所以这不是最有用的错误,因为它创建了一个单独的html页面,表示无法获取/未定义。它确实与传递url有关,因为如果我直接在函数内部实现完整的url,一切都会正常进行。但是我不想创建太多不同的功能。我在here处遇到了类似错误的人,这表明Javascript可能已将我的src设置为undefined?但这不应该,因为如果URL不通过props传递就可以正常工作。所以我猜我的语法是错误的,但是我不知道如何纠正它。

1 个答案:

答案 0 :(得分:1)

此行似乎是导致问题的原因:

const [texture] = useLoader(THREE.TextureLoader, url);

useLoader将无法读取url,因为它是一个数组,它将返回纹理作为对象,因此将其分解为数组将无法正常工作。

纹理URL需要保存在public文件夹中并可以访问,但是您可以在环境中访问public。我认为这是cannot GET问题的根源-请求纹理的文件无法正确访问公用文件夹。

在这里只是传递路径字符串作为prop的一种情况,如果需要,您可以将其作为独立字符串或数组的一部分来执行。在我的示例中,这是:

<Box url={["/plainmap.jpg"]} />

要在纹理加载器中访问该字符串,您需要指定索引或使用散布运算符。

const texture = useLoader(THREE.TextureLoader, ...url);