# 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`。