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

如何实现上下滚动时Three.js相机仅围绕Y轴旋转?

页面上下滚动控制Three.js相机仅绕Y轴旋转实现方案

以下是纯Vanilla JS环境下可直接落地的实现逻辑:

  • 前置配置(如果使用OrbitControls做基础交互)
    先锁死相机绕X轴的俯仰角度,避免交互过程中出现其他维度的旋转偏移:
    // 锁死垂直方向旋转角度,仅保留水平旋转自由度
    controls.minPolarAngle = Math.PI / 2;
    controls.maxPolarAngle = Math.PI / 2;
    controls.enableDamping = true; // 开启阻尼优化交互手感
    
    如果没有引入控件库,直接操作原生相机对象即可,跳过这步。
  • 滚动事件绑定与角度映射
    监听window的scroll事件,将页面滚动进度归一化到0-1区间,再映射为相机Y轴的旋转角度值,不要直接用scrollY原始值计算,避免页面内容高度变化时旋转速度失控:
    // 全局存储目标旋转角度
    let targetYRotation = 0;
    // 配置旋转总幅度,这里示例为滚动到底部时相机转2整圈
    const maxRotation = Math.PI * 4;
    
    window.addEventListener('scroll', () => {
      // 计算页面可滚动的总高度
      const maxScrollY = document.documentElement.scrollHeight - window.innerHeight;
      // 计算当前滚动进度,边界值兜底避免除0
      const scrollProgress = maxScrollY > 0 ? window.scrollY / maxScrollY : 0;
      // 映射为目标旋转角度
      targetYRotation = scrollProgress * maxRotation;
    }, { passive: true }); // 加passive提升滚动性能
    
  • 渲染循环内同步更新相机状态
    不要直接在scroll回调中修改相机属性,在requestAnimationFrame驱动的渲染循环中更新状态,保证和渲染帧率同步,还可以方便加缓动效果:
    function animate() {
      requestAnimationFrame(animate);
    
      // 无缓动:直接赋值
      // camera.rotation.y = targetYRotation;
    
      // 带缓动效果:插值过渡,数值越小过渡越柔和
      camera.rotation.y += (targetYRotation - camera.rotation.y) * 0.1;
    
      // 如果使用了OrbitControls记得调用update
      // controls.update();
    
      renderer.render(scene, camera);
    }
    animate();
    
  • 可选优化项
    • 如果页面滚动区域和3D画布区域分离,可以单独监听画布对应容器的scroll事件,逻辑和全局监听一致
    • 不需要兼容旧浏览器的话,可以用ScrollTimeline做更丝滑的滚动驱动动画,不需要手动计算进度
    • 低性能设备上可以给scroll回调加节流,减少不必要的计算

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 06:51:20