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

React中如何裁剪Three.js canvas且不产生缩放拉伸变形

解决方案

你遇到的变形问题本质是渲染画布尺寸和相机宽高比不匹配导致的,Three.js 不会自动同步相机参数和渲染画布的尺寸变化,仅修改renderer.setSize就会出现拉伸/挤压问题。

方案1:内容等比缩放适配横幅(无变形,完整显示场景内容)

如果希望场景内容完整显示在横幅区域内,仅调整整体比例为横幅样式,操作如下:

  • 确定横幅高度:可以按比例计算(比如16:9横幅)或者固定高度
  • 修改渲染尺寸的同时,同步更新相机宽高比和投影矩阵
    示例代码:
// 以16:9比例横幅为例,宽度保持全屏
const bannerHeight = window.innerWidth * 9 / 16
// 固定高度写法:const bannerHeight = 400

// 更新渲染器尺寸
renderer.setSize(window.innerWidth, bannerHeight)
// 同步更新相机宽高比
camera.aspect = window.innerWidth / bannerHeight
// 相机参数修改后必须调用该方法才会生效
camera.updateProjectionMatrix()

方案2:垂直裁剪场景内容(内容不缩放,仅裁掉上下超出部分)

如果希望场景水平方向显示范围和全屏时完全一致,仅裁剪垂直方向超出横幅高度的内容,不需要修改相机参数,用视口配置即可:

const bannerHeight = 400 // 你需要的横幅高度
// 渲染器保持全屏尺寸
renderer.setSize(window.innerWidth, window.innerHeight)
// 设置渲染视口,仅渲染垂直方向从底部到bannerHeight的区域,x轴保持满宽
renderer.setViewport(0, window.innerHeight - bannerHeight, window.innerWidth, bannerHeight)

同时给canvas的父容器添加样式,避免超出部分显示:

.three-banner-wrap {
  width: 100vw;
  height: 400px;
  overflow: hidden;
}
.three-banner-wrap canvas {
  display: block;
}

React组件注意事项

  • 以上逻辑需要同时写到组件初始化和窗口resize事件的回调中,避免窗口尺寸变化时再次出现变形
  • 不要给canvas元素单独设置CSS宽高,所有显示尺寸控制通过父容器实现,避免二次拉伸

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 07:39:01