# @14islands/r3f-scroll-rig 中文文档

规范地址：https://npmcn.com/package/%4014islands/r3f-scroll-rig/

版本：8\.15\.0
npm 元数据更新时间：2024-12-04T10:34:52.999Z
中文译文更新时间：2026-11-06T16:27:50.957Z
软件包许可：ISC

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%4014islands/r3f-scroll-rig
原文对照：https://npmcn.com/package/%4014islands/r3f-scroll-rig/?lang=original
项目主页：https://github.com/14islands/r3f-scroll-rig#readme
源码仓库：https://github.com/14islands/r3f-scroll-rig

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：991 kB，87 个文件
- 模块格式：ESM + CJS
- TypeScript 类型：包内自带
- 运行依赖：12 个
- peer 依赖：@react-three/drei \>=9\.0\.0，@react-three/fiber \>=8\.0\.0，react \>=18\.0，react-dom \>=18\.0，three \>=0\.139\.0
- 首次发布：2020-08-26T06:47:41.376Z
- 最新版本发布：2024-12-04T10:34:52.766Z
- 近 30 天下载量：2739（2026-10-05 至 2026-11-03，npm 官方下载统计）
- 已发布版本数：202（近 12 个月 0 个）

## 中文简介

用 WebGL 使用 @ react- 3/fiber 逐步增强任何反应网站

## 安装

```sh
npm install @14islands/r3f-scroll-rig
```

也可以使用：`pnpm add @14islands/r3f-scroll-rig`、`yarn add @14islands/r3f-scroll-rig`、`bun add @14islands/r3f-scroll-rig`

## README

# @14个岛屿/r3f-scroll-rig

![npm](https://img.shields.io/npm/v/@14islands/r3f-scroll-rig?color=magenta&style=flat-square)

使用 WebGL 逐步增强反应网站 `@react-three/fiber` 并展开平滑的卷轴.

![](https://www.dropbox.com/s/kqaweg996jtb2ho/14islands600_10fps_2.gif?dl=0&raw=1) ![](https://www.dropbox.com/s/vmpqf17oy0otkkl/pluto600_10fps.gif?dl=0&raw=1)

\[ [特征](https://npmcn.com/package/%4014islands/r3f-scroll-rig/#readme-features-) | [导言](https://npmcn.com/package/%4014islands/r3f-scroll-rig/#readme-introduction-) | [安装](https://npmcn.com/package/%4014islands/r3f-scroll-rig/#readme-installing-) | [开始](https://npmcn.com/package/%4014islands/r3f-scroll-rig/#readme-getting-started-) | [实例](https://npmcn.com/package/%4014islands/r3f-scroll-rig/#readme-examples-) | [API 密码](https://npmcn.com/package/%4014islands/r3f-scroll-rig/#readme-api-%EF%B8%8F) | [抓到他们了](https://npmcn.com/package/%4014islands/r3f-scroll-rig/#readme-gotchas-) \[ . \]

# 特征

-   QQ 跟踪 DOM 元素, 并用正确的比例和位置来绘制 Three.js 对象的位置 .
-   • 框架不可知 - 与 `next.js`, (中文(简体) ), `gatsby.js`, (中文(简体) ), `create-react-app` 包括:.
-   \* 可在取景口中渲染物体。 使每个物体都有可能拥有独特的相机,灯光,环境图等.
-   帮助从 DOM 装入响应图像 。 支助 `<picture>`, (中文(简体) ), `srset` 财务报告和审定财务报表 `loading="lazy"`
-   最佳表现。 电话 `getBoundingClientRect()` 一旦挂载,并使用交叉观察员/抵抗观察员来跟踪各项要素.
-   用户 [列尼斯语Name](https://github.com/darkroomengineering/lenis) 用于可访问的平滑滚动
-   百分之百符合@反应-三生态系统 [德莱](https://github.com/pmndrs/drei), (中文(简体) ), [反应-春季](https://www.react-spring.dev/) 财务报告和审定财务报表 [反应-xr](https://github.com/pmndrs/react-xr)

# 导言

用滚动的HTML来混合WebGL是困难的. 一种方式是拥有多幅画布,但对于WebGL中有多少个背景可以同时活跃,资源不能在上下文之间共享,有特定浏览器的限制.

![](https://user-images.githubusercontent.com/420472/191715313-cc813f47-4e4a-454f-a2f5-d8e2ec998c95.jpeg)

卷轴里格只有一个共享 `<GlobalCanvas/>` 在页面负载之间.

反应 DOM 组件可以选择在使用自定义钩子挂载时在此画布上绘图 `useCanvas()` 或 `<UseCanvas/>` 隧道组件.

库还提供了在滚动时将WebGL对象与DOM同步的手段. 我们使用一种技术,跟踪正常页面流中的“代理”元素,并更新WebGL场景位置,以匹配它们.

这个 `<ScrollScene/>`, (中文(简体) ), `<ViewportScrollScene/>` 或基础 `useTracker()` 钩会检测代理元素的初始位置和尺寸,并更新滚动时的位置.

所有东西都与主线上滚动条位置同步.

进一步读作: [用 WebGL 和 React 进行渐进增强](https://medium.com/14islands/progressive-enhancement-with-webgl-and-react-71cd19e66d4)

# 正在安装QQ

`yarn add @14islands/r3f-scroll-rig @react-three/fiber three`

# 开始QQ

1.  添加 `<GlobalCanvas>` 到您的布局。 将其保存在路由器外,以防在页间导航时卸载.
    
2.  添加 `<SmoothScrollbar/>` 到您的布局。 为了完全匹配WebGL对象和DOM内容,浏览器卷轴位置需要在主线程上被动画.
    

下一个.js

```jsx
import { GlobalCanvas, SmoothScrollbar } from '@14islands/r3f-scroll-rig'

// _app.jsx
function App({ Component, pageProps }: AppProps) {
  return (
    <>
      <GlobalCanvas />
      <SmoothScrollbar />
      <Component {...pageProps} />
    </>
  )
}
```
盖茨比.js

```jsx
// gatsby-browser.js
import { GlobalCanvas, SmoothScrollbar } from '@14islands/r3f-scroll-rig'

export const wrapRootElement = ({ element }) => (
  <>
    <GlobalCanvas />
    <SmoothScrollbar />
    {element}
  </>
)
```

2.  跟踪 DOM 元素并制取一个 3.js 对象

这是追踪DOM的组件的基本例子

```jsx
import { UseCanvas, ScrollScene } from '@14islands/r3f-scroll-rig'

export const HtmlComponent = () => (
  const el = useRef()
  return (
    <>
      <div ref={el}>Track me!</div>
      <UseCanvas>
        <ScrollScene track={el}>
          {(props) => (
            <mesh {...props}>
              <planeGeometry />
              <meshBasicMaterial color="turquoise" />
            </mesh>
          )}
        </ScrollScene>
      </UseCanvas>
    </>
  )
)
```

## 如何运作:

-   页面布局使用普通 HTML & CSS 样式
-   这个 `UseCanvas` 用于将孩子送到 `GlobalCanvas` 当组件挂起时
-   A 类 `<Scrollscene>` 用于跟踪 DOM 元素
-   内部 `<ScrollScene>` 我们定出一个网状的网状,它将作为已逝的一部分,获得正确的分寸 `props`

**注释:** HMR可能不为下列儿童服务: `<UseCanvas>` 除非你在外边定义了他们 此外,儿童身上的道具默认并非被动反应,因为部件被通向全球帆布. [更新道具需要这样通地道.](https://npmcn.com/docs/api.md#usecanvas)

了解更多关于边缘案例和解决方案 [获取区域](https://npmcn.com/package/%4014islands/r3f-scroll-rig/#readme-gotchas-)。 。 。 .

# 实例

-   [滚动环境基本实例](https://codesandbox.io/s/hello-world-ibc8y7?file=/src/App.jsx)
-   [由 DOM 和 Canvas 提供的 GLB 模型和事件滚动](https://codesandbox.io/s/scrollscene-with-glb-6l2fc3?file=/src/App.js)
-   [带有自定义相机和控件的 ViewportScrollScene](https://codesandbox.io/s/hello-viewportscrollscene-fu0ky6?file=/src/App.jsx)
-   [从“ img” 标签装入纹理](https://codesandbox.io/s/load-image-from-dom-n120ll?file=/src/App.jsx)
-   [从 DOM 装入响应的纹理](https://codesandbox.io/s/load-responsive-picture-from-dom-rgcx4b?file=/src/App.jsx)
-   [HTML 参数使用跟踪器( ) 和帧器运动](https://codesandbox.io/s/parallax-with-framer-motion-dx2v1p?file=/src/App.jsx)
-   [电源样品的粘相卷轴](https://codesandbox.io/s/r3f-scroll-rig-sticky-box-w5v4u7?file=/src/App.jsx)
-   [一个基本的后处理示例](https://codesandbox.io/p/sandbox/hello-scrollscene-forked-cp3n93?file=/src/App.jsx)

# API —— ——

所有组件和钩在 [API 文件](https://npmcn.com/docs/api.md)

<table><tbody><tr><td><h2><a href="https://npmcn.com/docs/api.md#components" rel="nofollow noopener noreferrer">构成部分</a></h2><ul><li><a href="https://npmcn.com/docs/api.md#globalcanvas" rel="nofollow noopener noreferrer">全球风景</a></li><li><a href="https://npmcn.com/docs/api.md#smoothscrollbar" rel="nofollow noopener noreferrer">平滑滚动栏</a></li><li><a href="https://npmcn.com/docs/api.md#usecanvas" rel="nofollow noopener noreferrer">使用 Canvas 时</a></li><li><a href="https://npmcn.com/docs/api.md#scrollscene" rel="nofollow noopener noreferrer">滚动环境</a></li><li><a href="https://npmcn.com/docs/api.md#viewportscrollscene" rel="nofollow noopener noreferrer">查看端口滚动环境</a></li></ul></td><td><h2><a href="https://npmcn.com/docs/api.md#hooks" rel="nofollow noopener noreferrer">钩子</a></h2><ul><li><a href="https://npmcn.com/docs/api.md#usescrollrig" rel="nofollow noopener noreferrer">使用 ScrollRig</a></li><li><a href="https://npmcn.com/docs/api.md#usescrollbar" rel="nofollow noopener noreferrer">使用滚动栏</a></li><li><a href="https://npmcn.com/docs/api.md#usetracker" rel="nofollow noopener noreferrer">使用跟踪器</a></li><li><a href="https://npmcn.com/docs/api.md#usecanvas-1" rel="nofollow noopener noreferrer">使用 Canvas 系统</a></li><li><a href="https://npmcn.com/docs/api.md#useimageastexture" rel="nofollow noopener noreferrer">图像图</a></li></ul></td></tr></tbody></table>

# 抓住他们了

默认相机

默认的卷轴-rig相机被锁定到50度的场景.

为了完全匹配DOM尺寸,将计算相机相距. 这种计算基于屏幕高度,因为Treejs使用垂直的FOV. 这意味着相机位置 -z会根据你的身高稍作改变.

您可以覆盖默认相机行为, 例如设置距离, 并有一个可变的 FOV :

```jsx
<GlobalCanvas camera={{ position: [0, 0, 10] }} />
```

或改变FOV, 它可以移动相机 更远在这种情况下:

```jsx
<GlobalCanvas camera={{ fov: 20 }} />
```

如果您需要完全控制相机,您可以在孩提时用自定义相机通过.

使用相对缩放 大小始终以从ScrollScene/ViewportScrollScene/useTracker上传下来的"比例尺"为基准,以便所有屏幕大小的缩放一致.

这个 `scale` 总是匹配跟踪的 DOM 元素,并将根据媒体查询等进行更新.

```jsx
<ScrollScene track={el}>
  {{ scale }} => (
  <mesh scale={scale} />
  )}
</ScrollScene>
```

缩放为 三维向量类型 [维克恩](https://www.npmjs.com/package/vecn) 支持擦去和标注对象。 你可以做这样的事情:

```js
position.x === position[0]
position.xy => [x,y]
scale.xy.min() => Math.min(scale.x, scale.y)
```
3D 对象上的 Z- 战斗( 比例倍增器)

默认情况下,卷轴-rig会计算相机FOV,这样一像素=一取景器单元.

在某些情况下,这可能会搅乱深度排序,导致3D模型中的视觉出故障. 1000像素宽屏幕会让场景1000取景器单元宽,默认情况下相机也会被定位为~1000个单元去Z轴(取决于FoV和屏幕高特).

一个解决的方法就是使 [对数深度缓冲](https://threejs.org/docs/index.html?q=webglre#api/en/renderers/WebGLRenderer) 但是这可能会对表现不利.

更好的解决问题的方法就是改变全球危机 `scaleMultiplier` 喜欢的东西 `0.01` 这将使1000px = 10个取景器单元.

```jsx
<GlobalCanvas scaleMultiplier={0.01} />
```

这个 `scaleMultiplier` 设置所有内部相机和缩放逻辑。 如果您更改了此设置, 需要更新已编码的缩放和位置 .

匹配精确的十六进制颜色

默认的R3F使用ACES Filmic语调映射,使得3D场景看起来很棒.

然而,如果需要匹配六分法颜色或显示编辑图像,可以禁用每个类似材料:

```jsx
<meshBasicMaterial toneMapping={false} />
```
累积布局变化( CLS)

页面上的所有项目都应有一个可预测的高度——始终使用CSS来定义图像和其他可能影响到文件加载时高度的交互式元素的宽比.

滚动指针使用 `ResizeObserver` 以检测对 `document.body` 高度, 例如在 webfonts 装入后, 并且会自动重新计算所装的 .

如果因某种原因失败, 可以触发手动操作 `reflow()` 以重新计算所有缓存位置.

```jsx
const { reflow } = useScrollRig()

useEffect(() => {
  heightChanged && reflow()
}, [heightChanged])
```
绩效提示

-   尽可能使用 CSS 动画,而不是 JS ,以尽量平滑
-   考虑取消平滑Scrollbar和移动上所有滚动的WebGL元素的功能 - 它通常是拉吉.
-   确保你 [阅读、理解和跟踪所有业绩建议](https://docs.pmnd.rs/react-three-fiber/advanced/pitfalls) 与 `React` 财务报告和审定财务报表 `three`数字 :

如何捕捉来自DOM和Canvas的事件

这在R3F中是可能的,方法是将事件系统重新连接到画布的母部分:

```tsx
const ref = useRef()
return (
  <div ref={ref}>
    <GlobalCanvas
      eventSource={ref} // rebind event source to a parent DOM element
      eventPrefix="client" // use clientX/Y for a scrolling page
      style={{
        pointerEvents: 'none', // delegate events to wrapper
      }}
    />
  </div>
)
```
我能在“视频空间”中使用R3F事件吗?

是的,如果您遵循上述步骤将事件系统重新连接到画布的母部分, 事件将会被正确地通入视图端口 .

在 Viewport 中 Margin 无法在代码对话框中工作

代码Sandbox 编辑器运行在一个 iframe 中, 它打破了 Intersection 观察器 `rootMargin`。如果你打开 iframe 外的示例, 你会看到它的工作原理.

这是知道 [问题](https://github.com/thebuilder/react-intersection-observer/issues/330#issuecomment-612221114)。 。 。 .

HMR不与UseCanvas儿童合作

有问题 `UseCanvas` 组件.

你也可以用这个 `useCanvas()` 钩子,或者通过定义您的孩子为顶级功能, 而不是内衬, 使 HMR 再次工作 :

```jsx
// HMR will work on me since I'm defined here!
const MyScrollScene = ({ el }) => <ScrollScene track={el}>/* ... */</ScrollScene>

function MyHtmlComponent() {
  return (
    <UseCanvas>
      <MyScrollScene />
    </UseCanvas>
  )
}
```

类似 [问题](https://github.com/pmndrs/tunnel-rat/issues/4) 存在于 `tunnel-rat`。 。 。 .

全局渲染环路

卷轴-rig运行自定义渲染环球场景在r3f内部的循环. 优先运行 `1000`。 。 。 .

您可以使用 `globalRender` 或用 `globalPriority` 道具装上 `<GlobalCanvas>`。仍然可以使用 `useFrame` 您的自定义优先级.

运行我们自己的自定义让通过 而不是默认的 R3F 渲染, 的主要原因是当没有 meshes 在视图中时能够避免渲染。 要启用此功能, 您需要设置 `frameloop="demand"` (原始内容存档于2012-10-12). On the Global Canvas.

高级 - 按需运行帧

如果设置为 R3F 帧 `demand` - 卷轴钻机会确保 全球性 和视图端 只有在需要它的情况下.

请求全局渲染呼叫 `requestRender()` 从 `useScrollRig` 每个框. `ScrollScene` 等网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状网状.

这个库还支持在取景口中进行单独的场景,作为单独的渲染通过调用 `renderViewport()`。这样我们就可以用单独的灯光 或不同的相机来制作场景 与全球场景不同。 就是这样 `ViewportScrollScene` 工作时.

在这种情况下,你还需要打电话 `invalidate` 以触发新的 R3F 框架.

如何使用后处理

后处理在单独的通道中运行,所以需要手动禁用全局渲染回路,以避免重复渲染.

```jsx
<GlobalCanvas globalRender={false} scaleMultiplier={0.01}>
  <Effects />
</GlobalCanvas>
```

说明: `ViewportScrollScene` 将不受全球后处理效应的影响,因为它运行在单独的转折中.

我怎么能把我的UseCanvas meshes 装入一个共享的悬念?

请在使用时读取 API 文件 [儿童作为渲染功能](https://npmcn.com/docs/api.md#children-as-render-function) 举个例子.

# \# 在野外 # # In the wird # #

-   [14岛.com](https://14islands.com/) 以 [14个岛屿](https://14islands.com/)
-   [v2.14 岛屿.com](https://14islands.com/) 以 [14个岛屿](https://14islands.com/)
-   [冥王星应用](https://www.pluto.app/) 以 [14个岛屿](https://14islands.com/)
-   [米里亚德.video](https://myriad.video/) 以 [14个岛屿](https://14islands.com/)
-   [内科保健](https://www.nekohealth.com/) 以 [14个岛屿](https://14islands.com/)
-   [播放目标.com](https://playgoals.com/) 以 [14个岛屿](https://14islands.com/)
-   [目标工作室](https://studio.playgoals.com/) 以 [14个岛屿](https://14islands.com/)
-   [冥王星 Dev 门户网站](https://dev.pluto.app/) 以 [14个岛屿](https://14islands.com/)
-   [量子钱包](https://quantumwallet.tech/) 以 [14个岛屿](https://14islands.com/)
-   [元任务学习](https://learn.metamask.io/) 以 [抗肿瘤工作室](https://antinomy.studio/)
-   [林克赛](https://lynxeye.com/) 以 [14个岛屿](https://14islands.com/)
-   [阿斯特拉·诺瓦](https://astranova.world/) 以 [学习/nk](https://thefwa.com/profiles/estudionk-r) 财务报告和审定财务报表 [@ juliperoncini (英语)](https://twitter.com/juliperoncini)
-   [Axolot 游戏](https://www.axolotgames.com/) 以 [14个岛屿](https://14islands.com/)

## 常见问题

### @14islands/r3f-scroll-rig 是什么？

用 WebGL 使用 @ react- 3/fiber 逐步增强任何反应网站

### 如何安装 @14islands/r3f-scroll-rig？

在项目目录运行 npm install @14islands/r3f-scroll-rig，或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖：react（\>=18\.0）、react-dom（\>=18\.0）、three（\>=0\.139\.0）。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖，Yarn 需要手动安装。

### @14islands/r3f-scroll-rig 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @14islands/r3f-scroll-rig 支持 ESM 还是 CommonJS？

同时提供 ES Module 与 CommonJS 入口，import 和 require\(\) 都可以使用，打包工具会自动选择合适的版本。

### @14islands/r3f-scroll-rig 可以商用吗？

@14islands/r3f-scroll-rig 使用 ISC 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @14islands/r3f-scroll-rig 的下载量有多少？

根据 npm 官方下载统计，@14islands/r3f-scroll-rig 在 2026/10/05 – 2026/11/03 这 30 天内被下载 2,739 次，日均约 91 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @14islands/r3f-scroll-rig 还在维护吗？

最新版本 8\.15\.0 发布于 2024/12/04（1\.9 年前）；至今共发布 202 个版本，其中过去 12 个月发布了 0 个；首次发布于 2020/08/26。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

