🔥 Hot Topics

你的品牌还停在2D?

为什么 3D 滚动网站总是加载慢、兼容差、SEO 暴跌?scroll-world 把任意品牌秒变可滚动 3D 世界,但 90% 团队复制即崩,本文拆解 3 个真实踩坑场景与可落地代码。

📅 July 12, 2026 📊 Level: intermediate 📦 GitHub: oso95/scroll-world

Sponsored

一个把品牌变成”可滚动世界”的开源脚手架

scroll-world 是 oso95 开源的一个”技能包(skill)“,核心理念只有一句话:把任意品牌的视觉资产——logo、产品图、色卡——拆成图层,再用 Three.js + ScrollTrigger 拼成一个可滚动推进的 3D 叙事。用户下滑推进场景,上滑回退,无需 Unity / Unreal,仅靠浏览器就能跑出电影感官网。它在 2026-07-12 凭借 ⭐830 冲上 GitHub Trending,背后是两条推力:WebGPU 在 Chrome / Safari 正式稳定、Three.js r166 把 PBR 与 glTF 流水线打磨到接近无坑;加上 Apple Vision Pro 把”空间浏览”概念重新带回桌面端,独立开发者都急着把品牌官网升级成”3D 体验”,scroll-world 正好是门槛最低的入场券。


1. 滚动到底,3D 相机却停在原地?

现象:用户滚到页面底部,3D 镜头还没推进到终点;或者镜头动了,DOM 滚动条却卡死。

根因:直接监听 wheelpreventDefault() 会把浏览器原生滚动完全接管,但 requestAnimationFrame 里用 lerp 平滑相机时,scrollY 已经不再更新,两条时间轴就此脱钩。

解法:让 ScrollTrigger 接管滚动驱动,把 progress 直接映射到相机参数:

import gsap from "gsap";
import { ScrollTrigger } from "gsap/ScrollTrigger";
gsap.registerPlugin(ScrollTrigger);

ScrollTrigger.create({
  trigger: "#scroll-world",
  start: "top top",
  end: "+4000",
  scrub: 1,
  pin: true,
  onUpdate(self) {
    camera.position.z = 10 - self.progress * 8;
    world.rotation.y = self.progress * Math.PI * 2;
    camera.lookAt(0, 0, 0);
  },
});

scrub: 1 会把动画绑到滚动条上,pin 住画布避免布局抖动,相机再也不会”掉队”。


2. 移动端 iPhone 跌到 15fps,触控镜头抽搐?

现象:桌面端 60fps 一到 Safari 移动端就崩到 15-20fps,双指捏合缩放时镜头还会”跳一下”。

根因:每帧都重传纹理、setPixelRatio(window.devicePixelRatio) 在 iPhone 14 上等于把像素量放大 9 倍,OrbitControls 的 enableZoom 又把 touch 事件抢走,与 ScrollTrigger 的 pinch 判定打架。

解法:限制 dpr、复用纹理、按需渲染、关掉冲突控件:

renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
renderer.setSize(width, height, false);

const dirty = { flag: true };
renderer.domElement.addEventListener("pointerdown", () => (dirty.flag = true));

function tick() {
  if (dirty.flag) {
    renderer.render(scene, camera);
    dirty.flag = false;
  }
  requestAnimationFrame(tick);
}
requestAnimationFrame(tick);

controls.enableZoom = false; // 让滚动驱动距离,不要触控打架

按需渲染能把空帧从 60 次/秒降到 0 次,电量与温度都明显改善。


3. Google 只能索引到一个空 canvas,SEO 暴跌?

现象:上线后 Search Console 显示”网页无可索引内容”,首屏 LCP 文本几乎为零,关键词排名一周内掉 30 位。

根因:所有品牌故事都渲染进 WebGL,HTML 里只剩一个 <canvas id="scroll-world"></canvas>,Googlebot(特别是 2026 还在用 Chromium 二代渲染的版本)抓不到任何语义内容。

解法:3D 是增强层,语义才是主层——SSR/预渲染一份完整 HTML 副本,3D 作为渐进增强:

<main>
  <!-- 给爬虫看的完整内容 -->
  <h1>ACME 2026 春夏系列</h1>
  <p>从街头到山野,ACME 用可回收尼龙与生物基橡胶重塑了 7 双经典鞋型……</p>

  <!-- 给浏览器看的 3D 层 -->
  <canvas id="scroll-world" aria-hidden="true"></canvas>
  <noscript><img src="/hero-poster.jpg" alt="ACME 春夏主视觉" /></noscript>
</main>

再用 IntersectionObserver 把 canvas 升级到 lazy mount,首屏 HTML 体积保持 14KB 以内,LCP 立刻回到 1.8s。


小结

scroll-world 不是银弹,它真正解决的问题是把”3D 品牌叙事”从电影公司手里抢回到普通前端团队。但要让它上线不掉链子,记住三条:滚动交给 ScrollTrigger、渲染改成按需、内容做双层 SSR。先跑通这三点,再去追求 Apple Vision Pro 的空间体验,否则你只是在给品牌官网加一个会卡的彩蛋。


Sources

📦 开源项目

本教程基于开源项目 oso95/scroll-world 整理。

⭐ View on GitHub →

📚 Sources

Sponsored

🛠️ Related Tools & Resources

Mechanical Keyboards →
For coding & writing tutorials
USB-C Hubs →
Multi-monitor dev setup
Noise-Cancelling Headphones →
Focus while learning
Laptop Stands →
Ergonomics for long tutorials