10秒决定60fps:appllama-skills的Reanimated动效规则与常见坑指南
【免费下载链接】appllama-skillsA builder, not just a researcher. Agent skills that turn top-grossing app patterns into native-quality mobile screens.项目地址: https://gitcode.com/gh_mirrors/ap/appllama-skills
appllama-skills 是一套把畅销 App 的设计模式变成原生质感移动界面的 Agent 技能包,其中 appllama-app-design-skill 对 React Native + Reanimated 动效定了一条硬标准:用户会在打开应用的头 10 秒内,凭一次掉帧、一个生硬的弹层,判断你的 App 是"真原生"还是"套壳网页"。这份指南把它的动效规则提炼成一份可直接对照的检查清单,帮你避开新手最常踩的坑。
动效两大家族:搞混了,一眼"非原生"
motion.md 开篇就把动效分成两类(见 motion.md#L6-L15):
| 家族 | 谁在驱动 | 用什么曲线 | 典型场景 |
|---|---|---|---|
| Responsive 响应型(手指正在碰它) | 手势的位置 / 速度 | 弹簧(spring),注入手势速度 | 弹层拖拽、滑动关闭、下拉刷新、卡片平移 |
| Narrative 叙事型(系统主动发起) | 时间 | withTiming+ ease-out,150–350 ms | 页面入场、渐显、Toast |
⚠️最常见的坑:两族混用。弹层在快速甩出后用一个固定 300ms 的 timing 关闭——感觉像"死"的;按钮点一下却弹跳 800ms——像玩具。手指参与 → 弹簧;系统发起 → 短 timing,这是第一判断。
弹簧参数速查表:全应用只该有两组预设
motion.md#L17-L29 给出的"弹簧词汇表"极简:
// SNAP:临界阻尼,无振荡 —— 日常归位、吸附 const SNAP = { duration: 400, dampingRatio: 1 }; // POP:一次柔和过冲 —— 只用于庆祝、吉祥物等少数时刻 const POP = { duration: 400, dampingRatio: 0.8 };两条配套规则(都是新手高频踩坑点):
- 手势松开时必须把手势速度喂进弹簧(
velocity: event.velocityY),否则手指甩得再快,元素也慢悠悠地走,手感立刻"假"。 - 一套应用一份弹簧词汇表:
SNAP/POP定义一次、到处 import。第 7 个页面突然冒出第三种弹跳参数,用户说不清哪里不对,但会记住"不对劲"。
坑一:动画跳了 JS 线程,手势必卡
手势 → 动画的整条链路都应在 UI 线程跑(worklet + 共享值)。三条红线(motion.md#L43-L50):
- ❌绝不在
onChange里读写 React state——每次手指移动都跨线程一次,performance.md#L61-L62 说得直接:"onChange里出现一次runOnJS就足以毁掉整个手势"。 - ✅
scheduleOnRN只在手势结束时用,留给导航、副作用这类事;共享值用.get()/.set()读写,绝不在渲染期间碰。 - ✅ 判定阈值用距离 OR 速度组合:从 10px 处快速一甩,也必须判定为"关闭"。
另外别忘了可中断性:弹簧飞行途中再次触摸,必须抓取"当前动画值"而不是"目标值",这是原生手感的关键细节。
坑二:入场、出场、布局动画的节奏错误
motion.md#L52-L66 的三条经验值:
- 列表入场按索引错峰:
delay(index * 40),stagger 封顶约 8 项,超出就整体入场(排到屏幕外的项错峰入场没有意义)。 - 出场永远比入场快(约 0.7 倍),并沿原路返回。
- 子项会重排/变尺寸的容器加
layout过渡——筛选 chips、展开卡片、拖拽排序的"高级感"就是这么来的。
坑三:忘了 Reduce Motion
每个空间动效(位移、缩放)都需要一个纯透明度过渡的降级版本(motion.md#L92-L101):
const reduceMotion = useReducedMotion(); entering = reduceMotion ? FadeIn.duration(150) : SlideInDown.springify();文档的原话:这是无障碍要求,不是加分项。
60fps 验收循环:唯一"测出来的"标准
"看着流畅"不算数。appllama-skills 的 60fps 门槛(SKILL.md#L218-L222)有三个反直觉要点:
- 必须在最慢支持设备的 release build 上测——Expo Go 和开发构建恰好会掩盖你正在追查的卡顿。
- 只动
transform和opacity;动 width/height/padding 这类布局属性会每帧强制重排。 - worklet 热路径里零分配——每帧一次
.map或对象展开都是隐患;每个动画节点一个useAnimatedStyle,别用一个巨型样式喂 20 个列表项。
卡顿时先 profile 再动手(performance.md#L1-L17):测量 → 优化被数据指控的那一项 → 复测 → 用数字验证(如 45 → 60 fps)。"没有数字就没有结论"。最常见的两个真凶:过渡中途提交的重渲染卡住 JS 线程、UI 线程上的图片解码。
最后跑一次全动效走查(simulator-loop.md):把整条流程录屏,看两遍——一遍全速看手感,一遍逐帧看。找掉帧、一帧白屏闪烁、布局跳变。一整帧的瑕疵就意味着流程未完成。
一张表带走:动效预算速查
| 指标 | 预算 |
|---|---|
| 过渡 / 手势 FPS | 60,核心流程零掉帧 |
| 入场 / 叙事动画 | < 300 ms,强 ease-out,出场 ≈ 0.7× 入场 |
| 按压反馈 | press-in 时 100–150 ms 出现(按钮 scale 0.97) |
| 动效属性 | 仅transform/opacity |
💡 新手建议的使用姿势:先读 motion.md 建立手感,卡顿时查 performance.md 定位,交付前过一遍 SKILL.md 的 Motion laws——其中最有价值的一条是"拿不准时,删掉动画本身就是最强的优化"。
【免费下载链接】appllama-skillsA builder, not just a researcher. Agent skills that turn top-grossing app patterns into native-quality mobile screens.项目地址: https://gitcode.com/gh_mirrors/ap/appllama-skills
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考