使用Three.VideoTexture加载竖屏视频时画面拉伸的问题求助
解决Three.js VideoTexture竖屏视频拉伸问题
嘿,这个问题我之前做Three.js视频项目时也踩过坑!核心原因很简单:你用来承载视频的平面是固定的520x520正方形,但竖屏视频的宽高比和这个正方形完全不匹配,画面自然就被强制拉伸变形了。下面给你两个实用的解决思路,按需选择:
方法一:根据视频真实宽高比调整平面尺寸
这个方法会让平面适配视频的比例,保证画面完全填充且不变形,缺点是平面不再是固定的520x520。关键是要等视频元数据加载完成后,获取它的真实宽高来计算比例:
// 监听视频元数据加载完成事件,确保能拿到真实宽高 video.addEventListener('loadedmetadata', function() { // 计算视频的宽高比 const videoAspectRatio = video.videoWidth / video.videoHeight; // 你的画布宽高比是520/520=1 const canvasAspectRatio = WIDTH / HEIGHT; let planeWidth, planeHeight; if (videoAspectRatio > canvasAspectRatio) { // 视频比画布宽,以画布宽度为基准,按比例计算高度 planeWidth = WIDTH; planeHeight = WIDTH / videoAspectRatio; } else { // 视频比画布高,以画布高度为基准,按比例计算宽度 planeHeight = HEIGHT; planeWidth = HEIGHT * videoAspectRatio; } // 创建适配后的平面几何体 const videoGeometry = new THREE.PlaneGeometry(planeWidth, planeHeight); const videoMaterial = new THREE.MeshBasicMaterial({ map: videoTexture }); const videoMesh = new THREE.Mesh(videoGeometry, videoMaterial); scene.add(videoMesh); });
方法二:保持平面尺寸不变,用UV映射适配视频比例(黑边填充)
如果需要保持平面的520x520大小不变,让视频居中显示、上下或左右留黑边,就可以通过调整纹理的UV映射来实现:
video.addEventListener('loadedmetadata', function() { const videoAspectRatio = video.videoWidth / video.videoHeight; const canvasAspectRatio = WIDTH / HEIGHT; let scaleX = 1, scaleY = 1; let offsetX = 0, offsetY = 0; if (videoAspectRatio > canvasAspectRatio) { // 视频更宽,压缩X轴方向的纹理,同时居中 scaleX = canvasAspectRatio / videoAspectRatio; offsetX = (1 - scaleX) / 2; } else { // 视频更高,压缩Y轴方向的纹理,同时居中 scaleY = videoAspectRatio / canvasAspectRatio; offsetY = (1 - scaleY) / 2; } // 将计算好的缩放和偏移应用到视频纹理 videoTexture.repeat.set(scaleX, scaleY); videoTexture.offset.set(offsetX, offsetY); });
重要提醒
一定要在loadedmetadata事件回调里执行这些计算,不然视频的videoWidth和videoHeight可能还没初始化,会得到0值,导致比例计算错误。
内容的提问来源于stack exchange,提问作者jpatel
相关产品推荐
相关产品推荐

