通过 react-three-fibre 中的道具传递 URL 作为纹理
Passing URL for texture through props in react-three-fibre
我最近开始使用 react-three-fibre,我发现 this example svg 图像是通过组件而不是直接在函数中加载的。我想使用这个想法,因为我想重用相同的组件但实现不同的 urls 来加载不同的纹理。
我试图复制这个例子所做的,但它一直出现错误:
无法获取 /undefined
这是我的代码:
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 而不是仅使用 url
但这也有类似的错误,我不知道如何纠正这个.我查看了文档 here 中的 react-three-fiber ,似乎这只适用于其他装载机?例如 Draco 或 GLTF。但我不知道为什么它对 TextureLoader 不起作用。
编辑:
完整错误:
所以这不是最有用的错误,因为它会创建一个单独的 html 页面,说明它不能 get/undefined。它确实与传递 url 有关,因为如果我直接在函数内部实现完整的 url 一切正常。但我不想创建这么多不同的功能。我查看了 和有类似错误的人,它表明可能 Javascript 将我的 src 设置为未定义?但它不应该,因为如果 url 没有通过道具传递,它就可以很好地工作。所以我猜我的语法有误,但我不知道如何更正它。
这一行似乎是导致问题的原因:
const [texture] = useLoader(THREE.TextureLoader, url);
useLoader
将无法读取 url
,因为它是一个数组,并且它将 return 纹理作为一个对象,因此将其解构为一个数组不会工作。
纹理 url 需要保存在 public
文件夹中并在您的环境中访问 public 时访问。我认为这是 cannot GET
问题的根源 - 请求纹理的文件无法正确访问 public 文件夹。
从那里开始,它只是将路径字符串作为道具向下传递的情况,您可以将其作为独立字符串或必要时作为数组的一部分来执行。在我的示例中,这是:
<Box url={["/plainmap.jpg"]} />
要在纹理加载器中访问该字符串,您需要指定索引或使用扩展运算符。
const texture = useLoader(THREE.TextureLoader, ...url);
我最近开始使用 react-three-fibre,我发现 this example svg 图像是通过组件而不是直接在函数中加载的。我想使用这个想法,因为我想重用相同的组件但实现不同的 urls 来加载不同的纹理。
我试图复制这个例子所做的,但它一直出现错误: 无法获取 /undefined 这是我的代码:
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 而不是仅使用 url
但这也有类似的错误,我不知道如何纠正这个.我查看了文档 here 中的 react-three-fiber ,似乎这只适用于其他装载机?例如 Draco 或 GLTF。但我不知道为什么它对 TextureLoader 不起作用。
编辑:
完整错误:
所以这不是最有用的错误,因为它会创建一个单独的 html 页面,说明它不能 get/undefined。它确实与传递 url 有关,因为如果我直接在函数内部实现完整的 url 一切正常。但我不想创建这么多不同的功能。我查看了
这一行似乎是导致问题的原因:
const [texture] = useLoader(THREE.TextureLoader, url);
useLoader
将无法读取 url
,因为它是一个数组,并且它将 return 纹理作为一个对象,因此将其解构为一个数组不会工作。
纹理 url 需要保存在 public
文件夹中并在您的环境中访问 public 时访问。我认为这是 cannot GET
问题的根源 - 请求纹理的文件无法正确访问 public 文件夹。
从那里开始,它只是将路径字符串作为道具向下传递的情况,您可以将其作为独立字符串或必要时作为数组的一部分来执行。在我的示例中,这是:
<Box url={["/plainmap.jpg"]} />
要在纹理加载器中访问该字符串,您需要指定索引或使用扩展运算符。
const texture = useLoader(THREE.TextureLoader, ...url);