Three.js 滚动条 3D 视差动画原理解析

🌌 Three.js 滚动条 3D 视差动画原理教学:滚着滚着,就进了宇宙

风格:硬核技术 + 一点点文学幻想 + 探险日志风格

技术栈:JavaScript(主力)、Three.js(主角)、HTML/CSS(配角)

🌠 前言:滚动条不只是滚动,它是时间的流动,是空间的扭曲

在现代网页中,用户滚动页面的动作不仅能驱动页面滑动,更能驱动三维世界发生剧烈变化 。这种看似炫酷的"视差滚动",其实是一个三维视角+位移映射的魔术表演。

我们今天就来拆解这个魔术的底牌,带你一步步从 JavaScript 到 GPU,从 DOM 到 3D 空间,掌握 Three.js 中如何优雅地做出滚动驱动的视差动画


🎢 什么是 3D 视差动画(Parallax Scrolling)

视差(Parallax)最初是天文学里的词,用来观测恒星位置随地球公转而变化的"假象"。

在前端界中,视差效果就是:背景和前景以不同速度滚动,营造出深度感和空间层次感。

🚀 进入 Three.js,我们能将页面滚动与摄像机、物体的三维坐标绑定,实现一种**"滚动中穿越空间"**的沉浸感。


🧱 核心原理拆解:把页面滚动转成三维动画

🧭 第一步:获取滚动进度

HTML 页面滚动其实就是一个"从 0 到 1"的比例尺(类似进度条)。

js 复制代码
const scrollY = window.scrollY
const scrollProgress = scrollY / (document.body.scrollHeight - window.innerHeight)

你可以把这个 scrollProgress 想象成:

👨‍🚀 "我已经从地球滚到了火星旅程的 % 完成度"


🎥 第二步:把滚动进度映射到 Three.js 场景中

🌍 场景初始构建
javascript 复制代码
import * as THREE from 'three'

const scene = new THREE.Scene()
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000)
camera.position.z = 5

const renderer = new THREE.WebGLRenderer()
renderer.setSize(window.innerWidth, window.innerHeight)
document.body.appendChild(renderer.domElement)
🧊 加几个物体(让你有东西能"穿越")
csharp 复制代码
const geometry = new THREE.BoxGeometry()
const material = new THREE.MeshNormalMaterial()
const cube = new THREE.Mesh(geometry, material)
scene.add(cube)
📈 滚动进度映射到物体位置 or 摄像机位置
scss 复制代码
function animate() {
  requestAnimationFrame(animate)

  const scrollY = window.scrollY
  const scrollProgress = scrollY / (document.body.scrollHeight - window.innerHeight)

  // 方法一:移动物体(你飞过去)
  cube.position.z = -10 * scrollProgress

  // 方法二:移动摄像机(宇宙推着你飞)
  // camera.position.z = 5 + scrollProgress * 20

  renderer.render(scene, camera)
}
animate()

🚨 注意:如果你移动的是摄像机,整个宇宙会随之"透视变化",那是一种更加震撼的视差效果。


🧠 数学底层揭秘:为什么会产生"深度感"?

  • 摄像机离一个物体越近,它变化得越快(比如你坐高铁看路边的电线杆 vs 远山)
  • 所以,只要让不同的物体(或者摄像机)以非线性速度响应滚动,就能模拟这种深度层叠

通俗理解如下:

层级 滚动响应速度 显示效果
背景背景背景 稳如泰山(远)
中景 正常 跟着动(普通)
前景 呼啸而过(近)

🪄 Bonus:滚动驱动的动画过渡(补间神器)

你也可以用 Tween.js 或者直接用 gsap 这种神器来插值动画:

javascript 复制代码
import gsap from 'gsap'

window.addEventListener('scroll', () => {
  const progress = window.scrollY / (document.body.scrollHeight - window.innerHeight)
  gsap.to(cube.position, {
    z: -progress * 10,
    duration: 0.5,
    ease: 'power2.out'
  })
})

这样滚动就不突兀了,而是有丝滑的物理缓动感,像滑雪一样优雅入弯~


🏔️ 场景复杂化:多图层视差世界

在真正的页面中,你可以:

  • 添加多个物体,每个绑定不同的滚动速度
  • 控制材质透明度、缩放、旋转,让动画更具空间幻觉
  • 甚至结合 HTML + WebGL overlay,打造页面 + 3D 场景联动
ini 复制代码
// 三个立方体,各自不同的滚动速率
cube1.position.z = -scrollProgress * 5
cube2.position.z = -scrollProgress * 10
cube3.position.z = -scrollProgress * 20

🌌 小提示:配合 IntersectionObserver 还能做到"到达某一段内容,触发动画"


🪐 总结:滚动,是与空间的对话

滚动条早已不是古早网页里的"拖动页面"工具,而是动画引擎的动力源泉

在 Three.js 的加持下,你拥有了穿越星系、折叠维度的能力。

你只是轻轻一滚,整个三维世界就开始演奏交响曲。


📚 延伸阅读推荐


🚀 愿你用 Three.js 打开 Web 的第四维度,滚着滚着就能看见银河尽头的自己。

相关推荐
JiaLin_Denny3 分钟前
javascript 中数组对象操作方法
前端·javascript·数组对象方法·数组对象判断和比较
代码老y4 分钟前
Vue3 从 0 到 ∞:Composition API 的底层哲学、渲染管线与生态演进全景
前端·javascript·vue.js
LaoZhangAI12 分钟前
ComfyUI集成GPT-Image-1完全指南:8步实现AI图像创作革命【2025最新】
前端·后端
LaoZhangAI14 分钟前
Cline + Gemini API 完整配置与使用指南【2025最新】
前端·后端
Java&Develop18 分钟前
防止电脑息屏 html
前端·javascript·html
Maybyy21 分钟前
javaScript中数组常用的函数方法
开发语言·前端·javascript
国王不在家23 分钟前
组件-多行文本省略-展开收起
前端·javascript·html
夏兮颜☆25 分钟前
【electron】electron实现窗口的最大化、最小化、还原、关闭
前端·javascript·electron
LaoZhangAI25 分钟前
Cline + Claude API 完全指南:2025年智能编程最佳实践
前端·后端