You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让坐标轴随立方体同步运动?(react-three-fiber/Three.js)

解决方案:让坐标轴及标签随立方体同步旋转

一、让坐标轴随立方体同步旋转

当前你的AxesHelper是场景的直接子元素,不会继承立方体的变换。只需将AxesHelper作为立方体mesh的子组件,它就会自动继承父对象的旋转、位移等所有变换。

修改Box组件,把axesHelper放到mesh标签内部:

const Box = (props) => {
    const ref = useRef()
         
    const websocketRef = useRef();
    const connectWebsocket = () => {
      if (!websocketRef.current) {
        socket.addEventListener("message", (ev) => {
          if (ev.data.includes('ahrs_yaw')) {
            setPose(JSON.parse(ev.data.replaceAll("'", '"')))
          }
        });
        websocketRef.current = socket;
      }
    };
    connectWebsocket();

    useFrame(() => {
        ref.current.rotation.x += .005
        ref.current.rotation.y += .005
        ref.current.rotation.z += .005
    })

    return (
      <mesh
        {...props}
        ref={ref}
        >
        <boxGeometry args={[3, 3, 3]} />
        <meshStandardMaterial color={'orange'} />
        {/* 将AxesHelper作为立方体的子元素 */}
        <axesHelper args={[5]} />
      </mesh>
    )
}

同时删除Canvas中单独的<axesHelper args={[5, 5, 5]} />,此时坐标轴会完全跟随立方体旋转。


二、添加跟随立方体的坐标轴标签

1. 改造为可复用的轴标签组件

创建一个能自动面向相机的文本组件,确保标签始终可读:

import { extend, useFrame, useThree } from '@react-three/fiber'
import { FontLoader } from 'three/examples/jsm/loaders/FontLoader.js'
import { TextGeometry } from 'three/examples/jsm/geometries/TextGeometry.js'
import helvetiker from "three/examples/fonts/helvetiker_regular.typeface.json"

extend({ TextGeometry })

const helvetikerRegular = new FontLoader().parse(helvetiker)

const textOptions = {
  font: helvetikerRegular,
  size: .4,
  depth: .2,
}

// 可复用的坐标轴标签组件
function AxisLabel({ text, color, position }) {
  const meshRef = useRef()
  const { camera } = useThree()

  // 让文本始终面向相机
  useFrame(() => {
    meshRef.current.lookAt(camera.position)
  })

  return(
    <mesh ref={meshRef} position={position}>
        <textGeometry attach='geometry' args={[text, textOptions]}/>
        <meshStandardMaterial attach='material' color={color}/>
    </mesh>
  )
}

2. 在立方体中添加三个轴标签

将标签作为立方体的子元素,位置对应各坐标轴末端(可根据立方体大小调整):

const Box = (props) => {
    // ... 原有代码不变 ...

    return (
      <mesh
        {...props}
        ref={ref}
        >
        <boxGeometry args={[3, 3, 3]} />
        <meshStandardMaterial color={'orange'} />
        <axesHelper args={[5]} />
        {/* 添加三个坐标轴标签 */}
        <AxisLabel text="X" color="red" position={[2, 0, 0]} />
        <AxisLabel text="Y" color="green" position={[0, 2, 0]} />
        <AxisLabel text="Z" color="blue" position={[0, 0, 2]} />
      </mesh>
    )
}

关键原理

  • Three.js中父子对象的变换是继承的:子对象会自动继承父对象的position、rotation、scale,因此将辅助器和标签绑定到立方体即可同步运动。
  • lookAt(camera.position)确保文本始终朝向相机,避免旋转后标签倒置无法阅读。

内容的提问来源于stack exchange,提问作者anonymous

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 19:18:42