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

@react-three/fiber的Canvas高度超出模型,如何让模型高度匹配Canvas?

解决Canvas尺寸远大于模型的问题

以下几种方法可以实现模型高度与Canvas高度匹配:

方法1:用drei的fitCameraToObject自动适配

这是最省心的方案,自动调整相机位置和视角,让模型完整适配视口:

在你的Model组件中添加适配逻辑:

import { useThree, useEffect } from '@react-three/fiber';
import { fitCameraToObject } from '@react-three/drei';
import { useRef } from 'react';

const Model = () => {
  const modelRef = useRef();
  const { camera } = useThree();

  useEffect(() => {
    if (modelRef.current) {
      // padding控制模型与Canvas边缘的空隙,0.1表示留10%的余量
      fitCameraToObject(camera, modelRef.current, { padding: 0.1 });
    }
  }, [camera]);

  // 替换成你实际的模型加载代码
  return <primitive ref={modelRef} object={yourModelAsset} />;
};

方法2:手动计算相机位置

通过模型包围盒计算相机所需距离,精准适配高度:

import { useThree, useEffect } from '@react-three/fiber';
import { useRef } from 'react';
import * as THREE from 'three';

const Model = () => {
  const modelRef = useRef();
  const { camera } = useThree();

  useEffect(() => {
    if (modelRef.current) {
      // 获取模型的包围盒
      const boundingBox = new THREE.Box3().setFromObject(modelRef.current);
      const modelSize = boundingBox.getSize(new THREE.Vector3());
      const modelHeight = modelSize.y;

      // 根据相机FOV计算所需的相机距离
      const fovRad = THREE.MathUtils.degToRad(camera.fov / 2);
      const requiredDistance = modelHeight / (2 * Math.tan(fovRad));

      // 调整相机Z轴位置,保留原有X/Y偏移
      camera.position.z = requiredDistance;
      // 让相机始终对准模型中心
      camera.lookAt(boundingBox.getCenter(new THREE.Vector3()));
    }
  }, [camera]);

  // 替换成你实际的模型加载代码
  return <primitive ref={modelRef} object={yourModelAsset} />;
};

方法3:调整模型缩放与Canvas样式

如果模型本身尺寸过小,直接调整缩放比例;同时确保Canvas占满目标容器:

  1. 给Canvas设置样式,确保高度符合需求:
<Canvas 
  shadows 
  camera={{ position: [-5, 0, 20], fov: 20 }}
  style={{ width: '100%', height: '100vh' }} // 让Canvas占满视口高度
>
  {/* ... 其他元素 ... */}
  <Model scale={3} /> {/* 根据实际情况调整缩放值 */}
</Canvas>

如果使用OrbitControls,相机位置调整后需要更新控制器状态:

const { controls } = useThree();
useEffect(() => {
  if (controls) controls.update();
}, [camera]);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 18:21:16