# Rips 开包动画技术拆解与复刻方案

## 结论先行

Rips 1.33.0 当前开包主流程不是 APK 内的一组逐帧图，也不是单个 Rive 文件。它是一个独立部署、按版本加载的 HTML5 3D 引擎：React Native App 获取购买结果后，将卡包图片、卡面图片、稀有度颜色等数据注入 WebView；远程 Three.js 页面负责选包、撕封、揭卡、粒子、声音与触觉节奏。

生产入口在分析时为：

```text
https://web.tlabs.app/pack-opening/v2/1.0.9/rn-harness.html
```

因此，复刻的关键不是提取一段视频，而是重建“数据协议 + 状态机 + 实时渲染 + 多感官时间轴”。

## 证据分级

### 已证实

- APK 的 GraphQL `ActivePacks` 查询含 `animationURL`、`packImageURL`、`particleColor`、`slabEdgeColor` 等动态配置。
- 购买返回值含卡片、稀有度颜色、附赠卡、揭示列表与奖励进度。
- App 内有 `PackOpeningOverlay`，使用全屏 WebView 加载版本化 `rn-harness.html`。
- App 注入 `window.PackOpeningBridge`，并接收 `bootStage`、`engineReady`、`haptic`、`done` 消息。
- 生产 harness 使用 Three.js 渲染器，明确以 `forceWebGL: true` 创建；动画时间轴由 GSAP 驱动。
- 真实 harness 已在隔离浏览器中跑通选包、聚焦、撕封、揭卡和完成流程。

### 高可信推断

- `animationURL` 很可能用于商品页或其他卡包展示动画，不是本版本主开包引擎的唯一入口。主开包路径在购买成功后统一进入版本化 WebView。
- 卡包外观主要由后端 `packImageURL` 驱动；深度、高光、反射与撕条来自引擎的通用材质和几何层。
- 稀有包并非另一套完整流程，而是在相同状态机上提高粒子、音效、停顿和烟花强度。

### 尚未完全证实

- 每类卡包是否会通过远端开关切换到不同的 harness 版本。
- `animationURL` 在所有商品类型中的完整使用范围。
- 真机不同 GPU、低电量模式和弱网下的降级阈值。

## 三层架构

### 1. React Native 壳层

职责：

- 发起购买并取得揭示结果。
- 创建全屏 WebView。
- 组装桥接参数并注入网页。
- 将网页的触觉请求映射到原生 haptics。
- 处理暂停、恢复、超时与错误降级。
- 动画失败时回退到普通揭示页，并记录 Datadog 事件。

### 2. Web 开包引擎

职责：

- 资源预加载和 GPU shader 预热。
- 15 包环形陈列与惯性拖拽。
- 选包聚焦、封条手势识别和包体变形。
- 卡面占位、颜色轮播、溶解揭示和光效。
- 粒子、烟花、音频、触觉节奏和完成回调。

### 3. 业务资源层

由接口动态提供：

```js
{
  packImageURL,
  particleColor,
  slabEdgeColor,
  tearStripColor,
  otherRaritySampleColors,
  isRare,
  soundEnabled,
  hapticsEnabled,
  cards: [
    {
      cardFrontImageURL,
      isBonus,
      isSlab,
      rarityColor
    }
  ]
}
```

网页内的通用资源包括 `pack-depth.jpg`、`pattern.jpg`、`perlin.avif`、MSDF 字体图集及约 20 个音频文件。业务卡包图与最终卡图不随 APK 固化，而是按 URL 加载。

## 状态机与节奏

| 阶段 | 用户动作 | 画面行为 | 声音/触觉 |
| --- | --- | --- | --- |
| Boot | 无 | 加载图片、音频、场景与 shader | 向 App 报告 boot stage |
| Carousel | 滑动或点击 | 15 包圆周排列、反射、雾、漂浮尘埃 | 滑动流粒子；正面包回弹重触觉 |
| Focus | 点击卡包 | 目标包移到镜头前，其他包退场 | 选中反馈 |
| Tear | 横向拖动 | 撕条跟手、顶部火花、未达阈值回弹 | 连续轻/中/重触觉；撕裂音 |
| Open | 达到阈值 | 包体打开、涡流、雪点、最终尘埃 | 连续轻触觉；开包与胜利音轨 |
| Reveal | 等待或点击 | 卡背/色块轮播、旋转、溶解为卡面 | 可点击四倍加速；揭卡低频和铃音 |
| Complete | 点击 | 稳定展示最终卡片，随后回调 App | 稀有包附加烟花与重触觉 |

原版关键提示词依次为：`Pick a Pack`、`Slice the seal`、`Tap to speed up`、`Tap to continue`。

## 渲染构成

### 卡包

- 15 个包围绕圆周分布，已观察配置为包宽 `3`、间距 `1.25`。
- 包体、顶部和底部使用实例化渲染，降低 draw call。
- 正面使用业务卡包图；深度图和光照制造褶皱与厚度感。
- 镜像实例与较高暗度形成地面反射，不依赖昂贵的实时反射。

### 撕封

- 输入不是播放预制视频，而是读取横向手势距离和方向。
- 封条位移、旋转、弯曲与进度绑定；火花沿撕裂前沿发射。
- 释放时按阈值分支：不足则回弹，达到则进入开包时间轴。

### 卡面揭示

- 最多预分配两张卡，普通卡优先，附赠卡随后。
- 真实卡图加载前用 `otherRaritySampleColors` 循环，制造稀有度搜索感。
- shader 预热避免第一次卡面溶解时明显掉帧。
- 揭示完成前保留输入监听，点击后提升时间轴倍率。

### 粒子与稀有特效

- 常驻：上升尘埃、点击尘埃、滑动流、顶部火花。
- 开包：撕裂火花、涡流、雪点、最终尘埃。
- 稀有：更强粒子密度和多轮烟花；分析到的实现为四轮、每轮约 250 粒子。

## 资源结构

### APK 本地资源

APK 内的 `.riv` 文件主要对应背景、发货成功和售货机等场景；没有发现能独立复现当前完整开包流程的本地 Rive 文件。另有 `magicalcoin.wav`，但主开包音频由远端引擎管理。

### 远端引擎资源

- 材质：深度图、噪声图、卡面 pattern。
- 字体：Liberation Sans MSDF JSON 与 atlas。
- 声音：轮播环境、软回弹、撕包、切割、预热、whoosh、纸张褶皱、胜利循环、揭卡、烟花。
- 动态图片：卡包正面图、普通卡图、附赠卡图。

不要把这些远端资源打进自有产品。应只把它们作为资源类别和节奏参考，重新制作可授权资产。

## clean-room 原型对应关系

本目录的原型采用同类技术结构，但未复制产品代码与素材：

- Three.js：场景、相机、包体、卡片、粒子和射线点击。
- GSAP：聚焦、开包与卡面揭示时间轴。
- CanvasTexture：程序化卡包、卡片和粒子纹理。
- Pointer Events：鼠标与触屏共用的滑动、点击和撕封输入。
- Web Audio：可选的简易合成反馈音，仅用于验证节奏。
- Vibration API：支持设备上的基础振动验证。

![桌面环形选包](./verification/desktop-carousel.png)

![手机最终揭卡](./verification/mobile-complete.png)

与原版实测截图对照：

![原版环形选包](../pack-opening-analysis/stage-1-carousel.png)

![原版撕封](../pack-opening-analysis/stage-3-tearing.png)

![原版最终卡面](../pack-opening-analysis/stage-5-complete.png)

## 产品化替换清单

1. 自有卡包正面图：建议 2:3 或接近实际包体比例，透明边缘需统一。
2. 自有深度/法线图：控制褶皱、封边和金属高光，不要从原资源衍生。
3. 自有卡背、卡框、最终卡图：按普通卡、评级卡、附赠卡建立模板。
4. 粒子纹理：圆点、火花、纸屑、烟花各一组，并定义低中高性能档。
5. 音频：轮播环境、选择、切割、撕裂、whoosh、揭示、稀有成功至少七类。
6. 原生桥：定义输入数据、`engineReady`、触觉、完成、错误与暂停恢复协议。
7. 降级策略：资源超时、WebGL context lost、低端 GPU 和后台恢复必须有静态揭示页。
8. 遥测：记录 boot 总耗时、各资源耗时、首次交互时间、掉帧、降级原因和完成率。

## 推荐实现顺序

1. 先固化桥接协议和无动画降级页。
2. 完成单包聚焦、撕封阈值和最终卡面，验证业务闭环。
3. 增加环形陈列、惯性与吸附。
4. 加入 shader 预热、卡面溶解和性能分档。
5. 最后编排音频、触觉、稀有烟花和埋点。

这样可以先证明交互和揭示可靠，再增加高成本的视觉层，不让动画失败阻断购买后的结果交付。

## 验证结果

- 构建：Vite production build 通过。
- 桌面：`1440x900` 完整流程通过，控制台无异常。
- 手机：`390x844` 完整流程通过，控制台无异常。
- 布局：两种视口画布与 viewport 一致，无页面溢出。
- 画面：各阶段截图均有大量非黑像素和丰富颜色，排除 WebGL 空白画布。

自动化结果保存在 `verification/verification.json`。
