通过 react-three-fiber 中的道具传递纹理的 URL
Posted
技术标签:
【中文标题】通过 react-three-fiber 中的道具传递纹理的 URL【英文标题】:Passing URL for texture through props in react-three-fibre 【发布时间】:2020-07-13 19:48:36 【问题描述】:我最近开始使用 react-three-fiber,我发现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 ,似乎这只适用于其他加载器?例如 Draco 或 GLTF。但我不知道为什么它不适用于 TextureLoader。
编辑: 完整错误:
所以这不是最有用的错误,因为它创建了一个单独的 html 页面,说它无法获取/未定义。它确实与传递 url 有关,因为如果我直接在函数中实现完整的 url,一切正常。但我不想创建这么多不同的功能。我与有类似错误的人一起查看了here,它表明可能是 javascript 将我的 src 设置为未定义?但它不应该,因为如果 url 没有通过 props 传递,它就可以正常工作。所以我猜我的语法是错误的,但我不知道如何纠正它。
【问题讨论】:
请发布错误的全文,包括它来自哪个文件/行。 @TheJim01 感谢您的评论。我在编辑中添加了完整的错误。 【参考方案1】:这条线似乎是导致问题的原因:
const [texture] = useLoader(THREE.TextureLoader, url);
useLoader
将无法读取 url
,因为它是一个数组,它会将纹理作为对象返回,因此将其解构为数组是行不通的。
纹理 url 需要保存在 public
文件夹中并且可以访问,但是您可以在您的环境中访问 public。我认为这就是cannot GET
问题的根源——请求纹理的文件没有正确访问公用文件夹的权限。
从那里只是将路径字符串作为道具传递的情况,如果需要,您可以将其作为独立字符串或作为数组的一部分进行。在我的示例中,这是:
<Box url=["/plainmap.jpg"] />
要在纹理加载器中访问该字符串,您需要指定索引或使用扩展运算符。
const texture = useLoader(THREE.TextureLoader, ...url);
CodeSandbox
【讨论】:
嗨@lawrence-witt 谢谢你的评论。我使用url
的唯一原因是因为它是上面的示例与 svg 加载器一起使用的,我想使用这种方法,因为我想将 url 定义为组件本身的道具而不是函数内部所以我将能够重用组件并为每个组件提供不同的纹理。我不知道另一种方法。
如果您查看您发布的示例,它显示 Svg 元素正在作为字符串传递 url
。如果您更改代码以匹配示例中显示的语法,我相信这应该没问题 - 尽管一旦加载纹理就根本不需要解构它。
另外,如果这不起作用,请注意一般性,通常当您收到cannot GET
消息时,这意味着您被提供文件的任何服务器拒绝。如果您在本地环境中,这可能意味着该文件超出了项目的范围。
我已经尝试了与示例完全相同的语法,但仍然显示错误。我不知道为什么这会是服务器问题,因为如果我直接加载它,例如const [texture] = useLoader(THREE.TextureLoader, ['../../url.png']);
它加载得很好我只需要通过组件中的字符串传递它
好吧,我已经在codesandbox 中玩了一段时间了,我无法让 textureLoader 将字符串解析为道具。事实上,我无法让它解析任何字符串,这实际上是我过去的经验,现在我想起来了。我通常做的是在主文件的顶部导入纹理,然后将该导入作为道具传递。检查沙箱,我会更新我的答案 - 希望这对您的用例来说没问题!以上是关于通过 react-three-fiber 中的道具传递纹理的 URL的主要内容,如果未能解决你的问题,请参考以下文章
bufferGeometry setFromPoints 与 react-three-fiber
React-Three-Fiber (R3F):GLTF 加载程序加载问题。为啥我看不到我的模型?