如何在 react-three-fiber canvas 中添加 jsx 组件?
How to add a jsx component inside a react-three-fiber canvas?
我想在 react-three-fiber 中插入一个 jsx 组件 canvas。有办法吗?
我已经 fork 了一个官方示例,它具有无限滚动功能。每个元素都是来自 @react-three/drei
的图像。假设我有一个组件数组。我如何定位它们才能达到相同的效果?
密码是:
import { Suspense, useRef } from 'react'
import { Canvas, useThree } from '@react-three/fiber'
import { ScrollControls, Scroll, Preload, Image as ImageImpl } from '@react-three/drei'
function Image(props) {
const ref = useRef()
const group = useRef()
return (
<group ref={group}>
<ImageImpl ref={ref} {...props} />
</group>
)
}
function Card() {
return (
<div style={{ background: '#red', width: 200, height: '100%', borderRadius: 8 }}>
<h3>hello world</h3>
<p>great text here!</p>
</div>
)
}
function Page({ m = 0.4, urls, ...props }) {
const { width } = useThree((state) => state.viewport)
const w = width < 10 ? 1.5 / 3 : 1 / 3
return (
<group {...props}>
<Image position={[-width * w, 0, -1]} scale={[width * w - m * 2, 5, 1]} url={urls[0]} />
<Image position={[0, 0, 0]} scale={[width * w - m * 2, 5, 1]} url={urls[1]} />
<Image position={[width * w, 0, 1]} scale={[width * w - m * 2, 5, 1]} url={urls[2]} />
</group>
)
}
function Pages() {
const { width } = useThree((state) => state.viewport)
return (
<>
<Page position={[-width * 1, 0, 0]} urls={['/trip1.jpg', '/trip2.jpg', '/trip3.jpg']} />
<Page position={[width * 0, 0, 0]} urls={['/img1.jpg', '/img2.jpg', '/img3.jpg']} />
<Page position={[width * 1, 0, 0]} urls={['/img4.jpg', '/img5.jpg', '/img6.jpg']} />
{/* INSERT JSX COMPONENT HERE */}
{/* <Card />*/}
<Page position={[width * 2, 0, 0]} urls={['/trip1.jpg', '/trip2.jpg', '/trip3.jpg']} />
<Page position={[width * 3, 0, 0]} urls={['/img1.jpg', '/img2.jpg', '/img3.jpg']} />
<Page position={[width * 4, 0, 0]} urls={['/img4.jpg', '/img5.jpg', '/img6.jpg']} />
</>
)
}
export default function App() {
return (
<Canvas gl={{ antialias: false }} dpr={[1, 1.5]}>
<Suspense fallback={null}>
<ScrollControls infinite horizontal damping={4} pages={4} distance={1}>
<Scroll>
<Pages />
</Scroll>
</ScrollControls>
<Preload />
</Suspense>
</Canvas>
)
}
这里还有一个codesandbox。谢谢!
r3f是渲染器,canvas里面的东西都渲染成threejs。 canvas 中的“div”与“new THREE.Div()”相同,但不存在。就像你试图写一个内部 react-dom 一样。您可以在 canvas 元素之前或之后添加 html。你也可以把它放在里面,但只能使用像 drei/Html 这样的助手,它将 html 绑定到网格或组的位置。查看示例,该用例有很多:https://docs.pmnd.rs/react-three-fiber/getting-started/examples
我想在 react-three-fiber 中插入一个 jsx 组件 canvas。有办法吗?
我已经 fork 了一个官方示例,它具有无限滚动功能。每个元素都是来自 @react-three/drei
的图像。假设我有一个组件数组。我如何定位它们才能达到相同的效果?
密码是:
import { Suspense, useRef } from 'react'
import { Canvas, useThree } from '@react-three/fiber'
import { ScrollControls, Scroll, Preload, Image as ImageImpl } from '@react-three/drei'
function Image(props) {
const ref = useRef()
const group = useRef()
return (
<group ref={group}>
<ImageImpl ref={ref} {...props} />
</group>
)
}
function Card() {
return (
<div style={{ background: '#red', width: 200, height: '100%', borderRadius: 8 }}>
<h3>hello world</h3>
<p>great text here!</p>
</div>
)
}
function Page({ m = 0.4, urls, ...props }) {
const { width } = useThree((state) => state.viewport)
const w = width < 10 ? 1.5 / 3 : 1 / 3
return (
<group {...props}>
<Image position={[-width * w, 0, -1]} scale={[width * w - m * 2, 5, 1]} url={urls[0]} />
<Image position={[0, 0, 0]} scale={[width * w - m * 2, 5, 1]} url={urls[1]} />
<Image position={[width * w, 0, 1]} scale={[width * w - m * 2, 5, 1]} url={urls[2]} />
</group>
)
}
function Pages() {
const { width } = useThree((state) => state.viewport)
return (
<>
<Page position={[-width * 1, 0, 0]} urls={['/trip1.jpg', '/trip2.jpg', '/trip3.jpg']} />
<Page position={[width * 0, 0, 0]} urls={['/img1.jpg', '/img2.jpg', '/img3.jpg']} />
<Page position={[width * 1, 0, 0]} urls={['/img4.jpg', '/img5.jpg', '/img6.jpg']} />
{/* INSERT JSX COMPONENT HERE */}
{/* <Card />*/}
<Page position={[width * 2, 0, 0]} urls={['/trip1.jpg', '/trip2.jpg', '/trip3.jpg']} />
<Page position={[width * 3, 0, 0]} urls={['/img1.jpg', '/img2.jpg', '/img3.jpg']} />
<Page position={[width * 4, 0, 0]} urls={['/img4.jpg', '/img5.jpg', '/img6.jpg']} />
</>
)
}
export default function App() {
return (
<Canvas gl={{ antialias: false }} dpr={[1, 1.5]}>
<Suspense fallback={null}>
<ScrollControls infinite horizontal damping={4} pages={4} distance={1}>
<Scroll>
<Pages />
</Scroll>
</ScrollControls>
<Preload />
</Suspense>
</Canvas>
)
}
这里还有一个codesandbox。谢谢!
r3f是渲染器,canvas里面的东西都渲染成threejs。 canvas 中的“div”与“new THREE.Div()”相同,但不存在。就像你试图写一个内部 react-dom 一样。您可以在 canvas 元素之前或之后添加 html。你也可以把它放在里面,但只能使用像 drei/Html 这样的助手,它将 html 绑定到网格或组的位置。查看示例,该用例有很多:https://docs.pmnd.rs/react-three-fiber/getting-started/examples