reactjs 难以创建基本行(@react-three/fiber和Typescript)

0kjbasz6  于 2023-05-06  发布在  React
关注(0)|答案(3)|浏览(134)

谁能帮我把这条线显示出来?我正在使用@react-three/fiber和Typescript

My Faulty Component:

import * as THREE from 'three'

const RoadLine = ({start, end}: {start: THREE.Vector3, end: THREE.Vector3}) => {

    return (
        <line>
            <bufferGeometry setFromPoints={() => new THREE.BufferGeometry().setFromPoints([start, end])}/>
            <lineBasicMaterial color={'green'}/>
        </line>
    )
}

export default RoadLine

------------------------------------------------------------------------------------------

The Props Im sending in: 

{roads?.map(road => {
                        return (
                            <RoadLine
                            key={road.id}
                            start={new THREE.Vector3(1,0,3)} //numbers just for test atm
                            end={new THREE.Vector3(11,0,33)} //numbers just for test atm
                            />
                        )
                    })}

我试着画一条从a点到b点的基本路线,我不确定我做的是否正确

0x6upsns

0x6upsns1#

我一直在纠结这个问题,直到我看到保罗·亨舍尔的回应。
如果你不把[line]看作是一个 Package 器或抽象,它会变得更容易。你写的jsx是threejs。如果你用三个ejs写一行代码,你可以用jsx。但你把 prop 和功能搞混了THREE.BufferGeometry.setPoints是一个函数,您可以覆盖它。react/jsx中不调用onClick,而是设置它。你不能以声明方式调用函数,你可以在useEffect或useLayoutEffect中作为副作用来调用。如果你想在东西呈现在屏幕上之前调用你的函数,你可以使用后者。
他链接了这个代码和盒子,我也会在这里发布代码。https://codesandbox.io/s/basic-demo-forked-e46t9?file=/src/App.js

import * as THREE from 'three'
import React, { useLayoutEffect, useRef } from 'react'
import { Canvas } from '@react-three/fiber'

function Line({ start, end }) {
  const ref = useRef()
  useLayoutEffect(() => {
    ref.current.geometry.setFromPoints([start, end].map((point) => new THREE.Vector3(...point)))
  }, [start, end])
  return (
    <line ref={ref}>
      <bufferGeometry />
      <lineBasicMaterial color="hotpink" />
    </line>
  )
}

export default function App() {
  return (
    <Canvas>
      <ambientLight intensity={0.5} />
      <spotLight position={[10, 10, 10]} angle={0.15} penumbra={1} />
      <pointLight position={[-10, -10, -10]} />
      <Line start={[0, 0, 0]} end={[1, 0, 0]} />
      <Line start={[1, 0, 0]} end={[1, 1, 0]} />
    </Canvas>
  )
}
xzlaal3s

xzlaal3s2#

我们的朋友的答案几乎可以工作,但对于 typescript 需要一些调整:

import * as THREE from 'three'
import React, { useRef } from 'react'
import { Canvas, useFrame } from '@react-three/fiber'

type props = {
    start: number[],
    end: number[]
}

function Line (props: props) {
    const ref = useRef<THREE.Line>()

    useFrame(() => {
        if(ref.current){
            ref.current.geometry.setFromPoints([props.start, props.end].map((point) => new THREE.Vector3(...point)));
        }
    })
    return (
        <line ref={ref}>
            <bufferGeometry />
            <lineBasicMaterial color="hotpink"/>
        </line>
    )
}

export default function App() {
  return (
    <Canvas>
      <ambientLight intensity={0.5} />
      <spotLight position={[10, 10, 10]} angle={0.15} penumbra={1} />
      <pointLight position={[-10, -10, -10]} />
      <Line start={[0,0,0]} end={[1,1,0]} />
      <Line start={[1,1,0]} end={[2,0,0]} />
    </Canvas>
  )
}
ubby3x7f

ubby3x7f3#

这两个答案都包含应该避免的已知反模式。
1.@william's将Vector 3示例化放在useFrame中。这是不好的,应该尽可能避免。参见dreithree.js代码库中的实现示例。
1.@sean在startend上的回答条件。这通常会导致在重新构造这两个变量时重新呈现,即使它们包含相同的值。
1.两个答案都使用map来示例化点。这不是一个好的风格,除非你试图容纳两个以上的点
我建议您使用drei中的Line组件,而不是自己实现。它们使用示例化来提高性能并适应多个段。参见下文:

import {
  Line,
} from "@react-three/drei";

export Example = ({cx, cy, distance}) => (
     <Line
        points={[
          [-cx, -cy, -distance],
          [cx, -cy, -distance],
          [cx, cy, -distance],
          [-cx, cy, -distance],
          [-cx, -cy, -distance],
        ]}       // Array of points, Array<Vector3 | Vector2 | [number, number, number] | [number, number] | number>
        color={"#23aaff"}                   // Default
        lineWidth={1}                   // In pixels (default)
        // segments                        // If true, renders a THREE.LineSegments2. Otherwise, renders a THREE.Line2
      />
)

相关问题